kubeconfig文件详解

650 阅读7分钟

kubeconfig文件解析

以kubeadm生成的.kube/config文件为例

apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0.....rCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
    server: https://192.168.217.143:6443
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    namespace: default
    user: kubernetes-admin
  name: kubernetes-admin@kubernetes
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
users:
- name: kubernetes-admin
  user:
    client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS......tLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
    client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb3dJ......klWQVRFIEtFWS0tLS0tCg==

clusters

clusters代表远程服务

  • certificate-authority-data

服务端的ca证书,用来验证kube-apiserver证书的正确性。

当使用kubectl发送请求到kube-apiserver时,kube-apiserver会返回通过参数--tls-cert-file=/etc/kubernetes/pki/apiserver.crt配置的证书文件

kubectl通过kubeconfig的certificate-authority-data字段来校验kube-apiserver返回证书的有效性。

因为kube-apiserver指定的--client-ca-file=/etc/kubernetes/pki/ca.crt这个ca文件是签名--tls-cert-file=/etc/kubernetes/pki/apiserver.crt的ca文件,因此kubeconfig配置文件的这个字段的内容就和kube-apiserver指定的--client-ca-file=/etc/kubernetes/pki/ca.crt这个ca文件的base64编码内容一样,才能成功验证

当kubectl指定了参数--insecure-skip-tls-verify=true,即可跳过对kube-apiserver证书的校验。

contexts

kubeconfig所配置的所有上下文,其中一个context是一个集群的上下文,这里使用kubeadm创建一个集群,因此只有一个context

contexts:
- context:
    cluster: kubernetes     # 指定集群标识
    namespace: default      # 当前使用的命名空间
    user: kubernetes-admin  # 当前使用的集群的用户名
  name: kubernetes-admin@kubernetes     # 给此集群起的名字

current-context

当前正在使用哪个集群

users

users代表api-server的配置

users:
- name: kubernetes-admin    # 用户名称
  user:
    client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS......tLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
    client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb3dJ......klWQVRFIEtFWS0tLS0tCg==
  • client-certificate-data

kubectl连接kube-apiserver时使用的客户端证书,会发送给kube-apiserver。内容经过base64编码。

  • client-key-data

客户端私钥信息。内容经过 base64 编码。

