当前位置: 首页 > ops >正文

Kubernetes高可用架构设计:多Master节点部署与etcd集群运维深度指南

目录

引言:高可用——Kubernetes生产环境的基石

一、 Kubernetes高可用架构设计原理

1.1 为什么需要高可用架构?

1.2 高可用架构的核心目标

1.3 高可用架构的两种主流模式

模式一:堆叠(Stacked)etcd拓扑

模式二:外部(External)etcd拓扑

二、 多Master节点部署:控制平面的冗余与协作

2.1 多Master架构的核心组件与角色

2.2 核心组件的高可用实现机制

2.2.1 kube-apiserver:负载均衡是关键

2.2.2 kube-controller-manager & kube-scheduler:Leader Election保障唯一性

2.2.3 etcd:外部集群保障数据基石(详见第三部分)

2.3 多Master部署的关键配置与注意事项

2.3.1 网络规划

2.3.2 部署工具选择

2.3.3 证书管理

2.3.4 kubelet配置(Master节点)

三、 etcd集群运维:高可用的数据基石

3.1 etcd核心原理:Raft一致性协议深度解析

3.1.1 Raft核心概念

3.1.2 Raft在etcd中的关键参数与影响

3.2 etcd集群部署最佳实践(外部拓扑)

3.2.1 节点规划

3.2.2 部署步骤(以kubeadm外部etcd为例)

3.3 etcd集群日常运维核心操作

3.3.1 备份与恢复:灾难恢复的生命线

3.3.2 节点管理:扩容与缩容

3.3.3 升级与维护

3.3.4 性能监控与调优

3.3.5 安全加固

四、 实战实验:搭建高可用Kubernetes集群(外部etcd)

4.1 实验环境规划

4.2 实验步骤(30%)

步骤1:基础环境准备(所有节点)

步骤2:部署etcd集群(etcd1, etcd2, etcd3)

步骤3:部署负载均衡器(Keepalived + HAProxy)

步骤4:部署Kubernetes Master节点

步骤5:加入Worker节点(可选)

步骤6:高可用性测试

五、 总结与展望:迈向Kubernetes架构师之路

核心要点回顾

架构师成长之路


专栏: Kubernetes架构师之路:系统化学习与实践
作者: 庸子
用户ID: 2401_86478612
首发平台: CSDN

引言:高可用——Kubernetes生产环境的基石

在容器化与云原生技术席卷全球的今天,Kubernetes(K8s)已成为企业构建现代化应用基础设施的事实标准。然而,单Master节点的Kubernetes集群如同“单点故障”的定时炸弹,一旦Master节点宕机,整个集群将陷入瘫痪,导致服务中断、业务受损。高可用(High Availability, HA)架构正是解决这一痛点的核心方案,它通过冗余设计、故障转移和负载均衡,确保集群在部分组件失效时仍能持续提供服务。

本文将深入剖析Kubernetes高可用架构的核心原理,重点讲解多Master节点部署的架构设计与实现细节,并聚焦于集群状态存储大脑——etcd集群的运维实践。我们将遵循70%理论深度与30%实战验证的原则,为您构建从理论到实践的完整知识体系,助您迈向Kubernetes架构师之路。

一、 Kubernetes高可用架构设计原理

1.1 为什么需要高可用架构?

  • 单点故障风险: 单Master节点承载着API Server、Controller Manager、Scheduler等核心组件,其故障将导致集群控制平面完全失效。
  • 业务连续性要求: 现代应用对服务可用性要求极高(如99.95%、99.99%),单Master无法满足SLA。
  • 维护窗口压力: 升级、配置变更等操作需要停机,影响业务运行。
  • 扩展性瓶颈: 单Master在处理大规模集群(节点数、Pod数激增)时,API Server可能成为性能瓶颈。

1.2 高可用架构的核心目标

  • 消除单点故障: 关键组件(Master节点、etcd)冗余部署。
  • 故障自动转移: 当主节点或组件故障时,系统能自动切换到备用节点/组件。
  • 负载均衡: 将客户端(kubectl、kubelet、调度器)请求均匀分发到多个健康的API Server实例。
  • 数据一致性: 确保集群状态(存储在etcd中)在所有节点间保持一致。
  • 最小化中断: 故障发生时,服务中断时间(RTO)和数据丢失量(RPO)尽可能小。

1.3 高可用架构的两种主流模式

Kubernetes高可用架构主要围绕控制平面(Control Plane)的冗余设计展开,核心是Master节点和etcd的部署方式。业界主要有两种成熟模式:

模式一:堆叠(Stacked)etcd拓扑
  • 架构描述: 每个Master节点上同时运行一个etcd实例。etcd实例与Master控制平面组件(API Server, Controller Manager, Scheduler)部署在同一台物理机或虚拟机上。
    • 优点:部署相对简单: 资源需求相对集中,管理节点较少。
    • 配置简化: etcd与控制平面组件间通信通常通过本地回环地址(127.0.0.1),网络配置简单。
    • 缺点:耦合度高: Master节点故障同时影响etcd和控制平面组件,风险集中。
    • 资源竞争: etcd(尤其是I/O密集型)与控制平面组件(CPU/内存密集型)争抢主机资源,可能互相影响性能。
    • 扩展性受限: 增加Master节点必须同时增加etcd节点,扩展不够灵活。
    • 故障域大: 一台主机故障同时失去一个etcd成员和一个Master节点。
  • 适用场景: 中小型集群,资源有限,对部署简易性要求高于极致隔离性。
模式二:外部(External)etcd拓扑
  • 架构描述: etcd集群独立部署在专用的服务器(或虚拟机)上,与Master控制平面节点完全分离。Master节点只运行控制平面组件。
    • 优点:高隔离性: etcd集群与控制平面组件物理或逻辑隔离,故障域分离。Master节点故障不影响etcd,etcd节点故障不影响Master(只要etcd集群仍可用)。
    • 资源优化: 可为etcd集群和Master集群分别配置最合适的硬件资源(如etcd节点使用SSD、优化网络)。
    • 独立扩展: 可根据需要独立扩展etcd集群规模(增加节点)或Master节点规模,灵活性高。
    • 性能优化: 避免etcd与控制平面组件的资源竞争,有助于提升整体性能和稳定性。
    • 运维清晰: etcd集群的运维(备份、恢复、升级、监控)与控制平面运维解耦,职责更清晰。
    • 缺点:部署复杂度高: 需要管理两套独立的集群(etcd集群、Master集群),节点数量更多,初始配置更复杂。
    • 网络要求高: etcd集群内部通信、Master节点与etcd集群之间的通信对网络延迟和稳定性要求极高。
    • 成本更高: 需要更多的服务器资源。
  • 适用场景: 生产环境首选! 中大型集群,对高可用性、性能、隔离性、扩展性有严格要求的企业级部署。

架构师视角: 对于追求极致稳定性和可扩展性的生产环境,外部etcd拓扑是强烈推荐的最佳实践。它提供了更清晰的故障边界、更优的资源利用和更灵活的运维能力。本文后续将主要基于外部etcd拓扑进行深入讲解,因其代表了生产级高可用的标准范式。

二、 多Master节点部署:控制平面的冗余与协作

2.1 多Master架构的核心组件与角色

