Kubernetes 系統提供了三種認證方式:CA 認證、Token 認證 和 Base 認證。安全功能是一把雙刃劍,它保護系統不被攻擊,但是也帶來額外的性能損耗。集群內的各組件訪問 API Server 時,由於它們與 API Server 同時處於同一局域網內,所以建議用非安全的方式訪問 API Server 效率更高。
接下來對集群的雙向認證配置和簡單認證配置過程進行詳細說明。
雙向認證配置
雙向認證方式是最為嚴格和安全的集群安全配置方式,主要配置流程如下:
- 生成根證書、API Server 服務端證書、服務端私鑰、各個組件所用的客戶端證書和客戶端私鑰。
- 修改 Kubernetes 各個服務進程的啟動參數,啟用雙向認證模式。
詳細的配置操作流程如下:
生成根證書
用 openssl 工具生成 CA 證書,請注意將其中 subject 等參數改為用戶所需的數據,CN 的值通常是域名、主機名或 IP 地址。
$ cd /var/run/kubernetes $ openssl genrsa -out dd_ca.key 2048 $ openssl req -x509 -new -nodes -key dd_ca.key -subj "/CN=YOUDOMAIN.COM" -days 5000 -out dd_ca.crt
生成 API Server 服務端證書和私鑰
$ openssl genrsa -out dd_server.key 2048 $ HN=`hostname` $ openssl req -new -key dd_server.key -subj "/CN=$HN" -out dd_server.csr $ openssl x509 -req -in dd_server.csr -CA dd_ca.crt -CAkey dd_ca.key -CAcreateserial-out dd_server.crt -days 5000
生成 Controller Manager 與 Scheduler 進程共用的證書和私鑰
$ openssl genrsa -out dd_cs_client.key 2048 $ openssl req -new -key dd_cs_client.key -subj "/CN=$HN" -out dd_cs_client.csr $ openssl x509 -req -in dd_cs_client.csr -CA dd_ca.crt -CAkey dd_ca.key -CAcreateserial -out dd_cs_client.crt -days 5000
生成 Kubelet 所用的客戶端證書和私鑰
注意,這里假設 Kubelet 所在機器的 IP 地址為 192.168.1.129。
$ openssl genrsa -out dd_kubelet_client.key 2048 $ openssl req -new -key dd_kubelet_client.key -subj "/CN=192.168.1.129" -out dd_kubelet_client.csr $ openssl x509 -req -in dd_kubelet_client.csr -CA dd_ca.crt -CAkey dd_ca.key -CAcreateserial -out dd_kubelet_client.crt -days 5000
修改 API Server 的啟動參數
增加 CA 根證書、Server 自身證書等參數並設置安全端口為 443.
修改/etc/kubernetes/apiserver 配置文件的 KUBE_API_ARGS 參數:
KUBE_API_ARGS="--log-dir=/var/log/kubernetes --secure-port=443 --client_ca_file=/var/run/kubernetes/dd_ca.crt --tls-private-key-file=/var/run/kubernetes/dd_server.key --tls-cert-file=/var/run/kubernetes/dd_server.crt"
重啟 kube-apiserver 服務:
# systemctl restart kube-apiserver
驗證 API Server 的 HTTPS 服務。
$ curl https://kubernetes-master:443/api/v1/nodes --cert /var/run/kubernetes/dd_cs_client.crt --key /var/run/kubernetes/dd_cs_client.key --cacert /var/run/kubernetes/dd_ca.crt
修改 Controller Manager 的啟動參數
修改/etc/kubernetes/controller-manager 配置文件
KUBE_CONTROLLER_MANAGER_ARGS="--log-dir=/var/log/kubernetes --service_account_private_key_file=/var/run/kubernetes/server.key --root-ca-file=/var/run/kubernetes/ca.crt --master=https://kubernetes-master:443 --kubeconfig=/etc/kubernetes/cmkubeconfig"
創建/etc/kubernetes/cmkubeconfig 文件,配置證書等相關參數,具體內容如下:
apiVersion: v1
kind: Config
users
- name: controllermanager
user:
client-certificate: /var/run/kubernetes/dd_cs_client.crt client-key: /var/run/kubernetes/dd_cs_client.key clusters: - name: local cluster: certificate-authority: /var/run/kubernetes/dd_ca.crt contexts: - context: cluster: local user: controllermanager name: my-context current-context: my-context
重啟 kube-controller-manager 服務:
# systemctl restart kube-controller-manager
配置各個節點上的 Kubelet 進程
復制 Kubelet 的證書、私鑰 與 CA 根證書到所有 Node 上。
$ scp /var/run/kubernetes/dd_kubelet* root@kubernetes-minion1:/home $ scp /var/run/kubernetes/dd_ca.* root@kubernetes-minion:/home
在每個 Node 上創建/var/lib/kubelet/kubeconfig 文件,內容如下:
apiVersion: v1
kind: Config
users:
- name: kubelet
user:
client-certificats: /home/dd_kubelet_client.crt client-key: /home/dd_kubelet_client.key clusters: - name: local cluster: certificate-authority: /home/dd_ca.crt contexts: - context: cluster: local user: kubelet name: my-context current-context: my-context
修改 Kubelet 的啟動參數,以修改/etc/kubernetes/kubelet 配置文件為例:
KUBELET_API_SERVER="--api_servers=https://kubernetes-master:443" KUBELET_ARGS="--pod_infro_container_image=192.168.1.128:1180/google_containers/pause:latest --cluster_dns=10.2.0.100 --cluster_domain=cluster.local --kubeconfig=/var/lib/kubelet/kubeconfig"
重啟 kubelet 服務:
# systemctl restart kubelet
配置 kube-proxy
首先,創建/var/lib/kubeproxy/proxykubeconfig 文件,內容如下:
apiVersion: v1
kind: Config
users:
- name: kubeproxy
user:
client-certificate: /home/dd_kubelet_client.crt client-key: /home/dd_kubelet_client.key clusters: - name: local cluster: certificate-authority: /home/dd_ca.crt contexts: - context: cluster: local user: kubeproxy name: my-context current-context: my-context
然后,修改 kube-proxy 的啟動參數,引用上述文件並指明 API Server 在安全模式下的訪問地址,以修改配置文件/etc/kubenetes/proxy 為例:
KUBE_PROXY_ARGS="--kubeconfig=/var/lib/kubeproxy/proxykubeconfig --master=https://kubenetes-master:443"
重啟 kube-proxy 服務:
# systemctl restart kube-proxy
至此,一個雙向認證的 Kubernetes 集群環境就搭建完成了。
簡單認證配置
除了雙向認證方式,Kubernets 也提供了基於 Token 和 HTTP Base 的簡單認證方式。通信方式仍然采用 HTTPS,但不使用數字證書。
采用基於 Token 和 HTTP Base 的簡單認證方式時,API Server 對外暴露 HTTPS 端口,客戶端提供 Token 或用戶名、密碼來完成認證過程。這里需要說明的一點是 Kubelet 比較特殊,它同時支持雙向認證與簡單認證兩種模式,其他組件智能配置為雙向認證或非安全模式。
API Server 基於 Token 認證的配置過程如下
建立包括用戶名、密碼和 UID 的文件 token_auth_file:
$ cat /root/token_auth_file
dingmingk,dingmingk,1 admin,admin,2 system,system,3
修改 API Server 的配置,采用上述文件進行安全認證
$ vi /etc/kubernetes/apiserver KUBE_API_ARGS="--secure-port=443 --token_auth_file=/root/token_auth_file"
重啟 API Server 服務
# systemctl restart kube-apiserver
用 curl 驗證連接 API Server
$ curl https://kubenetes-master:443/version --header "Authorization: Bearer dingmingk" -k { "major": "1", "minor": "0", "gitVersion": "v1.0.0", "gitCommit": "xxxHASHCODE", "gitTreeState": "clean" }
API Server 基於 HTTP Base 認證的配置過程如下
創建包括用戶名、密碼和 UID 的文件 basic_auth_file:
$ cat /root/basic_auth_file
dingmingk,dingmingk,1 admin,admin,2 system,system,3
修改 API Server 的配置,采用上述文件進行安全認證
$ vi /etc/kubernetes/apiserver KUBE_API_ARGS="--secure-port=443 --basic_auth_file=/root/basic_auth_file"
重啟 API Server 服務
# systemctl restart kube-apiserver
用 curl 驗證連接 API Server
$ curl https://kubernetes-master:443/version --basic -u dingmingk:dingmingk -k { "major": "1", "minor": "0", "gitVersion": "v1.0.0", "gitCommit": "xxxHASHCODE", "gitTreeState": "clean" }
使用 Kubelet 時則需要指定用戶名和密碼來訪問 API Server
$ kubectl get nodes --server="https://kubernetes-master:443" --api-version="v1" --username="dingmingk" --password="dingmingk" --insecure-skip-tls-verify=true
kubectl config set-cluster
在kubeconfig配置文件中設置一個集群項。
摘要
在kubeconfig配置文件中設置一個集群項。 如果指定了一個已存在的名字,將合並新字段並覆蓋舊字段。
示例
選項
繼承自父命令的選項