client-certificate-data对应的为用户的公钥信息,使用命令 echo 'LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS...' | base64 -d > /tmp/client.crt; openssl x509 -in /tmp/client.crt -noout -text可对证书的内容进行解密。解密完成后的证书内容如下

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 7762911071323638964 (0x6bbb667d5d314cb4)
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN = kubernetes
        Validity
            Not Before: Dec 26 07:28:57 2023 GMT
            Not After : Dec 25 07:34:01 2024 GMT
        Subject: O = system:masters, CN = kubernetes-admin  # O对应k8s中的group,CN对应k8s中的user,
                                                            # kube-apiserver会通过证书的O和CN获取到User和Group信息
                                                            # k8s中实际没有存储group和user信息,完全依赖证书中的信息
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:ec:40:63:9e:ea:9a:65:eb:0c:0a:5f:fc:a9:ba:
                    44:98:97:5a:38:81:83:f9:7c:80:65:ef:83:05:c4:
                    d9:aa:19:36:da:d5:e6:3d:b1:d0:d2:d1:7e:74:58:
                    9b:9b:a7:b1:51:d4:b3:d8:47:40:c2:ee:74:fe:61:
                    a2:39:5f:c2:6a:fc:74:a1:fe:7c:37:c5:3a:2a:ab:
                    36:49:a5:6e:7a:35:5c:de:df:ed:01:b1:ec:4f:fd:
                    96:e0:f4:68:e2:a6:03:3a:d6:b9:ce:3c:b7:3c:69:
                    b3:c7:6d:d2:18:62:ad:f8:e3:33:2b:4f:d5:8e:fa:
                    9b:d6:38:45:dc:42:e5:51:83:63:c7:34:28:32:5a:
                    ed:2f:63:ed:5e:2e:91:71:76:45:84:12:42:1b:c3:
                    6a:2b:9f:fe:05:00:92:c6:38:00:d5:70:6f:3e:d2:
                    62:28:0b:c4:d7:82:e8:85:61:0a:35:02:fc:c8:8c:
                    ad:5d:88:8a:f7:24:9c:ac:92:06:fc:22:98:b9:84:
                    49:47:b1:cc:40:5a:b4:8a:47:2a:87:ff:6c:82:e1:
                    15:03:d5:32:7f:a7:83:06:04:09:86:db:71:6b:c7:
                    97:18:dc:b4:bb:f0:45:6f:40:60:d6:3a:0d:de:ae:
                    bc:b2:bd:20:12:be:59:ae:8b:8a:a0:a4:98:e9:3e:
                    c8:87
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            X509v3 Extended Key Usage:
                TLS Web Client Authentication
            X509v3 Basic Constraints: critical
                CA:FALSE
            X509v3 Authority Key Identifier:
                BA:F7:01:81:E4:E0:C3:79:D4:34:3D:DB:05:10:5F:A0:A3:E4:B7:4E
    Signature Algorithm: sha256WithRSAEncryption
    Signature Value:
        6c:d3:16:1f:73:43:52:18:06:d2:d1:02:5c:b8:c4:4b:5d:2a:
        cf:05:72:a5:9b:4a:75:ae:ee:6d:7a:4f:0c:77:03:45:8a:56:
        8f:9d:e8:68:27:c5:3b:f7:ed:bc:1e:5f:d4:ac:69:49:01:5f:
        bb:96:39:b0:4e:9e:c8:02:ba:9b:65:3c:08:3d:83:46:05:a6:
        21:70:e4:4e:c9:9f:c8:ef:84:0b:e9:ff:3e:0f:86:80:c2:c2:
        aa:6a:ba:0e:cc:4a:d2:a5:cc:c1:05:e2:37:2e:d4:8c:e8:72:
        38:00:4a:20:6e:79:34:79:d7:c7:dd:f6:63:1a:8a:f0:2a:75:
        9c:d1:4d:02:df:ee:d7:a5:5b:09:b7:8c:74:b3:98:37:3b:15:
        34:49:a3:9a:21:cf:e8:aa:70:cb:ef:9c:bf:1f:df:af:72:b4:
        74:7f:31:bf:9e:d5:07:dd:0e:1f:c7:74:99:85:f4:82:a4:d0:
        af:3c:ca:b4:9d:dc:48:7c:aa:96:9c:bf:ab:7f:02:8c:ad:22:
        e2:89:c4:fd:ec:4e:f7:74:c0:1d:ab:7e:a5:7f:96:37:aa:b9:
        7d:47:25:be:3f:dc:ad:c7:86:96:93:7c:d2:3c:f8:75:dc:9f:
        b3:4e:7f:dd:51:51:6b:40:ff:68:40:47:80:17:ad:07:08:76:
        90:24:cc:13

使用curl访问kube-apiserver

WORK_DIR=/tmp
KUBECONFIG=~/.kube/config
CONTEXT=kubernetes
USER_NAME=kubernetes-admin
​
# yq是一个yaml解析工具
server=`cat $KUBECONFIG | yq -P '.clusters.[]|select(.name=="'$CONTEXT'")|.cluster.server'` 
​
cat $KUBECONFIG | yq -P '.users.[]|select(.name=="'$USER_NAME'")|.user.client-certificate-data' | base64 --decode > ${WORK_DIR}/client.crt
​
cat $KUBECONFIG | yq -P '.users.[]|select(.name=="'$USER_NAME'")|.user.client-key-data' | base64 --decode > ${WORK_DIR}/client.key
​
cat $KUBECONFIG | yq -P '.clusters.[]|select(.name=="'$CONTEXT'")|.cluster.certificate-authority-data' | base64 --decode > ${WORK_DIR}/ca.crt
​
curl --cert ${WORK_DIR}/client.crt --key ${WORK_DIR}/client.key --cacert ${WORK_DIR}/ca.crt "$server/api/v1/namespaces/default/pods"

