ServiceAccount在k8s1.24版本中的变化
创建之后查看Pod挂载的卷,如下所示,可以看到Pod定义了一个卷kube-api-access-xxx,并且也挂载到容器内/var/run/secrets/kubernetes.io/serviceaccount目录下的文件和之前的版本是一致的,但卷的数据来源并不是Secret,其中token是由kubelet到tokenRequest api去申请的token,且token的有效期为1小时;再查
在k8s1.24之前的版本中,创建ServiceAccout时会自动为其创建一个对应的Secret,里边包含了集群的CA证书、ServiceAccount所在名称空间和访问API Server的token,创建Pod的时候这个Secret会作为存储卷被自动挂载到Pod中,用于Pod中的应用访问API Server时使用
但从1.24版本起不会自动创建这个Secret,如下,在1.24版本的环境中测试
创建一个ServiceAccount sa1
root@k8s-master01:~# kubectl create sa sa1
serviceaccount/sa1 created
root@k8s-master01:~# kubectl get sa
NAME SECRETS AGE
default 0 46h
my-sa 0 46h
sa1 0 4s
查询Secret资源,如下图,没有为sa1自动生成对应的Secret
root@k8s-master01:~# kubectl get secret
NAME TYPE DATA AGE
aliyun-image-registry kubernetes.io/dockerconfigjson 1 44d
harbor-secret kubernetes.io/dockerconfigjson 1 53d
k8s-cert kubernetes.io/tls 2 53d
mysql-root-password Opaque 1 26d
nginx-cert kubernetes.io/tls 2 45d
secret-basic-auth kubernetes.io/basic-auth 2 53d
secret-for-my-sa kubernetes.io/service-account-token 3 46h
root@k8s-master01:~#
现在我们手动创建一个Secret,和sa1绑定,yaml文件如下:
apiVersion: v1
kind: Secret
metadata:
name: secret-for-sa1
annotations:
kubernetes.io/service-account.name: sa1 #指定Secret所属的SecviceAccount
type: kubernetes.io/service-account-token #指定类型
创建之后,查看Secret内容,k8s会自动为其自动添加token数据
root@k8s-master01:~/resources-yaml# kubectl apply -f secret-for-sa1.yaml
secret/secret-for-sa1 created
root@k8s-master01:~/resources-yaml# kubectl get secret
NAME TYPE DATA AGE
secret-for-sa1 kubernetes.io/service-account-token 3 9s
root@k8s-master01:~/resources-yaml# kubectl describe secret/secret-for-sa1
Name: secret-for-sa1
Namespace: default
Labels: <none>
Annotations: kubernetes.io/service-account.name: sa1
kubernetes.io/service-account.uid: 2bfc1ddd-8d33-439c-a0eb-282a01191a4d
Type: kubernetes.io/service-account-token
Data
====
ca.crt: 1302 bytes
namespace: 7 bytes
token: eyJhbGciOiJSUzI1NiIsImtpZCI6ImFRd0lqbGF0V2hsODRZZlF3UWdrQmFBckpDc0o0T2Z2OUc1c0hrY0hHNjQifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6InNlY3JldC1mb3Itc2ExIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6InNhMSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjJiZmMxZGRkLThkMzMtNDM5Yy1hMGViLTI4MmEwMTE5MWE0ZCIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0OnNhMSJ9.rSsUz2V0MIPt31Xt1UPCJlRVe32JI4X8SGbvigWqT-7VkWK-13JGJ3nLM5gO0tIECBMz1Rtoh7FMAI-qZlCq9PAtU1mfUIBVXtKbi-MZ8P5xUMeQWkxH4dqR0UA0nVDuXoeYYSBU_19iy8VzNaiSW_5iDU_DCSNhygw5Huj-zK2_pg2cdm9ZXwYQKZSZpEQGnmfPjIzlJCLsy6-3KjlpvYMlsAs9xCSSBQ03PiEu27lwW78k6R0NWvJ0NT7sRt5H2q_-yl6jn_x2r8FVGQNNzDxd6kxvvaJDaAFoLxX6O9TTKiMzNUZ2RH9gcWN4YhkqF23PjyrdVIeW6njANVyk2g
root@k8s-master01:~/resources-yaml#
注意:这里只添加了token,集群的CA和名称空间数据没有被添加,这和之前版本中Service Account对应Secret中的内容是不一样的
创建一个Pod引用sa1
apiVersion: v1
kind: Pod
metadata:
name: testpod
spec:
serviceAccountName: sa1
containers:
- name: ubuntu
image: harbor-server.linux.io/base-images/ubuntu:20.04
imagePullPolicy: IfNotPresent
command:
- /bin/sh
- -c
- "sleep 3600"
创建之后查看Pod挂载的卷,如下所示,可以看到Pod定义了一个卷kube-api-access-xxx,并且也挂载到容器内/var/run/secrets/kubernetes.io/serviceaccount 目录下的文件和之前的版本是一致的,但卷的数据来源并不是Secret,其中token是由kubelet到tokenRequest api去申请的token,且token的有效期为1小时;ca.crt来自configmap,这个kube-root-ca.crt在每个名称空间都存在,创建新namespace时k8s会自动在namespace下添加;namespace是通过downwardAPI插件获取Pod自身的字段值
root@k8s-master01:~# kubectl get pods/testpod -o yaml #查看Pod的卷定义和卷挂载信息
......
volumeMounts:
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: kube-api-access-652fr
readOnly: true
.......
volumes:
- name: kube-api-access-652fr
projected:
defaultMode: 420
sources:
- serviceAccountToken:
expirationSeconds: 3607
path: token
- configMap:
items:
- key: ca.crt
path: ca.crt
name: kube-root-ca.crt
- downwardAPI:
items:
- fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
path: namespace
root@k8s-master01:~# kubectl exec pods/testpod -- ls /var/run/secrets/kubernetes.io/serviceaccount #查看Pod的容器内挂载点下的文件
ca.crt
namespace
token
我们再对比一下Pod中的token和secret-for-sa1中的token是否是同一个
root@k8s-master01:~# kubectl exec pods/testpod -- cat /var/run/secrets/kubernetes.io/serviceaccount/token
eyJhbGciOiJSUzI1NiIsImtpZCI6ImFRd0lqbGF0V2hsODRZZlF3UWdrQmFBckpDc0o0T2Z2OUc1c0hrY0hHNjQifQ.eyJhdWQiOlsiYXBpIiwiaXN0aW8tY2EiXSwiZXhwIjoxNjk3MzU4Mjk3LCJpYXQiOjE2NjU4MjIyOTcsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2YyIsImt1YmVybmV0ZXMuaW8iOnsibmFtZXNwYWNlIjoiZGVmYXVsdCIsInBvZCI6eyJuYW1lIjoidGVzdHBvZCIsInVpZCI6IjdhNzQ1ZGQ4LWIzZjEtNDQzNy1hNzM5LTQwNmVkMjEzOGYwZSJ9LCJzZXJ2aWNlYWNjb3VudCI6eyJuYW1lIjoic2ExIiwidWlkIjoiMmJmYzFkZGQtOGQzMy00MzljLWEwZWItMjgyYTAxMTkxYTRkIn0sIndhcm5hZnRlciI6MTY2NTgyNTkwNH0sIm5iZiI6MTY2NTgyMjI5Nywic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50OmRlZmF1bHQ6c2ExIn0.EdGMk4YYYxlnJFr1X-XfKUQ8pFFPe1MpNIkSKQYhlTAeHR-qN5mnsnc9xf9lvsl12qLHTk2cBY0hRk2M3LqBDHEUhGg22xYdmFEVX2qMbyz64Kuz9dAOIQHfDOp4VzIMHrsUPJpYF2yh9ZmZuE09VEAdt6QHYobQgUVp2m54Z5B-qDajVHkCovJCiDzUkfKYx38_HdPS8FAhx_o6jslfVD3QCxJ4azs6nFdiu1Rq5HEDYG53wuFRSWOCVe2MiNi38uwR1W_N_2Fdr5JebiJucGOIBqYy5VtGR00Ni80I9yzf4-cewhuhUlR7nVniG-yDyLrLgXdxOfWccohdEX5GrA
root@k8s-master01:~#
root@k8s-master01:~# kubectl get secret/secret-for-sa1 -o jsonpath={.data.token} |base64 -d
eyJhbGciOiJSUzI1NiIsImtpZCI6ImFRd0lqbGF0V2hsODRZZlF3UWdrQmFBckpDc0o0T2Z2OUc1c0hrY0hHNjQifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6InNlY3JldC1mb3Itc2ExIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6InNhMSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjJiZmMxZGRkLThkMzMtNDM5Yy1hMGViLTI4MmEwMTE5MWE0ZCIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0OnNhMSJ9.rSsUz2V0MIPt31Xt1UPCJlRVe32JI4X8SGbvigWqT-7VkWK-13JGJ3nLM5gO0tIECBMz1Rtoh7FMAI-qZlCq9PAtU1mfUIBVXtKbi-MZ8P5xUMeQWkxH4dqR0UA0nVDuXoeYYSBU_19iy8VzNaiSW_5iDU_DCSNhygw5Huj-zK2_pg2cdm9ZXwYQKZSZpEQGnmfPjIzlJCLsy6-3KjlpvYMlsAs9xCSSBQ03PiEu27lwW78k6R0NWvJ0NT7sRt5H2q_-yl6jn_x2r8FVGQNNzDxd6kxvvaJDaAFoLxX6O9TTKiMzNUZ2RH9gcWN4YhkqF23PjyrdVIeW6njANVyk2g
root@k8s-master01:~#
如上所示,两个token值是不一致的。将两个token在线解析(jwt.io)一下,查看有什么区别。
先查看Pod内的token,如下图所示,有效期为1年,但这个token在Pod内会1小时更新一次
再查看secre-for-sa1中的token,如下图,它没有过期时间,是永不过期的
综上所述:
- 1.24版本后创建ServiceAccount不再自动创建对应的Secret
- 可以手动创建Secret绑定到ServiceAccount,k8s会为其自动添加永久有效的token
- Pod中的应用使用ServiceAccount访问API Server的方式不变,依然可以通过/var/run/secrets/kubernetes.io/serviceaccount目录下的token文件、ca.crt文件和namespace文件访问API Server。但需要注意,token文件中的token每个小时会更新一次
更多推荐
所有评论(0)