Kubernetes 环境下的 Etcd 部署指南
基于 bitnami/etcd 镜像的生产级部署实践
前言
在 Kubernetes 生态系统中,Etcd 作为核心的分布式键值存储,承担着至关重要的角色。它不仅是 Kubernetes API Server 的数据后端,还广泛用于服务发现、配置共享等场景。
今天,我将分享一套基于 Kubernetes 的 Etcd 部署方案,这套方案已经在生产环境中稳定运行,服务于 APISIX 网关等关键系统。
为什么选择这个方案?
在深入技术细节之前,先说说为什么选择这个部署方案:
| 特性 | 说明 |
|---|---|
| bitnami 镜像 | 业界最可靠的 etcd 容器镜像,维护活跃,安全更新及时 |
| StatefulSet | 原生支持有状态应用,保证 Pod 启动顺序和数据持久性 |
| 双 Service 模式 | Headless + NodePort,分别满足内部发现和外部访问需求 |
| HostPath 存储 | 简化运维,节点级别的数据持久化 |
整体架构一览
先来看一张部署架构图,对整体结构有个直观认识:

从图中可以看到,整个部署包含以下几个核心组件:
1. Namespace 隔离
所有资源都部署在 bjac-etcd 命名空间中,实现了与其他业务资源的逻辑隔离。
2. StatefulSet 控制器
采用 StatefulSet 而非 Deployment,是 etcd 作为有状态应用的必然选择:
- 稳定的 Pod 标识:Pod 名称固定为
etcd-0、etcd-1... - 有序的部署和扩缩容:新 Pod 必须等前一个就绪后才启动
- 独立的持久存储:每个 Pod 绑定独立的 PV
3. 双 Service 模式
┌─────────────────────────────────────────────────────────┐
│ etcd-hs (Headless) │
│ │
│ • ClusterIP: None │
│ • 用于 Pod 之间的 DNS 发现 │
│ • 支持 publishNotReadyAddresses=true │
│ │
│ DNS: etcd-0.etcd-hs.bjac-etcd.svc.cluster.local │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ etcd-cs (NodePort) │
│ │
│ • Type: NodePort │
│ • NodePort: 30379 │
│ • 用于集群外部客户端访问 │
│ │
│ 访问地址: <NodeIP>:30379 │
└─────────────────────────────────────────────────────────┘
4. 存储设计
采用 HostPath 方式挂载宿主机目录:
volumes:
- name: etcd-data
hostPath:
path: /home/etcd/data/
提示:在生产环境中,建议使用 Local PV 或云存储以获得更好的数据可靠性保障。
配置文件深度解析
完整的 YAML 编排
apiVersion: v1
kind: Namespace
metadata:
name: bjac-etcd
---
apiVersion: v1
kind: Service
metadata:
labels:
app: etcd-cs
name: etcd-cs
namespace: bjac-etcd
spec:
type: NodePort
ports:
- name: tcp-client
port: 2379
targetPort: 2379
nodePort: 30379
selector:
app: etcd
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
labels:
app: etcd
name: etcd
namespace: bjac-etcd
spec:
serviceName: etcd-hs
replicas: 1
selector:
matchLabels:
app: etcd
template:
metadata:
labels:
app: etcd
spec:
nodeSelector:
etcd-server: master
containers:
- name: etcd
image: bitnami/etcd:3.5.6
imagePullPolicy: IfNotPresent
ports:
- name: client
containerPort: 2379
env:
- name: ETCD_ENABLE_V2
value: "true"
- name: ALLOW_NONE_AUTHENTICATION
value: "yes"
- name: ETCD_ADVERTISE_CLIENT_URLS
value: "http://0.0.0.0:2379"
- name: ETCD_LISTEN_CLIENT_URLS
value: "http://0.0.0.0:2379"
volumeMounts:
- name: etcd-data
mountPath: /bitnami/etcd/
volumes:
- name: etcd-data
hostPath:
path: /home/etcd/data/
关键环境变量说明
| 环境变量 | 值 | 作用 |
|---|---|---|
ETCD_ENABLE_V2 |
true | 启用 V2 API(APISIX 需要) |
ALLOW_NONE_AUTHENTICATION |
yes | 无认证模式(开发环境) |
ETCD_ADVERTISE_CLIENT_URLS |
http://0.0.0.0:2379 | 通告给客户端的地址 |
ETCD_LISTEN_CLIENT_URLS |
http://0.0.0.0:2379 | 监听客户端连接的地址 |
部署实战
部署流程
下面通过一张流程图,展示完整的部署步骤:

