k8s运行容器之deployment(三)--技术流ken

 

deployment

 

咱们已经知道k8s是经过各类controller来管理pod的生命周期。为了知足不一样业务场景,k8s开发了DeploymentReplicaSetDaemonSetStatefuleSetJob 等多种 Controller。咱们首先学习最经常使用的 Deploymentnode

 

运行一个deploymentlinux

[root@ken ~]# kubectl run httpd-ken1--generator=run-pod/v1 --image=httpd --replicas=2

 

下面详细分析 Kubernetes 都作了些什么工做。nginx

[root@ken ~]# kubectl get deployment NAME READY UP-TO-DATE AVAILABLE AGE httpd-ken   2/2     2            2           35m

kubectl get deplouyment命令能够查看 httpd-ken 的状态,输出显示两个副本正常运行。docker

 

接下来咱们用 kubectl describe deployment 了解更详细的信息。api

[root@ken ~]# kubectl  describe deployment httpd-ken Name: httpd-ken Namespace: default CreationTimestamp: Tue, 29 Jan 2019 15:27:40 +0800 Labels: run=httpd-ken Annotations: deployment.kubernetes.io/revision: 1 Selector: run=httpd-ken Replicas: 2 desired | 2 updated | 2 total | 2 available | 0 unavailable StrategyType: RollingUpdate MinReadySeconds: 0 RollingUpdateStrategy: 25% max unavailable, 25% max surge Pod Template: Labels: run=httpd-ken Containers: httpd-ken: Image: httpd Port: <none> Host Port: <none> Environment: <none> Mounts: <none> Volumes: <none> Conditions: Type Status Reason ----           ------  ------ Available True MinimumReplicasAvailable Progressing True NewReplicaSetAvailable OldReplicaSets: <none> NewReplicaSet: httpd-ken-5c949b96f (2/2 replicas created) Events: Type Reason Age From Message ----    ------             ----  ----                   ------- Normal ScalingReplicaSet 18m deployment-controller  Scaled up replica set httpd-ken-5c949b96f to 2

 

大部份内容都是自解释的,咱们重点看最下面部分。这里告诉咱们建立了一个 ReplicaSet httpd-ken-5c949b96,Events Deployment 的日志,记录了 ReplicaSet 的启动过程。app

 

经过上面的分析,也验证了 Deployment 经过 ReplicaSet 来管理 Pod 的事实。接着咱们将注意力切换到 httpd-ken-5c949b96,执行 kubectl describe replicasetide

[root@ken ~]# kubectl get replicaset NAME DESIRED CURRENT READY AGE httpd-ken-5c949b96f   2         2         2       20m

 

两个副本已经就绪,用 kubectl describe replicaset 查看详细信息:学习

 

[root@ken ~]# kubectl describe replicaset Name: httpd-ken-5c949b96f Namespace: default Selector: pod-template-hash=5c949b96f,run=httpd-ken Labels: pod-template-hash=5c949b96f run=httpd-ken Annotations: deployment.kubernetes.io/desired-replicas: 2 deployment.kubernetes.io/max-replicas: 3 deployment.kubernetes.io/revision: 1 Controlled By: Deployment/httpd-ken Replicas: 2 current / 2 desired Pods Status: 2 Running / 0 Waiting / 0 Succeeded / 0 Failed Pod Template: Labels: pod-template-hash=5c949b96f run=httpd-ken Containers: httpd-ken: Image: httpd Port: <none> Host Port: <none> Environment: <none> Mounts: <none> Volumes: <none> Events: Type Reason Age From Message ----    ------            ----  ----                   ------- Normal SuccessfulCreate 20m replicaset-controller  Created pod: httpd-ken-5c949b96f-twdsd Normal SuccessfulCreate 20m replicaset-controller  Created pod: httpd-ken-5c949b96f-9cd52

 

Controlled By 指明此 ReplicaSet 是由 Deployment httpd-ken 建立。Events 记录了两个副本 Pod 的建立。接着咱们来看 Pod,执行 kubectl get pod:测试

[root@ken ~]# kubectl get pod NAME READY STATUS RESTARTS AGE httpd-ken-5c949b96f-9cd52   1/1     Running   0 22m httpd-ken-5c949b96f-twdsd   1/1     Running   0          22m

 

