Deployment是ReplicaSet的升级版,支持在恒定速度的之下从一个状态转移到另一个状态(滚动升级)。
和ReplicaSet Replication Controller的不同之处
ReplicaSet 和Replication Controller 也支持rollout update,但是存在问题
kubectl rolling-update kubia-v1 kubia-v2 --image=luksa/kubia:v2
存在的问题是rollout过程归client端控制而不是server。如果在rollout过程中kubectl和server失去联系,整个rollout会出现问题。
Deployment的rollout过程归server控制,不存在上述的问题。
Deployment的实现依赖ReplicaSet(仍会创建ReplicaSet),Deployment是ReplicaSet的封装。
Deployment可以做到什么
- Delpoyment控制ReplicaSet的滚动升级
- 通过修改podTemplate的方式来滚动升级(使用配置的速度限制滚动升级)
- 回滚到更早的Deployment版本
- 暂停和恢复Delpoyment滚动升级过程
创建Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
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的Deployment
- 管理的pod具有app: nginx标签
- 创建的pod具有3个副本
- pod使用的镜像为nginx:1.7.9
查看运行的Deployment
kubectl get deployments
输出表格有如下几列:
- NAME:集群中的deployments名称
- READY:目前已运行pod/期待运行多少个replicas
- UP-TO-DATE: 已经达到期待状态的replica数目
- AVAILABLE:application有多少个副本可用(启动完毕)
- AGE:application已启动多长时间
查看Deployment的细节
kubectl describe deployments
创建Deployment
kubectl create -f kubia-deployment-v1.yaml --record
--record会记录deployment的历史revision。
相关的修改命令会记录在pod的kubernetes.io/change-cause annotation中。
pod-template-hash
查看pod-template-hash
kubectl get pods --show-labels
kubectl get rs --show-labels
Deployment自己创建的ReplicaSet以及pod的label会带有一段hash,即pod-template-hash。它的作用为确保归此deployment管理的ReplicaSet和pod不会和其他的发生冲突。
触发滚动升级
滚动升级当且仅当在pod template修改之后才会触发。
修改镜像版本
kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1 --record
或者是编辑deployment描述文件
kubectl edit deployment.v1.apps/nginx-deployment
Label selector 修改
- 增加新的label:要求pod template的label和deployment的spec同步增加,否则会报错。新的selector并不会选定原先创建出来的ReplicaSet和Pod,他们会被孤立(不归deployment管理),deployment接下来创建出新的ReplicaSet和Pod。
- selector修改:和新增label相同。
- selector删除(减少label):不要求pod template随着改变。执行之后旧的ReplicaSet和Pod会保持不变,被移除的label在就的ReplicaSet和Pod中仍存在。不会创建出新的ReplicaSet,旧的ReplicaSet和Pod也不会孤立。
获取滚动升级状态
kubectl rollout status deployment/nginx-deployment
# 或
kubectl rollout status deployment.apps/nginx-deployment
# 或
kubectl rollout status deployment.v1.apps/nginx-deployment
Deployment rollout过程
pod被update之后,deployment会创建新的replicaSet,并且逐步scale到配置的replica数。同时老的replicaSet会逐步scale到0。
如果在rollout过程中pod发生了更新,不会等到老的replicaSet scale到 desired state(达到指定的replica数量),会立刻开始scale到0的过程。
新的pod状态变为ready或available(至少需要等待MinReadySeconds)。
查看deployment rollout历史
kubectl rollout history deployment.v1.apps/nginx-deployment
输入类似如下界面:
deployments "nginx-deployment"
REVISION CHANGE-CAUSE
1 kubectl apply --filename=https://k8s.io/examples/controllers/nginx-deployment.yaml --record=true
2 kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.9.1 --record=true
3 kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.91 --record=true
可以通过如下方式指定CHANGE-CAUSE:
- 增加deployment的annotation,类似于kubectl annotate deployment.v1.apps/nginx-deployment kubernetes.io/change-cause="image updated to 1.9.1"
- 修改Deployment的时候附带--record参数
- 手工修改资源的manifest信息
查看某一个revision更具体的信息
kubectl rollout history deployment.v1.apps/nginx-deployment --revision=2
回滚到上一个版本
kubectl rollout undo deployment.v1.apps/nginx-deployment
回滚到指定revision
kubectl rollout undo deployment.v1.apps/nginx-deployment --to-revision=2
动态扩展deployment
kubectl scale deployment.v1.apps/nginx-deployment --replicas=10
水平自动扩展
kubectl autoscale deployment.v1.apps/nginx-deployment --min=10 --max=15 --cpu-percent=80
百分比扩展
在滚动升级的过程中,新老版本的pod同时在运行。如果在升级过程尚未完成之时调大replica数值,比如说增加5。由于百分比扩展特性的存在,这新增的5个replica不会都分配给新的ReplicaSet,而是按照比例同时分配给新老ReplicaSet,新的ReplicaSet占比多,老的ReplicaSet占比少。以新增5个replica为例,新的ReplicaSet会增加3,老的ReplicaSet会增加2。
暂停rollout
kubectl rollout pause deployment.v1.apps/nginx-deployment
继续rollout
kubectl rollout resume deployment.v1.apps/nginx-deployment
以watch状态观察rollout过程
kubectl get rs -w
minReadySeconds
pod至少多久之后才会被认为可用。
只有在时间超过minReadySeconds,并且readness probe检测状态正常的时候,pod才会被k8s认为是可用的,滚动升级才会进行。
progressDeadlineSeconds
增加deployment部署时间超时限制。
kubectl patch deployment.v1.apps/nginx-deployment -p '{"spec":{"progressDeadlineSeconds":600}}'
Deployment超时的时候k8s不会自动处理,只会返回状态值Reason=ProgressDeadlineExceeded
Rollout时候暂停,k8s不会检查部署超时限制(progressDeadlineSeconds),因此不用担心rollout恢复操作的时候超时。
DEPLOYMENT STRATEGIES
- Recreate 删除所有的旧pod,再创建新的pod。中间服务会不可用。
- RollingUpdate 滚动升级,默认值。
spec:
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
type: RollingUpdate
RollingUpdate参数解释(英文描述还是比较精确的,因此从官网摘抄下来):
- maxSurge: Determines how many pod instances you allow to exist above the desired replica count configured on the Deployment. It defaults to 25%, so there can be at most 25% more pod instances than the desired count. If the desired replica count is set to four, there will never be more than five pod instances running at the same time during an update. When converting a percentage to an absolute number, the number is rounded up. Instead of a percentage, the value can also be an absolute value (for example, one or two additional pods can be allowed).
- maxUnavailable: Determines how many pod instances can be unavailable relative to the desired replica count during the update. It also defaults to 25%, so the number of available pod instances must never fall below 75% of the desired replica count. Here, when converting a percentage to an absolute number, the number is rounded down. If the desired replica count is set to four and the percentage is 25%, only one pod can be unavailable. There will always be at least three pod instances available to serve requests during the whole rollout. As with maxSurge, you can also specify an absolute value instead of a percentage.
个人对应的理解为:
- maxSurge:滚动升级是一个新的ReplicaSet逐渐扩容,旧的ReplicaSet逐渐缩容的过程。在这个过程中为了保障服务不被中断,同时又希望同时启动更多的新版本pod,允许在这个期间,同时运行的replica数量超过Deployment配置的replica数。这个超出数量的上限值为maxSurge。它的默认值为25%。maxSurge既可以配置百分比(计算出的replica数量向上取整),也可以配置具体replica个数。
- maxUnavailable:在滚动升级过程中,新的pod不可能很快的启动完毕,进入到能够对外提供服务的状态。但是为了加快滚动升级的速度,k8s会尽可能同时启动最多的新版本pod。由于maxSurge的限制,同时启动的新版本pod不可能无限多。在保障业务不中断(此时服务主要由旧的pod支撑)的情况下,k8s会kill掉一些旧的pod,腾出尽量多的replica余额来启动新的pod。在这个过程中系统需要保证无法对外提供服务的pod数量(未完成启动过程的pod数量)不得超过maxUnavailable。如果maxUnavailable配置的为百分比,含义为无法提供服务的pod占Deployment配置的replica数量的比例不得大于maxUnavailable。maxUnavailable的默认值为25%。