详细部署步骤
步骤一:节点标签
# 查看当前节点及其标签
kubectl get node --show-labels=true
# 给指定节点添加标签
kubectl label nodes <YOUR_NODE_NAME> etcd-server=master
这一步很关键!StatefulSet 使用 nodeSelector 确保 Pod 调度到专用节点。
步骤二:创建存储目录
# 在目标节点上创建数据目录
mkdir -p /home/etcd/data
chmod -R 777 /home/etcd
注意:
chmod -R 777确保容器内的 etcd 进程有权限读写数据目录。
步骤三:部署资源
# 一键部署所有资源
kubectl apply -f etcd.yaml
步骤四:验证部署
# 检查 Pod 状态
kubectl get pod -n bjac-etcd -o wide
# 查看 Pod 详细信息
kubectl -n bjac-etcd describe pod etcd-0
# 查看日志
kubectl -n bjac-etcd logs etcd-0 --all-containers=true
步骤五:DNS 解析验证
# 测试 Headless Service DNS
nslookup etcd-hs.bjac-etcd.svc.cluster.local <COREDNS_IP>
# 测试 Pod 专属 DNS
nslookup etcd-0.etcd-hs.bjac-etcd.svc.cluster.local 172.16.0.10
数据备份:保障数据安全
数据备份是运维工作中不可或缺的一环。以下是完整的备份方案:
备份策略架构

备份实战
# 进入 Etcd Pod
kubectl exec -it pod/etcd-0 -n bjac-etcd -- bash
# 进入备份目录
cd /opt/
mkdir backup
cd backup
# 方式一:导出 APISIX 配置
etcdctl --endpoints=<ETCD_ENDPOINT> \
get /apisix/ --prefix --print-value-only=false \
> apisix_backup.txt -w=simple
# 方式二:创建完整快照
etcdctl --endpoints=<ETCD_ENDPOINT> \
snapshot save snapshot.db
# 查看快照状态
etcdctl --endpoints=<ETCD_ENDPOINT> \
snapshot status snapshot.db -w=table
# 退出 Pod
exit
# 将备份复制到宿主机
kubectl cp bjac-etcd/etcd-0:/opt/backup /home/tmp/etcd
备份数据分析
从备份文件中可以看到,APISIX 的关键配置数据结构如下:
| 路径 | 说明 |
|---|---|
/apisix/routes/ |
路由规则配置 |
/apisix/services/ |
服务(Upstream)定义 |
/apisix/consumers/ |
消费者/认证配置 |
/apisix/ssl/ |
SSL 证书 |
/apisix/plugins/ |
插件配置 |
/apisix/upstreams/ |
上游服务器组 |
运维最佳实践
日常检查清单
# 1. Pod 状态检查
kubectl get pod -n bjac-etcd
# 2. Service 端点检查
kubectl get ep -n bjac-etcd
# 3. 存储使用情况
kubectl exec etcd-0 -n bjac-etcd -- df -h /bitnami/etcd/
# 4. 健康检查
etcdctl --endpoints=10.105.197.216:30379 endpoint health
故障排查指南
| 症状 | 可能原因 | 解决方案 |
|---|---|---|
| Pod 处于 Pending | 节点标签不存在 | 添加 kubectl label nodes <node> etcd-server=master |
| Pod 处于 CrashLoopBackOff | 数据目录权限问题 | 检查 /home/etcd/data/ 权限 |
| 无法从外部访问 | NodePort 未开放 | 检查防火墙规则 |
| DNS 解析失败 | CoreDNS 问题 | 检查 publishNotReadyAddresses 设置 |
总结
本文详细介绍了在 Kubernetes 环境中部署 Etcd 的完整方案,涵盖了:
- ✅ 架构设计:Namespace + StatefulSet + 双 Service 模式
- ✅ 配置详解:bitnami 镜像的环境变量配置
- ✅ 部署流程:从节点准备到验证的完整步骤
- ✅ 数据备份:快照备份与数据导出方案
- ✅ 运维实践:日常检查与故障排查