k8s運行容器之deployment(三)

deployment

我們已經(jīng)知道k8s是通過各種controller來管理pod的生命周期。為了滿足不同業(yè)務(wù)場景,k8s開發(fā)了Deployment、ReplicaSet、DaemonSet、StatefuleSet、Job 等多種 Controller。我們首先學(xué)習(xí)最常用的 Deployment。

運行一個deployment

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

下面詳細分析 Kubernetes 都做了些什么工作。

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

kubectl get deplouyment命令可以查看 httpd-ken 的狀態(tài),輸出顯示兩個副本正常運行。

接下來我們用 kubectl describe deployment 了解更詳細的信息。

[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

大部分內(nèi)容都是自解釋的,我們重點看最下面部分。這里告訴我們創(chuàng)建了一個 ReplicaSet httpd-ken-5c949b96,Events 是 Deployment 的日志,記錄了 ReplicaSet 的啟動過程。

通過上面的分析,也驗證了 Deployment 通過 ReplicaSet 來管理 Pod 的事實。接著我們將注意力切換到 httpd-ken-5c949b96,執(zhí)行 kubectl describe replicaset:

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

兩個副本已經(jīng)就緒,用 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 創(chuàng)建。Events 記錄了兩個副本 Pod 的創(chuàng)建。接著我們來看 Pod,執(zhí)行 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 狀態(tài),用 kubectl describe pod 查看更詳細的信息:

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創(chuàng)建。Events 記錄了 Pod 的啟動過程。如果操作失?。ū热?image 不存在),也能在這里查看到原因。

總結(jié)一下這個過程:

用戶通過 kubectl 創(chuàng)建 Deployment。

Deployment 創(chuàng)建 ReplicaSet。

ReplicaSet 創(chuàng)建 Pod

也可以看出,對象的命名方式是:子對象的名字 = 父對象名字 + 隨機字符串或數(shù)字。

命令vs配置文件

k8s支持兩種創(chuàng)建資源的方式:

1.用 kubectl 命令直接創(chuàng)建,比如:

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

在命令行中通過參數(shù)指定資源的屬性。

2. 通過配置文件和 kubectl apply 創(chuàng)建,要完成前面同樣的工作,可執(zhí)行命令:

kubectl apply -f nginx.yml

nginx.yml 的內(nèi)容為:

image

資源的屬性寫在配置文件中,文件格式為 YAML。

下面對這兩種方式進行比較。

基于命令的方式:

簡單直觀快捷,上手快。

適合臨時測試或?qū)嶒灐?/p>

基于配置文件的方式:

配置文件描述了 What,即應(yīng)用最終要達到的狀態(tài)。

配置文件提供了創(chuàng)建資源的模板,能夠重復(fù)部署。

可以像管理代碼一樣管理部署。

適合正式的、跨環(huán)境的、規(guī)?;渴稹?/p>

這種方式要求熟悉配置文件的語法,有一定難度。

后面我們都將采用配置文件的方式,大家需要盡快熟悉和掌握。

kubectl apply 不但能夠創(chuàng)建 Kubernetes 資源,也能對資源進行更新,非常方便。不過 Kubernets 還提供了幾個類似的命令,例如 kubectl create、kubectl replace、kubectl edit 和 kubectl patch。

為避免造成不必要的困擾,我們會盡量只使用 kubectl apply,

此命令已經(jīng)能夠應(yīng)對超過 90% 的場景,事半功倍。

deployment yaml

既然要用 YAML 配置文件部署應(yīng)用,現(xiàn)在就很有必要了解一下 Deployment 的配置格式,其他 Controller(比如 DaemonSet)非常類似。

image

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

先執(zhí)行kubectl api-resources找到所有的資源

在執(zhí)行命令 kubectl explain deploy即可獲取到版本和類型信息

image

② kind 是要創(chuàng)建的資源類型,這里是 Deployment。

③ metadata 是該資源的元數(shù)據(jù),name 是必需的元數(shù)據(jù)項。

④ spec 部分是該 Deployment 的規(guī)格說明。

⑤ replicas 指明副本數(shù)量,默認為 1。

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

⑦ metadata 定義 Pod 的元數(shù)據(jù),至少要定義一個 label。label 的 key 和 value 可以任意指定。

⑧ spec 描述 Pod 的規(guī)格,此部分定義 Pod 中每一個容器的屬性,name 和 image 是必需的。

注意:最后name前面加個橫線是因為container后面是一個列表

此 nginx.yml 是一個最簡單的 Deployment 配置文件,后面我們學(xué)習(xí) Kubernetes 各項功能時會逐步豐富這個文件。

執(zhí)行 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 都已經(jīng)就緒。如果要刪除這些資源,執(zhí)行 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 的副本數(shù)。

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 上各跑了一個副本?,F(xiàn)在修改 nginx.yml,將副本改成 5 個。

image

再次執(zhí)行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>

三個新副本被創(chuàng)建并調(diào)度到 k8s-node1 和 k8s-node2 上。

接下來修改配置文件,將副本數(shù)減少為 3 個,重新執(zhí)行 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 上?,F(xiàn)在模擬 k8s-node2 故障,關(guān)閉該節(jié)點(poweroff)。

首先查看節(jié)點

[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

發(fā)現(xiàn)host2狀態(tài)為NotReady

等待一段時間,Kubernetes 會檢查到 k8s-node2 不可用,將 k8s-node2 上的 Pod 標記為 Terminating狀態(tài),并在 k8s-node1 上新創(chuàng)建兩個 Pod,維持總副本數(shù)為 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 恢復(fù)后, Terminating的 Pod 會被刪除,不過已經(jīng)運行的 Pod 不會重新調(diào)度回 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 調(diào)度到所有可用的 Node。不過有些情況我們希望將 Pod 部署到指定的 Node,比如將有大量磁盤 I/O 的 Pod 部署到配置了 SSD 的 Node;或者 Pod 需要 GPU,需要運行在配置了 GPU 的節(jié)點上。

Kubernetes 是通過 label 來實現(xiàn)這個功能的。

label 是 key-value 對,各種資源都可以設(shè)置 label,靈活添加各種自定義屬性。比如執(zhí)行如下命令標注 k8s-node1 是配置了 SSD 的節(jié)點。

第一步:定義標簽

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 已經(jīng)成功添加到 host1,除了 disk,Node 還有幾個 Kubernetes 自己維護的 label。

第三步:配置nginx.yml

有了 disk 這個自定義 label,接下來就可以指定將 Pod 部署到 host1。編輯 nginx.yml:

image

在 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 的運行節(jié)點

[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 上,符合我們的預(yù)期。

要刪除 label disktype,執(zhí)行如下命令:

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 設(shè)置,然后通過 kubectl apply 重新部署。

不需要刪除之前的deployment,直接部署即可

Kubernetes 自己會刪除之前的 Pod 并調(diào)度和運行新的 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      

文章轉(zhuǎn)自:http://www.kendd.cn/?p=685

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容