繁体   English   中英

如何使用 SELinux 在 Kube.netes 中挂载 HostPath Volume

[英]How to mount HostPath Volume in Kubernetes with SELinux

我正在尝试将hostPath 卷挂载到 Kube.netes Pod 中。 下面显示了hostPath卷规范的示例,该示例取自文档。 我正在部署到运行启用了 SELinux 的 RHEL 7 的主机。

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: k8s.gcr.io/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /test-pd
      name: test-volume
  volumes:
  - name: test-volume
    hostPath:
      # directory location on host
      path: /data
      # this field is optional
      type: Directory

当我的 Pod 尝试读取已从底层主机挂载的文件时,我收到“权限被拒绝”错误。 当我运行setenforce 0关闭 SELinux 时,错误消失,我可以访问该文件。 当我将一个目录绑定到 Docker 容器时,我得到了同样的错误。

此处描述了该问题,并且在使用 Docker 时,可以通过使用zZ绑定安装标志来修复,如Docker文档中所述。

虽然我可以通过运行来解决问题

chcon -Rt svirt_sandbox_file_t /path/to/my/host/dir/to/mount

我认为这是一个令人讨厌的 hack,因为我需要在我的 Kube.netes 集群中的每个主机上执行此操作,还因为我在 YAML 规范中描述的 Kube.netes 部署并未完整描述需要什么完成以使我的 YAML 正常运行。 关闭 SELinux 不是一个选项。

我可以看到 Kube.netes 在此处的文档中提到了 SELinux 安全上下文,但是我无法在没有出现权限被拒绝错误的情况下成功地将 hostPath 卷挂载到 pod 中。

YAML 需要是什么样子才能使容器成功地从运行 SELinux 的底层主机挂载 HostPath 卷?

更新:

我正在访问的文件是具有以下标签的 CA 证书:

system_u:object_r:cert_t:s0

当我使用以下选项时:

securityContext:
  seLinuxOptions:
    level: "s0:c123,c456"

然后通过ausearch -m avc -ts recent检查访问控制审计错误,我可以看到存在权限被拒绝错误,其中容器的级别 label 为s0:c123,c456 ,所以我可以看到级别 label 有效. 我已将 label 设置为s0

但是,如果我尝试将type label 更改为cert_t ,容器甚至不会启动,就会出现错误:

container_linux.go:247: starting container process caused "process_linux.go:364: container init caused \"write /proc/self/task/1/attr/exec: invalid argument\""

我似乎无法更改容器的类型 label。

您可以使用seLinuxOptions分配 SELinux 标签:

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: k8s.gcr.io/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /test-pd
      name: test-volume
    securityContext:
      seLinuxOptions: # it may don’t have the desired effect
        level: "s0:c123,c456"
  securityContext:
    seLinuxOptions:
      level: "s0:c123,c456"
  volumes:
  - name: test-volume
    hostPath:
      # directory location on host
      path: /data
      # this field is optional
      type: Directory

根据文档

感谢Phil指出这一点。 根据问题评论,它似乎只在Pod.spec.securityContext工作

  • seLinuxOptions :支持 SELinux 标签的卷被重新标记为可通过 seLinuxOptions 下指定的标签访问。 通常你只需要设置电平部分。 这将设置为Pod 中的所有容器以及 Volumes 提供的多类别安全 (MCS) 标签。

扩展VAS 的答案,因为它部分正确:

在重新标记hostPath卷指向的路径目标时,您只能指定 SELinux 标签的级别部分 这是由自动完成这样seLinuxOptions.level在您指定的属性securityContext

但是, seLinuxOptions.type等属性目前对卷重新标记没有影响。 在撰写本文时,这仍然是Kubernetes 中的一个悬而未决的问题

您可以尝试使用完全权限:

 ...
 image: k8s.gcr.io/test-webserver
 securityContext:
   privileged: true
 ...

使用selinux可以解决这个问题。 参考文章: https://zhimin-wen.medium.com/selinux-policy-for-openshift-containers-40baa1c86aa5

另外:可以参考selinux参数设置挂载目录的增删改查 https://selinuxproject.org/page /ObjectClassesPerms

我的设置:

如果一个目录的 selinux 是 unconfined_u:object_r:kube.netes_file_t:s0,你可以定义一个 selinux 策略:

module myapp 1.0;

require {
 type kubernetes_file_t;
 type container_t;
 class file { create open read unlink write getattr execute setattr link };
 class dir { add_name create read remove_name write };
}

#============= container_t ==============

#!!!! This avc is allowed in the current policy
allow container_t kubernetes_file_t:dir { add_name create read remove_name write };

#!!!! This avc is allowed in the current policy
allow container_t kubernetes_file_t:file { create open read unlink write getattr execute setattr link };

在节点上运行命令:

sudo checkmodule -M -m -o myapp.mod myapp.te
sudo semodule_package -o myapp.pp -m myapp.mod
sudo semodule -i myapp.pp

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM