
你有没有遇到过这样的情况?
半夜收到告警,说某个服务挂了。赶紧爬起来登录服务器,手动重启应用。
结果刚睡着,告警又来了。
反复折腾,直到天亮。
说实话,我之前也是这样。
从手动部署到自动化运维,从反复重启到零宕机更新,这条路我走了很久。
今天,我想把这套 Kubernetes Deployment 的实战经验,毫无保留地分享给你。
手动创建 Pod,就像在没有空调的房间里装电风扇。
能用,但不可靠。
节点故障时 Pod 不会自动恢复,版本更新更是噩梦。
Deployment 给你三个超能力:
先给你看一个完整的配置文件,覆盖了 90% 的常见场景。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
namespace: prod
labels:
app: nginx
version: v1
spec:
replicas: 3
revisionHistoryLimit: 10
selector:
matchLabels:
app: nginx
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
progressDeadlineSeconds: 600
template:
metadata:
labels:
app: nginx
spec:
imagePullSecrets:
- name: regcred
containers:
- name: nginx
image: nginx:1.25.3
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
env:
- name: TZ
value: "Asia/Shanghai"
- name: APP_ENV
valueFrom:
configMapKeyRef:
name: app-config
key: environment
resources:
requests:
cpu: "100m"
memory: "256Mi"
limits:
cpu: "500m"
memory: "512Mi"
livenessProbe:
httpGet:
path: /healthz
port: 80
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /ready
port: 80
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 2
volumeMounts:
- name: config-volume
mountPath: /etc/nginx/conf.d
readOnly: true
- name: cache-volume
mountPath: /var/cache/nginx
volumes:
- name: config-volume
configMap:
name: nginx-config
- name: cache-volume
emptyDir: {}
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app: nginx
topologyKey: kubernetes.io/hostname看起来有点长?
别担心,我帮你拆解一下。
replicas: 3
selector:
matchLabels:
app: nginx注意:selector.matchLabels 必须与 template.metadata.labels 完全一致,这是 Deployment 管理 Pod 的依据。
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # 最多额外创建 1 个 Pod
maxUnavailable: 0 # 不允许任何 Pod 不可用maxSurge:更新期间允许超出 replicas 的 Pod 数量。设置为 1 意味着 3 副本时最多有 4 个 Pod 同时运行。
maxUnavailable:最多允许多少个 Pod 不可用。设置为 0 实现真正的零宕机更新。
推荐配置:生产环境 maxSurge: 1, maxUnavailable: 0;测试环境可以适当放宽加速更新。
resources:
requests:
cpu: "100m" # 保证分配 100 毫核 CPU
memory: "256Mi" # 保证分配 256Mi 内存
limits:
cpu: "500m" # 最多使用 500 毫核 CPU
memory: "512Mi" # 最多使用 512Mi 内存为什么两个都要设置?
requests 影响调度决策,保证 Pod 能被调度到有足够资源的节点。
limits 防止 Pod 占用过多资源影响其他应用。
设置合理的 limits 能避免 OOMKilled,设置 requests 能避免资源争抢。
livenessProbe:
httpGet:
path: /healthz
port: 80
initialDelaySeconds: 30
periodSeconds: 10
failureThreshold: 3
readinessProbe:
httpGet:
path: /ready
port: 80
initialDelaySeconds: 5livenessProbe:容器"活"不活,不活就重启。initialDelaySeconds 要给足应用启动时间。
readinessProbe:容器能不能接流量,不能接就从 Service 摘除。这个检查要轻量快速。
常见坑:initialDelaySeconds 设置太短,应用还没启动就被反复重启。
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app: nginx
topologyKey: kubernetes.io/hostname这个配置让同一个应用的 Pod 尽量分散到不同节点,提升高可用性。
# 创建 Deployment
kubectl apply -f deployment.yaml
# 更新镜像触发滚动更新
kubectl set image deployment/nginx-deployment nginx=nginx:1.26.0
# 查看 Deployment 状态
kubectl get deployments
kubectl describe deployment nginx-deployment# 实时查看滚动更新状态
kubectl rollout status deployment/nginx-deployment
# 查看 Pod 变化
kubectl get pods -l app=nginx -w# 查看历史版本
kubectl rollout history deployment/nginx-deployment
# 回滚到上一版本
kubectl rollout undo deployment/nginx-deployment
# 回滚到指定版本
kubectl rollout undo deployment/nginx-deployment --to-revision=3# 手动扩容到 5 个副本
kubectl scale deployment/nginx-deployment --replicas=5
# 自动扩容(需要先安装 Metrics Server)
kubectl autoscale deployment/nginx-deployment --min=3 --max=10 --cpu-percent=80现象:kubectl get pods 显示 STATUS 为 Pending
排查:
kubectl describe pod <pod-name>常见原因:
解决:调整资源请求,增加节点,检查 PVC 状态
现象:Pod 启动后立即崩溃
排查:
kubectl logs <pod-name> --previous常见原因:
解决:检查应用日志,确认依赖服务可用
现象:kubectl rollout status 一直显示等待
排查:
kubectl describe deployment <deployment-name>常见原因:
解决:检查新 Pod 日志,调整探针配置,增加节点资源
现象:镜像拉取失败,Pod 无法启动
排查:
kubectl describe pod <pod-name>常见原因:
解决:确认镜像名称和 tag,创建 imagePullSecrets
kubectl create secret docker-registry regcred \
--docker-server=<registry-url> \
--docker-username=<username> \
--docker-password=<password>所有 YAML 文件纳入 Git 管理,使用 GitOps 工具(如 ArgoCD)自动部署。
在 Namespace 级别设置 ResourceQuota,防止单个应用占用过多资源。
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-quota
spec:
hard:
requests.cpu: "10"
requests.memory: 20Gi
limits.cpu: "20"
limits.memory: 40Gi配置 Prometheus 监控关键指标:
定期进行故障演练,验证自愈能力:
# 暂停滚动更新,只更新部分 Pod
kubectl rollout pause deployment/nginx-deployment
# 验证新版本无误后继续
kubectl rollout resume deployment/nginx-deployment# 创建新的 Deployment(如 nginx-deployment-blue)
# 更新 Service 的 selector 指向新的 Deployment
# 验证通过后删除旧 Deployment使用 ConfigMap 的挂载方式,更新 ConfigMap 后重启 Pod 即可生效:
kubectl create configmap nginx-config --from-file=nginx.conf
# 修改 ConfigMap
kubectl create configmap nginx-config --from-file=nginx.conf --dry-run=client -o yaml | kubectl apply -f -
# 触发 Pod 重启
kubectl rollout restart deployment/nginx-deploymentKubernetes Deployment 的核心价值在于声明式管理和自动化运维。
掌握本文的内容,你已经能够处理 90% 的生产场景。
记住三个关键:
“无他,惟手熟尔”!有需要的用起来!
如果你觉得这篇文章有用,欢迎点赞、转发、收藏、留言、推荐❤!
本文分享自 Nicholas与Pypi 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!