请启用 Javascript 以查看内容

k8s 存活探针,滚动更新

 ·   ·  ☕ 5 分钟  ·  ✍ CNSRE

文章链接

存活探针

Kubelet使用liveness probe(存活探针)来确定何时重启容器。例如,当应用程序处于运行状态但无法做进一步操作,liveness探针将捕获到deadlock,重启处于该状态下的容器,使应用程序在存在bug的情况下依然能够继续运行下去(谁的程序还没几个bug呢)。

Kubelet使用readiness probe(就绪探针)来确定容器是否已经就绪可以接受流量。只有当Pod中的容器都处于就绪状态时kubelet才会认定该Pod处于就绪状态。该信号的作用是控制哪些Pod应该作为service的后端。如果Pod处于非就绪状态,那么它们将会被从service的load balancer中移除。

重启策略 (RestartPolicy )

  • Always:当容器终止退出后,总是重启容器,默认策略。
  • OnFailure:当容器异常退出(退出状态码非0)时,才重启容器。
  • Never:当容器终止退出,从不重启容器。

probe有以下两种类型:

  • livenessProbe:如果检查失败,将杀死容器,根据Pod的restartPolicy来操作。
  • readinessProbe: 如果检查失败,Kubernetes会把Pod从service endpoints中剔除

Probe支持以下三种检查方法:

  • httpGet:发送HTTP请求,返回200-400范围状态码为成功。
  • exec:执行Shell命令返回状态码是0为成功。
  • tcpSocket:发起TCP Socket建立成功。

健康检查的方法

方法一 httpGet

nginx使用httpGet健康检查的方法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
复制代码apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  minReadySeconds: 1
  progressDeadlineSeconds: 60
  revisionHistoryLimit: 2
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
  template:
    metadata:
      name: nginx
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.19
        ports:
        - containerPort: 80
        resources:
          requests:
            memory: "500Mi"
            cpu: "250m"
          limits: 
            memory: "500Mi" 
            cpu: "500m"
       livenessProbe:
           httpGet:
             path: /index.html
             port: 80
           initialDelaySeconds: 10  #pod启动10秒执行第一次检查
           periodSeconds: 5         #第一次检查后每隔5秒检查一次**
        volumeMounts:
        - name: html
          mountPath: /usr/share/nginx/html
      volumes:
      - name: html
        hostPath:
          path: /home/k8s/data/nginx
---
apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  type: NodePort
  ports:
   - port: 8080
     nodePort: 30080
  selector:
    app: nginx

方法二:tcpSocket

nginx使用tcpSocket健康检查的方法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  minReadySeconds: 1
  progressDeadlineSeconds: 60
  revisionHistoryLimit: 2
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
  template:
    metadata:
      name: nginx
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.19
        ports:
        - containerPort: 80
        resources:
          requests:
            memory: "500Mi"
            cpu: "250m"
          limits: 
            memory: "500Mi" 
            cpu: "500m"
        livenessProbe:
           tcpSocket:
             port: 80
           initialDelaySeconds: 10
           periodSeconds: 5
        volumeMounts:
        - name: html
          mountPath: /usr/share/nginx/html
      volumes:
      - name: html
        hostPath:
          path: /home/k8s/data/nginx
---
apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  type: NodePort
  ports:
   - port: 8080
     nodePort: 30080
  selector:
    app: nginx

滚动发布

k8s创建副本应用程序的最佳方法就是部署(Deployment),部署自动创建副本集(ReplicaSet),副本集可以精确地控制每次替换的Pod数量,从而可以很好的实现滚动更新。具体来说,k8s每次使用一个新的副本控制器(replication controller)来替换已存在的副本控制器,从而始终使用一个新的Pod模板来替换旧的pod模板。
步骤如下:

  • 创建一个新的replication controller。
  • 增加或减少pod副本数量,直到满足当前批次期望的数量。
  • 删除旧的replication controller

实战练习

Q: 假如一个nginx服务 起了3个pod,我做了发版,然后没想到这次发版有问题。健康检查也没过!这种情况下发布,会把3个pod都替换掉?还是说检测到一个pod健康检查有问题,下一个就pod就不发布了?已经发布的pod会对外提供服务吗?
带着这些疑问,来做个实验。

创建nginx服务

创建一个nginx服务,选择1个副本。
cnsre运维博客|Linux系统运维|自动化运维|云计算|运维监控
具体yaml如下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
apiVersion: apps/v1
kind: Deployment        
metadata:
  name: nginx-deployment
  labels:           
    app: nginx  
spec:            
  replicas: 1    
  selector:       
    matchLabels:  
      app: nginx
  minReadySeconds: 1
  progressDeadlineSeconds: 60
  revisionHistoryLimit: 2
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
  template:      
    metadata:    
      labels:    
        app: nginx
    spec:         
      containers:  
      - name: nginx   
        image: wenlongxue/xxxx:6f965dd    # 需要修改自己的镜像
        imagePullPolicy: Always           
        ports:
        - containerPort: 80
        resources:
          requests:
            memory: "600Mi"
            cpu: "250m"
          limits: 
            memory: "600Mi" 
            cpu: "500m"
        readinessProbe:
          httpGet:
            path: /actuator/health
            port: 80
          periodSeconds: 5
          timeoutSeconds: 3
          successThreshold: 1
          failureThreshold: 30     
---
apiVersion: v1
kind: Service
metadata:      
  name: nginx-service 
  labels:        
    app: nginx   
spec:        
  selector:    
    app: nginx  
  ports:
  - name: nginx-port 
    protocol: TCP     
    port: 80           
    nodePort: 30081    
    targetPort: 80      
  type: NodePort         

查看当前pod

另起一个窗口

1
kubectl get pods -l app=nginx  -w

cnsre运维博客|Linux系统运维|自动化运维|云计算|运维监控

发布健康检查有问题的版本

修改yaml
将副本数replicas: 1 设置为replicas: 3
将健康检查path: / 修改为一个不存在的静态页面,这样健康检查就不过了。
具体代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
...
spec:            
  replicas: 3  
...
        readinessProbe:
          httpGet:
            path: /cnsre.html
            port: 80
          periodSeconds: 5
          timeoutSeconds: 3
          successThreshold: 1
          failureThreshold: 30      

执行滚动发布并观察

执行更新滚动发布

1
kubectl  apply  -f nginx.yaml

查看pod状态

1
kubectl  get  pods  -l app=nginx

观察滚动更新过程

1
kubectl get pods -l app=nginx  -w

cnsre运维博客|Linux系统运维|自动化运维|云计算|运维监控

健康检查滚动发布实验结果

通过实验发现,新发版,健康检查没过!这种情况下发布,会把之前的pod保留,新发布的pod 运行,但是不对外提供服务。
带着这些疑问,来做个实验。
cnsre运维博客|Linux系统运维|自动化运维|云计算|运维监控
cnsre运维博客|Linux系统运维|自动化运维|云计算|运维监控
文章链接

分享

CNSRE
作者
CNSRE
一个📚学习中的👨‍💻SRE运维工程师🚀🚀🚀


目录