k8s☞06无状态服务deployment

阅读量: zyh 2020-09-14 14:44:04
Categories: > Tags:

基本

Deployment控制器用来管理无状态应用,通过Deployment控制器创建ReplicaSet,ReplicaSet控制Pod副本集。

任何时候,都不应该直接去创建ReplicaSet控制器,应始终使用Deployment控制器。

例子

API语法:https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/deployment-v1/

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:
      imagePullSecrets:
      - name: apps-ro-token
      containers:
      - name: nginx
        image: nginx:v1.20.1
        command:
        - nginx
        args:
        - -g
        - "daemon off;"
        ports:
        - containerPort: 80

spec.selector:Deployment通过它控制Pod,与Podspec.template.metadata.labels一致。

metadata: 这里会定义name,labels,namespace,annotations。

⚠️Deployment的spec.selector选择的标签应该是全局唯一,这样可以避免多个Deployment出现冲突出现不可预知的问题。

ℹ️ 其中 annotations (注解)很特殊,k8s通过注解中的key来确认要关联的额外服务信息。

例如在阿里云的k8s服务中,你可以添加镜像快照注解信息,从而让 pod 无需从镜像仓库下载启动,而是直接通过快照加速启动。

更新

Deployment的默认策略大致如下

更新规则:

回滚规则:

Deployment只会针对spec.template更新Pod

初始版本

创建一个nginx的deployment

kubectl apply -f nginx-deployment-1.14.2.yaml
===
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  minReadySeconds: 3
  revisionHistoryLimit: 10
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 30%
      maxSurge: 30%
  template:
    metadata:
      labels:
        app: nginx
        version: v1.14.2
      annotations:
        kubernetes.io/change-cause: "version: v1.14.2"
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        lifecycle:
          postStart:
            exec:
              command: ["/bin/sh", "-c", "echo This is v1.14.2 > /usr/share/nginx/html/index.html"]
        command:
        - nginx
        args:
        - -g
        - "daemon off;"
        ports:
        - containerPort: 80

spec.template.metadata.annotations.kubernetes.io/change-cause 通过注解添加变更说明

更新策略

deployment 的 .spec 中可以添加一些策略.

spec:  
  replicas: 3
  minReadySeconds: 3  # pod 就绪时间,在此时间之前,deployment 认为 pod 还没有准备好. 默认0
  revisionHistoryLimit: 10 # 最大版本保留次数. 默认10 
  strategy:
    type: RollingUpdate # 定义变更策略. 除了 RollingUpdate,还可以是Recreate.Recreate指的是先删除所有pod,再创建.
    rollingUpdate:
      maxUnavailable: 30% # 变更期间,不可用的副本数。可以是具体数字
      maxSurge: 30% # 变更期间,可以超出replicas定义的副本数。可以是具体数字

maxUnavailable 和 maxSurge 设置相等即可. 即开多少个新的同时,就关多少个老的

通过命令添加/删除变更说明

kubectl annotate deployment/nginx-deployment kubernetes.io/change-cause="first"
kubectl annotate deployment/nginx-deployment <注解key>-
kubectl xxx --record

版本历史

➜   kubectl rollout history deployment/nginx-deployment
deployment.apps/nginx-deployment
REVISION  CHANGE-CAUSE
1         version: v1.14.2

暂停发布

此操作不会影响pod的运行,仅仅是阻断deployment实施更新。

如果更新之前就暂停,则你可以多次更新,这些更新在【恢复发布】之前不会被应用,也不会记录在【历史版本】中。

如果更新期间执行暂停,则更新会处于等待状态,已更新的不会回滚。

kubectl rollout pause deployment/nginx-deployment

更新版本

发布版本1.20.1

sed 's@1.14.2@1.20.1@g' nginx-deployment-1.14.2.yaml > nginx-deployment-1.20.1.yaml
kubectl apply -f nginx-deployment-1.20.1.yaml

恢复发布

kubectl rollout resume deployment/nginx-deployment

启用恢复后,则暂停期间启用的所有更新将开始发挥作用,并且只会将更新的最终版本写入【历史版本】

➜   kubectl rollout history deployment/nginx-deployment
deployment.apps/nginx-deployment
REVISION  CHANGE-CAUSE
1         version: v1.14.2
2         version: v1.20.1

更新过程和结果查看,可运行:

kubectl rollout status deployment/nginx-deployment

更深层的rs状态查看,可运行:

kubectl get rs -l app=nginx -l version=v1.20.1
kubectl get pod -l app=nginx -l version=v1.20.1

-l 是调用标签过滤

你可以通过追加版本号来看具体的版本内容

kubectl rollout history deployment/nginx-deployment --revision=<num>

回滚版本

我们选择将nginx版本回滚到第一个版本。被回滚的版本会从版本库里移动到最新位置。

kubectl rollout undo deployment/nginx-deployment --to-revision=1
➜   kubectl rollout history deployment/nginx-deployment
deployment.apps/nginx-deployment
REVISION  CHANGE-CAUSE
2         version: v1.20.1
3         version: v1.14.2

如果不指定版本,则回滚到上一个版本。

小结

kubectl rollout history deployment/<> # 查看对象历史
kubectl rollout undo deployment/<> --to-revision=<> # 对象版本回退
kubectl rollout status deployment/<># 展示执行状态
kubectl rollout pause deployment/<> # 暂停此次版本操作行为
kubectl rollout resume deployment/<> # 恢复此次版本操作行为
kubectl set image # 修改镜像配置
kubectl annotate # 添加一个注释

更新过程:

另外,可以通过判断kubectl rollout status deployment/<>命令执行结果,$? 状态为 0,则说明 deployment 处于 complete。

金丝雀发布

金丝雀发布的逻辑:

操作步骤:

  1. 调整新版本Deployment更新策略
  1. 启动更新,并立即暂停发布
kubectl apply -f new-nginx-deployment.yaml && kubectl rollout pause deployment/nginx-deployment
  1. 若新 Pod 没有通过验证,则恢复发布并立即回滚上一个版本。
kubectl rollout resume deployment/nginx-deployment && kubectl rollout undo deployment/nginx-deployment

这个过程不会重建老版本Pod,只会通过新版本rs删除新版本Pod

  1. 若新 Pod 通过验证,则恢复发布
kubectl rollout resume deployment/nginx-deployment

整个更新过程,若顺利,效果如下所示:

image-20211215163355711