Deployment 简介
deployment 是用来管理无状态应用的,面向的集群的管理,而不是面向的是一个不可变的个体,举例:有一群鸭子,要吃掉一个,只需要再放一个新的鸭仔就好了,不会影响什么,而有状态的应用,就同时养三条狗一样,而每个狗都是无法代替用新的事物代替的,因为有“感情”这个状态在里面。
Deployment 为Pod 和 ReplicaSet 之上,提供了一个声明式定义(declarative)方法,用来替代以前的ReplicationController 来方便的管理应用。
你只需要在 Deployment 中描述您想要的目标状态是什么,Deployment controller 就会帮您将 Pod 和ReplicaSet 的实际状态改变到您的目标状态。您可以定义一个全新的 Deployment 来
创建 ReplicaSet 或者删除已有的 Deployment 并创建一个新的来替换。也就是说Deployment是可以管理多个ReplicaSet的,如下图:
典型的应用场景包括:
- 定义Deployment来创建Pod和ReplicaSet,使用Deployment来创建ReplicaSet。ReplicaSet在后台创建pod。检查启动状态,看它是成功还是失败。
- 然后,通过更新Deployment的PodTemplateSpec字段来声明Pod的新状态。这会创建一个新的ReplicaSet,Deployment会按照控制的速率将pod从旧的ReplicaSet移动到新d的ReplicaSet中。
- 如果当前状态不稳定,回滚到之前的Deployment revision。每次回滚都会更新Deployment的revision。
- 扩容Deployment以满足更高的负载。
- 暂停Deployment来应用PodTemplateSpec的多个修复,然后恢复上线。
- 根据Deployment 的状态判断上线是否hang住了。
- 清除旧的不必要的 ReplicaSet。
Deployment 升级
kubectl explain deploy.spec.strategy 策略订是配置怎么滚动升级的,支持两种策略:
- Recreate 重建式更新,就是删一个建一个。
- rollingUpdate 滚动更新,简单定义 更新期间pod最多有几个等
rollingUpdate 有两种策略
- maxSurge 指定超出副本数有几个,两种方式:1、指定数量 2、百分比
- maxUnavailable 最多有几个不可用
Deployment 历史版本
kubectl explain deploy.spec.revisionHistoryLimit
最多保存多少个历史版本,默认是10个
Deployment 模板
kubectl explain deploy.spec.template
通过template 创建我们的目标状态
类似pod的定义(包含 spec 、 metadata)
spec <Object> Specification of the desired behavior of the pod. More info: https:// git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status/ metadata <Object> Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata
案例:
apiVersion: apps/v1 kind: Deployment metadata: name: myapp-deploy namespace: default spec: replicas: 2 selector: matchLabels: app: myapp release: dev template: metadata: labels: app: myapp release: dev spec: containers: - name: myapp-containers image: ikubernetes/myapp:v1 ports: - name: http containerPort: 80
结果
看一下deploy 是否成功 $ kubectl get deploy NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE myapp-deploy 2 2 2 2 2m 因为deploy 是三层架构 现在会自动启动一个replicasets 我们看一下是否启动 $ kubectl get rs NAME DESIRED CURRENT READY AGE myapp-deploy-f4bcc4799 2 2 2 5m 我们看自动创建一个rs.名称后面的字符串是 模板的哈希值。是不会发生变化的,最后pod的是随机值 我们再看一下最后一层,最后一层为pod $ kubectl get pods NAME READY STATUS RESTARTS AGE myapp-deploy-f4bcc4799-cs5xc 1/1 Running 0 7m myapp-deploy-f4bcc4799-k4tq5 1/1 Running 0 7m
滚动升级案例:
我们通过修改yaml的方式升级
apiVersion: apps/v1 kind: Deployment metadata: name: myapp-deploy namespace: default spec: replicas: 5 selector: matchLabels: app: myapp release: dev template: metadata: labels: app: myapp release: dev spec: containers: - name: myapp-containers image: ikubernetes/myapp:v2 ports: - name: http containerPort: 80
升级过程(我们看到,是停止一台,升级一台的这种循环。)
kubectl get pods -l app=myapp -w NAME READY STATUS RESTARTS AGE myapp-deploy-f4bcc4799-cs5xc 1/1 Running 0 23m myapp-deploy-f4bcc4799-cwzd9 1/1 Running 0 14m myapp-deploy-f4bcc4799-k4tq5 1/1 Running 0 23m myapp-deploy-f4bcc4799-shbmb 1/1 Running 0 14m myapp-deploy-f4bcc4799-vtk6m 1/1 Running 0 14m myapp-deploy-f4bcc4799-shbmb 1/1 Terminating 0 16m myapp-deploy-869b888f66-mv5c6 0/1 Pending 0 0s myapp-deploy-869b888f66-mv5c6 0/1 Pending 0 0s myapp-deploy-869b888f66-vk9j6 0/1 Pending 0 0s myapp-deploy-869b888f66-vk9j6 0/1 Pending 0 0s myapp-deploy-869b888f66-mv5c6 0/1 ContainerCreating 0 0s myapp-deploy-869b888f66-r57t5 0/1 Pending 0 0s myapp-deploy-869b888f66-r57t5 0/1 Pending 0 0s myapp-deploy-869b888f66-vk9j6 0/1 ContainerCreating 0 1s myapp-deploy-869b888f66-r57t5 0/1 ContainerCreating 0 1s myapp-deploy-869b888f66-r57t5 0/1 ContainerCreating 0 1s myapp-deploy-869b888f66-mv5c6 0/1 ContainerCreating 0 1s myapp-deploy-869b888f66-vk9j6 0/1 ContainerCreating 0 2s myapp-deploy-f4bcc4799-shbmb 0/1 Terminating 0 16m myapp-deploy-f4bcc4799-shbmb 0/1 Terminating 0 16m myapp-deploy-869b888f66-r57t5 1/1 Running 0 4s myapp-deploy-f4bcc4799-vtk6m 1/1 Terminating 0 16m myapp-deploy-869b888f66-rxzbb 0/1 Pending 0 1s myapp-deploy-869b888f66-rxzbb 0/1 Pending 0 1s myapp-deploy-869b888f66-rxzbb 0/1 ContainerCreating 0 1s myapp-deploy-869b888f66-vk9j6 1/1 Running 0 5s myapp-deploy-f4bcc4799-cwzd9 1/1 Terminating 0 16m myapp-deploy-869b888f66-vvwwv 0/1 Pending 0 0s myapp-deploy-869b888f66-vvwwv 0/1 Pending 0 0s .....
我们查看一下 rs的情况 以下可以看到原的rs作为备份,而现在是启动新的rs
$ kubectl get rs -o wide NAME DESIRED CURRENT READY AGE CONTAINER(S) IMAGE(S) SELECTOR myapp-deploy-869b888f66 5 5 5 3m myapp-containers ikubernetes/myapp:v2 app=myapp,pod-template-hash=4256444922,release=dev myapp-deploy-f4bcc4799 0 0 0 29m myapp-containers ikubernetes/myapp:v1 app=myapp,pod-template-hash=906770355,release=dev
修改滚动升级策略
$ kubectl patch deplop myapp-deploy -p '{"spec":{"strategy":{"rollingUpdate":{"maxSurge":1,"maxUnavailable":0}}}}'
$ kubectl describe deploy myapp-deploy
Name: myapp-deploy
Namespace: default
CreationTimestamp: Tue, 28 Aug 2018 09:52:03 -0400
Labels: app=myapp
release=dev
Annotations: deployment.kubernetes.io/revision=4
kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"name":"myapp-deploy","namespace":"default"},"spec":{"replicas":3,"selector":{...
Selector: app=myapp,release=dev
Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 0 max unavailable, 1 max surge
Pod Template:
....
金丝雀发布
##通过 set image 发布新的镜像 也可以通过yaml文件发布 myapp-containers 是containers 的名称 $ kubectl set image deploy myapp-deploy myapp-containers=ikubernetes/myapp:v3 && kubectl rollout pause deploy myapp-deploy deployment "myapp-deploy" image updated deployment "myapp-deploy" paused #查看更新情况(新增加一个资源,但是没执行。是因为pause暂停命令,所以发布一个,这样形成了金丝雀发布,这个金丝雀就是让真实用户验证的) $ kubectl get pods -l app=myapp -w NAME READY STATUS RESTARTS AGE myapp-deploy-869b888f66-dpwvk 1/1 Running 0 24m myapp-deploy-869b888f66-frspv 1/1 Running 0 24m myapp-deploy-869b888f66-sgsll 1/1 Running 0 24m myapp-deploy-7cbd5b69b9-5s4sq 0/1 Pending 0 0s myapp-deploy-7cbd5b69b9-5s4sq 0/1 Pending 0 0s myapp-deploy-7cbd5b69b9-5s4sq 0/1 ContainerCreating 0 1s myapp-deploy-7cbd5b69b9-5s4sq 0/1 ContainerCreating 0 2s myapp-deploy-7cbd5b69b9-5s4sq 1/1 Running 0 19s #那个金丝雀没问题,可以发布后续的更新了 kubectl rollout resume deploy myapp-deploy #查看更新情况 kubectl get pods -l app=myapp -w NAME READY STATUS RESTARTS AGE myapp-deploy-869b888f66-dpwvk 1/1 Running 0 24m myapp-deploy-869b888f66-frspv 1/1 Running 0 24m myapp-deploy-869b888f66-sgsll 1/1 Running 0 24m myapp-deploy-7cbd5b69b9-5s4sq 0/1 Pending 0 0s myapp-deploy-7cbd5b69b9-5s4sq 0/1 Pending 0 0s myapp-deploy-7cbd5b69b9-5s4sq 0/1 ContainerCreating 0 1s myapp-deploy-7cbd5b69b9-5s4sq 0/1 ContainerCreating 0 2s myapp-deploy-7cbd5b69b9-5s4sq 1/1 Running 0 19s myapp-deploy-869b888f66-dpwvk 1/1 Terminating 0 31m myapp-deploy-7cbd5b69b9-p6kzm 0/1 Pending 0 1s myapp-deploy-7cbd5b69b9-p6kzm 0/1 Pending 0 1s myapp-deploy-7cbd5b69b9-p6kzm 0/1 ContainerCreating 0 1s myapp-deploy-7cbd5b69b9-p6kzm 0/1 ContainerCreating 0 2s myapp-deploy-869b888f66-dpwvk 0/1 Terminating 0 31m myapp-deploy-869b888f66-dpwvk 0/1 Terminating 0 31m myapp-deploy-869b888f66-dpwvk 0/1 Terminating 0 31m myapp-deploy-7cbd5b69b9-p6kzm 1/1 Running 0 18s myapp-deploy-869b888f66-frspv 1/1 Terminating 0 31m myapp-deploy-7cbd5b69b9-q8mvs 0/1 Pending 0 0s myapp-deploy-7cbd5b69b9-q8mvs 0/1 Pending 0 0s myapp-deploy-7cbd5b69b9-q8mvs 0/1 ContainerCreating 0 0s myapp-deploy-7cbd5b69b9-q8mvs 0/1 ContainerCreating 0 1s myapp-deploy-869b888f66-frspv 0/1 Terminating 0 31m myapp-deploy-869b888f66-frspv 0/1 Terminating 0 31m myapp-deploy-869b888f66-frspv 0/1 Terminating 0 31m myapp-deploy-869b888f66-frspv 0/1 Terminating 0 31m
回滚
查看现在有几个版本
kubectl rollout history deploy myapp-deploy deployments "myapp-deploy" REVISION CHANGE-CAUSE 0 <none> 3 <none> 4 <none> 5 <none>
回滚到第0版(默认回滚上一版,可以通过 --to-revision指定版本)
$ kubectl rollout undo deploy myapp-deploy --to-revision=0 deployment "myapp-deploy" rolled back #查看回滚情况 $ kubectl get pods -l app=myapp -w NAME READY STATUS RESTARTS AGE myapp-deploy-7cbd5b69b9-5s4sq 1/1 Running 0 6m myapp-deploy-7cbd5b69b9-p6kzm 1/1 Running 0 1m myapp-deploy-7cbd5b69b9-q8mvs 1/1 Running 0 54s ^[[Amyapp-deploy-869b888f66-7shh9 0/1 Pending 0 0s myapp-deploy-869b888f66-7shh9 0/1 Pending 0 0s myapp-deploy-869b888f66-7shh9 0/1 ContainerCreating 0 0s myapp-deploy-869b888f66-7shh9 0/1 ContainerCreating 0 1s myapp-deploy-869b888f66-7shh9 1/1 Running 0 3s myapp-deploy-7cbd5b69b9-q8mvs 1/1 Terminating 0 5m myapp-deploy-869b888f66-4l4cv 0/1 Pending 0 0s myapp-deploy-869b888f66-4l4cv 0/1 Pending 0 0s myapp-deploy-869b888f66-4l4cv 0/1 ContainerCreating 0 0s myapp-deploy-869b888f66-4l4cv 0/1 ContainerCreating 0 1s myapp-deploy-7cbd5b69b9-q8mvs 0/1 Terminating 0 5m myapp-deploy-869b888f66-4l4cv 1/1 Running 0 2s myapp-deploy-7cbd5b69b9-p6kzm 1/1 Terminating 0 6m myapp-deploy-869b888f66-vwgj2 0/1 Pending 0 0s myapp-deploy-869b888f66-vwgj2 0/1 Pending 0 0s myapp-deploy-869b888f66-vwgj2 0/1 ContainerCreating 0 0s myapp-deploy-7cbd5b69b9-q8mvs 0/1 Terminating 0 5m myapp-deploy-7cbd5b69b9-q8mvs 0/1 Terminating 0 5m myapp-deploy-7cbd5b69b9-p6kzm 0/1 Terminating 0 6m myapp-deploy-869b888f66-vwgj2 0/1 ContainerCreating 0 1s myapp-deploy-869b888f66-vwgj2 1/1 Running 0 3s myapp-deploy-7cbd5b69b9-5s4sq 1/1 Terminating 0 11m myapp-deploy-7cbd5b69b9-5s4sq 0/1 Terminating 0 11m myapp-deploy-7cbd5b69b9-5s4sq 0/1 Terminating 0 11m myapp-deploy-7cbd5b69b9-p6kzm 0/1 Terminating 0 6m myapp-deploy-7cbd5b69b9-p6kzm 0/1 Terminating 0 6m myapp-deploy-7cbd5b69b9-5s4sq 0/1 Terminating 0 11m myapp-deploy-7cbd5b69b9-5s4sq 0/1 Terminating 0 11m $ kubectl get rs -l app=myapp -o wide NAME DESIRED CURRENT READY AGE CONTAINER(S) IMAGE(S) SELECTOR myapp-deploy-7cbd5b69b9 0 0 0 14m myapp-containers ikubernetes/myapp:v3 app=myapp,pod-template-hash=3768162565,release=dev myapp-deploy-869b888f66 3 3 3 1h myapp-containers ikubernetes/myapp:v2 app=myapp,pod-template-hash=4256444922,release=dev myapp-deploy-f4bcc4799 0 0 0 1h myapp-containers ikubernetes/myapp:v1 app=myapp,pod-template-hash=906770355,release=dev
kubectl patch 打补丁的方式更新
格式案例(通过json格式)
kubectl patch pod valid-pod -p '{"spec":{"containers":[{"name":"kubernetes-serve-hostname","image":"new image"}]}}'
更新一个images
kubectl patch deploy myapp-deploy -p '{"spec":{"template":{"spec":{"containers":[{"name":"myapp-containers","image":"ikubernetes/myapp:v1"}]}}}}'