Kubernetes-16:一文详解ServiceAccount及RBAC权限控制
一、ServiceAccount
1.ServiceAccount 介绍
首先Kubernetes中账户区分为:User Accounts(用户账户) 和 Service Accounts(服务账户) 两种,它们的设计及用途如下:
UserAccount是给kubernetes集群外部用户使用的,例如运维或者集群管理人员,使用kubectl命令时用的就是UserAccount账户;UserAccount是全局性。在集群所有namespaces中,名称具有唯一性,默认情况下用户为admin;
用户名称可以在kubeconfig中查看
[root@Centos8 ~]# cd ~/.kube/
[root@Centos8 .kube]# ls
cache config http-cache
[root@Centos8 .kube]# cat config
users:
- name: kubernetes-admin
- ServiceAccount是给运行在Pod的程序使用的身份认证,Pod容器的进程需要访问API Server时用的就是ServiceAccount账户;ServiceAccount仅局限它所在的namespace,每个namespace都会自动创建一个default service account;创建Pod时,如果没有指定Service Account,Pod则会使用default Service Account。
2.Secret 与 SA 的关系
Kubernetes设计了一种Secret资源,分为两类,一种是用于 ServiceAccount 的 kubernetes.io/ service-account-token,就是上边说的 SA,另一种就是用户自定义的保密信息Opaque。
3.默认的Service Account
ServiceAccount仅局限它所在的namespace,所以在创建namespace时会自动创建一个默认的 SA,而 SA 创建时,也会创建对应的 Secret,下面操作验证下:
创建名称空间
[root@Centos8 .kube]# kubectl create ns vfan
namespace/vfan created
查看SA
[root@Centos8 .kube]# kubectl get sa -n vfan
NAME SECRETS AGE
default 67s
查看 SA 的 Secret
[root@Centos8 .kube]# kubectl describe sa default -n vfan
Name: default
Namespace: vfan
Labels: <none>
Annotations: <none>
Image pull secrets: <none>
Mountable secrets: default-token-wwbc8
Tokens: default-token-wwbc8
Events: <none> [root@Centos8 ~]# kubectl get secret -n vfan
NAME TYPE DATA AGE
default-token-wwbc8 kubernetes.io/service-account-token 3m15s
可以看到,创建ns时默认创建了SA,SA默认创建了一个 kubernetes.io/service-account-token类型的secret
创建一个Pod
vim pods.yaml
apiVersion: v1
kind: Pod
metadata:
name: test-sa
namespace: vfan
spec:
containers:
- name: test-sa
image: nginx:1.2.
imagePullPolicy: IfNotPresent
ports:
- containerPort:
[root@Centos8 rbac]# kubectl create -f pods.yaml
pod/test-sa created [root@Centos8 rbac]# kubectl get pod -n vfan
NAME READY STATUS RESTARTS AGE
test-sa / Running 12s [root@Centos8 rbac]# kubectl describe pod test-sa -n vfan
...
Containers:
test-sa:
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-wwbc8 (ro)
Volumes:
default-token-wwbc8:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-wwbc8
Optional: false
...
在不指定SA的情况下,当前 ns下面的 Pod 会默认使用 “default” 这个 SA,对应的 Secret 会自动挂载到 Pod 的 /var/run/secrets/kubernetes.io/serviceaccount/ 目录中,我们可以在 Pod 里面获取到用于身份认证的信息。
进入Pod Container内,查看 SA
[root@Centos8 rbac]# kubectl exec -it test-sa -n vfan -- /bin/bash
root@test-sa:/# cd /var/run/secrets/kubernetes.io/serviceaccount/
root@test-sa:/var/run/secrets/kubernetes.io/serviceaccount# ls
ca.crt namespace token ### 可以看到有三个文件,作用分别为
ca.crt:根证书,用于Client端验证API Server发送的证书
namespace:标识这个service-account-token的作用域空间
token:使用API Server私钥签名的JWT,用于访问API Server时,Server端的验证
4.使用自定义SA
创建一个 SA
[root@Centos8 rbac]# kubectl create sa vfansa -n vfan
serviceaccount/vfansa created [root@Centos8 rbac]# kubectl get sa -n vfan
NAME SECRETS AGE
default 19m
vfansa 7s [root@Centos8 rbac]# kubectl describe sa vfansa -n vfan
Name: vfansa
Namespace: vfan
Labels: <none>
Annotations: <none>
Image pull secrets: <none>
Mountable secrets: vfansa-token-9s8f7
Tokens: vfansa-token-9s8f7
Events: <none> [root@Centos8 rbac]# kubectl get secret -n vfan
NAME TYPE DATA AGE
default-token-wwbc8 kubernetes.io/service-account-token 19m
vfansa-token-9s8f7 kubernetes.io/service-account-token 49s
同样,创建SA后,自动创建了对应的Secret
更新Pod,使用新创建的SA
vim pods.yaml
apiVersion: v1
kind: Pod
metadata:
name: test-sa
namespace: vfan
spec:
containers:
- name: test-sa
image: nginx:1.2.
imagePullPolicy: IfNotPresent
ports:
- containerPort:
serviceAccountName: vfansa
[root@Centos8 rbac]# kubectl create -f pods.yaml
pod/test-sa created [root@Centos8 rbac]# kubectl describe pod test-sa -n vfan
...
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from vfansa-token-9s8f7 (ro)
Volumes:
vfansa-token-9s8f7:
Type: Secret (a volume populated by a Secret)
SecretName: vfansa-token-9s8f7
Optional: false
...
5.ServiceAccount中添加Image pull secrets
在笔者之前的博客中:Secret介绍及演示( https://www.cnblogs.com/v-fan/p/13269433.html )中提及到,可以使用Secret来保存镜像仓库的登录信息,来达到免登录获取image的效果,同样,可以将创建好的Secret直接与SA进行绑定,绑定完成后,只要使用此 SA 的 Pod,都可达到免登录获取image的效果
创建 docker-registry 的 Secret
[root@Centos8 rbac]# kubectl create secret docker-registry myregistrykey --docker-server=hub.vfancloud.com --docker-username=admin --docker-password=admin@ --docker-email=vfan8991@.com -n vfan
secret/myregistrykey created [root@Centos8 rbac]# kubectl get secret -n vfan
NAME TYPE DATA AGE
default-token-wwbc8 kubernetes.io/service-account-token 62m
myregistrykey kubernetes.io/dockerconfigjson 7s
vfansa-token-9s8f7 kubernetes.io/service-account-token 43m
将 docker-registry 的 Secret 添加到SA
kubectl edit sa vfansa -n vfan
apiVersion: v1
kind: ServiceAccount
metadata:
creationTimestamp: "2020-08-30T03:38:47Z"
name: vfansa
namespace: vfan
resourceVersion: ""
selfLink: /api/v1/namespaces/vfan/serviceaccounts/vfansa
uid: 8a44df93-b2d6-4e61-ad2e-25bc5852f66e
secrets:
- name: vfansa-token-9s8f7
imagePullSecrets:
- name: myregistrykey
查看 SA 的 Image pull secrets
[root@Centos8 rbac]# kubectl describe sa vfansa -n vfan
Name: vfansa
Namespace: vfan
Labels: <none>
Annotations: <none>
Image pull secrets: myregistrykey
Mountable secrets: vfansa-token-9s8f7
Tokens: vfansa-token-9s8f7
Events: <none>
这个时候,只要是使用此 SA 的Pod,都可以在docker-registry拉取镜像了,同样,可以把此 Secret 添加到default 的 SA 中,达到相同的效果
二、RBAC权限控制
1.RBAC介绍
在Kubernetes中,所有资源对象都是通过API对象进行操作,他们保存在etcd里。而对etcd的操作我们需要通过访问 kube-apiserver 来实现,上面的Service Account其实就是APIServer的认证过程,而授权的机制是通过RBAC:基于角色的访问控制实现。
2.Role and ClusterRole
在RBAC API中,Role表示一组规则权限,权限只会增加(累加权限),不存在一个资源开始就有很多权限而通过RBAC对其进行减少的操作:Role 是定义在一个 namespace 中,而 ClusterRole 是集群级别的。
下面我们定义一个Role:
vim roles.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: test-role
namespace: vfan
rules:
- apiGroups: [""] # 为空表示为默认的core api group
resources: ["pods"] # 数据源类型
verbs: ["get","watch","list"] #赋予的权限
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get","list","create","update","patch","delete","watch"]
以上Role策略表示在名字为 vfan ns中,对Pods有get,watch,list的权限,对Deployment有......权限
ClusterRole 具有与 Role 相同权限角色控制能力,不同的就是 Cluster Role是集群级别,它可以用于:
- 集群级别的资源控制(例如 node 访问权限)
- 非资源型 endpoints(例如对某个目录或文件的访问:/healthz)
- 所有命名空间资源控制(Pod、Deployment等)
vim clusterroles.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: test-clusterrole
rules:
- apiGroups: [""]
resources: ["services"]
verbs: ["get","create","list"]
以上Cluster role策略表示,有get,create,list整个集群service的权限
下面开始创建
## role
[root@Centos8 rbac]# kubectl create -f roles.yaml
role.rbac.authorization.k8s.io/test-rbac created [root@Centos8 rbac]# kubectl get role -n vfan
NAME AGE
test-rbac 27s ## cluster role
[root@Centos8 rbac]# kubectl get clusterrole -n vfan
NAME AGE
admin 141d
cluster-admin 141d
edit 141d
flannel 141d
ingress-nginx 90d
ingress-nginx-admission 90d
system:aggregate-to-admin 141d
system:aggregate-to-edit 141d
system:aggregate-to-view 141d
可以看到,role和cluster role都已经创建成功,但是clusterrole除了这次创建的还有许多,其中以system开头的全部是系统所用的,其他的都是在装一些插件时自动添加的,也要注意,我们自己创建cluster role时不要以system开通,以免分不清楚
3.RoleBinding and ClusterRoleBinding
RoleBinding可以将角色中定义的权限授予用户或用户组,RoleBinding包含一组权限列表(Subjects),权限列表中包含有不同形式的待授予权限资源类型(users,groups, or Service Account):Rolebinding 同样包含对被 Bind 的 Role 引用;RoleBinding 适用于某个命名空间内授权,ClusterRoleBinding适用于集群范围内的授权。
创建RoleBinding
vim rolebindings.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: test-rolebinding
namespace: vfan
subjects:
- kind: User # 权限资源类型
name: vfan # 名称
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role #要绑定的Role的类型(可以是Role或ClusterRole)
name: test-role # Role的名称
apiGroup: rbac.authorization.k8s.io
此策略表示,将名称为test-role的Role的权限资源赋予名为vfan的用户,仅作用于vfan namespace。
RoleBinding同样可以引用ClusterRole来对当前 namespace 内用户、用户组或SA来进行授权,这种操作允许管理员在整个集群中定义一些通用的ClusterRole,然后在不同的namespace中使用RoleBinding绑定。
vim rolebindings2.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: test-rolebinding2
namespace: vfan
subjects:
- kind: User
name: vfan
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: test-clusterrole
apiGroup: rbac.authorization.k8s.io
以上策略表示,将名称为test-clusterrole的ClusterRole的资源权限赋予给了名称为vfan的用户,虽然赋予的是ClusterRole,但是由于Role仅作用于单个namespace,所以此资源策略仅仅对vfan namespace有效
vim clusterrolebindings.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: test-clusterrolebinding
subjects:
- kind: Group
name: vfan
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: test-clusterrole
apiGroup: rbac.authorization.k8s.io
以上策略表示,将name为test-clusterrole的ClusterRole的资源权限赋予给groupname为vfan的用户组,此用户组下所有用户拥有对整个集群的 test-clusterrole内的资源权限
实践:创建一个用户只能管理名为 vfan 的NameSpace
1.创建系统用户
[root@Centos8 rbac]# useradd vfan
[root@Centos8 rbac]# su - vfan ## 进入vfan用户测试访问k8s集群
[vfan@Centos8 ~]$ kubectl get pod
The connection to the server localhost: was refused - did you specify the right host or port?
默认肯定是访问不到的,如果想要访问,必须要创建vfan用户的访问证书
2.为 vfan 用户创建访问证书
## 下载证书生成工具 cfssl
[root@Centos8 bin]# wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
[root@Centos8 bin]# wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
[root@Centos8 bin]# wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 ## 改名,给执行权限
[root@Centos8 bin]# mv cfssl_linux-amd64 cfssl
[root@Centos8 bin]# mv cfssljson_linux-amd64 cfssljson
[root@Centos8 bin]# mv cfssl-certinfo_linux-amd64 cfssl-certinfo
[root@Centos8 bin]# chmod +x *
[root@Centos8 bin]# ll -h
总用量 19M
-rwxr-xr-x root root 9.9M 3月 cfssl
-rwxr-xr-x root root 6.3M 3月 cfssl-certinfo
-rwxr-xr-x root root 2.2M 3月 cfssljson
[root@Centos8 bin]# mkdir /usr/local/vfancert
[root@Centos8 bin]# cd /usr/local/vfancert/
创建CA证书签名请求JSON文件
vim vfan-csr.json
{
"CN": "vfan", # 用户名称
"hosts": [], # 主机地址,不填表示所有主机都可使用
"key": {
"algo": "rsa", # 加密算法
"size":
},
"names": [
{
"C": "CN",
"L": "BeiJing",
"O": "Ctyun",
"ST": "BeiJing",
"OU": "System"
}
]
}
开始创建访问证书
[root@Centos8 vfancert]# cd /etc/kubernetes/pki/
[root@Centos8 pki]# cfssl gencert -ca=ca.crt -ca-key=ca.key -profile=kubernetes /usr/local/vfancert/vfan-csr.json | cfssljson -bare vfanuser
// :: [INFO] generate received request
// :: [INFO] received CSR
// :: [INFO] generating key: rsa-
// :: [INFO] encoded CSR
// :: [INFO] signed certificate with serial number
// :: [WARNING] This certificate lacks a "hosts" field. This makes it unsuitable for
websites. For more information see the Baseline Requirements for the Issuance and Management
of Publicly-Trusted Certificates, v.1.1., from the CA/Browser Forum (https://cabforum.org);
specifically, section 10.2. ("Information Requirements"). ## 创建成功,pki目录下多出vfanuser-key.pem、vfanuser.pem和vfanuser.csr文件
[root@Centos8 pki]# ls
vfanuser.csr
vfanuser-key.pem
vfanuser.pem
3.为 vfan 用户生成集群配置文件
## 设置api server的环境变量
[root@Centos8 vfancert]# export KUBE_APISERVER="https://192.168.152.53:6443" ## 创建kubeconfig文件,以下详细参数信息可通过kubectl config set-cluster --help查看
[root@Centos8 vfancert]# kubectl config set-cluster kubernetes --certificate-authority=/etc/kubernetes/pki/ca.crt --embed-certs=true --server=${KUBE_APISERVER} --kubeconfig=vfan.kubeconfig
Cluster "kubernetes" set. ## 配置文件生成
[root@Centos8 vfancert]# ls
vfan-csr.json vfan.kubeconfig ## 设置客户端参数,绑定用户信息至kubeconfig中
[root@Centos8 vfancert]# kubectl config set-credentials vfanuser \
> --client-certificate=/etc/kubernetes/pki/vfanuser.pem \
> --client-key=/etc/kubernetes/pki/vfanuser-key.pem \
> --embed-certs=true \
> --kubeconfig=vfan.kubeconfig
User "vfanuser" set. ## 设置上下文参数
[root@Centos8 vfancert]# kubectl config set-context kubernetes \
> --cluster=kubernetes \
> --user=vfan \
> --namespace=vfan \
> --kubeconfig=vfan.kubeconfig
Context "kubenetes" created.
4.进行RoleBinding 验证权限生效
vim vfanrolebind.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: test-rolebinding
namespace: vfan
subjects:
- kind: User
name: vfan
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: test-rbac # 绑定上文中创建的名称为 test-rbac 的Role,具体权限,往上翻下哈
apiGroup: rbac.authorization.k8s.io
把kubeconfig文件复制到 vfan 用户的家目录的.kube下
[root@Centos8 vfancert]# mkdir -p /home/vfan/.kube
[root@Centos8 vfancert]# cp vfan.kubeconfig /home/vfan/.kube/config
[root@Centos8 vfancert]# cd /home/vfan/.kube/
[root@Centos8 .kube]# ls
config ## 修改文件所有者
[root@Centos8 vfan]# chown -R vfan:vfan .kube/
切换上下文,使kubectl读取到config的信息
[vfan@Centos8 .kube]$ kubectl config use-context kubernetes --kubeconfig=config
Switched to context "kubernetes".
开始测试权限
[vfan@Centos8 .kube]$ kubectl get pod
No resources found. [vfan@Centos8 .kube]$ kubectl get svc
Error from server (Forbidden): services is forbidden: User "vfan" cannot list resource "services" in API group "" in the namespace "vfan"
可以get pod,但是不可以get service,因为之前的Role中明确的表示了自己的权限
在vfan名称空间下创建测试Deployment
## root用户下创建
[root@Centos8 k8sYaml]# kubectl run deployment test-vfan --replicas= --image=nginx:1.2. --namespace=vfan [root@Centos8 k8sYaml]# kubectl get pod -n vfan
NAME READY STATUS RESTARTS AGE
deployment-7b89b946d-5dtvp / Running 17s
deployment-7b89b946d-jpr5v / Running 17s
deployment-7b89b946d-r8k4l / Running 17s ## 前往vfan用户查看
[vfan@Centos8 .kube]$ kubectl get pod
NAME READY STATUS RESTARTS AGE
deployment-7b89b946d-5dtvp / Running 67s
deployment-7b89b946d-jpr5v / Running 67s
deployment-7b89b946d-r8k4l / Running 67s
可以看到,vfan用户也可以查看到相对应的Pod,因为vfan用户在get pod时并没有指定名称空间,所以可以证明vfan的默认名称空间即是vfan
Kubernetes-16:一文详解ServiceAccount及RBAC权限控制的更多相关文章
- 图文详解基于角色的权限控制模型RBAC
我们开发一个系统,必然面临权限控制的问题,即不同的用户具有不同的访问.操作.数据权限.形成理论的权限控制模型有:自主访问控制(DAC: Discretionary Access Control).强制 ...
- Docker Kubernetes 服务发现原理详解
Docker Kubernetes 服务发现原理详解 服务发现支持Service环境变量和DNS两种模式: 一.环境变量 (默认) 当一个Pod运行到Node,kubelet会为每个容器添加一组环境 ...
- 一文详解Hexo+Github小白建站
作者:玩世不恭的Coder时间:2020-03-08说明:本文为原创文章,未经允许不可转载,转载前请联系作者 一文详解Hexo+Github小白建站 前言 GitHub是一个面向开源及私有软件项目的托 ...
- 第7.16节 案例详解:Python中classmethod定义的类方法
第7.16节 案例详解:Python中classmethod定义的类方法 上节介绍了类方法定义的语法以及各种使用的场景,本节结合上节的知识具体举例说明相关内容. 一. 案例说明 本节定义的一个 ...
- 一文详解 Linux 系统常用监控工一文详解 Linux 系统常用监控工具(top,htop,iotop,iftop)具(top,htop,iotop,iftop)
一文详解 Linux 系统常用监控工具(top,htop,iotop,iftop) 概 述 本文主要记录一下 Linux 系统上一些常用的系统监控工具,非常好用.正所谓磨刀不误砍柴工,花点时间 ...
- 第三节:带你详解Java的操作符,控制流程以及数组
前言 大家好,给大家带来带你详解Java的操作符,控制流程以及数组的概述,希望你们喜欢 操作符 算数操作符 一般的 +,-,*,/,还有两个自增 自减 ,以及一个取模 % 操作符. 这里的操作算法,一 ...
- Solon详解(九)- 渲染控制之定制统一的接口输出
Solon详解系列文章: Solon详解(一)- 快速入门 Solon详解(二)- Solon的核心 Solon详解(三)- Solon的web开发 Solon详解(四)- Solon的事务传播机制 ...
- Solon 框架详解(九)- 渲染控制之定制统一的接口输出
Springboot min -Solon 详解系列文章: Springboot mini - Solon详解(一)- 快速入门 Springboot mini - Solon详解(二)- Solon ...
- Kubernetes K8S之Ingress详解与示例
K8S之Ingress概述与说明,并详解Ingress常用示例 主机配置规划 服务器名称(hostname) 系统版本 配置 内网IP 外网IP(模拟) k8s-master CentOS7.7 2C ...
随机推荐
- MarkDown总结(适合初学者快速入门)
本文转自https://blog.csdn.net/sun8112133/article/details/79871702 总得的来说,MarkDown是一种简单.轻量级的标记语法,它是基于HTML之 ...
- Vue Slots
子组件vue <template> <div> <slot v-if="slots.header" name="header"&g ...
- 9个常用ES6特性归纳(一般用这些就够了)
ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准,已经在 2015 年 6 月正式发布了.它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应 ...
- My_Tomcat_Host 靶机
1:扫描网段: 发现主机IP为192.168.1.203 2:nmap 扫描端口信息 发现8080端口开启了http服务 22ssh服务 3:尝试ssh连接是需要密码的,然后访问8080端口 4:发 ...
- python基本数据类型(—)
数字 int(整型) 在32位机器上,整数的位数为32位,取值范围为-2**31-2**31-1,即-2147483648-2147483647 在64位系统上,整数的位数为64位,取值范围为-2** ...
- web基础(四)严格模式与混杂模式
web基础(四)严格模式与混杂模式 一.介绍 DOCTYPE 标签是一种标准通用标记语言的文档类型声明,它的目的是要告诉标准通用标记语言解析器,它应该使用什么样的文档类型定义(DTD)来解析文档.DO ...
- JAVA——JVM参数设置规则以及参数含义
JVM参数设置规则: -XX:+<option> 启用option,例如:-XX:+PrintGCDetails启动打印GC信息的选项,其中+号表示true,开启的意思-XX:-<o ...
- 七脚OLED屏幕使用IIC接口
7pin 0.96寸OLED模块支持SPI和IIC接口 默认是SPI接口;如果想用IC接口;操作如下几步骤: 1.将模块背面的电阻R3换到R1位置,此时将模块切换为IIC接口:电阻R8可以用0欧姆电阻 ...
- 第五篇 Scrum冲刺博客
一.会议图片 二.项目进展 成员 完成情况 今日任务 冯荣新 未完成 购物车列表,购物车工具栏 陈泽佳 未完成 静态结构 徐伟浩 商品信息录入 协助前端获取数据 谢佳余 未完成 搜索算法设计 邓帆涛 ...
- Hadoop的SecondaryNameNode的作用是什么?
为节省篇幅,将SecondaryNameNode简称SNN,NameNode简称NN. NN与fsimage.edits文件 NN负责管理HDFS中所有的元数据,包括但不限于文件/目录结构.文件权限. ...