两个副本 Pod 都处于 Running 状态,用 kubectl describe pod 查看更详细的信息:spa

root@ken ~]# kubectl describe pod Name: httpd-ken-5c949b96f-9cd52 Namespace: default Priority: 0 PriorityClassName: <none> Node: host1/172.20.10.7 Start Time: Tue, 29 Jan 2019 15:46:45 +0800 Labels: pod-template-hash=5c949b96f run=httpd-ken Annotations: <none> Status: Running IP: 10.244.1.3 Controlled By: ReplicaSet/httpd-ken-5c949b96f Containers: httpd-ken: Container ID: docker://e59bda9941a16f20027c89a0d8fa8e17797b517f6f5461e905c0d29b57369dde
 Image: httpd Image ID: docker-pullable://httpd@sha256:44daa8e932a32ab6e50636d769ca9a60ad412124653707e5ed59c0209c72f9b3
    Port:           <none> Host Port: <none> State: Running Started: Tue, 29 Jan 2019 15:47:10 +0800 Ready: True Restart Count: 0 Environment: <none> Mounts: /var/run/secrets/kubernetes.io/serviceaccount from default-token-vb7lm (ro) Conditions: Type Status Initialized True Ready True ContainersReady True PodScheduled True Volumes: default-token-vb7lm: Type: Secret (a volume populated by a Secret) SecretName: default-token-vb7lm Optional: false QoS Class: BestEffort Node-Selectors:  <none> Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s node.kubernetes.io/unreachable:NoExecute for 300s Events: Type Reason Age From Message ----    ------     ----  ----               ------- Normal Scheduled 23m default-scheduler  Successfully assigned default/httpd-ken-5c949b96f-9cd52 to host1 Normal Pulling 23m kubelet, host1 pulling image "httpd" Normal Pulled 22m kubelet, host1 Successfully pulled image "httpd" Normal Created 22m kubelet, host1 Created container Normal Started 22m kubelet, host1 Started container

Controlled By 指明此 Pod 是由 ReplicaSet  httpd-ken-5c949b96f建立。Events 记录了 Pod 的启动过程。若是操做失败(好比 image 不存在),也能在这里查看到缘由。

 

总结一下这个过程:

用户经过 kubectl 建立 Deployment。

Deployment 建立 ReplicaSet。

ReplicaSet 建立 Pod

也能够看出,对象的命名方式是:子对象的名字 = 父对象名字 + 随机字符串或数字。

 

命令vs配置文件

 

k8s支持两种建立资源的方式:

1.用 kubectl 命令直接建立,好比:

kubectl run nginx-deployment --image=nginx:1.7.9 --replicas=2

在命令行中经过参数指定资源的属性。

 

2. 经过配置文件和 kubectl apply 建立,要完成前面一样的工做,可执行命令:

kubectl apply -f nginx.yml

nginx.yml 的内容为:

 

资源的属性写在配置文件中,文件格式为 YAML。

 

下面对这两种方式进行比较。

 

基于命令的方式:

简单直观快捷,上手快。

适合临时测试或实验。

 

基于配置文件的方式:

配置文件描述了 What,即应用最终要达到的状态。

配置文件提供了建立资源的模板,可以重复部署。

能够像管理代码同样管理部署。

适合正式的、跨环境的、规模化部署。

这种方式要求熟悉配置文件的语法,有必定难度。

后面咱们都将采用配置文件的方式,你们须要尽快熟悉和掌握。

 

kubectl apply 不但可以建立 Kubernetes 资源,也能对资源进行更新,很是方便。不过 Kubernets 还提供了几个相似的命令,例如 kubectl createkubectl replacekubectl edit kubectl patch

为避免形成没必要要的困扰,咱们会尽可能只使用 kubectl apply,

此命令已经可以应对超过 90% 的场景,事半功倍。

 

deployment yaml

 

既然要用 YAML 配置文件部署应用,如今就颇有必要了解一下 Deployment 的配置格式,其余 Controller(好比 DaemonSet)很是相似。

① apiVersion 是当前配置格式的版本。

  先执行kubectl api-resources找到全部的资源  

  在执行命令 kubectl explain deploy便可获取到版本和类型信息

  