在多Master(外部etcd)架构中,控制平面由多个Master节点组成,每个节点运行相同的核心组件:

  • kube-apiserver: 集群的唯一入口,提供RESTful API,负责处理所有资源对象的增删改查(CRUD)操作,是状态变更的发起者和协调者。高可用关键点: 需要负载均衡。
  • kube-controller-manager: 运行控制器进程,负责维护集群的期望状态(如Pod副本数、节点状态、服务端点等)。通过Leader Election机制确保同一时间只有一个实例在工作。高可用关键点: Leader Election。
  • kube-scheduler: 负责为新创建的Pod选择合适的Node节点进行调度。同样通过Leader Election确保只有一个活跃调度器。高可用关键点: Leader Election。
  • kubelet(可选但推荐): 在Master节点上运行kubelet,使其本身也成为集群的一个Node。这有助于监控Master节点自身状态(如通过Node对象),并允许在Master节点上运行系统级Pod(如监控Agent、网络插件DaemonSet)。高可用关键点: 提升Master节点可观测性和管理能力。
  • 容器运行时(Container Runtime): 如containerd、CRI-O、Docker Engine(已弃用),负责运行容器。高可用关键点: 稳定可靠的运行时环境。

2.2 核心组件的高可用实现机制

2.2.1 kube-apiserver:负载均衡是关键
  • 问题: 客户端(kubectl, kubelet, scheduler, controllers)需要访问API Server。多个API Server实例如何被统一访问?如何确保请求只发往健康的实例?
      • 解决方案: 负载均衡器(Load Balancer)作用:提供一个虚拟IP(VIP) 或稳定的DNS名称作为集群API Server的统一入口。
      • 监控后端多个API Server实例的健康状态(通常通过TCP端口检查或HTTP健康检查端点,如/healthz)。
      • 将进入的客户端请求智能分发到当前健康的API Server实例上(常用算法:轮询Round Robin、最少连接Least Connections)。
      • 在检测到某个API Server实例故障时,自动将其从服务池中移除,停止向其转发流量。
      • 实现方式:硬件负载均衡器: F5 BIG-IP, Citrix ADC等。性能强大,功能丰富,成本高。
        • 软件负载均衡器:云厂商LB: AWS NLB/ALB, GCP Internal TCP/UDP LB, Azure Load Balancer。与云平台深度集成,管理便捷。
          • 开源软件:HAProxy: 高性能、高可靠性的TCP/HTTP负载均衡器,配置灵活,是Kubernetes HA部署的经典选择。
          • Nginx: 功能强大的Web服务器和反向代理,也可配置为TCP/UDP负载均衡器。
          • Keepalived + HAProxy/Nginx: Keepalived负责实现VIP的高可用(使用VRRP协议),配合HAProxy/Nginx提供实际的后端服务健康检查和负载分发。这是在私有云或裸金属环境中非常流行的纯软件高可用方案。
      • 配置要点:健康检查: 必须配置准确的健康检查(如检查API Server的/healthz端点),确保故障实例被及时剔除。
      • 会话保持(Session Affinity): 通常需要禁用! Kubernetes API设计是无状态的,客户端应能连接到任何健康的API Server实例。启用会话保持可能导致请求集中到某个实例,破坏负载均衡效果,并在该实例故障时导致大量会话中断。
      • 超时设置: 合理设置连接超时、服务器超时等参数,避免因个别慢请求影响整体性能。
      • SSL/TLS终结: 负载均衡器可以配置为SSL终结点(处理HTTPS流量),将解密后的HTTP流量转发给后端API Server(使用HTTP),简化后端证书管理。也可配置为SSL透传(Pass-Through),将加密流量直接转发给后端API Server处理。
2.2.2 kube-controller-manager & kube-scheduler:Leader Election保障唯一性
  • 问题: Controller Manager和Scheduler的设计原则是同一时间只能有一个活跃实例在工作。如果多个实例同时运行,它们会竞争修改同一资源(如尝试调度同一个Pod到不同节点),导致状态混乱甚至数据损坏。如何在多个实例中选出唯一的Leader?
    • 解决方案: Leader Election(领导者选举)原理: 所有Controller Manager/Scheduler实例启动时,都会尝试在etcd中创建一个特定的资源锁(Resource Lock)(通常是Lease对象或Endpoint对象)。第一个成功创建锁的实例成为Leader。其他实例成为Candidate(候选者)。
    • 续租(Lease Renewal): Leader实例需要定期(如几秒一次)更新(续租)这个锁,表明自己仍然存活。
    • 故障检测与重新选举: Candidate实例会持续监听这个锁的状态。如果发现锁在指定时间内(如15秒)没有被更新(Leader故障或网络分区),它们会认为Leader已失效,并立即尝试重新获取锁。第一个成功获取锁的Candidate成为新的Leader。
    • 实现: Kubernetes提供了k8s.io/client-go/tools/leaderelection包,组件通过配置--leader-elect=true(默认启用)即可自动参与选举。选举使用的资源对象、租约时长等参数可配置(如--leader-elect-resource-lock, --leader-elect-lease-duration)。
    • 高可用效果: 当Leader实例所在的Master节点故障或组件崩溃时,其他Candidate实例会快速(通常在几秒到十几秒内)检测到并选举出新的Leader,恢复控制功能。整个过程对用户透明,集群控制能力得以持续。
2.2.3 etcd:外部集群保障数据基石(详见第三部分)

etcd作为集群的唯一可信数据源,其高可用是整个Kubernetes集群高可用的绝对前提。在多Master(外部etcd)架构中,etcd以独立集群形式部署,通常由3或5个(推荐奇数个)节点组成,利用Raft协议保证数据一致性和高可用。

2.3 多Master部署的关键配置与注意事项

2.3.1 网络规划
  • Master节点间网络: Master节点之间需要稳定、低延迟的网络通信,用于组件间协作(如Controller Manager/Scheduler的Leader Election心跳、API Server之间的状态同步)。
  • Master到etcd集群网络: 至关重要! 所有Master节点上的API Server实例必须能够稳定、低延迟地访问etcd集群的所有节点。这是API Server读写集群状态的关键路径。网络抖动或高延迟会严重影响集群性能和稳定性。建议使用专用网络或高质量的网络连接。
  • 负载均衡器网络: 负载均衡器需要能访问所有后端API Server实例的健康检查端口(通常6443)。客户端(用户、kubelet、其他组件)需要能访问负载均衡器的VIP/DNS。
  • Node节点到API Server网络: 所有工作节点(Node)上的kubelet、kube-proxy以及Pod内的应用(如果需要直接访问API Server)都需要能够访问负载均衡器提供的VIP/DNS。这是集群正常工作的基础。
2.3.2 部署工具选择
  • kubeadm: 官方推荐的集群部署工具,从v1.12版本开始原生支持高可用部署(堆叠和外部etcd模式)。通过kubeadm initkubeadm join命令配合配置文件(如kubeadm-config.yaml)可以较方便地搭建多Master集群。优点: 标准化、自动化程度高、社区支持好。缺点: 灵活性相对较低,复杂网络配置可能需要额外脚本。
  • kops: 在AWS上生产级部署Kubernetes的利器,内置完善的高可用支持(包括自动配置负载均衡器、etcd集群等)。优点: 云原生、自动化程度极高、声明式管理。缺点: 主要面向AWS,其他云平台或裸金属支持有限。
  • kubespray: 基于Ansible的集群部署工具,支持多种平台(公有云、私有云、裸金属),高度可定制,对高可用架构支持非常完善。优点: 灵活性强、平台无关、社区活跃。缺点: 需要一定的Ansible基础,配置相对复杂。
  • 手动部署: 通过下载二进制文件、编写systemd服务文件、手动配置证书和组件参数来部署。优点: 理解最深、控制最细。缺点: 极其繁琐、易出错、维护成本高,不推荐用于生产环境。

架构师建议: 对于大多数生产环境,kubeadm(外部etcd模式) 或 kubespray 是平衡易用性、标准化和灵活性的较好选择。kops是AWS用户的理想选择。

