認證類型
kubernetes 提供了三種級別的客戶端認證方式:
- HTTPS證書認證,是基於CA根證書簽名的雙向數字證書認證方式,是最嚴格的認證
- HTTP Token認證,通過Token識別每個合法的用戶
- HTTP Basic認證
HTTP Token認證和Http Basic認證是相對簡單的認證方式,Kubernetes的各組件與Api Server的通信方式仍然是HTTPS,但不再使用CA數字證書。
基於CA證書的雙向認證
apiserver端配置
使用kubeadm初始化 kubernetes集群中,kube-apiserver是以靜態pod的形式運行在master node上的。可以在master node上找琪定義文件/etc/kubernetes/manifests/kube-apiserver.json,其中啟動命令部分參數如下:
"command": [
"kube-apiserver",
"--insecure-bind-address=127.0.0.1",
"--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,ResourceQuota",
"--service-cluster-ip-range=10.96.0.0/12",
"--service-account-key-file=/etc/kubernetes/pki/apiserver-key.pem",
"--client-ca-file=/etc/kubernetes/pki/ca.pem",
"--tls-cert-file=/etc/kubernetes/pki/apiserver.pem",
"--tls-private-key-file=/etc/kubernetes/pki/apiserver-key.pem",
"--token-auth-file=/etc/kubernetes/pki/tokens.csv",
"--secure-port=6443",
"--allow-privileged",
"--advertise-address=192.168.61.100",
"--kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname",
"--anonymous-auth=false",
"--etcd-servers=http://127.0.0.1:2379"
],
我們注意到有如下三個啟動參數:
- --client-ca-file: 指定CA根證書文件為/etc/kubernetes/pki/ca.pem,內置CA公鑰用於驗證某證書是否是CA簽發的證書
- --tls-private-key-file: 指定ApiServer私鑰文件為/etc/kubernetes/pki/apiserver-key.pem
- --tls-cert-file:指定ApiServer證書文件為/etc/kubernetes/pki/apiserver.pem
說明Api Server已經啟動了HTTPS證書認證,此時如果在集群外部使用瀏覽器訪問https://:6443/api會提示Unauthorized。
生成客戶端私鑰和證書
客戶端要通過https證書雙向認證的形式訪問apiserver需要生成客戶端的私鑰和證書。在最新版本的kubernetes中,已經不再需要手動為客戶端生成證書。直接由Master端簽發即可。
客戶端啟動方式:
/usr/bin/kubelet --logtostderr=false --log-dir=/var/log/kubernetes --v=2 --address=0.0.0.0 --hostname-override=192.168.0.140 --allow-privileged=true --cgroup-driver=systemd --max-pods=30 --cluster_dns=10.254.0.10 --cluster_domain=cluster.local --pod-infra-container-image=dk-reg.op.douyuyuba.com/library/pause-amd64:3.0 --experimental-bootstrap-kubeconfig=/etc/kubernetes/bootstrap.kubeconfig --require-kubeconfig --kubeconfig=/etc/kubernetes/kubelet.kubeconfig --cert-dir=/etc/kubernetes/pki --hairpin-mode promiscuous-bridge --serialize-image-pulls=false --pod-manifest-path=/etc/kubernetes/manifests
master端允許其證書申請:
# 查看 csr
➜ kubectl get csr
NAME AGE REQUESTOR CONDITION
csr-l9d25 2m kubelet-bootstrap Pending
# 簽發證書
➜ kubectl certificate approve csr-l9d25
certificatesigningrequest "csr-l9d25" approved
# 查看 node
➜ kubectl get node
NAME STATUS AGE VERSION
docker4.node Ready 26s v1.6.7
master核心組件與apiserver的認證方式
/etc/kubernetes/manifests下的kube-controller-manager.json和kube-scheduler.json說明Controller Manager和Scheduler都是以靜態Pod的形式運行在Master Node上,注意到這兩個文件里的啟動參數--master=127.0.0.1:8080,說明它們直接通過insecure-port 8080和ApiServer通信。 而前面ApiServer的--insecure-bind-address=127.0.0.1,因此他們之間無需走secure-port。
HTTP Token認證
在上面master node的apiserver的啟動命令里面,除了證書的雙向認證,還同時啟動了token認證。
--token-auth-file=/etc/kubernetes/pki/token.csv 指定了靜態token文件,這個文件的格式如下:
token,user,uid,"group1,group2,group3"
生成token方式如下:
export BOOTSTRAP_TOKEN=$(head -c 16 /dev/urandom | od -An -t x | tr -d ' ')
cat > token.csv <<EOF
${BOOTSTRAP_TOKEN},kubelet-bootstrap,10001,"system:kubelet-bootstrap"
EOF
請求Api時只要在Authorization頭中加入Bearer Token即可:
curl -k --header "Authorization: Bearer fe0b40f90ac632c26d79c39673f3dd80" https://192.168.0.129:6443/api
{
"kind": "APIVersions",
"versions": [
"v1"
],
"serverAddressByClientCIDRs": [
{
"clientCIDR": "0.0.0.0/0",
"serverAddress": "192.168.0.129:6443"
}
]
}
kubectl使用Bearer訪問apiserver:
kubectl --server=https://192.168.0.129:6443 \
--token=fe0b40f90ac632c26d79c39673f3dd80 \
--insecure-skip-tls-verify=true \
cluster-info
HTTP Basic認證
kubeadm在初始化集群時並沒有開啟http basic認證,官方也不建議在實踐中使用。但是,在前面的兩種認證方式中,如果我們要在外部通過https的方式訪問dashboard,則無法辦到,除非對外開啟apiserver非安全認證的8080端口,這顯然不是我們想看到的。在這種情況 下,我們就可以開啟http basic認證,既可以通過https的方式 在外部打開dashboard,同時還能提供基本的安全認證。在這里也簡單的列一下http basic認證的配置。
- 在master上創建/etc/kubernetes/basic_auth文件,文件中每行的格式如下:
password,user,uid,"group1,group2,group3"
示例如下:
1234,admin,1
- 在啟動apiserver的時候,啟動項添加如下參數即可:
--basic_auth_file=/etc/kubernetes/basic_auth
- 使用請求頭Authorization Basic BASE64ENCODED(USER:PASSWORD)訪問方式如下:
echo admin:1234|base64
YWRtaW46MTIzNAo=
curl -k --header "Authorization:Basic YWRtaW46MTIzNAo=" https://192.168.0.129:6443/api
{
"kind": "APIVersions",
"versions": [
"v1"
],
"serverAddressByClientCIDRs": [
{
"clientCIDR": "0.0.0.0/0",
"serverAddress": "192.168.0.129:6443"
}
]
}
- 使用kubectl訪問如下:
kubectl --server=https://192.168.0.129:6443 \
--username=admin \
--password=1234 \
--insecure-skip-tls-verify=true \
cluster-info
kubectl config簡要說明
從上面各種認證訪問apiserver的過程中,不難看出,一旦使用了認證,kubectl的用法就會需要帶上需多參數,變的非常復雜。kubectl config提供了一個簡化的方法,就是將這些配置項都固化到配置文件中,而不用每次調用 都得作為參數手動帶上。
我們以http basic認證方式為例:
- 配置admin用戶:
kubectl config set-credentials cluster-admin --username=admin --password=123456
- 配置apiserver的訪問方式,還需要給集群起個名字,就叫kubernetes:
kubectl config set-cluster kubernetes --insecure-skip-tls-verify=true --server=https://192.168.0.129
- 創建一個context,它連接用戶admin和集群kubernetes:
kubectl config set-context default --user=admin --cluster=kubernetes
- 將剛剛創建的context設置為默認的context:
kubectl config use-context default
這時,會在/roo/.kube目錄下生成一個config的配置文件,內容如下:
apiVersion: v1
clusters:
- cluster:
insecure-skip-tls-verify: true
server: https://192.168.0.129
name: kubernetes
contexts:
- context:
cluster: kubernetes
namespace: default
user: admin
name: default
current-context: default
kind: Config
preferences: {}
users:
- name: admin
user:
password: 123456
username: admin
我們后面再執行kubectl的時候,會自動讀取該配置文件完成相關認證。
也可以在配置的過程中,指定Kubeconfig文件的路徑,如下:
export KUBE_APISERVER="https://192.168.0.129:6443"
# 設置集群參數,即api-server的訪問方式,給集群起個名字就叫kubernetes
kubectl config set-cluster kubernetes \
--certificate-authority=ca.pem \
--embed-certs=true \
--server=${KUBE_APISERVER} \
--kubeconfig=bootstrap.kubeconfig
# 設置客戶端認證參數,這里采用token認證
kubectl config set-credentials kubelet-bootstrap \
--token=${BOOTSTRAP_TOKEN} \
--kubeconfig=bootstrap.kubeconf
# 設置上下文參數,用於連接用戶kubelet-bootstrap與集群kubernetes
kubectl config set-context default \
--cluster=kubernetes \
--user=kubelet-bootstrap \
--kubeconfig=bootstrap.kubeconfig
# 設置默認上下文
kubectl config use-context default --kubeconfig=bootstrap.kubeconfig
參考:http://blog.frognew.com/2017/01/kubernetes-api-server-authc.html#master-node核心組件與apiserver的認證方式