1. RBAC–基于角色的访问控制

1.1 Kubernetes基于意图的声明式API

Kubernetes API的设计与大多数现代API不同。它是基于意图的,这意味着使用API的人考虑的是他们想要Kubernetes做什么,而不是如何实现。其结果是一个令人难以置信的可扩展性、弹性,和一个强大而流行的系统。

大多数API都是所谓的基于行动的(action-based),这意味着当你想到一个API调用时,你正在考虑你想要执行的行动,以改变软件的运行方式。

相比之下,Kubernetes有所谓的基于意图的(intent-based)API,这意味着当你想要进行一个API调用时,你要考虑的是你希望该系统处于何种状态。你并不关心用什么操作来实现这种希望的状态。你只需告诉系统你想要什么(你的意图),系统就会想出如何实现它——采取哪些动作将系统过渡到期望的状态。

架构上的关键区别在于,基于意图的系统既能理解系统当前所处的状态(有时称为实际状态),也能理解你对系统应该处于何种状态的意图(期望状态)。系统不断地计算两者之间的差距,并采取任何必要的行动使实际状态变成期望状态。用户可以直接通过API调用来改变期望状态,而依靠系统本身来改变实际状态。

K8s每个API调用都允许指定一个对象的期望状态:pod、service、ingress、configmap等。例如,下面是你为一个nginx工作负载定义的期望状态。

# nginx-pod.yaml
kind: Pod
apiVersion: v1
metadata:name: nginxlabels:app: nginx
spec:containers:- image: nginxname: nginx

然后要把这个想要的状态发送到Kubernetes,用kubectl,把上面的YAML文件交给它就行了。

kubectl apply -f nginx-pod.yaml

假设你想改变nginx的版本,挂载一个外部卷,或者提供额外的配置,你更新nginx-pod.yaml文件到任何你想要的状态,然后再使用kubectl apply。更新nginx-pod.yaml文件到任何需要的状态,然后再使用kubectl apply。

kubectl apply -f nginx-pod.yaml

这里的关键要点是,你不是在运行像 updateVersion 或 mountVolume 这样的 API,而是在改变一些描述系统应该处于什么状态的 YAML,并通过运行 apply 来说"使之如此"。

这种方式,使得学习更简单,你只需要学习每个对象的YAML配置格式。相比之下,基于动作的API还需要你学习可能是1,000个动作。

1.2 k8s + rbac的使用

Kubernetes 从 1.6 开始支持基于角色的访问控制机制(Role-Based Access,RBAC),集群管理员可以对用户或服务账号的角色进行更精确的资源访问控制。

要启用 RBAC,请使用 --authorization-mode=RBAC 启动 API Server。

用户可以像使用其他 Kubernetes API 资源一样 (例如通过 kubectl、API 调用等)与RBAC相关的资源进行交互。例如,命令 kubectl create -f (resource).yml

1.2.1 Role 与 ClusterRole

RBAC 授权策略会创建一系列的 Role 和 ClusterRole 来绑定相应的资源实体(serviceAccount 或 group),以此来限制其对集群的操作。

角色可以由命名空间(namespace)内的 Role 对象定义,比如:

kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:namespace: defaultname: pod-reader
rules:
- apiGroups: [""] # 空字符串"" 表明使用 core API groupresources: ["pods"]verbs: ["get", "watch", "list"]

而整个 Kubernetes 集群范围内有效的角色则通过 ClusterRole 对象实现:

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:# 鉴于 ClusterRole 是集群范围对象,所以这里不需要定义 "namespace" 字段name: secret-reader
rules:
- apiGroups: [""]resources: ["secrets"]verbs: ["get", "watch", "list"]

1.2.2 RoleBinding 与 ClusterRoleBinding

角色绑定将一个角色中定义的各种权限授予一个或者一组用户。

角色绑定包含了一组相关主体(即 subject, 包括用户 ——User、用户组 ——Group、或者服务账户 ——Service Account)以及对被授予角色的引用。

在命名空间中可以通过 RoleBinding 对象授予权限,而集群范围的权限授予则通过 ClusterRoleBinding 对象完成。

