创建加密的ETCD docker集群 实战记录

ETCD 集群在现代IT界面里被广泛用到,Mesos,Kubernetes, SpringCloud,
Ceph 这些知名的开源软件都用到了etcd集群。

之前的部署基本都是内部使用,没有考虑到如何使用安全加密的ETCD,最近深入研究了k8s和Ceph, 发现etcd 基于TLS安全通讯的集群模式是很重要的事情。 下面是基于实践的记录,如何成功部署基于docker 的ETCD 集群

前提条件:
1.有3台虚拟机centos7,虚拟机已经安装好了docker
2. 每一个虚拟机导入 k8s.gcr.io/etcd:3.3.10 镜像
如果您无法下载 可以下载 docker pull ascs/k8s-gcr-io-etcd:3.3.10

然后 docker image tag ascs/k8s-gcr-io-etcd:3.3.10 k8s.gcr.io/etcd:3.3.10

部署安全的etcd集群。
本指南说明了如何设置高可用性etcd服务器集群以及如何确保与TLS的通信安全。 本指南改编自官方的etcd文档,您可以在其中找到更多详细信息。
证书生成要启用TLS,您需要生成自签名证书颁发机构和服务器证书。 在此示例中,我们将考虑使用以下节点作为etcd服务器。

主机名FQDNIP地址
etcd1etcd1.linkaixin.com10.6.4.31
etcd2etcd2.linkaixin.com10.6.4.32
etcd3etcd3.linkaixin.com10.6.4.33

注意:为了获得高可用性,最好使用奇数个服务器。 添加更多服务器可提高高可用性,并可以提高读取性能,但会降低写入性能。 建议使用3、5或7个服务器。为了生成CA和服务器证书,我们按照官方文档中的建议使用Cloudflare的cfssl。 它可以很容易地安装,如下所示:

第一步: 创建证书

mkdir ~/bin
curl -s -L -o ~/bin/cfssl https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
curl -s -L -o ~/bin/cfssljson https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
chmod +x ~/bin/{cfssl,cfssljson}
export PATH=$PATH:~/bin

#创建一个目录来保存您的证书和私钥。 如果需要生成更多证书,将来可能会需要它们,因此请确保将它们保存在具有受限访权限的安全位置:

mkdir ~/etcd-ca
cd ~/etcd-ca

#生成CA证书
echo '{"CN":"CA","key":{"algo":"rsa","size":2048}}' | cfssl gencert -initca - | cfssljson -bare ca -
echo '{"signing":{"default":{"expiry":"43800h","usages":["signing","key encipherment","server auth","client auth"]}}}' > ca-config.json

#对于每个etcd服务器,生成如下证书:

export NAME=etcd1
export DOMAIN="linkaixin.com"
export ADDRESS=10.6.4.31,$NAME.$DOMAIN,$NAME
echo '{"CN":"'$NAME'","hosts":[""],"key":{"algo":"rsa","size":2048}}' | cfssl gencert -config=ca-config.json -ca=ca.pem -ca-key=ca-key.pem -hostname="$ADDRESS" - | cfssljson -bare $NAME
export NAME=etcd2
export DOMAIN="linkaixin.com"
export ADDRESS=10.6.4.32,$NAME.$DOMAIN,$NAME
echo '{"CN":"'$NAME'","hosts":[""],"key":{"algo":"rsa","size":2048}}' | cfssl gencert -config=ca-config.json -ca=ca.pem -ca-key=ca-key.pem -hostname="$ADDRESS" - | cfssljson -bare $NAME
export NAME=etcd3
export DOMAIN="linkaixin.com"
export ADDRESS=10.6.4.33,$NAME.$DOMAIN,$NAME
echo '{"CN":"'$NAME'","hosts":[""],"key":{"algo":"rsa","size":2048}}' | cfssl gencert -config=ca-config.json -ca=ca.pem -ca-key=ca-key.pem -hostname="$ADDRESS" - | cfssljson -bare $NAME

在etcd1 机器上
依次执行上面的命令
在这里插入图片描述

得到如下文件列表:

