OceaBase开发者大会落地上海!4月20日共同探索数据库前沿趋势!报名戳 了解详情
写点什么

实例演示:如何简化生产中的 Pod 安全策略?

  • 2020-05-25
  • 本文字数:6062 字

    阅读完需:约 20 分钟

实例演示:如何简化生产中的Pod安全策略?

之前的文章中,我们演示了如何使用受限的 PSP 策略作为默认值在 Rancher 中启用 PSP。我们还展示了如何防止特权 Pod 被接纳到集群中。



启用 Pod 安全策略的功能


我们有意省略了有关基于角色的访问控制(RBAC)以及如何将 Pod 与特定 PSP 连接的具体细节。那么,这篇文章让我们继续深入研究 PSP。

将 Pod 与 Pod 安全策略匹配

你可能已经注意到,PSP 模式没有与任何 Kubernetes 命名空间、Service Account 或 Pod 相关联。实际上,PSP 是集群范围的资源。那么,我们如何指定哪些 Pod 应该由哪些 PSP 来管理呢?下图显示了所有参与组件、资源以及准入流程的工作方式。



也许一开始听起来很复杂。现在,我们来详细介绍一下。


部署 Pod 时,准入控制将根据请求 deployment 的对象来应用策略。


Pod 本身没有任何关联的策略——执行该 Deployment 的是 service account。在上图中,Jorge 使用 webapp-sa service account 部署了 pod。


RoleBinding 将 service account 与 Roles(或 ClusterRoles)相关联,Role 是指定可以使用 PSP 的资源。在该图中,webapp-sa 与 webapp-role 关联,后者为特定的 PSP 资源提供使用许可。部署 Pod 时,将根据 webapp-sa PSP 对 Pod 进行检查。实际上,一个 service account 可以使用多个 PSP,并且其中一个可以验证 Pod 就足够了。你可以在官方文档中查看详细信息:


https://kubernetes.io/docs/concepts/policy/pod-security-policy/#policy-order


然后,准入控制将决定 Pod 是否符合其中任何一个 PSP。如果 Pod 符合要求,准入控制将调度 Pod;如果 Pod 不符合规定,则会阻止部署。


以上内容可以总结为以下几点:


  • Pod 身份由其 service account 确定


如果规范中未声明任何 service account,则将使用默认账户


  • 你需要允许使用声明 Role 或 ClusterRole

  • 最后,需要有一个 RoleBinding,它将 Role(从而允许访问使用 PSP)与 Pod 规范中声明的 Servcie Account 相关联。


让我们用一些例子来说明。

RBAC 的真实示例

假设你已经有一个启用了PSP的集群,这是采用 PSP 创建限制性 PSP 的常用方法,该 PSP 可以被任意 Pod 使用。然后你将添加更为特定的 PSP,该 PSP 有绑定到特定 service account 的其他特权。拥有默认、安全且严格的策略有助于集群的管理,因为大多数 Pod 不需要特殊的特权或功能,并且在默认情况下即可运行。然后,如果你的某些工作负载需要其他特权,我们可以创建一个自定义 PSP 并将该工作负载的特定 service account 绑定到限制较少的 PSP。


但是,如何将 Pod 绑定到特定的 PSP 而不是默认的受限 PSP?以及如何使用不自动添加 RoleBindings 的普通 Kubernetes 集群来做到这一点?


让我们看一个完整的示例,在该示例中,我们定义一些安全的默认值(集群中任何 service account 都可以使用的受限 PSP),然后为需要该服务的特定 deployment 向单个 service account 提供其他特权。


首先,我们手动创建一个新的命名空间。它不会由 Rancher 管理,所以不会自动创建 RoleBindings。然后我们在该命名空间中尝试部署一个受限的 Pod:


$ kubectl create ns psp-test$ cat deploy-not-privileged.yamlapiVersion: apps/v1kind: Deploymentmetadata: labels:   app: not-privileged-deploy name: not-privileged-deployspec: replicas: 1 selector:   matchLabels:     app: not-privileged-deploy template:   metadata:     labels:       app: not-privileged-deploy   spec:     containers:     - image: alpine       name: alpine       stdin: true       tty: true       securityContext:         runAsUser: 1000         runAsGroup: 1000$ kubectl -n psp-test apply -f deploy-not-privileged.yaml$ kubectl -n psp-test describe rs...  Warning  FailedCreate  4s (x12 over 15s)  replicaset-controller  Error creating: pods "not-privileged-
复制代码


