一、简介

Deployment 是一种更高级的资源,用于部署升级应用.

创建Deployment时,ReplicaSet资源会随之创建,实际Pod是由ReplicaSet创建和管理,而不是由Deployment直接管理

Deployment可以在应用滚动升级过程中, 引入另一个RepliaSet, 并协调两个ReplicaSet.

deployment 设置不滚动更新 deployment滚动更新原理_回滚

cat <<EOF > kubia-deployment-v1.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: kubia
spec:
  replicas: 3
  selector: 
    matchLabels:
      app: kubia
  template:
    metadata:
      name: kubia
      labels:
        app: kubia
    spec:
      containers:
      - image: luksa/kubia:v1
        imagePullPolicy: Never
        name: nodejs
EOF
k create -f kubia-deployment-v1.yml --record

k get deploy
-----------------------------------------------
NAME    READY   UP-TO-DATE   AVAILABLE   AGE
kubia   3/3     3            3           2m35s

k get rs
----------------------------------------------------
NAME               DESIRED   CURRENT   READY   AGE
kubia-66b4657d7b   3         3         3       3m4s  

k get po
------------------------------------------------------------
NAME                     READY   STATUS    RESTARTS   AGE
kubia-66b4657d7b-f9bn7   1/1     Running   0          3m12s
kubia-66b4657d7b-kzqwt   1/1     Running   0          3m12s
kubia-66b4657d7b-zm4xd   1/1     Running   0          3m12s

k rollout status deploy kubia
------------------------------------------
deployment "kubia" successfully rolled out

rs 和 pod 名称中的数字,是 用镜像名称的哈希值

二、升级 Deployment

只需要在 pod 模板中修改镜像的 Tag, Deployment 就可以自动完成升级过程
Deployment的升级策略

  • 滚动升级 Rolling Update - 渐进的删除旧的pod, 同时创建新的pod, 这是默认的升级策略
  • 重建 Recreate - 一次删除所有旧的pod, 再重新创建新的pod
    minReadySeconds设置为10秒, 减慢滚动升级速度, 便于我们观察升级的过程.
k patch deploy kubia -p '{"spec": {"minReadySeconds": 10}}'

部署service

cat <<EOF > kubia-svc-nodeport.yml
apiVersion: v1
kind: Service
metadata:
  name: kubia-nodeport
spec:
  type: NodePort           # 在每个节点上开放访问端口
  ports:
  - port: 80               # 集群内部访问该服务的端口
    targetPort: 8080       # 容器的端口
    nodePort: 30123        # 外部访问端口
  selector:
    app: kubia
EOF

触发滚动升级
修改 Deployment 中 pod 模板使用的镜像就可以触发滚动升级

为了便于观察, 在另一个终端中执行循环, 通过 service 来访问pod

while true; do curl http://192.168.64.191:30123; sleep 0.5s; done
k set image deploy kubia nodejs=luksa/kubia:v2

通过不同的命令来了解升级的过程和原理

k rollout status deploy kubia
k get rs
k get po --show-labels
k describe rs kubia-66b4657d7b

三、回滚 Deployment

luksa/kubia:v3 镜像中的应用模拟一个 bug, 从第5次请求开始, 会出现 500 错误

k set image deploy kubia nodejs=luksa/kubia:v3

手动回滚到上一个版本 k rollout undo deploy kubia

控制滚动升级速率

滚动升级时

  • 先创建新版本pod
  • 再销毁旧版本pod

可以通过参数来控制, 每次新建的pod数量和销毁的pod数量:

  • maxSurge - 默认25% 允许超出的 pod 数量.
    如果期望pod数量是4, 滚动升级期间, 最多只允许实际有5个 pod.
  • maxUnavailable - 默认 25%,允许有多少 pod 处于不可用状态.
    如果期望pod数量是4, 滚动升级期间, 最多只允许 1 个 pod 不可用, 也就是说任何时间都要保持至少有 3 个可用的pod.

查看参数

k get deploy -o yaml
--------------------------------
......
    strategy:
      rollingUpdate:
        maxSurge: 25%
        maxUnavailable: 25%
      type: RollingUpdate
......

四、暂停滚动升级

将 image 升级到 v4 版本触发更新, 并立即暂停更新.这时会有一个新版本的 pod 启动, 可以暂停更新过程, 让少量用户可以访问到新版本, 并观察其运行是否正常.根据新版本的运行情况, 可以继续完成更新, 或回滚到旧版本,被叫做金丝雀升级

k set image deploy kubia nodejs=luksa/kubia:v4
# 暂停
k rollout pause deploy kubia
# 继续
k rollout resume deploy kubia

五、自动阻止出错版本升级

minReadySeconds

  • 新创建的pod成功运行多久后才,继续升级过程
  • 在该时间段内, 如果容器的就绪探针返回失败, 升级过程将被阻止

修改Deployment配置,添加就绪探针

cat <<EOF > kubia-deployment-v3-with-readinesscheck.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: kubia
spec:
  replicas: 3
  selector: 
    matchLabels:
      app: kubia
  minReadySeconds: 10
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
    type: RollingUpdate
  template:
    metadata:
      name: kubia
      labels:
        app: kubia
    spec:
      containers:
      - image: luksa/kubia:v3
        name: nodejs
        imagePullPolicy: Never
        readinessProbe:
          periodSeconds: 1
          httpGet:
            path: /
            port: 8080
EOF
k apply -f kubia-deployment-v3-with-readinesscheck.yml

就绪探针探测间隔设置成了 1 秒, 第5次请求开始每次请求都返回500错, 容器会处于未就绪状态. minReadySeconds被设置成了10秒, 只有pod就绪10秒后, 升级过程才会继续.所以这是滚动升级过程会被阻塞, 不会继续进行.

默认升级过程被阻塞10分钟后, 升级过程会被视为失败, Deployment描述中会显示超时(ProgressDeadlineExceeded).

k describe deploy kubia
-----------------------------
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    False   ProgressDeadlineExceeded

这是只能通过手动执行 rollout undo 命令进行回滚 k rollout undo deploy kubia