[ceph@ceph1 etcd-ca]$ pwd
/home/ceph/etcd-ca
[ceph@ceph1 etcd-ca]$ ls -al
总用量 52
drwxrwxr-x 2 ceph ceph 239 10月 28 15:01 .
drwx------. 7 ceph ceph 168 10月 28 15:00 …
-rw-rw-r-- 1 ceph ceph 112 10月 28 15:00 ca-config.json
-rw-r–r-- 1 ceph ceph 883 10月 28 15:00 ca.csr
-rw------- 1 ceph ceph 1679 10月 28 15:00 ca-key.pem
-rw-rw-r-- 1 ceph ceph 1119 10月 28 15:00 ca.pem
-rw-r–r-- 1 ceph ceph 928 10月 28 15:01 etcd1.csr
-rw------- 1 ceph ceph 1679 10月 28 15:01 etcd1-key.pem
-rw-rw-r-- 1 ceph ceph 1220 10月 28 15:01 etcd1.pem
-rw-r–r-- 1 ceph ceph 928 10月 28 15:01 etcd2.csr
-rw------- 1 ceph ceph 1679 10月 28 15:01 etcd2-key.pem
-rw-rw-r-- 1 ceph ceph 1220 10月 28 15:01 etcd2.pem
-rw-r–r-- 1 ceph ceph 928 10月 28 15:01 etcd3.csr
-rw------- 1 ceph ceph 1679 10月 28 15:01 etcd3-key.pem
-rw-rw-r-- 1 ceph ceph 1220 10月 28 15:01 etcd3.pem

注意:
如果将通过其他IP或DNS别名访问服务器,请确保在ADDRESS变量中引用它们。(当你的etcd机器上有多个IP时 或多个域名指向时)

现在,您必须在每个服务器节点的/ etc / etcd /目录中部署生成的密钥和证书。

#在etcd-ca目录下 分别为3个etcd 节点创建对应的证书

 mkdir -p deploy/etcd1
 mkdir -p deploy/etcd2
 mkdir -p deploy/etcd3


cd etcd-ca/deploy/etcd1

cp ../../ca.pem etcd-ca.crt
cp ../../etcd1.pem server.crt
cp ../../etcd1-key.pem server.key


cd etcd-ca/deploy/etcd2
cp ../../ca.pem etcd-ca.crt
cp ../../etcd2.pem server.crt
cp ../../etcd2-key.pem server.key


cd etcd-ca/deploy/etcd3
cp ../../ca.pem etcd-ca.crt
cp ../../etcd3.pem server.crt
cp ../../etcd3-key.pem server.key

确保通信安全:
要为etcd配置安全的对等通信,请指定标志 --peer-key-file=peer.key 和 --peer-cert-file=peer.cert,并使用https作为URL架构。
同样,要为etcd配置安全的客户端通信,请指定标志 --key-file=k8sclient.key and --cert-file=k8sclient.cert, 并使用https作为URL架构。

注意:
稍后将必须在承载pcocc的所有节点(前端和计算节点)上部署CA证书ca.pem。 确保与整个etcd-ca目录一起保留备份。
etcd配置:
需要在/etc/etcd/etcd.conf配置文件中的每个服务器节点上配置etcd。 这是node1的示例:
ETCD_NAME=node1
ETCD_LISTEN_PEER_URLS=“https://10.19.213.101:2380”
ETCD_LISTEN_CLIENT_URLS=“https://10.19.213.101:2379”
ETCD_INITIAL_CLUSTER_TOKEN=“pcocc-etcd-cluster”
ETCD_INITIAL_CLUSTER=“node1=https://node1.mydomain.com:2380,node2=https://node2.mydomain.com:2380,node3=https://node3.mydomain.com:2380”
ETCD_INITIAL_ADVERTISE_PEER_URLS=“https://node1.mydomain.com:2380”
ETCD_ADVERTISE_CLIENT_URLS=“https://node1.mydomain.com:2379”
ETCD_TRUSTED_CA_FILE=/etc/etcd/etcd-ca.crt
ETCD_CERT_FILE="/etc/etcd/server.crt"
ETCD_KEY_FILE="/etc/etcd/server.key"
ETCD_PEER_CLIENT_CERT_AUTH=true
ETCD_PEER_TRUSTED_CA_FILE=/etc/etcd/etcd-ca.crt
ETCD_PEER_KEY_FILE=/etc/etcd/server.key
ETCD_PEER_CERT_FILE=/etc/etcd/server.crt

注意
ETCD_NAME,ETCD_ADVERTISE_CLIENT_URLS,ETCD_INITIAL_ADVERTISE_PEER_URLS,ETCD_LISTEN_PEER_URLS和ETCD_LISTEN_CLIENT_URLS必须适合每个服务器节点。

最后,您可以在所有etcd节点上启用并启动服务:
在 etcd1,etcd2,etcd3 创建目录/var/server/secure-etcd
mkdir -p /var/server/secure-etcd
拷贝对应的证书过去和对应的脚本过去。

/var/server/secure-etcd
[ceph@ceph1 secure-etcd]$ ls
data ssl start-etcd-cluster.sh
[ceph@ceph1 secure-etcd]$

