3. 用户、组与服务账户管理
在 OpenShift 中,权限治理的第一步不是分配角色,而是把“身份”理清楚。OpenShift 的身份体系分为两条线:一条面向人,即 User(用户) 与 Group(组);另一条面向工作负载,即 ServiceAccount(服务账户)。前者通常由外部身份提供者(如 LDAP、OIDC、HTPasswd)同步而来,后者由集群自身在命名空间内创建和管理。理解这两条线的创建、同步与绑定方式,是后续 RBAC 授权、镜像拉取、令牌分发的基础。
一、用户与组:身份从哪里来
OpenShift 本身不存储用户密码,它是一个“身份消费者”。用户对象(User)在集群中通常是只读的,由身份提供者(Identity Provider,IdP)在用户首次登录时自动创建。管理员真正需要配置的是 OAuth 配置 与 身份提供者,而不是手工创建 User。常见的 IdP 类型包括:
- HTPasswd:用一份 htpasswd 文件保存用户名与 bcrypt 密码哈希,适合实验与小型环境。
- LDAP:对接企业目录,支持按组同步,是生产环境最常见的方式。
- OIDC:对接 Keycloak、Azure AD、Okta 等,使用标准声明映射用户与组。
以 HTPasswd 为例,创建身份提供者的核心是先生成密码文件,再把它挂载进 OAuth 配置。示例命令如下(示例参数,非实测结果):
# 生成 htpasswd 文件(示例用户 dev1、dev2)
htpasswd -c -B -b /tmp/users.htpasswd dev1 'Passw0rd!'
htpasswd -B -b /tmp/users.htpasswd dev2 'Passw0rd!'
# 创建 Secret 承载该文件
oc create secret generic htpass-secret \
--from-file=htpasswd=/tmp/users.htpasswd \
-n openshift-config
# 将 Secret 关联到 OAuth 的 htpasswd 身份提供者
oc edit oauth cluster
在 oauth/cluster 中,需要声明 identityProviders 的 type: HTPasswd 并引用该 Secret。保存后 OAuth Pod 会自动滚动重启,随后用户即可登录。登录成功后,可用 oc get users 看到自动生成的 User 对象,用 oc get identities 看到身份映射。
二、组的创建与同步
组是权限治理的“批量单位”。与其给 50 个人逐个绑定 RoleBinding,不如把他们放进一个 Group,再给 Group 绑定角色。组有两种来源:
- 手工组:直接创建
Group对象并维护users列表,适合小规模或临时场景。 - 同步组:由 LDAP/OIDC 的组声明自动同步,成员随目录变化自动更新,适合企业环境。
手工创建组并加入用户的示例:
oc adm groups new dev-team
oc adm groups add-users dev-team dev1 dev2
oc get group dev-team -o yaml
对于 LDAP 同步,需要在 oauth/cluster 中配置 ldap 提供者,并设置 groupMembership 属性(如 member、uniqueMember),同时通过 oc adm groups sync 或定时任务把目录组同步为 OpenShift Group。同步后的组名通常带有前缀,例如 ldap-dev-team,便于与手工组区分。
cn 或 sAMAccountName 决定组名,member 决定成员。映射写错会导致组存在但成员为空,这是排障时最先检查的点。三、标签管理:让身份可被选择
标签(Label)是 OpenShift 中“按条件选择对象”的通用机制。对用户和组而言,标签的价值在于:可以用 oc get users -l 快速筛选,也可以让某些自动化策略按标签生效。例如给组打上部门标签:
oc label group dev-team department=engineering
oc label group ops-team department=operations
# 按标签筛选
oc get groups -l department=engineering
标签本身不授予权限,但它让“谁属于哪个部门、哪个环境”变得可查询、可审计。在后续章节中,ClusterRoleBinding 也可以结合标签做批量治理。
四、ServiceAccount:工作负载的身份
ServiceAccount(SA)是 Pod 在集群内的身份。每个命名空间默认有一个 default SA。当 Pod 未指定 SA 时,就使用它。SA 的创建非常简单:
oc create serviceaccount app-sa -n myproject
oc get sa app-sa -n myproject -o yaml
创建后,SA 会自动关联一个 长期令牌 Secret(在较新版本中默认不再自动生成,需要显式创建),以及可选的 镜像拉取密钥(imagePullSecret)。SA 的核心用途有三类:
- 作为 Pod 身份:在 Deployment 的
spec.template.spec.serviceAccountName中引用,Pod 内即可用挂载的令牌访问 API。 - 绑定镜像拉取密钥:私有镜像仓库的凭据以 Secret 形式存在,通过
imagePullSecrets绑定到 SA,Pod 拉镜像时自动使用。 - 绑定 RBAC 角色:通过 RoleBinding 把 SA 与 Role 关联,控制它能操作哪些资源。
五、令牌与镜像拉取密钥的绑定
令牌绑定有两种方式。第一种是让 SA 引用一个 kubernetes.io/service-account-token 类型的 Secret:
# 创建长期令牌 Secret 并绑定到 SA
oc create token app-sa -n myproject --duration=24h
# 或创建 Secret 方式
oc apply -f - <<'EOF'
apiVersion: v1
kind: Secret
metadata:
name: app-sa-token
namespace: myproject
annotations:
kubernetes.io/service-account.name: app-sa
type: kubernetes.io/service-account-token
EOF
第二种是使用 oc create token 生成短期令牌,适合 CI/CD 或临时调试。短期令牌不会持久化到 Secret,安全性更高。
镜像拉取密钥的绑定则分两步:先创建 docker-registry 类型的 Secret,再把它挂到 SA 上。
# 1. 创建镜像仓库凭据
oc create secret docker-registry regcred \
--docker-server=registry.example.com \
--docker-username=devuser \
--docker-password='S3cret!' \
-n myproject
# 2. 绑定到 ServiceAccount
oc secrets link app-sa regcred --for=pull -n myproject
绑定后,使用 app-sa 的 Pod 在拉取 registry.example.com 的镜像时会自动携带该凭据。可以用 oc get sa app-sa -o yaml 查看 imagePullSecrets 字段确认绑定生效。
六、身份治理的整体关系
把上述内容串起来看:外部 IdP 提供用户与组,OpenShift 将其同步为 User/Group 对象;命名空间内创建 ServiceAccount 供工作负载使用;令牌与镜像拉取密钥通过 Secret 与 SA 绑定;最后通过 RoleBinding/ClusterRoleBinding 把身份与权限连接起来。下图展示了这条身份与凭据的流转关系。
从图中可以看到,用户与组解决“谁是人”,ServiceAccount 解决“谁是工作负载”,令牌与镜像拉取密钥解决“凭据从哪来”,而 RBAC 解决“能做什么”。四者环环相扣,缺一不可。实际治理中,建议遵循三条原则:用户与组尽量由 IdP 同步而非手工维护;ServiceAccount 按应用粒度创建,避免共用 default;令牌优先使用短期形式,镜像拉取密钥按命名空间隔离并定期轮换。