搭建etcd叢集
前言
kubeadm安裝的叢集,預設etcd是一個單機的容器化的etcd,並且k8s和etcd通訊沒有經過ssl加密和認證,這點是需要改造的。
所以首先我們需要先部署一個三節點的etcd叢集,二進位制部署,systemd守護程式,並且需要生成ca證書。
ETCD叢集詳情
kuberntes 系統使用 etcd 儲存所有資料,此外calico網路也使用該etcd叢集,本文件介紹部署一個三節點高可用 etcd 叢集的步驟,分別命名為etcd-host1
、etcd-host2
、etcd-host3
:
- etcd-host1:172.16.120.151
- etcd-host2:172.16.120.152
- etcd-host3:172.16.120.153
本文件用到的變數定義如下:
$ export NODE_NAME=etcd-host1 # 當前部署的機器名稱(隨便定義,只要能區分不同機器即可)
$ export NODE_IP=172.16.120.151 # 當前部署的機器 IP
$ export NODE_IPS="172.16.120.151 172.16.120.152 172.16.120.153" # etcd 叢集所有機器 IP
$ # etcd 叢集間通訊的IP和埠
$ export ETCD_NODES=etcd-host1=https://172.16.120.151:2380,etcd-host2=https://172.16.120.152:2380,etcd-host3=https://172.16.120.153:2380
$
本系列預設使用root使用者操作。
建立 CA 證書和祕鑰
本文件使用 CloudFlare 的 PKI 工具集 cfssl 來生成 Certificate Authority (CA) 證書和祕鑰檔案,CA 是自簽名的證書,用來簽名後續建立的其它 TLS 證書。
安裝cfssl
如果不希望將cfssl工具安裝到部署主機上,可以在其他的主機上進行該步驟,生成以後將證書拷貝到部署etcd的主機上即可。本教程就是採取這種方法,在一臺測試機上執行下面操作。
$ wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
$ chmod +x cfssl_linux-amd64
$ mv cfssl_linux-amd64 /usr/local/bin/cfssl
$ wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
$ chmod +x cfssljson_linux-amd64
$ mv cfssljson_linux-amd64 /usr/local/bin/cfssljson
$ wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
$ chmod +x cfssl-certinfo_linux-amd64
$ mv cfssl-certinfo_linux-amd64 /usr/local/bin/cfssl-certinfo
$
生成ETCD的TLS 祕鑰和證書
為了保證通訊安全,客戶端(如 etcdctl) 與 etcd 叢集、etcd 叢集之間的通訊需要使用 TLS 加密,本節建立 etcd TLS 加密所需的證書和私鑰。
建立 CA 配置檔案:
$ cat > ca-config.json <<EOF
{
"signing": {
"default": {
"expiry": "8760h"
},
"profiles": {
"kubernetes": {
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
],
"expiry": "8760h"
}
}
}
}
EOF
-
ca-config.json
:可以定義多個 profiles,分別指定不同的過期時間、使用場景等引數;後續在簽名證書時使用某個 profile; -
signing
:表示該證書可用於簽名其它證書;生成的 ca.pem 證書中CA=TRUE
; -
server auth
:表示 client 可以用該 CA 對 server 提供的證書進行驗證; -
client auth
:表示 server 可以用該 CA 對 client 提供的證書進行驗證;
建立 CA 證書籤名請求:
$ cat > ca-csr.json <<EOF
{
"CN": "kubernetes",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "k8s",
"OU": "System"
}
]
}
EOF
- “CN”:
Common Name
,kube-apiserver 從證書中提取該欄位作為請求的使用者名稱 (User Name);瀏覽器使用該欄位驗證網站是否合法; - “O”:
Organization
,kube-apiserver 從證書中提取該欄位作為請求使用者所屬的組 (Group);
生成 CA 證書和私鑰:
$ cfssl gencert -initca ca-csr.json | cfssljson -bare ca
$ ls ca*
ca-config.json ca.csr ca-csr.json ca-key.pem ca.pem
$
建立 etcd 證書籤名請求:
$ cat > etcd-csr.json <<EOF
{
"CN": "etcd",
"hosts": [
"127.0.0.1",
"${NODE_IP}"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "k8s",
"OU": "System"
}
]
}
EOF
- hosts 欄位指定授權使用該證書的 etcd 節點 IP;
生成 etcd 證書和私鑰:
$ cfssl gencert -ca=ca.pem
-ca-key=ca-key.pem
-config=ca-config.json
-profile=kubernetes etcd-csr.json | cfssljson -bare etcd
$ ls etcd*
etcd.csr etcd-csr.json etcd-key.pem etcd.pem ca-config.json ca.csr ca-csr.json ca-key.pem ca.pem
$ rm etcd.csr etcd-csr.json
將生成好的etcd.pem和etcd-key.pem以及ca.pem三個檔案拷貝到目標主機的/etc/etcd/ssl目錄下。
下載二進位制檔案
到 https://github.com/coreos/etcd/releases
頁面下載最新版本的二進位制檔案:
$ wget https://github.com/coreos/etcd/releases/download/v3.2.11/etcd-v3.2.11-linux-amd64.tar.gz
$ tar -xvf etcd-v3.2.11-linux-amd64.tar.gz
$ mv etcd-v3.2.11-linux-amd64/etcd* /usr/local/bin
$
建立 etcd 的 systemd unit 檔案
$ mkdir -p /var/lib/etcd # 必須先建立工作目錄
$ cat > etcd.service <<EOF
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target
Documentation=https://github.com/coreos
[Service]
Type=notify
WorkingDirectory=/var/lib/etcd/
ExecStart=/usr/local/bin/etcd \
--name=${NODE_NAME} \
--cert-file=/etc/etcd/ssl/etcd.pem \
--key-file=/etc/etcd/ssl/etcd-key.pem \
--peer-cert-file=/etc/etcd/ssl/etcd.pem \
--peer-key-file=/etc/etcd/ssl/etcd-key.pem \
--trusted-ca-file=/etc/etcd/ssl/ca.pem \
--peer-trusted-ca-file=/etc/etcd/ssl/ca.pem \
--initial-advertise-peer-urls=https://${NODE_IP}:2380 \
--listen-peer-urls=https://${NODE_IP}:2380 \
--listen-client-urls=https://${NODE_IP}:2379,http://127.0.0.1:2379 \
--advertise-client-urls=https://${NODE_IP}:2379 \
--initial-cluster-token=etcd-cluster-0 \
--initial-cluster=${ETCD_NODES} \
--initial-cluster-state=new \
--data-dir=/var/lib/etcd
Restart=on-failure
RestartSec=5
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
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
列表中;
啟動 etcd 服務
$ mv etcd.service /etc/systemd/system/
$ systemctl daemon-reload
$ systemctl enable etcd
$ systemctl start etcd
$ systemctl status etcd
$
驗證服務
部署完 etcd 叢集后,在任一 etcd 叢集節點上執行如下命令:
$ etcdctl
--endpoints=https://172.16.120.151:2379
--ca-file=/etc/etcd/ssl/ca.pem
--cert-file=/etc/etcd/ssl/etcd.pem
--key-file=/etc/etcd/ssl/etcd-key.pem
cluster-health
預期結果:
member 71df888fdf6f0bb9 is healthy: got healthy result from https://172.16.120.153:2379
member 73b5207bc2491164 is healthy: got healthy result from https://172.16.120.151:2379
member 7a4ddb7c77253f4b is healthy: got healthy result from https://172.16.120.152:2379
三臺 etcd 的輸出均為 healthy 時表示叢集服務正常(忽略 warning 資訊)。