kubernetes - 滚动更新策略不会在实时流量中提供零停机时间
问题描述
我正在使用滚动更新策略进行部署,使用这两个命令:
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
我尝试更改参数maxsurge
和maxunavailable
不同的initialdelayseconds
参数。另外,我尝试给出livelinessprobe
参数
livenessprobe:
tcpSocket:
port: 8080
initialDelaySeconds: 15
periodSeconds: 20
,但都没有奏效。它给出了连接错误,表明某些 pod 已关闭,因此存在停机时间。
解决方案
首先,您需要确保您的 yaml 文件正确且所有缩进都已到位。之后,您需要正确设置值以实现零停机更新。下面的示例显示了正确定义RollingUpdate
的 s:
spec:
replicas: 2
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
在此示例中,将maxSurge: 1
在所需数量 2 之上增加一个 Pod ( ),并且可用 Pod 的数量不能低于该数量 ( maxUnavailable: 0
)。
选择这个配置,Kubernetes 将启动一个额外的 Pod,然后停止一个“旧的”。如果有另一个节点可用于部署此 Pod,系统将能够在部署期间处理相同的工作负载。如果没有,该 Pod 将部署在已使用的节点上,代价是来自同一节点上托管的其他 Pod 的资源。
你也可以尝试这样的事情:
spec:
replicas: 2
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 0
maxUnavailable: 1
对于上面的示例,将没有额外的 Pod ( maxSurge: 0
),并且一次只有一个 Pod 不可用 ( maxUnavailable: 1
)。
在这种情况下,Kubernetes 会先停止一个 Pod,然后再启动一个新的 Pod。这样做的好处是基础架构不需要扩展,但最大工作负载会更少。
如果您选择使用百分比值maxSurge
并且maxUnavailable
您需要记住:
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。
我已经成功地测试了上述场景。
请让我知道这是否有帮助。
推荐阅读
- javascript - 如何重命名猫鼬中的字段?
- php - 非法偏移类型(查看:/code/resources/views/emergencia/nuevo.blade.php)
- python - “将数据聚合到每周级别,以便每个产品周组合有一行”是什么意思,我如何使用 python(熊猫)来做到这一点
- mosquitto - mosquitto_pub 配置文件格式
- python - 使用正则表达式的 Python Glob 原始目录
- flutter - Flutter 中的 StatefulBuilder VS StatefulWidget - 性能
- python - 如何在字节字符串中的表达式'\ xb'之后提取数值
- flutter - 如何最好地在 for-in 循环中进行空检查?
- python - 寻找大型稀疏矩阵的最小特征向量,在 SciPy 中比在 Octave 中慢 100 倍以上
- google-cloud-platform - 在 Windows 10 上安装 Google Cloud SDK 失败