一、为什么需要高可用架构

想象一下你正在运营一个电商网站,突然某个服务器宕机了,整个网站无法访问,用户无法下单,老板急得直跳脚。这就是单点故障的可怕之处。高可用架构就是为了解决这个问题,让系统即使部分组件失效也能继续提供服务。

Kubernetes作为容器编排的事实标准,本身已经具备一定的容错能力。但要让整个集群真正实现高可用,还需要在多个层面进行精心设计。这就像建造一座大桥,不仅要考虑单个桥墩的坚固程度,还要确保即使某个桥墩垮塌,整座桥也不会坍塌。

二、高可用架构的核心要素

要实现真正的高可用,我们需要关注三个关键点:

  1. 控制平面高可用:包括API Server、Controller Manager、Scheduler等核心组件
  2. 工作节点高可用:确保应用实例分布在多个节点上
  3. 数据存储高可用:etcd集群的可靠性和持久化

这就像是一个三脚凳,缺了任何一条腿都会坐不稳。让我们用一个实际例子来说明:

# 技术栈:Kubernetes v1.24 + etcd v3.5
# 这是一个3节点的高可用控制平面配置示例
apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
apiServer:
  extraArgs:
    # 启用API Server的高可用特性
    endpoint-reconciler-type: lease
controllerManager:
  extraArgs:
    # 设置Controller Manager的选举参数
    leader-elect: "true"
    leader-elect-lease-duration: 15s
    leader-elect-renew-deadline: 10s
scheduler:
  extraArgs:
    # 设置Scheduler的选举参数
    leader-elect: "true"
etcd:
  external:
    endpoints:
      - "https://etcd1:2379"
      - "https://etcd2:2379"
      - "https://etcd3:2379"
    caFile: /etc/kubernetes/pki/etcd/ca.crt
    certFile: /etc/kubernetes/pki/etcd/client.crt
    keyFile: /etc/kubernetes/pki/etcd/client.key

这个配置展示了如何设置Kubernetes控制平面的高可用参数。注意leader-elect这个参数,它确保了即使某个组件实例崩溃,其他实例也能快速接管工作。

三、etcd集群的高可用实现

etcd是Kubernetes的大脑,存储着集群的所有状态数据。要实现etcd高可用,至少需要3个节点。这就像是一个三人小组做决策,即使一个人请假,其他两人也能继续工作。

下面是一个etcd集群的配置示例:

# 技术栈:etcd v3.5
# etcd节点1的配置
name: etcd1
data-dir: /var/lib/etcd
initial-cluster: etcd1=https://10.0.0.1:2380,etcd2=https://10.0.0.2:2380,etcd3=https://10.0.0.3:2380
initial-cluster-token: my-etcd-cluster
initial-cluster-state: new
listen-peer-urls: https://10.0.0.1:2380
listen-client-urls: https://10.0.0.1:2379,https://127.0.0.1:2379
advertise-client-urls: https://10.0.0.1:2379
advertise-peer-urls: https://10.0.0.1:2380
client-cert-auth: true
trusted-ca-file: /etc/etcd/ca.crt
cert-file: /etc/etcd/server.crt
key-file: /etc/etcd/server.key
peer-client-cert-auth: true
peer-trusted-ca-file: /etc/etcd/ca.crt
peer-cert-file: /etc/etcd/peer.crt
peer-key-file: /etc/etcd/peer.key

这个配置有几个关键点:

  • initial-cluster定义了集群的初始成员
  • listen-peer-urls指定了节点间通信的地址
  • client-cert-auth启用了基于证书的认证

四、工作节点的高可用策略

控制平面高可用只是故事的一半,我们还需要确保应用实例本身也是高可用的。Kubernetes提供了多种机制来实现这一点:

  1. 副本集(ReplicaSet):确保指定数量的Pod始终运行
  2. 部署(Deployment):支持滚动更新和回滚
  3. Pod反亲和性:避免Pod集中在少数节点上

来看一个实际的部署示例:

# 技术栈:Kubernetes v1.24
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-high-availability
spec:
  replicas: 6
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      affinity:
        podAntiAffinity:
          # 确保Pod尽量分散在不同节点上
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - nginx
            topologyKey: "kubernetes.io/hostname"
      containers:
      - name: nginx
        image: nginx:1.21
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: "100m"
            memory: "128Mi"
          limits:
            cpu: "200m"
            memory: "256Mi"

这个配置有几个亮点:

  • 设置了6个副本,确保有足够的冗余
  • 使用podAntiAffinity强制Pod分散在不同节点
  • 设置了资源限制,避免单个Pod占用过多资源

五、负载均衡与流量管理

高可用的另一个关键点是流量管理。我们需要确保:

  1. 客户端请求能正确分发到可用的Pod
  2. 故障节点能自动从服务发现中移除
  3. 支持优雅终止,避免请求中断

Kubernetes的Service和Ingress资源就是为此设计的:

# 技术栈:Kubernetes v1.24
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: LoadBalancer
  externalTrafficPolicy: Local
  healthCheckNodePort: 32456
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress
  annotations:
    nginx.ingress.kubernetes.io/affinity: "cookie"
    nginx.ingress.kubernetes.io/session-cookie-name: "route"
    nginx.ingress.kubernetes.io/session-cookie-expires: "172800"
    nginx.ingress.kubernetes.io/session-cookie-max-age: "172800"
spec:
  rules:
  - host: example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx-service
            port:
              number: 80

这个配置实现了:

  • 通过LoadBalancer类型的Service暴露服务
  • 使用externalTrafficPolicy: Local保留客户端IP
  • 通过Ingress实现基于cookie的会话保持

六、监控与自动恢复

高可用系统需要实时监控和自动恢复能力。Prometheus和Alertmanager是常用的监控方案:

# 技术栈:Prometheus Operator
apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
  name: k8s
  labels:
    prometheus: k8s
spec:
  replicas: 2
  serviceAccountName: prometheus-k8s
  serviceMonitorSelector:
    matchLabels:
      team: frontend
  ruleSelector:
    matchLabels:
      role: alert-rules
      prometheus: k8s
  alerting:
    alertmanagers:
    - namespace: monitoring
      name: alertmanager-main
      port: web
  resources:
    requests:
      memory: 400Mi
  enableAdminAPI: false

这个配置:

  • 部署了2个Prometheus实例实现冗余
  • 关联了ServiceMonitor自动发现监控目标
  • 配置了Alertmanager处理告警

七、实际应用场景分析

高可用架构适用于多种场景:

  1. 电商网站:黑五大促时不能宕机
  2. 金融服务:交易系统必须24/7可用
  3. 医疗系统:患者数据必须随时可访问

但高可用也有代价:

  • 硬件成本增加(至少3个节点)
  • 运维复杂度提高
  • 性能可能略有下降(由于数据同步开销)

八、注意事项与最佳实践

在实施高可用架构时,需要注意:

  1. 网络分区问题:确保集群有足够的网络带宽
  2. 备份策略:定期备份etcd数据
  3. 容量规划:预留足够的资源应对故障转移
  4. 测试验证:定期模拟节点故障测试系统恢复能力

九、总结

构建Kubernetes高可用集群就像组建一个可靠的团队:

  • 控制平面是管理层,需要冗余和快速故障转移
  • 工作节点是执行层,需要合理分配任务
  • etcd是记忆中枢,需要安全可靠的存储
  • 监控系统是体检医生,需要及时发现并处理问题

通过合理的架构设计和配置,我们可以构建出能够抵御各种故障的生产级Kubernetes集群,为业务提供坚实的基石。