比如,以下角色绑定定义将允许用户 “jane” 从 “default” 命名空间中读取 pod。

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:name: read-podsnamespace: default
subjects:
- kind: Username: janeapiGroup: rbac.authorization.k8s.io
roleRef:kind: Rolename: pod-readerapiGroup: rbac.authorization.k8s.io

以下 ClusterRoleBinding 对象允许在用户组 “manager” 中的任何用户都可以读取集群中任何命名空间中的 secret。

kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:name: read-secrets-global
subjects:
- kind: Groupname: managerapiGroup: rbac.authorization.k8s.io
roleRef:kind: ClusterRolename: secret-readerapiGroup: rbac.authorization.k8s.io

1.2.3 综合运用rbac

举个例子

  1. 先创建一个名叫 helm 的 ServiceAccount
  2. 然后创建相应的 Role 绑定 “tiller-world” namespace,该 Role 只拥有 list pods 的权限
  3. 最后通过创建 RoleBinding 将该 Role 与之前创建的 ServiceAccount 绑定。
apiVersion: v1
kind: ServiceAccount
metadata:name: helmnamespace: helm-world
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:name: tiller-usernamespace: tiller-world
rules:
- apiGroups:- ""resources:- pods/portforwardverbs:- create
- apiGroups:- ""resources:- podsverbs:- list
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:name: tiller-user-bindingnamespace: tiller-world
roleRef:apiGroup: rbac.authorization.k8s.iokind: Rolename: tiller-user
subjects:
- kind: ServiceAccountname: helmnamespace: helm-world

1.2.4 rback审计rbac

为了查看每个 Role 的作用以及每个资源对象应该能做哪些事情,比如确认某个 CI/CD Service Account 在指定的 namespace 内是否拥有 Update Pod 的权限。

rback可以用来帮助大家更方便地审计 RBAC。

rback 用来对 kubectl 的输出结果进行可视化展示,可以输出为 .dot 格式,也可以输出为 .png 或任何格式。

 kubectl get sa,roles,rolebindings \-n monitoring -o json \| rback | dot -Tpng > rback.png

1.3 为什么RBAC不足以保证Kubernetes的API安全?

基于Kubernetes意图的API的挑战来自于你想要保护和保障API的安全时——当你想要控制哪些人可以使用该API做什么时。

Kubernetes中的RBAC由于其基于意图的API。从API的角度来看,只有十几个动作,这意味着如果alice可以更新一个资源,她就可以更新这个资源的任何部分。

相反,如果Kubernetes是基于动作的。那么我们就可以使用RBAC做更细粒度的控制。

简而言之,Kubernetes API提供了一个强大的、可扩展的、统一的资源模型,但也正是这个资源模型使得RBAC对于很多用例来说过于粗粒度。

2. 我们需要什么来保证K8s的API安全?

2.1 Admission机制

我们需要一个访问控制系统,让管理员编写更细粒度的策略.

标准的访问控制范式都不能满足这些要求。这包括基于角色的访问控制(RBAC)、基于属性的访问控制(ABAC)、访问控制列表(ACL),甚至是IAM风格的策略。

幸运的是,Kubernetes团队预见到了这个问题,并创建了一个Admission Control机制,在这里你可以把控制的范围远远超过RBAC和标准的访问控制机制。Kubernetes API服务器提供了一条访问控制的管道,分为Authorization(如RBAC),和Admission


通过Addmission,你将获得以下信息以做出决定:

  • 用户:用户、组、认证提供的额外属性。
  • 动作:路径、API动词、HTTP动词。
  • 资源:资源、子资源、命名空间、API组。

2.2 OPA(Open Policy Agent)

准入控制(Admission Control)赋予了用户控制API的额外权力。你可以使用声明式授权解决方案(如Open Policy Agent)作为Kubernetes Admission Controller,为你提供所需的表达能力,以克服这些新的访问挑战,并提供真正有效的粒度。

开放策略代理(OPA,发音为“ oh-pa”)是一个开放源代码的通用策略引擎。提供了一套统一的框架和语言,用于声明、实施和控制云原生解决方案中各个组件的策略,也是策略即代码(Policy as Code)的经典实现。作为CNCF的毕业项目,目前在CI/CD、Kubernetes、微服务等场景下都有广泛的应用。OPA的架构采用将规则和数据进行分离的解耦设计,不同的角色各司其职,决策系统负责提供决策输入数据。


