云原生学习路线导航页(持续更新中)
- kubernetes学习系列快捷链接
- Kubernetes架构原则和对象设计(一)
- Kubernetes架构原则和对象设计(二)
- Kubernetes架构原则和对象设计(三)
- Kubernetes控制平面组件:etcd(一)
- Kubernetes控制平面组件:etcd(二)
- Kubernetes控制平面组件:etcd常用配置参数
- Kubernetes控制平面组件:etcd高可用集群搭建
- Kubernetes控制平面组件:etcd高可用解决方案
- Kubernetes控制平面组件:Kubernetes如何使用etcd
- kubectl 和 kubeconfig 基本原理
- kubeadm 升级 k8s集群 1.17到1.20
- Kubernetes常见问题解答
- 查看云机器的一些常用配置
本文主要对kubernetes API Server 认证机制中的 Token>静态Token认证进行介绍,包括 Token>静态Token的设计理念、认证流程,并给出 Kubernetes 中的认证实操演练
Token_22">1.Token>静态Token的认证方式简介
Token_31">2.实操演练:Token>静态Token的认证
Token__32">2.1.创建 Token 文件
- 文件格式(CSV):
token,username,uid,"group1,group2,..." # 比如 31ada4fd.ade128006b1723da,devuser,1000,"developers,qa"
- 创建文件
/etc/kubernetes/pki/tokens.csv
:sudo mkdir -p /etc/kubernetes/pki echo "31ada4fd.ade128006b1723da,devuser,1000,\"developers,qa\"" | sudo tee /etc/kubernetes/pki/tokens.csv
2.2.配置 API Server
- 找到 kube-apiserver 静态pod配置:
- 如果是kubeadm启动的kubernetes集群,那么api-server会以静态pod的方式启动
- 静态pod默认路径 /etc/kubernetes/manifests,可以在这里找到 kube-apiserver 的pod配置
- 修改 kube-apiserver 静态pod配置:
# 文件路径:/etc/kubernetes/manifests/kube-apiserver.yaml spec: containers: - command: - kube-apiserver - --token-auth-file=/etc/kubernetes/pki/tokens.csv # 添加此参数 # 其他参数不用改
- 因为我们把token文件放在了 /etc/kubernetes/pki 目录下,该目录默认已经被挂载到 api-server的容器中了,所以我们可以直接在参数中写这个目录,容器可以拿到该文件
- 因为我们把token文件放在了 /etc/kubernetes/pki 目录下,该目录默认已经被挂载到 api-server的容器中了,所以我们可以直接在参数中写这个目录,容器可以拿到该文件
2.3.重启 API Server
- 修改了/etc/kubernetes/manifests/kube-apiserver.yaml,kubelet会自动重启api-server
kubernetescurl_66">2.4.验证使用token访问kubernetes集群:直接curl
- 获取不到pod,因为该token只是通过了认证,但是没有授权,属于正常现象
curl https://<API_SERVER_IP>:6443/api/v1/pods \ --header "Authorization: Bearer 31ada4fd.ade128006b1723da" \ --insecure # 示例 [root@VM-226-235-tencentos ~]# curl https://xxx.xxx.xxx.xxx:6443/api/v1/pods \ > --header "Authorization: Bearer 31ada4fd.ade128006b1723da" \ > --insecure { "kind": "Status", "apiVersion": "v1", "metadata": { }, "status": "Failure", "message": "pods is forbidden: User \"devuser\" cannot list resource \"pods\" in API group \"\" at the cluster scope", "reason": "Forbidden", "details": { "kind": "pods" }, "code": 403 }
- 或者也可以通过
kubectl get pods -v 9
看看正常的get pod curl请求是什么样,加一个header参数即可- 从响应最后的json看,apiserver已经知道我是devuser了,但是没有权限访问pod
# 获取真实的curl请求 [root@VM-226-235-tencentos ~]# kubectl get pods -v 9 ....... I0218 22:36:48.698775 29701 round_trippers.go:424] curl -k -v -XGET -H "Accept: application/json;as=Table;v=v1;g=meta.k8s.io,application/json;as=Table;v=v1beta1;g=meta.k8s.io,application/json" -H "User-Agent: kubectl/v1.19.16 (linux/amd64) kubernetes/e37e4ab" 'https://xxx.xxx.xxx.xxx:6443/api/v1/namespaces/default/pods?limit=500' # 添加一个header后,发送请求 [root@VM-226-235-tencentos ~]# curl -k -v -XGET -H "Authorization: Bearer 31ada4fd.ade128006b1723da" -H "Accept: application/json;as=Table;v=v1;g=meta.k8s.io,application/json;as=Table;v=v1beta1;g=meta.k8s.io,application/json" -H "User-Agent: kubectl/v1.19.16 (linux/amd64) kubernetes/e37e4ab" 'https://xxx.xxx.xxx.xxx:6443/api/v1/namespaces/default/pods?limit=500' * About to connect() to xxx.xxx.xxx.xxx port 6443 (#0) * Trying xxx.xxx.xxx.xxx... * Connected to xxx.xxx.xxx.xxx (xxx.xxx.xxx.xxx) port 6443 (#0) * Initializing NSS with certpath: sql:/etc/pki/nssdb * skipping SSL peer certificate verification * NSS: client certificate not found (nickname not specified) * SSL connection using TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 * Server certificate: * subject: CN=kube-apiserver * start date: Apr 17 08:00:10 2024 GMT * expire date: Apr 21 07:13:02 2025 GMT * common name: kube-apiserver * issuer: CN=kubernetes > GET /api/v1/namespaces/default/pods?limit=500 HTTP/1.1 > Host: xxx.xxx.xxx.xxx:6443 > Accept: application/json;as=Table;v=v1;g=meta.k8s.io,application/json;as=Table;v=v1beta1;g=meta.k8s.io,application/json > User-Agent: kubectl/v1.19.16 (linux/amd64) kubernetes/e37e4ab > Authorization: Bearer 31ada4fd.ade128006b1723da > < HTTP/1.1 403 Forbidden < Cache-Control: no-cache, private < Content-Type: application/json < X-Content-Type-Options: nosniff < Date: Tue, 18 Feb 2025 14:38:17 GMT < Content-Length: 252 < {"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"pods is forbidden: User \"devuser\" cannot list resource \"pods\" in API group \"\" in the namespace \"default\"","reason":"Forbidden","details":{"kind":"pods"},"code":403} * Connection #0 to host xxx.xxx.xxx.xxx left intact
kuberneteskubectl_132">2.5.验证使用token访问kubernetes集群:配置kubectl
# 基于静态token生成一个user
kubectl config set-credentials devuser --token=31ada4fd.ade128006b1723da
# 为user创建一个context
kubectl config set-context dev-context --cluster=<your-cluster> --user=devuser
# 切换上下文
kubectl config use-context dev-context
# 验证。若显示 "Forbidden",说明user没有权限,需配置 RBAC 授权
kubectl get pods
[root@VM-226-235-tencentos ~]# kubectl get pods
Error from server (Forbidden): pods is forbidden: User "devuser" cannot list resource "pods" in API group "" in the namespace "default"
-
上面的操作将会修改到kubeconfig中,可以查看 ~/.kube/config 的内容
...... contexts: - context: cluster: kubernetes user: devuser name: dev-context - context: cluster: kubernetes user: kubernetes-admin name: kubernetes-admin@kubernetes - context: cluster: kubernetes user: myuser name: myuser@kubernetes current-context: dev-context kind: Config preferences: {} users: - name: devuser user: token: 31ada4fd.ade128006b1723da - name: ......
-
RBAC授权
- 注意需要先切换回原来的上下文,我们新建的dev-context没有Role权限的
apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: default name: pod-reader rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "list", "watch"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: namespace: default name: read-pods subjects: - kind: User name: devuser apiGroup: rbac.authorization.k8s.io roleRef: kind: Role name: pod-reader apiGroup: rbac.authorization.k8s.io
3.注意事项
- 生产环境建议使用更安全的认证方式(如 OIDC、X509 证书)
- Token 文件变更后需要重启 API Server
- 文件权限应设置为 600
- 结合 RBAC 进行细粒度权限控制
- 定期轮换 Token(需手动操作)
4.用途
- 比如有几个人要共享一个集群,可以每个人分配一个静态token,对授权做一些限制,就不怕别人访问或删除你的资源了