使用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)

[root@k8s-master1 ~]# 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

整个证书如下:

[root@k8s-master1 ~]# 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节点执行

[root@k8s-master1 ~]# 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证书集群部署完成。

猜你喜欢

转载自www.cnblogs.com/harlanzhang/p/10116118.html