Etcd 作为 Kubernetes 的“中枢神经”,以强一致性和高可用性保障集群数据安全,是云原生架构不可或缺的基石。
Etcd 是 Kubernetes 集群的核心组件之一,作为分布式键值存储系统,负责保存集群的所有配置信息和状态数据。本文将深入解析 etcd 在 Kubernetes 中的作用、原理和使用方法。
Etcd 作为高可用的分布式键值存储系统,采用 Raft 共识算法保证数据一致性。在 Kubernetes 生态系统中,etcd 主要承担以下职责:
Etcd 在生产环境中广泛使用,特别是作为 Kubernetes 的主要数据存储和其他需要可靠协调服务的分布式系统。
Etcd 遵循客户端 - 服务器架构,其中多个 etcd 服务器实例形成集群。客户端使用 etcd 客户端库或 etcdctl 命令行工具与集群通信。
下图展示了 etcd 的主要架构组件及其交互关系。
```mermaid “Etcd 系统架构” flowchart TD subgraph “Clients” ClientApp[“Client Applications”] etcdctl[“etcdctl Command Line”] end
subgraph "Client Interface"
ClientLibraries["clientv3 Libraries"]
gRPC["gRPC API"]
end
subgraph "etcd Server"
Server["EtcdServer"]
Auth["AuthStore"]
MVCC["MVCC Store"]
Lease["Lease Manager"]
Raft["Raft Consensus"]
WAL["Write-Ahead Log"]
Backend["bbolt Backend"]
end
ClientApp -->|API calls| ClientLibraries
etcdctl --> ClientLibraries
ClientLibraries -->|RPC| gRPC
gRPC --> Auth
Auth --> Server
Server --> MVCC
Server --> Lease
Server --> Raft
MVCC --> Backend
Lease --> Backend
Raft --> WAL
WAL --> Backend ```
{width=1920 height=3638}
Etcd 架构由以下关键组件组成:
下图说明了不同类型的请求如何通过 etcd 系统处理:
```mermaid “Etcd 请求处理流程” sequenceDiagram participant Client as Client Application participant ClientLib as clientv3 Library participant Server as EtcdServer participant Auth as AuthStore participant MVCC as MVCC Store participant Raft as Raft Node participant WAL as Write-Ahead Log participant Backend as bbolt Backend
Client->>ClientLib: Operation (Put/Get/Delete)
ClientLib->>Server: gRPC Request
alt Read Operation (Serializable)
Server->>Auth: IsRangePermitted
Auth-->>Server: Permission Result
Server->>MVCC: Range
MVCC->>Backend: Read from storage
Backend-->>MVCC: Return data
MVCC-->>Server: Return result
else Read Operation (Linearizable)
Server->>Server: linearizableReadNotify
Server->>Raft: ReadIndex
Raft-->>Server: ReadIndex response
Server->>Auth: IsRangePermitted
Auth-->>Server: Permission Result
Server->>MVCC: Range
MVCC->>Backend: Read from storage
Backend-->>MVCC: Return data
MVCC-->>Server: Return result
else Write Operation
Server->>Server: raftRequest
Server->>Raft: Process (Propose)
Raft->>WAL: Record proposal
Raft->>Raft: Reach consensus
Raft-->>Server: Committed entry
Server->>Auth: Check permissions
Auth-->>Server: Permission Result
Server->>MVCC: Apply changes
MVCC->>Backend: Write to storage
Backend-->>MVCC: Confirm write
MVCC-->>Server: Return result
end
Server-->>ClientLib: gRPC Response
ClientLib-->>Client: Operation Result ```
{width=1920 height=2024}
读取操作可分为可序列化(可能过时)和线性化(保证最新);写入操作始终通过 Raft 共识过程以确保跨集群一致性。
Etcd 采用 Raft 共识算法 实现分布式一致性,确保即使在部分节点故障的情况下,集群仍能正常工作并保持数据一致性。
详细的架构分析请参考:Etcd 架构与实现解析
EtcdServer 是中央协调组件,处理客户端请求、管理 Raft 共识协议,并集成所有其他 etcd 子系统。它在 server/etcdserver/server.go 中定义,并实现了多个接口,包括 Server、RaftStatusGetter 和 Authenticator。
主要职责:
etcd 使用 Raft 共识算法维护集群一致性。server/etcdserver/raft.go 中的 raftNode 结构封装了 Raft 协议实现:
```mermaid “Raft 节点与 EtcdServer 交互” flowchart TD subgraph “RaftNode” Node[“raft.Node”] MemoryStorage[“raft.MemoryStorage”] MsgSnapC[“msgSnapC channel”] ApplyC[“applyc channel”] ReadStateC[“readStateC channel”] end
subgraph "EtcdServer"
Server["EtcdServer"]
Apply["apply()"]
Process["process()"]
end
subgraph "Transport"
RaftHTTP["rafthttp.Transport"]
Peers["Peer Connections"]
end
Node --> MemoryStorage
Node -->|"Sends Ready"| Server
Server -->|"Proposes"| Node
Server -->|"Processes ReadIndex"| Node
Server -->|"Applies entries"| Apply
Apply -->|"Reads from"| ApplyC
Node -->|"Sends to"| ApplyC
Node -->|"Sends to"| ReadStateC
Node -->|"Sends snapshots to"| MsgSnapC
RaftHTTP -->|"Connects to"| Peers
Server -->|"Sends/Receives via"| RaftHTTP
RaftHTTP -->|"Delivers messages to"| Node ```
{width=2059 height=882}
Raft 实现的关键方面:
etcd 的存储系统由多个层组成:
```mermaid “Etcd 存储层次结构” flowchart TD subgraph “Storage Layers” MVCC[“MVCC (Multi-Version Concurrency Control)”] Backend[“bbolt Backend”] WAL[“Write-Ahead Log (WAL)”] Snapshot[“Snapshotter”] end
subgraph "Data Flow"
Write["Write Request"]
Read["Read Request"]
Recovery["Recovery"]
end
Write -->|"1. Log"| WAL
Write -->|"2. Propose"| MVCC
MVCC -->|"3. Commit"| Backend
Read -->|"Query"| MVCC
MVCC -->|"Retrieve"| Backend
WAL -->|"Replay logs"| Recovery
Snapshot -->|"Load snapshot"| Recovery
Recovery -->|"Restore state"| MVCC
MVCC -->|"Periodic snapshot"| Snapshot
Snapshot -->|"Compact"| WAL ```
{width=1920 height=1632}
各层功能说明:
etcd 提供全面的安全模型,具有认证和基于角色的访问控制 (RBAC):
```mermaid “Etcd 认证与授权流程” flowchart TD subgraph “Authentication Components” Auth[“AuthStore”] TokenProvider[“TokenProvider”] UserStore[“User Storage”] RoleStore[“Role Storage”] end
subgraph "Request Flow"
Request["Client Request"]
Authenticate["Authenticate"]
CheckPermission["Check Permission"]
Response["Process Request"]
end
Request -->|"1. Validate token"| Authenticate
Authenticate -->|"2. Get user info"| Auth
Auth -->|"Verify token"| TokenProvider
Auth -->|"Check user"| UserStore
Auth -->|"3. Check permissions"| CheckPermission
CheckPermission -->|"Get roles"| RoleStore
CheckPermission -->|"4. Allow/Deny"| Response ```
{width=1920 height=1900}
关键安全特性:
Kubernetes 使用 etcd v3 API 进行所有操作,提供更好的性能和功能。
# 设置 etcd v3 API
export ETCDCTL_API=3
早期版本的网络插件(如 flannel)可能使用 etcd v2 API,但现代版本通常已升级到 v3 API。
Kubernetes 将所有资源对象存储在 etcd 的 /registry 路径下,结构如下:
/registry/
├── pods/
├── services/
├── deployments/
├── configmaps/
├── secrets/
├── namespaces/
├── nodes/
├── persistentvolumes/
├── persistentvolumeclaims/
├── storageclasses/
├── customresourcedefinitions/
└── ...
建议仅用于调试、排查或只读场景,切勿直接修改 etcd 中的 Kubernetes 资源数据,否则可能导致集群状态不一致或不可预期的故障。所有生产环境下的资源管理应通过 Kubernetes API Server 进行。
访问 Kubernetes 数据时,需指定 etcd v3 API:
export ETCDCTL_API=3
或在命令前添加环境变量:
ETCDCTL_API=3 etcdctl get /registry/namespaces/default -w=json | jq .
对于使用 kubeadm 创建的集群,etcd 默认启用 TLS 认证。需使用相应证书文件:
ETCDCTL_API=3 etcdctl \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/peer.crt \
--key=/etc/kubernetes/pki/etcd/peer.key \
get /registry/namespaces/default -w=json | jq .
参数说明:
--cacert: CA 证书文件路径--cert: 客户端证书文件路径--key: 客户端私钥文件路径-w: 指定输出格式(json、table 等)查看 default 命名空间的详细信息:
ETCDCTL_API=3 etcdctl get /registry/namespaces/default -w=json | jq .
输出示例:
{
"count": 1,
"header": {
"cluster_id": 12091028579527406772,
"member_id": 16557816780141026208,
"raft_term": 36,
"revision": 29253467
},
"kvs": [
{
"create_revision": 5,
"key": "L3JlZ2lzdHJ5L25hbWVzcGFjZXMvZGVmYXVsdA==",
"mod_revision": 5,
"value": "azhzAAoPCgJ2MRIJTmFtZXNwYWNlEmIKSAoHZGVmYXVsdBIAGgAiACokZTU2YzMzMDgtMWVhOC0xMWU3LThjZDctZjRlOWQ0OWY4ZWQwMgA4AEILCIn4sscFEKOg9xd6ABIMCgprdWJlcm5ldGVzGggKBkFjdGl2ZRoAIgA=",
"version": 1
}
]
}
查看多个对象:
ETCDCTL_API=3 etcdctl get /registry/namespaces --prefix -w=json | jq .
列出所有键:
ETCDCTL_API=3 etcdctl get /registry --prefix --keys-only
查看集群节点信息:
ETCDCTL_API=3 etcdctl get /registry/minions --prefix
ETCDCTL_API=3 etcdctl get /registry/minions/node-name
监控资源变化:
ETCDCTL_API=3 etcdctl watch /registry/pods --prefix
ETCDCTL_API=3 etcdctl watch /registry/services/default/my-service
etcd 中的键值都经过 base64 编码,需要解码才能查看实际内容。
echo "L3JlZ2lzdHJ5L25hbWVzcGFjZXMvZGVmYXVsdA==" | base64 -d
# 输出:/registry/namespaces/default
批量解码脚本:
#!/bin/bash
export ETCDCTL_API=3
keys=$(etcdctl get /registry --prefix -w json | jq -r '.kvs[].key')
for key in $keys; do
echo $key | base64 -d
done | sort
Kubernetes 在 etcd 中的数据遵循以下层次结构:
/registry/
├── <资源类型复数形式>/
│ ├── <命名空间>/
│ │ └── <对象名称>
│ └── <集群级别对象名称>
主要资源类型包括:
获取所有 Kubernetes 对象键:
#!/bin/bash
export ETCDCTL_API=3
ETCD_OPTS=""
if [ -f "/etc/kubernetes/pki/etcd/ca.crt" ]; then
ETCD_OPTS="--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/peer.crt \
--key=/etc/kubernetes/pki/etcd/peer.key"
fi
etcdctl $ETCD_OPTS get /registry --prefix -w json | \
jq -r '.kvs[].key' | \
while read key; do
echo $key | base64 -d
done | sort
按资源类型统计对象数量:
#!/bin/bash
export ETCDCTL_API=3
etcdctl get /registry --prefix --keys-only | \
while read key; do
echo $key | base64 -d
done | \
cut -d'/' -f3 | \
sort | uniq -c | \
sort -nr
通过 etcdctl 访问 Kubernetes 数据有助于深入理解集群的内部工作机制,对于故障排查和性能优化具有重要意义。
etcd 使用 Raft 共识维护集群一致性,允许容忍机器故障,包括 leader 故障,同时维护数据完整性。
集群可以通过以下方式形成:
成员可动态添加、删除或更新。新节点可作为 “learner” 添加,然后提升为完整投票成员。
```mermaid “Etcd 集群形成与成员管理” flowchart TD subgraph “Cluster Formation” Bootstrap[“Bootstrap”] Discovery[“Discovery Service”] StaticConfig[“Static Configuration”] DNSDiscovery[“DNS Discovery”] end
subgraph "Membership"
AddMember["AddMember"]
RemoveMember["RemoveMember"]
UpdateMember["UpdateMember"]
PromoteMember["PromoteMember"]
end
subgraph "Operation"
Leader["Leader"]
Follower1["Follower"]
Follower2["Follower"]
Learner["Learner"]
end
Bootstrap -->|"Uses"| Discovery
Bootstrap -->|"Uses"| StaticConfig
Bootstrap -->|"Uses"| DNSDiscovery
Leader -->|"Replicates to"| Follower1
Leader -->|"Replicates to"| Follower2
Leader -->|"Replicates to"| Learner
AddMember -->|"Can add"| Learner
PromoteMember -->|"Promotes"| Learner
Learner -->|"Becomes"| Follower1
RemoveMember -->|"Can remove"| Follower2 ```
{width=2422 height=979}
在 Raft 系统中:
leader 选举过程确保在任何时候只存在一个 leader,防止脑裂场景。
客户端通过 etcdctl 命令行工具或客户端库与 etcd 交互。主要通信协议是 gRPC,具有用于 RESTful 访问的 HTTP/JSON 网关。
主要的客户端库是 clientv3,为 etcd 提供 Go API,包括:
```mermaid “Etcd 客户端库结构” flowchart LR subgraph “Client Application” App[“Application Code”] end
subgraph "clientv3"
Client["Client"]
KV["KV Interface"]
Watch["Watch Interface"]
Lease["Lease Interface"]
Auth["Auth Interface"]
Cluster["Cluster Interface"]
Maintenance["Maintenance Interface"]
end
subgraph "Transport"
Balancer["Balancer"]
gRPCConn["gRPC Connection"]
end
App -->|"Uses"| Client
Client -->|"Provides"| KV
Client -->|"Provides"| Watch
Client -->|"Provides"| Lease
Client -->|"Provides"| Auth
Client -->|"Provides"| Cluster
Client -->|"Provides"| Maintenance
Client -->|"Manages"| Balancer
Balancer -->|"Controls"| gRPCConn
gRPCConn -->|"Connects to"| Endpoints["etcd Endpoints"] ```
{width=1920 height=1088}
etcdctl CLI 提供了从命令行与 etcd 交互的用户友好方式,支持所有核心操作。
示例操作:
put、get、delwatchlease grant、lease revokeuser add、role grantmember add、endpoint health现代网络插件(如 Calico、Flannel、Cilium)通常将网络配置存储在 etcd 中。
# 查看网络配置(以 Calico 为例)
ETCDCTL_API=3 etcdctl get /calico --prefix
# 查看 Flannel 网络配置(如果使用)
ETCDCTL_API=3 etcdctl get /coreos.com/network --prefix
定期创建快照以防止数据丢失,恢复时需严格按照官方流程操作,避免数据一致性问题。
# 创建 etcd 快照
ETCDCTL_API=3 etcdctl snapshot save /backup/etcd-snapshot-$(date +%Y%m%d-%H%M%S).db
# 验证快照
ETCDCTL_API=3 etcdctl snapshot status /backup/etcd-snapshot.db
恢复操作会将 etcd 数据目录重建为快照中的状态,建议先在隔离环境中验证快照完整性。
# 从快照恢复
ETCDCTL_API=3 etcdctl snapshot restore /backup/etcd-snapshot.db \
--data-dir=/var/lib/etcd-restore \
--initial-cluster-token=etcd-cluster-restore
etcd 提供 Prometheus 指标和内置健康检查。
/health、/livez、/readyz维护操作包括:
建议所有 etcd 节点间通信和客户端访问均启用 TLS。
# 使用 TLS 证书访问 etcd
ETCDCTL_API=3 etcdctl \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
get /registry/pods --prefix
# 检查集群健康状态
ETCDCTL_API=3 etcdctl endpoint health
# 查看成员列表
ETCDCTL_API=3 etcdctl member list
# 检查集群状态
ETCDCTL_API=3 etcdctl endpoint status --cluster -w table
Etcd 为分布式系统提供可靠的分布式键值存储,具有强一致性保证,是存储关键配置数据的理想选择。其简单性、安全性、性能、可靠性和一致性的组合,使其成为现代云原生架构的基础,尤其在 Kubernetes 体系中发挥着不可替代的作用。