[ceph@ceph2 secure-etcd]$ pwd
/var/server/secure-etcd
[ceph@ceph2 secure-etcd]$ ls -al
总用量 20
drwxrwxr-x 4 ceph ceph 125 10月 28 15:07 .
drwxr-xr-x. 7 ceph ceph 266 10月 28 11:30 …
drwxr-xr-x 3 root root 20 10月 28 13:49 data
-rw-r–r-- 1 ceph ceph 4096 10月 28 11:31 ._.DS_Store
-rw-r–r-- 1 ceph ceph 6148 10月 28 11:31 .DS_Store
drwxrwxr-x 2 ceph ceph 68 10月 28 12:02 ssl
-rw-r–r-- 1 ceph ceph 4096 10月 28 11:31 ._start-etcd-cluster.sh
-rwxr-xr-x 1 ceph ceph 1856 10月 28 13:49 start-etcd-cluster.sh
[ceph@ceph2 secure-etcd]$

/var/server/secure-etcd
[ceph@ceph3 secure-etcd]$ ls -al
总用量 20
drwxrwxr-x 4 root root 125 10月 28 15:07 .
drwxr-xr-x. 6 ceph ceph 255 10月 28 11:31 …
drwxr-xr-x 3 root root 20 10月 28 13:50 data
-rw-r–r-- 1 root root 4096 10月 28 11:31 ._.DS_Store
-rw-r–r-- 1 root root 6148 10月 28 11:31 .DS_Store
drwxrwxr-x 2 root root 68 10月 28 12:09 ssl
-rw-r–r-- 1 root root 4096 10月 28 11:31 ._start-etcd-cluster.sh
-rwxr-xr-x 1 ceph ceph 1856 10月 28 13:50 start-etcd-cluster.sh
[ceph@ceph3 secure-etcd]$

使用docker 启动etcd

[ceph@ceph1 secure-etcd]$ more start-etcd-cluster.sh

#!/bin/bash
sudo systemctl start firewalld
sudo systemctl enable firewalld
firewall-cmd --add-port=2379/tcp --permanent --zone=public
firewall-cmd --add-port=2380/tcp --permanent --zone=public

current_file_path=$(cd "$(dirname "$0")"; pwd)
cd ${current_file_path}

ETCD_INITIAL_SECURE_CLUSTER="etcd1=https://10.6.4.31:2380,etcd2=https://10.6.4.32:2380,etcd3=https://10.6.4.333:2380"

ETCD_INITIAL_CLUSTER_STATE=new

#export currentHostIp=`ip -4 address show eth0 | grep 'inet' |  grep -v grep | awk '{print $2}' | cut -d '/' -f1`

firewall-cmd --reload
firewall-cmd --list-all

#注意防火墙出现奇怪问题,集群可能还无法访问,只能本机访问,需要重现启动可以解决问题. to do

docker stop etcd1
docker rm   etcd1

docker run \
  -d \
  --restart=always \
  --hostname=etcd1 \
  -p 2379:2379 \
  -p 2380:2380 \
  -v /etc/localtime:/etc/localtime \
  -v `pwd`/data:/data \
  -v `pwd`/ssl:/etc/etcd/ssl \
  --name etcd1 \
  nexus.linkaixin.com:2443/k8s.gcr.io/etcd:3.3.10 \
   etcd \
  -name etcd1 \
  --cert-file=/etc/etcd/ssl/etcd1-server.crt \
  --key-file=/etc/etcd/ssl/etcd1-server.key \
  --peer-cert-file=/etc/etcd/ssl/etcd1-server.crt \
  --peer-key-file=/etc/etcd/ssl/etcd1-server.key \
  --trusted-ca-file=/etc/etcd/ssl/ca.pem \
  --peer-trusted-ca-file=/etc/etcd/ssl/ca.pem \
  --initial-advertise-peer-urls https://10.6.4.31:2380 \
  --listen-peer-urls https://0.0.0.0:2380 \
  --listen-client-urls https://0.0.0.0:2379 \
  --advertise-client-urls https://10.6.4.31:2379 \
  --initial-cluster-token etcd-cluster-of-ceph \
  --initial-cluster etcd1=https://10.6.4.31:2380,etcd2=https://10.6.4.32:2380,etcd3=https://10.6.4.33:2380 \
  --initial-cluster-state new \
  --data-dir=/data

docker logs -f etcd1

etcd2 启动脚本 如下:

[ceph@ceph2 secure-etcd]$ more start-etcd-cluster.sh
#!/bin/bash
sudo systemctl start firewalld
sudo systemctl enable firewalld
firewall-cmd --add-port=2379/tcp --permanent --zone=public
firewall-cmd --add-port=2380/tcp --permanent --zone=public

