通常我们使用 kubectl 命令来访问 k8s 集群,本质也是通过 API Server 来访问的 k8s 集群。如果不基于 kubectl,也可以直接通过调用 HTTP API 的方式访问 API Server。
在与 API Server 交互的时候,需要提前获得一个具有正确权限的 ServiceAccount。权限可以通过将 ServiceAccount 与具有目标权限的 ClusterRole 或 Role 通过 RoleBinding 或 ClusterRoleBinding 绑定后获得。
下面记录一个具有全局权限(类似 /etc/kubernetes/admin.conf)的 ServiceAccount 的创建过程。
创建一个 ServiceAccount:
# 在 kube-system 中创建,因为目标:访问 API Server
kubectl create sa -n kube-system api-explorer-service-account
通过创建 ClusterRole 或 Role,可以授予对所需资源的访问权限。这里设置 ClusterRole 资源,因为 API Server 的访问是一种更全局的行为。k8s 中默认提供了 cluster-admin ClusterRole,它具有全部的访问权限,参考它的设置生成 api-explorer-cluster-role ClusterRole。
或者干脆直接使用
cluster-admin,这里主要为了演示创建过程。
kubectl apply -f - <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: api-explorer-cluster-role
rules:
- apiGroups:
- '*'
resources:
- '*'
verbs:
- '*'
- nonResourceURLs:
- '*'
verbs:
- '*'
EOF
将 api-explorer-service-account ServiceAccount 和 api-explorer-cluster-role ClusterRole 进行绑定。通过 ClusterRoleBinding 或是 RoleBinding 都可以。下面使用 ClusterRoleBinding:
kubectl create clusterrolebinding system:api-explorer:cluster --clusterrole api-explorer-cluster-role --serviceaccount kube-system:api-explorer-service-account
注意,在 k8s 1.22 以后,ServiceAccount 关联的 Secret 不会自动创建出来,需手动创建,然后才可以从 Secret 中获取永久不过期的 token。如果只是获取临时性的访问,可以通过 kubectl create token 获取临时 token。下面演示通过手动创建 ServiceAccount 关联的 Secret。
ServiceAccount关联的Secret创建参考: https://kubernetes.io/docs/concepts/configuration/secret/#service-account-token-secrets
kubectl apply -f - <<EOF
apiVersion: v1
kind: Secret
metadata:
name: api-explorer-secret
namespace: kube-system
annotations:
kubernetes.io/service-account.name: "api-explorer-service-account"
type: kubernetes.io/service-account-token
EOF
准备工作做完,现在可以获取表示 api-explorer-service-account ServiceAccount 的 token 以备访问 API Server。获取 token:
# describe 输出中获取 token 字段
kubectl describe secrets -n kube-system api-explorer-secret
测试 token 是否有效:
export API_SERVER=${your_api_server}
# 设置 token,需要 base64 解码
export TOKEN=$(kubectl get -n kube-system secret api-explorer-secret -o jsonpath='{.data.token}' | base64 --decode)
# API_SERVER 是 HTTPS 路径,可以直接通过 --insecure/-k 直接访问
curl -k --header "Authorization: Bearer ${TOKEN}" ${API_SERVER}/api/v1/namespaces
# 或者从 Secret 中提取出 ca 证书,通过 --cacert 指定后,安全访问
kubectl get -n kube-system secret api-explorer-secret -o jsonpath='{.data.ca\.crt}' | base64 --decode > api-explorer-secret-ca.crt
curl --cacert api-explorer-secret-ca.crt --header "Authorization: Bearer ${TOKEN}" ${API_SERVER}/api/v1/namespaces
后续,即可通过这个 token 直接进行 API 调用了。
评论 / 共 0 条