Master apiserver啟用TLS認證後,Node節點kubelet元件想要加入叢集,必須使用CA簽發的有效證書才能與
apiserver通信,當Node節點很多時,簽署證書是一件很繁瑣的事情,是以有了TLS Bootstrapping機制,kubelet
會以一個低權限使用者自動向apiserver申請證書,kubelet的證書由apiserver動态簽署。
認證大緻工作流程如圖所示:

1、将kubelet-bootstrap使用者綁定到系統叢集角色
在主節點(192.168.1.13)上運作
[root@docker kubeconfig]# kubectl create clusterrolebinding kubelet-bootstrap \
--clusterrole=system:node-bootstrapper \
--user=kubelet-bootstrap
傳回結果:
clusterrolebinding.rbac.authorization.k8s.io/kubelet-bootstrap created
2、拷貝檔案:(将前面下載下傳的二進制包中的kubelet和kube-proxy拷貝到/opt/kubernetes/bin目錄下)
[root@docker bin]# pwd
/data/tools/k8s/kubernetes/server/bin
[root@docker bin]# scp kubelet kube-proxy 192.168.1.23:/opt/kubernetes/bin/
[root@docker bin]# scp kubelet kube-proxy 192.168.1.24:/opt/kubernetes/bin/
執行腳本,生成 kube-proxy.kubeconfig bootstrap.kubeconfig 2個檔案
cat /data/k8s/kubeconfig/kubeconfig.sh
[root@docker kubeconfig]# cat kubeconfig.sh
#-----------------start-----------------------------------------------------------------------------------------
#已經建立 cat /opt/kubernetes/cfg/token.csv 就不需要再建立了
#建立 TLS Bootstrapping Token
#BOOTSTRAP_TOKEN=$(head -c 16 /dev/urandom | od -An -t x | tr -d ' ')
#BOOTSTRAP_TOKEN=0fb61c46f8991b718eb38d27b605b008
#cat > token.csv << EOF
#${BOOTSTRAP_TOKEN},kubelet-bootstrap,10001,"system:kubelet-bootstrap"
#EOF
BOOTSTRAP_TOKEN=674c457d4dcf2eefe4920d7dbb6b0ddcc
APISERVER=$1
SSL_DIR=$2
#建立kubelet bootstrapping kubeconfig
export KUBE_APISERVER="https://$APISERVER:6443"
#設定叢集參數
kubectl config set-cluster kubernetes \
--certificate-authority=$SSL_DIR/ca.pem \
--embed-certs=true \
--server=${KUBE_APISERVER} \
--kubeconfig=bootstrap.kubeconfig
#設定用戶端認證參數
kubectl config set-credentials kubelet-bootstrap \
--token=${BOOTSTRAP_TOKEN} \
#設定上下文參數
kubectl config set-context default \
--cluster=kubernetes \
--user=kubelet-bootstrap \
#設定預設上下文
kubectl config use-context default --kubeconfig=bootstrap.kubeconfig
#建立kube-proxy kubeconfig檔案
--kubeconfig=kube-proxy.kubeconfig
kubectl config set-credentials kube-proxy \
--client-certificate=$SSL_DIR/kube-proxy.pem \
--client-key=$SSL_DIR/kube-proxy-key.pem \
--user=kube-proxy \
kubectl config use-context default --kubeconfig=kube-proxy.kubeconfig
#-----------------end-----------------------------------------------------------------------------------------
參數1:本地ip,參數2:ca.pem目錄
[root@docker kubeconfig]# bash kubeconfig.sh 192.168.1.13 /data/k8s/master-ca
3、拷貝檔案
[root@docker kubeconfig]# scp bootstrap.kubeconfig kube-proxy.kubeconfig 192.168.1.23:/opt/kubernetes/cfg/
[root@docker kubeconfig]# scp bootstrap.kubeconfig kube-proxy.kubeconfig 192.168.1.24:/opt/kubernetes/cfg/
1、建立kubelet配置檔案
[root@docker cfg]# cd /opt/kubernetes/cfg
[root@docker cfg]# cat kubelet.sh
#--------------------start-------------------------------------------------------------
#!/bin/bash
NODE_ADDRESS=$1
DNS_SERVER_IP=${2:-"10.0.0.2"}
cat <<EOF >/opt/kubernetes/cfg/kubelet
KUBELET_OPTS="--logtostderr=true \
--v=4 \
--hostname-override=${NODE_ADDRESS} \
--kubeconfig=/opt/kubernetes/cfg/kubelet.kubeconfig \
--bootstrap-kubeconfig=/opt/kubernetes/cfg/bootstrap.kubeconfig \
--config=/opt/kubernetes/cfg/kubelet.config \
--cert-dir=/opt/kubernetes/ssl \
--pod-infra-container-image=registry.cn-hangzhou.aliyuncs.com/google-containers/pause-amd64:3.0"
EOF
cat <<EOF >/opt/kubernetes/cfg/kubelet.config
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
address: ${NODE_ADDRESS}
port: 10250
readOnlyPort: 10255
cgroupDriver: cgroupfs
clusterDNS:
${DNS_SERVER_IP}
clusterDomain: cluster.local.
failSwapOn: false
authentication:
anonymous:
enabled: true
cat << EOF > /usr/lib/systemd/system/kubelet.service
[Unit]
Description=Kubernetes Kubelet
After=docker.service
Requires=docker.service
[Service]
EnvironmentFile=/opt/kubernetes/cfg/kubelet
ExecStart=/opt/kubernetes/bin/kubelet \$KUBELET_OPTS
Restart=on-failure
KillMode=process
[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable kubelet
systemctl restart kubelet
#--------------------end-------------------------------------------------------------
執行腳本(生成kubelet、kubelet.config配置檔案):
bash kubelet.sh 192.168.1.23
參數說明:
--hostname-override 在叢集中顯示的主機名
--kubeconfig 指定kubeconfig檔案位置,會自動生成
--bootstrap-kubeconfig 指定剛才生成的bootstrap.kubeconfig檔案
--cert-dir 頒發證書存放位置
--pod-infra-container-image 管理Pod網絡的鏡像
systemd管理kubelet元件:
[root@docker cfg]# cat /usr/lib/systemd/system/kubelet.service
ExecStart=/opt/kubernetes/bin/kubelet $KUBELET_OPTS
啟動:
錯誤日志:/var/log/message
很大一個原因是:在master主機上生成的配置檔案(bootstrap.kubeconfig kube-proxy.kubeconfig)有問題,需要在看看
啟動後還沒加入到叢集中,需要手動允許該節點才可以。 在Master節點檢視請求簽名的Node:
主節點上:
檢視未授權的CSR請求:
通過CSR請求:
[root@docker kubeconfig]# kubectl certificate approve node-csr-SgU-ybOM3oSGMi_9WJ10D3LXtCp9JNolSrRRchdw7So
certificatesigningrequest.certificates.k8s.io/node-csr-SgU-ybOM3oSGMi_9WJ10D3LXtCp9JNolSrRRchdw7So approved
驗證:
[root@docker kubeconfig]# kubectl get csr
NAME AGE REQUESTOR CONDITION
node-csr-SgU-ybOM3oSGMi_9WJ10D3LXtCp9JNolSrRRchdw7So 9m48s kubelet-bootstrap Approved,Issued
檢視node節點
[root@docker kubeconfig]# kubectl get node
NAME STATUS ROLES AGE VERSION
192.168.1.23 NotReady <none> 8s v1.12.3
NAME STATUS ROLES AGE VERSION
192.168.1.23 Ready <none> 11s v1.12.3
執行腳本(包含建立kube-proxy、啟動項kube-proxy.service):
[root@docker cfg]# cd /opt/kubernetes/cfg
[root@docker cfg]# cat proxy.sh
#-----------------------------start----------------------------------------------------------------
cat <<EOF >/opt/kubernetes/cfg/kube-proxy
KUBE_PROXY_OPTS="--logtostderr=true \
--cluster-cidr=10.0.0.0/24 \
--proxy-mode=ipvs \
--kubeconfig=/opt/kubernetes/cfg/kube-proxy.kubeconfig"
cat <<EOF >/usr/lib/systemd/system/kube-proxy.service
Description=Kubernetes Proxy
After=network.target
EnvironmentFile=-/opt/kubernetes/cfg/kube-proxy
ExecStart=/opt/kubernetes/bin/kube-proxy \$KUBE_PROXY_OPTS
systemctl enable kube-proxy
systemctl restart kube-proxy
#-----------------------------end----------------------------------------------------------------
執行腳本:sh proxy.sh 192.168.1.23
檢視是否啟動:
1、拷貝node1(192.168.1.23)上的整個kubernetes 包
scp -r kubernetes/ 192.168.1.24:/opt/
2、scp -r /usr/lib/systemd/system/{kubelet,kube-proxy}.service 192.168.1.24:/usr/lib/systemd/system/
3、到node2上修改IP
cd /opt/kubernetes/cfg
修改kubelet、kubelet.config、kube-proxy為:192.168.1.24
4、啟動:
systemctl start kubelet
systemctl start kube-proxy
5、驗證
6、加入叢集
部署前所有節點關閉firewalld(systemctl stop firewalld),并同步網際網路時間。
1、自簽ETCD證書
2、ETCD部署
3、Node安裝Docker
4、Flannel部署(先寫入子網到etcd)
5、自簽APIServer證書
6、部署APIServer元件(token.csv)
7、部署controller-manager(指定apiserver證書)和scheduler元件
8、生成kubeconfig(bootstrap.kubeconfig和kube-proxy.kubeconfig)
9、部署kubelet元件(kubectl create clusterrolebinding kubelet-bootstrap ...)
10、部署kube-proxy元件
11、kubectl get csr && kubectl certificate approve 允許頒發證書,加入叢集
12、增加一個Node(删除第一台Node已生成的ssl/*證書,修改kubelet,kubele.config,kube-proxy裡Node IP)