Kubernetes 中的 Pod 安全策略
来源:伪架构师
作者:崔秀龙
很多人分不清 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: pause
version: v1
spec:
containers:
- name: sleep
image: k8s.gcr.io/pause
securityContext:
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: common
containers:
...
spec:
serviceAccount: common
containers:
...
提交变更,会发现非特权 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-proxy
serviceAccountName: 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 安全策略的更多相关文章
- kubernetes高级之pod安全策略
系列目录 什么是pod安全策略 pod安全策略是集群级别的用于控制pod安全相关选项的一种资源.PodSecurityPolicy定义了一系列pod相要进行在系统中必须满足的约束条件,以衣一些默认的约 ...
- 傲视Kubernetes(三):Kubernetes中的Pod
从本文开始,将正式开始Kubernetes的核心内容学习.首先要了解的是Pod,总共大约分为六篇左右,本篇是第一篇,相信学完之后,我们会对Pod有一个整体的理解. 本文内容: 1.什么是Pod 2.P ...
- kubernetes 中,Pod、Deployment、ReplicaSet、Service 之间关系分析
deploy控制RS,RS控制Pod,这一整套,向外提供稳定可靠的Service. 详见:https://blog.csdn.net/ucsheep/article/details/81781509
- (译)Kubernetes中的多容器Pod和Pod内容器间通信
原文:https://www.mirantis.com/blog/multi-container-pods-and-container-communication-in-kubernetes/Pave ...
- Kubernetes中 Pod 是怎样被驱逐的?
前言 在 Kubernetes 中,Pod 使用的资源最重要的是 CPU.内存和磁盘 IO,这些资源可以被分为可压缩资源(CPU)和不可压缩资源(内存,磁盘 IO).可压缩资源不可能导致 Pod 被驱 ...
- Kubernetes中资源清单与Pod的生命周期(二)
一.资源清单 1,定义: 在k8s中一般使用yaml格式的文件来创建符合我们预期的资源,这样的yaml被称为资源清单. 使用资源清单创建Pod: kubectl apply -f nginx.yaml ...
- 实操教程丨使用Pod安全策略强化K8S安全
本文来自Rancher Labs 什么是Pod安全策略? Kubernetes Pod安全策略(PSP)是Kubernetes安全版块中极为重要的组件.Pod安全策略是集群级别的资源,用于控制Pod安 ...
- kubernetes集群pod使用tc进行网络资源限额
kubernetes集群pod使用tc进行网络资源限额 Docker容器可以实现CPU,内存,磁盘的IO限额,但是没有实现网络IO的限额.主要原因是在实际使用中,构建的网络环境是往超级复杂的大型网络. ...
- [Kubernetes]深入解析Pod
Pod是Kubernetes项目的原子调度单位 为什么需要Pod? 容器是未来云计算系统中的进程,容器镜像就是这个系统里的".exe"安装包,那Kubernetes就是操作系统. ...
随机推荐
- Wireshark(四):网络性能排查之TCP重传与重复ACK
原文出处: EMC中文支持论坛 作为网络管理员,很多时间必然会耗费在修复慢速服务器和其他终端.但用户感到网络运行缓慢并不意味着就是网络问题. 解决网络性能问题,首先从TCP错误恢复功能(TCP重传与重 ...
- 图数据库HugeGraph:HugeGraph-Hubble基于Web的可视化图管理初体验
原创/朱季谦 一.HugeGraph-Hubble简介 关于HugeGraph,官方资料是这样介绍的,它是一款易用.高效.通用的开源图数据库系统(Graph Database), 实现了 Apache ...
- 成本资源(Project)
<Project2016 企业项目管理实践>张会斌 董方好 编著 张同学说,成本资源就是balabalabala--算了,反正就是一种资源,比如,张同学列出的差旅费.住宿费.交通费.通信费 ...
- CF897B Chtholly's request 题解
Content 我们将长度为偶数的回文数称作 zcy 数,比如 \(11,1221\) 是 zcy 数,而 \(34,121\) 不是.假设第 \(i\) 个 zcy 数为 \(a_i\),求 \(\ ...
- AcWing422. 校门外的树
题目: 某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米. 我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置:数轴上的每个整数点,即0,1,2,--,L,都种 ...
- 刷完 900 多题后的首次总结:LeetCode 应该怎么刷?
「负雪明烛」公众号是负雪明烛维护的一个算法题解公众号,致力于帮助大家刷题.找工作.欢迎关注. 大家好,我是负雪明烛.今天跟大家聊一聊「LeetCode应该怎么刷?」这个话题. 我是大二的时候开始接触 ...
- 【LeetCode】968. Binary Tree Cameras 解题报告(C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...
- 【LeetCode】880. Decoded String at Index 解题报告(Python)
[LeetCode]880. Decoded String at Index 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzhu 个人博 ...
- 【LeetCode】735. Asteroid Collision 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 栈 日期 题目地址:https://leetcode ...
- 《HelloGitHub》第 69 期
兴趣是最好的老师,HelloGitHub 让你对编程感兴趣! 简介 HelloGitHub 分享 GitHub 上有趣.入门级的开源项目. https://github.com/521xueweiha ...