我们看个例子,假设又一个组织有这些元素:

系统中共有三种组件:

  • 服务器:暴露零个或多个协议(例如,http,ssh等)
  • 网络:连接服务器,可以是公共的或私有的。公共网络连接到 Internet。
  • 端口将服务器连接到网络。

所有服务器、网络和端口都由json描述。

{"servers": [{"id": "app", "protocols": ["https", "ssh"], "ports": ["p1", "p2", "p3"]},{"id": "db", "protocols": ["mysql"], "ports": ["p3"]},{"id": "cache", "protocols": ["memcache"], "ports": ["p3"]},{"id": "ci", "protocols": ["http"], "ports": ["p1", "p2"]},{"id": "busybox", "protocols": ["telnet"], "ports": ["p1"]}],"networks": [{"id": "net1", "public": false},{"id": "net2", "public": false},{"id": "net3", "public": true},{"id": "net4", "public": true}],"ports": [{"id": "p1", "network": "net1"},{"id": "p2", "network": "net3"},{"id": "p3", "network": "net2"}]
}

比如,你要实施两条策略

1. Servers reachable from the Internet must not expose the insecure 'http' protocol.
2. Servers are not allowed to expose the 'telnet' protocol.

这两条策略通过OPA的Rego语言实现, 输入则是上面的json数据:

package exampleallow = true {                                      # allow is true if...count(violation) == 0                           # there are zero violations.
}violation[server.id] {                              # a server is in the violation set if...some serverpublic_server[server]                           # it exists in the 'public_server' set and...server.protocols[_] == "http"                   # it contains the insecure "http" protocol.
}violation[server.id] {                              # a server is in the violation set if...server := input.servers[_]                      # it exists in the input.servers collection and...server.protocols[_] == "telnet"                 # it contains the "telnet" protocol.
}public_server[server] {                             # a server exists in the public_server set if...some i, jserver := input.servers[_]                      # it exists in the input.servers collection and...server.ports[_] == input.ports[i].id            # it references a port in the input.ports collection and...input.ports[i].network == input.networks[j].id  # the port references a network in the input.networks collection and...input.networks[j].public                        # the network is public.
}

我们可以通过opa eval命令,验证策略是否生效

# Evaluate a policy on the command line and use the exit code.
./opa eval --fail-defined -i input.json -d example.rego "data.example.violation[x]"

2.3 k8s Admission Controller + OPA

通过将 OPA 部署为admission controller,可以实现如下策略:

  • 要求在所有资源上都有特定标签。
  • 要求容器镜像来自企业镜像注册中心。
  • 要求所有 Pod 指定资源请求和限制。
  • 防止创建冲突的 Ingress 对象。
    等等

比如:
输入

{"apiVersion": "admission.k8s.io/v1beta1","kind": "AdmissionReview","request": {"kind": {"group": "","kind": "Pod","version": "v1"},"object": {"metadata": {"name": "myapp"},"spec": {"containers": [{"image": "nginx","name": "nginx-frontend"},{"image": "mysql","name": "mysql-backend"}]}}}
}

OPA + REGO

package kubernetes.admissiondeny[msg] {input.request.kind.kind == "Pod"some iimage := input.request.object.spec.containers[i].imagenot startswith(image, "hooli.com/")msg := sprintf("image '%v' comes from untrusted registry", [image])
}

输出

{"deny": ["image 'mysql' comes from untrusted registry","image 'nginx' comes from untrusted registry"]
}

参考:

为什么 RBAC 不足以保障 Kubernetes 的安全?

Open Policy Agent

