简介
Service account 是为了方便 Pod 里面的进程调用 Kubernetes API 或其他外部服务而设计的。它与 User account 不同
- User account 是为人设计的,而 service account 则是为 Pod 中的进程调用 Kubernetes API 而设计;
- User account 是跨 namespace 的,而 service account 则是仅局限它所在的 namespace;
- 每个 namespace 都会自动创建一个 default service account
- Token controller 检测 service account 的创建,并为它们创建 secret
- 开启 ServiceAccount Admission Controller 后
- 每个 Pod 在创建后都会自动设置
spec.*serviceAccount*Name
为 default(除非指定了其他 ServiceAccout) - 验证 Pod 引用的 service account 已经存在,否则拒绝创建
- 如果 Pod 没有指定 ImagePullSecrets,则把 service account 的 ImagePullSecrets 加到 Pod 中
- 每个 container 启动后都会挂载该 service account 的 token 和
ca.crt
到/var/run/secrets/kubernetes.io/*serviceaccount*/
- 每个 Pod 在创建后都会自动设置
[root@k8s-master ~]# kubectl exec web-0 -it -- ls -l /var/run/secrets/kubernetes.io/serviceaccount/
total 0
lrwxrwxrwx 1 root root 13 Apr 1 08:34 ca.crt -> ..data/ca.crt
lrwxrwxrwx 1 root root 16 Apr 1 08:34 namespace -> ..data/namespace
lrwxrwxrwx 1 root root 12 Apr 1 08:34 token -> ..data/token
创建一个serviceaccount
[root@k8s-master ~]# kubectl create sa admin
serviceaccount/admin created
查看serviceaccount
[root@k8s-master ~]# kubectl get sa
NAME SECRETS AGE
admin 1 37s
default 1 25d
[root@k8s-master ~]# kubectl describe sa admin
Name: admin
Namespace: default
Labels:
Annotations:
Image pull secrets:
Mountable secrets: admin-token-vcjv6
Tokens: admin-token-vcjv6
Events:
创建一个serviceaccount会自动创建一个secret
[root@k8s-master ~]# kubectl get secret
NAME TYPE DATA AGE
admin-token-vcjv6 kubernetes.io/service-account-token 3 11m
RBAC
Kubernetes 从 1.6 开始支持基于角色的访问控制机制(Role-Based Access Control,RBAC),集群管理员可以对用户或服务账号的角色进行更精确的资源访问控制。在 RBAC 中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限。这就极大地简化了权限的管理。在一个组织中,角色是为了完成各种工作而创造,用户则依据它的责任和资格来被指派相应的角色,用户可以很容易地从一个角色被指派到另一个角色。
Kubernetes 1.6 中的一个亮点时 RBAC 访问控制机制升级到了 beta 版本(版本为 *rbac*.authorization.k8s.io/v1beta1
)。RBAC,基于角色的访问控制机制,是用来管理 kubernetes 集群中资源访问权限的机制。使用 RBAC 可以很方便的更新访问授权策略而不用重启集群。
从 Kubernetes 1.8 开始,RBAC 进入稳定版,其 API 为 *rbac*.authorization.k8s.io/v1
。
在使用 RBAC 时,只需要在启动 kube-apiserver 时配置 --authorization-mode=*RBAC*
即可。
RBAC VS ABAC
目前 kubernetes 中已经有一系列 l 鉴权机制。鉴权的作用是,决定一个用户是否有权使用 Kubernetes API 做某些事情。它除了会影响 kubectl 等组件之外,还会对一些运行在集群内部并对集群进行操作的软件产生作用,例如使用了 Kubernetes 插件的 Jenkins,或者是利用 Kubernetes API 进行软件部署的 Helm。ABAC 和 RBAC 都能够对访问策略进行配置。
ABAC(Attribute Based Access Control)本来是不错的概念,但是在 Kubernetes 中的实现比较难于管理和理解,而且需要对 Master 所在节点的 SSH 和文件系统权限,而且要使得对授权的变更成功生效,还需要重新启动 API Server。
而 RBAC 的授权策略可以利用 kubectl 或者 Kubernetes API 直接进行配置。RBAC 可以授权给用户,让用户有权进行授权管理,这样就可以无需接触节点,直接进行授权管理。RBAC 在 Kubernetes 中被映射为 API 资源和操作。
因为 Kubernetes 社区的投入和偏好,相对于 ABAC 而言,RBAC 是更好的选择。
创建私钥
[root@k8s-master pki]# cd /etc/kubernetes/pki/
[root@k8s-master ~]# (umask 077; openssl genrsa -out piaopiao.key 2048)
[root@k8s-master pki]# ll
total 60
-rw-r--r-- 1 root root 1269 Mar 10 14:55 apiserver.crt
-rw-r--r-- 1 root root 1135 Mar 10 14:55 apiserver-etcd-client.crt
-rw------- 1 root root 1679 Mar 10 14:55 apiserver-etcd-client.key
-rw------- 1 root root 1675 Mar 10 14:55 apiserver.key
-rw-r--r-- 1 root root 1143 Mar 10 14:55 apiserver-kubelet-client.crt
-rw------- 1 root root 1679 Mar 10 14:55 apiserver-kubelet-client.key
-rw-r--r-- 1 root root 1066 Mar 10 14:55 ca.crt
-rw------- 1 root root 1675 Mar 10 14:55 ca.key
drwxr-xr-x 2 root root 162 Mar 10 14:55 etcd
-rw-r--r-- 1 root root 1078 Mar 10 14:55 front-proxy-ca.crt
-rw------- 1 root root 1679 Mar 10 14:55 front-proxy-ca.key
-rw-r--r-- 1 root root 1103 Mar 10 14:55 front-proxy-client.crt
-rw------- 1 root root 1679 Mar 10 14:55 front-proxy-client.key
-rw------- 1 root root 1679 Apr 7 10:44 piaopiao.key
-rw------- 1 root root 1675 Mar 10 14:55 sa.key
-rw------- 1 root root 451 Mar 10 14:55 sa.pub
生成证书签署请求&签署证书
[root@k8s-master pki]# openssl req -new -key piaopiao.key -out piaopiao.csr -subj "/CN=xiaofang"
[root@k8s-master pki]# openssl x509 -req -in piaopiao.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out piaopiao.crt -days 365
创建k8s用户
[root@k8s-master pki]# kubectl config set-credentials xiaofang --client-certificate=./piaopiao.crt --client-key=./piaopiao.key --embed-certs=true
添加用户到集群
[root@k8s-master pki]# kubectl config set-context xiaofang@kubernetes --cluster=kubernetes --user=xiaofang
[root@k8s-master pki]# kubectl config view
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://10.0.0.11:6443
name: kubernetes
contexts:
- context:
cluster: kubernetes
user: kubernetes-admin
name: kubernetes-admin@kubernetes
- context:
cluster: kubernetes
user: xiaofang
name: xiaofang@kubernetes
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
users:
- name: kubernetes-admin
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
- name: xiaofang
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
Role & ClusterRole RoleBinding & ClusterRoleBinding
Role(角色)是一系列权限的集合,例如一个角色可以包含读取 Pod 的权限和列出 Pod 的权限。Role 只能用来给某个特定 namespace 中的资源作鉴权,对多 namespace 和集群级的资源或者是非资源类的 API(如 /healthz)使用 ClusterRole。
RBAC 的 Role 或 ClusterRole 中包含一组代表相关权限的规则。 这些权限是纯粹累加的(不存在拒绝某操作的规则)。
Role 总是用来在某个名字空间 内设置访问权限;在你创建 Role 时,你必须指定该 Role 所属的名字空间。
与之相对,ClusterRole 则是一个集群作用域的资源。这两种资源的名字不同(Role 和 ClusterRole)是因为 Kubernetes 对象要么是名字空间作用域的,要么是集群作用域的, 不可两者兼具。
ClusterRole 有若干用法。你可以用它来:
- 定义对某名字空间域对象的访问权限,并将在各个名字空间内完成授权;
- 为名字空间作用域的对象设置访问权限,并跨所有名字空间执行授权;
- 为集群作用域的资源定义访问权限。
如果你希望在名字空间内定义角色,应该使用 Role; 如果你希望定义集群范围的角色,应该使用 ClusterRole。
1,Role
一个Role内类型的角色只能访问他所在的namesoace下的资源
创建一个role
1,使用kubectl create创建
[root@k8s-master ~]# kubectl create role app-role --verb=get,list,create,delete --resource=pods
2,使用yaml创建
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
creationTimestamp: null
name: app-role
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- list
- create
- delete
查看role
[root@k8s-master ~]# kubectl describe role app-role
Name: app-role
Labels:
Annotations:
PolicyRule:
Resources Non-Resource URLs Resource Names Verbs
--------- ----------------- -------------- -----
pods [] [] [get list create delete]
使用Rolebinding绑定role
命令创建
[root@k8s-master ~]# kubectl create rolebinding app-rolebinding --role=app-role --user=xiaofang
使用yaml创建
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: app-rolebinding
namespace: default
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: app-role
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: xiaofang
查看rolebinding
[root@k8s-master ~]# kubectl describe rolebindings.rbac.authorization.k8s.io app-rolebinding
Name: app-rolebinding
Labels:
Annotations:
Role:
Kind: Role
Name: app-role
Subjects:
Kind Name Namespace
---- ---- ---------
User xiaofang
验证
[root@k8s-master ~]# kubectl config use-context xiaofang@kubernetes
Switched to context "xiaofang@kubernetes".
[root@k8s-master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
web-0 0/1 Terminating 0 5d23h
web-2 0/1 Terminating 0 5d23h
web-4 0/1 Terminating 0 5d23h
[root@k8s-master ~]# kubectl get pods -n kube-system
Error from server (Forbidden): pods is forbidden: User "xiaofang" cannot list resource "pods" in API group "" in the namespace "kube-system"
#这里切换用户后,查看default的名称空间的pod是可以的而查看其他的namespace中是没有权限的
2,clusterrole
创建clusterrole时不能使用名称空间,因为clusterrole属于集群级别资源
创建一个clusterrole
1,命令创建
[root@k8s-master ~]# kubectl create clusterrole app-clusterrole --verb=get,list,watch,create,delete --resource=pods
2,yaml创建
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: app-clusterrole
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- list
- watch
- create
- delete
查看clusterrole
[root@k8s-master ~]# kubectl describe clusterrole app-clusterrole
Name: app-clusterrole
Labels:
Annotations:
PolicyRule:
Resources Non-Resource URLs Resource Names Verbs
--------- ----------------- -------------- -----
pods [] [] [get list watch create delete]
使用clusterrolebinding绑定
命令创建
[root@k8s-master ~]# kubectl create clusterrolebinding app-clusterrolebinding --clusterrole=app-clusterrole --user=xiaofang
yaml创建
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
creationTimestamp: null
name: app-clusterrolebinding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: app-clusterrole
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: xiaofang
查看clusterrolebinding
[root@k8s-master ~]# kubectl get clusterrolebindings.rbac.authorization.k8s.io app-clusterrolebinding
NAME ROLE AGE
app-clusterrolebinding ClusterRole/app-clusterrole 113s
[root@k8s-master ~]# kubectl describe clusterrolebindings.rbac.authorization.k8s.io app-clusterrolebinding
Name: app-clusterrolebinding
Labels:
Annotations:
Role:
Kind: ClusterRole
Name: app-clusterrole
Subjects:
Kind Name Namespace
---- ---- ---------
User xiaofang
切换用户验证
[root@k8s-master ~]# kubectl config use-context xiaofang@kubernetes
Switched to context "xiaofang@kubernetes".
[root@k8s-master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
web-0 0/1 Terminating 0 6d
web-2 0/1 Terminating 0 6d
web-4 0/1 Terminating 0 6d
[root@k8s-master ~]# kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-6d56c8448f-htht4 1/1 Running 4 28d
coredns-6d56c8448f-m78cl 1/1 Running 4 28d
etcd-k8s-master 1/1 Running 4 28d
kube-apiserver-k8s-master 1/1 Running 8 28d
kube-controller-manager-k8s-master 1/1 Running 28 28d
kube-flannel-ds-kvzz6 1/1 Running 4 28d
kube-flannel-ds-rwlhk 1/1 Running 8 28d
kube-flannel-ds-x6hdm 1/1 Running 15 28d
kube-proxy-7g68v 1/1 Running 10 28d
kube-proxy-9zxx6 1/1 Running 7 28d
kube-proxy-mnqql 1/1 Running 4 28d
kube-scheduler-k8s-master 1/1 Running 24 28d
#验证现实可以查看其他namespace中的pods,clusterrolebinding不限制在单个的namespace中,是授权在整个集群范围类
使用Rolebinding绑定ClusterRole
使用Rolebinding绑定ClusterRole这种方式会让clusterrole的权限降级,绑定后clusterrole只能对rolebinding的namespace中的资源进行操作,
使用命令创建
[root@k8s-master ~]# kubectl create rolebinding rolebinding-cluster --clusterrole=app-clusterrole --user=xiaofang
使用yaml创建
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
creationTimestamp: null
name: rolebinding-cluster
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: app-clusterrole
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: xiaofang
查看rolebinding
[root@k8s-master ~]# kubectl describe rolebindings.rbac.authorization.k8s.io rolebinding-cluster
Name: rolebinding-cluster
Labels:
Annotations:
Role:
Kind: ClusterRole
Name: app-clusterrole
Subjects:
Kind Name Namespace
---- ---- ---------
User xiaofang
切换用户验证
[root@k8s-master ~]# kubectl config use-context xiaofang@kubernetes
Switched to context "xiaofang@kubernetes".
[root@k8s-master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
web-0 0/1 Terminating 0 6d1h
web-2 0/1 Terminating 0 6d1h
web-4 0/1 Terminating 0 6d1h
[root@k8s-master ~]# kubectl get pods -n kube-system
Error from server (Forbidden): pods is forbidden: User "xiaofang" cannot list resource "pods" in API group "" in the namespace "kube-system",
ps:
如果集群中有多个namespace分配给不同的管理员,但是他们的权限是一样的,那么这样可以先定义一个ClusterRole,然后通过RoleBinding将不同namespace的管理员做绑定,这样可以解决多次定义Role的问题。