Docker 最佳实战:Docker 部署单节点 etcd 实战
2024 年云原生运维实战文档 99 篇原创计划 第 004 篇 |Docker 最佳实战「2024」系列 第 004 篇
前言
你好,欢迎来到运维有术。
今天分享的内容是 Docker 最佳实战「2024」 系列文档中的 Docker 部署单节点 etcd 实战。
内容导图
实战服务器配置 (架构 1:1 复刻小规模生产环境,配置略有不同)
主机名 | IP | CPU(核) | 内存(GB) | 系统盘(GB) | 数据盘(GB) | 用途 |
---|---|---|---|---|---|---|
docker-node-1 | 192.168.9.81 | 4 | 16 | 40 | 100 | Docker 节点 1 |
docker-node-2 | 192.168.9.82 | 4 | 16 | 40 | 100 | Docker 节点 2 |
docker-node-3 | 192.168.9.83 | 4 | 16 | 40 | 100 | Docker 节点 3 |
合计 | 3 | 12 | 48 | 120 | 300 |
实战环境涉及软件版本信息
- 操作系统:openEuler 22.03 LTS SP3
- Docker:24.0.7
- Containerd:1.6.27
- Etcd:3.5.12
1. 前提说明
目前主流的 etcd 容器化部署方案可用的容器有以下两种:
- coreos 官方提供:
quay.io/coreos/etcd:v3.5.12
- bitnami 提供:
bitnami/etcd:3.5.12
etcd 服务的配置有三种方式 :
- Command-line flags:命令行标记,etcd 服务启动时加入命令行参数 (flag)。flags 参考文档
- Environment variables: 系统环境变量,etcd 服务启动时读取系统环境变量
- Configuration file: 配置文件,etcd 服务启动时读取 --config-file 参数指定的配置文件。etcd 配置文件参考
采用系统环境变量配置 etcd 服务说明:
- 每个命令行 flag 都有一个对应的环境变量
- 该变量具有相同的名称,但前缀为 'etcd_' 并以大写和蛇形命名法格式化
- 例如, --some-flag 转换后 ETCD_SOME_FLAG
- 蛇形命名法(snake_case):是指每个空格皆以底线(_)取代的书写风格,且每个单字的第一个字母皆为小写(一般习惯全小写),例如
lower_case_with_underscores
。参考 wiki 百科
本实战课程采用 coreos 官方提供的 etcd 镜像,部署单节点的 etcd 服务,并分别演示使用配置文件和环境变量的方式实现 etcd 服务配置。
为什么选择 coreos 镜像?
- etcd 官方提供
- etcd 基础镜像采用了 distroless/static-debian12,容量更小,更加安全。什么是 "Distroless" Container Images
- Bitnami 的 etcd 镜像也是一个非常好的选择,该镜像下载量已经达到了 100M ,可以结合本文内容参考 bitnami-etcd 官方文档,自行实现。
2. 单节点 etcd 部署实战-基于配置文件
本节内容使用配置文件的方式实现 etcd 服务配置。
2.1 创建 etcd 数据目录
代码语言:bash复制mkdir -p /data/containers/etcd/{data,config}
- data 目录:建议, 存储容器持久化数据
- config 目录:建议, 存储容器使用的配置文件
2.2 创建 etcd 配置文件
etcd 服务配置文件路径为:/data/containers/etcd/config/etcd.conf.yml
文件内容如下:
代码语言:yaml复制name: etcd-s1
data-dir: /var/etcd
listen-client-urls: http://0.0.0.0:2379
advertise-client-urls: http://0.0.0.0:2379
listen-peer-urls: http://0.0.0.0:2380
initial-advertise-peer-urls: http://0.0.0.0:2380
initial-cluster: etcd-s1=http://0.0.0.0:2380
initial-cluster-token: etcd-cluster
initial-cluster-state: new
logger: zap
log-level: info
#log-outputs: stderr
特殊参数说明:
name: etcd member 名称,可根据实际情况修改 data-dir: etcd 数据目录,可根据实际情况修改 listen-client-urls: client 流量监听地址,没特殊需求按文档填写即可 advertise-client-urls: 该 member 向外部通告的客户端 url 列表,单节点部署时不需要修改,集群部署模式需修改为容器所在节点对外提供服务的 IP listen-peer-urls: peer 流量监听地址,没特殊需求按文档填写即可 initial-advertise-peer-urls: 该 member 向同一集群内其他 member 通告的 peer url 列表,单节点部署时不需要修改,集群部署模式需修改为容器所在节点对外提供服务的 IP initial-cluster: 初始化集群节点信息,单节点部署时不需要修改,集群部署模式需要填写集群中所有 member 的信息 initial-cluster-token: 初始化集群时使用的 token,随便写 initial-cluster-state: 初始化集群状态,可选的值为 new 或者 existing,通常采用 new
2.3 创建 docker-compose 文件
代码语言:yaml复制version: '3'
services:
etcd:
container_name: etcd-s1
image: quay.io/coreos/etcd:v3.5.12
command: /usr/local/bin/etcd --config-file=/var/lib/etcd/conf/etcd.conf.yml
volumes:
- ${DOCKER_VOLUME_DIRECTORY:-.}/data:/var/etcd
- ${DOCKER_VOLUME_DIRECTORY:-.}/config/etcd.conf.yml:/var/lib/etcd/conf/etcd.conf.yml
- "/etc/localtime:/etc/localtime:ro"
ports:
- 2379:2379
- 2380:2380
restart: always
networks:
default:
name: etcd-tier
driver: bridge
特殊参数说明:
networks.default: 创建一个新的使用 bridge 模式的网络 etcd-tier, 名称可以根据需求自定义。
2.4 创建并启动 etcd 服务
代码语言:bash复制cd /data/containers/etcd
docker compose up -d
命令成功执行的结果如下:
代码语言:bash复制[root@docker-node-1 etcd]# docker compose up -d
[ ] Running 1/2
⠸ Network etcd-tier Created 0.4s
✔ Container etcd-s1 Started
2.5 验证容器状态
- 查看 etcd 容器状态
[root@docker-node-1 etcd]# docker compose ps -a
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
etcd-s1 quay.io/coreos/etcd:v3.5.12 "/usr/local/bin/etcd…" etcd 53 seconds ago Up 53 seconds 0.0.0.0:2379-2380->2379-2380/tcp, :::2379-2380->2379-2380/tcp
3. 单节点 etcd 部署实战-基于环境变量
本节内容使用环境变量的方式实现 etcd 服务配置。
3.1 创建 etcd 数据目录
代码语言:bash复制mkdir -p /data/containers/etcd/data
- data 目录:建议, 存储容器持久化数据
3.2 创建 docker-compose 文件
代码语言:yaml复制version: '3'
services:
etcd:
container_name: etcd-s1
image: quay.io/coreos/etcd:v3.5.12
environment:
- ETCD_NAME=etcd-s1
- ETCD_DATA_DIR=/var/etcd
- ETCD_LISTEN_CLIENT_URLS=http://0.0.0.0:2379
- ETCD_ADVERTISE_CLIENT_URLS=http://0.0.0.0:2379
- ETCD_LISTEN_PEER_URLS=http://0.0.0.0:2380
- ETCD_INITIAL_ADVERTISE_PEER_URLS=http://0.0.0.0:2380
- ETCD_INITIAL_CLUSTER_TOKEN=etcd-cluster
- ETCD_INITIAL_CLUSTER=etcd-s1=http://0.0.0.0:2380
- ETCD_INITIAL_CLUSTER_STATE=new
- ETCD_LOGGER=zap
- ETCD_LOG_LeveL=info
volumes:
- ${DOCKER_VOLUME_DIRECTORY:-.}/data:/var/etcd
- "/etc/localtime:/etc/localtime:ro"
ports:
- 2379:2379
- 2380:2380
restart: always
networks:
default:
name: etcd-tier
driver: bridge
3.3 创建并启动 etcd 服务
代码语言:bash复制cd /data/containers/etcd
docker compose up -d
3.4 验证容器状态
- 查看 etcd 容器状态
[root@docker-node-1 etcd]# docker compose ps -a
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
etcd-s1 quay.io/coreos/etcd:v3.5.12 "/usr/local/bin/etcd" etcd 17 seconds ago Up 16 seconds 0.0.0.0:2379-2380->2379-2380/tcp, :::2379-2380->2379-2380/tcp
4. etcd 服务可用性测试
为了测试 etcd 服务的可用性,额外再找一台机器安装 etcd 客户端工具用于验证测试。
- 下载并解压软件包
cd /srv
wget https://github.com/etcd-io/etcd/releases/download/v3.5.12/etcd-v3.5.12-linux-amd64.tar.gz
tar xvf etcd-v3.5.12-linux-amd64.tar.gz
cd etcd-v3.5.12-linux-amd64
- 使用 etcdctl 工具验证测试 endpoint
# ./etcdctl --endpoints=192.168.9.81:2379 --write-out=table endpoint health
------------------- -------- ------------ -------
| ENDPOINT | HEALTH | TOOK | ERROR |
------------------- -------- ------------ -------
| 192.168.9.81:2379 | true | 2.517794ms | |
------------------- -------- ------------ -------
# ./etcdctl --endpoints=192.168.9.81:2379 --write-out=table endpoint status
------------------- ----------------- --------- --------- ----------- ------------ ----------- ------------ -------------------- --------
| ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
------------------- ----------------- --------- --------- ----------- ------------ ----------- ------------ -------------------- --------
| 192.168.9.81:2379 | 1c70f9bbb41018f | 3.5.12 | 20 kB | true | false | 2 | 4 | 4 | |
------------------- ----------------- --------- --------- ----------- ------------ ----------- ------------ -------------------- --------
- 使用 etcdctl 工具验证测试 member
# ./etcdctl --endpoints=192.168.9.81:2379 --write-out=table member list
----------------- --------- --------- --------------------- --------------------- ------------
| ID | STATUS | NAME | PEER ADDRS | CLIENT ADDRS | IS LEARNER |
----------------- --------- --------- --------------------- --------------------- ------------
| 1c70f9bbb41018f | started | etcd-s1 | http://0.0.0.0:2380 | http://0.0.0.0:2379 | false |
----------------- --------- --------- --------------------- --------------------- ------------
- 使用 etcdctl 工具验证测试数据读写
# 写入数据
# ./etcdctl --endpoints=192.168.9.81:2379 put foo bar
OK
# 读取数据
# ./etcdctl --endpoints=192.168.9.81:2379 get foo
foo
bar
5. 自动化 Shell 脚本
全文所有的操作,我都整理成了自动化脚本:
- 配置文件模式
deploy-etcd-conf.sh
#!/bin/bash
set -e
etcd_name=${1:-"etcd-s1"}
docker_container_dir=${2:-"/data/containers"}
# 创建基础目录
mkdir -p ${docker_container_dir}/etcd/{data,config}
# 创建 etcd 配置文件
function deploy_etcd_config(){
cat > ${docker_container_dir}/etcd/config/etcd.conf.yml <<-EOF
name: ${etcd_name}
data-dir: /var/etcd
listen-client-urls: http://0.0.0.0:2379
advertise-client-urls: http://0.0.0.0:2379
listen-peer-urls: http://0.0.0.0:2380
initial-advertise-peer-urls: http://0.0.0.0:2380
initial-cluster: etcd-s1=http://0.0.0.0:2380
initial-cluster-token: etcd-cluster
initial-cluster-state: new
logger: zap
log-level: info
#log-outputs: stderr
EOF
}
# 创建 docker-compose 文件
function deploy_compose_config(){
cat > ${docker_container_dir}/etcd/docker-compose.yml <<-EOF
version: '3'
services:
etcd:
container_name: ${etcd_name}
image: quay.io/coreos/etcd:v3.5.12
command: /usr/local/bin/etcd --config-file=/var/lib/etcd/conf/etcd.conf.yml
volumes:
- ${DOCKER_VOLUME_DIRECTORY:-.}/data:/var/etcd
- ${DOCKER_VOLUME_DIRECTORY:-.}/config/etcd.conf.yml:/var/lib/etcd/conf/etcd.conf.yml
- "/etc/localtime:/etc/localtime:ro"
ports:
- 2379:2379
- 2380:2380
restart: always
networks:
default:
name: etcd-tier
driver: bridge
EOF
}
# 创建 etcd 服务
function deploy_etcd(){
cd ${docker_container_dir}/etcd
docker compose up -d
}
# 验证 etcd 服务
function check_etcd(){
cd ${docker_container_dir}/etcd
docker compose ps
}
echo -e "