由于命名空间 psp-test 中没有 RoleBinding,且该命名空间绑定到允许使用任何 PSP 的角色,因此无法创建 pod。我们将通过创建集群范围的 ClusterRole 和 ClusterRoleBinding 来解决此问题,以允许任何 Service Account 默认使用受限的 PSP。之前的文章中启用 PSP 时,Rancher 创建了受限 PSP。


  resourceNames:  - restricted-psp---apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRoleBindingmetadata:  name: restricted-role-bindroleRef:  apiGroup: rbac.authorization.k8s.io  kind: ClusterRole  name: use-restricted-pspsubjects:- apiGroup: rbac.authorization.k8s.io  kind: Group  name: system:serviceaccounts$ kubectl apply -f clusterrole-use-restricted.yaml
复制代码


我们应用这些更改之后,非特权 deployment 应正常工作。


但是,如果我们需要部署特权 Pod,则不会被现有策略允许:


$ cat deploy-privileged.yamlapiVersion: v1kind: ServiceAccountmetadata:  name: privileged-sa  namespace: psp-test---apiVersion: apps/v1kind: Deploymentmetadata:  labels:    app: privileged-deploy  name: privileged-deploy  namespace: psp-testspec:  replicas: 1  selector:    matchLabels:      app: privileged-deploy  template:    metadata:      labels:        app: privileged-deploy    spec:      containers:      - image: alpine        name: alpine        stdin: true        tty: true        securityContext:          privileged: true      hostPID: true      hostNetwork: true      serviceAccountName: privileged-sa
$ kubectl -n psp-test apply -f deploy-privileged.yaml$ kubectl -n psp-test describe rs privileged-deploy-7569b9969dName: privileged-deploy-7569b9969dNamespace: defaultSelector: app=privileged-deploy,pod-template-hash=7569b9969dLabels: app=privileged-deploy...Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedCreate 4s (x14 over 45s) replicaset-controller Error creating: pods "privileged-deploy-7569b9969d-" is forbidden: unable to validate against any pod security policy: [spec.securityContext.hostNetwork: Invalid value: true: Host network is not allowed to be used spec.securityContext.hostPID: Invalid value: true: Host PID is not allowed to be used spec.containers[0].securityContext.privileged: Invalid value: true: Privileged containers are not allowed]

复制代码


在这种情况下,由于我们创建了 ClusterRoleBinding,所以 Pod 可以使用 PSP,但是 restricted-psp 不会验证 Pod,因为它需要 privileged 、hostNetwork 等参数。


我们已经在前文中看到了 restricted-psp 策略。让我们检查一下 default-psp 的细节,这是由 Rancher 在启用 PSP 允许这些特权时创建的:


$ kubectl get psp default-psp -o yaml
apiVersion: policy/v1beta1kind: PodSecurityPolicymetadata: annotations: seccomp.security.alpha.kubernetes.io/allowedProfileNames: '*' creationTimestamp: "2020-03-10T08:45:08Z" name: default-psp resourceVersion: "144774" selfLink: /apis/policy/v1beta1/podsecuritypolicies/default-psp uid: 1f83b803-bbee-483c-8f66-bfa65feaef56spec: allowPrivilegeEscalation: true allowedCapabilities: - '*' fsGroup: rule: RunAsAny hostIPC: true hostNetwork: true hostPID: true hostPorts: - max: 65535 min: 0 privileged: true runAsUser: rule: RunAsAny seLinux: rule: RunAsAny supplementalGroups: rule: RunAsAny volumes: - '*'
复制代码


你可以看到这是一个非常宽松的策略,特别是我们允许 privileged、hostNetwork、hostPID、hostIPC、hostPorts 以及以 root 身份运行以及其他功能。


我们只需要明确允许该 Pod 使用 PSP。我们通过创建类似于现有 restricted-clusterrole 的 ClusterRole,但允许使用 default-psp 资源,然后为我们的 psp-test 命名空间创建 RoleBinding 来将 privileged-sa ServiceAccount 绑定到该 ClusterRole:


$ cat clusterrole-use-privileged.yaml---apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRolemetadata:  name: use-privileged-psprules:- apiGroups: ['policy']  resources: ['podsecuritypolicies']  verbs:     ['use']  resourceNames:  - default-psp---  apiVersion: rbac.authorization.k8s.io/v1  kind: RoleBinding  metadata:    name: privileged-role-bind    namespace: psp-test  roleRef:    apiGroup: rbac.authorization.k8s.io    kind: ClusterRole    name: use-privileged-psp  subjects:  - kind: ServiceAccount    name: privileged-sa$ kubectl -n psp-test apply -f clusterrole-use-privileged.yaml
复制代码


一会儿之后,特权 Pod 将会被创建。然后你会注意到 restricted-psp 和 default-psp 现在已经可以直接使用。接下来,我们来详细介绍一下它们。

在 Rancher 上默认的 PSP

在 Rancher 中通过编辑集群设置来启用 PSP 准入控制,并选择其中一个已经定义好的 PSP 作为默认选项:



Rancher 将在集群中创建一对 PSP 资源:


  • restricted-psp:如果你选择“受限(restricted)”作为默认的 PSP

  • default-psp:默认的 PSP,允许创建特权 Pod。


除了 restricted-psp 和 default-psp,Rancher 还会创建名为 restricted-clusterrole 的 ClusterRole:


  annotations:    serviceaccount.cluster.cattle.io/pod-security: restricted  creationTimestamp: "2020-03-10T08:44:39Z"  labels:    cattle.io/creator: norman  name: restricted-clusterrolerules:- apiGroups:  - extensions  resourceNames:  - restricted-psp  resources:  - podsecuritypolicies  verbs:  - use
复制代码


此 ClusterRole 允许使用 restricted-psp 策略。那么 Binding 在何处才可以允许授权使用 pod ServiceAccount 呢?


对于属于 Rancher 中项目的命名空间,它还在其中为你设置 RoleBinding 配置:


$ kubectl -n default get rolebinding default-default-default-restricted-clusterrole-binding -o yamlapiVersion: rbac.authorization.k8s.io/v1kind: RoleBindingmetadata:  annotations:    podsecuritypolicy.rbac.user.cattle.io/psptpb-role-binding: "true"    serviceaccount.cluster.cattle.io/pod-security: restricted  labels:    cattle.io/creator: norman  name: default-default-default-restricted-clusterrole-binding  namespace: default...roleRef:  apiGroup: rbac.authorization.k8s.io  kind: ClusterRole  name: restricted-clusterrolesubjects:- kind: ServiceAccount  name: default  namespace: default
复制代码


资源名称(default-default-default-restricted-clusterrole-binding)可能会令人感到困惑,实际上它的构成为:


default- serviceaccountname-namespace -restricted-clusterrole-binding


并且如果你创建一个类似 myserviceaccount 的新的 service account,那么将会自动创建一个新的角色绑定:


$ kubectl create sa myserviceaccountserviceaccount/myserviceaccount created$ kubectl get rolebindingNAME                                                              AGE---default-default-default-restricted-clusterrole-binding            13mdefault-myserviceaccount-default-restricted-clusterrole-binding   4s
复制代码


借助这种神奇的功能,你无需为不需要任何提升特权的安全 pod 配置 RBAC。

在 Rancher 中创建你的 PSP

PSP 是一个标准的 Kubernetes 资源,全程是 Pod 安全策略,所以你可以通过 Kubernetes API 或 kubectl CLI 来使用它。


