k8s 滚动发布

一、deployment和ReplicaSet的关系
1、一个nginx的deployment
# more deployment-test.yaml
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
# kubectl apply -f deployment-test.yaml 
# kubectl get deploy
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3/3     3            3           9s

# kubectl get rs
NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-7d74b5d679   3         3         3       33s

# kubectl get pod
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-7d74b5d679-67ktf   1/1     Running   0          47s
nginx-deployment-7d74b5d679-c2wjm   1/1     Running   0          47s
nginx-deployment-7d74b5d679-v7dmm   1/1     Running   0          47s
  • DESIRED:用户期望的 Pod 副本个数(spec.replicas 的值)
  • CURRENT:当前处于 Running 状态的 Pod 的个数
  • UP-TO-DATE:当前处于最新版本的 Pod 的个数,所谓最新版本指的是 Pod 的 Spec 部分与 Deployment 里 Pod 模板里定义的完全一致
  • AVAILABLE:当前已经可用的 Pod 的个数,即:既是 Running 状态,又是最新版本,并且已经处于 Ready(健康检查正确)状态的 Pod 的个数
2、命名方式
1)RS:Deployment 的名字和一个随机字符串
2)POD:RS的名称+随机字符串
3、逻辑关系

 

 

4、扩缩容
kubectl scale deployment nginx-deployment --replicas=4 //指定副本数

二、滚动更新

1、版本更新

# kubectl edit deployment/nginx-deployment
    spec:
      containers:
      - image: harbor.tenserpay.xyz/op/nginx:1.9.1
# kubectl get deploy
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   2/2     1            2           153m

# kubectl get rs
NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-5746f84557   2         2         1       17s
nginx-deployment-7d74b5d679   1         1         1       153m

# kubectl get pod
NAME                                READY   STATUS        RESTARTS   AGE
nginx-deployment-5746f84557-6zwws   1/1     Running       0          8s
nginx-deployment-5746f84557-hdvkq   1/1     Running       0          22s
nginx-deployment-7d74b5d679-rx6s2   1/1     Terminating   0          154m

# kubectl describe deployment nginx-deployment
  Normal  ScalingReplicaSet  82s   deployment-controller  Scaled up replica set nginx-deployment-5746f84557 to 1
  Normal  ScalingReplicaSet  68s   deployment-controller  Scaled down replica set nginx-deployment-7d74b5d679 to 1
  Normal  ScalingReplicaSet  68s   deployment-controller  Scaled up replica set nginx-deployment-5746f84557 to 2
  Normal  ScalingReplicaSet  60s   deployment-controller  Scaled down replica set nginx-deployment-7d74b5d679 to 0
2、逻辑关系

 

 

3、更新策略
1)Recreate:在创建新Pods之前,所有现有的Pods会被杀死
2)RollingUpdate:滚动升级,逐步替换的策略,同时滚动升级时,支持更多的附加参数

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
...
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
  • maxSurge:1 表示滚动升级时会先启动1个pod
  • maxUnavailable:1 表示滚动升级时允许的最大Unavailable的pod个数,也可以填写比例,maxUnavailable=50%
 
4、滚动升级过程
1)K8S首先启动新的POD
2)K8S等待新的POD进入Ready状态
3)K8S创建Endpoint,将新的POD纳入负载均衡
4)K8S移除与老POD相关的Endpoint,并且将老POD状态设置为Terminating,此时将不会有新的请求到达老POD
5.1)如果有preStop,kubelet 会调用每个容器的 preStop hook,假如 preStop hook 的运行时间超出了terminationGracePeriodSeconds,kubelet 会发送SIGTERM并再等 2 秒;
5.2)如果没有preStop,K8S 会给老POD发送SIGTERM信号,并且等待 terminationGracePeriodSeconds 这么长的时间。(默认为30秒)
6)超过terminationGracePeriodSeconds等待时间后,K8S会强制结束老POD
 
这里可能存在的问题
1)程序不处理SIGTERM信号,无法保证所有事务完成后再关闭程序,需要程序代码支持
2)无法在terminationGracePeriodSeconds时间内,正常关闭程序,需要适当调整terminationGracePeriodSeconds时长

posted @ 2021-02-22 20:03  guoxianqi  阅读(467)  评论(0编辑  收藏  举报