本文记录 Kubernetes 集成 KeyCloak 统一认证的配置和验证步骤,仅供测试参考。
1. 部署 KeyCloak 服务
keycloak 独立于 Kubernetes 集群单独部署,本文通过 Docker Compose 启动:
mkdir -p ~/work/keycloak
cd ~/work/keycloak
cat <<EOF > generate-certs.sh
#!/bin/bash
# 创建证书目录
mkdir -p certs
# 生成自签名证书,如果有域名可以使用,不要使用 IP 而是使用域名
# 这里为了简单,就直接用的本机 IP 地址生成证书了
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout certs/tls.key \
-out certs/tls.crt \
-subj "/C=CN/ST=Beijing/L=Beijing/O=Test/OU=Keycloak/CN=192.168.124.7" \
-addext "subjectAltName = IP:192.168.124.7"
# 设置文件权限
chmod 644 certs/*
echo "证书已生成到 certs/ 目录:"
echo "- tls.crt / tls.key: PEM 格式证书"
# 显示证书信息
echo -e "\n证书信息:"
openssl x509 -in certs/tls.crt -text -noout | grep -A1 "Subject:"
openssl x509 -in certs/tls.crt -text -noout | grep -A1 "Subject Alternative Name"
EOF
bash generate-certs.sh
cat <<EOF > docker-compose.yaml
version: '3.8'
services:
postgres:
image: postgres:15-alpine
environment:
POSTGRES_DB: keycloak
POSTGRES_USER: keycloak
POSTGRES_PASSWORD: password
volumes:
- postgres_data:/var/lib/postgresql/data
restart: unless-stopped
keycloak:
image: quay.io/keycloak/keycloak:24.0.4
command: >
start-dev
--db=postgres
--db-url=jdbc:postgresql://postgres:5432/keycloak
--db-username=keycloak
--db-password=password
--https-certificate-file=/opt/keycloak/certs/tls.crt
--https-certificate-key-file=/opt/keycloak/certs/tls.key
--hostname=192.168.124.7
--hostname-strict=false
--hostname-strict-https=false
environment:
KEYCLOAK_ADMIN: admin
KEYCLOAK_ADMIN_PASSWORD: admin123
KC_HOSTNAME: 192.168.124.7
KC_HOSTNAME_STRICT: "false"
KC_HOSTNAME_STRICT_HTTPS: "false"
KC_HTTPS_CERTIFICATE_FILE: /opt/keycloak/certs/tls.crt
KC_HTTPS_CERTIFICATE_KEY_FILE: /opt/keycloak/certs/tls.key
ports:
- "8080:8080" # HTTP 端口(可选)
- "8443:8443" # HTTPS 端口
depends_on:
- postgres
volumes:
- keycloak_data:/opt/keycloak/data
- ./certs:/opt/keycloak/certs:ro
restart: unless-stopped
volumes:
postgres_data:
keycloak_data:
EOF
docker-compose up -d
验证 keycloak 服务,访问 https://192.168.124.7:8443 (或 http://192.168.124.7:8080)(注意这里访问的地址是 KC_HOSTNAME 的设置地址,实际应用时可以使用域名,这里直接用的 IP)

输入用户名 admin,密码 admin123 登入

2. 创建 Realm 和 Client
这两个后边需要配置给 kube-apiserver 用于验证身份
创建 Realm

创建 Client



创建 Group


以下步骤为 token 添加 groups 字段:



3. 配置 kubernetes OIDC
修改 kube-apiserver 启动参数,添加如下参数:
--oidc-issuer-url=https://192.168.124.7:8443/realms/kubernetes
--oidc-client-id=kubernetes
--oidc-username-claim=preferred_username
--oidc-groups-claim=groups
"--oidc-username-prefix=oidc:"
"--oidc-groups-prefix=oidc:"
--oidc-ca-file=/etc/kubernetes/pki/keycloak.crt
由于 keycloak 使用的自签名证书,因此需要通过 --oidc-ca-file 指定证书。
复制 keycloak 的 tls.crt 文件到 kube-apiserver 所在机器的 /etc/kubernetes/pki/keycloak.crt
–oidc-username-prefix 和 --oidc-groups-prefix 参数需要整体用引号引起来,防止末尾冒号歧义。
在 Kubernetes 集群中,需要设置好 User 或 Group 对应的权限:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: keycloak_cluster_admin
subjects:
- kind: Group
name: "oidc:KubernetesClusterAdmin" # should match the Keycloak Group
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: keycloak_cluster_viewer
subjects:
- kind: Group
name: "oidc:KubernetesClusterViewer" # should match the Keycloak Group
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: view
apiGroup: rbac.authorization.k8s.io
如果是给指定用户授权,可以
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: keycloak_john
subjects:
- kind: User
name: "oidc:john"
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
4. 配置 kubeconfig 使用 keycloak 验证
首先,需要安装 kubelogin 插件,将二进制 kubelogin 重名命名为 kubectl-oidc_login。参考 https://github.com/int128/kubelogin#getting-started
参考如下模版,创建 kubeconfig 配置文件
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: xxx
server: https://127.0.0.1:60066
name: kind-kind
contexts:
- context:
cluster: kind-kind
user: kind-kind
name: kind-kind
current-context: kind-kind
kind: Config
preferences: {}
users:
- name: kind-kind
user:
exec:
apiVersion: client.authentication.k8s.io/v1beta1
command: kubectl
args:
- oidc-login
- get-token
- --insecure-skip-tls-verify
- --oidc-issuer-url=https://192.168.124.7:8443/realms/kubernetes
- --oidc-client-id=kubernetes
- --oidc-client-secret=LSXFEa6cjoZubwe5gjq2yekiRo3Gu84N
其中 --oidc-issuer-url,–oidc-client-id,–oidc-client-secret 可以从 keycloak 创建的 Client 配置获取。

在 keycloak 创建 john 用户,并为其设置一个密码,执行 kubectl 命令时,会自动调起浏览器登录 keycloak,完成认证后,命令行就可以正确执行了。
kubectl get node --kubeconfig `前边创建的 kubeconfig`


如何退出登录?执行 kubectl oidc-login clean 即可。
如何 Debug 获得的 Token,可以执行如下命令,即执行 kubeconfig 里的登录命令:
kubectl oidc-login --insecure-skip-tls-verify \
--oidc-issuer-url=https://192.168.124.7:8443/realms/kubernetes \
--oidc-client-id=kubernetes \
--oidc-client-secret=LSXFEa6cjoZubwe5gjq2yekiRo3Gu84N \
--oidc-extra-scope=email \
--oidc-extra-scope=profile \
get-token
会得到类似如下信息:
{"kind":"ExecCredential","apiVersion":"client.authentication.k8s.io/v1beta1","spec":{"interactive":false},"status":{"expirationTimestamp":"2025-12-13T16:15:55Z","token":"eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJNSGx1OUdoYWsyYTFMX2p4NmJzMWpMbkxBZS0xczhkZjlHRmJOT1FFNmlFIn0.eyJleHAiOjE3NjU2NDI1NTUsImlhdCI6MTc2NTY0MjI1NSwiYXV0aF90aW1lIjoxNzY1NjM5OTg5LCJqdGkiOiJmNmI1Yjg3Zi0xZjAzLTRkOGEtYWE2Zi0wNzQ0YmY2OTNlNTUiLCJpc3MiOiJodHRwczovLzE5Mi4xNjguMTI0Ljc6ODQ0My9yZWFsbXMva3ViZXJuZXRlcyIsImF1ZCI6Imt1YmVybmV0ZXMiLCJzdWIiOiI2OTY2OTA5MC1iZjc0LTQxMmYtYTc4MS03ZGQ3MWVmYmJkMGYiLCJ0eXAiOiJJRCIsImF6cCI6Imt1YmVybmV0ZXMiLCJub25jZSI6ImtVM3E3ZkF3VFl3Rkw0UVJGYzZlbllHdmxSQmo3S1FyazFFcTlBM09ibVkiLCJzZXNzaW9uX3N0YXRlIjoiNWIwZGRkN2MtZTNkOC00ZDA4LWFhZDEtMmE3ODg4OGQ3NWY3IiwiYXRfaGFzaCI6IlJoQU9UQUhvM2ZLV0pkS01JTk41N3ciLCJhY3IiOiIwIiwic2lkIjoiNWIwZGRkN2MtZTNkOC00ZDA4LWFhZDEtMmE3ODg4OGQ3NWY3IiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJuYW1lIjoiam9obiBqb2huIiwicHJlZmVycmVkX3VzZXJuYW1lIjoiam9obiIsImdpdmVuX25hbWUiOiJqb2huIiwiZmFtaWx5X25hbWUiOiJqb2huIiwiZW1haWwiOiIxMjMzQHFxLmNvbSJ9.DOxOoERVTzc8g01uMgMVLK6wDX_JpR1BdlJriLtgpkAZMmhqMq7z3WXULKDn5l95JRjwAIc3mbTxe5zFfj-Qs3C0Y7P5wtGLeqne9jeegUQAJgwlsWYIxi14wR_zUEr7e-NkSxR7EYRYTSXR68jPNLfqUtz83brw6VBjwz1Uu6PDOfrZ4LC3a8RtR2PtHxfXF-aerEbt7dbVf5yN8jJOqDnNbn_34KM5--tBzdvNnNfICwZLh-6XSlOFldRJLPgAcJg9dgcMSNwsMOScyipB2zYGpCaDgA0oQLMb5kOduy28qDvFr1nPGjhkzY2brnTSdq5VSxaMQQqmNeK4lnLHqQ"}}
这里保存了从 keycloak 返回的 token 信息,通过 JWT 解码,可以看到具体的用户数据
{
"exp": 1765641235,
"iat": 1765640935,
"auth_time": 1765639989,
"jti": "ae3ed7b7-6945-492d-8838-daccca6e1f71",
"iss": "https://192.168.124.7:8443/realms/kubernetes",
"aud": "kubernetes",
"sub": "69669090-bf74-412f-a781-7dd71efbbd0f",
"typ": "ID",
"azp": "kubernetes",
"nonce": "AA8CtMWJoO5Tu_X17rbODn6dS-j9wYbAi8CjNeMF-pA",
"session_state": "5b0ddd7c-e3d8-4d08-aad1-2a78888d75f7",
"at_hash": "29rHiJtTsyvtOMKnJ8gb-Q",
"acr": "0",
"sid": "5b0ddd7c-e3d8-4d08-aad1-2a78888d75f7",
"email_verified": false,
"name": "john john",
"preferred_username": "john",
"given_name": "john",
"family_name": "john",
"email": "1233@qq.com"
}
可以看到,preferred_username 字段是 john,加上前缀 oidc: 组成最终 User 格式恰好是 oidc:john,即 ClusterRoleBinding 里授权的用户名。
如何为用户分配 Group?keycloak 直接分配即可,如下图:

如何对接多集群?可以分别给不同集群创建对应的 Client,共享一套 User 和 Group 信息。



2万+

被折叠的 条评论
为什么被折叠?