2.3.3 证书管理
  • 重要性: Kubernetes组件间通信(API Server <-> etcd, API Server <-> kubelet, kubelet <-> API Server等)以及客户端访问API Server都依赖TLS证书进行加密和认证。证书管理混乱是集群故障的常见原因。
    • 最佳实践:使用PKI: 建立或使用现有的公钥基础设施(PKI)。
    • 集中管理: 使用如cfssl, cert-manager(Kubernetes原生证书管理控制器)等工具进行证书的创建、分发、轮换自动化。
    • 明确有效期: 为所有证书设置合理的有效期(如1年),并建立自动化轮换机制。避免证书过期导致集群组件无法通信。
    • 安全存储: 私钥必须严格保密,妥善存储(如使用Kubernetes Secrets、Vault等)。
    • 最小权限原则: 为不同组件签发具有最小必要权限的证书(如API Server证书需要能访问etcd,kubelet证书需要能访问API Server)。
2.3.4 kubelet配置(Master节点)
  • 推荐配置: 在Master节点上也运行kubelet,并将其注册为集群的Node。
      • 优点:可观测性: Master节点本身的状态(如Ready状态、资源使用情况)可以通过kubectl get nodes查看,便于监控。
      • DaemonSet部署: 允许在Master节点上部署系统级DaemonSet Pod(如监控Agent Prometheus Node Exporter、日志收集Fluentd、网络插件Calico/Cilium的DaemonSet),统一管理。
      • 污点(Taints)与容忍(Tolerations): 可以给Master节点添加污点(如node-role.kubernetes.io/master:NoSchedule),防止普通业务Pod被调度到Master节点(除非Pod明确容忍该污点),保证控制平面资源。
    • 配置要点: 在kubelet的启动参数中,需要正确配置--register-node=true(默认),并提供连接API Server的证书(kubelet client cert)和CA证书。确保kubelet能通过负载均衡器的VIP访问API Server。

三、 etcd集群运维:高可用的数据基石

etcd是Kubernetes集群的唯一可信数据源,存储了集群的所有状态信息:节点信息、Pod配置、Service定义、Secret、ConfigMap、RoleBinding、Deployment状态等等。可以说,etcd的可用性和一致性直接决定了整个Kubernetes集群的可用性和一致性。运维好etcd集群是保障Kubernetes高可用的重中之重。

3.1 etcd核心原理:Raft一致性协议深度解析

etcd的高可用和强一致性能力源于其使用的Raft一致性算法。理解Raft是理解etcd运维的基础。

3.1.1 Raft核心概念
    • 节点状态:Leader(领导者): 唯一负责处理所有客户端写请求(通过API Server发起)、复制日志到Followers、提交日志条目的节点。集群中同一时间最多只有一个Leader。
    • Follower(追随者): 被动接收并复制来自Leader的日志条目。如果Leader失效,可参与选举成为Candidate。
    • Candidate(候选者): 当Follower在选举超时(election timeout)内未收到Leader的心跳时,会转变为Candidate,发起选举请求投票。
  • Term(任期): Raft将时间划分为连续的任期(Term),用单调递增的整数表示。每个Term最多选举出一个Leader。Term在Raft中充当逻辑时钟,用于检测过时的Leader(如网络分区后恢复的旧Leader)。
  • 日志(Log): etcd的核心数据结构。由按顺序编号的**日志条目(Entry)**组成。每个条目包含:
    • 命令(Command): 实际要存储的键值对数据(如/registry/pods/default/nginx 的JSON数据)。
    • Term(任期号): 该条目被Leader创建时的Term。
    1. 日志复制:客户端(API Server)向Leader发起写请求(如创建一个Pod)。
    2. Leader将请求内容(键值对操作)封装成一个日志条目,追加到自己的本地日志中。
    3. Leader将该日志条目并行的发送(AppendEntries RPC)给集群中所有的Follower。
    4. Follower收到条目后,将其追加到自己的本地日志中(如果条目索引和Term匹配),并向Leader回复成功。
    5. Leader等待大多数(Quorum,即 (N/2)+1 个节点,N为集群节点总数) 的Follower成功复制该条目后,认为该条目已提交(Committed)。
    6. Leader将已提交的条目应用到其状态机(etcd的内存B树存储),此时数据才真正可读。
    7. Leader在后续的心跳(AppendEntries RPC)中会携带已提交的最高索引,通知Followers它们也可以安全地提交并应用这些条目。
    8. Leader选举:Follower在选举超时(election timeout,随机值,如150ms-300ms) 内未收到来自Leader的AppendEntries RPC(心跳)或Candidate的RequestVote RPC。
    9. Follower递增当前Term,转变为Candidate。
    10. Candidate给自己投票,并并行地向集群中其他节点发送RequestVote RPC请求投票。
    11. 其他节点收到请求后,在以下条件下会投票给该Candidate:
      • Candidate的Term >= 自己的当前Term。
      • 自己的日志中,最后一条日志条目的Term >= Candidate的lastLogTerm,或者Term相同但索引 >= Candidate的lastLogIndex(确保新Leader的日志至少和自己一样新)。
      • 在当前Term中尚未投过票。
    12. Candidate收到大多数节点的投票后,转变为Leader,开始发送心跳(AppendEntries RPC)阻止新的选举。
    13. 如果选举超时内未获得多数票(如平票、网络分区),Candidate重新开始新一轮选举(Term递增)。
    • 安全性:选举安全: 在一个给定的Term内,最多只能选举出一个Leader。
    • Leader只追加日志: Leader从不覆盖或删除其日志中的条目,只追加。
    • 日志匹配: 如果两个日志在某个索引上的条目Term相同,那么它们在该索引之前的所有条目也完全相同。这保证了日志复制的正确性。
    • Leader完备性: 如果一个日志条目在某个Term被提交,那么它将出现在所有任期更长的Leader的日志中。这保证了已提交的数据不会丢失。
3.1.2 Raft在etcd中的关键参数与影响
  • --heartbeat-interval:Leader发送心跳(AppendEntries RPC)的间隔。影响: 较短的间隔能更快检测到Leader故障,但增加网络带宽和CPU开销。默认100ms。
  • --election-timeout:Follower触发选举的超时时间。影响: 较短的值能更快发起选举,但容易在短暂网络抖动时导致不必要的选举。默认1000ms。实际超时是此值的随机倍数(如1x-2x)。
  • --snapshot-count:触发内存快照(Snapshot)的日志条目数阈值。影响: 较小的值更频繁生成快照,减少日志大小和恢复时间,但增加I/O压力。默认100000。
  • --quota-backend-bytes:etcd后端数据库(bbolt)大小限制。影响: 达到限制后写操作将被拒绝,用于防止etcd耗尽磁盘空间。需根据集群规模和存储容量合理设置(如8GB)。

架构师理解: Raft协议通过强Leader、日志复制、多数派投票等机制,在分布式节点间实现了线性一致性(Linearizability)。这意味着:

  1. 写操作一旦被Leader确认提交(收到多数派复制成功),后续所有读操作(无论访问哪个节点)都必须能看到这个写的结果。
  2. 集群能容忍最多 (N-1)/2 个节点故障(N为节点总数)。 例如,3节点集群可容忍1个节点故障,5节点集群可容忍2个节点故障。因此,生产环境etcd集群节点数必须为奇数(3, 5, 7),且至少3个节点。

3.2 etcd集群部署最佳实践(外部拓扑)

