生产环境实践

生产环境实践

高可用架构

集群架构设计

┌─────────────────────────────────────────────┐
│            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 数量接近上限"

备份与恢复

备份策略

备份内容

  1. etcd 数据:集群状态
  2. 配置文件:证书、配置
  3. 应用数据:PV 数据
  4. 自定义资源: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 集群需要全方位考虑:

可用性

  • 高可用架构设计
  • 多可用区部署
  • 负载均衡和故障转移
  • 定期演练灾备

可靠性

  • 完善的备份策略
  • 经过测试的恢复流程
  • 平滑的升级方案
  • 可控的回滚机制

可观测性

  • 全面的监控覆盖
  • 及时的告警通知
  • 完整的日志收集
  • 清晰的性能指标

安全性

  • 多层安全防护
  • 最小权限原则
  • 定期安全审计
  • 合规性保障

可维护性

  • 标准化的变更流程
  • 详细的运维文档
  • 自动化运维工具
  • 持续优化改进

成本优化

  • 合理的资源规划
  • 弹性伸缩策略
  • 定期成本分析
  • 资源利用优化

关键原则

  1. 预防胜于治疗:做好容量规划和风险评估
  2. 自动化优先:减少人工操作,降低出错概率
  3. 持续改进:定期复盘,不断优化流程
  4. 文档先行:记录所有关键配置和操作步骤
  5. 测试充分:在测试环境充分验证后再上生产

Kubernetes 生产环境运维是一个持续的过程,需要团队协作、技术积累和经验总结。


🎉 恭喜!你已完成 Kubernetes 完整教程!

从入门到实战,你已经掌握了:

  • ✅ Kubernetes 核心概念和架构
  • ✅ 基础资源的使用和管理
  • ✅ 高级特性和调度策略
  • ✅ 生产环境最佳实践

下一步建议

  1. 搭建自己的 Kubernetes 集群
  2. 部署实际项目到 K8s
  3. 参与开源社区贡献
  4. 考取 CKA/CKAD 认证
  5. 持续关注云原生技术发展

祝你在云原生的道路上越走越远!🚀