② kind 是要建立的资源类型,这里是 Deployment。

③ metadata 是该资源的元数据,name 是必需的元数据项。

④ spec 部分是该 Deployment 的规格说明。

⑤ replicas 指明副本数量,默认为 1。

⑥ template 定义 Pod 的模板,这是配置文件的重要部分。

⑦ metadata 定义 Pod 的元数据,至少要定义一个 label。label 的 key 和 value 能够任意指定。

⑧ spec 描述 Pod 的规格,此部分定义 Pod 中每个容器的属性,name 和 image 是必需的。

 

此 nginx.yml 是一个最简单的 Deployment 配置文件,后面咱们学习 Kubernetes 各项功能时会逐步丰富这个文件。

 

执行 kubectl apply -f nginx.yml:

[root@ken ~]# kubectl apply -f nginx.yml
deployment.extensions/nginx-deployment created

 

查看nginx-deployment各类资源

[root@ken ~]# kubectl get deployment
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
httpd-ken          2/2     2            2           73m
nginx-deployment   2/2     2            2           107s
[root@ken ~]# kubectl get replicaset
NAME                          DESIRED   CURRENT   READY   AGE
httpd-ken-5c949b96f           2         2         2       54m
nginx-deployment-65998d8886   2         2         2       111s
[root@ken ~]# kubectl get pod -o wide
NAME                                READY   STATUS    RESTARTS   AGE    IP           NODE    NOMINATED NODE   READINESS GATES
httpd-ken-5c949b96f-9cd52           1/1     Running   0          54m    10.244.1.3   host1   <none>           <none>
httpd-ken-5c949b96f-twdsd           1/1     Running   0          54m    10.244.2.3   host2   <none>           <none>
nginx-deployment-65998d8886-9qrrv   1/1     Running   0          2m4s   10.244.2.4   host2   <none>           <none>
nginx-deployment-65998d8886-vnbgt   1/1     Running   0          2m4s   10.244.1.4   host1   <none>           <none>

 

Deployment、ReplicaSet、Pod 都已经就绪。若是要删除这些资源,执行 kubectl delete deployment nginx-deployment 或者 kubectl delete -f nginx.yml (编写的nginx.yml文件不会被删除)。

[root@ken ~]# kubectl delete -f nginx.yml
deployment.extensions "nginx-deployment" deleted

 

Scale Up/Down

 

伸缩(Scale Up/Down)是指在线增长或减小 Pod 的副本数。

Deployment nginx-deployment 初始是两个副本。

[root@ken ~]# kubectl apply -f nginx.yml
[root@ken ~]# kubectl get pod -o wide
NAME                                READY   STATUS    RESTARTS   AGE   IP           NODE    NOMINATED NODE   READINESS GATES
nginx-deployment-65998d8886-5b5rc   1/1     Running   0          84s   10.244.1.5   host1   <none>           <none>
nginx-deployment-65998d8886-tnpcx   1/1     Running   0          84s   10.244.2.5   host2   <none>           <none>

 

k8s-node1 和 k8s-node2 上各跑了一个副本。如今修改 nginx.yml,将副本改为 5 个。

 

再次执行kubectl apply

[root@ken ~]# kubectl apply -f nginx.yml
deployment.extensions/nginx-deployment configured

 

查看pod

[root@ken ~]# kubectl get pod -o wide
NAME                                READY   STATUS    RESTARTS   AGE     IP           NODE    NOMINATED NODE   READINESS GATES
nginx-deployment-65998d8886-4hfgp   1/1     Running   0          3m      10.244.1.7   host1   <none>           <none>
nginx-deployment-65998d8886-5b5rc   1/1     Running   0          5m48s   10.244.1.5   host1   <none>           <none>
nginx-deployment-65998d8886-btrsq   1/1     Running   0          3m      10.244.2.6   host2   <none>           <none>
nginx-deployment-65998d8886-tnpcx   1/1     Running   0          5m48s   10.244.2.5   host2   <none>           <none>
nginx-deployment-65998d8886-x4pbd   1/1     Running   0          3m      10.244.1.6   host1   <none>           <none>

 

