K8s集群构建签名验证部署实操
技术栈:Kubernetes v1.32.13 + RBAC + OIDC + Vault + Jenkins/GitLab CI + Rocky Linux 8.6
操作环境 / 对接原理 / 详细步骤 / 完整命令 / 配置文件 / 验证流程 / 排错方案
K8s集群构建签名验证部署实操
操作环境
K8s 集群版本 v1.32.13,已配置 RBAC 授权
CI/CD 工具:Jenkins / GitLab CI / GitHub Actions / ArgoCD
密钥管理:HashiCorp Vault,外部 Secrets 管理
OIDC 提供商:GitLab / GitHub / Keycloak,SSO 认证
镜像仓库 Harbor v2.10.x,项目级权限控制
审计日志:K8s Audit Log + CI 审计日志
对接原理
流水线权限对接是 CI/CD 安全的核心,确保构建和部署过程遵循最小权限原则,防止凭据泄露和越权操作。K8s 侧通过 RBAC(Role/ClusterRole + RoleBinding/ClusterRoleBinding)为 CI ServiceAccount 授予最小权限,区分命名空间级别(Role)和集群级别(ClusterRole)权限,避免使用 cluster-admin 等超管权限。CI 侧通过凭据管理(Jenkins Credentials / GitLab Variables / GitHub Secrets)存储敏感信息,支持掩码(Masked)、受保护(Protected)、环境作用域(Environment scope),防止日志泄露和未授权访问。高级方案:OIDC 联邦认证(无密钥,GitHub Actions/GitLab CI 通过 OIDC Token 换取 K8s 短期凭证)、Vault 动态密钥(短期数据库凭据、云厂商 Access Key)、External Secrets Operator(从 Vault 同步到 K8s Secret)。权限审计:定期审查 CI 凭据和 K8s RBAC,启用 K8s Audit Log 记录 API 操作,CI 流水线记录所有执行操作。
详细步骤
1. 流水线权限基础操作
# 查看 ServiceAccount kubectl get serviceaccount -n ci # 查看 Role kubectl get role -n default # 查看 RoleBinding kubectl get rolebinding -n default # 验证权限 kubectl auth can-i create deployments --as=system:serviceaccount:ci:ci-deployer -n default # 查看 kubeconfig kubectl config view # 轮换 Token kubectl delete secret ci-deployer-token -n ci kubectl apply -f ci-token.yaml
2. 权限排错命令
# 查看 ServiceAccount 权限 kubectl auth can-i --list --as=system:serviceaccount:ci:ci-deployer -n default # 查看 Role 详情 kubectl describe role ci-deployer-role -n default # 查看 RoleBinding kubectl describe rolebinding ci-deployer-binding -n default # 查看 Token 内容 kubectl get secret ci-deployer-token -n ci -o jsonpath='{.data.token}' | base64 -d | cut -d. -f2 | base64 -d | jq . # 测试 API 访问 APISERVER=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}') TOKEN=$(kubectl get secret ci-deployer-token -n ci -o jsonpath='{.data.token}' | base64 -d) curl -k --header "Authorization: Bearer $TOKEN" $APISERVER/api/v1/namespaces/default/pods验证流程
# 1. 验证 ServiceAccount 权限 kubectl auth can-i create deployments --as=system:serviceaccount:ci:ci-deployer -n default # yes kubectl auth can-i delete namespaces --as=system:serviceaccount:ci:ci-deployer # no(最小权限) # 2. 验证 kubeconfig 可用 export KUBECONFIG=ci-kubeconfig.yaml kubectl get pods -n default # 正常列出 Pod kubectl get nodes # 应被拒绝(无集群权限) # 3. 验证 CI 凭据掩码 # Jenkins/GitLab/GitHub 构建日志中 # $HARBOR_PASS 显示为 ****** 或 [MASKED] # 不出现明文密码 # 4. 验证 OIDC(如配置) # GitHub Actions 日志显示: # OIDC token acquired # kubeconfig configured # 无需配置 K8S_SA_TOKEN Secret # 5. 验证 Vault 动态密钥 # 数据库中查看临时用户 # SELECT usename FROM pg_user WHERE usename LIKE 'v-token-myapp-%'; # 显示动态生成的用户,TTL 过期后自动删除 # 6. 验证审计日志 grep "ci-deployer" /var/log/kubernetes/audit.log | tail -5 # 显示 CI 的操作记录(时间、用户、操作、资源) # 7. 验证环境隔离 kubectl auth can-i create deployments --as=system:serviceaccount:ci:ci-deployer-dev -n production # no(dev 环境 SA 无 production 权限)
排错方案
CI 部署 Forbidden:检查 ServiceAccount 是否存在,Role/RoleBinding 是否正确绑定到目标命名空间,资源和动词是否在 Role 中授权,kubeconfig Token 是否正确,kubectl auth can-i 验证
Token 过期无效:K8s v1.24+ 默认 Token 无过期但需手动创建 Secret,检查 Secret 是否存在,Token 是否被删除,使用 OIDC 或 Vault 短期 Token 避免长期 Token 问题
凭据日志泄露:检查 CI 变量是否设置为 Masked/Protected,withCredentials 是否正确绑定,是否在脚本中 echo 密码,是否启用了凭据掩码插件,日志中搜索密码关键词
Harbor 推送 403:检查机器人账号是否有项目推送权限,Token 是否过期,项目是否为私有且账号是否为项目成员,不可变标签规则是否阻止覆盖
Vault 认证失败:检查 K8s Auth Method 配置,ServiceAccount 是否匹配 role,Vault Policy 是否授予读取权限,Vault 地址是否可从 CI 访问,Token 是否过期
OIDC 登录失败:检查 kube-apiserver OIDC 配置(issuer-url/client-id),GitHub Actions permissions 是否包含 id-token: write,RBAC 用户名称是否与 OIDC sub 匹配,CA 证书是否正确
审计日志不记录:检查 kube-apiserver 是否配置 audit-policy-file 和 audit-log-path,审计策略规则是否匹配,日志文件路径是否可写,kube-apiserver 是否重启生效
环境越权:检查 RoleBinding 的 namespace 是否正确,ServiceAccount 是否绑定到正确环境,NetworkPolicy 是否生效,CI 流水线是否使用了错误环境的凭据,定期审计权限绑定