3.2.1 节点规划
  • 节点数量: 强烈推荐3个或5个节点。 3节点提供基础高可用(容忍1节点故障),是性价比最高的选择。5节点提供更高容错能力(容忍2节点故障),但增加复杂性和资源开销。7节点及以上通常只在超大规模或特殊地理分布场景下使用。
    • 硬件要求:CPU: etcd不是CPU密集型,但Leader需要处理所有写请求和复制。建议2-4核。
    • 内存: etcd将整个数据集(包括历史版本)加载到内存中。内存大小需远大于预期数据集大小(建议至少是活跃数据集的2-4倍)。例如,如果集群数据约2GB,建议配置8GB或以上内存。内存不足会导致频繁磁盘交换,性能急剧下降。
    • 磁盘: 最关键! etcd对磁盘延迟和IOPS极其敏感。
      • 类型: 必须使用SSD(NVMe优先)! 机械硬盘(HDD)的高延迟会严重拖慢etcd性能,甚至导致集群不稳定。
      • 性能: 选择高IOPS、低延迟的SSD。关注顺序写和随机读性能。
      • 容量: 预留足够空间。除了活跃数据,还需考虑:
        • 历史版本数据(由--auto-compaction-retention控制保留时长)。
        • WAL(Write-Ahead Log)文件。
        • 快照文件。
        • 空间用于压缩和碎片整理。
        • 建议至少是预期活跃数据集的3-5倍,并设置监控(如etcd_disk_wal_fsync_duration_seconds)。
      • 专用: 强烈建议为etcd使用独立的物理磁盘或高性能云盘(如AWS io2 Block Express, GCP Hyperdisk Extreme)。 避免与操作系统日志、其他应用(如数据库)争抢I/O。
    • 网络:低延迟: etcd节点间(Raft通信)以及Master节点到etcd节点(API Server读写)的网络延迟必须尽可能低(目标 < 10ms,最好 < 5ms)。跨机房、跨地域部署需谨慎评估。
    • 高带宽: 虽然单次请求不大,但集群规模大、操作频繁时,网络带宽也可能成为瓶颈。
    • 稳定性: 网络抖动会触发不必要的Leader选举或导致操作超时。确保网络连接稳定可靠。
    • 安全: 使用TLS加密节点间通信(--peer-auto-tls或手动配置证书)。
3.2.2 部署步骤(以kubeadm外部etcd为例)
  1. 准备环境: 准备3台(或5台)满足硬件要求的专用服务器/虚拟机。安装操作系统(如Ubuntu 20.04/22.04, CentOS 7/8/9),配置好主机名、网络(静态IP)、时间同步(NTP)、防火墙规则(开放2379客户端端口,2380集群通信端口)。
  2. 安装etcd: 在每台etcd节点上安装etcd二进制文件(下载官方Release包或使用包管理器如apt install etcd)。
  3. 生成证书: 为etcd集群生成TLS证书:
    • CA证书: 用于签发etcd服务器和客户端证书。
    • 服务器证书(Peer Cert): 用于etcd节点间通信(2380端口)。需包含所有etcd节点的IP和主机名作为SAN(Subject Alternative Name)。
    • 客户端证书(Client Cert): 用于API Server连接etcd(2379端口)。CN通常设置为kube-apiserver
    • 工具: 使用cfssl, easyrsa, openssl等工具生成。
  4. 创建etcd配置文件: 在每个etcd节点上创建配置文件(如/etc/etcd.conf或通过systemd unit文件指定参数)。关键参数:
# 节点1 (etcd1) 示例配置
name: etcd1
data-dir: /var/lib/etcd
listen-peer-urls: https://192.168.1.101:2380  # 本地监听集群通信
listen-client-urls: https://192.168.1.101:2379, https://127.0.0.1:2379 # 本地监听客户端
initial-advertise-peer-urls: https://192.168.1.101:2380 # 告知其他节点自己的集群通信地址
advertise-client-urls: https://192.168.1.101:2379 # 告知客户端自己的访问地址
initial-cluster: etcd1=https://192.168.1.101:2380,etcd2=https://192.168.1.102:2380,etcd3=https://192.168.1.103:2380
initial-cluster-state: new
initial-cluster-token: etcd-cluster-1
# TLS配置
peer-cert-file: /etc/etcd/pki/peer.crt
peer-key-file: /etc/etcd/pki/peer.key
peer-trusted-ca-file: /etc/etcd/pki/ca.crt
peer-client-cert-auth: true
cert-file: /etc/etcd/pki/server.crt
key-file: /etc/etcd/pki/server.key
trusted-ca-file: /etc/etcd/pki/ca.crt
client-cert-auth: true
# 安全加固
auto-tls: false
peer-auto-tls: false
# 性能调优
snapshot-count: 10000
heartbeat-interval: 100
election-timeout: 1000
quota-backend-bytes: 8589934592 # 8GB
  1. 启动etcd服务: 使用systemd管理etcd服务。创建/etc/systemd/system/etcd.service文件:
[Unit]
Description=etcd key-value store
Documentation=https://github.com/etcd-io/etcd
After=network.target[Service]
Type=notify
User=etcd
Group=etcd
ExecStart=/usr/local/bin/etcd --config-file /etc/etcd.conf
Restart=on-failure
RestartSec=5s
LimitNOFILE=65536
LimitNPROC=65536[Install]
WantedBy=multi-user.target
  1. 执行systemctl daemon-reload && systemctl enable --now etcd启动服务。
  2. 验证集群状态: 在任意etcd节点或配置好证书的客户端机器上执行:
ETCDCTL_API=3 etcdctl --endpoints=https://192.168.1.101:2379,https://192.168.1.102:2379,https://192.168.1.103:2379 \--cacert=/etc/etcd/pki/ca.crt \--cert=/etc/etcd/pki/client.crt \--key=/etc/etcd/pki/client.key \endpoint health
  1. 输出应显示所有节点healthy。执行etcdctl member list查看成员状态。
  2. 部署Kubernetes Master节点: 使用kubeadm部署Master节点时,在kubeadm-config.yaml中指定外部etcd集群的端点:
apiVersion: kubeadm.k8s.io/v1beta3
kind: InitConfiguration
localAPIEndpoint:advertiseAddress: "192.168.1.11" # 本Master节点IPbindPort: 6443
---
apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
kubernetesVersion: v1.28.0
controlPlaneEndpoint: "192.168.1.100:6443" # 负载均衡器VIP:Port
etcd:external:endpoints:- https://192.168.1.101:2379- https://192.168.1.102:2379- https://192.168.1.103:2379caFile: /etc/kubernetes/pki/etcd/ca.crtcertFile: /etc/kubernetes/pki/etcd/server.crtkeyFile: /etc/kubernetes/pki/etcd/server.key
# ... 其他配置如networking, certSANs等
  1. 然后执行kubeadm init --config kubeadm-config.yaml初始化第一个Master节点。后续Master节点使用kubeadm join命令加入,并携带--control-plane标志。

3.3 etcd集群日常运维核心操作

3.3.1 备份与恢复:灾难恢复的生命线
    • 备份策略:频率: 根据集群变更频率和RPO(恢复点目标)要求确定。高活跃集群可能需要每小时甚至更频繁备份。低活跃集群可每天备份。
      • 方式:快照备份(推荐): 使用etcdctl snapshot save命令。这是最常用、最可靠的备份方式。它会创建一个包含etcd数据完整状态的点-in-time快照文件。
ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 \--cacert=/etc/etcd/pki/ca.crt \--cert=/etc/etcd/pki/client.crt \--key=/etc/etcd/pki/client.key \snapshot save /backups/etcd-snapshot-$(date +%Y%m%d%H%M%S).db
      • 数据目录备份: 直接复制--data-dir指定的整个目录(如/var/lib/etcd)。风险较高! 需确保etcd进程已停止或处于只读模式,否则可能备份到不一致的数据。不推荐作为常规备份手段。
    • 存储: 将备份文件存储在安全、可靠、异地的位置(如对象存储S3/OSS、异地备份服务器)。确保备份文件本身也受到保护(加密、访问控制)。
    • 验证: 定期(如每月)验证备份文件的可用性,尝试在测试环境中恢复。
    • 恢复操作:场景: etcd集群严重故障(如多数节点永久丢失、数据损坏)且无法修复时,需要从备份恢复整个集群。
      1. 步骤:停止所有etcd进程: 在所有etcd节点上停止etcd服务(systemctl stop etcd)。
      2. 移除旧数据目录: 在所有etcd节点上备份并移除旧的数据目录(mv /var/lib/etcd /var/lib/etcd.bak)。
      3. 恢复数据到第一个节点: 选择一个节点(通常是etcd1),使用etcdctl snapshot restore命令将快照恢复到其数据目录:
ETCDCTL_API=3 etcdctl snapshot restore /backups/etcd-snapshot-20230825120000.db \--name etcd1 \--initial-cluster etcd1=https://192.168.1.101:2380,etcd2=https://192.168.1.102:2380,etcd3=https://192.168.1.103:2380 \--initial-cluster-token etcd-cluster-1 \--initial-advertise-peer-urls https://192.168.1.101:2380 \--data-dir /var/lib/etcd
        • 关键: --initial-cluster必须包含所有成员(包括后续要加入的节点)的初始信息,且名称和URL必须与原集群一致(或按新规划配置)。
      1. 启动第一个节点: 在恢复数据的节点(etcd1)上启动etcd服务(systemctl start etcd)。此时它将成为单节点集群的Leader。
      2. 添加其他成员: 在其他节点(etcd2, etcd3)上,不要再次执行restore!而是使用etcdctl member add命令将它们作为新成员添加到已恢复的单节点集群中:
# 在etcd2节点上,先启动一个临时的单点etcd(仅用于加入集群)
# 然后在etcd1节点或任意有权限的客户端上执行:
ETCDCTL_API=3 etcdctl --endpoints=https://192.168.1.101:2379 \--cacert=/etc/etcd/pki/ca.crt \--cert=/etc/etcd/pki/client.crt \--key=/etc/etcd/pki/client.key \member add etcd2 --peer-urls=https://192.168.1.102:2380
      1. 命令会输出etcd2节点启动时需要的--initial-cluster--initial-cluster-state参数。在etcd2节点上使用这些参数启动etcd服务(无需restore)。
      2. 重复步骤5: 为etcd3节点执行member add并启动服务。
      3. 验证集群: 使用etcdctl endpoint healthmember list验证集群是否恢复为3节点健康状态。
    • 影响: 恢复操作会导致集群状态回退到备份时间点。在备份时间点之后发生的所有变更(如新创建的Pod、更新的配置)都会丢失。这是恢复的固有代价(RPO)。
3.3.2 节点管理:扩容与缩容
  • 添加节点(扩容):
    • 场景: 提升集群容错能力(如从3节点扩到5节点)或增加读吞吐量。
      1. 步骤:准备新节点: 按照部署要求准备新服务器(硬件、OS、网络、证书)。
      2. 获取加入信息: 在现有集群的任意Leader节点上,使用etcdctl member add命令添加新成员:
ETCDCTL_API=3 etcdctl --endpoints=https://192.168.1.101:2379 \--cacert=/etc/etcd/pki/ca.crt \--cert=/etc/etcd/pki/client.crt \--key=/etc/etcd/pki/client.key \member add etcd4 --peer-urls=https://192.168.1.104:2380
      1. 命令会输出新节点启动所需的--initial-cluster(包含所有成员,包括新成员)和--initial-cluster-state=existing
      2. 启动新节点: 在新节点(etcd4)上,使用上一步输出的参数启动etcd服务(无需执行snapshot restore)。
      3. 验证: 使用etcdctl member list确认新节点状态变为startedendpoint health确认其健康。
    • 注意: 扩容会增加Raft协议的通信开销(需要更多节点达成共识),可能略微降低写延迟。扩容后需更新所有Kubernetes Master节点配置中指向etcd的端点列表(如果之前未包含新节点)。
  • 移除节点(缩容):
    • 场景: 节点硬件故障且无法修复、降低成本、调整集群规模。
      1. 步骤:确认移除目标: 确定要移除的节点ID(通过etcdctl member list获取)。
      2. 移除成员: 在集群的任意Leader节点上,使用etcdctl member remove命令:
ETCDCTL_API=3 etcdctl --endpoints=https://192.168.1.101:2379 \--cacert=/etc/etcd/pki/ca.crt \--cert=/etc/etcd/pki/client.crt \--key=/etc/etcd/pki/client.key \member remove <member_id>
      1. 停止节点服务: 在被移除的节点上停止etcd服务(systemctl stop etcd)。
      2. 清理数据: (可选但推荐)备份并移除该节点上的etcd数据目录(/var/lib/etcd)。
      3. 验证: 使用etcdctl member list确认该节点已从列表中消失,endpoint health确认剩余节点健康。
    • 关键: 移除节点后,集群的可用节点数必须仍然满足多数派要求(> N/2)! 例如,3节点集群移除1个节点后,剩余2个节点,仍能工作(2 > 3/2)。但5节点集群移除2个节点后,剩余3个节点(3 > 5/2),仍可工作。如果5节点集群移除3个节点,剩余2个节点(2 <= 5/2),集群将失去法定人数(Quorum),无法进行写操作或选举新Leader,集群只读,需要恢复或添加节点。因此,缩容操作必须谨慎,确保剩余节点数 > N/2。
3.3.3 升级与维护
  • 版本兼容性: 严格遵循etcd官方的版本兼容性策略。通常只支持升级到次版本(minor version),不支持跨主版本(major version)升级(如v3.4直接升级到v3.6)。升级前务必阅读目标版本的Release Notes。
    1. 滚动升级(推荐):备份: 升级前必须进行完整备份!
    2. 升级顺序: 一次升级一个节点。强烈建议从Follower节点开始,最后升级Leader节点。
    3. 步骤(单个节点):
    4. a. 在待升级节点上停止etcd服务(systemctl stop etcd)。
    5. b. 备份etcd二进制文件和数据目录(cp /usr/local/bin/etcd /usr/local/bin/etcd.bak)。
    6. c. 下载并替换为新版本的etcd二进制文件。
    7. d. 启动etcd服务(systemctl start etcd)。
    8. e. 使用etcdctl endpoint status --clusteretcdctl version确认该节点已升级并加入集群。
    9. 重复: 对下一个节点重复步骤3,直到所有节点升级完毕。
    10. 验证: 确认整个集群版本一致,功能正常。
  • 维护窗口: 对于关键业务,选择低峰期进行升级。虽然滚动升级能保持集群可用,但升级过程中短暂的网络分区或节点重启可能对性能有轻微影响。
  • 降级: 官方不支持降级! 升级后如遇问题,通常需要回滚到备份或寻求其他解决方案。
