Kubernetes进阶之基于RBAC授权安全框架

K8S 安全机制

  1. Kubernetes的安全框架
  2. 传输安全,认证,授权,准入控制
  3. 使用RBAC授权,我们作为一个用户如何去授权不同的同事去访问集群的权限,比如开发同事,可以访问哪个资源,哪个命名空间,测试同事可以访问哪些,通过这方面我们怎么去限制。

一、K8S的安全框架

? 访问K8S集群的资源需要过三关:认证、鉴权、准入控制
? 普通用户若要安全访问集群API Server,往往需要证书、Token或者用户名+密码;Pod访问,比如ingress控制器Ui的Dashboard都需要ServiceAccount,主要是让这个容器能够访问这个API,也就是所有的交互都是通过API的,这可能通过一个人去通过kubectl去交互,也有可能你的程序去调用API,但这些都是需要授权的

? K8S安全控制框架主要由下面3个阶段进行控制,每一个阶段都支持插件方式,通过API Server配置来启用插件。

  1. Authentication 认证
  2. Authorization 鉴权
  3. Admission Control 准入控制

说在前面的话,也就是每个阶段都是插件化的设计,可以自己开发插件,把这些集成到步骤里面,来实现相关的访问控制,这样的话你就不需要去修改原有的代码去增加了,所以k8s设计原则有很多都是以扩展性去设计的,都尽可能的让用户自定义一些东西,集成到里面。

接下来看一张图,这是访问API经历的一些阶段

从上面kubectl、API、UI,访问的是k8sAPI,k8s的API提供了很多的接口

这些都是Apiserver去提供的,也支持不同的功能,来完成相关的处理的,相关的认证,再往下就是API内置有三层的授权,第一层就是认证,第二层就是鉴权,第三层就是准入控制,然后通过之后就可以访问相关的资源了,这些资源都是从ETCD中去调用的,一些存储状态的信息

传输安全:
现在k8s都已经改成https进行访问,也就是不管你是kubeadm部署还是二进制部署,他都是建议你使用https进行全栈的通信,告别8080,使用6443

认证:
API收到用户发送的请求之后,他会先认证,认证它这边有三个可以做到
三种客户端身份认证:

? HTTPS 证书认证:基于CA证书签名的数字证书认证,也就是k8s,CA签出来的证书可以作为你客户端访问携带的证书,它会帮你认证,这是一种方式,从这个证书里面去提取你有没有权限去访问。
? HTTP Token认证:通过一个Token来识别用户。
? HTTP Base认证:用户名+密码的方式认证,这是基于http自身的一个认证,不过这个很少人去用,因为安全系数比较低。

第一关就是标识你是用哪个证书进来的,还是token标识进来的,看看我这里是不是可信任的,看看我这个token我这里有没有相关的授权,也就是我这里有没有这个token,如果没有就不允许通过,然后下面就不会再进行了,如果通过的话,就比如本地已经创建这个token了,有的话就给你放行,进行下一个判断,也就是第二关授权。

授权:
RBAC(Role-Based Access Control,基于角色的访问控制):负责完成授权(Authorization)工作。也就是会查看你的访问符不符合权限,所以它会在这个地方去给你判断,如果你来的这个身份,虽然有这个身份,但是没有这个权限访问这个资源,也会不允许你通过。

授权的资源有很多类型的支持

准入控制:
简单讲就是开发将一些高级的功能,直接插件化的去设计,也就是准入控制器就是一个插件的集合,集合里面就有一些高级的特性,都是以插件去实现的,如果不启用这些插件的话,那你就使用不了这个功能,这也就是第三关,也就是你的请求会经过你的插件准入控制,准入控制呢会给你效验请求的实现的这个方法,到底这个插件有没有启用这一块,不过大多数的方式默认的插件都是启用的,启动之后来请求相关的资源,才会被允许,因为它启用插件了,如果没启动的话也会不通过