三个新副本被建立并调度到 k8s-node1 和 k8s-node2 上。

 

接下来修改配置文件,将副本数减小为 3 个,从新执行 kubectl apply

[root@ken ~]# kubectl apply -f nginx.yml
deployment.extensions/nginx-deployment configured
[root@ken ~]# kubectl get pod -o wide
NAME                                READY   STATUS    RESTARTS   AGE     IP           NODE    NOMINATED NODE   READINESS GATES
nginx-deployment-65998d8886-5b5rc   1/1     Running   0          7m6s    10.244.1.5   host1   <none>           <none>
nginx-deployment-65998d8886-btrsq   1/1     Running   0          4m18s   10.244.2.6   host2   <none>           <none>
nginx-deployment-65998d8886-tnpcx   1/1     Running   0          7m6s    10.244.2.5   host2   <none>           <none>

能够看到两个副本被删除,最终保留了 3 个副本。

 

模拟故障

 

上面咱们有 3 个 nginx 副本分别运行在 k8s-node1 k8s-node2 上。如今模拟 k8s-node2 故障,关闭该节点(poweroff)。

首先查看节点

[root@ken ~]# kubectl get node
NAME    STATUS     ROLES    AGE     VERSION
host1   Ready      <none>   5h25m   v1.13.2
host2   NotReady   <none>   5h43m   v1.13.2
ken     Ready      master   6h18m   v1.13.2

发现host2状态为NotReady

 

等待一段时间,Kubernetes 会检查到 k8s-node2 不可用,将 k8s-node2 上的 Pod 标记为  Terminating状态,并在 k8s-node1 上新建立两个 Pod,维持总副本数为 3。

[root@ken ~]# kubectl get pod -o wide
NAME                                READY   STATUS        RESTARTS   AGE   IP           NODE    NOMINATED NODE   READINESS GATES
nginx-deployment-65998d8886-5b5rc   1/1     Running       0          16m   10.244.1.5   host1   <none>           <none>
nginx-deployment-65998d8886-8647d   1/1     Running       0          79s   10.244.1.8   host1   <none>           <none>
nginx-deployment-65998d8886-btrsq   1/1     Terminating   0          13m   10.244.2.6   host2   <none>           <none>
nginx-deployment-65998d8886-qp6jj   1/1     Running       0          79s   10.244.1.9   host1   <none>           <none>
nginx-deployment-65998d8886-tnpcx   1/1     Terminating   0          16m   10.244.2.5   host2   <none>           <none>

 

当 k8s-node2 恢复后, Terminating的 Pod 会被删除,不过已经运行的 Pod 不会从新调度回 k8s-node2

[root@ken ~]# kubectl get node
NAME    STATUS   ROLES    AGE     VERSION
host1   Ready    <none>   5h33m   v1.13.2
host2   Ready    <none>   5h51m   v1.13.2
ken     Ready    master   6h26m   v1.13.2
[root@ken ~]# kubectl get pod -o wide
NAME                                READY   STATUS    RESTARTS   AGE     IP           NODE    NOMINATED NODE   READINESS GATES
nginx-deployment-65998d8886-5b5rc   1/1     Running   0          19m     10.244.1.5   host1   <none>           <none>
nginx-deployment-65998d8886-8647d   1/1     Running   0          4m33s   10.244.1.8   host1   <none>           <none>
nginx-deployment-65998d8886-qp6jj   1/1     Running   0          4m33s   10.244.1.9   host1   <none>           <none>

 

删除 nginx-deployment:

[root@ken ~]# kubectl delete -f nginx.yml
deployment.extensions "nginx-deployment" deleted

 

 label 控制 Pod 的位置

 

默认配置下,Scheduler 会将 Pod 调度到全部可用的 Node。不过有些状况咱们但愿将 Pod 部署到指定的 Node,好比将有大量磁盘 I/O 的 Pod 部署到配置了 SSD 的 Node;或者 Pod 须要 GPU,须要运行在配置了 GPU 的节点上。

 

Kubernetes 是经过 label 来实现这个功能的。

 

label 是 key-value 对,各类资源均可以设置 label,灵活添加各类自定义属性。好比执行以下命令标注 k8s-node1 是配置了 SSD 的节点。

 

