Kubernetes 使用 keycload 实现 OIDC 认证
1、keycloak 部署
参考 https://blog.csdn.net/yxydde/article/details/128710155
2、keycloak创建Kubernetes Realm
进入控制台,场景Realm即可
3、Kubernetes Realm 中创建 Client
Client Type 选 OpenID Connect,其它默认选项即可
注意:只有打开 Client authentication 时才有 Credentials 选项卡,关闭时客户端不需要提供 client-secret
4、配置 Mapper
选择 dedicated scope 进行添加
添加 username 和 groups 两个 predefined mapper
修改 username Mapper (Token Claim Name 修改为 username)
添加 Realm roles 和 User
Realm roles 默认选项创建即可
User 设置密码,分配指定 Realm roles 即可
内建 default-roles-kubernetes 角色可以登录 account-console 进行修改账号基本信息
5、查看 keycload 服务端点
{
"issuer": "https://keycloak.example.io/realms/kubernetes",
"authorization_endpoint": "https://keycloak.example.io/realms/kubernetes/protocol/openid-connect/auth",
"token_endpoint": "https://keycloak.example.io/realms/kubernetes/protocol/openid-connect/token",
"introspection_endpoint": "https://keycloak.example.io/realms/kubernetes/protocol/openid-connect/token/introspect",
"userinfo_endpoint": "https://keycloak.example.io/realms/kubernetes/protocol/openid-connect/userinfo",
"end_session_endpoint": "https://keycloak.example.io/realms/kubernetes/protocol/openid-connect/logout",
......
}
6、修改 kubernetes apiserver 配置,并重启apiserver
其中 --oidc-username-claim=username 和 --oidc-groups-claim=groups 和 步骤4中配置的 Mappers 对应
--oidc-ca-file=/etc/kubernetes/pki/ca.pem \
--oidc-issuer-url=https://keycloak.example.io/realms/kubernetes \
--oidc-client-id=apiserver \
--oidc-username-claim=username \
--oidc-username-prefix=- \
--oidc-groups-claim=groups \
7、kubectl 连接 kubernetes 集群
# 创建 devops namespace
kubectl create ns devops
# 给 devops 组授予 devops namespace 的管理权限
kubectl create rolebinding devops-admin --clusterrole=admin --group=devops --namespace devops
# 请求token样例
curl -X POST https://keycloak.example.io/realms/kubernetes/protocol/openid-connect/token \
--cacert /etc/kubernetes/pki/ca.pem \
-d grant_type=password -d client_id=apiserver \
-d username=yangxy -d password=changeme -d scope=openid
# 返回结果样例
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJYUmdsdFBOeVBxVUJlUk5aTThVUnZZZlZlX3h1bFFjcmNjajFKLUF0dXg4In0.eyJleHAiOjE2NzM1OTY4MzQsImlhdCI6MTY3MzU5NjUzNCwianRpIjoiN2M3ZDA1MTctNWIzNS00OThhLWE2MTAtODQ2NzdlNGZhMDhjIiwiaXNzIjoiaHR0cHM6Ly9rZXljbG9hay5leGFtcGxlLmlvL3JlYWxtcy9rdWJlcm5ldGVzIiwic3ViIjoiM2ZlZjFhNzUtMDJjMS00NGYxLThjOTYtZDUxZmMxOWFkOWVlIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoiYXBpc2VydmVyIiwic2Vzc2lvbl9zdGF0ZSI6IjZjYThlZDM0LTgwMzgtNDFkMi1iNTg4LTU1NTliNzY5OGNkMiIsImFjciI6IjEiLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsiZGV2b3BzIl19LCJzY29wZSI6Im9wZW5pZCBlbWFpbCBwcm9maWxlIiwic2lkIjoiNmNhOGVkMzQtODAzOC00MWQyLWI1ODgtNTU1OWI3Njk4Y2QyIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsIm5hbWUiOiJ5YW5nIHh5IiwiZ3JvdXBzIjpbImRldm9wcyJdLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJ5YW5neHkiLCJnaXZlbl9uYW1lIjoieWFuZyIsImZhbWlseV9uYW1lIjoieHkiLCJlbWFpbCI6Inlhbmd4eUAxNjMuY29tIiwidXNlcm5hbWUiOiJ5YW5neHkifQ.AKqRyAAcBeOAtufrat8JgG4fzGVBq9D-akvc3Ea2Lb_pZ3K1BQOo5_aXZN6jyJmCBrRjcA3oYoKCgilWOVt8vLxcPVT_bsFHCPcta-o5HZfspru91mlA3NgvvELKWylwn9B_QVWze8ggcbWZE1PSz2WxHxF5Nd1YuExZm09DHIp_2D_wipzpnK1n_leY97GTx8vafUVA_9uvfnAlBNsYzMzsLB3yT86LeRgAz8Ko9ReqIJPXjaSwBOQ-giDIUBIjN-MZXwBejYOIgawjFBTPxmLEN0vU_k25KRzkn1jpbdzd6FEkRM-jbme4VwnGHTw-1leH6nHnZ4I79Ph4a2nuCg",
"expires_in": 300,
"refresh_expires_in": 1800,
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJjZTBmNzllNi02OTFhLTQzYTQtYTVjNS02YzI3ZTY0ZjkxYjIifQ.eyJleHAiOjE2NzM1OTgzMzQsImlhdCI6MTY3MzU5NjUzNCwianRpIjoiNzA2ZjNlZDUtMmFlYS00OGMzLWIzZDktZDE2OGNjZGU1Zjg4IiwiaXNzIjoiaHR0cHM6Ly9rZXljbG9hay5leGFtcGxlLmlvL3JlYWxtcy9rdWJlcm5ldGVzIiwiYXVkIjoiaHR0cHM6Ly9rZXljbG9hay5leGFtcGxlLmlvL3JlYWxtcy9rdWJlcm5ldGVzIiwic3ViIjoiM2ZlZjFhNzUtMDJjMS00NGYxLThjOTYtZDUxZmMxOWFkOWVlIiwidHlwIjoiUmVmcmVzaCIsImF6cCI6ImFwaXNlcnZlciIsInNlc3Npb25fc3RhdGUiOiI2Y2E4ZWQzNC04MDM4LTQxZDItYjU4OC01NTU5Yjc2OThjZDIiLCJzY29wZSI6Im9wZW5pZCBlbWFpbCBwcm9maWxlIiwic2lkIjoiNmNhOGVkMzQtODAzOC00MWQyLWI1ODgtNTU1OWI3Njk4Y2QyIn0.bCdi42YkC6SW4zV8lb_p4ZYHMadC16ECceDd0b2E5rE",
"token_type": "Bearer",
"id_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJYUmdsdFBOeVBxVUJlUk5aTThVUnZZZlZlX3h1bFFjcmNjajFKLUF0dXg4In0.eyJleHAiOjE2NzM1OTY4MzQsImlhdCI6MTY3MzU5NjUzNCwiYXV0aF90aW1lIjowLCJqdGkiOiJmNzk1ZWU2Yy1lYWUzLTQyZTMtYTVmMi05Y2MxOWRhNTUxYWEiLCJpc3MiOiJodHRwczovL2tleWNsb2FrLmV4YW1wbGUuaW8vcmVhbG1zL2t1YmVybmV0ZXMiLCJhdWQiOiJhcGlzZXJ2ZXIiLCJzdWIiOiIzZmVmMWE3NS0wMmMxLTQ0ZjEtOGM5Ni1kNTFmYzE5YWQ5ZWUiLCJ0eXAiOiJJRCIsImF6cCI6ImFwaXNlcnZlciIsInNlc3Npb25fc3RhdGUiOiI2Y2E4ZWQzNC04MDM4LTQxZDItYjU4OC01NTU5Yjc2OThjZDIiLCJhdF9oYXNoIjoiMnM4eXpFaWRGUUlTa1JVWmt1Y2MxZyIsImFjciI6IjEiLCJzaWQiOiI2Y2E4ZWQzNC04MDM4LTQxZDItYjU4OC01NTU5Yjc2OThjZDIiLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwibmFtZSI6InlhbmcgeHkiLCJncm91cHMiOlsiZGV2b3BzIl0sInByZWZlcnJlZF91c2VybmFtZSI6Inlhbmd4eSIsImdpdmVuX25hbWUiOiJ5YW5nIiwiZmFtaWx5X25hbWUiOiJ4eSIsImVtYWlsIjoieWFuZ3h5QDE2My5jb20iLCJ1c2VybmFtZSI6Inlhbmd4eSJ9.FIpMPYKAp6UCevk0_q9MI2bdFoGVDwg3-AUJVqYh_nvY83uAjz035p1B-Dzl_Ku-JXN8yc_OqXIWfWvBboxAolIiBy2oWO2v7io4jh3rQ3LMFD5ZFbEmzgk7xf9M-Dm8TS23l-MBX7vuVGMJoGRbv5TyRIihIC_MSWhEJxwnYM1D8egphlkscn9Ztz8AoGFZ0HdPVb7yAymrlNW40wGhzD1cjLLdAOJpkvTWyHQ3WBQjj3hNHiC8064dL3DRP1R6YF57V14z6C0wsbJmcTdjxKjKBvkCSIUzw0yVh5TTTWns6caQdkX-iH5IQ4q4A1dLtDpKZBVwhm8OIqCtH0bJ6g",
"not-before-policy": 0,
"session_state": "6ca8ed34-8038-41d2-b588-5559b7698cd2",
"scope": "openid email profile"
}
将 id_token 粘贴到 https://jwt.io/ 可以解析出具体的 claim 内容
kubectl config set-cluster kubernetes \
--embed-certs=true \
--server="https://10.0.2.10:6443" \
--certificate-authority=/etc/kubernetes/pki/ca.pem
kubectl config set-credentials yangxy \
--auth-provider=oidc \
--auth-provider-arg=idp-issuer-url=https://keycloak.example.io/realms/kubernetes \
--auth-provider-arg=client-id=apiserver \
--auth-provider-arg=refresh-token=<refresh_token> \
--auth-provider-arg=id-token=<id_token> \
--auth-provider-arg=idp-certificate-authority=/etc/kubernetes/pki/ca.pem
kubectl config set-context kubernetes \
--user=yangxy \
--namespace=devops \
--cluster=kubernetes
kubectl config use-context kubernetes
参考连接
https://cloud.tencent.com/developer/article/1804656
https://www.keycloak.org/docs/latest/authorization_services/index.html
https://www.keycloak.org/docs/latest/server_admin/index.html
https://www.keycloak.org/docs/latest/securing_apps/index.html