Adminssion Control实际上是一个准入控制器插件列表,发送到API Server的请求都需要经过这个列表中的每个准入控制器,插件的检查,检查不通过,则拒绝请求。

1.11版本以上推荐使用的插件:
--enable-admission-plugins= \
NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,ResourceQuota

使用RBAC授权
RBAC(Role-Based Access Control,基于角色的访问控制),允许通过Kubernetes API动态配置策略。也就是即使配置,即时生效,不需要重启服务

角色
? Role:授权特定命名空间的访问权限
? ClusterRole:授权所有命名空间的访问权限

角色绑定
? RoleBinding:将角色绑定到主体(即subject)
? ClusterRoleBinding:将集群角色绑定到主体

主体(subject)
? User:用户
? Group:用户组
? ServiceAccout: 服务账号
要做一个权限的管理系统,有两块,第一块就是对象是谁,创建的用户,第二就是权限组,比如创建一个开发组,开发组有哪些权限,可以访问这个系统,这也是为了方便去管理这些权限,来划分这个权限组,每个用户都给他创建一个权限很麻烦,有这个组的话,直接将用户加入这个组里面就可以了,比如来一个开放,并给他设置权限,他是一个来宾用户的组,这个组里面只能查看一些东西,但是他是一个开发组的,对一些项目有一些开发权限,管理员进去呢,在这个管理页面去再去加一个开发组,这样的话他就有开发组的权限了

K8s和刚才说的其实都是一样的,用户就是这个主体,就是谁来访问,然后权限组呢就是角色,定义了一组权限的集合,用户要想将用户与权限集合做一个附加,将开发附加一个权限组,就称为角色绑定,角色里面又分为了,角色及集群角色,集群角色是授权集群命名空间的,
也就是k8s有命名空间这一说,所以有分为了单个命名空间和所有命名空间,这个权限集合的设置,ClusterRole也就是授权所有命名空间,也就是说将某个用户加入这个权限角色里,那就意味着它可以访问所有命名空间,相关的一些权限。

示例:为zhaocheng用户授权default命名空间Pod读取权限
比如就是只能查看pod默认的空间的运行的一些资源,像svc,日志是没有权限查看的,当你试用期过了之后,再给你加一些权限,再做一些相关的操作
实现这个目标需要完成以下三步

  1. 用K8S CA签发客户端证书
  2. 生成kubeconfig授权文件
  3. 创建RBAC权限策略
    Ca.crt 和 Ca.key就是这两个需要签发的证书
    [[email protected] ~]# ls /etc/kubernetes/pki/
    apiserver.crt              apiserver.key                 ca.crt  front-proxy-ca.crt      front-proxy-client.key
    apiserver-etcd-client.crt  apiserver-kubelet-client.crt  ca.key  front-proxy-ca.key      sa.key
    apiserver-etcd-client.key  apiserver-kubelet-client.key  etcd    front-proxy-client.crt  sa.pub
  4. 用K8S CA签发客户端证书
    [[email protected] ~]# cd demo/
    [[email protected] demo]# mkdir rbac
    [[email protected] demo]# cd rbac/
    [[email protected] rbac]# rz -E
    rz waiting to receive.
    [[email protected] rbac]# ls
    cert.sh  cfssl.sh  config.sh  rbac.yaml
    [[email protected] rbac]# cat cfssl.sh
    wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
    wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
    wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
    chmod +x cfssl*
    mv cfssl_linux-amd64 /usr/bin/cfssl
    mv cfssljson_linux-amd64 /usr/bin/cfssljson
    mv cfssl-certinfo_linux-amd64 /usr/bin/cfssl-certinfo
    [[email protected] rbac]# sh cfssl.sh 

然后这里我们把我们证书签发的脚本拿过来,这里注意的是签发用户的CN这里是指签发用户的用户名,就是说k8s拿这个CA来认证,它不单效验是不是我颁发的证书,还要效验里面的用户名,就是CN这个字段是不是授权过的,相当于鉴权那一块,O是用户组,也可以基于这个用户组去做这个权限限制

