生产环境实践
生产环境实践
高可用架构
集群架构设计
┌─────────────────────────────────────────────┐
│ Load Balancer (HA) │
│ (keepalived + haproxy) │
└───────────────┬─────────────────────────────┘
│
┌───────────┴───────────┬─────────────┐
│ │ │
┌───▼────┐ ┌────▼───┐ ┌────▼───┐
│Master-1│ │Master-2│ │Master-3│
│ etcd │ │ etcd │ │ etcd │
└────────┘ └────────┘ └────────┘
│ │ │
└───────────┬───────────┴─────────────┘
│
┌───────────┴───────────┬─────────────┐
│ │ │
┌───▼────┐ ┌────▼───┐ ┌────▼───┐
│Worker-1│ │Worker-2│ │Worker-N│
└────────┘ └────────┘ └────────┘
控制平面高可用
最低配置:
- Master 节点:3 个(奇数个,支持容错)
- etcd 节点:3 个(与 Master 共存或独立部署)
- Load Balancer:2 个(主备模式)
kubeadm 高可用部署:
# 在第一个 Master 节点
kubeadm init --control-plane-endpoint "lb.example.com:6443" \
--upload-certs \
--pod-network-cidr=10.244.0.0/16
# 保存输出的 join 命令和证书密钥
# 在其他 Master 节点
kubeadm join lb.example.com:6443 \
--token <token> \
--discovery-token-ca-cert-hash sha256:<hash> \
--control-plane \
--certificate-key <cert-key>
# 在 Worker 节点
kubeadm join lb.example.com:6443 \
--token <token> \
--discovery-token-ca-cert-hash sha256:<hash>
负载均衡配置
HAProxy 配置:
# /etc/haproxy/haproxy.cfg
global
log /dev/log local0
maxconn 4096
chroot /var/lib/haproxy
user haproxy
group haproxy
daemon
defaults
log global
mode tcp
option tcplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
frontend k8s-api
bind *:6443
mode tcp
default_backend k8s-api-backend
backend k8s-api-backend
mode tcp
balance roundrobin
option tcp-check
server master-1 192.168.1.11:6443 check fall 3 rise 2
server master-2 192.168.1.12:6443 check fall 3 rise 2
server master-3 192.168.1.13:6443 check fall 3 rise 2
Keepalived 配置:
# /etc/keepalived/keepalived.conf
vrrp_script check_haproxy {
script "/usr/bin/killall -0 haproxy"
interval 2
weight 2
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1234
}
virtual_ipaddress {
192.168.1.100
}
track_script {
check_haproxy
}
}
etcd 高可用
# 检查 etcd 集群状态
ETCDCTL_API=3 etcdctl \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
member list
# 检查健康状态
ETCDCTL_API=3 etcdctl \
--endpoints=https://192.168.1.11:2379,https://192.168.1.12:2379,https://192.168.1.13:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
endpoint health
# 备份 etcd
ETCDCTL_API=3 etcdctl snapshot save /backup/etcd-snapshot-$(date +%Y%m%d-%H%M%S).db
# 恢复 etcd
ETCDCTL_API=3 etcdctl snapshot restore snapshot.db \
--data-dir=/var/lib/etcd-restore
容量规划
节点规格建议
Master 节点:
生产环境:
- CPU: 4 核以上
- 内存: 8GB 以上
- 磁盘: 100GB SSD (etcd 需要低延迟)
- 网络: 1Gbps
大规模集群(500+ 节点):
- CPU: 8 核以上
- 内存: 16GB 以上
- 磁盘: 200GB SSD
- 网络: 10Gbps
Worker 节点:
通用节点:
- CPU: 8-16 核
- 内存: 32-64GB
- 磁盘: 100GB+ SSD
- 网络: 1-10Gbps
计算密集:
- CPU: 32+ 核
- 内存: 64-128GB
内存密集:
- CPU: 16 核
- 内存: 256GB+
存储密集:
- 磁盘: 1TB+ SSD/NVMe
Pod 密度规划
# 默认限制
每个节点最多 110 个 Pod
# 调整限制(kubelet 配置)
--max-pods=250
# 计算公式
节点总 Pod 数 = 系统 Pod + 应用 Pod
# 示例
# 16 核 32GB 节点
# 系统 Pod: ~15 个
# 可用于应用: ~95 个
# 每个 Pod 平均资源: 0.16 核 / 340MB
资源配额规划
# Namespace 级别配额
apiVersion: v1
kind: ResourceQuota
metadata:
name: production-quota
namespace: production
spec:
hard:
# 计算资源
requests.cpu: "100"
requests.memory: "200Gi"
limits.cpu: "200"
limits.memory: "400Gi"
# 对象数量
pods: "500"
services: "100"
persistentvolumeclaims: "50"
# 存储
requests.storage: "1Ti"
容量监控
# Prometheus 告警规则
groups:
- name: capacity
rules:
# 节点资源使用率
- alert: NodeCPUHigh
expr: (1 - avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) by (instance)) > 0.8
for: 10m
annotations:
summary: "节点 CPU 使用率超过 80%"
# 内存使用率
- alert: NodeMemoryHigh
expr: (1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) > 0.85
for: 10m
annotations:
summary: "节点内存使用率超过 85%"
# Pod 数量接近上限
- alert: PodCountHigh
expr: count(kube_pod_info) by (node) / kube_node_status_capacity{resource="pods"} > 0.9
for: 5m
annotations:
summary: "节点 Pod 数量接近上限"
备份与恢复
备份策略
备份内容:
- etcd 数据:集群状态
- 配置文件:证书、配置
- 应用数据:PV 数据
- 自定义资源:CRD、Operator
Velero 备份方案
安装 Velero:
# 下载 Velero CLI
wget https://github.com/vmware-tanzu/velero/releases/download/v1.12.0/velero-v1.12.0-linux-amd64.tar.gz
tar -xvf velero-v1.12.0-linux-amd64.tar.gz
sudo mv velero-v1.12.0-linux-amd64/velero /usr/local/bin/
# 安装 Velero 到集群(使用 Minio 作为存储)
velero install \
--provider aws \
--plugins velero/velero-plugin-for-aws:v1.8.0 \
--bucket velero \
--secret-file ./credentials-velero \
--use-volume-snapshots=false \
--backup-location-config region=minio,s3ForcePathStyle="true",s3Url=http://minio:9000
创建备份:
# 手动备份
velero backup create full-backup --include-namespaces production,staging
# 定时备份
velero schedule create daily-backup \
--schedule="0 2 * * *" \
--include-namespaces production \
--ttl 720h0m0s
# 备份特定资源
velero backup create nginx-backup \
--selector app=nginx \
--include-resources deployment,service,configmap
# 排除某些资源
velero backup create app-backup \
--include-namespaces production \
--exclude-resources events,pods
恢复备份:
# 查看备份
velero backup get
# 恢复完整备份
velero restore create --from-backup full-backup
# 恢复到不同 namespace
velero restore create --from-backup prod-backup \
--namespace-mappings production:production-restore
# 仅恢复特定资源
velero restore create --from-backup full-backup \
--include-resources deployment,service
# 查看恢复状态
velero restore get
velero restore describe <restore-name>
etcd 定时备份
# 创建备份脚本
cat > /usr/local/bin/etcd-backup.sh << 'EOF'
#!/bin/bash
BACKUP_DIR=/backup/etcd
DATE=$(date +%Y%m%d-%H%M%S)
ENDPOINTS="https://127.0.0.1:2379"
mkdir -p $BACKUP_DIR
ETCDCTL_API=3 etcdctl \
--endpoints=$ENDPOINTS \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
snapshot save $BACKUP_DIR/etcd-snapshot-$DATE.db
# 保留最近 7 天的备份
find $BACKUP_DIR -name "etcd-snapshot-*.db" -mtime +7 -delete
echo "Backup completed: etcd-snapshot-$DATE.db"
EOF
chmod +x /usr/local/bin/etcd-backup.sh
# 添加到 crontab
crontab -e
# 每天凌晨 2 点备份
0 2 * * * /usr/local/bin/etcd-backup.sh >> /var/log/etcd-backup.log 2>&1
集群升级
升级前准备
# 1. 备份集群
velero backup create pre-upgrade-backup --wait
# 2. 检查集群状态
kubectl get nodes
kubectl get pods --all-namespaces
kubectl get componentstatuses
# 3. 查看当前版本
kubectl version
kubeadm version
# 4. 检查可升级版本
apt update
apt-cache madison kubeadm
升级 Master 节点
# 在第一个 Master 节点
# 1. 升级 kubeadm
apt-mark unhold kubeadm
apt-get update && apt-get install -y kubeadm=1.28.0-00
apt-mark hold kubeadm
# 2. 检查升级计划
kubeadm upgrade plan
# 3. 执行升级
kubeadm upgrade apply v1.28.0
# 4. 驱逐 Pod
kubectl drain master-1 --ignore-daemonsets --delete-emptydir-data
# 5. 升级 kubelet 和 kubectl
apt-mark unhold kubelet kubectl
apt-get update && apt-get install -y kubelet=1.28.0-00 kubectl=1.28.0-00
apt-mark hold kubelet kubectl
# 6. 重启 kubelet
systemctl daemon-reload
systemctl restart kubelet
# 7. 恢复调度
kubectl uncordon master-1
# 在其他 Master 节点重复以下步骤
kubeadm upgrade node
# 然后重复步骤 4-7
升级 Worker 节点
# 在 Worker 节点
# 1. 升级 kubeadm
apt-mark unhold kubeadm
apt-get update && apt-get install -y kubeadm=1.28.0-00
apt-mark hold kubeadm
# 2. 升级配置
kubeadm upgrade node
# 3. 驱逐 Pod(在 Master 执行)
kubectl drain worker-1 --ignore-daemonsets --delete-emptydir-data
# 4. 升级 kubelet
apt-mark unhold kubelet kubectl
apt-get update && apt-get install -y kubelet=1.28.0-00 kubectl=1.28.0-00
apt-mark hold kubelet kubectl
# 5. 重启 kubelet
systemctl daemon-reload
systemctl restart kubelet
# 6. 恢复调度(在 Master 执行)
kubectl uncordon worker-1
回滚策略
# 如果升级失败,回滚步骤
# 1. 停止升级
kubectl uncordon <node-name>
# 2. 恢复 etcd 备份
ETCDCTL_API=3 etcdctl snapshot restore /backup/etcd-snapshot.db \
--data-dir=/var/lib/etcd-restore
# 3. 降级软件包
apt-get install -y --allow-downgrades \
kubeadm=1.27.0-00 \
kubelet=1.27.0-00 \
kubectl=1.27.0-00
# 4. 重启服务
systemctl daemon-reload
systemctl restart kubelet
灾备方案
多区域部署
# 跨区域 Pod 反亲和性
apiVersion: apps/v1
kind: Deployment
metadata:
name: critical-app
spec:
replicas: 6
template:
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app: critical-app
topologyKey: topology.kubernetes.io/zone
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
preference:
matchExpressions:
- key: topology.kubernetes.io/zone
operator: In
values:
- zone-a
- zone-b
- zone-c
异地容灾
Federation V2 (KubeFed):
# 安装 KubeFed
helm repo add kubefed-charts https://raw.githubusercontent.com/kubernetes-sigs/kubefed/master/charts
helm install kubefed kubefed-charts/kubefed --namespace kube-federation-system --create-namespace
# 加入集群
kubefedctl join cluster1 --cluster-context cluster1 --host-cluster-context cluster1
kubefedctl join cluster2 --cluster-context cluster2 --host-cluster-context cluster1
# 联邦化资源
kubectl apply -f - <<EOF
apiVersion: types.kubefed.io/v1beta1
kind: FederatedDeployment
metadata:
name: myapp
namespace: default
spec:
template:
metadata:
labels:
app: myapp
spec:
replicas: 3
template:
spec:
containers:
- name: myapp
image: myapp:v1
placement:
clusters:
- name: cluster1
- name: cluster2
EOF
运维最佳实践
1. 变更管理
# 变更前检查清单
☐ 在测试环境验证
☐ 创建完整备份
☐ 准备回滚方案
☐ 通知相关人员
☐ 选择低峰时段
☐ 准备监控大盘
# 变更中
☐ 遵循变更流程
☐ 逐个节点操作
☐ 实时监控指标
☐ 记录操作日志
# 变更后
☐ 验证功能正常
☐ 检查监控指标
☐ 更新文档
☐ 复盘总结
2. 监控告警
# 关键指标监控
- API Server 可用性
- etcd 性能
- 节点健康状态
- Pod 状态
- 资源使用率
- 网络延迟
# 告警级别
Critical: 影响服务可用性,需立即处理
Warning: 需要关注,计划处理
Info: 仅记录,不需处理
3. 日常巡检
#!/bin/bash
# 每日健康检查脚本
echo "=== Cluster Health Check ==="
echo "Date: $(date)"
echo -e "\n1. Node Status:"
kubectl get nodes
echo -e "\n2. Component Status:"
kubectl get componentstatuses
echo -e "\n3. Pod Status:"
kubectl get pods --all-namespaces | grep -v Running | grep -v Completed
echo -e "\n4. Failed Pods:"
kubectl get pods --all-namespaces --field-selector=status.phase=Failed
echo -e "\n5. Recent Events:"
kubectl get events --all-namespaces --sort-by='.lastTimestamp' | tail -20
echo -e "\n6. Resource Usage:"
kubectl top nodes
kubectl top pods --all-namespaces --sort-by=memory | head -10
echo -e "\n7. Certificate Expiration:"
kubeadm certs check-expiration
echo -e "\n8. etcd Health:"
ETCDCTL_API=3 etcdctl endpoint health \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key
4. 性能优化
# API Server 优化
--max-requests-inflight=800
--max-mutating-requests-inflight=400
--event-ttl=1h
# etcd 优化
--quota-backend-bytes=8589934592 # 8GB
--auto-compaction-retention=1
--snapshot-count=10000
# kubelet 优化
--max-pods=250
--pods-per-core=10
--kube-api-qps=50
--kube-api-burst=100
5. 成本优化
# 资源利用率分析
kubectl top nodes
kubectl describe node <node-name> | grep "Allocated resources" -A 10
# 清理未使用资源
kubectl delete pods --field-selector=status.phase=Failed -A
kubectl delete pods --field-selector=status.phase=Succeeded -A
# 使用 Spot/Preemptible 实例
# 为非关键工作负载使用低成本节点
# 启用 Cluster Autoscaler
# 自动调整节点数量
检查清单
上线前检查
- ✅ 高可用配置(3+ Master)
- ✅ 负载均衡配置
- ✅ 网络插件安装
- ✅ 存储类配置
- ✅ Ingress Controller
- ✅ 监控系统部署
- ✅ 日志收集配置
- ✅ 备份策略就绪
- ✅ RBAC 配置
- ✅ Network Policy
- ✅ 资源配额设置
- ✅ Pod Security Policy
- ✅ 审计日志启用
- ✅ 证书有效期检查
- ✅ 灾备方案测试
日常运维检查
- ✅ 每日健康巡检
- ✅ 资源使用监控
- ✅ 备份成功验证
- ✅ 告警响应及时
- ✅ 日志审查
- ✅ 安全扫描
- ✅ 性能分析
- ✅ 容量规划
- ✅ 文档更新
小结
生产环境 Kubernetes 集群需要全方位考虑:
可用性:
- 高可用架构设计
- 多可用区部署
- 负载均衡和故障转移
- 定期演练灾备
可靠性:
- 完善的备份策略
- 经过测试的恢复流程
- 平滑的升级方案
- 可控的回滚机制
可观测性:
- 全面的监控覆盖
- 及时的告警通知
- 完整的日志收集
- 清晰的性能指标
安全性:
- 多层安全防护
- 最小权限原则
- 定期安全审计
- 合规性保障
可维护性:
- 标准化的变更流程
- 详细的运维文档
- 自动化运维工具
- 持续优化改进
成本优化:
- 合理的资源规划
- 弹性伸缩策略
- 定期成本分析
- 资源利用优化
关键原则:
- 预防胜于治疗:做好容量规划和风险评估
- 自动化优先:减少人工操作,降低出错概率
- 持续改进:定期复盘,不断优化流程
- 文档先行:记录所有关键配置和操作步骤
- 测试充分:在测试环境充分验证后再上生产
Kubernetes 生产环境运维是一个持续的过程,需要团队协作、技术积累和经验总结。
🎉 恭喜!你已完成 Kubernetes 完整教程!
从入门到实战,你已经掌握了:
- ✅ Kubernetes 核心概念和架构
- ✅ 基础资源的使用和管理
- ✅ 高级特性和调度策略
- ✅ 生产环境最佳实践
下一步建议:
- 搭建自己的 Kubernetes 集群
- 部署实际项目到 K8s
- 参与开源社区贡献
- 考取 CKA/CKAD 认证
- 持续关注云原生技术发展
祝你在云原生的道路上越走越远!🚀