k8s访问控制--理解RBAC和OPA相关推荐

  1. kubernetes(k8s)之rbac权限管理详解

    kubernetes(k8s)之rbac权限管理详解 RBAC简介 RBAC(Role-Based Access Control) [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 ...

  2. k8s集群RBAC安全机制:role rolebing user

    k8s集群RBAC安全机制:role rolebing user

  3. K8s集群RBAC认证授权详解

    文章目录 1 什么是RBAC 2 创建Account 2.1 创建ServiceAccount(sa) 2.2 创建UserAccount并自签证书 3 RBAC认证授权 3.1 Role/RoleB ...

  4. Yii基于角色的访问控制(非Rbac)

    今天遇到了权限控制的问题,后台不同级别的用户登录后看到的内容是不一样的.网上查了下,说Yii中有自带的RBAC权限控制,大概看了下,没理解太明白.然后就是采用filter进行过滤验证,看着这个还不错. ...

  5. docker和k8s发展史--理解oci/cri/cni/docker swarm/containerd/runc/dockershim

    1. docker和k8s的爱恨情仇 1.1 PaaS的普及和难点 2013年,伴随着 PaaS 概念的逐步普及,以 Cloud Foundry 为代表的经典 PaaS 项目,开始进入基础设施领域的视 ...

  6. 基于角色的访问控制(RBAC)

    来自:编程新说 很多时候,需要对一些事物进行控制,如一个房间,为了不让人随便进,通常会装一把锁,如果要想进入,你必须得有一把钥匙,且还得和这个锁匹配才行. 基于此做一个抽象,其实包含三方面内容: 1) ...

  7. 【k8s】理解Docker容器的进程管理(PID1进程(容器内kill命令无法杀死)、进程信号处理、僵尸进程)

    文章目录 概述 1. 容器的PID namespace(名空间) 2. 如何指明容器PID1进程 3. 进程信号处理 4. 孤儿进程与僵尸进程管理 5. 进程监控 6. 总结 参考 概述 简介: Do ...

  8. 实战:k8s中基于角色的权限访问控制-RBAC(成功测试-博客输出)-20211005

    目录 文章目录 目录 写在前面 基础知识介绍 实验环境 实验软件 老师原课件内容 1..用K8S CA签发客户端证书 2. 生成kubeconfig授权文件 3. 创建RBAC权限策略 4.指定kub ...

  9. k8s、ServiceAccount权限详解、RBAC 详解(基于角色的访问控制),常用操作指令

    文章目录 Service Account应用示例 RBAC 详解(基于角色的访问控制) 创建一个角色(role)---权限 实验二 常用操作指令 Service Account应用示例 概念图权限关系 ...

最新文章

  1. STL--priority_queue学习笔记
  2. Crontab使用语法格式
  3. 浏览器窗口的高度和宽度
  4. CommandLineRunner、ApplicationRunner 接口
  5. List的remove(对象)操作有时候会报ConcurrentModificationException异常
  6. python 网络爬虫requests模块
  7. VS.Net 2003/VC6.0常用快捷键集合
  8. 小程序开发 宽度100%_这是您作为开发人员可以实现100%年度目标的方式
  9. ios nstimer实现延时_iOS 中常见 Crash 总结
  10. java程序linux自己更新自己,Linux下升级JAVA的一个小方法
  11. windows桌面美化
  12. Vue 动态加载子组件
  13. 电脑桌面云便签怎么登录便签账号?
  14. 天不生Tobler,万古GIS如长夜
  15. WPF DataGrid MVVM 绑定 SelectedCells
  16. 【读官方文档,学原味技术】SpringBoot-Staters和自定义Starter
  17. 计算机毕业设计Java无人售货机管理系统(源码+系统+mysql数据库+Lw文档)
  18. 2020年中级银行从业资格报考注意事项
  19. 机器学习sklearn实战-----随机森林调参乳腺癌分类预测
  20. 【51单片机】继电器的原理以及使用

热门文章

  1. 注册围框html,一种可调模具围框的制作方法
  2. K-SVD字典学习算法
  3. Ajax通讯异常12002,前端MVC框架[02] 发送AJAX请求及建立连接池
  4. c#如何实现从xml中加载树目录,并且显示完整的Text
  5. ArcGiS/ArcInfo/ArcEditor/ArcMap/ArcView的区别
  6. python如何收集数据_如何从另一个文件导入列表并从中“收集”数据?(Python)...
  7. 算法训练 纪念品分组(java)
  8. java 坦克重叠_【Java】我所知道坦克大战(单机版)之画出坦克的实心圆、让圆动起来、双缓冲解决闪烁问题...
  9. MCGS 无限配方数据存储及U盘导入导出-第二集
  10. html怎么添加5px高的线,css给div添加0.5px的边框