Kubernetes OIDC 集成 KeyCloak 实现统一认证登录配置步骤

本文记录 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 信息。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值