跳转到内容

Kubernetes kubeconfig 与 RBAC

本指南适用于自己管理的控制面,也适用于接受相同 OIDC 字段的托管服务。请先完成 Kubernetes 与 OIDC。

在使用示例前准备以下占位值:

REALMROOT_ISSUER=https://id.example.com/api/auth
KUBERNETES_CLIENT_ID=APPLICATION_CLIENT_ID
ORGANIZATION_ID=REALMROOT_ORGANIZATION_ID
KUBERNETES_SERVER=https://kubernetes.example.com:6443

使用传统 Flags 配置时,在每个 kube-apiserver 实例增加:

--oidc-issuer-url=https://id.example.com/api/auth
--oidc-client-id=APPLICATION_CLIENT_ID
--oidc-username-claim=email
--oidc-username-prefix=-
--oidc-groups-claim=groups
--oidc-groups-prefix=
--oidc-required-claim=urn:realmroot:params:oauth:org=REALMROOT_ORGANIZATION_ID
--oidc-signing-algs=RS256

空 Groups Prefix 会原样保留 Team name。如果发行版不能表示空参数,只有在确认它不会自动 添加默认 Prefix 后,才能省略 Groups Prefix 参数。

修改 kube-apiserver 参数通常会重启控制面。在 OIDC 验证完成前保留现有管理员 kubeconfig。

Kubernetes 1.34+ Structured Authentication

Section titled “Kubernetes 1.34+ Structured Authentication”

Kubernetes 1.34 已将 AuthenticationConfiguration 标记为 Stable。把下面的文件保存到每个 控制面节点,并使用 --authentication-config=/etc/kubernetes/realmroot-authentication.yaml 启动 kube-apiserver:

apiVersion: apiserver.config.k8s.io/v1
kind: AuthenticationConfiguration
jwt:
- issuer:
url: https://id.example.com/api/auth
audiences:
- APPLICATION_CLIENT_ID
audienceMatchPolicy: MatchAny
claimValidationRules:
- expression: "claims['urn:realmroot:params:oauth:org'] == 'REALMROOT_ORGANIZATION_ID'"
message: token is not issued for this Realmroot Organization
- expression: "claims.?email_verified.orValue(true) == true"
message: email must be verified when the claim is present
claimMappings:
username:
claim: email
prefix: ""
groups:
claim: groups
prefix: ""
uid:
claim: sub
userValidationRules:
- expression: "!user.username.startsWith('system:')"
message: username must not use the Kubernetes system prefix
- expression: "user.groups.all(group, !group.startsWith('system:'))"
message: groups must not use the Kubernetes system prefix

不要同时配置 --authentication-config 和 --oidc-* Flags。Kubernetes 会把这种组合视为 致命配置错误。

Realmroot CLI 当前没有实现 Kubernetes ExecCredential 协议。本指南使用独立的 int128/kubelogin 插件:

Terminal window
brew install kubelogin
# 或者
kubectl krew install oidc-login

选择固定的 Loopback Callback,例如 http://127.0.0.1:8000。在 Realmroot Application 中添加这个准确的 URI,并在后续配置中保持一致。

修改 kubeconfig 前先测试 OIDC Flow:

Terminal window
kubectl oidc-login setup \
--oidc-issuer-url=https://id.example.com/api/auth \
--oidc-client-id=APPLICATION_CLIENT_ID \
--oidc-redirect-url=http://127.0.0.1:8000 \
--oidc-extra-scope=email \
--oidc-extra-scope=profile \
--oidc-extra-scope=groups \
--oidc-extra-scope=offline_access \
--oidc-pkce-method=S256

确认输出的 Claims 包含正确的 Organization ID 和 Team names。不要把 Token 粘贴到 Issue 或日志中。

通过现有管理员访问获取集群 CA,并编码 CA 的 PEM 证书,不要编码管理员 Client Certificate:

Terminal window
base64 < cluster-ca.pem | tr -d '\n'

使用以下模板创建 kubeconfig:

apiVersion: v1
kind: Config
clusters:
- name: CLUSTER_NAME
cluster:
server: https://kubernetes.example.com:6443
certificate-authority-data: BASE64_CLUSTER_CA
users:
- name: realmroot
user:
exec:
apiVersion: client.authentication.k8s.io/v1
command: kubectl
interactiveMode: IfAvailable
provideClusterInfo: false
args:
- oidc-login
- get-token
- --oidc-issuer-url=https://id.example.com/api/auth
- --oidc-client-id=APPLICATION_CLIENT_ID
- --oidc-redirect-url=http://127.0.0.1:8000
- --oidc-extra-scope=email
- --oidc-extra-scope=profile
- --oidc-extra-scope=groups
- --oidc-extra-scope=offline_access
- --oidc-pkce-method=S256
- --token-cache-storage=keyring
contexts:
- name: CLUSTER_NAME
context:
cluster: CLUSTER_NAME
user: realmroot
current-context: CLUSTER_NAME

该文件不包含用户 Token、Refresh Token、Client Secret 或管理员凭证,可以分发给获准的 Organization 成员。每个用户在自己的浏览器中登录,Keyring Cache 只保存在本机。

认证本身不会授予权限。以下 Namespace 级示例允许 developers Team 查看工作负载,但不 允许读取 Secrets:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: workload-reader
namespace: example
rules:
- apiGroups: [""]
resources: ["pods", "pods/log", "services", "configmaps"]
verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
resources: ["deployments", "replicasets", "statefulsets", "daemonsets"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: developers-workload-reader
namespace: example
subjects:
- kind: Group
name: developers
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: workload-reader
apiGroup: rbac.authorization.k8s.io

不要把范围很大的 Team 绑定到 cluster-admin。如果紧急 Bootstrap 必须使用,应创建受到 严格控制的 Binding,并在验证后替换成最小权限 Role。

Terminal window
kubectl auth whoami
kubectl auth can-i list pods -n example
kubectl auth can-i list secrets -n example

第一条命令应显示用户 Email 和 Realmroot Team names。上述示例策略应对 Pods 返回 yes,对 Secrets 返回 no。

需要强制重新登录时,使用 kubelogin 的 Cache 命令清除缓存,或从所配置的 Keyring 中删除 对应条目。撤销权限时,把用户移出 Team 或 Organization,然后等待当前十分钟 ID Token 过期。只有确认仍保留另一条管理员访问路径后,才能删除 OIDC 配置。

更多信息参见 Kubernetes 官方的 Authentication 和 RBAC 文档。