kubernetes 提供了多種安全認證機制, 其中對於集羣通信間可採用 TLS(https) 雙向認證機制,也可採用基於 Token 或用戶名密碼的單向 tls 認證。k8s通常在內網部署,採用私有 IP 地址進行通信,權威CA只能簽署域名證書,咱們這裏採用自建CA。node
環境:git
Master:172.20.103.1vim
Node:172.20.103.2api
基於CA簽名的雙向數字證書的生成過程以下:安全
爲kube-apiserver生成一個數字證書,並用CA證書籤名。服務器
爲kube-apiserver進程配置證書相關的啓動參數,包括CA證書(用於驗證客戶端證書的簽名真僞)、本身的通過CA簽名後的證書及私鑰。ide
爲每一個訪問K8S API Server 的客戶端(kube-controller-manager、kube-scheduler、kubelet、kube-proxy及調用API Server的客戶端程序kubectl等)進程均可以生成本身的數字證書,也都用CA證書籤名,在相關程序的啓動參數裏增長CA證書、本身的證書等相關參數。工具
設置kube-apiserver的CA證書相關的文件和啓動參數ui
使用OpenSSL工具在Master服務器上建立CA證書和私鑰相關的文件:spa
yum -y install openssl
cd /var/run/kubernetes/ (證書默認存放目錄)
openssl genrsa -out ca.key 2048
openssl req -x509 -new -nodes -key ca.key -subj "/CN=k8s-master" -days 5000 -out ca.crt
openssl genrsa -out server.key 2048
注意:在生成ca.crt時,-subj參數中「」/CN「」的值爲Master主機名。
準備master_ssl.cnf文件,該文件用於x509 v3版本的證書。在該文件中主要須要設置Master服務器的hostname(k8s-master)、IP地址(172.20.103.1)、以及K8S Master Service 的虛擬服務名稱(kubernetes.default 等)和該虛擬服務的ClusterIP地址(169.169.0.1)。
master_ssl.cnf 文件的配置以下:
[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
[req_distinguished_name]
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = kubernetes
DNS.2 = kubernetes.default
DNS.3 = kubernetes.default.svc
DNS.4 = kubernetes.default.svc.cluster.local
DNS.5 = k8s-master
IP.1 = 169.169.0.1
IP.2 = 172.20.103.1
基於master_ssl.cnf 建立server.csr 和 server.crt 文件。在生成server.csr 時,-subj參數中「」/CN「」的值需爲Master的主機名:
openssl req -new -key server.key -subj "/CN=k8s-master" -config master_ssl.cnf -out server.csr
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -days 5000 -extensions v3_req -extfile master_ssl.cnf -out server.crt
在所有執行完後會生成6個文件:ca.crt ca.key ca.srl master_ssl.cnf server.crt server.csr server.key
而後設置kube-apiserver的三個啓動參數"--client-ca-file","--tls-private-key-file","--tls-cert-file",分別表明CA根證書文件、服務端私鑰文件、服務端證書文件:
--client-ca-file=/var/run/kubernetes/ca.crt
--tls-private-key-file=/var/run/kubernetes/server.key
--tls-cert-file=/var/run/kubernetes/server.crt
同時,能夠關閉非安全端口(設置--insecure-port=0),設置安全端口爲6443(默認值):
--insecure-port=0 --secure-port=6443
最後重啓kube-apiserver服務
systemctl restart kube-apiserver
設置kube-controller-manager的客戶端證書、私鑰和啓動參數
openssl genrsa -out cs_client.key 2048
openssl req -new -key cs_client.key -subj "/CN=k8s-master" -out cs_client.csr
openssl x509 -req -in cs_client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out cs_client.crt -days 5000
其中,在生成cs_client.crt時,-CA參數和-CAkey參數使用的是API Server的ca.crt和ca.key文件。
接下來建立/etc/kubernetes/kubeconfig 文件(kube-controller-manager與kube-scheduler共用),配置客戶端證書等相關參數,內容以下:
vim /etc/kubernetes/kubeconfig
apiVersion: v1
kind: Config
users:
- name: controllermanager
user:
client-certificate: /var/run/kubernetes/cs_client.crt
client-key: /var/run/kubernetes/cs_client.key
clusters:
- name: local
cluster:
certificate-authority: /var/run/kubernetes/ca.crt
server: https://172.20.103.1:6443
contexts:
- context:
cluster: local
user: controllermanager
name: my-context
current-context: my-context
設置kube-controller-manager服務的啓動參數:
--kubeconfig=/etc/kubernetes/kubeconfig
重啓kube-controller-manager服務
systemctl restart kube-controller-manager
設置kube-scheduler服務的啓動參數:
--kubeconfig=/etc/kubernetes/kubeconfig
重啓kube-scheduler服務
systemctl restart kube-scheduler
設置每一個Node上kubelet的客戶端證書、私鑰和啓動參數
複製kube-apiserver的ca.crt和ca.key文件到node上,在生成kubelet_client.crt時-CA參數和- CAkey參數使用的是API Server的ca.crt和ca.key文件;生成kubelet_client.csr時,將-subj參數中的「」/CN「」設置爲本機Node的IP地址。
在node上建立存放證書的目錄:
mkdir /etc/kubernetes/ssl_keys
把master上的ca.crt和ca.key文件複製到node上:
scp ca.crt ca.key root@172.20.103.2:/etc/kubernetes/ssl_keys/
openssl genrsa -out kubelet_client.key 2048
openssl req -new -key kubelet_client.key -subj "/CN=172.20.103.2" -out kubelet_client.csr
openssl x509 -req -in kubelet_client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out kubelet_client.crt -days 5000
接下來建立/etc/kubernetes/kubeconfig文件(kubelet和kube-proxy組件共用),配置客戶端證書等相關參數,內容以下:
apiVersion: v1
kind: Config
users:
- name: kubelet
user:
client-certificate: /etc/kubernetes/ssl_keys/kubelet_client.crt
client-key: /etc/kubernetes/ssl_keys/kubelet_client.key
clusters:
- name: local
cluster:
certificate-authority: /etc/kubernetes/ssl_keys/ca.crt
server: https://172.20.103.2:6443
contexts:
- context:
cluster: local
user: kubelet
name: my-context
current-context: my-context
設置kubelet服務的啓動參數:
--kubeconfig=/etc/kubernetes/kubeconfig
重啓kubelet服務
systemctl restart kubelet
設置kube-proxy服務的啓動參數:
--kubeconfig=/etc/kubernetes/kubeconfig
重啓kube-proxy服務:
systemctl restart kube-proxy
至此,一個基於CA的雙向數字證書認證的K8S集羣環境就搭建完成了。
設置kubectl客戶端使用安全方式訪問API Server
在使用kubectl對K8S集羣進行操做時,默認使用非安全端口8080對API Server進行訪問,也能夠設置爲安全訪問API Server的模式,須要設置3個證書相關的參數:
「」--certificate-authority「」,「」--client-certificate「」,「」--client-key「」,分別表示用於CA受權的證書,客戶端證書和客戶端祕鑰。
--certificate-authority:使用爲kube-apiserver生成的ca.crt文件。
--client-certificate:使用爲kube-controller-manager生成的cs_client.crt文件。
--client-key:使用爲kube-controller-manager生成的cs_client.key文件
同時,指定API Server的URL地址爲HTTPS安全地址(例如:https://k8s-master:443),最後輸入須要執行的子命令,便可對API Server進行安全訪問了:
kubectl --server=https://172.20.103.1:6443 --certificate-authority=/var/run/kubernetes/ca.crt --client-certificate=/var/run/kubernetes/cs_client.crt --client-key=/var/run/kubernetes/cs_client.key get nodes