1. 程式人生 > >使用TLS證書搭建etcd叢集

使用TLS證書搭建etcd叢集

本文etcd叢集才用三臺centos7.5搭建完成。

vmnode1:192.168.20.210

vmnode2:192.168.20.211

vmnode3:192.168.20.212

一、建立CA證書和金鑰

kubernetes 系統各元件需要使用 TLS 證書對通訊進行加密,本文件使用 CloudFlare 的 PKI 工具集 cfssl 來生成 Certificate Authority (CA) 證書和祕鑰檔案,CA 是自簽名的證書,用來簽名後續建立的其它 TLS 證書。

以下操作都在 master 節點即 192.168.20.210 上執行,證書只需要建立一次即可,以後在向叢集中新增新節點時只要將 /etc/kubernetes/ 目錄下的證書拷貝到新節點上即可。

1、安裝 CFSSL

curl -o /usr/bin/cfssl https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
curl -o /usr/bin/cfssljson https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64

2、建立CA配置檔案

mkdir -p /etc/kubernetes/pki/etcd && cd /etc/kubernetes/pki/etcd 

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 提供的證書進行驗證;

3、建立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

4、建立 kubernetes 證書籤名請求檔案

cat > kubernetes-csr.json << EOF
{
   "CN": "kubernetes",
    "hosts": [
      "127.0.0.1",
      "192.168.20.210",
      "192.168.20.211",
      "192.168.20.212",
      "10.254.0.1",
      "kubernetes",
      "kubernetes.default",
      "kubernetes.default.svc",
      "kubernetes.default.svc.cluster",
      "kubernetes.default.svc.cluster.local"
    ],
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "ST": "BeiJing",
            "L": "BeiJing",
            "O": "k8s",
            "OU": "System"
        }
    ]
}
EOF

紅色粗體的ip替換成自己伺服器的ip
hosts 中的內容可以為空,即使按照上面的配置,向叢集中增加新節點後也不需要重新生成證書。
如果 hosts 欄位不為空則需要指定授權使用該證書的 IP 或域名列表,由於該證書後續被 etcd 叢集和 kubernetes master 叢集使用,所以上面分別指定了 etcd 叢集、kubernetes master 叢集的主機 IP 和 kubernetes 服務的服務 IP

生成 kubernetes 證書和私鑰

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kubernetes-csr.json | cfssljson -bare kubernetes

 

分發證書

將生成的證書和祕鑰檔案(字尾名為.pem)拷貝到所有機器的 /etc/kubernetes/pki/etcd目錄下

scp *.pem vmnode2:/etc/kubernetes/pki/etcd
scp *.pem vmnode3:/etc/kubernetes/pki/etcd

至此ETCD需要的證書生成完成!(如果不涉及kubernetes 叢集則下面生成證書的步驟跳過,直接看部署etcd)

[[email protected] ~]# ll /etc/kubernetes/pki/etcd
總用量 32
-rw------- 1 root root 1679 12月 13 19:30 ca-key.pem
-rw-r--r-- 1 root root 1359 12月 13 19:30 ca.pem
-rw------- 1 root root 1675 12月 13 19:30 kubernetes-key.pem
-rw-r--r-- 1 root root 1627 12月 13 19:30 kubernetes.pem

如果配置kubernetes master TLS叢集,則按如下步驟生成證書。

5、建立admin證書

cat > admin-csr.json << EOF
{
  "CN": "admin",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "BeiJing",
      "L": "BeiJing",
      "O": "system:masters",
      "OU": "System"
    }
  ]
}
EOF

kube-apiserver 使用 RBAC 對客戶端(如 kubelet、kube-proxy、Pod)請求進行授權;
kube-apiserver 預定義了一些 RBAC 使用的 RoleBindings,如 cluster-admin 將 Group system:masters 與 Role cluster-admin 繫結,該 Role 授予了呼叫kube-apiserver 的所有 API的許可權;
OU 指定該證書的 Group 為 system:masters,kubelet 使用該證書訪問 kube-apiserver 時 ,由於證書被 CA 簽名,所以認證通過,同時由於證書使用者組為經過預授權的 system:masters,所以被授予訪問所有 API 的許可權

生成 admin 證書和私鑰

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes admin-csr.json | cfssljson -bare admin

6、建立 kube-proxy 證書

cat > kube-proxy-csr.json << EOF
{
  "CN": "system:kube-proxy",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "BeiJing",
      "L": "BeiJing",
      "O": "k8s",
      "OU": "System"
    }
  ]
}
EOF