current_file_path=$(cd "$(dirname "$0")"; pwd)
cd ${current_file_path}

#ETCD_INITIAL_CLUSTER="etcd1=http://10.6.4.31:2380,etcd2=http://10.6.4.32:2380,etcd3=http://10.6.4.333:2380"
ETCD_INITIAL_SECURE_CLUSTER="etcd1=https://10.6.4.31:2380,etcd2=https://10.6.4.32:2380,etcd3=https://10.6.4.333:2380"

ETCD_INITIAL_CLUSTER_STATE=new

#export currentHostIp=`ip -4 address show eth0 | grep 'inet' |  grep -v grep | awk '{print $2}' | cut -d '/' -f1`

firewall-cmd --reload
firewall-cmd --list-all

#注意防火墙出现奇怪问题,集群可能还无法访问,只能本机访问,需要重现启动可以解决问题. to do

docker stop etcd2
docker rm   etcd2

docker run \
  -d \
  --restart=always \
  --hostname=etcd2 \
  -p 2379:2379 \
  -p 2380:2380 \
  -v /etc/localtime:/etc/localtime \
  -v `pwd`/data:/data \
  -v `pwd`/ssl:/etc/etcd/ssl \
  --name etcd2 \
  nexus.linkaixin.com:2443/k8s.gcr.io/etcd:3.3.10 \
   etcd \
  -name etcd2 \
  --cert-file=/etc/etcd/ssl/etcd2-server.crt \
  --key-file=/etc/etcd/ssl/etcd2-server.key \
  --peer-cert-file=/etc/etcd/ssl/etcd2-server.crt \
  --peer-key-file=/etc/etcd/ssl/etcd2-server.key \
  --trusted-ca-file=/etc/etcd/ssl/ca.pem \
  --peer-trusted-ca-file=/etc/etcd/ssl/ca.pem \
  --initial-advertise-peer-urls https://10.6.4.32:2380 \
  --listen-peer-urls https://0.0.0.0:2380 \
  --listen-client-urls https://0.0.0.0:2379 \
  --advertise-client-urls https://10.6.4.32:2379 \
  --initial-cluster-token etcd-cluster-of-ceph \
  --initial-cluster etcd1=https://10.6.4.31:2380,etcd2=https://10.6.4.32:2380,etcd3=https://10.6.4.33:2380 \
  --initial-cluster-state existing \
  --data-dir=/data

docker logs -f etcd2

etcd3 启动脚本如下:

[ceph@ceph3 secure-etcd]$ more start-etcd-cluster.sh
#!/bin/bash
sudo systemctl start firewalld
sudo systemctl enable firewalld
firewall-cmd --add-port=2379/tcp --permanent --zone=public
firewall-cmd --add-port=2380/tcp --permanent --zone=public

current_file_path=$(cd "$(dirname "$0")"; pwd)
cd ${current_file_path}

#ETCD_INITIAL_CLUSTER="etcd1=http://10.6.4.31:2380,etcd2=http://10.6.4.32:2380,etcd3=http://10.6.4.333:2380"
ETCD_INITIAL_SECURE_CLUSTER="etcd1=https://10.6.4.31:2380,etcd2=https://10.6.4.32:2380,etcd3=https://10.6.4.333:2380"

ETCD_INITIAL_CLUSTER_STATE=new

#export currentHostIp=`ip -4 address show eth0 | grep 'inet' |  grep -v grep | awk '{print $2}' | cut -d '/' -f1`

firewall-cmd --reload
firewall-cmd --list-all

#注意防火墙出现奇怪问题,集群可能还无法访问,只能本机访问,需要重现启动可以解决问题. to do

docker stop etcd3
docker rm   etcd3

docker run \
  -d \
  --restart=always \
  --hostname=etcd3 \
  -p 2379:2379 \
  -p 2380:2380 \
  -v /etc/localtime:/etc/localtime \
  -v `pwd`/data:/data \
  -v `pwd`/ssl:/etc/etcd/ssl \
  --name etcd3 \
  nexus.linkaixin.com:2443/k8s.gcr.io/etcd:3.3.10 \
   etcd \
  -name etcd3 \
  --cert-file=/etc/etcd/ssl/etcd3-server.crt \
  --key-file=/etc/etcd/ssl/etcd3-server.key \
  --peer-cert-file=/etc/etcd/ssl/etcd3-server.crt \
  --peer-key-file=/etc/etcd/ssl/etcd3-server.key \
  --trusted-ca-file=/etc/etcd/ssl/ca.pem \
  --peer-trusted-ca-file=/etc/etcd/ssl/ca.pem \
  --initial-advertise-peer-urls https://10.6.4.33:2380 \
  --listen-peer-urls https://0.0.0.0:2380 \
  --listen-client-urls https://0.0.0.0:2379 \
  --advertise-client-urls https://10.6.4.33:2379 \
  --initial-cluster-token etcd-cluster-of-ceph \
  --initial-cluster etcd1=https://10.6.4.31:2380,etcd2=https://10.6.4.32:2380,etcd3=https://10.6.4.33:2380 \
  --initial-cluster-state existing \
  --data-dir=/data

