Docker 最佳实战:Docker 部署 etcd 集群实战

2024-03-07 17:40:09 浏览数 (3)

Docker 最佳实战:Docker 部署 etcd 集群实战

2024 年云原生运维实战文档 99 篇原创计划 第 005 篇 |Docker 最佳实战「2024」系列 第 005 篇

前言

你好,欢迎来到运维有术

今天分享的内容是 Docker 最佳实战「2024」 系列文档中的 Docker 部署 etcd 集群实战

内容导图

docker-cluster-etcd-mindmapdocker-cluster-etcd-mindmap

实战服务器配置 (架构 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

上一期我们基于 coreos 官方提供的 Docker 镜像完成了单节点 etcd 部署实战。

本期我们继续基于配置文件和环境变量两种方式,完成 etcd 集群部署实战。

1. 部署 etcd 集群-基于配置文件

本节内容使用配置文件的方式实现 etcd 集群服务配置。

1.1 创建 etcd 数据目录

代码语言:bash复制
mkdir -p /data/containers/etcd/{data,config}
  • data 目录:建议, 存储容器持久化数据
  • config 目录:建议, 存储容器使用的配置文件

1.2 创建 etcd 配置文件

etcd 服务配置文件路径为:/data/containers/etcd/config/etcd.conf.yml

每个节点内容不一样,需要分别编写。

节点 1 的文件内容如下:

代码语言:yaml复制
name: etcd-1
data-dir: /var/etcd
listen-client-urls: http://0.0.0.0:2379
advertise-client-urls: http://192.168.9.81:2379
listen-peer-urls: http://0.0.0.0:2380
initial-advertise-peer-urls: http://192.168.9.81:2380
initial-cluster: etcd-1=http://192.168.9.81:2380,etcd-2=http://192.168.9.82:2380,etcd-3=http://192.168.9.83:2380
initial-cluster-token: etcd-cluster
initial-cluster-state: new
logger: zap
log-level: info
#log-outputs: stder

节点 2 的文件内容如下:

代码语言:yaml复制
name: etcd-2
data-dir: /var/etcd
listen-client-urls: http://0.0.0.0:2379
advertise-client-urls: http://192.168.9.82:2379
listen-peer-urls: http://0.0.0.0:2380
initial-advertise-peer-urls: http://192.168.9.82:2380
initial-cluster: etcd-1=http://192.168.9.81:2380,etcd-2=http://192.168.9.82:2380,etcd-3=http://192.168.9.83:2380
initial-cluster-token: etcd-cluster
initial-cluster-state: new
logger: zap
log-level: info
#log-outputs: stderr

节点 3 的文件内容如下:

代码语言:yaml复制
name: etcd-3
data-dir: /var/etcd
listen-client-urls: http://0.0.0.0:2379
advertise-client-urls: http://192.168.9.83:2379
listen-peer-urls: http://0.0.0.0:2380
initial-advertise-peer-urls: http://192.168.9.83:2380
initial-cluster: etcd-1=http://192.168.9.81:2380,etcd-2=http://192.168.9.82:2380,etcd-3=http://192.168.9.83:2380
initial-cluster-token: etcd-cluster
initial-cluster-state: new
logger: zap
log-level: info
#log-outputs: stder

配置文件特殊配置项说明:

  • name: 每个节点的 etcd 服务名称
  • advertise-client-urls: 填写每个 etcd 容器所在节点对外提供服务的 IP
  • initial-advertise-peer-urls: 填写每个 etcd 容器所在节点对外提供服务的 IP
  • initial-cluster: 每个节点使用相同配置,包含所有节点的名称和 initial-advertise-peer-urls 地址

1.3 创建 docker-compose 文件

代码语言:yaml复制
version: '3'

services:
  etcd:
    container_name: etcd
    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

1.4 创建并启动 etcd 服务

所有节点都执行下面的命令,完成 etcd 集群服务的创建。

代码语言:bash复制
cd /data/containers/etcd
docker compose up -d

命令成功执行的结果如下 (以节点 1 为例):

代码语言:bash复制
[root@docker-node-1 etcd]# docker compose up -d
[ ] Running 1/2
 ⠸ Network etcd-tier  Created                                                                                                                                   0.4s
 ✔ Container etcd-s1  Started 

1.5 验证容器状态

  • 查看 etcd 容器状态 (以节点 1 为例)
代码语言:bash复制
[root@docker-node-1 etcd]# docker compose ps -a
NAME      IMAGE                         COMMAND                  SERVICE   CREATED          STATUS          PORTS
etcd-1    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

2. 部署 etcd 集群-基于环境变量

本节内容使用环境变量的方式实现 etcd 服务配置。

2.1 创建 etcd 数据目录

代码语言:bash复制
mkdir -p /data/containers/etcd/data
  • data 目录:建议, 存储容器持久化数据

2.2 创建 docker-compose 文件

每个节点内容不一样,需要分别编写,vi/data/containers/etcd/docker-compose.yml

节点 1 的文件内容如下:

代码语言:yaml复制
version: '3'

services:
  etcd:
    container_name: etcd-s1
    image: quay.io/coreos/etcd:v3.5.12
    environment:
      - ETCD_NAME=etcd-1
      - ETCD_DATA_DIR=/var/etcd
      - ETCD_LISTEN_CLIENT_URLS=http://0.0.0.0:2379
      - ETCD_ADVERTISE_CLIENT_URLS=http://192.168.9.81:2379
      - ETCD_LISTEN_PEER_URLS=http://0.0.0.0:2380
      - ETCD_INITIAL_ADVERTISE_PEER_URLS=http://192.168.9.81:2380
      - ETCD_INITIAL_CLUSTER_TOKEN=etcd-cluster
      - ETCD_INITIAL_CLUSTER=etcd-1=http://192.168.9.81:2380,etcd-2=http://192.168.9.82:2380,etcd-3=http://192.168.9.83: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

节点 2 的文件内容如下:

代码语言:yaml复制
version: '3'

services:
  etcd:
    container_name: etcd-s1
    image: quay.io/coreos/etcd:v3.5.12
    environment:
      - ETCD_NAME=etcd-1
      - ETCD_DATA_DIR=/var/etcd
      - ETCD_LISTEN_CLIENT_URLS=http://0.0.0.0:2379
      - ETCD_ADVERTISE_CLIENT_URLS=http://192.168.9.82:2379
      - ETCD_LISTEN_PEER_URLS=http://0.0.0.0:2380
      - ETCD_INITIAL_ADVERTISE_PEER_URLS=http://192.168.9.82:2380
      - ETCD_INITIAL_CLUSTER_TOKEN=etcd-cluster
      - ETCD_INITIAL_CLUSTER=etcd-1=http://192.168.9.81:2380,etcd-2=http://192.168.9.82:2380,etcd-3=http://192.168.9.83: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 的文件内容如下:

代码语言:yaml复制
version: '3'

services:
  etcd:
    container_name: etcd-s1
    image: quay.io/coreos/etcd:v3.5.12
    environment:
      - ETCD_NAME=etcd-1
      - ETCD_DATA_DIR=/var/etcd
      - ETCD_LISTEN_CLIENT_URLS=http://0.0.0.0:2379
      - ETCD_ADVERTISE_CLIENT_URLS=http://192.168.9.83:2379
      - ETCD_LISTEN_PEER_URLS=http://0.0.0.0:2380
      - ETCD_INITIAL_ADVERTISE_PEER_URLS=http://192.168.9.83:2380
      - ETCD_INITIAL_CLUSTER_TOKEN=etcd-cluster
      - ETCD_INITIAL_CLUSTER=etcd-1=http://192.168.9.81:2380,etcd-2=http://192.168.9.82:2380,etcd-3=http://192.168.9.83: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

配置文件特殊配置项说明:

  • ETCD_NAME 每个节点的 etcd 服务名称
  • ETCD_ADVERTISE_CLIENT_URLS 填写每个 etcd 容器所在节点对外提供服务的 IP
  • ETCD_INITIAL_ADVERTISE_PEER_URLS 填写每个 etcd 容器所在节点对外提供服务的 IP
  • ETCD_INITIAL_CLUSTER:每个节点使用相同配置,包含所有节点的名称和 ETCD_INITIAL_ADVERTISE_PEER_URLS 地址

2.3 创建并启动 etcd 服务

所有节点都执行下面的命令,完成 etcd 集群服务的创建。

代码语言:bash复制
cd /data/containers/etcd
docker compose up -d

2.4 验证容器状态

  • 查看 etcd 容器状态 (以节点 1 为例)
代码语言:bash复制
[root@docker-node-1 etcd]# docker compose ps -a
NAME      IMAGE                         COMMAND                  SERVICE   CREATED          STATUS          PORTS
etcd-1    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 服务的可用性,额外再找一台机器安装 etcd 客户端工具用于验证测试。

  • 下载并解压软件包
代码语言:bash复制
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
代码语言:bash复制
# ./etcdctl --endpoints=192.168.9.81:2379,192.168.9.82:2379,192.168.9.83:2379 --write-out=table endpoint health
 ------------------- -------- ------------- ------- 
|     ENDPOINT      | HEALTH |    TOOK     | ERROR |
 ------------------- -------- ------------- ------- 
| 192.168.9.81:2379 |   true |  6.698562ms |       |
| 192.168.9.82:2379 |   true | 20.894522ms |       |
| 192.168.9.83:2379 |   true | 21.585328ms |       |
 ------------------- -------- ------------- ------- 

# ./etcdctl --endpoints=192.168.9.81:2379,192.168.9.82:2379,192.168.9.83: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 | ee1780cf52566749 |  3.5.12 |   20 kB |      true |      false |         2 |         13 |                 13 |        |
| 192.168.9.82:2379 | 94e339f5d245a36b |  3.5.12 |   20 kB |     false |      false |         2 |         13 |                 13 |        |
| 192.168.9.83:2379 | 247803a54771eb27 |  3.5.12 |   20 kB |     false |      false |         2 |         13 |                 13 |        |
 ------------------- ------------------ --------- --------- ----------- ------------ ----------- ------------ -------------------- -------- 
  • 使用 etcdctl 工具验证测试 member
代码语言:bash复制
# ./etcdctl --endpoints=192.168.9.81:2379,192.168.9.82:2379,192.168.9.83:2379 --write-out=table member list
 ------------------ --------- -------- -------------------------- -------------------------- ------------ 
|        ID        | STATUS  |  NAME  |        PEER ADDRS        |       CLIENT ADDRS       | IS LEARNER |
 ------------------ --------- -------- -------------------------- -------------------------- ------------ 
| 247803a54771eb27 | started | etcd-3 | http://192.168.9.83:2380 | http://192.168.9.83:2379 |      false |
| 94e339f5d245a36b | started | etcd-2 | http://192.168.9.82:2380 | http://192.168.9.82:2379 |      false |
| ee1780cf52566749 | started | etcd-1 | http://192.168.9.81:2380 | http://192.168.9.81:2379 |      false |
 ------------------ --------- -------- -------------------------- -------------------------- ------------ 
  • 使用 etcdctl 工具验证测试数据读写
代码语言:bash复制
# 写入数据
# ./etcdctl --endpoints=192.168.9.81:2379,192.168.9.82:2379,192.168.9.83:2379 put foo bar
OK

# 读取数据
# ./etcdctl --endpoints=192.168.9.81:2379,192.168.9.82:2379,192.168.9.83:2379 get foo
foo
bar

4. 自动化 Shell 脚本

全文所有的操作,我都整理成了自动化脚本。

自动化脚本说明:

  • 由于调试过程中没有解决 EOF 报错的问题,function 里 cat 部分的内容没有缩进,看着不美观,但是不影响使用。
  • Shell 脚本实现这种多节点,多变量的自动化部署配置比较麻烦,实际中建议使用 Ansible 实现自动化。

4.1 配置文件模式

编写部署脚本 deploy-etcd-cluser-conf.sh

代码语言:bash复制
#!/bin/bash
# author:@运维有术
set -e

# 设置 etcd 服务名称,必须修改
etcd_name=${1:-"etcd-1"}

# 设置 etcd 服务对外 IP,必须修改(填写 etcd 容器所在节点对外提供服务的 IP)
etcd_client_ip=${2:-"0.0.0.0"}

# 设置 etcd 初始化集群信息,必须修改
etcd_initial_cluster=${3:-"etcd-1=http://192.168.9.81:2380,etcd-2=http://192.168.9.82:2380,etcd-3=http://192.168.9.83:2380"}

# 设置 containers 基础目录,可选修改
docker_container_dir=${4:-"/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://${etcd_client_ip}:2379
listen-peer-urls: http://0.0.0.0:2380
initial-advertise-peer-urls: http://${etcd_client_ip}:2380
initial-cluster: ${etcd_initial_cluster}
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 "33[1;32m [1].Deploy etcd config.n 33[0m"
deploy_etcd_config

echo -e "33[1;32m [2].Deploy docker compose config.n 33[0m"
deploy_compose_config

echo -e "33[1;32m [3].Deploy etcd service.n 33[0m"
deploy_etcd

echo -e "33[1;32m [4].Check etcd service status. 33[0m"
check_etcd

使用脚本部署 etcd 集群。

  • 节点 1 执行
代码语言:bash复制
./deploy-etcd-cluster-conf.sh etcd-1 192.168.9.81 etcd-1=http://192.168.9.81:2380,etcd-2=http://192.168.9.82:2380,etcd-3=http://192.168.9.83:2380
  • 节点 2 执行
代码语言:bash复制
./deploy-etcd-cluster-conf.sh etcd-2 192.168.9.82 etcd-1=http://192.168.9.81:2380,etcd-2=http://192.168.9.82:2380,etcd-3=http://192.168.9.83:2380
  • 节点 3 执行
代码语言:bash复制
./deploy-etcd-cluster-conf.sh etcd-3 192.168.9.83 etcd-1=http://192.168.9.81:2380,etcd-2=http://192.168.9.82:2380,etcd-3=http://192.168.9.83:2380

4.2 环境变量模式

编写部署脚本 deploy-etcd-cluster-env.sh

代码语言:bash复制
#!/bin/bash
# author:@运维有术
set -e

# 设置 etcd 服务名称,必须修改
etcd_name=${1:-"etcd-1"}

# 设置 etcd 服务对外 IP,必须修改(填写 etcd 容器所在节点对外提供服务的 IP)
etcd_client_ip=${2:-"0.0.0.0"}

# 设置 etcd 初始化集群信息,必须修改
etcd_initial_cluster=${3:-"etcd-1=http://192.168.9.81:2380,etcd-2=http://192.168.9.82:2380,etcd-3=http://192.168.9.83:2380"}

# 设置 containers 基础目录,可选修改
docker_container_dir=${4:-"/data/containers"}

# 创建基础目录
mkdir -p ${docker_container_dir}/etcd/data

# 创建 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
    environment:
      - ETCD_NAME=${etcd_name}
      - ETCD_DATA_DIR=/var/etcd
      - ETCD_LISTEN_CLIENT_URLS=http://0.0.0.0:2379
      - ETCD_ADVERTISE_CLIENT_URLS=http://${etcd_client_ip}:2379
      - ETCD_LISTEN_PEER_URLS=http://0.0.0.0:2380
      - ETCD_INITIAL_ADVERTISE_PEER_URLS=http://${etcd_client_ip}:2380
      - ETCD_INITIAL_CLUSTER_TOKEN=etcd-cluster
      - ETCD_INITIAL_CLUSTER=${etcd_initial_cluster}
      - 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

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 "33[1;32m [1].Deploy docker compose config.n 33[0m"
deploy_compose_config

echo -e "33[1;32m [2].Deploy etcd service.n 33[0m"
deploy_etcd

echo -e "33[1;32m [3].Check etcd service status. 33[0m"
check_etcd

使用脚本部署 etcd 集群。

  • 节点 1 执行
代码语言:bash复制
./deploy-etcd-cluster-env.sh etcd-1 192.168.9.81 etcd-1=http://192.168.9.81:2380,etcd-2=http://192.168.9.82:2380,etcd-3=http://192.168.9.83:2380
  • 节点 2 执行
代码语言:bash复制
./deploy-etcd-cluster-env.sh etcd-2 192.168.9.82 etcd-1=http://192.168.9.81:2380,etcd-2=http://192.168.9.82:2380,etcd-3=http://192.168.9.83:2380
  • 节点 3 执行
代码语言:bash复制
./deploy-etcd-cluster-env.sh etcd-3 192.168.9.83 etcd-1=http://192.168.9.81:2380,etcd-2=http://192.168.9.82:2380,etcd-3=http://192.168.9.83:2380

5. 课后练习

根据本文所学,请完成以下实战任务。

  1. 手工部署基于配置文件的 etcd 集群
  2. 手工部署基于环境变量的 etcd 集群
  3. 使用自动化脚本部署基于配置文件的 etcd 集群
  4. 使用自动化脚本部署基于环境变量的 etcd 集群
  5. 使用命令行验证测试 etcd 集群服务可用性及状态

6. 总结

本文分享了基于 coreos 官方提供的 etcd 镜像部署 etcd 集群服务的详细流程及注意事项。主要内容概括如下:

  • 基于配置文件的方式实现 etcd 集群服务部署
  • 基于环境变量的方式实现 etcd 集群服务部署
  • 基于配置文件和环境变量方式的 etcd 集群服务自动化部署脚本编写
  • etcd 集群服务可用性验证测试

Get 本文实战视频(请注意,文档视频异步发行,请先关注)

  • B 站 运维有术

免责声明:

  • 笔者水平有限,尽管经过多次验证和检查,尽力确保内容的准确性,但仍可能存在疏漏之处。敬请业界专家大佬不吝指教。
  • 本文所述内容仅通过实战环境验证测试,读者可学习、借鉴,但严禁直接用于生产环境由此引发的任何问题,作者概不负责

结束语

如果你喜欢本文,请分享、收藏、点赞、评论! 请持续关注 @ 运维有术,及时收看更多好文!

欢迎加入 「运维有术·云原生实战训练营」 ,获取更多的 KubeSphere、Kubernetes、云原生运维实战技能。

版权声明

  • 所有内容均属于原创,感谢阅读、收藏,转载请联系授权,未经授权不得转载

1 人点赞