阻止Kubernetes用户创建特权容器



我目前正在尝试研究是否有可能阻止Kubernetes用户通过RBAC创建特权容器。我知道,从Kubernetes 1.1开始,特权容器默认启用以支持底层Docker需求。这很好,我不希望阻止每个人能够运行特权容器。

然而,我想研究最小特权原则。例如,我希望防止能够使用kubectl node-shell之类的东西的用户能够获得对工作节点的根访问权,最好是通过RBAC。

这可能吗?

有几种方法可以实现这一点,我想从第一个正式的方法开始:Pod安全策略。

需要执行的策略如下:Privileged

决定pod中的任何容器是否可以启用特权模式。默认情况下,容器不允许访问主机上的任何设备,但可以访问"特权"设备。容器被赋予对主机上所有设备的访问权。这使得容器几乎拥有与主机上运行的进程相同的访问权限。这对于想要使用linux功能(如操作网络堆栈和访问设备)的容器非常有用。

Kubernetes文档提供了一些关于如何与PSP交互的示例,尽管必须声明一个大免责声明:受控的PodSecurityPolicy准入必须在API服务器上激活。

除了官方的准入控制器,还有其他项目允许执行容器匹配标准的拒绝,以及作为特权运行:Gatekeeper, Kyverno。

还有其他项目可以解决您的用例,但我想分享最后两个项目,因为它们看起来最有前途。

例子
  • 看门人
  • Kyverno

一旦在您的集群上启用了PodSecurityPolicies,标准建议创建3个级别的策略:

特权
  • >基线
  • 限制那么您必须使用RBAC将这些策略映射到您的用户。这里有一个极简主义的例子:https://github.com/k8s-school/kind-travis-ci/tree/master/psp。一旦启用了PodSecurityPolicies,它至少允许引导控制平面,实际上,kube-proxy和CNI daemonset,以及coredns部署服务帐户需要在PodSecurityPolicies上有一些权限,以便能够创建相关的pod。
  • 从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

    相关内容

    • 没有找到相关文章

    最新更新