3.3.4 性能监控与调优
      • 关键监控指标(Prometheus + Grafana):集群健康:etcd_server_has_leader: 1表示有Leader,0表示无(集群不可用)。
      • etcd_server_leader_changes_seen_total: Leader变更次数。频繁变更说明集群不稳定(网络、资源问题)。
      • etcd_disk_wal_fsync_duration_seconds: WAL文件fsync操作耗时。核心指标! 持续高值(如>100ms)表明磁盘性能瓶颈。
      • etcd_mvcc_db_total_size_in_bytes: etcd后端数据库大小。监控增长趋势,避免达到--quota-backend-bytes限制。
      • 延迟:etcd_disk_backend_commit_duration_seconds: 后端数据库提交耗时。反映写性能。
      • etcd_network_peer_round_trip_time_seconds: 节点间Raft消息往返时间。反映网络延迟。
      • etcd_grpc_proxy_unary_requests_duration_seconds: API请求处理延迟(通过grpc-proxy)。
      • 吞吐量:etcd_grpc_proxy_unary_requests_total: API请求总数(按方法分类)。
      • etcd_debugging_mvcc_keys_total: 键值对总数。
      • etcd_debugging_mvcc_put_total: 写操作总数。
      • 资源:process_cpu_seconds_total: CPU使用率。
      • process_resident_memory_bytes: 内存使用量(RSS)。
      • process_virtual_memory_bytes: 虚拟内存使用量。
      • etcd_disk_wal_fsync_duration_seconds (再次强调): 磁盘I/O延迟。
    • 调优建议:磁盘: 优先解决etcd_disk_wal_fsync_duration_seconds高的问题。升级到更快的SSD(NVMe),确保磁盘专用,检查文件系统(推荐ext4/xfs),关闭磁盘写缓存(如果控制器支持电池备份)。
    • 内存: 确保内存充足,避免交换(swap)。监控etcd_mvcc_db_total_size_in_bytes,必要时增加内存或调整--auto-compaction-retention减少历史数据保留。
    • 网络: 优化网络配置,确保低延迟、高带宽。检查防火墙、QoS设置。
    • Raft参数: 在极端情况下,可微调--heartbeat-interval(默认100ms)和--election-timeout(默认1000ms)。需谨慎! 过短的值可能增加不必要的选举和网络开销。通常默认值在大多数场景下工作良好。
    • 客户端: 优化Kubernetes组件(如API Server)的etcd客户端缓存(--etcd-servers-overrides),减少不必要的etcd请求。使用etcdctl--endpoints负载均衡到多个etcd节点。
    • 压缩: 定期执行etcdctl compact手动压缩历史版本(或依赖--auto-compaction-retention自动压缩),减少数据库大小。压缩后执行etcdctl defrag碎片整理回收空间。
3.3.5 安全加固
  • TLS: 强制启用TLS加密所有通信(客户端-服务器、服务器-服务器)。使用强密码套件,定期轮换证书。
    • 认证与授权:启用客户端证书认证(--client-cert-auth=true)。
    • 配置基于用户名/密码的认证(--auth-token-ttl)。
    • 启用RBAC(Role-Based Access Control),为不同用户/服务(如kube-apiserver)分配最小必要权限。
  • 网络隔离: 使用防火墙(iptables, firewalld, 云安全组)严格限制访问etcd端口(2379, 2380)的源IP地址。只允许Master节点(API Server)和必要的运维工具访问2379;只允许etcd节点之间访问2380。
  • 审计日志: 启用etcd审计日志(--log-package-levels=etcdserver=debug或更高版本支持审计配置),记录所有关键操作,用于安全审计和故障排查。
  • 定期更新: 及时跟进etcd安全补丁和版本更新。

四、 实战实验:搭建高可用Kubernetes集群(外部etcd)

4.1 实验环境规划

    • 节点角色与IP:etcd节点 (3台):etcd1 (192.168.1.101), etcd2 (192.168.1.102), etcd3 (192.168.1.103)
    • Master节点 (3台):master1 (192.168.1.11), master2 (192.168.1.12), master3 (192.168.1.13)
    • 负载均衡器 (VIP):192.168.1.100 (使用Keepalived + HAProxy实现)
    • Worker节点 (2台,可选):worker1 (192.168.1.21), worker2 (192.168.1.22)
    • 软件版本:OS: Ubuntu 22.04 LTS
    • etcd: v3.5.9
    • Kubernetes: v1.28.0
    • Docker: 24.0.5 (作为容器运行时)
    • Keepalived: v2.2.8
    • HAProxy: 2.6.12
  • 网络: 所有节点位于同一局域网192.168.1.0/24,确保节点间网络互通。

4.2 实验步骤(30%)

步骤1:基础环境准备(所有节点)
更新系统:
sudo apt update && sudo apt upgrade -y
sudo reboot
设置主机名:
# 在etcd1上
sudo hostnamectl set-hostname etcd1
# 在master1上
sudo hostnamectl set-hostname master1
# ... 其他节点同理
  1. 配置/etc/hosts: 在所有节点添加所有主机名和IP映射。
