之前文章中我们都是用POD部署应用,特别是用POD部署应用时如果要更新应用程序,必须先更新镜像(Image)/配置(ConfigMap),删除POD再重新部署应用程序才能整整的更新。Kubernetes提供了更高级的应用部署和升级方法。
使用ReplicationController部署应用
如果用ReplicationController(RC)部署的应用可以通过RC
update来更新应用。 具体的kubia-rc.yaml文件如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 apiVersion: v1 kind: ReplicationController metadata: name: kubia spec: replicas: 3 selector: app: kubia template: metadata: name: kubia labels: app: kubia spec: containers: - name: kubia image: 172.17 .0 .1 :5000/kubia:v1 ports: - containerPort: 3000
使用kubectl create -f kubia-rc.yaml
创建RC,部署成功以后即可看到根据RC的配置会产生3个副本kubectl get rc,po
。
1 2 3 4 5 6 7 8 9 kubectl get po,rc NAME READY STATUS RESTARTS AGE pod/kubia-bqszw 1/1 Running 0 62s pod/kubia-c4cb9 1/1 Running 0 62s pod/kubia-wxj55 1/1 Running 0 62s NAME DESIRED CURRENT READY AGE replicationcontroller/kubia 3 3 3 62s
当前POD到到镜像版本为v1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 kubectl describe po Name: kubia-bqszw Namespace: default Priority: 0 Node: minikube/172.17.0.3 Start Time: Wed, 14 Oct 2020 20:29:56 +0800 Labels: app=kubia Annotations: <none> Status: Running IP: 172.18.0.3 IPs: IP: 172.18.0.3 Controlled By: ReplicationController/kubia Containers: kubia: Container ID: docker://ec65afaeea2e8726530863981512165bec02ceb8e953a3d6575f6ea4ad7cc3f3 Image: 172.17.0.1:5000/kubia:v1 Image ID: docker-pullable://172.17.0.1:5000/kubia@sha256:0a9705988c08da5cc4fd535f40216a7b0ef89325b594ddb97ffcbd220c6731f1 ...
通过kubectl set image rc/kubia kubia=172.17.0.1:5000/kubia:v2
更新镜像。此时的应用程序并不会自动更新。当POD
异常或者手工删除以后RC 会自动拉起一个POD ,保证POD的副本数和RC
中配置的一致,此时新的POD 就是使用新的镜像创建应用,也就是说有的POD
使用新的镜像,有的POD
使用老的镜像。可以通过kubectl describe po
查询到POD中容器的镜像版本不同。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 kubectl describe po Name: kubia-c4cb9 Namespace: default Priority: 0 Node: minikube/172.17.0.3 Start Time: Wed, 14 Oct 2020 20:29:56 +0800 Labels: app=kubia Annotations: <none> Status: Running IP: 172.18.0.4 IPs: IP: 172.18.0.4 Controlled By: ReplicationController/kubia Containers: kubia: Container ID: docker://2b259af30a0c75987f027ac4516a7ea368774bbac4259a732f8141fdbcae376a Image: 172.17.0.1:5000/kubia:v1 Image ID: docker-pullable://172.17.0.1:5000/kubia@sha256:0a9705988c08da5cc4fd535f40216a7b0ef89325b594ddb97ffcbd220c6731f1 Port: 3000/TCP Host Port: 0/TCP State: Running Started: Wed, 14 Oct 2020 20:30:04 +0800 Ready: True Restart Count: 0 Environment: <none> Mounts: /var/run/secrets/kubernetes.io/serviceaccount from default-token-d2hsm (ro) Conditions: Type Status Initialized True Ready True ContainersReady True PodScheduled True Volumes: default-token-d2hsm: Type: Secret (a volume populated by a Secret) SecretName: default-token-d2hsm Optional: false QoS Class: BestEffort Node-Selectors: <none> Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s node.kubernetes.io/unreachable:NoExecute op=Exists for 300s Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 6m43s default-scheduler Successfully assigned default/kubia-c4cb9 to minikube Normal Pulled 6m36s kubelet Container image "172.17.0.1:5000/kubia:v1" already present on machine Normal Created 6m36s kubelet Created container kubia Normal Started 6m35s kubelet Started container kubia Name: kubia-s6822 ‹--自动使用新的镜像创建新的POD Namespace: default Priority: 0 Node: minikube/172.17.0.3 Start Time: Wed, 14 Oct 2020 20:35:57 +0800 Labels: app=kubia Annotations: <none> Status: Running IP: 172.18.0.6 IPs: IP: 172.18.0.6 Controlled By: ReplicationController/kubia Containers: kubia: Container ID: docker://91fd664961c798256afbfd9b2e6cd47697a817f27803812da26e28d56212371e Image: 172.17.0.1:5000/kubia:v2 Image ID: docker-pullable://172.17.0.1:5000/kubia@sha256:0709bbd6e3a34f306a16207b79b045e6a4bf33c22a3e7a88404166caee41e51f Port: 3000/TCP Host Port: 0/TCP State: Running Started: Wed, 14 Oct 2020 20:36:02 +0800 Ready: True Restart Count: 0 Environment: <none> Mounts: /var/run/secrets/kubernetes.io/serviceaccount from default-token-d2hsm (ro) Conditions: Type Status Initialized True Ready True ContainersReady True PodScheduled True Volumes: default-token-d2hsm: Type: Secret (a volume populated by a Secret) SecretName: default-token-d2hsm Optional: false QoS Class: BestEffort Node-Selectors: <none> Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s node.kubernetes.io/unreachable:NoExecute op=Exists for 300s Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 42s default-scheduler Successfully assigned default/kubia-s6822 to minikube Normal Pulled 38s kubelet Container image "172.17.0.1:5000/kubia:v2" already present on machine Normal Created 37s kubelet Created container kubia Normal Started 37s kubelet Started container kubia Name: kubia-wxj55 Namespace: default Priority: 0 Node: minikube/172.17.0.3 Start Time: Wed, 14 Oct 2020 20:29:56 +0800 Labels: app=kubia Annotations: <none> Status: Running IP: 172.18.0.2 IPs: IP: 172.18.0.2 Controlled By: ReplicationController/kubia Containers: kubia: Container ID: docker://a5195a7ec8573d429445f7c79218372abc887d360b3564c8659b600c236c0248 Image: 172.17.0.1:5000/kubia:v1 Image ID: docker-pullable://172.17.0.1:5000/kubia@sha256:0a9705988c08da5cc4fd535f40216a7b0ef89325b594ddb97ffcbd220c6731f1 Port: 3000/TCP Host Port: 0/TCP State: Running Started: Wed, 14 Oct 2020 20:30:04 +0800 Ready: True Restart Count: 0 Environment: <none> Mounts: /var/run/secrets/kubernetes.io/serviceaccount from default-token-d2hsm (ro) Conditions: Type Status Initialized True Ready True ContainersReady True PodScheduled True Volumes: default-token-d2hsm: Type: Secret (a volume populated by a Secret) SecretName: default-token-d2hsm Optional: false QoS Class: BestEffort Node-Selectors: <none> Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s node.kubernetes.io/unreachable:NoExecute op=Exists for 300s Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 6m44s default-scheduler Successfully assigned default/kubia-wxj55 to minikube Normal Pulled 6m36s kubelet Container image "172.17.0.1:5000/kubia:v1" already present on machine Normal Created 6m36s kubelet Created container kubia Normal Started 6m35s kubelet Started container kubia
使用ReplicationController部署应用,需要手工选择POD
逐一进行升级。实际部署应用过程中我们希望这个过程可以可控、且自动完成,这就需要通过更高级更高级的概念来部署应用。
使用Deployment部署应用
Kubernetes提供更高级的概念来实现应用的部署、滚动升级以及回滚。一个典型的kubernetes的应用会包含:POD、RepliciaSet以及Deployment。他们之间的关系如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 apiVersion: apps/v1 kind: Deployment metadata: name: kubia spec: replicas: 3 selector: matchLabels: app: kubia template: metadata: labels: app: kubia spec: containers: - name: kubia image: 172.17 .0 .1 :5000/kubia:v1
还是上面的例子,这次将ReplicationController的yaml文件中kinde替换城Deployment,并另存为kubia-deploymnent.yaml,使用kubectl create -f kubia-deployment.yaml
重新部署应用,部署成功以后可以功过kubectl get po,rs,deployment
查询部署的应用情况。
1 2 3 4 5 6 7 8 9 10 11 12 kubectl get po,rs,deployment NAME READY STATUS RESTARTS AGE pod/kubia-7fc889c9c9-b7b8f 1/1 Running 1 21h pod/kubia-7fc889c9c9-lp7m8 1/1 Running 1 21h pod/kubia-7fc889c9c9-qkz9w 1/1 Running 1 21h NAME DESIRED CURRENT READY AGE replicaset.apps/kubia-7fc889c9c9 3 3 3 21h NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/kubia 3/3 3 3 21h
通过kubectl descibe po
查询到POD到详细情况如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 kubectl describe po Name: kubia-7fc889c9c9-b7b8f Namespace: default Priority: 0 Node: minikube/172.17.0.3 Start Time: Tue, 13 Oct 2020 22:44:19 +0800 Labels: app=kubia pod-template-hash=7fc889c9c9 Annotations: <none> Status: Running IP: 172.18.0.2 IPs: IP: 172.18.0.2 Controlled By: ReplicaSet/kubia-7fc889c9c9 Containers: kubia: Container ID: docker://aa524c986c27e53d12961173a5a0adf43a3554e13aeac5fc1c5cca083da09271 Image: 172.17.0.1:5000/kubia:v1 ‹-- 镜像版本是v1 Image ID: docker-pullable://172.17.0.1:5000/kubia@sha256:0a9705988c08da5cc4fd535f40216a7b0ef89325b594ddb97ffcbd220c6731f1 ...
更新应用
kubectl set image deployment/kubia kubia=172.17.0.1:5000/kubia:v2
设置完成以后deployment会自动滚动升级,可以通过kubectl rollout deployment/kubia status
查询升级状态,此时查询应用部署的详情可以看到PO,RS更新中或者已经更新成功。
kubectl get po,rs,deployment
其中存在2个rs,一个升级前的rs,一个是当前到rs。
1 2 3 4 5 6 7 8 9 10 11 12 13 kubectl get po,rs,deployment NAME READY STATUS RESTARTS AGE pod/kubia-7fc889c9c9-b7b8f 1/1 Running 1 21h pod/kubia-7fc889c9c9-lp7m8 1/1 Running 1 21h pod/kubia-7fc889c9c9-qkz9w 1/1 Running 1 21h pod/kubia-84ddcd9474-bv8fl 0/1 ContainerCreating 0 3s ‹-- 新建POD NAME DESIRED CURRENT READY AGE replicaset.apps/kubia-7fc889c9c9 3 3 3 21h ‹-- 升级前的rs replicaset.apps/kubia-84ddcd9474 1 1 0 4s ‹-- 当前的rs NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/kubia 3/3 1 3 21h
查询POD详细信息,可以看到新建到POD已经更新为新到镜像。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 kubectl describe po kubia-84ddcd9474-bv8fl ‹-- 新建POD Name: kubia-84ddcd9474-bv8fl Namespace: default Priority: 0 Node: minikube/172.17.0.3 Start Time: Wed, 14 Oct 2020 20:19:12 +0800 Labels: app=kubia pod-template-hash=84ddcd9474 Annotations: <none> Status: Running IP: 172.18.0.6 IPs: IP: 172.18.0.6 Controlled By: ReplicaSet/kubia-84ddcd9474 Containers: kubia: Container ID: docker://3de190659e28bebcde082b287c7c4c434ab706c08654f6d1c7db3db455304508 Image: 172.17.0.1:5000/kubia:v2 ‹-- 镜像版本是v2 Image ID: docker-pullable://172.17.0.1:5000/kubia@sha256:0709bbd6e3a34f306a16207b79b045e6a4bf33c22a3e7a88404166caee41e51f
此时如果使用kubectl rollout undo deployment/kubia
即可全部回滚应用,可以通过kubectl rollout
pause/resume/restart/history等控制滚动升级过程(如果测试过程中难以观察到升级过程,可以讲deployment中副本数量调高)。
此外,也可以使用StatefulSet部署有状态应用。StatefulSet和Deployment最大的区别是为每个副本POD实例提供店里存储,可以保证POD副本有固定的名字和主机,可以按照预期的顺序启停POD副本。