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/