1. ServiceAccount 与 Kubernetes 访问控制基础在 Kubernetes 集群中ServiceAccount 是专门为运行在 Pod 中的进程提供身份认证的机制。与 UserAccount 不同ServiceAccount 是集群内部的账户主要用于自动化流程和系统组件间的通信。理解这一点很重要因为很多刚开始接触 Kubernetes 的开发者常常混淆这两种账户类型。ServiceAccount 的典型使用场景包括CI/CD 流水线中的自动化部署监控系统采集集群指标日志收集组件访问 API 服务器自定义控制器操作集群资源每个命名空间都会自动创建一个名为 default 的 ServiceAccountPod 如果没有指定 ServiceAccount就会使用这个默认账户。但实际生产环境中我们强烈建议为不同用途创建专门的 ServiceAccount并分配最小必要权限。2. 快速创建 ServiceAccount 与关联权限2.1 创建基础 ServiceAccount让我们从创建一个名为 cicd-agent 的 ServiceAccount 开始这个账户将用于 CI/CD 系统的集群操作kubectl create sa cicd-agent -n automation在 Kubernetes 1.24 及以上版本中Secret 不会自动创建需要手动补充。这是一个重要的变化很多人在新版本集群中会遇到这个问题cat EOF | kubectl apply -f - apiVersion: v1 kind: Secret metadata: name: cicd-agent namespace: automation annotations: kubernetes.io/service-account.name: cicd-agent type: kubernetes.io/service-account-token EOF2.2 权限绑定实战技巧权限绑定是安全管控的关键环节。Kubernetes 提供了两种主要方式ClusterRoleBinding适用于集群范围的权限RoleBinding适用于特定命名空间的权限假设我们的 CI/CD 系统需要部署应用到 dev 和 staging 命名空间同时需要读取集群节点信息但不应该有任何修改节点的权限。这种场景下我们可以这样配置# 创建 ClusterRole 用于节点只读访问 kubectl create clusterrole node-viewer --verbget,list,watch --resourcenodes # 创建 Role 用于应用部署 kubectl create role deploy-manager -n dev --verb* --resourcedeployments,services,pods kubectl create role deploy-manager -n staging --verb* --resourcedeployments,services,pods # 绑定权限 kubectl create clusterrolebinding cicd-node-viewer --clusterrolenode-viewer --serviceaccountautomation:cicd-agent kubectl create rolebinding cicd-dev-deployer -n dev --roledeploy-manager --serviceaccountautomation:cicd-agent kubectl create rolebinding cicd-staging-deployer -n staging --roledeploy-manager --serviceaccountautomation:cicd-agent这种精细化的权限分配遵循了最小权限原则即使凭证泄露也能将风险控制在有限范围内。3. 生成 kubeconfig 文件的进阶方法3.1 自动化脚本解析原始文章提供了一个基础脚本我们可以对其进行增强增加错误处理和更多实用功能#!/bin/bash set -eo pipefail # 颜色定义 RED\033[0;31m GREEN\033[0;32m NC\033[0m # 参数检查 if [ $# -lt 3 ]; then echo -e ${RED}错误缺少参数${NC} echo 用法: $0 serviceaccount-name namespace output-file [context-name] echo 示例: $0 cicd-agent automation ~/.kube/cicd-config my-cicd-context exit 1 fi SERVICE_ACCOUNT_NAME$1 NAMESPACE$2 OUTPUT_FILE$3 CONTEXT_NAME${4:-${SERVICE_ACCOUNT_NAME}-context} # 验证 ServiceAccount 是否存在 if ! kubectl get sa ${SERVICE_ACCOUNT_NAME} -n ${NAMESPACE} /dev/null; then echo -e ${RED}错误ServiceAccount ${SERVICE_ACCOUNT_NAME} 在命名空间 ${NAMESPACE} 中不存在${NC} exit 1 fi # 获取集群信息 CURRENT_CONTEXT$(kubectl config current-context) CLUSTER_NAME$(kubectl config get-contexts $CURRENT_CONTEXT --no-headers | awk {print $3}) SERVER$(kubectl config view --minify -o jsonpath{.clusters[0].cluster.server}) # 获取 Secret 名称兼容 1.24 版本 SECRET_NAME$(kubectl get sa ${SERVICE_ACCOUNT_NAME} -n ${NAMESPACE} -o jsonpath{.secrets[0].name}) if [ -z $SECRET_NAME ]; then SECRET_NAME${SERVICE_ACCOUNT_NAME} echo -e ${RED}警告未找到自动创建的 Secret尝试使用 ServiceAccount 名称作为 Secret 名称${NC} fi # 获取 Token 和 CA 证书 TOKEN$(kubectl get secret $SECRET_NAME -n $NAMESPACE -o jsonpath{.data.token} | base64 --decode) CA_DATA$(kubectl get secret $SECRET_NAME -n $NAMESPACE -o jsonpath{.data.ca\.crt}) # 生成 kubeconfig cat EOF $OUTPUT_FILE apiVersion: v1 kind: Config clusters: - name: ${CLUSTER_NAME} cluster: certificate-authority-data: ${CA_DATA} server: ${SERVER} contexts: - name: ${CONTEXT_NAME} context: cluster: ${CLUSTER_NAME} user: ${SERVICE_ACCOUNT_NAME} namespace: ${NAMESPACE} current-context: ${CONTEXT_NAME} users: - name: ${SERVICE_ACCOUNT_NAME} user: token: ${TOKEN} EOF echo -e ${GREEN}成功kubeconfig 已生成到 ${OUTPUT_FILE}${NC} echo 使用命令测试kubectl --kubeconfig${OUTPUT_FILE} get pods这个增强版脚本具有以下改进更好的错误处理和用户反馈支持自定义上下文名称更完善的参数验证颜色化输出提升可读性自动检测 Secret 存在情况3.2 多集群配置管理在实际工作中我们经常需要管理多个集群的访问凭证。kubeconfig 文件支持配置多个集群、用户和上下文。我们可以扩展上面的脚本来支持多集群配置的合并# 合并现有配置与新配置 if [ -f $OUTPUT_FILE ]; then echo 检测到现有 kubeconfig 文件将合并配置... KUBECONFIG${OUTPUT_FILE}:${HOME}/.kube/config kubectl config view --flatten /tmp/kubeconfig-tmp mv /tmp/kubeconfig-tmp ${OUTPUT_FILE} echo 配置合并完成 fi4. 权限吊销的深度实践4.1 临时权限吊销临时吊销权限而不影响 ServiceAccount 本身是常见的运维需求。除了删除 ClusterRoleBinding/RoleBinding 外还有更精细的控制方式修改 Role/ClusterRole 定义kubectl edit clusterrole node-viewer然后调整 verbs 字段比如从get,list,watch改为get,list使用权限拒绝规则Deny RulesapiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: access-denier rules: - apiGroups: [] resources: [secrets] verbs: [*] resourceNames: [database-credentials]然后创建 RoleBinding 将特定用户/ServiceAccount 绑定到这个拒绝角色。4.2 永久权限吊销的注意事项当需要永久吊销访问权限时除了删除 ServiceAccount 外还需要考虑清理所有关联的 RoleBinding/ClusterRoleBinding检查并清理 Pod 中使用该 ServiceAccount 的情况如果使用了 Secret 存储凭证确保也删除相关 Secret在集群审计日志中记录吊销操作完整的吊销流程应该是# 1. 查找所有关联的权限绑定 kubectl get clusterrolebindings --all-namespaces -o json | jq -r .items[] | select(.subjects[]?.namecicd-agent) | .metadata.name # 2. 删除这些绑定 kubectl delete clusterrolebinding cicd-node-viewer kubectl delete rolebinding cicd-dev-deployer -n dev kubectl delete rolebinding cicd-staging-deployer -n staging # 3. 删除 ServiceAccount kubectl delete sa cicd-agent -n automation # 4. 删除关联的 Secret kubectl delete secret cicd-agent -n automation5. 生产环境最佳实践5.1 安全加固建议定期轮换凭证即使没有泄露迹象也应该定期如每90天更新 ServiceAccount 的 token网络策略限制使用 NetworkPolicy 限制哪些 Pod 可以访问 API Server审计日志监控启用 Kubernetes 审计日志监控敏感操作使用短时效 token对于 Kubernetes 1.20可以考虑使用 TokenRequest API 获取短时效 token5.2 大规模环境管理技巧当管理数十个 ServiceAccount 时可以考虑使用命名规范如{用途}-{环境}-sa集中管理脚本创建统一的脚本库管理所有凭证使用 GitOps 管理将 RBAC 配置纳入版本控制自动化审计定期扫描检查权限分配情况# 示例查找所有具有集群管理员权限的 ServiceAccount kubectl get clusterrolebindings -o json | jq -r .items[] | select(.roleRef.namecluster-admin) | .subjects[] | select(.kindServiceAccount) | \(.namespace):\(.name)5.3 常见问题排查当 kubeconfig 不工作时可以按照以下步骤排查检查 token 是否有效kubectl --kubeconfigproblematic-config get secret -n kube-system验证 API Server 可访问curl -k -H Authorization: Bearer $TOKEN $SERVER/api检查证书是否过期echo $CA_DATA | base64 -d | openssl x509 -noout -dates查看 API Server 日志kubectl logs -n kube-system kube-apiserver-control-plane我在实际使用中发现大多数问题都源于以下原因Token 过期或无效CA 证书不匹配API Server 网络不可达RBAC 权限配置错误掌握这些排查技巧可以节省大量故障排除时间。
快速创建与吊销基于 ServiceAccount 的 Kubernetes 集群访问凭证
1. ServiceAccount 与 Kubernetes 访问控制基础在 Kubernetes 集群中ServiceAccount 是专门为运行在 Pod 中的进程提供身份认证的机制。与 UserAccount 不同ServiceAccount 是集群内部的账户主要用于自动化流程和系统组件间的通信。理解这一点很重要因为很多刚开始接触 Kubernetes 的开发者常常混淆这两种账户类型。ServiceAccount 的典型使用场景包括CI/CD 流水线中的自动化部署监控系统采集集群指标日志收集组件访问 API 服务器自定义控制器操作集群资源每个命名空间都会自动创建一个名为 default 的 ServiceAccountPod 如果没有指定 ServiceAccount就会使用这个默认账户。但实际生产环境中我们强烈建议为不同用途创建专门的 ServiceAccount并分配最小必要权限。2. 快速创建 ServiceAccount 与关联权限2.1 创建基础 ServiceAccount让我们从创建一个名为 cicd-agent 的 ServiceAccount 开始这个账户将用于 CI/CD 系统的集群操作kubectl create sa cicd-agent -n automation在 Kubernetes 1.24 及以上版本中Secret 不会自动创建需要手动补充。这是一个重要的变化很多人在新版本集群中会遇到这个问题cat EOF | kubectl apply -f - apiVersion: v1 kind: Secret metadata: name: cicd-agent namespace: automation annotations: kubernetes.io/service-account.name: cicd-agent type: kubernetes.io/service-account-token EOF2.2 权限绑定实战技巧权限绑定是安全管控的关键环节。Kubernetes 提供了两种主要方式ClusterRoleBinding适用于集群范围的权限RoleBinding适用于特定命名空间的权限假设我们的 CI/CD 系统需要部署应用到 dev 和 staging 命名空间同时需要读取集群节点信息但不应该有任何修改节点的权限。这种场景下我们可以这样配置# 创建 ClusterRole 用于节点只读访问 kubectl create clusterrole node-viewer --verbget,list,watch --resourcenodes # 创建 Role 用于应用部署 kubectl create role deploy-manager -n dev --verb* --resourcedeployments,services,pods kubectl create role deploy-manager -n staging --verb* --resourcedeployments,services,pods # 绑定权限 kubectl create clusterrolebinding cicd-node-viewer --clusterrolenode-viewer --serviceaccountautomation:cicd-agent kubectl create rolebinding cicd-dev-deployer -n dev --roledeploy-manager --serviceaccountautomation:cicd-agent kubectl create rolebinding cicd-staging-deployer -n staging --roledeploy-manager --serviceaccountautomation:cicd-agent这种精细化的权限分配遵循了最小权限原则即使凭证泄露也能将风险控制在有限范围内。3. 生成 kubeconfig 文件的进阶方法3.1 自动化脚本解析原始文章提供了一个基础脚本我们可以对其进行增强增加错误处理和更多实用功能#!/bin/bash set -eo pipefail # 颜色定义 RED\033[0;31m GREEN\033[0;32m NC\033[0m # 参数检查 if [ $# -lt 3 ]; then echo -e ${RED}错误缺少参数${NC} echo 用法: $0 serviceaccount-name namespace output-file [context-name] echo 示例: $0 cicd-agent automation ~/.kube/cicd-config my-cicd-context exit 1 fi SERVICE_ACCOUNT_NAME$1 NAMESPACE$2 OUTPUT_FILE$3 CONTEXT_NAME${4:-${SERVICE_ACCOUNT_NAME}-context} # 验证 ServiceAccount 是否存在 if ! kubectl get sa ${SERVICE_ACCOUNT_NAME} -n ${NAMESPACE} /dev/null; then echo -e ${RED}错误ServiceAccount ${SERVICE_ACCOUNT_NAME} 在命名空间 ${NAMESPACE} 中不存在${NC} exit 1 fi # 获取集群信息 CURRENT_CONTEXT$(kubectl config current-context) CLUSTER_NAME$(kubectl config get-contexts $CURRENT_CONTEXT --no-headers | awk {print $3}) SERVER$(kubectl config view --minify -o jsonpath{.clusters[0].cluster.server}) # 获取 Secret 名称兼容 1.24 版本 SECRET_NAME$(kubectl get sa ${SERVICE_ACCOUNT_NAME} -n ${NAMESPACE} -o jsonpath{.secrets[0].name}) if [ -z $SECRET_NAME ]; then SECRET_NAME${SERVICE_ACCOUNT_NAME} echo -e ${RED}警告未找到自动创建的 Secret尝试使用 ServiceAccount 名称作为 Secret 名称${NC} fi # 获取 Token 和 CA 证书 TOKEN$(kubectl get secret $SECRET_NAME -n $NAMESPACE -o jsonpath{.data.token} | base64 --decode) CA_DATA$(kubectl get secret $SECRET_NAME -n $NAMESPACE -o jsonpath{.data.ca\.crt}) # 生成 kubeconfig cat EOF $OUTPUT_FILE apiVersion: v1 kind: Config clusters: - name: ${CLUSTER_NAME} cluster: certificate-authority-data: ${CA_DATA} server: ${SERVER} contexts: - name: ${CONTEXT_NAME} context: cluster: ${CLUSTER_NAME} user: ${SERVICE_ACCOUNT_NAME} namespace: ${NAMESPACE} current-context: ${CONTEXT_NAME} users: - name: ${SERVICE_ACCOUNT_NAME} user: token: ${TOKEN} EOF echo -e ${GREEN}成功kubeconfig 已生成到 ${OUTPUT_FILE}${NC} echo 使用命令测试kubectl --kubeconfig${OUTPUT_FILE} get pods这个增强版脚本具有以下改进更好的错误处理和用户反馈支持自定义上下文名称更完善的参数验证颜色化输出提升可读性自动检测 Secret 存在情况3.2 多集群配置管理在实际工作中我们经常需要管理多个集群的访问凭证。kubeconfig 文件支持配置多个集群、用户和上下文。我们可以扩展上面的脚本来支持多集群配置的合并# 合并现有配置与新配置 if [ -f $OUTPUT_FILE ]; then echo 检测到现有 kubeconfig 文件将合并配置... KUBECONFIG${OUTPUT_FILE}:${HOME}/.kube/config kubectl config view --flatten /tmp/kubeconfig-tmp mv /tmp/kubeconfig-tmp ${OUTPUT_FILE} echo 配置合并完成 fi4. 权限吊销的深度实践4.1 临时权限吊销临时吊销权限而不影响 ServiceAccount 本身是常见的运维需求。除了删除 ClusterRoleBinding/RoleBinding 外还有更精细的控制方式修改 Role/ClusterRole 定义kubectl edit clusterrole node-viewer然后调整 verbs 字段比如从get,list,watch改为get,list使用权限拒绝规则Deny RulesapiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: access-denier rules: - apiGroups: [] resources: [secrets] verbs: [*] resourceNames: [database-credentials]然后创建 RoleBinding 将特定用户/ServiceAccount 绑定到这个拒绝角色。4.2 永久权限吊销的注意事项当需要永久吊销访问权限时除了删除 ServiceAccount 外还需要考虑清理所有关联的 RoleBinding/ClusterRoleBinding检查并清理 Pod 中使用该 ServiceAccount 的情况如果使用了 Secret 存储凭证确保也删除相关 Secret在集群审计日志中记录吊销操作完整的吊销流程应该是# 1. 查找所有关联的权限绑定 kubectl get clusterrolebindings --all-namespaces -o json | jq -r .items[] | select(.subjects[]?.namecicd-agent) | .metadata.name # 2. 删除这些绑定 kubectl delete clusterrolebinding cicd-node-viewer kubectl delete rolebinding cicd-dev-deployer -n dev kubectl delete rolebinding cicd-staging-deployer -n staging # 3. 删除 ServiceAccount kubectl delete sa cicd-agent -n automation # 4. 删除关联的 Secret kubectl delete secret cicd-agent -n automation5. 生产环境最佳实践5.1 安全加固建议定期轮换凭证即使没有泄露迹象也应该定期如每90天更新 ServiceAccount 的 token网络策略限制使用 NetworkPolicy 限制哪些 Pod 可以访问 API Server审计日志监控启用 Kubernetes 审计日志监控敏感操作使用短时效 token对于 Kubernetes 1.20可以考虑使用 TokenRequest API 获取短时效 token5.2 大规模环境管理技巧当管理数十个 ServiceAccount 时可以考虑使用命名规范如{用途}-{环境}-sa集中管理脚本创建统一的脚本库管理所有凭证使用 GitOps 管理将 RBAC 配置纳入版本控制自动化审计定期扫描检查权限分配情况# 示例查找所有具有集群管理员权限的 ServiceAccount kubectl get clusterrolebindings -o json | jq -r .items[] | select(.roleRef.namecluster-admin) | .subjects[] | select(.kindServiceAccount) | \(.namespace):\(.name)5.3 常见问题排查当 kubeconfig 不工作时可以按照以下步骤排查检查 token 是否有效kubectl --kubeconfigproblematic-config get secret -n kube-system验证 API Server 可访问curl -k -H Authorization: Bearer $TOKEN $SERVER/api检查证书是否过期echo $CA_DATA | base64 -d | openssl x509 -noout -dates查看 API Server 日志kubectl logs -n kube-system kube-apiserver-control-plane我在实际使用中发现大多数问题都源于以下原因Token 过期或无效CA 证书不匹配API Server 网络不可达RBAC 权限配置错误掌握这些排查技巧可以节省大量故障排除时间。