[[email protected] rbac]# chmod +x cert.sh
[[email protected] rbac]# vim cert.sh
cat > ca-config.json <<EOF
{
  "signing": {
    "default": {
      "expiry": "87600h"
    },
    "profiles": {
      "kubernetes": {
        "usages": [
            "signing",
            "client auth"
        ],
        "expiry": "87600h"
      }
    }
  }
}
EOF

cat > zhaocheng-csr.json <<EOF
{
  "CN": "zhaocheng",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "BeiJing",
      "L": "BeiJing",
      "O": "k8s",
      "OU": "System"
    }
  ]
}
EOF

cfssl gencert -ca=/etc/kubernetes/pki/ca.crt -ca-key=/etc/kubernetes/pki/ca.key -config=ca-config.json -profile=kubernetes zhaocheng-csr.json | cfssljson -bare zhaocheng

[[email protected] rbac]# bash cert.sh 

主要生成的就是zhaocheng-key.pem zhaocheng.pem

[[email protected] rbac]# ls
ca-config.json  cert.sh  cfssl.sh  config.sh  rbac.yaml  zhaocheng.csr  zhaocheng-csr.json  zhaocheng-key.pem  zhaocheng.pem

需要用这两个证书来对客户端做请求认证,写到客户端授权文件里,用这个授权文件就能请求这个k8s集群了
比如公司有多个集群,那么这个开发需要登录这个集群,需要这个config证书,到时候可以拿这个来回切换登录不同的集群
--kubeconfig=zhaocheng.kubeconfig

[[email protected] rbac]# vim config.sh
kubectl config set-cluster kubernetes   --certificate-authority=/etc/kubernetes/pki/ca.crt   --embed-certs=true   --server=https://192.168.30.21:6443   --kubeconfig=zhaocheng.kubeconfig

设置客户端认证
kubectl config set-credentials zhaocheng   --client-key=zhaocheng-key.pem   --client-certificate=zhaocheng.pem   --embed-certs=true   --kubeconfig=zhaocheng.kubeconfig

设置默认上下文
kubectl config set-context kubernetes   --cluster=kubernetes   --user=zhaocheng   --kubeconfig=zhaocheng.kubeconfig

设置当前使用配置
kubectl config use-context kubernetes --kubeconfig=zhaocheng.kubeconfig

[[email protected] rbac]# bash config.sh
[[email protected] rbac]# cat zhaocheng.kubeconfig 

现在就可以拿这个kubeconfig去访问集群了
到这呢其实是到认证这个地方给打回去了,node节点是没有访问权限的,已经识别出来是zhaocheng用户了,但是鉴权这块没有相关的授权,所以现在要为这个用户授权

[[email protected] rbac]# kubectl get --kubeconfig=./zhaocheng.kubeconfig node
Error from server (Forbidden): nodes is forbidden: User "zhaocheng" cannot list resource "nodes" in API group "" at the cluster scope

如果有一个组的命名空间,权限比较大,就是可以访问所有命名空间,比如运维来讲,有很多的运维,可以创建集群的角色,这样它是管控所有命名空间的角色,这个角色就是针对于特定的命名空间的,比如开发,测试,它只能访问命名空间的项目,它负责的项目,然后可以使用这个指定命名空间,然后就是集群的绑定,然后绑定到zhaocheng这个用户身上,这里我定义的是user,也可以是group组。

pod也是不能访问的

[[email protected] rbac]# kubectl get --kubeconfig=./zhaocheng.kubeconfig pod
Error from server (Forbidden): pods is forbidden: User "zhaocheng" cannot list resource "pods" in API group "" in the namespace "default"
[[email protected] rbac]# vim rbac.yaml
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: default
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "watch", "list"]

---

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: read-pods
  namespace: default
subjects:
- kind: User
  name: zhaocheng
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

[[email protected] rbac]# kubectl create -f rbac.yaml 

