一、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权限控制的更多相关文章

  1. 图文详解基于角色的权限控制模型RBAC

    我们开发一个系统,必然面临权限控制的问题,即不同的用户具有不同的访问.操作.数据权限.形成理论的权限控制模型有:自主访问控制(DAC: Discretionary Access Control).强制 ...

  2. Docker Kubernetes 服务发现原理详解

    Docker Kubernetes  服务发现原理详解 服务发现支持Service环境变量和DNS两种模式: 一.环境变量 (默认) 当一个Pod运行到Node,kubelet会为每个容器添加一组环境 ...

  3. 一文详解Hexo+Github小白建站

    作者:玩世不恭的Coder时间:2020-03-08说明:本文为原创文章,未经允许不可转载,转载前请联系作者 一文详解Hexo+Github小白建站 前言 GitHub是一个面向开源及私有软件项目的托 ...

  4. 第7.16节 案例详解:Python中classmethod定义的类方法

    第7.16节  案例详解:Python中classmethod定义的类方法 上节介绍了类方法定义的语法以及各种使用的场景,本节结合上节的知识具体举例说明相关内容. 一.    案例说明 本节定义的一个 ...

  5. 一文详解 Linux 系统常用监控工一文详解 Linux 系统常用监控工具(top,htop,iotop,iftop)具(top,htop,iotop,iftop)

    一文详解 Linux 系统常用监控工具(top,htop,iotop,iftop)     概 述 本文主要记录一下 Linux 系统上一些常用的系统监控工具,非常好用.正所谓磨刀不误砍柴工,花点时间 ...

  6. 第三节:带你详解Java的操作符,控制流程以及数组

    前言 大家好,给大家带来带你详解Java的操作符,控制流程以及数组的概述,希望你们喜欢 操作符 算数操作符 一般的 +,-,*,/,还有两个自增 自减 ,以及一个取模 % 操作符. 这里的操作算法,一 ...

  7. Solon详解(九)- 渲染控制之定制统一的接口输出

    Solon详解系列文章: Solon详解(一)- 快速入门 Solon详解(二)- Solon的核心 Solon详解(三)- Solon的web开发 Solon详解(四)- Solon的事务传播机制 ...

  8. Solon 框架详解(九)- 渲染控制之定制统一的接口输出

    Springboot min -Solon 详解系列文章: Springboot mini - Solon详解(一)- 快速入门 Springboot mini - Solon详解(二)- Solon ...

  9. Kubernetes K8S之Ingress详解与示例

    K8S之Ingress概述与说明,并详解Ingress常用示例 主机配置规划 服务器名称(hostname) 系统版本 配置 内网IP 外网IP(模拟) k8s-master CentOS7.7 2C ...

随机推荐

  1. 2020-04-29:现在你有个秒杀抢购的app,用户不断大量增加,技术层面,你要怎么做

    2020-04-29:现在你有个秒杀抢购的app,用户不断大量增加,技术层面,你要怎么做,才能既满足用户需求,又能扛住压力,还能帮公司合理支出?福哥答案2020-04-29: 限流(杀部分用户祭天). ...

  2. Css 图片自适应

    设置 CSS .container{ overflow:auto; } img{ width:100%; height:auto; overflow:hidden; } 设置 template < ...

  3. stat 命令家族(2)- 详解 pidstat

    性能测试必备的 Linux 命令系列,可以看下面链接的文章哦 https://www.cnblogs.com/poloyy/category/1819490.html 介绍 对 Linux 任务的统计 ...

  4. excel如何复制筛选内容

    https://jingyan.baidu.com/article/ca00d56c75b7e5e99eebcf3c.html

  5. 你们要的MyCat实现MySQL分库分表来了

    ❝ 借助MyCat来实现MySQL的分库分表落地,没有实现过的,或者没了解过的可以看看 ❞ 前言 在之前写过一篇关于mysql分库分表的文章,那篇文章只是给大家提供了一个思路,但是回复下面有很多说是细 ...

  6. React 17 要来了,非常特别的一版

    写在前面 React 最近发布了v17.0.0-rc.0,距上一个大版本v16.0(发布于 2017/9/27)已经过去近 3 年了 与新特性云集的 React 16及先前的大版本相比,React 1 ...

  7. 修改linux 动态ip为静态ip

    vi /etc/sysconfig/network-scripts/ifcfg-ens33 BOOTPROTO=static 设置网卡引导协议为 静态 ONBOOT=yes 网卡开机自启动 配置[IP ...

  8. nvm -- node 多版本管理器

    Node.js 越来越热,应用的场景也越来越多. 在开发中,我们可能同时在进行多个 node 项目,而这些不同的项目所使用的 node 版本又是不一样的,或者是要用更新的 node 版本进行试验和学习 ...

  9. .NET Core实用技巧(一)如何将EF Core生成的SQL语句显示在控制台中

    目录 .NET Core实用技巧(一)如何将EF Core生成的SQL语句显示在控制台中 前言 笔者最近在开发和维护一个.NET Core项目,其中使用几个非常有意思的.NET Core相关的扩展,在 ...

  10. shell 三剑客之 sed

    sed 在shell 编程里也很常用,功能强大! 同grep一样,sed提供两种方式: 方式一:stdout | sed [option] "pattern command" 从文 ...