我目前正在尝试研究是否有可能阻止Kubernetes用户通过RBAC创建特权容器。我知道,从Kubernetes 1.1开始,特权容器默认启用以支持底层Docker需求。这很好,我不希望阻止每个人能够运行特权容器。
然而,我想研究最小特权原则。例如,我希望防止能够使用kubectl node-shell之类的东西的用户能够获得对工作节点的根访问权,最好是通过RBAC。
这可能吗?
有几种方法可以实现这一点,我想从第一个正式的方法开始:Pod安全策略。
需要执行的策略如下:Privileged
决定pod中的任何容器是否可以启用特权模式。默认情况下,容器不允许访问主机上的任何设备,但可以访问"特权"设备。容器被赋予对主机上所有设备的访问权。这使得容器几乎拥有与主机上运行的进程相同的访问权限。这对于想要使用linux功能(如操作网络堆栈和访问设备)的容器非常有用。
Kubernetes文档提供了一些关于如何与PSP交互的示例,尽管必须声明一个大免责声明:受控的PodSecurityPolicy准入必须在API服务器上激活。
除了官方的准入控制器,还有其他项目允许执行容器匹配标准的拒绝,以及作为特权运行:Gatekeeper, Kyverno。
还有其他项目可以解决您的用例,但我想分享最后两个项目,因为它们看起来最有前途。
例子- 看门人
- Kyverno
一旦在您的集群上启用了PodSecurityPolicies,标准建议创建3个级别的策略:
特权从1.23开始,正确的答案是使用由Pod安全许可控制器强制执行的Pod安全标准,该标准从1.23开始默认包含。K8s在1.25中删除了Pod安全策略(PSP), PSP在1.23中已弃用。
K8s带有3个预定义的Pod安全标准:特权,基线和限制。执行基线和限制标准都可以防止特权舱。但是,restricted可能对您的pod限制太大,所以我建议从基线标准开始。
执行基线Pod安全标准
对命名空间实施pod安全标准有阻止新pod部署到该命名空间的风险。所以让我们先做一个演练,而不是直接执行基线。
运行试运行并检查是否抛出任何警告:
kubectl label --dry-run=server --overwrite ns default
pod-security.kubernetes.io/enforce=baseline
如果你看到命名空间/default被标记而没有任何警告,那么这意味着如果基线被强制执行,那么当前在命名空间default中运行的所有pod都将被允许。
假设没有警告。让我们从在默认名称空间上执行基线标准开始:
kubectl label --overwrite ns default
pod-security.kubernetes.io/enforce=baseline
注意,这次没有添加——dry-run=server参数。
让我们验证特权pod确实被阻塞了。
创建名为nginx-priv的文件。内容如下:
apiVersion: v1
kind: Pod
metadata:
name: nginx-priv
spec:
containers:
- name: nginx-priv
image: nginx:1.14.2
ports:
- containerPort: 80
securityContext:
privileged: true
尝试创建特权pod:
kubectl apply -f nginx-priv.yaml
您应该看到以下输出:
Error from server (Forbidden): error when creating "nginx-priv.yaml": pods "nginx-priv" is forbidden: violates PodSecurity "baseline:latest": privileged (container "nginx-priv" must not set securityContext.privileged=true)
注意,您也可以像这样在所有命名空间中强制执行基线(可能在部署新pod时导致问题):
kubectl label --overwrite ns --all
pod-security.kubernetes.io/enforce=baseline
免责声明:我是以下来源的作者
来源:https://samos-it.com/posts/Preventing-Privileged-pods-using-Pod-Security-Admission-Standards.html