創建加密的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服務器。

主機名 FQDN IP地址
etcd1 etcd1.linkaixin.com 10.6.4.31
etcd2 etcd2.linkaixin.com 10.6.4.32
etcd3 etcd3.linkaixin.com 10.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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章