滚动更新策略不会在实时流量中实现零停机时间



我正在使用滚动更新策略进行部署,使用这两个命令:

kubectl patch deployment.apps/<deployment-name> -n <namespace> -p '{"spec":{"template":{"metadata":{"labels":{"date":"`date +'%s'`"}}}}}' 
kubectl apply -f ./kube.deploy.yml -n <namespace>
kubectl apply -f ./kube_service.yml -n <namespace>

滚动更新的 YAML 属性:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: "applyupui-persist-service-deployment"
spec:
# this replicas value is default
# modify it according to your case
replicas: 2
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 20%
template:
metadata:
labels:
app: "applyupui-persist-service-selector"
spec:
hostAliases:
- ip: "xx.xx.xx.xxx"
hostnames:
- "kafka02.prod.fr02.bat.cloud"

imagePullSecrets:
- name: tpdservice-devops-image-pull-secret
containers:
- name: applyupui-persist-service
image: gbs-bat-devops-preprod-docker-local.artifactory.swg-devops.com:443/applyupui-msg-persist-service:latest
imagePullPolicy: Always
env:
- name: KAFKA_BROKER
value: "10.194.6.221:9092,10.194.6.221:9093,10.194.6.203:9092"
- name: SCYLLA_DB
value: "scylla01.fr02.bat.cloud,scylla02.fr02.bat.cloud,scylla03.fr02.bat.cloud"
- name: SCYLLA_PORT
value: "9042"            
- name: SCYLLA_DB_USER_ID
value: "kafcons"
- name: SCYLLA_DB_PASSWORD
value: "@%$lk*&we@45"
- name: SCYLLA_LOCAL_DC_NAME
value: "Frankfurt-DC"
- name: DC_LOCATION
value: "FRA"
- name: kafka.consumer.retry.topic.timeout.interval            
value: "100"
- name: kafka.consumer.retry.topic.max.retry.count
value: "5"
- name: kafka.consumer.dlq.topic.timeout.interval
value: "100"
- name: kafka.producer.timeout.interval
value: "100"             
- name: debug.log.enabled
value: "false"
- name: is-application-intransition-phase
value: "false"
- name: is-grace-period
value: "false"             
- name: SCYLLA_KEYSPACE
value: "bat_tpd_pri_msg"
readinessProbe:
httpGet:
path: /greeting
port: 8080
initialDelaySeconds: 3
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
nodeSelector:
deployment: frankfurt
# resources:
#   requests:
#     cpu: 100m
#     memory: 100Mi

我尝试更改maxsurgemaxunavailable参数以及不同的initialdelayseconds参数。此外,我尝试给出livelinessprobe参数

livenessprobe:
tcpSocket:
port: 8080
initialDelaySeconds: 15
periodSeconds: 20  

,但都没有奏效。 它给出连接错误,表明某些 pod 已关闭,因此存在停机时间。

首先,您需要确保yaml文件正确并且所有缩进都已到位。之后,您需要正确设置值以实现零停机时间更新。以下示例显示了正确定义的RollingUpdates:

spec:
replicas: 2
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0

在这个例子中,在所需的 2 个 Pod 之上会有一个额外的 Pod(maxSurge: 1(,并且可用 Pod 的数量不能低于该数字 (maxUnavailable: 0(。

选择这个配置,Kubernetes 将启动一个额外的 Pod,然后停止一个"旧"的 Pod。如果有另一个节点可用于部署此 Pod,则系统将能够在部署期间处理相同的工作负载。如果没有,Pod 将部署在已经使用的节点上,代价是来自同一节点上的其他 Pod 的资源。

你也可以尝试这样的事情:

spec:
replicas: 2
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 0
maxUnavailable: 1

在上面的例子中,不会有额外的 Pod(maxSurge: 0(,并且一次只有一个 Pod 不可用(maxUnavailable: 1(。

在这种情况下,Kubernetes 将首先停止一个 Pod,然后再启动一个新的 Pod。这样做的好处是基础设施不需要纵向扩展,但最大工作负载会更少。

如果选择对maxSurgemaxUnavailable使用百分比值,则需要记住:

  • maxSurge- 绝对数字是通过四舍五入从百分比计算得出

  • maxUnavailable- 绝对数字通过向下舍入从百分比计算得出

正确定义RollingUpdate后,您还必须确保您的应用程序提供由 Kubernetes 查询的端点,这些端点返回应用程序的状态。下面是一个/greeting终结点,当它准备好处理请求时返回 HTTP 200 状态,当它未处理请求时返回 HTTP 500 状态:

readinessProbe:
httpGet:
path: /greeting
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
  • initialDelaySeconds- 完成第一次准备检查之前的时间(以秒为单位(。

  • periodSeconds- 第一次检查后两次准备情况检查之间的时间(以秒为单位(。

  • successThreshold- 探测在失败后被视为成功的最小连续成功数。默认值为 1。必须为 1 才能存活。最小值为 1。

  • timeoutSeconds- 探测器超时的秒数。默认为 1 秒。最小值为 1。

我已经成功地测试了上述场景。

如果有帮助,请告诉我。

最新更新