readinessProbe+preStop使应用更新时用户无感知

Posted 草根追逐

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了readinessProbe+preStop使应用更新时用户无感知相关的知识,希望对你有一定的参考价值。

背景

在K8s部署多副本时候,使用nacos作为服务注册和发现中心,而在多副本应用更新的过程中会出现应用已经停止,但是nacos服务却扔然将流量转发给已经停止的应用,导致报错。

解决办法

1、想办法让应用停止前发送通知给nacos,告诉他应用即将停止,叫nacos不要再转发给他,在这里就使用脚本实现,具体脚本如下:

#!/bin/sh
Token=$(curl -s --location --request POST http://nacos:8848/nacos/v1/auth/users/login --form username=nacos --form password=nacos|awk -F "accessToken" print $2|awk -F ":" print $2|awk -F " print $2)
curl -X PUT  "http://nacos:8848/nacos/v1/ns/instance?accessToken=$Token&serviceName=apaas-gateway-provider&groupName=apaas&namespaceId=apaas-srm-huami-dev&ip=$MY_POD_IP&clusterName=DEFAULT&port=5100&ephemeral=true&weight=1&enabled=1"

说明:此处的MY_POD_IP变量是由deployment的env属性中的status.podIP字段传入的,如下:

      containers:
      - env:
        - name: MY_POD_IP
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: status.podIP

2、将以上脚本上传到pod持久化存储的目录,在deployment的preStop的hook执行,如下:

        lifecycle:
          preStop:
            exec:
              command:
              - /home/logs/service_offline_nacos.sh

3、光添加preStop还不够,因为虽然应用在关闭前通知nacos注销应用自身,但是在更新新的应用后当应用更新完但是还不能提供服务的时候svc就会认为应用已经Running,就会将流量转发给他,此时仍然会报错,所以需要添加探针,如下:
可读性探针:

        readinessProbe:
          tcpSocket:
            port: 5100

最好再添加个存活性检测探针:

        livenessProbe:
          tcpSocket:
            port: 5100

完整配置如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: gateway
  namespace: test
spec:
  replicas: 2
  selector:
    matchLabels:
      app: gateway
  template:
    metadata:
      labels:
        app: gateway
    spec:
      containers:
      - env:
        - name: MY_POD_IP
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: status.podIP
        image: harbor.xxx.com/xxx/gateway:2022-03-25-14-53
        imagePullPolicy: Always
        lifecycle:
          preStop:
            exec:
              command:
              - /home/logs/service_offline_nacos.sh
        livenessProbe:
          tcpSocket:
            port: 5100
        name: gateway
        ports:
        - containerPort: 5100
          protocol: TCP
        readinessProbe:
          tcpSocket:
            port: 5100
        volumeMounts:
        - mountPath: /home/logs
          name: data
      dnsPolicy: ClusterFirst
      imagePullSecrets:
      - name: registry-pull-secret
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: gateway-pvc

以上是关于readinessProbe+preStop使应用更新时用户无感知的主要内容,如果未能解决你的问题,请参考以下文章

如何监控`preStop`命令的执行?

pod健康检查(LivenessProbe和ReadinessProbe)

k8s 开船记-修船:改 readinessProbe ,去 DaemonSet ,上 ??Autoscaler

Kubernetes:readinessProbes 失败,但 livelinessProbe 使用相同的设置成功

lua require缓存踩坑记录

关于 Kubernetes中Pod健康检测和服务可用性检查的一些笔记(LivenessProbe+ReadinessProbe)