你可以通过在 YAML 文件中定义它们来创建你的自定义 PSP,然后使用 kubectl 在集群中创建资源。查看官方文档即可了解所有可用控件(https://kubernetes.io/docs/concepts/policy/pod-security-policy/)。在 YAML 中定义了控件集之后,你可以运行:


$ kubectl create psp my-custom-psp
复制代码


以创建 PSP 资源。


使用 Rancher,你可以从 UI 中直接查看或添加新的策略:


PSP 十分强大,但也十分复杂

配置 Pod 安全策略是一个十分乏味的过程。你在 Kubernetes 集群中启用 PSP 之后,你想要部署的任意 Pod 都必须经由其中一个 PSP 允许。实施强大的安全策略可能十分耗时,而且为每个应用程序的每个 deployment 生成一个策略也是一种负担。如果你的策略十分宽松,那么不强制执行最小特权访问方法;然而,如果它存在很多限制,你可能会破坏你的应用程序,因为 Pod 无法在 Kubernetes 中成功运行。


能够以最少的访问要求集自动生成 Pod 安全策略,将帮助你更轻松地安装 PSP。并且你不能只在生产环境中部署它们,而不验证你的应用程序是否可以正常工作,而且进行手动测试既繁琐又效率低下。如果你可以针对 Kubernetes 工作负载的运行时行为验证 PSP 呢?

如何简化生产环境中 PSP 的使用?

Kubernetes Pod 安全策略 Advisor(又名 kube-psp-advisor)是一个 Sysdig 的开源工具。kube-psp-advisor 会从 Kubernetes 资源(如 deployment、daemonset、replicaset 等)中扫描现有的安全上下文,将其作为我们想要执行的 reference 模型,然后在整个集群中为所有资源自动生成 Pod 安全策略。kube-psp-advisor 通过查看不同的属性以创建推荐的 Pod 安全策略:


  • allowPrivilegeEscalation

  • allowedCapabilities

  • allowedHostPaths

  • hostIPC

  • hostNetwork

  • hostPID

  • Privileged

  • readOnlyRootFilesystem

  • runAsUser

  • Volume


查看 kube-psp-advisor 教程,以获取有关其工作原理的更多详细信息:


https://sysdig.com/blog/enable-kubernetes-pod-security-policy/

使用 Sysdig Secure 自动生成 PSP

Sysdig Secure Kubernetes Policy Advisor 可以帮助用户创建和验证 Pod 安全策略。


第一步是设置新的 PSP 模拟环境。你可以针对不同范围内的不同策略(例如 Kubernetes 命名空间)进行多种模拟。


Sysdig 在你的 Deployment 定义中分析 Pod 规范的要求,并为你的应用程序创建权限最小的 PSP。这可以控制是否允许特权 Pod,用户将其作为容器、volume 等运行。Ni 可以微调 PSP 并针对你将要运行的模拟环境定义命名空间:



左侧的策略会破坏应用程序,因为 nginx Deployment 是特权 Pod,并且具有主机网络访问权限。你必须决定是扩大 PSP 以允许这种行为,还是选择减少 Deployment 的特权以适应该策略。无论如何,你在应用 PSP 之前都会检测到此情况,这会阻止 Pod 运行并在应用程序部署上造成破坏。

结论

如这些示例所示,通过授予或拒绝对特定资源的访问,PSP 使你可以对在 Kubernetes 中运行的 Pod 和容器进行精细控制。这些策略相对来说容易创建和部署,并且应该是任何 Kubernetes 安全策略的有用组件。


2020-05-25 16:41594

评论

发布
暂无评论
发现更多内容

阿里云 EMAS & 魔笔:4月产品动态

移动研发平台EMAS

阿里云 DevOps 消息推送 低代码平台 兼容性测试

Django认证系统

测吧(北京)科技有限公司

测试

重塑财务计划,拥抱全面预算管理的未来

智达方通

业财融合 全面预算管理 财务计划

开源工具系列7:Kube-bench

HummerCloud

Kubernetes 云原生安全

今日分享丨inBuilder低代码平台有关前端的“道、法、术、器”

inBuilder低代码平台

前端 低代码平台

酷家乐x极盾科技:“智能安全决策平台”助力日均十亿级日志分析

极盾科技

数据安全

iOS MachineLearning 系列(13)—— 语音与音频相关的AI能力

珲少

Alibaba技术官熬夜肝出的,Kafka“限量笔记”牛掰!

程序知音

Java kafka java架构 Java进阶 后端技术

程序员最终会被自己开发的轮子所淘汰吗?

这我可不懂

程序员 低代码 JNPF

ChatGPT会如何影响我们,会让我们失业吗?兼与吴军博士商榷 | 社区征文

李韧

人工智能 ChatGPT 三周年征文

联合索引该如何选择合适的列?

江南一点雨

MySQL

【干货集】PCBA板边器件布局重要性

华秋PCB

工具 电路 PCB 布局 PCB设计

JMeter实时性能监控平台实战

测吧(北京)科技有限公司

测试

企业办公转型的出路在哪里?华为云桌面开创办公新形式

轶天下事

安卓机上 4G 内存跑 alpaca,欢迎试用轻量级 LLM 模型推理框架 InferLLM

MegEngineBot

开源 大模型 MegEngine LLM

接口测试

测吧(北京)科技有限公司

测试

数字化管理时代来临,瓴羊Quick BI、帆软Fine BI领跑国产BI市场

对不起该用户已成仙‖

Alibaba开发十年,写出这本“MQ技术手册”,看完我愣住了

程序知音

Java RocketMQ 消息中间件 Java进阶 后端技术

开启数字化,传统工厂该如何布局?

优秀

数字化 数字工厂

mac软件卸载不干净怎么办?

真大的脸盆

Mac Mac 软件 软件卸载工具 卸载软件

软件测试 | 编程语言中的Interface

测吧(北京)科技有限公司

测试

案例实践|云智慧ITSM产品在利星行汽车的运维实践

云智慧AIOps社区

运维 ITSM ITSM软件 ITSM解决方案 IT 运维

看火山引擎DataLeap如何做好电商治理(一):挑战与痛点

字节跳动数据平台

监控 模型 电商 数据平台 DataLeap

一文带你直观感受,BPM管理系统如何在低代码平台实现搭建

加入高科技仿生人

低代码 数字化 系统开发 BPM

10年IT老兵亲述SpringCloud开发从入门到实战文档

程序知音

Java 微服务 java架构 Java进阶 spring-cloud

数据标注——数字世界的基石

来自四九城儿

华为云大数据治理轻量级解决方案为中长尾企业赋能

轶天下事

神奇,声网Web SDK还能这么实现直播中美颜功能

声网

前端 Web RTC 美颜

JAVA快速开发框架 一键生成表单模板代码

力软低代码开发平台

什么是点对点传输?什么是点对多传输

镭速

业务出海,华为云全球加速服务GA助一臂之力

轶天下事

实例演示:如何简化生产中的Pod安全策略?_文化 & 方法_Rancher_InfoQ精选文章