然后现在就可以进行访问了

[[email protected] rbac]# kubectl get --kubeconfig=./zhaocheng.kubeconfig pod
NAME                                     READY   STATUS             RESTARTS   AGE
my-pod                                   1/1     Running            0          10h
nfs-744d977b46-dh9xj                     1/1     Running            0          29h
nfs-744d977b46-kcx6h                     1/1     Running            0          29h
nfs-744d977b46-wqhc6                     1/1     Running            0          29h
nfs-client-provisioner-fbc77b9d4-kkkll   1/1     Running            0          11h
nginx-797db8dc57-tdd5s                   1/1     Running            0          8h
nginx-a1-6d5fd7b8dd-w647x                1/1     Running            0          4h55m
nginx-statefulset-0                      1/1     Running            0          7h7m
nginx-statefulset-1                      1/1     Running            0          7h6m
nginx-statefulset-2                      1/1     Running            0          7h6m
web-0                                    1/1     Running            0          4h55m
web-1                                    1/1     Running            0          4h53m
web-2                                    1/1     Running            0          4h52m

但是svc是没有定义的所以还不能访问

[[email protected] rbac]# kubectl get --kubeconfig=./zhaocheng.kubeconfig svc
Error from server (Forbidden): services is forbidden: User "zhaocheng" cannot list resource "services" in API group "" in the namespace "default"

比如我们加一个别的访问权限,比如service,deployment
在刚才我们的rbac的策略里面加上这些权限

- apiGroups: [""]
  resources: ["pods","services"]
  verbs: ["get", "watch", "list"]

再来测试一下,已经可以正常去访问svc了

[[email protected] rbac]# kubectl get --kubeconfig=./zhaocheng.kubeconfig service
NAME         TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.1.0.1      <none>        443/TCP        30h
my-service   ClusterIP   None          <none>        80/TCP         7h22m
nginx        ClusterIP   None          <none>        80/TCP         4h59m
service      NodePort    10.1.207.32   <none>        80:30963/TCP   8h
zhao         ClusterIP   10.1.75.232   <none>        80/TCP         7h31m
zhaocheng    ClusterIP   10.1.27.206   <none>        80/TCP         7h33m

像其他的授权可以查看官方提供
https://kubernetes.io/docs/reference/access-authn-authz/rbac/

原文地址:https://blog.51cto.com/14143894/2436500

时间: 2024-09-30 05:10:46

Kubernetes进阶之基于RBAC授权安全框架的相关文章

Kubernetes 基于 RBAC 的授权(十六)

一.RBAC介绍 在Kubernetes中,授权有ABAC(基于属性的访问控制).RBAC(基于角色的访问控制).Webhook.Node.AlwaysDeny(一直拒绝)和AlwaysAllow(一直允许)这6种模式.从1.6版本起,Kubernetes 默认启用RBAC访问控制策略.从1.8开始,RBAC已作为稳定的功能.通过设置--authorization-mode=RBAC,启用RABC.在RABC API中,通过如下的步骤进行授权:定义角色:在定义角色时会指定此角色对于资源的访问控制

一种基于RBAC模型的动态访问控制改进方法

本发明涉及一种基于RBAC模型的动态访问控制改进方法,属于访问控制领域.对原有RBAC模型进行了权限的改进和约束条件的改进,具体为将权限分为静态权限和动态权限,其中静态权限是非工作流的权限,动态权限是工作流中的权限:将约束条件分为静态约束和动态约束,其中静态约束包括最小权限约束和职责分离约束,动态约束使动态权限按照工作流进行操作.采用本发明的方法改进后的RBAC模型具有以下优势:为传统的RBAC模型中增加了动态特性:跟纯动态模型相比较具有更高的效率:保证需要按顺序执行的权限能够按顺序执行,使得系

基于RBAC权限管理模型学习

