TLS Bootstrapping
TLS Bootstrapping 的作用就是自动创建 kubelet 和 kube-proxy 的证书的。手动创建证书也行,但是集群规模大了手动创建比较麻烦,TLS Bootstrapping 的作用就是为了省点事。
官方文档:
https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/
Bootstrap启动过程:
1、kubelet 启动。
2、kubelet 未发现 kubeconfig文件。
3、kubelet 寻找 bootstrap-kubeconfig文件。
4、kubelet 读取 bootstrap-kubeconfig 内容,从中知道 apiserver地址 和 token。
5、kubelet 连接到 apiserver,使用token进行身份验证。
6、kubelet 现在具有向 apiserver发起证书签名请求(CSR)的权限了。
7、kubelet 为自己创建CSR请求。
8、批准CSR有以下两种方式:
(一)、配置controller-manager自动批准CSR,(controller-manager负责证书的签署)。
(二)、手动批准CSR(批准命令:kubectl certificate approve csr-msxdh)。
9、apiserver为kubelet创建证书。
10、apiserver给kubelet颁发证书。
11、kubelet 把证书拿回来(这个证书是一个文件中包含私钥和证书)。
12、kubelet 使用 证书和私钥创建kubeconfig(正式的配置文件)。
13、kubelet 开始其他工作。
14、可选:如果kubelet配置了自动更新证书,kubelet会在证书快到期时自动更新证书。
15、如果配置了CSR自动批准则自动批准,否则手动批准,同第8步。
要配置的几个组件:
kube-apiserver
kube-controller-manager
kubelet
集群内资源:ClusterRoleBinding 和 ClusterRole(1.8之前)。
Kubernetes证书颁发机构(这里指x509的CA)。
x509证书:
全局的ca证书,也就是master节点使用的那个自签证书,用来给其他证书签证的证书,ca.crt 和 ca.key。如果集群已近存在目前只是增加节点这个证书就不用创建了。
apiserver的配置
apiserver的工作主要有以下几点:
1、识别客户证书(kubelet将ca证书发给apiserver进行认证)
2、验证 kubelet。
3、授权kubelet创建CSR。
识别客户证书:
第一步只要在kubelet中将ca.crt配置好即可,在kubelet配置中会提到。
验证kubelet:
验证kubelet的方式有多种,推荐的有两种。
(一)、Bootstrap Tokens(Beta)
(二)、Token 认证文件
这里使用第二种认证方式,认证原理就是对比token是否相同,步骤如下。
生成token:
head -c 16 /dev/urandom | od -An -t x | tr -d ' '
token认证文件:
02b50b05283e98dd0fd71db496ef01e8,kubelet-bootstrap,10001,"system:bootstrappers"
授权kubelet创建CSR:enable bootstrapping nodes to create CSR
cat <<EOF | kubectl apply -f - apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: create-csrs-for-bootstrapping subjects: - kind: Group name: system:bootstrappers apiGroup: rbac.authorization.k8s.io roleRef: kind: ClusterRole name: system:node-bootstrapper apiGroup: rbac.authorization.k8s.io EOF
controller-manager的配置
controller-manager的功能:
1、查看证书
2、签署证书
因为controller-manager要签署证书,所以要将用于签证的秘钥和证书提供给controller-manager。
在kube-controller-manager.service中要添加的配置项:
--cluster-signing-cert-file="/etc/path/to/kubernetes/ca/ca.crt" --cluster-signing-key-file="/etc/path/to/kubernetes/ca/ca.key"
签证时间:如果要设置签证的时间则添加如下参数,默认为一年8760h0m0s。
--experimental-cluster-signing-duration=8760h0m0s
下面是设置controller-manager批准bootstrapping的CSR请求,和批准证书自动更新的CSR请求,主要设置一些权限绑定。低于1.8版本的要加上两个ClusterRoles,详见官方文档。
批准bootstrapping的CSR请求:Approve all CSRs for the group "system:bootstrappers"
cat <<EOF | kubectl apply -f - apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: auto-approve-csrs-for-group subjects: - kind: Group name: system:bootstrappers apiGroup: rbac.authorization.k8s.io roleRef: kind: ClusterRole name: system:certificates.k8s.io:certificatesigningrequests:nodeclient apiGroup: rbac.authorization.k8s.io EOF
批准自动更新的CSR请求:Approve renewal CSRs for the group "system:nodes"
cat <<EOF | kubectl apply -f - apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: auto-approve-renewals-for-nodes subjects: - kind: Group name: system:nodes apiGroup: rbac.authorization.k8s.io roleRef: kind: ClusterRole name: system:certificates.k8s.io:certificatesigningrequests:selfnodeclient apiGroup: rbac.authorization.k8s.io EOF
或者使用如下命令:
自动Approve CSR请求:
kubectl create clusterrolebinding auto-approve-csrs-for-group --group=system:bootstrappers --clusterrole=system:certificates.k8s.io:certificatesigningrequests:nodeclient
自动批准更新CSR请求:
kubectl create clusterrolebinding auto-approve-renewals-for-nodes --group=system:nodes --clusterrole=system:certificates.k8s.io:certificatesigningrequests:selfnodeclient
kubelet的配置
kubelet的相关功能配置:
1、设置签发过来的证书存储目录,不设置则使用默认目录。
2、设置生成的配置文件 kubeconfig 的文件路径。
3、设置 bootstrap-kubeconfig 文件的路径,文件中包含 apiserver 地址和 token。
4、配置证书轮询,包括客户端和服务端证书。
1、证书存储目录:
--cert-dir=/etc/kubernetes/cert/
2、kubeconfig:
--kubeconfig=/etc/kubernetes/kubeconfig
3、bootstrap-kubeconfig:
--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubeconfig
4、证书轮询:
现有证书快到期时创建CSR请求来轮询客户端证书。
--rotate-certificates=true
客户端证书轮询后再进行服务端的证书轮询:
--rotate-server-certificates=true
具体的配置过程如下:
使用命令创建bootstrap-kubeconfig文件:
kubectl config --kubeconfig=/etc/kubernetes/bootstrap-kubeconfig set-cluster bootstrap --server='https://192.168.1.133:6443' --certificate-authority=/etc/kubernetes/cert/ca.crt kubectl config --kubeconfig=/etc/kubernetes/bootstrap-kubeconfig set-credentials kubelet-bootstrap --token=5e9e293d3b14c995bd7c1415c5e0c6c0 kubectl config --kubeconfig=/etc/kubernetes/bootstrap-kubeconfig set-context bootstrap --user=kubelet-bootstrap --cluster=bootstrap kubectl config --kubeconfig=/etc/kubernetes/bootstrap-kubeconfig use-context bootstrap
安装并运行docker等:
wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
kubelet.service
[Unit] Description=Kubernetes kubelet Server After=docker.service Requires=docker.service [Service] WorkingDirectory=/var/lib/kubelet ExecStart=/usr/bin/kubelet \ --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubeconfig \ --kubeconfig=/etc/kubernetes/kubeconfig \ --cert-dir=/etc/kubernetes/cert/ \ --rotate-certificates=true \ --rotate-server-certificates=true Restart=on-failure [Install] WantedBy=multi-user.target
查看和批准CSR请求:
[root@k8s-01 kubernetes]# kubectl get csr NAME AGE REQUESTOR CONDITION csr-msxdh 64s system:node:k8s-05 Pending csr-nxh65 78s kubelet-bootstrap Approved,Issued [root@k8s-01 kubernetes]# kubectl certificate approve csr-msxdh certificatesigningrequest.certificates.k8s.io/csr-msxdh approved [root@k8s-01 kubernetes]# [root@k8s-01 kubernetes]# kubectl get csr NAME AGE REQUESTOR CONDITION csr-msxdh 2m31s system:node:k8s-05 Approved,Issued csr-nxh65 2m45s kubelet-bootstrap Approved,Issued
其他需要认证的组件:
如kube-proxy、监控、网络等其他组件也需要向apiserver获得身份验证,有两种方法,第一种是同kubelet。第二种是Daemonset方式。
操作示例
以下实验环境为二进制安装的k8s 1.14.2,如果是kubeadm安装的话实际操作有区别。
设置主机名:
hostnamectl set-hostname k8s-06
配置DNS:
cat >> /etc/hosts <<EOF 192.168.1.133 k8s-01 192.168.1.134 k8s-02 192.168.1.135 k8s-03 192.168.1.136 k8s-04 192.168.1.137 k8s-05 192.168.1.138 k8s-06 EOF
关闭swap:
swapoff -a
注释swap:
vim /etc/fstab
配置docker yum源:
wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
安装docker:
yum install docker-ce -y
启动docker:
systemctl start docker systemctl status docker
从其他节点拷贝或下载 kubelet kubectl和 kube-proxy:
scp /usr/bin/kubelet root@192.168.1.138:/usr/bin/ scp /usr/bin/kube-proxy root@192.168.1.138:/usr/bin/ scp /usr/bin/kubectl root@192.168.1.138:/usr/bin/
apiserver上的配置:在master节点上
生成token:
head -c 16 /dev/urandom | od -An -t x | tr -d ' '
设置token文件:这个token下面还要用
cat > /etc/kubernetes/token.csv <<EOF 5e9e293d3b14c995bd7c1415c5e0c6c0,kubelet-bootstrap,10001,"system:bootstrappers" EOF
打开kube-apiserver.service:
vim /usr/lib/systemd/system/kube-apiserver.service
添加如下选项:
--token-auth-file=/etc/kubernetes/token.csv
controller-manager的配置:
vim /usr/lib/systemd/system/kube-controller-manager.service
添加如下两个选项:
--cluster-signing-cert-file=/etc/kubernetes/cert/ca.crt \ --cluster-signing-key-file=/etc/kubernetes/cert/ca.key \
创建ClusterRoleBinding:
1、批准CSR
cat <<EOF | kubectl apply -f - apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: create-csrs-for-bootstrapping subjects: - kind: Group name: system:bootstrappers apiGroup: rbac.authorization.k8s.io roleRef: kind: ClusterRole name: system:node-bootstrapper apiGroup: rbac.authorization.k8s.io EOF
2、client rotate
cat <<EOF | kubectl apply -f - apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: auto-approve-csrs-for-group subjects: - kind: Group name: system:bootstrappers apiGroup: rbac.authorization.k8s.io roleRef: kind: ClusterRole name: system:certificates.k8s.io:certificatesigningrequests:nodeclient apiGroup: rbac.authorization.k8s.io EOF
3、server rotate
cat <<EOF | kubectl apply -f - apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: auto-approve-renewals-for-nodes subjects: - kind: Group name: system:nodes apiGroup: rbac.authorization.k8s.io roleRef: kind: ClusterRole name: system:certificates.k8s.io:certificatesigningrequests:selfnodeclient apiGroup: rbac.authorization.k8s.io EOF
kubelet的配置:在node节点上
创建目录:
mkdir /etc/kubernetes/cert -pv mkdir /var/lib/kubelet -pv
从主节点拷贝ca证书到node节点:
scp /etc/kubernetes/cert/ca.crt root@192.168.1.138:/etc/kubernetes/cert/
创建bootstrap-kubeconfig文件:
kubectl config --kubeconfig=/etc/kubernetes/bootstrap-kubeconfig set-cluster bootstrap --server='https://192.168.1.133:6443' --certificate-authority=/etc/kubernetes/cert/ca.crt kubectl config --kubeconfig=/etc/kubernetes/bootstrap-kubeconfig set-credentials kubelet-bootstrap --token=5e9e293d3b14c995bd7c1415c5e0c6c0 kubectl config --kubeconfig=/etc/kubernetes/bootstrap-kubeconfig set-context bootstrap --user=kubelet-bootstrap --cluster=bootstrap kubectl config --kubeconfig=/etc/kubernetes/bootstrap-kubeconfig use-context bootstrap
创建 kubelet.service文件:
cat > /usr/lib/systemd/system/kubelet.service <<EOF [Unit] Description=Kubernetes kubelet Server After=docker.service Requires=docker.service [Service] WorkingDirectory=/var/lib/kubelet ExecStart=/usr/bin/kubelet \\ --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubeconfig \\ --kubeconfig=/etc/kubernetes/kubeconfig \\ --cert-dir=/etc/kubernetes/cert/ \\ --rotate-certificates=true \\ --rotate-server-certificates=true Restart=on-failure [Install] WantedBy=multi-user.target EOF
启动kubelet:
systemctl start kubelet.service
查看状态:
systemctl status kubelet.service
查看日志:
tail -f /var/log/messages
到主节点查看CSR请求:
[root@k8s-01 ~]# kubectl get csr NAME AGE REQUESTOR CONDITION csr-dgftc 2m21s kubelet-bootstrap Approved,Issued csr-gvj2j 22s system:node:k8s-06 Pending
批准CSR请求:
[root@k8s-01 ~]# kubectl certificate approve csr-gvj2j certificatesigningrequest.certificates.k8s.io/csr-gvj2j approved [root@k8s-01 ~]# kubectl get csr NAME AGE REQUESTOR CONDITION csr-dgftc 6m5s kubelet-bootstrap Approved,Issued csr-gvj2j 4m6s system:node:k8s-06 Approved,Issued
查看签署过来的证书:
[root@k8s-06 ~]# ll /etc/kubernetes/cert/ total 12 -rw-r--r-- 1 root root 1086 Oct 26 05:13 ca.crt -rw------- 1 root root 1151 Oct 26 05:28 kubelet-client-2019-10-26-05-28-37.pem lrwxrwxrwx 1 root root 59 Oct 26 05:28 kubelet-client-current.pem -> /etc/kubernetes/cert/kubelet-client-2019-10-26-05-28-37.pem -rw------- 1 root root 1187 Oct 26 05:34 kubelet-server-2019-10-26-05-34-40.pem lrwxrwxrwx 1 root root 59 Oct 26 05:34 kubelet-server-current.pem -> /etc/kubernetes/cert/kubelet-server-2019-10-26-05-34-40.pem
查看生成的配置文件:
[root@k8s-06 ~]# cat /etc/kubernetes/kubeconfig apiVersion: v1 clusters: - cluster: certificate-authority: /etc/kubernetes/cert/ca.crt server: https://192.168.1.133:6443 name: default-cluster contexts: - context: cluster: default-cluster namespace: default user: default-auth name: default-context current-context: default-context kind: Config preferences: {} users: - name: default-auth user: client-certificate: /etc/kubernetes/cert/kubelet-client-current.pem client-key: /etc/kubernetes/cert/kubelet-client-current.pem
配置kube-proxy:只需要配置--kubeconfig选项即可。
cat < /usr/lib/systemd/system/kube-proxy.service <<EOF [Unit] Description=Kubernetes Kube-Proxy Server After=network.target Requires=network.service [Service] WorkingDirectory=/var/lib/kubelet ExecStart=/usr/bin/kube-proxy \\ --kubeconfig=/etc/kubernetes/kubeconfig Restart=on-failure LimitNOFILE=65536 [Install] WantedBy=multi-user.target EOF
启动kube-proxy:
systemctl start kube-proxy.service
查看状态:
systemctl status kube-proxy.service
查看新加进来的节点:
[root@k8s-01 ~]# kubectl get nodes NAME STATUS ROLES AGE VERSION k8s-02 Ready <none> 141d v1.14.2 k8s-03 Ready <none> 141d v1.14.2 k8s-06 Ready <none> 14m v1.14.2