Kubernetes 没有用户以及用户组
Kubernetes 的 RBAC 模型授权对象(Subject)是用户(User)或者用户组(Group),即使ServiceAccount 也会当作为一个虚拟 User。
通过 Kubernetes 找不到真正的用户以及用户组信息,甚至连对应的 User Resource 以及 Group Resource 都没有,所以有时候在写 rolebingding 的时候会觉得很奇怪,Subjects 需要填 User 或者Group,可是 Kubernetes 却没有办法列出可信任的 User 列表以及 Group 列表。
换句话说 Kubernetes 并没有提供用户管理和身份认证功能,除了 Service Account 外,所有的用户信息都依赖外部的用户管理系统来存储,因此通过 api-serever 根本无法列出 User 和 Group。
这样做的好处也显而易见,用户账户信息与 Kubernetes 集群松耦合,便于集成企业已有的身份认证系统,如 AD、LADP、Keycloak 等。
前置条件
《Docker 安装 Keycloak,配置 SSL/TLS》
《Kubernetes 安装 Keycloak 以及配置SSL》
Keycloak 认证信息配置
登录keycloak管理页面创建一个realm以及client,名称都为int32bit-kubernetes。其中realm类似namespace概念,实现了多租户模型,client对应一个认证主体,所有使用keycloak认证的都需要创建一个对应的client。
创建 realm 和 client
配置 secret
每个 client 会对应有一个 secret,这二者关系就是 access key 和 access secret 关系
创建 Role 和 User
打开 Keycloak Web 管理界面
- 在 Roles 中创建两个 role 分别为
int32bit-kubernetes-cluster-admin、int32bit-kubernetes-readonly。

- 在 Users 中创建两个用户
k8s-admin、k8s-readonlly。

k8s-admin关联int32bit-kubernetes-cluster-adminrole,k8s-readonlly关联int32bit-kubernetes-readonlyrole。


- 为了支持 Kubernetes 的 Group 认证,需要在 client 中添加 mappers 字段 groups
这里之所以映射 User Realm Role,而不是 Group MemberShip,是因为 Group 会在 id_token 中添加前缀 /,如 /test-group1, /test-group2,这个暂时没想到怎么处理,或许有更好的办法。 更新:《Keycloak User Groups 实现 K8s RBAC》
设置 User Password
获取 Token
curl -sSLk \-d "client_id=int32bit-kubernetes" \-d "client_secret=5ef28ad1-5ed5-4227-99ca-4ac13390edc6" \-d "response_type=code token" \-d "grant_type=password" \-d "username=k8s-admin" \-d "password=k8s-admin" \-d "scope=openid" \https://192.168.56.10:8443/auth/realms/int32bit-kubernetes/protocol/openid-connect/token

其中返回的 id_token,在后面 Kubernetes 对接中非常重要,它也是一个 JWT Token,解码后的内容如下:
你可以打开 https://jwt.io,对 id_token 进行解码
其中,JWT Token 包含了 Groups 信息
"groups": [
"int32bit-kubernetes-cluster-admin"
],
{
"exp": 1636781925,
"iat": 1636781625,
"auth_time": 0,
"jti": "7d1825d9-d28f-479c-9931-cf7ad12aaf7e",
"iss": "https://192.168.56.10:8443/auth/realms/int32bit-kubernetes",
"aud": "int32bit-kubernetes",
"sub": "2bffc6a7-1b0b-493c-b29b-cf55f7b922f8",
"typ": "ID",
"azp": "int32bit-kubernetes",
"session_state": "52aaabff-4bdc-4157-b387-0f72ce624b62",
"at_hash": "J4608t81sDbP3A3tWpk3BA",
"acr": "1",
"sid": "52aaabff-4bdc-4157-b387-0f72ce624b62",
"email_verified": false,
"groups": [
"int32bit-kubernetes-cluster-admin"
],
"preferred_username": "k8s-admin"
}
Kubernetes 集成 keycloak 认证
在 api-server 中增加如下命令行启动参数
注意:
--oidc-issuer-url需要使用 https 协议
- --oidc-issuer-url=https://192.168.56.10:8443/auth/realms/int32bit-kubernetes
- --oidc-client-id=int32bit-kubernetes
- --oidc-username-claim=preferred_username
- --oidc-username-prefix=-
- --oidc-groups-claim=groups
- --oidc-ca-file=/etc/kubernetes/pki/keycloak.crt
相对应的在 Kubernetes 创建两个 clusterrolebinging
cluster-admin
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
labels:
kubernetes.io/bootstrapping: rbac-defaults
name: cluster-admin
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: system:masters
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: int32bit-kubernetes-cluster-admin
cluster-readonly
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
labels:
kubernetes.io/bootstrapping: rbac-defaults
name: cluster-readonly
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: view
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: int32bit-kubernetes-readonly
使用 OpenId Connect 认证
生成config文件:
kubectl config set-credentials oidc \
--auth-provider=oidc \
--auth-provider-arg=idp-issuer-url=https://192.168.56.10:8443/auth/realms/int32bit-kubernetes \
--auth-provider-arg=client-id=int32bit-kubernetes \
--auth-provider-arg=client-secret=5ef28ad1-5ed5-4227-99ca-4ac13390edc6
为了便于登录,下载 kube-login插件
kubectl krew install oidc-login
如果你没有安装 kubectl krew:《Install kubectl krew》
切换到 oidc 用户
kubectl config set-context --current --user=oidc
此时可以直接通过如下命令进行登录
kubectl oidc-login --username username --password password
你可能会遇到一个错误,这是自签证书的原因
[root@master kubernetes]# kubectl oidc-login --username k8s-admin --password k8s-admin
NOTE: You can use the credential plugin mode for better user experience.
Kubectl automatically runs kubelogin and you do not need to run kubelogin explicitly.
See https://github.com/int128/kubelogin for more.
error: login: authentication error: oidc error: oidc discovery error: Get "https://192.168.56.10:8443/auth/realms/int32bit-kubernetes/.well-known/openid-configuration": x509: certificate signed by unknown authority
使用 --insecure-skip-tls-verify=true 跳过验证
kubectl oidc-login --username k8s-admin --password k8s-admin --insecure-skip-tls-verify=true


