Kubernetes部署和升级应用

之前文章中我们都是用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副本。

Kubernetes部署和升级应用

http://mixiang.tech/2020/10/14/2020-10-14-19/

作者

Mixion

发布于

2020-10-14

更新于

2022-12-02

许可协议