CN 指定該證書的 User 為 system:kube-proxy;
kube-apiserver 預定義的 RoleBinding cluster-admin 將User system:kube-proxy 與 Role system:node-proxier 繫結,該 Role 授予了呼叫 kube-apiserver Proxy 相關 API 的許可權;

生成 kube-proxy 客戶端證書和私鑰

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes  kube-proxy-csr.json | cfssljson -bare kube-proxy

整個證書如下:

[[email protected] ~]# ll /etc/kubernetes/pki/etcd
總用量 32
-rw------- 1 root root 1679 12月 13 19:30 admin-key.pem
-rw-r--r-- 1 root root 1399 12月 13 19:30 admin.pem
-rw------- 1 root root 1679 12月 13 19:30 ca-key.pem
-rw-r--r-- 1 root root 1359 12月 13 19:30 ca.pem
-rw------- 1 root root 1675 12月 13 19:30 kube-proxy-key.pem
-rw-r--r-- 1 root root 1403 12月 13 19:30 kube-proxy.pem
-rw------- 1 root root 1675 12月 13 19:30 kubernetes-key.pem
-rw-r--r-- 1 root root 1627 12月 13 19:30 kubernetes.pem

二、部署etcd叢集

在三個節點都安裝etcd,下面的操作需要再三個節點都執行一遍

1、下載etcd安裝包

wget https://github.com/etcd-io/etcd/releases/download/v3.3.10/etcd-v3.3.10-linux-amd64.tar.gz
tar zxf etcd-v3.3.10-linux-amd64.tar.gz
cp etcd-v3.3.10-linux-amd64/etcd* /usr/local/bin

2、建立工作目錄

mkdir -p /var/lib/etcd

3、建立systemd unit 檔案(紅色字填寫對應etcd主機的名稱和ip)

cat > /etc/systemd/system/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 vmnode1 \
  --cert-file=/etc/kubernetes/ssl/kubernetes.pem \
  --key-file=/etc/kubernetes/ssl/kubernetes-key.pem \
  --peer-cert-file=/etc/kubernetes/ssl/kubernetes.pem \
  --peer-key-file=/etc/kubernetes/ssl/kubernetes-key.pem \
  --trusted-ca-file=/etc/kubernetes/ssl/ca.pem \
  --peer-trusted-ca-file=/etc/kubernetes/ssl/ca.pem \
  --initial-advertise-peer-urls https://192.168.20.210:2380 \
  --listen-peer-urls https://192.168.20.210:2380 \
  --listen-client-urls https://192.168.20.210:2379 \
  --advertise-client-urls https://192.168.20.210:2379 \
  --initial-cluster-token etcd-cluster-0 \
  --initial-cluster vmnode1=https://192.168.20.210:2380,vmnode2=https://192.168.20.211:2380,vmnode3=https://192.168.20.212:2380 \
  --initial-cluster-state new \
  --data-dir=/var/lib/etcd
Restart=on-failure
RestartSec=5
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

為了保證通訊安全,需要指定 etcd 的公私鑰(cert-file和key-file)、Peers 通訊的公私鑰和 CA 證書(peer-cert-file、peer-key-file、peer-trusted-ca-file)、客戶端的CA證書(trusted-ca-file);
建立 kubernetes.pem 證書時使用的 kubernetes-csr.json 檔案的 hosts 欄位包含所有 etcd 節點的IP,否則證書校驗會出錯;
–initial-cluster-state 值為 new 時,–name 的引數值必須位於 –initial-cluster 列表中.

4、啟動etcd服務並且設定開機自啟動

sudo systemctl daemon-reload
sudo systemctl enable etcd
sudo systemctl start etcd

5、檢視etcd服務狀態資訊

systemctl status etcd

最先啟動的 etcd 程序會卡住一段時間,等待其它節點上的 etcd 程序加入叢集,為正常現象。

6、驗證etcd服務,在任何一個etcd節點執行

[[email protected] ~]# etcdctl --ca-file=/etc/kubernetes/pki/etcd/ca.pem --cert-file=/etc/kubernetes/pki/etcd/kubernetes.pem --key-file=/etc/kubernetes/pki/etcd/kubernetes-key.pem cluster-health
member 5970da41edcbb862 is healthy: got healthy result from https://192.168.20.210:2379
member 8fba95eda6aec582 is healthy: got healthy result from https://192.168.20.211:2379
member 9def704eef1953f1 is healthy: got healthy result from https://192.168.20.212:2379
cluster is healthy

至此ETCD TLS證書叢集部署完成。