转 https://blog.qikqiak.com/post/add-authorization-for-kubernetes-dashboard/
另外还可以参考这个 https://mritd.me/2018/03/20/use-rbac-to-control-kubectl-permissions/ , https://gi thub.com/kubernetes/dashboard/issues/1991 , https://jimmysong.io/posts/user-authentication-in-kubernetes/
前面我们在kubernetes仪表板升级之路一文中成功的将Dashboard
升级到最新版本了,增加了身份认证功能,之前为了方便增加了一个admin
用户,然后授予了cluster-admin
的角色绑定,而该角色绑定是系统内置的一个超级管理员权限,就是也。用该用户的token
登录Dashboard
后会很强势,什么权限都有,想干嘛干嘛,这样的操作显然是非常危险的。接下来我们来为一个新的用户添加访问权限控制。
角色
Role
表示是一组规则权限,只能累加,Role
可以定义在一个namespace
中,只能用于授予对单个命名空间中的资源访问的权限比如我们新建一个对默认命名空间中。Pods
具有访问权限的角色:
kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
resources: ["pods"]
verbs: ["get", "watch", "list"]
ClusterRole
ClusterRole
与具有Role
相同的权限角色控制能力,的不同的英文ClusterRole
的英文集群级别的,可以用于:
- 集群级别的资源控制(例如节点访问权限)
- 非资源型endpoints(例如/ healthz访问)
- 所有命名空间资源控制(例如pods)
比如我们要创建一个授权某个特定命名空间或全部命名空间(取决于绑定方式)访问秘密的集群角色:
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
# "namespace" omitted since ClusterRoles are not namespaced
name: secret-reader
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "watch", "list"]
RoleBinding和ClusterRoleBinding
RoloBinding
可以将角色中定义的权限授予用户或用户组,RoleBinding
包含一组权限列表(subjects
),权限列表中包含有不同形式的待授予权限资源类型(用户,群组,服务帐户),RoleBinding
适用于某个命名空间内授权,而ClusterRoleBinding
适用于集群范围内的授权。
我们比如默认将命名空间的pod-reader
角色授予用户简,以后这样用户该默认在命名空间中将具有pod-reader
的权限:
# This role binding allows "jane" to read pods in the "default" namespace.
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: read-pods
namespace: default
subjects:
- kind: User
name: jane
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
RoleBinding
同样可以引用ClusterRole
来对当前命名空间内用户,用户组或ServiceAccount进行授权,这种操作允许集群管理员在整个集群内定义一些通用的ClusterRole,然后在不同的命名空间中使用RoleBinding来引用
例如,以下RoleBinding引用了一个ClusterRole,这个ClusterRole具有整个集群内对秘密的访问权限;但是其授权用户dave只能访问开发空间中的秘密(因为RoleBinding定义在开发命名空间)
# This role binding allows "dave" to read secrets in the "development" namespace.
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: read-secrets
namespace: development # This only grants permissions within the "development" namespace.
subjects:
- kind: User
name: dave
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io
最后,使用ClusterRoleBinding可以对整个集群中的所有命名空间资源权限进行授权;以下ClusterRoleBinding样例展示了授权管理器组内所有用户在全部命名空间中对秘密进行访问
# This cluster role binding allows anyone in the "manager" group to read secrets in any namespace.
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: read-secrets-global
subjects:
- kind: Group
name: manager
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io
限制仪表板用户权限
有了上面的理论基础,我们就可以来新建一个用户,为该用户指定特定的访问权限了,比如我们的需求是:
- 新增一个新的用户
cnych
- 用户该对只能命名空间
kube-system
下面的pods
状语从句:deployments
进行管理
第一步新建一个ServiceAccount
:
$ kubectl create sa cnych -n kube-system
然后我们新建一个角色role-cnych:(role.yaml)
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: kube-system
name: role-cnych
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
- apiGroups: ["extensions", "apps"]
resources: ["deployments"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
上面注意的rules
规则:管理pods
状语从句:deployments
的权限。
然后我们创建一个角色绑定,上面将角色的role-cnych
绑定到cnych的ServiceAccount
上:(角色bind.yaml)
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: role-bind-cnych
namespace: kube-system
subjects:
- kind: ServiceAccount
name: cnych
namespace: kube-system
roleRef:
kind: Role
name: role-cnych
apiGroup: rbac.authorization.k8s.io
执行分别两个上面yaml
文件:
$ kubect create -f role.yaml
$ kubect create -f role-bind.yaml
接下来该怎么做和前面一样的,我们只需要拿到?cnych
这个ServiceAccount
的token
就可以登录Dashboard
了:
$ kubectl get secret -n kube-system |grep cnych
cnych-token-nxgqx kubernetes.io/service-account-token 3 47m
$ kubectl get secret cnych-token-nxgqx -o jsonpath={.data.token} -n kube-system |base64 -d
# 会生成一串很长的base64后的字符串
在然后dashboard
登录页面上直接使用上面得到的token
字符串即可登录,登录过后能看到下面的页面。
的英文这因为当前的这个token
对应的用户没有被授予访问默认命名空间的权限,所以会出现这种提示,我们然后访问kube-system
这个命名空间试下看看(https://开头<dashboard_url>!?/#/荚命名空间= KUBE-系统):
我们可以看到可以访问pod
列表了,但是也会有一些其他额外的提示:事件被禁止:用户“system:serviceaccount:kube-system:cnych”无法列出名称空间“kube-system”中的事件,这是因为登录当前只用被授权了访问pod
状语从句:deployment
的权限,同样的,下访问deployment
看看可以了吗?
同样的,你可以根据自己的需求来对访问用户的权限进行限制,自己可以通过Role
定义更加细粒度的权限,也可以使用系统内置的一些权限......
参考资料
为K8S集群建立只读权限帐号
参考URL:
https://www.jianshu.com/p/a1a0d64f1245
https://mritd.me/2018/03/20/use-rbac-to-control-kubectl-permissions/
https://studygolang.com/articles/11730?fr=sidebar
公司的k8s集群里的运维用户是为k8s的运维同事增加的。有的研发同事也需要登陆到k8s的master上,查看一些日志,或是了解一下k8s的运行信息。这里,我们就需要新增一个只读权限供研发同事操作。
要建立一个对k8s集群信息只读权限的帐户,重点就是限制用户运行kubectl命令的权限。用户运行kubectl命令时,默认是读取用户目录下的~/.kube/config文件,并将其中的认证信息与k8s集群的api server认证鉴权。之后,就会用提定的权限,与k8s的集群打交道了。
建立一个只读权限的帐号,分为如下三大步骤:
- 使用集群证书为指定用户生成集群认证信息(我们举例的k8s集群用户为xxx)。
- 使用认证信息,生成kube.config文件。
- 建立合适的cluster-role,并将此角色与前面的用户进行clouster-role-binding操作。
一,使用集群证书生成用户认证信息
1, 使用docker帐号登陆k8s集群的master机器。
2, 下载https://pkg.cfssl.org/下的软件放到机器的/tmp/目录。(cfssl,cfssljson)
本来下载的文件为:cfssl_linux-amd64,cfssljson_linux-amd64。最好更改为短名字(后面演示的名称为cfssl和cfssljson),并使用chmod +x 增加执行权限。
3, 将/etc/kubernetes/pki/目录下的ca.crt和ca.key文件cp到/tmp/目录。
cp /etc/kubernetes/pki/ca.crt /tmp/ca.crt
cp /etc/kubernetes/pki/ca.key /tmp/ca.key
4, 在/tmp/目录下生成ca-config.json文件,内容如下:
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"kubernetes": {
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
],
"expiry": "87600h"
}
}
}
}
5, 在/tmp/目录下生成xxx-csr.json文件,内容如下:
{
"CN": "xxx",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "ShangHai",
"L": "ShangHai",
"O": "k8s",
"OU": "System"
}
]
}
6, 运行如下命令,生成xxx.pem和xxx-key.pem文件。
./cfssl gencert -ca=./ca.crt -ca-key=./ca.key -config=./ca-config.json
-profile=kubernetes xxx-csr.json | ./cfssljson -bare xxx
二,使用认证信息,生成kube.config文件
1, 将/etc/kubernetes/目录下的admin.conf文件cp到/tmp/目录,并重命名。
cp /etc/kubernetes/admin.conf ./ro-user.kubeconfig
2, 运行如下xxx.sh脚本,生成最终的config文件。
3, 将config文件更名为config文件。
cp ro-user.kubeconfig config
4, 使用研发用户登陆,并将/tmp/config文件cp到~/.kube/目录下。
mkdir ~/.kube/
cp /tmp/config ~/.kube/
三,使用K8s的RBAC授权
1, 建立一个cluster-role-ro.yaml文件,生成只读资源。
以下文件,可以在导出集群管理员权限基础之上修改,命令为
kubectl get clusterrole admin -o yaml >cluster-role-ro.yaml
2, 建立cluster-rolebinding-ro.yaml文件,绑定用户和资源。
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: k8s-ro-cluster
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cro-readonly
subjects:
- kind: User
name: xxx
apiGroup: rbac.authorization.k8s.io
3, 在运维用户下,使用kubectl apply –f 命令将这两个yaml文件应用于集群。
4, 使用研发用户登陆,并进行命令测试。
比如,运行如下命令,显示OK。
kubectl --kubeconfig=/tmp/ro-user.kubeconfig get pod --all-namespaces -o wide
再比如,运行如下命令,显示无权限。
kubectl apply -f xxx-dep-svc.yaml
from server for: "xxx-dep-svc.yaml": deployments.extensions "xxx" is forbidden: User "xxx" cannot get deployments.extensions in the namespace "kube-system"
至此,K8S集群的只读权限帐号建立完成。
后期改进方向:
l 在统一的机器上制作,然后分发。
l 操作脚本化,加快工作效率。