Deployment
1 创建
一个 Deployment 拥有多个 Replica Set,而一个 Replica Set 拥有一个或多个 Pod。一个 Deployment 控制多个 rs 主要是为了支持回滚机制,每当 Deployment 操作时,Kubernetes 会重新生成一个 Replica Set 并保留,以后有需要的话就可以回滚至之前的状态。 下面创建一个 Deployment,它创建了一个 Replica Set 来启动 3 个 nginx pod,yaml 文件如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deploy
labels:
k8s-app: nginx-demo
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
将上面内容保存为:nginx-deployment.yaml,执行命令:
$ kubectl create -f nginx-deployment.yaml
deployment "nginx-deploy" created
然后执行一下命令查看刚刚创建的 Deployment:
$ kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
nginx-deploy 3 0 0 0 1s
隔一会再次执行上面命令:
$ kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
nginx-deploy 3 3 3 3 4m
我们可以看到 Deployment 已经创建了 1 个 Replica Set 了,执行下面的命令查看 rs 和 pod:
$ kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deploy-431080787 3 3 3 6m
$ kubectl get pod --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx-deploy-431080787-53z8q 1/1 Running 0 7m app=nginx,pod-template-hash=431080787
nginx-deploy-431080787-bhhq0 1/1 Running 0 7m app=nginx,pod-template-hash=431080787
nginx-deploy-431080787-sr44p 1/1 Running 0 7m app=nginx,pod-template-hash=431080787
上面的 Deployment 的 yaml 文件中的replicas:3
将会保证我们始终有 3 个 POD 在运行。
2 滚动升级
现在我们将刚刚保存的 yaml 文件中的 nginx 镜像修改为nginx:1.13.3
,然后在 spec 下面添加滚动升级策略:
minReadySeconds: 5
strategy:
# indicate which strategy we want for rolling update
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
minReadySeconds:
Kubernetes 在等待设置的时间后才进行升级
如果没有设置该值,Kubernetes 会假设该容器启动起来后就提供服务了
如果没有设置该值,在某些极端情况下可能会造成服务不正常运行
maxSurge:
升级过程中最多可以比原先设置多出的 POD 数量
例如:maxSurage=1,replicas=5,则表示 Kubernetes 会先启动 1 一个新的 Pod 后才删掉一个旧的 POD,整个升级过程中最多会有 5+1 个 POD。
maxUnavaible:
升级过程中最多有多少个 POD 处于无法提供服务的状态
当
maxSurge
不为 0 时,该值也不能为 0例如:maxUnavaible=1,则表示 Kubernetes 整个升级过程中最多会有 1 个 POD 处于无法服务的状态。
然后执行命令:
$ kubectl apply -f nginx-deployment.yaml
deployment "nginx-deploy" configured
然后我们可以使用rollout
命令:
查看状态:
$ kubectl rollout status deployment/nginx-deploy Waiting for rollout to finish: 1 out of 3 new replicas have been updated.. deployment "nginx-deploy" successfully rolled out
暂停升级
$ kubectl rollout pause deployment <deployment>
继续升级
$ kubectl rollout resume deployment <deployment>
升级结束后,继续查看 rs 的状态:
$ kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deploy-2078889897 0 0 0 47m
nginx-deploy-3297445372 3 3 3 42m
nginx-deploy-431080787 0 0 0 1h
根据 AGE 我们可以看到离我们最近的当前状态是:3,和我们的 yaml 文件是一致的,证明升级成功了。用describe
命令可以查看升级的全部信息:
Name: nginx-deploy
Namespace: default
CreationTimestamp: Wed, 18 Oct 2017 16:58:52 +0800
Labels: k8s-app=nginx-demo
Annotations: deployment.kubernetes.io/revision=3
kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"labels":{"k8s-app":"nginx-demo"},"name":"nginx-deploy","namespace":"defa...
Selector: app=nginx
Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: app=nginx
Containers:
nginx:
Image: nginx:1.13.3
Port: 80/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Progressing True NewReplicaSetAvailable
Available True MinimumReplicasAvailable
OldReplicaSets: <none>
NewReplicaSet: nginx-deploy-3297445372 (3/3 replicas created)
Events:
FirstSeen LastSeen Count From SubObjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
50m 50m 1 deployment-controller Normal ScalingReplicaSet Scaled up replica set nginx-deploy-2078889897 to 1
45m 45m 1 deployment-controller Normal ScalingReplicaSet Scaled down replica set nginx-deploy-2078889897 to 0
45m 45m 1 deployment-controller Normal ScalingReplicaSet Scaled up replica set nginx-deploy-3297445372 to 1
39m 39m 1 deployment-controller Normal ScalingReplicaSet Scaled down replica set nginx-deploy-431080787 to 2
39m 39m 1 deployment-controller Normal ScalingReplicaSet Scaled up replica set nginx-deploy-3297445372 to 2
38m 38m 1 deployment-controller Normal ScalingReplicaSet Scaled down replica set nginx-deploy-431080787 to 1
38m 38m 1 deployment-controller Normal ScalingReplicaSet Scaled up replica set nginx-deploy-3297445372 to 3
38m 38m 1 deployment-controller Normal ScalingReplicaSet Scaled down replica set nginx-deploy-431080787 to 0
3 回滚 Deployment
我们已经能够滚动平滑的升级我们的 Deployment 了,但是如果升级后的 POD 出了问题该怎么办?我们能够想到的最好最快的方式当然是回退到上一次能够提供正常工作的版本,Deployment 就为我们提供了回滚机制。
首先,查看 Deployment 的升级历史:
$ kubectl rollout history deployment nginx-deploy
deployments "nginx-deploy"
REVISION CHANGE-CAUSE
1 <none>
2 <none>
3 kubectl apply --filename=Desktop/nginx-deployment.yaml --record=true
从上面的结果可以看出在执行Deployment
升级的时候最好带上record
参数,便于我们查看历史版本信息。
默认情况下,所有通过kubectl xxxx --record
都会被kubernetes
记录到etcd
进行持久化,这无疑会占用资源,最重要的是,时间久了,当你kubectl get rs
时,会有成百上千的垃圾RS
返回给你,那时你可能就眼花缭乱了。
上生产时,我们最好通过设置 Deployment 的.spec.revisionHistoryLimit
来限制最大保留的revision number
,比如 15 个版本,回滚的时候一般只会回滚到最近的几个版本就足够了。其实rollout history
中记录的revision
都和ReplicaSets
一一对应。如果手动delete
某个 ReplicaSet,对应的rollout history
就会被删除,也就是还说你无法回滚到这个revison
了。
rollout history
和ReplicaSet
的对应关系,可以在kubectl describe rs $RSNAME
返回的revision
字段中得到,这里的revision
就对应着rollout history
返回的revison
。
同样我们可以使用下面的命令查看单个revison
的信息:
$ kubectl rollout history deployment nginx-deploy --revision=3
deployments "nginx-deploy" with revision #3
Pod Template:
Labels: app=nginx
pod-template-hash=3297445372
Annotations: kubernetes.io/change-cause=kubectl apply --filename=nginx-deployment.yaml --record=true
Containers:
nginx:
Image: nginx:1.13.3
Port: 80/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
假如现在要直接回退到当前版本的前一个版本:
$ kubectl rollout undo deployment nginx-deploy
deployment "nginx-deploy" rolled back
当然也可以用revision
回退到指定的版本:
$ kubectl rollout undo deployment nginx-deploy --to-revision=2
deployment "nginx-deploy" rolled back
现在可以用命令查看 Deployment 现在的状态了。
Last updated