在RBAC中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限.这就极大地简化了权限的管理. 在一个组织中,角色是为了完成各种工作而创造,用户则依据它的责任和资格来被指派相应的角色,用户可以很容易地从一个角色被指派到另一个角色.角色可依新的需求和系统的合并而赋予新的权限,而权限也可根据需要而从某角色中回收. 角色与角色的关系可以建立起来以囊括更广泛的客观情况. BAC支持三个著名的安全原则:最小权限原则,责任分离原则和数据抽象原则. (1)最小权限原则之所以被RBAC所支持,是因

RBAC授权

给用户授予RBAC权限 没有权限会报如下错误: 执行查看资源报错: unable to upgrade connection: Forbidden (user=kubernetes, verb=create, resource=nodes, subresource=proxy) [[email protected] ~]# kubectl exec -it http-test-dm2-6dbd76c7dd-cv9qf sh error: unable to upgrade connection:

Kubernetes进阶之ingress-nginx

Kubernetes进阶之ingress-nginx 目录:一 从外部访问应用最佳方式 二 配置管理 三 数据卷与数据持久卷 四 再谈有状态应用部署 五 K8S 安全机制 说在前面的话,选择nodeport的方式去暴露端口,那你需要得去判断暴露的端口有没有被占用,再创建新的应用会判断端口有没有被分配出去 nodeport本身是基于默认的iptables的代理模式做的网络转发,也就是SANT,DANT,基于四层的,做七层是做不了的,性能差一点,因为它需要防火墙的转发和过滤. 一.从外部访问应用最佳

Kubernetes系列之基于NFS的PV动态供给(StorageClass)

一.简介 PersistentVolume(PV)是指由集群管理员配置提供的某存储系统上的段存储空间,它是对底层共享存储的抽象,将共享存储作为种可由用户申请使的资源,实现了"存储消费"机制.通过存储插件机制,PV支持使用多种网络存储系统或云端存储等多种后端存储系统,例如,NFS.RBD和Cinder等.PV是集群级别的资源,不属于任何名称空间,用户对PV资源的使需要通过PersistentVolumeClaim(PVC)提出的使申请(或称为声明)来完成绑定,是PV资源的消费者,它向PV

基于Selenium的自动化测试框架 - SeLion学习之一(基本介绍)

SeLion是一个基于Selenium的自动化测试框架,是Selenium下的一款非常优秀的框架结构,但是资料非常少,在国内使用的也就相对较少,本人会用一系列的文章,比较详细的介绍该框架结构,希望能给广大的自动化测试爱好者提供一个实现思路,如果对该本人文章感兴趣或者有什么问题,欢迎留言,我会尽量回答,也欢迎转载该系列文章.该文章是本系列第一节,SeLion的基本介绍,先让大家对SeLion有一个基本的认识. 一:SeLion是什么?SeLion是基于Selenium的一款开源测试框架,是对Sel

基于SEDA的异步框架设计与实现

基于SEDA的异步框架设计与实现 二.为什么使用SEDA 目前,面对并发环境,主流互联网服务器编程模型有两种:多线程模型以及事件驱动模型.但是这两个模型都不足以解决这个问题.我们来首先看一下这两种编程模型. 1.多线程并发模型 多线程并发模型是目前最普遍的服务器编程模型,该模型的架构如下图所示:        该模型针对每一个请求,会为其创建并分配一个线程.该线程负责这个请求的处理.该模型的优点:执行粒度是整个完整的处理流程.处理逻辑清晰,容易开发.但与此同时缺点也很明显:如果处理过程中某一步骤

基于asp.net + easyui框架,一步步学习easyui-datagrid——实现分页和搜索(二)

http://blog.csdn.net/jiuqiyuliang/article/details/19967031 目录: 基于asp.net + easyui框架,一步步学习easyui-datagrid——界面(一) 基于asp.net + easyui框架,一步步学习easyui-datagrid——实现分页和搜索(二) 基于asp.net + easyui框架,一步步学习easyui-datagrid——实现添加.编辑.删除(三) 基于asp.net + easyui框架,一步步学习e