docker logs -f etcd3

检查ETCD状态
要检查您的etcd服务器是否正常运行,可以执行以下操作:
$ etcdctl --endpoints=https://node1.mydomain.com:2379 --ca-file=~/etcd-ca/ca.pem member list
6c86f26914e6ace, started, Node2, https://node3.mydomain.com:2380, https://node3.mydomain.com:2379
1ca80865c0583c45, started, Node1, https://node2.mydomain.com:2380, https://node2.mydomain.com:2379
99c7caa3f8dfeb70, started, Node0, https://node1.mydomain.com:2380, https://node1.mydomain.com:2379

[ceph@ceph1 ~]$ docker exec etcd1 etcdctl --endpoints=https://10.6.4.31:2379 --ca-file=/etc/etcd/ssl/ca.pem member list
2e26c284a608e734: name=etcd1 peerURLs=https://10.6.4.31:2380 clientURLs=https://10.6.4.31:2379 isLeader=true
86110446cab57f89: name=etcd2 peerURLs=https://10.6.4.32:2380 clientURLs=https://10.6.4.32:2379 isLeader=false
ebbc05ecb174c1c3: name=etcd3 peerURLs=https://10.6.4.33:2380 clientURLs=https://10.6.4.33:2379 isLeader=false

浏览器查看状态:
在这里插入图片描述

为pcocc配置etcd
启用身份验证之前,请在etcd中配置root用户:
etcdctl --endpoints=“https://node1.mydomain.com:2379” --ca-file=~/etcd-ca/ca.pem user add root

docker exec etcd1
/ # etcdctl --endpoints=https://10.6.4.31:2379 --ca-file=/etc/etcd/ssl/ca.pem user add root
New password:
User root created
/ # etcdctl --endpoints=https://10.6.4.31:2379 --ca-file=/etc/etcd/ssl/ca.pem user add etcd
New password:
User etcd created

docker exec etcd1 etcdctl --endpoints=https://10.6.4.31:2379 --ca-file=/etc/etcd/ssl/ca.pem user add root

警告
选择一个安全密码。 您必须在pcocc配置文件中引用它。
启用身份验证:
etcdctl --endpoints=“https://node1.mydomain.com:2379” --ca-file=~/etcd-ca/ca.pem auth enable
etcdctl --endpoints=https://10.6.4.31:2379 --ca-file=/etc/etcd/ssl/ca.pem auth enable

删除Guest角色:
$ etcdctl --endpoints=“https://node1.mydomain.com:2379” --ca-file=~/etcd-ca/ca.pem -u root: role remove guest
Role guest removed

etcdctl --endpoints=https://10.6.4.31:2379 --ca-file=/etc/etcd/ssl/ca.pem -u root:kaixin.com role remove guest

未经身份验证,您将不再能够访问密钥库:
$ etcdctl --endpoints “https://node1.mydomain.com:2379” --ca-file=~/etcd-ca/ca.pem get /
Error: 110: The request requires user authentication (Insufficient credentials) [0]

测试集群状态:
在这里插入图片描述

#在ceph1 上操作 添加一个key=test value=test123
etcdctl --endpoints=https://10.6.4.31:2379 --ca-file=/etc/etcd/ssl/ca.pem -u root:kaixin.com set test test123
test123
/ # etcdctl --endpoints=https://10.6.4.31:2379 --ca-file=/etc/etcd/ssl/ca.pem -u root:kaixin.com get test

测试集群是非正常
[ceph@ceph2 secure-etcd]$ docker exec -ti etcd2 sh
/ # etcdctl --endpoints=https://10.6.4.31:2379 --ca-file=/etc/etcd/ssl/ca.pem -u root:kaixin.com get test
test123
/ # etcdctl --endpoints=https://10.6.4.31:2379 --ca-file=/etc/etcd/ssl/ca.pem get test
Error: 110: The request requires user authentication (Insufficient credentials) [0]

错误:
etcdmain: member has already been bootstrapped
解决办法:
修改启动shell脚本
–initial-cluster-state new 为
–initial-cluster-state existing

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

开心自由天使

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值