通常我们使用 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 条