kubeconfig文件生成

kubeconfig文件本质上是个证书,包含了ca、证书公钥和证书私钥,在有了证书后可以通过kubectl命令生成新的kubeconfig文件

使用kubeconfig向kube-apiserver发送请求原理

API请求要么与普通用户相关,要么与ServiceAccount相关,其他的视为匿名请求

kubernetes使用证书中的 subject.CommonName 字段来确定用户名,接下来,通过RBAC确认用户对某资源是否存在要求的操作权限。

kubeconfig文件的两种配置方案

  • 第1种是像kubeadm生成的~/.kube/config这种设置私钥key和证书crt(Kind=User)
  • 第2种是设置token(Kind=ServiceAccount)

第1种配置方案,设置私钥key和证书crt

创建私钥key和证书crt后(注意其中的O和CN字段的设置),假定这里设置的CN为myuser

注意:k8s中不保存user这类资源,只保存ServiceAccount资源

为了让这个用户能访问k8s集群资源,需要创建Role和RoleBinding,比如

kubectl create role developer --verb=create --verb=get --verb=list --verb=update --verb=delete --resource=pods
kubectl create rolebinding developer-binding-myuser --role=developer --user=myuser  # 这里指定Kind为User

将这个用户添加到kubeconfig文件,这时myuser就可以通过RBAC鉴权了

kubectl config set-credentials myuser --client-key=myuser.key --client-certificate=myuser.crt --embed-certs=true

后续就是设置kubeconfig的上下文等操作了

参考链接https://kubernetes.io/zh-cn/docs/reference/access-authn-authz/certificate-signing-requests/#normal-user

第2种配置方案,设置token

这里的变量都是随便设置的,设置为aa也可以(已实验验证,主要起作用的是token)

CLUSTER_NAME=kubernetes
CONTEXT_NAME=kubernetes-admin@kubernetes
USER_NAME=kubernetes-admin
JWT_TOKEN=`kubectl create token kubernetes-dashboard -n kubernetes-dashboard`   # 申领一个token令牌,其中kubernetes-dashboard是一个ServiceAccount
​
kubectl --kubeconfig ~/.kube/test.kubeconfig config set-cluster ${CLUSTER_NAME} --certificate-authority=/etc/kubernetes/pki/ca.crt --embed-certs=true --server=https://192.168.217.143:6443
​
kubectl --kubeconfig ~/.kube/test.kubeconfig config set-context ${CONTEXT_NAME} --cluster=${CLUSTER_NAME} --user=${USER_NAME}
​
kubectl --kubeconfig ~/.kube/test.kubeconfig config use-context ${CONTEXT_NAME}
​
kubectl --kubeconfig ~/.kube/test.kubeconfig config set-credentials ${USER_NAME} --token=${JWT_TOKEN}
​
kubectl --kubeconfig ~/.kube/test.kubeconfig config view

此时创建的test.config内容如下

apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURCVEN....S0tRU5EIENFUlRJRklDQVRFLS0tLS0K
    server: https://192.168.217.143:6443
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    user: kubernetes-admin
  name: kubernetes-admin@kubernetes
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
users:
- name: kubernetes-admin
  user:
    token: eyJhbGciOiJSUzI1NiIsImtpZCI6I....Ni_z0gHbirD-NPw

和kubeadm创建的~/.kube/config文件类似了,只是users.user.token部分不同,这里文件里是配置的token,kubeadm配置的是证书和密钥

用这个kubeconfig配置文件可以用来以kubeconfig的方式来登录Dashboard,因为Dashboard中kubeconfig登录方式要求提供的就是token,而不是证书和密钥

参考链接

http://kuring.me/post/kubeconfig/