部署高可用 etcd 集群

kuberntes 系统使用 etcd 存储所有数据,本文档介绍部署一个三节点高可用 etcd 集群的步骤,这三个节点复用 kubernetes master 机器,分别命名为etcd-host0etcd-host1etcd-host2

  • etcd-host0:10.64.3.7
  • etcd-host1:10.64.3.8
  • etcd-host2:10.66.3.86

使用的变量

本文档用到的变量定义如下:

  1. $ export NODE_NAME=etcd-host0 # 当前部署的机器名称(随便定义,只要能区分不同机器即可)
  2. $ export NODE_IP=10.64.3.7 # 当前部署的机器 IP
  3. $ export NODE_IPS="10.64.3.7 10.64.3.8 10.66.3.86" # etcd 集群所有机器 IP
  4. $ # etcd 集群间通信的IP和端口
  5. $ export ETCD_NODES=etcd-host0=https://10.64.3.7:2380,etcd-host1=https://10.64.3.8:2380,etcd-host2=https://10.66.3.86:2380
  6. $ # 导入用到的其它全局变量:ETCD_ENDPOINTS、FLANNEL_ETCD_PREFIX、CLUSTER_CIDR
  7. $ source /root/local/bin/environment.sh
  8. $

下载二进制文件

https://github.com/coreos/etcd/releases 页面下载最新版本的二进制文件:

  1. $ wget https://github.com/coreos/etcd/releases/download/v3.1.6/etcd-v3.1.6-linux-amd64.tar.gz
  2. $ tar -xvf etcd-v3.1.6-linux-amd64.tar.gz
  3. $ sudo mv etcd-v3.1.6-linux-amd64/etcd* /root/local/bin
  4. $

创建 TLS 秘钥和证书

为了保证通信安全,客户端(如 etcdctl) 与 etcd 集群、etcd 集群之间的通信需要使用 TLS 加密,本节创建 etcd TLS 加密所需的证书和私钥。

创建 etcd 证书签名请求:

  1. $ cat > etcd-csr.json <<EOF
  2. {
  3. "CN": "etcd",
  4. "hosts": [
  5. "127.0.0.1",
  6. "${NODE_IP}"
  7. ],
  8. "key": {
  9. "algo": "rsa",
  10. "size": 2048
  11. },
  12. "names": [
  13. {
  14. "C": "CN",
  15. "ST": "BeiJing",
  16. "L": "BeiJing",
  17. "O": "k8s",
  18. "OU": "System"
  19. }
  20. ]
  21. }
  22. EOF
  • hosts 字段指定授权使用该证书的 etcd 节点 IP;

生成 etcd 证书和私钥:

  1. $ cfssl gencert -ca=/etc/kubernetes/ssl/ca.pem \
  2. -ca-key=/etc/kubernetes/ssl/ca-key.pem \
  3. -config=/etc/kubernetes/ssl/ca-config.json \
  4. -profile=kubernetes etcd-csr.json | cfssljson -bare etcd
  5. $ ls etcd*
  6. etcd.csr etcd-csr.json etcd-key.pem etcd.pem
  7. $ sudo mkdir -p /etc/etcd/ssl
  8. $ sudo mv etcd*.pem /etc/etcd/ssl
  9. $ rm etcd.csr etcd-csr.json

创建 etcd 的 systemd unit 文件

  1. $ sudo mkdir -p /var/lib/etcd # 必须先创建工作目录
  2. $ cat > etcd.service <<EOF
  3. [Unit]
  4. Description=Etcd Server
  5. After=network.target
  6. After=network-online.target
  7. Wants=network-online.target
  8. Documentation=https://github.com/coreos
  9. [Service]
  10. Type=notify
  11. WorkingDirectory=/var/lib/etcd/
  12. ExecStart=/root/local/bin/etcd \\
  13. --name=${NODE_NAME} \\
  14. --cert-file=/etc/etcd/ssl/etcd.pem \\
  15. --key-file=/etc/etcd/ssl/etcd-key.pem \\
  16. --peer-cert-file=/etc/etcd/ssl/etcd.pem \\
  17. --peer-key-file=/etc/etcd/ssl/etcd-key.pem \\
  18. --trusted-ca-file=/etc/kubernetes/ssl/ca.pem \\
  19. --peer-trusted-ca-file=/etc/kubernetes/ssl/ca.pem \\
  20. --initial-advertise-peer-urls=https://${NODE_IP}:2380 \\
  21. --listen-peer-urls=https://${NODE_IP}:2380 \\
  22. --listen-client-urls=https://${NODE_IP}:2379,http://127.0.0.1:2379 \\
  23. --advertise-client-urls=https://${NODE_IP}:2379 \\
  24. --initial-cluster-token=etcd-cluster-0 \\
  25. --initial-cluster=${ETCD_NODES} \\
  26. --initial-cluster-state=new \\
  27. --data-dir=/var/lib/etcd
  28. Restart=on-failure
  29. RestartSec=5
  30. LimitNOFILE=65536
  31. [Install]
  32. WantedBy=multi-user.target
  33. EOF
  • 指定 etcd 的工作目录和数据目录为 /var/lib/etcd,需在启动服务前创建这个目录;
  • 为了保证通信安全,需要指定 etcd 的公私钥(cert-file和key-file)、Peers 通信的公私钥和 CA 证书(peer-cert-file、peer-key-file、peer-trusted-ca-file)、客户端的CA证书(trusted-ca-file);
  • --initial-cluster-state 值为 new 时,--name 的参数值必须位于 --initial-cluster 列表中;

完整 unit 文件见:etcd.service

启动 etcd 服务

  1. $ sudo mv etcd.service /etc/systemd/system/
  2. $ sudo systemctl daemon-reload
  3. $ sudo systemctl enable etcd
  4. $ sudo systemctl start etcd
  5. $ systemctl status etcd
  6. $

最先启动的 etcd 进程会卡住一段时间,等待其它节点上的 etcd 进程加入集群,为正常现象。

在所有的 etcd 节点重复上面的步骤,直到所有机器的 etcd 服务都已启动。

验证服务

部署完 etcd 集群后,在任一 etcd 集群节点上执行如下命令:

  1. $ for ip in ${NODE_IPS}; do
  2. ETCDCTL_API=3 /root/local/bin/etcdctl \
  3. --endpoints=https://${ip}:2379 \
  4. --cacert=/etc/kubernetes/ssl/ca.pem \
  5. --cert=/etc/etcd/ssl/etcd.pem \
  6. --key=/etc/etcd/ssl/etcd-key.pem \
  7. endpoint health; done

预期结果:

  1. 2017-04-10 14:50:50.011317 I | warning: ignoring ServerName for user-provided CA for backwards compatibility is deprecated
  2. https://10.64.3.7:2379 is healthy: successfully committed proposal: took = 1.687897ms
  3. 2017-04-10 14:50:50.061577 I | warning: ignoring ServerName for user-provided CA for backwards compatibility is deprecated
  4. https://10.64.3.8:2379 is healthy: successfully committed proposal: took = 1.246915ms
  5. 2017-04-10 14:50:50.104718 I | warning: ignoring ServerName for user-provided CA for backwards compatibility is deprecated
  6. https://10.66.3.86:2379 is healthy: successfully committed proposal: took = 1.509229ms

三台 etcd 的输出均为 healthy 时表示集群服务正常(忽略 warning 信息)。