2

我知道这个问题被问了很多次,但都是关于 docker 的,这次是 crio。

CentOS Linux release 7.6
CRI-O Version: 1.16.1
Kubernetes: v1.16.3
KubeAdm: v1.16.3

CoreDNS pod 处于 Error/CrashLoopBackOff 状态,并且 audit.log 显示 selinux 阻止 CoreDNS 从 /var/lib/kubelet/container_id/volumes/ 读取

type=AVC msg=audit(1576203392.727:1431): avc: denied { read } for pid=15866 comm="coredns" name="Corefile" dev="dm-0" ino=35369330 scontext=system_u:system_r:container_t:s0:c307,c586 tcontext=system_u:object_r:var_lib_t:s0 tclass=file permissive=1

type=AVC msg=audit(1576203392.727:1431): avc: denied { open } for pid=15866 comm="coredns" path="/etc/coredns/..2019_12_13_02_13_30.965446608/Corefile" dev="dm-0" ino=35369330 scontext=system_u:system_r:container_t:s0:c307,c586 tcontext=system_u:object_r:var_lib_t:s0 tclass=file permissive=1

type=AVC msg=audit(1576203393.049:1432): avc: denied { open } for pid=15866 comm="coredns" path="/var/run/secrets/kubernetes.io/serviceaccount/..2019_12_13_02_13_30.605147375/token" dev="tmpfs" ino=124481 scontext=system_u:system_r:container_t:s0:c307,c586 tcontext=system_u:object_r:tmpfs_t:s0 tclass=file permissive=1

如果我使用比 1.7 更新的 docker,它可以正常工作,我认为这可能与带有 z/Z 选项的安装卷补丁有关。

我可以像下面那样添加策略,但它会损害安全性。

module coredns 0.1;

require {
  type tmpfs_t;
  type container_t;
  type var_lib_t;

  class file { open read };
}

allow container_t tmpfs_t:file open;
allow container_t var_lib_t:file { open read };

有没有更好的解决方案?就像 docker 一样,稍加努力,并且不损害安全性。

4

3 回答 3

2

我已经调查过了,似乎问题出在kubelet 版本上。让我详细说明一下:

SELinux 卷未在 1.16 中重新标记- 此链接提供有关该问题的更多详细信息。

我试图在不同版本的 Kubernetes 上重现这个 coredns 问题。

问题显示在 1.16 及更高版本上。在版本 1.15.6 上启用 SELinux 似乎可以正常工作

为此,您需要工作的 CentOS 和 CRI-O 环境。

CRI-O 版本:

Version:  0.1.0
RuntimeName:  cri-o
RuntimeVersion:  1.16.2
RuntimeApiVersion:  v1alpha1

为了部署这个基础设施,我大部分时间都在关注这个网站:KubeVirt

Kubernetes v1.15.7

重现步骤

  • 禁用 SELinux 并重启机器:
    • $ setenforce 0
    • $ sed -i s/^SELINUX=.*$/SELINUX=disabled/ /etc/selinux/config
    • $ reboot
  • 通过调用命令检查 SELinux 是否被禁用:$ sestatus
  • 安装软件包$ yum install INSERT_PACKAGES_BELOW
    • kubelet-1.15.7-0.x86_64
    • kubeadm-1.15.7-0.x86_64
    • kubectl-1.15.7-0.x86_64
  • 使用以下命令初始化 Kubernetes 集群$ kubeadm init --pod-network-cidr=10.244.0.0/16
  • 等待集群正确初始化并按照 kubeadm 指令连接集群
  • 应用法兰绒 CNI$ kubectl apply -f https://github.com/coreos/flannel/raw/master/Documentation/kube-flannel.yml

使用以下命令检查 coredns pod 是否正常运行: $ kubectl get pods -A

它应该给出类似的输出:

NAMESPACE     NAME                                         READY   STATUS    RESTARTS   AGE
kube-system   coredns-5c98db65d4-2c7lt                     1/1     Running   2          7m59s
kube-system   coredns-5c98db65d4-5dp9s                     1/1     Running   2          7m59s
kube-system   etcd-centos-kube-master                      1/1     Running   2          7m20s
kube-system   kube-apiserver-centos-kube-master            1/1     Running   2          7m4s
kube-system   kube-controller-manager-centos-kube-master   1/1     Running   2          6m55s
kube-system   kube-flannel-ds-amd64-mzh27                  1/1     Running   2          7m14s
kube-system   kube-proxy-bqll8                             1/1     Running   2          7m58s
kube-system   kube-scheduler-centos-kube-master            1/1     Running   2          6m58s

