0. 写在前面:为什么你需要“神器”而非“常用命令
大家好,欢迎来到干货、技术、专业全方位遥遥领先的老杨的博客.
帮老杨点赞、转发、在看以及打开小星标哦
攒今世之功德,修来世之福报
零停机就是用户无感知的发布。 请求不断。 连接不中断。 服务平稳切换到新版本。 重要的是用户体验不变。
听起来好听,但它不是魔法。 它靠方法、流程和反复演练。
改动要向后兼容。 流量要可控。 实例要能优雅下线。 数据库变更要可回滚。 步骤要自动化并可审计。
我会把新版本部署到绿环境。 验证无误再切流量到绿。 回滚只需把流量切回蓝。 缺点是需要额外资源。
示例:切流量命令和校验输出如下。
$ kubectl patch svc myservice -n prod -p '{"spec":{"selector":{"app":"green"}}}'
service/myservice patched$ kubectl get endpoints myservice -n prod -o wide
NAME ENDPOINTS
myservice 10.244.1.12:8080,10.244.2.15:8080这适合能承受双倍容量的场景。
把少量真实流量先丢给新版本。 观察指标后逐步放量。 我建议把错误率和 95% 延迟作为准入门槛。 用服务网格能精细控制权重。
示例:把 Canary 配置应用后的反馈。
$ kubectl apply -f virtualservice-canary.yaml -n prod
virtualservice.networking.istio.io/myservice configured金丝雀适合风险较高的功能变更。
在资源有限时使用它。 Kubernetes 按策略替换 Pod。 关键是 readiness 要做得严一点。
更新和观察命令如下。
$ kubectl set image deployment/myapp mycontainer=myapp:2025-09-01 -n prod
deployment.apps/myapp image updated
$ kubectl rollout status deployment/myapp -n prod
Waiting for rollout to finish: 2 of 3 updated...
deployment "myapp" successfully rolled out滚动时要保证旧实例能处理未完成的请求。
readiness 决定实例是否能接流量。 liveness 决定容器是否需要重启。 preStop 用来给应用清理并排尽连接。
下面是常见的配置片段(示例保留)。
readinessProbe:
httpGet:
path: /health/ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
lifecycle:
preStransform: translateY(
exec:
command: ["/bin/sh", "-c", "sleep 10"]preStop 常用来关闭监听、等待连接数降到 0。 这样能避免半条请求在替换时被中断。
应用配置后,用下面命令部署并查看状态。
$ kubectl apply -f deployment.yaml -n prod
deployment.apps/myapp configured下线节点前先把流量排干。 Kubernetes 的 drain 可以把 Pod 驱逐并迁移。
命令与示例输出如下。
$ kubectl drain node-node01 --ignore-daemonsets --delete-local-data
node/node01 cordoned
evicting pod myapp-abcde...
pod/myapp-abcde evicted
node/node01 drained对外部负载均衡器亦同理。 先从后端池移出实例。 观察活跃连接为 0 再做维护。
数据库变更最容易翻车。 原则是小步快跑,保证可回滚。 步骤我常用三段走法:新增字段→双写回填→切读旧字段→删旧字段。
在线变更工具会把热表分片拷贝再切换。 gh-ost 的示例如下。
$ gh-ost \
--user="ghuser" --password="ghpass" \
--host="db-master" --database="mydb" --table="orders" \
--alter="ADD COLUMN new_flag TINYINT(1) DEFAULT 0" \
--allow-on-master --execute模拟输出示例:
INFO Migrating table orders
INFO Ghost table created: _orders_gho
INFO Applying row-copy...
INFO Cut-over completed.工具会逐步复制行并最小化锁定窗口。 不要在高峰期做大范围结构变更。
每次发布都要有秒级回滚方案。 Kubernetes 支持 rollout undo。
命令和反馈示例:
$ kubectl rollout undo deployment/myapp -n prod
deployment.apps/myapp rolled back
$ kubectl rollout status deployment/myapp -n prod
deployment "myapp" successfully rolled out回滚前要确认目标镜像、配置和 probe 都存在并可用。 回滚也要走健康检查流程,别跳过验证。
把发布流程写成 pipeline。 允许人工暂停和审查。 关键是把发布操作可审计、可回溯。
示例 GitLab CI 片段(占位):
deploy_canary:
stage: deploy
script:
- kubectl apply -f k8s/canary.yaml -n prod
- kubectl rollout status deployment/myapp-canary -n prod
when: manual手动触发能减少误发。 自动化里也要内置告警触发回滚的逻辑。
上线前做压力和功能验证。 对比错误率、延迟、连接数这三项。
一个常用的压力测试示例:
$ wrk -t2 -c200 -d30s http://myservice.prod/health
Running 30s test @ http://myservice.prod/health
2 threads and 200 connections
Requests/sec: 12000
Latency 25ms在 Canary 上重复同样测试。 对比指标差异决定是否放量。
改非兼容字段会出错。 probe 配置太宽松会把未就绪实例拉入流量池。 未排干连接就下线会造成错误。 忘记清理旧指标会误导后续分析。 缺回滚路径会拉长故障恢复时间。
这段脚本适合小团队快速发布并检查就绪。
#!/bin/bash
set -e
DEPLOY=deployment/myapp
NAMESPACE=prod
NEW_IMAGE=myapp:2025-09-01
echo "更新镜像..."
kubectl set image $DEPLOY mycontainer=$NEW_IMAGE -n $NAMESPACE
echo "等待 rollout..."
kubectl rollout status $DEPLOY -n $NAMESPACE
echo "检查 readiness..."
kubectl get pods -l app=myapp -n $NAMESPACE -o jsonpath='{range .items[*]}{.metadata.name} {.status.phase} {.status.containerStatuses[0].ready}{"\n"}{end}'
echo "发布完成"输出如下。
更新镜像...
deployment.apps/myapp image updated
等待 rollout...
deployment "myapp" successfully rolled out
myapp-abcde Running true
myapp-fghij Running true
发布完成这只是基础版。 复杂场景要接入流量网格、灰度控制和审计系统。
评论区等你们!
这里老杨先声明一下,日常生活中大家都叫老杨波哥,跟辈分没关系,主要是岁数大了.就一个代称而已. 老杨的00后小同事老杨喊都是带哥的.张哥,李哥的. 但是这个称呼呀,在线下参加一些活动时.金主爸爸也这么叫就显的不太合适. 比如上次某集团策划总监,公司开大会来一句:“今个咱高兴!有请IT运维技术圈的波哥讲两句“ 这个氛围配这个称呼在互联网这行来讲就有点对不齐! 每次遇到这个情况老杨老杨周末浅聊服务器开在公网的那些坑老杨干了,你们随意!” 所以以后咱们改叫老杨,即市井又低调.还挺亲切,老杨觉得挺好.
运维X档案系列文章:
企业级 Kubernetes 集群安全加固全攻略( 附带一键检查脚本)
看完别走.修行在于点赞、转发、在看.攒今世之功德,修来世之福报
老杨AI的号: 98dev