第一步:定义标签

disk为自定义字符串

[root@ken ~]# kubectl label node host1 disk=ssd

 

第二步:查看标签

[root@ken ~]# kubectl get node --show-labels
NAME    STATUS   ROLES    AGE   VERSION   LABELS
host1   Ready    <none>   8h    v1.13.2   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,disk=ssd,kubernetes.io/hostname=host1
host2   Ready    <none>   8h    v1.13.2   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/hostname=host2
ken     Ready    master   8h    v1.13.2   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/hostname=ken,node-role.kubernetes.io/master=

 

disk=ssd 已经成功添加到 host1,除了 disk,Node 还有几个 Kubernetes 本身维护的 label。

 

第三步:配置nginx.yml

有了 disk 这个自定义 label,接下来就能够指定将 Pod 部署到 host1。编辑 nginx.yml:

 

 

在 Pod 模板的 spec 里经过 nodeSelector 指定将此 Pod 部署到具备 label disktype=ssd Node 上。

注意:1. nodeSelector须要与containers位置保持一致

           2. S必须大写

 

第四步:部署

部署 Deployment

[root@ken ~]# kubectl apply -f nginx.yml
deployment.extensions/nginx-deployment created

 

第五步:查看 Pod 的运行节点

[root@ken ~]# kubectl get pod -o wide
NAME                                READY   STATUS              RESTARTS   AGE    IP       NODE    NOMINATED NODE   READINESS GATES
nginx-deployment-5d8db4598d-2gdmz   0/1     ContainerCreating   0          102s   <none>   host1   <none>           <none>
nginx-deployment-5d8db4598d-cq55q   0/1     ContainerCreating   0          102s   <none>   host1   <none>           <none>
nginx-deployment-5d8db4598d-qjh4x   0/1     ContainerCreating   0          102s   <none>   host1   <none>           <none>

 

所有 3个副本都运行在 host1 上,符合咱们的预期。

 

要删除 label disktype,执行以下命令:

 

kubectl label node k8s-node1 disktype-

- 即删除。

[root@ken ~]# kubectl label node host1 disk-
node/host1 labeled
[root@ken ~]# kubectl get node --show-labels
NAME    STATUS     ROLES    AGE   VERSION   LABELS
host1   NotReady   <none>   8h    v1.13.2   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/hostname=host1
host2   Ready      <none>   8h    v1.13.2   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/hostname=host2
ken     Ready      master   9h    v1.13.2   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/hostname=ken,node-role.kubernetes.io/master=

 

不过此时 Pod 并不会从新部署,依然在 host1 上运行。

[root@ken ~]# kubectl get pod -o wide
NAME                                READY   STATUS    RESTARTS   AGE   IP            NODE    NOMINATED NODE   READINESS GATES
nginx-deployment-5d8db4598d-2dbw9   1/1     Running   0          39s   10.244.1.12   host1   <none>           <none>
nginx-deployment-5d8db4598d-4brh5   1/1     Running   0          39s   10.244.1.11   host1   <none>           <none>
nginx-deployment-5d8db4598d-p87mj   1/1     Running   0          39s   10.244.1.13   host1   <none>           <none>

 

除非在 nginx.yml 中删除 nodeSelector 设置,而后经过 kubectl apply 从新部署。

不须要删除以前的deployment,直接部署便可

Kubernetes 本身会删除以前的 Pod 并调度和运行新的 Pod。

[root@ken ~]# kubectl apply -f nginx.yml
[root@ken ~]# kubectl get pod -o wide
NAME                                READY   STATUS        RESTARTS   AGE   IP            NODE    NOMINATED NODE   READINESS GATES
nginx-deployment-5d8db4598d-p87mj   0/1     Terminating   0          2m    10.244.1.13   host1   <none>           <none>
nginx-deployment-65998d8886-t5nmv   1/1     Running       0          7s    10.244.2.9    host2   <none>           <none>
nginx-deployment-65998d8886-wz7c2   1/1     Running       0          4s    10.244.2.10   host2   <none>           <none>
nginx-deployment-65998d8886-xdlz4   1/1     Running       0          6s    10.244.1.14   host1   <none>           <none>
相关文章
相关标签/搜索