禁用 SELinux的 kubernetes 集群中的 Coredns pod工作正常。

启用 SELinux

从 root 帐户调用命令以启用 SELinux 并重新启动机器:

  • $ setenforce 1
  • $ sed -i s/^SELINUX=.*$/SELINUX=enforcing/ /etc/selinux/config
  • $ reboot

检查 coredns pod 是否正常运行。它们在运行时不应出现 crashloopbackoff 错误kubectl get pods -A

Kubernetes v1.16.4

重现步骤

  • $ kubeadm reset如果来自另一个版本,则运行
  • 删除旧的 Kubernetes 包$ yum remove OLD_PACKAGES
  • 禁用 SELinux 并重启机器:
    • $ setenforce 0
    • $ sed -i s/^SELINUX=.*$/SELINUX=disabled/ /etc/selinux/config
    • $ reboot
  • 通过调用命令检查 SELinux 是否被禁用:$ sestatus
  • 安装软件包$ yum install INSERT_PACKAGES_BELOW
    • kubelet-1.16.4-0.x86_64
    • kubeadm-1.16.4-0.x86_64
    • kubectl-1.16.4-0.x86_64
  • 使用以下命令初始化 Kubernetes 集群$ kubeadm init --pod-network-cidr=10.244.0.0/16
  • 等待集群正确初始化并按照 kubeadm 指令连接集群
  • 应用法兰绒 CNI$ kubectl apply -f https://github.com/coreos/flannel/raw/master/Documentation/kube-flannel.yml

使用以下命令检查 coredns pod 是否正常运行: $ kubectl get pods -A

它应该给出类似的输出:

NAMESPACE     NAME                                         READY   STATUS             RESTARTS   AGE
kube-system   coredns-5644d7b6d9-fgbkl                     1/1     Running            1          13m
kube-system   coredns-5644d7b6d9-x6h4l                     1/1     Running            1          13m
kube-system   etcd-centos-kube-master                      1/1     Running            1          12m
kube-system   kube-apiserver-centos-kube-master            1/1     Running            1          12m
kube-system   kube-controller-manager-centos-kube-master   1/1     Running            1          12m
kube-system   kube-proxy-v52ls                             1/1     Running            1          13m
kube-system   kube-scheduler-centos-kube-master            1/1     Running            1          12m

启用 SELinux

从 root 帐户调用命令以启用 SELinux 并重新启动机器:

  • $ setenforce 1
  • $ sed -i s/^SELINUX=.*$/SELINUX=enforcing/ /etc/selinux/config
  • $ reboot

重启 coredns 后,pod应该会进入 crashloopbackoff 状态,如下图所示:

NAMESPACE     NAME                                         READY   STATUS             RESTARTS   AGE
kube-system   coredns-5644d7b6d9-fgbkl                     0/1     CrashLoopBackOff   25         113m
kube-system   coredns-5644d7b6d9-x6h4l                     0/1     CrashLoopBackOff   25         113m
kube-system   etcd-centos-kube-master                      1/1     Running            1          112m
kube-system   kube-apiserver-centos-kube-master            1/1     Running            1          112m
kube-system   kube-controller-manager-centos-kube-master   1/1     Running            1          112m
kube-system   kube-proxy-v52ls                             1/1     Running            1          113m
kube-system   kube-scheduler-centos-kube-master            1/1     Running            1          112m

来自 pod 的日志coredns-5644d7b6d9-fgbkl显示:

plugin/kubernetes: open /var/run/secrets/kubernetes.io/serviceaccount/token: permission denied
于 2020-01-06T11:35:55.670 回答
2

在主机上执行以下操作

chcon -R -t container_file_t /var/lib/kubelet/container_id/volumes

这将更改主机卷上的标签,以便容器 SELinux 标签可以访问。

我不知道处理秘密传递的好方法。但是添加

允许 container_t tmpfs_t:文件打开;

应该是最好的。

我相信,在 OpenShift 中,这些都是自动处理的。虽然我不在堆栈的那个级别工作。

于 2019-12-28T11:41:38.730 回答
0

我是通过下面的命令完成的。

semanage fcontext -a -t container_file_t "/var/lib/kubelet/pods/pod_id/volumes(/.*)?"
restorecon -R -v /var/lib/kubelet/pods/pod_id/
于 2020-01-07T01:06:11.060 回答