关闭Swap:
sudo swapoff -a
sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
安装Docker:
sudo apt install -y docker.io docker-compose
sudo systemctl enable --now docker
# 配置Docker cgroup driver为systemd
sudo mkdir -p /etc/docker
cat <<EOF | sudo tee /etc/docker/daemon.json
{"exec-opts": ["native.cgroupdriver=systemd"],"log-driver": "json-file","log-opts": {"max-size": "100m"},"storage-driver": "overlay2"
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
安装kubeadm, kubelet, kubectl:
sudo apt-get update && sudo apt-get install -y apt-transport-https ca-certificates curl
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.28/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.28/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
配置内核参数:
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables  = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward                 = 1
EOF
sudo sysctl --system
步骤2:部署etcd集群(etcd1, etcd2, etcd3)
安装etcd:
ETCD_VER=v3.5.9
GITHUB_URL=https://github.com/etcd-io/etcd/releases/download
DOWNLOAD_URL=${GITHUB_URL}
curl -L ${DOWNLOAD_URL}/${ETCD_VER}/etcd-${ETCD_VER}-linux-amd64.tar.gz -o /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz
mkdir -p /tmp/etcd-download
tar xzvf /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz -C /tmp/etcd-download --strip-components=1
sudo mv /tmp/etcd-download/etcd* /usr/local/bin/
创建用户和目录:
sudo useradd -r -s /bin/false etcd
sudo mkdir -p /var/lib/etcd /etc/etcd/pki
sudo chown -R etcd:etcd /var/lib/etcd /etc/etcd
    • 生成证书(在master1上操作,然后分发):安装cfssl:
curl -L https://github.com/cloudflare/cfssl/releases/download/v1.6.4/cfssl_1.6.4_linux_amd64 -o cfssl
curl -L https://github.com/cloudflare/cfssl/releases/download/v1.6.4/cfssljson_1.6.4_linux_amd64 -o cfssljson
curl -L https://github.com/cloudflare/cfssl/releases/download/v1.6.4/cfssl-certinfo_1.6.4_linux_amd64 -o cfssl-certinfo
chmod +x cfssl cfssljson cfssl-certinfo
sudo mv cfssl cfssljson cfssl-certinfo /usr/local/bin/
    • 创建CA配置:
mkdir ~/etcd-certs && cd ~/etcd-certs
cat > ca-config.json <<EOF
{"signing": {"default": {"expiry": "87600h"},"profiles": {"etcd": {"usages": ["signing", "key encipherment", "server auth", "client auth"],"expiry": "87600h"}}}
}
EOF
cat > ca-csr.json <<EOF
{"CN": "etcd CA","key": {"algo": "rsa","size": 2048},"names": [{"C": "CN","L": "Beijing","O": "Kubernetes","OU": "CA"}]
}
EOF
cfssl gencert -initca ca-csr.json | cfssljson -bare ca
    • 创建etcd服务器证书(包含所有节点IP和主机名):
cat > etcd-server-csr.json <<EOF
{"CN": "etcd-server","hosts": ["127.0.0.1","192.168.1.101","192.168.1.102","192.168.1.103","etcd1","etcd2","etcd3"],"key": {"algo": "rsa","size": 2048},"names": [{"C": "CN","L": "Beijing","O": "Kubernetes","OU": "etcd"}]
}
EOF
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=etcd etcd-server-csr.json | cfssljson -bare etcd-server
    • 创建etcd对等证书(用于节点间通信):
cat > etcd-peer-csr.json <<EOF
{"CN": "etcd-peer","hosts": ["192.168.1.101","192.168.1.102","192.168.1.103","etcd1","etcd2","etcd3"],"key": {"algo": "rsa","size": 2048},"names": [{"C": "CN","L": "Beijing","O": "Kubernetes","OU": "etcd"}]
}
EOF
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=etcd etcd-peer-csr.json | cfssljson -bare etcd-peer
    • 分发证书到所有etcd节点:
for NODE in etcd1 etcd2 etcd3; dossh ${NODE} "mkdir -p /etc/etcd/pki"scp ca.pem ${NODE}:/etc/etcd/pki/scp etcd-server.pem ${NODE}:/etc/etcd/pki/server.crtscp etcd-server-key.pem ${NODE}:/etc/etcd/pki/server.keyscp etcd-peer.pem ${NODE}:/etc/etcd/pki/peer.crtscp etcd-peer-key.pem ${NODE}:/etc/etcd/pki/peer.key
done
创建etcd配置文件(以etcd1为例):
sudo tee /etc/etcd.conf <<EOF
name: etcd1
data-dir: /var/lib/etcd
listen-peer-urls: https://192.168.1.101:2380
listen-client-urls: https://192.168.1.101:2379,https://127.0.0.1:2379
initial-advertise-peer-urls: https://192.168.1.101:2380
advertise-client-urls: https://192.168.1.101:2379
initial-cluster: etcd1=https://192.168.1.101:2380,etcd2=https://192.168.1.102:2380,etcd3=https://192.168.1.103:2380
initial-cluster-state: new
initial-cluster-token: etcd-cluster-ha
# TLS
peer-cert-file: /etc/etcd/pki/peer.crt
peer-key-file: /etc/etcd/pki/peer.key
peer-trusted-ca-file: /etc/etcd/pki/ca.pem
peer-client-cert-auth: true
cert-file: /etc/etcd/pki/server.crt
key-file: /etc/etcd/pki/server.key
trusted-ca-file: /etc/etcd/pki/ca.pem
client-cert-auth: true
# Security
auto-tls: false
peer-auto-tls: false
# Performance
snapshot-count: 10000
heartbeat-interval: 100
election-timeout: 1000
quota-backend-bytes: 4294967296 # 4GB
EOF
    • etcd2etcd3上创建类似配置,修改name, listen-peer-urls, listen-client-urls, initial-advertise-peer-urls, advertise-client-urls为对应节点的IP和主机名。
创建systemd服务文件:
sudo tee /etc/systemd/system/etcd.service <<EOF
[Unit]
Description=etcd key-value store
Documentation=https://github.com/etcd-io/etcd
After=network.target[Service]
Type=notify
User=etcd
Group=etcd
ExecStart=/usr/local/bin/etcd --config-file /etc/etcd.conf
Restart=on-failure
RestartSec=5s
LimitNOFILE=65536
LimitNPROC=65536[Install]
WantedBy=multi-user.target
EOF
启动并验证etcd集群:
sudo systemctl daemon-reload
sudo systemctl enable --now etcd
# 在任意etcd节点上验证
ETCDCTL_API=3 etcdctl --endpoints=https://192.168.1.101:2379,https://192.168.1.102:2379,https://192.168.1.103:2379 \--cacert=/etc/etcd/pki/ca.pem \--cert=/etc/etcd/pki/server.crt \--key=/etc/etcd/pki/server.key \endpoint health
# 预期输出:所有节点 healthy
ETCDCTL_API=3 etcdctl --endpoints=https://192.168.1.101:2379 \--cacert=/etc/etcd/pki/ca.pem \--cert=/etc/etcd/pki/server.crt \--key=/etc/etcd/pki/server.key \member list
# 预期输出:3个成员,状态为started
步骤3:部署负载均衡器(Keepalived + HAProxy)
  • master1, master2, master3上安装并配置Keepalived和HAProxy。
安装:
sudo apt install -y keepalived haproxy
配置HAProxy(所有Master节点相同配置):
sudo tee /etc/haproxy/haproxy.cfg <<EOF
globallog /dev/log local0log /dev/log local1 noticechroot /var/lib/haproxystats socket /run/haproxy/admin.sock mode 660 level adminstats timeout 30suser haproxygroup haproxydaemondefaultslog globalmode tcpoption tcplogoption dontlognulltimeout connect 5000timeout client 50000timeout server 50000frontend kubernetes-apiserverbind *:6443mode tcpoption tcplogdefault_backend kubernetes-apiserverbackend kubernetes-apiservermode tcpoption tcplogoption tcp-checkbalance roundrobindefault-server inter 10s downinter 5s rise 2 fall 2 slowstart 60s maxconn 250 maxqueue 256 weight 100server master1 192.168.1.11:6443 checkserver master2 192.168.1.12:6443 checkserver master3 192.168.1.13:6443 check
EOF
sudo systemctl enable --now haproxy
配置Keepalived(master1 - BACKUP, master2 - BACKUP, master3 - MASTER):master1 (BACKUP, priority 100):
sudo tee /etc/keepalived/keepalived.conf <<EOF
global_defs {router_id LVS_DEVEL
}
vrrp_script check_haproxy {script "killall -0 haproxy"interval 2weight 2
}
vrrp_instance VI_1 {state BACKUPinterface eth0 # 替换为实际网卡名virtual_router_id 51priority 100advert_int 1authentication {auth_type PASSauth_pass K8s_HA_PASS}virtual_ipaddress {192.168.1.100/24 dev eth0}track_script {check_haproxy}
}
EOF
    • master2 (BACKUP, priority 90): 配置类似,修改priority 90
    • master3 (MASTER, priority 110): 配置类似,修改state MASTERpriority 110
启动Keepalived并验证VIP:
sudo systemctl enable --now keepalived
# 在master3上执行
ip addr show eth0
# 预期输出:应能看到 192.168.1.100/24
# 模拟故障:在master3上停止keepalived (sudo systemctl stop keepalived)
# 检查master1或master2,VIP应漂移到priority最高的BACKUP节点(master1)
步骤4:部署Kubernetes Master节点
准备kubeadm配置文件(在master1上):
mkdir ~/k8s-ha && cd ~/k8s-ha
tee kubeadm-config.yaml <<EOF
apiVersion: kubeadm.k8s.io/v1beta3
kind: InitConfiguration
localAPIEndpoint:advertiseAddress: "192.168.1.11"bindPort: 6443
---
apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
kubernetesVersion: v1.28.0
controlPlaneEndpoint: "192.168.1.100:6443"
imageRepository: registry.aliyuncs.com/google_containers
etcd:external:endpoints:- https://192.168.1.101:2379- https://192.168.1.102:2379- https://192.168.1.103:2379caFile: /etc/kubernetes/pki/etcd/ca.pemcertFile: /etc/kubernetes/pki/etcd/server.crtkeyFile: /etc/kubernetes/pki/etcd/server.key
networking:podSubnet: "10.244.0.0/16"serviceSubnet: "10.96.0.0/12"dnsDomain: "cluster.local"
apiServer:certSANs:- "192.168.1.100"- "192.168.1.11"- "192.168.1.12"- "192.168.1.13"- "master1"- "master2"- "master3"- "127.0.0.1"
controllerManager:extraArgs:bind-address: "0.0.0.0"
scheduler:extraArgs:bind-address: "0.0.0.0"
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
cgroupDriver: systemd
EOF
初始化第一个Master节点(master1):
sudo kubeadm init --config kubeadm-config.yaml --upload-certs
# 记录输出中的 join 命令(包含 --control-plane --certificate-key 和 --token)
# 配置kubectl
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
    • 加入其他Master节点(master2, master3):将/etc/kubernetes/pki目录下的证书(ca., sa., front-proxy-ca.*, etcd/ca.pem)从master1安全地复制到master2和master3的/etc/kubernetes/pki目录(注意权限)。
    • 在master2和master3上执行记录的kubeadm join命令(包含--control-plane标志)。
安装网络插件(如Calico):
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
验证Master集群:
kubectl get nodes
# 预期输出:3个Master节点状态为 Ready
kubectl get pods -n kube-system
# 预期输出:所有核心组件(kube-apiserver-* x3, kube-controller-manager-* x3, kube-scheduler-* x3, etcd-* x3, coredns, calico) Running
# 检查Leader
kubectl get endpoints kube-controller-manager -n kube-system
# 预期输出:只有一个地址(Leader)
kubectl get endpoints kube-scheduler -n kube-system
# 预期输出:只有一个地址(Leader)
步骤5:加入Worker节点(可选)
在worker1, worker2上执行:
# 使用master1初始化时输出的普通节点join命令(无--control-plane)
sudo kubeadm join 192.168.1.100:6443 --token <token> --discovery-token-ca-cert-hash <hash>
验证:
kubectl get nodes
# 预期输出:5个节点(3 Master, 2 Worker)状态为 Ready
步骤6:高可用性测试
    • 模拟Master节点故障:停止master1上的kube-apiserver服务:sudo systemctl stop kube-apiserver
    • 观察负载均衡器(HAProxy状态页或日志):应将流量自动切换到master2master3
    • 在客户端(如worker1)执行kubectl get nodes:应能正常工作(可能短暂延迟)。
    • 检查Leader选举:kubectl get endpoints kube-controller-manager -n kube-system,Leader应已切换到其他Master节点。
    • 恢复master1sudo systemctl start kube-apiserver,观察其重新加入集群。
    • 模拟etcd节点故障:停止etcd2上的etcd服务:sudo systemctl stop etcd
    • 在任意Master节点执行ETCDCTL_API=3 etcdctl --endpoints=... endpoint health:应显示etcd2unhealthy,但etcd1etcd3仍为healthy,集群可读写(因为2/3 > 1.5)。
    • 在Kubernetes集群中创建一个测试Pod:kubectl run nginx --image=nginx,应能成功创建并运行。
    • 恢复etcd2sudo systemctl start etcd,观察其重新加入集群并同步数据。
    • 模拟负载均衡器故障(VIP漂移):在当前持有VIP的节点(如master3)上停止Keepalived:sudo systemctl stop keepalived
    • 观察VIP漂移到其他Master节点(如master1)。
    • 在客户端执行kubectl get nodes:应能正常工作(短暂网络中断后恢复)。
    • 恢复master3的Keepalived:sudo systemctl start keepalived

五、 总结与展望:迈向Kubernetes架构师之路

本文系统性地阐述了Kubernetes高可用架构设计的核心原理与最佳实践,重点剖析了多Master节点部署的架构细节、组件协作机制(负载均衡、Leader Election)以及etcd集群的深度运维(Raft协议、部署、备份恢复、节点管理、监控调优、安全)。通过70%的理论深度剖析与30%的实战实验验证,我们构建了一个从理解到实践的完整知识闭环。

核心要点回顾

  1. 高可用是生产刚需: 单Master架构存在致命单点故障,多Master+外部etcd是生产环境标准范式。
    • 控制平面高可用关键:kube-apiserver: 依赖负载均衡器(HAProxy/Nginx/Keepalived/云LB)实现流量分发与健康检查。
    • kube-controller-manager & kube-scheduler: 依赖Leader Election机制确保唯一活跃实例。
    • 网络规划: Master间、Master-etcd间、Node-API Server间网络质量至关重要。
    • etcd是集群基石:Raft协议: 理解Leader选举、日志复制、多数派原则是运维基础。
    • 部署原则: 奇数节点(3/5)、专用SSD、充足内存、低延迟网络。
    • 运维核心: 定期备份(快照)、掌握恢复流程、安全扩缩容、滚动升级、深度监控(尤其磁盘延迟)、严格安全加固。
  2. 实战验证: 通过kubeadm + Keepalived/HAProxy + 外部etcd成功搭建了具备故障转移能力的高可用集群,并验证了Master、etcd、LB故障场景下的自动恢复。

架构师成长之路

掌握Kubernetes高可用架构设计与etcd运维,是成为Kubernetes架构师的关键一步。但这仅仅是起点。要持续精进,您还需关注:

  • 高级网络方案: 深入理解CNI插件(Calico, Cilium, Antrea)的BGP、eBGP、IPVLAN、Macvlan等高级模式,优化集群网络性能与安全策略。
  • 存储深度优化: 掌握CSI驱动开发与调优,理解分布式存储(Rook/Ceph, Longhorn)在K8s中的集成与高可用设计。
  • 多集群管理: 探索Cluster API, Karmada, Rancher等工具,实现跨区域、跨云的Kubernetes集群联邦管理与应用分发。
  • 性能极致优化: 针对超大规模集群(万级节点、十万级Pod)进行API Server、etcd、调度器、kubelet的性能瓶颈分析与调优。
  • 安全纵深防御: 构建从容器镜像安全、运行时安全(Falco, Policy Controller)、网络策略(Network Policy)、零信任网络(SPIFFE/SPIRE)到供应链安全(Sigstore, Cosign)的全方位安全体系。
  • GitOps与云原生生态: 精通Argo CD, Flux等GitOps工具,实现基础设施与应用的声明式管理与自动化交付。深入服务网格(Istio, Linkerd)、Serverless(Knative, OpenFaaS)等云原生技术。

立即行动,开启您的Kubernetes架构师成长之旅! 订阅本专栏,我们将持续为您提供系统化、实战化的深度内容,助您在云原生浪潮中乘风破浪,成为真正的Kubernetes专家。下一期,我们将深入探讨《Kubernetes网络模型深度解析与CNI插件实战》,敬请期待!

http://www.xdnf.cn/news/18698.html

相关文章:

  • centos7 安装coze
  • ZYNQ [Petalinux的运行]
  • Pytorch框架的训练测试以及优化
  • 数据结构青铜到王者第三话---ArrayList与顺序表(2)
  • 区块链技术原理(18)-以太坊共识机制
  • 哈夫曼树详解
  • 神经网络|(十五)概率论基础知识-协方差标准化和皮尔逊相关系数
  • 人机协作,温暖升级:有鹿机器人与保洁张阿姨的故事
  • 2025年06月 Python(二级)真题解析#中国电子学会#全国青少年软件编程等级考试
  • Python Day 33 JavaScript BOM 与 DOM 核心笔记整合
  • Linux(从入门到精通)
  • Elasticsearch JVM调优:核心参数与关键技巧
  • 2025生成式引擎优化(GEO)技术研究报告:技术演进、行业应用与服务商能力选择指南
  • 《微服务架构下API网关流量控制Bug复盘:从熔断失效到全链路防护》
  • 解析电商本地生活竞争:从我店模式创新到生态协同的进化路径
  • 基坑监测报警系统方案:实时监测数据联动响应方式
  • Node.js特训专栏-性能优化:24.V8引擎内存管理机制
  • Python办公——爬虫百度翻译网页版(自制翻译小工具——进阶更新版)
  • 渗透测试报告编写平台 | 简化和自动化渗透测试报告的生成过程。
  • 大数据治理域——离线数据开发
  • 深度学习(二):数据集定义、PyTorch 数据集定义与使用(分板块解析)
  • leetcode 498. 对角线遍历 中等
  • (论文速读)FloVD:光流遇见视频扩散模型,开启相机控制视频生成
  • RAG实现多语言客户端的技术方案
  • Claude Code 使用及配置智能体
  • MQTT协议详解:从基础原理到工业级实践指南
  • CANopen - DCF(Device Configuration File) 介绍
  • Apache Maven 3.1.1 (eclipse luna)
  • MATLAB 绘制根轨迹、Bode图的方法
  • 扭蛋机小程序系统开发:连接线上线下娱乐的新桥梁