K8S Api Server認證


認證類型

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認證的配置。

  1. 在master上創建/etc/kubernetes/basic_auth文件,文件中每行的格式如下:
password,user,uid,"group1,group2,group3"

示例如下:

1234,admin,1
  1. 在啟動apiserver的時候,啟動項添加如下參數即可:
--basic_auth_file=/etc/kubernetes/basic_auth
  1. 使用請求頭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"
    }
  ]
}
  1. 使用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認證方式為例:

  1. 配置admin用戶:
kubectl config set-credentials cluster-admin --username=admin --password=123456
  1. 配置apiserver的訪問方式,還需要給集群起個名字,就叫kubernetes:
kubectl config set-cluster kubernetes --insecure-skip-tls-verify=true --server=https://192.168.0.129

  1. 創建一個context,它連接用戶admin和集群kubernetes:
kubectl config set-context default --user=admin  --cluster=kubernetes

  1. 將剛剛創建的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的認證方式


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM