很多人分不清 SecurityContext 和 PodSecurityPolicy 这两个关键字的差别,其实很简单:

•SecurityContext 是 Pod 中的一个字段,而 PSP 是一个独立的资源类型。

•SecurityContext 是 Pod 自身对安全上下文的声明;

而 PSP 则是强制实施的——不合规矩的 Pod 无法创建。

PSP 的用法和 RBAC 是紧密相关的,换句话说,应用 PSP 的基础要求是:

•不同运维人员的操作账号需要互相隔离并进行单独授权。

•不同命名空间,不同 ServiceAccount 也同样要纳入管理流程。

PSP 环境下,运维人员或者新应用要接入集群,除了 RBAC 设置之外,还需要声明其工作范围所需的安全策略,并进行绑定,才能完成工作。

PSP 的官方文档中提到,PSP 是通过 Admission Controller 启用的,并且注明了:启用 PSP 是一个有风险的工作,未经合理授权,可能导致 Pod 无法创建。

开始之前,首先设置一个别名,在 default 命名空间新建 ServiceAccount 来模拟一个有权创建 Pod 的用户:

$ kubectl create sa common
serviceaccount/common created$ kubectl create rolebinding common --clusterrole=edit --serviceaccount=default:common
rolebinding.rbac.authorization.k8s.io/common created$ alias kube-common='kubectl --as=system:serviceaccount:default:common'

第一个 PSP

我们首先创建一个不允许创建特权 Pod 的策略:

apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: noprivileged
spec:
privileged: false
seLinux:
rule: RunAsAny
supplementalGroups:
rule: RunAsAny
runAsUser:
rule: RunAsAny
fsGroup:
rule: RunAsAny
volumes:
- '*'

保存为 psp.noprivileged.yaml 并提交给集群。

接下来创建两个 Pod:

apiVersion: v1
kind: Pod
metadata:
name: noprivileged
spec:
containers:
- name: pause

image: k8s.gcr.io/pause

apiVersion: v1 kind: Pod metadata: name: privileged spec: containers: - name: pause image: k8s.gcr.io/pause securityContext:   privileged: true

用普通用户创建这个 Pod:

$ kube-common apply -f pod.yaml && kube-common delete -f pod.yaml
pod/noprivileged created
pod/privileged created
pod "noprivileged" deleted
pod "privileged" deleted

可以看到,在不允许创建特权容器的规则之中,我们的用户还是能够创建特权容器,这是因为还没启用 PSP,接下来在集群设置中启动 PSP,各种环境的启用方式不同,例如在 GKE 环境:

$ gcloud beta container clusters update gcp-k8s --enable-pod-security-policy --zone=asia-east1-a
Updating gcp-vlab-k8s...done.
删除重建 Pod:
$ kube-common apply -f pod.yaml && kube-common delete -f pod.yaml
Error from server (Forbidden): error when creating "pod.yaml": pods "noprivileged" is forbidden: unable to validate against any pod security policy: []
Error from server (Forbidden): error when creating "pod.yaml": pods "privileged" is forbidden: unable to validate against any pod security policy: []

可以看到,Pod 的新建请求被拒绝了——然而使用集群管理员身份还是能成功创建的:

$ kubectl apply -f pod.yaml && kubectl delete -f pod.yaml
pod/noprivileged created
pod/privileged created
pod "noprivileged" deleted
pod "privileged" deleted

全员 admin 是万恶之源。

用 RBAC 进行授权:

$ kubectl create role psp:noprivileged \
--verb=use \
--resource=podsecuritypolicy \
--resource-name=noprivileged
role.rbac.authorization.k8s.io/psp:noprivileged created$ kubectl create rolebinding common:psp:noprivileged \
--role=psp:noprivileged \
--serviceaccount=default:common
rolebinding.rbac.authorization.k8s.io/common:psp:noprivileged created

再试试普通用户的能力:

$ kube-common apply -f pod.yaml ; kube-common delete -f pod.yaml
pod/noprivileged created
Error from server (Forbidden): error when creating "pod.yaml": pods "privileged" is forbidden: unable to validate against any pod security policy: [spec.containers[0].securityContext.privileged: Invalid value: true: Privileged containers are not allowed]
pod "noprivileged" deleted
Error from server (NotFound): error when deleting "pod.yaml": pods "privileged" not found

非特权 Pod 才能够成功创建,这符合我们的预期。

副作用

Pod 成功创建了之后,顺理成章,做个 Deployment 看看:

kind: Deployment
metadata:
name: privileged
spec:
replicas: 1
template:
metadata:labels:app: pauseversion: v1
spec:containers:- name: sleepimage: k8s.gcr.io/pausesecurityContext:
privileged: true
apiVersion: extensions/v1beta1 kind: Deployment metadata: name: noprivileged spec: replicas: 1 template: serviceAccount: common metadata:   labels:     app: pause     version: v1 spec:   containers:   - name: sleep     image: k8s.gcr.io/pause
我们会发现,Deployment 无法正常工作:
$ kubectl get pods
kuNo resources found in default namespace.
$ kubectl get deployment
NAME           READY   UP-TO-DATE   AVAILABLE   AGE
noprivileged   0/1     0            0           15m
privileged     0/1     0            0           15m

查看一下事件:

$ kubectl get events | grep policy
8m38s       Warning   FailedCreate        replicaset/noprivileged-6f94f9c9b8                 Error creating: pods "noprivileged-6f94f9c9b8-" is forbidden: unable to validate against any pod security policy: []
8m38s       Warning   FailedCreate        replicaset/privileged-6d78d5458                    Error creating: pods "privileged-6d78d5458-" is forbidden: unable to validate against any pod security policy: []

这次的 Pod 不是由我们授权的 common 用户创建的,而是由 RS Controller 启动的,因此会失败,加入一个 Service Account:

...
spec:serviceAccount: commoncontainers:
...
spec:serviceAccount: commoncontainers:
...

提交变更,会发现非特权 Pod 开始创建:

$ kubectl get pods
NAME                            READY   STATUS    RESTARTS   AGE
noprivileged-6cf595c5bd-rc8cx   1/1     Running   0          4s

系统 Pod 怎么办

这时候我想到个问题,其它 Pod 会不会受到影响?我删除了 kube-system 下面的一个 kube-proxy的 Pod,发现这个 Pod 自动重建了,没有受到 PSP 的影响,查看一下 RBAC 相关配置,会发现 GCP 在更新集群的过程中已经为系统服务进行了预设:

$ kubectl get rolebinding
...
gce:podsecuritypolicy:kube-proxy                    80m
gce:podsecuritypolicy:metadata-agent                80m
gce:podsecuritypolicy:metadata-proxy                80m
gce:podsecuritypolicy:nodes                         80m
...

追查下去:

$ kubectl get rolebinding gce:podsecuritypolicy:metadata-proxy -o yaml
...
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: gce:podsecuritypolicy:privileged
subjects:
- kind: ServiceAccount
name: metadata-proxy
namespace: kube-system
如果追查其中涉及到的 ClusterRole,会发现它指向一个 PSP:
$ kubectl get clusterrole gce:podsecuritypolicy:privileged -o yaml
...
rules:
- apiGroups:
- policy
resourceNames:
- gce.privileged
resources:
- podsecuritypolicies
verbs:
- use
看看这个 PSP 的内容:
$ kubectl get psp  gce.privileged -o yaml
...
privileged: true
...

的确包含了特权 Pod 的内容。

最后看看负责创建这个特权 Pod 的 Daemonset:

$  kubectl get daemonset  metadata-proxy-v0.1 -o yaml
...serviceAccount: metadata-proxyserviceAccountName: metadata-proxy
...

PSP的限制能力

分为以下几个大方面:

•特权容器

•主机命名空间:

例如 HostPID、HostNetwork 等。

•卷和文件系统:

例如 PVC、configMap、emptyDir 等卷类型,以及 fsGroup、AllowedHostPaths 等加载能力。

•用户和组:

运行身份

•提权:

是否允许

•Capability 和 sysctl

•SeLinux、AppArmor 等。

马后炮

kubectl 的 advise-psp 插件,能够根据当前运行的 Pod,提取出所需的 PSP 信息。

参考链接:

•https://kubernetes.io/docs/con ... licy/

来源:伪架构师

作者:崔秀龙

Kubernetes 中的 Pod 安全策略相关推荐

  1. Kubernetes 中创建 Pod 时集群中到底发生了些什么?

    想象一下,如果我想将 nginx 部署到 Kubernetes 集群,我可能会在终端中输入类似这样的命令: $ kubectl run --image=nginx --replicas=3 然后回车. ...

  2. Kubernetes 中 设置pod不部署在同一台节点上

    在k8s中,节点的调度主要由亲和性和污点来进行控制的.   而在亲和性部分由分为了节点亲和性和节点反亲和性.   节点亲和性是指在pod部署时,尽量(软策略)或者必须满足(硬策略)部署在某些节点上. ...

  3. Kubernetes 中 Evicted pod 是如何产生的

    线上被驱逐实例数据 最近在线上发现很多实例处于 Evicted 状态,通过 pod yaml 可以看到实例是因为节点资源不足被驱逐,但是这些实例并没有被自动清理,平台的大部分用户在操作时看到服务下面出 ...

  4. Kubernetes 学习总结(25)—— Kubernetes 中的 pod 与容器的区别和联系

    前言 容器本可以成为轻量级虚拟机的替代品.但是由于 Docker/OCI 的标准化,最广泛使用的容器形式是每个容器只有一个进程服务.这种方法有很多优点--增加隔离性.简化水平扩展.更高的可重用性等.但 ...

  5. Kubernetes 中的 Pod 是什么?

    前言 本文隶属于专栏<1000个问题搞定大数据技术体系>,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢! 本专栏目录结构和参考文献请见1000个问题搞定大数据技 ...

  6. kubernetes中给pod加hosts解析

    在一些环境中,有些服务会绑定一个域名,这个时候我们想去访问这个服务的域名就需要做下对应的解析,经常使用的做法是在主机的/etc/hosts文件里面加上域名对应的ip方可访问,如果给在k8s上运行的po ...

  7. 为 Kubernetes 集群启用 Pod 安全策略

    最近有客户反馈在开启了安全策略的集群中部署产品失败,因此研究了一下 Kubernetes 提供的 pod 安全策略. 文中的演示和示例均在 v1.18.17 集群中通过验证. Pod Security ...

  8. 安全策略_实操教程丨使用Pod安全策略强化K8S安全

    什么是Pod安全策略? Kubernetes Pod安全策略(PSP)是Kubernetes安全版块中极为重要的组件.Pod安全策略是集群级别的资源,用于控制Pod安全相关选项,并且还是一种强化Kub ...

  9. 容器编排技术 -- Pod 安全策略

    容器编排技术 -- Pod 安全策略 1 什么是 Pod 安全策略? 1.1 RunAsUser 1.2 SELinux 1.3 SupplementalGroups 1.4 FSGroup 1.5  ...

最新文章

  1. 本月Github热门开源项目排行榜...
  2. 使用JQuery从客户端调用C#方法
  3. python进阶-第二季第一章
  4. Linux从入门到精通——磁盘与目录的容量(du、df)
  5. Struts2显示double价格格式0.00
  6. sencha touch调试时Please close other application using ADB: Monitor, DDMS, Eclipse
  7. Python的安装路径
  8. Linux命令--- /dev/null和/dev/tty
  9. 验证码——ImageIO.write的坑
  10. 全国计算机等级考试在线报名,全国计算机等级考试网上报考具体流程
  11. 金融银行测试面试题:网上银行转账是怎么测的?
  12. 一些学习网址,centos镜像下载地址
  13. objective-C的内存管理机制琢磨不透
  14. 【安装库】WARNING: A newer version of conda exists.
  15. 以开发之名|线上家装新美学——梦想之家,由你来定
  16. 2021年三季度中国医疗服务行业A股上市企业营收排行榜:国际医学于1月17日起戴帽,简称变更为“ST国医”(附热榜TOP37详单)
  17. 2021CUDA编程:加速计算基础 —— CUDA C/C++
  18. 由于文件组 'PRIMARY 中的磁盘空间不足,无法为数据库 'newnet' 分配新页。请删除文件组中的对象、将其他文件添加到文件组或者为文件组中的现有文件启用自动增长,以便增加必要的空间。
  19. python中的继承的初始化_python中子类继承父类的__init__方法实例
  20. matlab程序 地震 相干噪声_地震资料读写相干噪声的消除

热门文章

  1. T 客汇盘点:2017 年备受关注的 20 家企业级服务公司
  2. 苹果删除的短信怎么恢复?两个用过都说好的操作技巧
  3. 微软的bing(www.bing.com.cn)
  4. 兵棋推演系统软件开发方法有哪些呢
  5. 递归和迭代在图遍历中的对比-栈结构
  6. ViTDet:Exploring Plain Vision Transformer Backbonesfor Object Detection(arXiv 2022)
  7. MatLab 的界面文字模糊解决【强迫症福音】
  8. Java--多态(polymorphic),上下转型,多态好处弊端
  9. 《庄子.齐物论》天地一指 万物一马
  10. 庄子 内篇 齐物论第二