Kubeadm: Experiências SElinux para quem quer saber

Criado em 10 jan. 2017  ·  85Comentários  ·  Fonte: kubernetes/kubeadm

Olá a todos,

Portanto, tenho lutado com minha configuração especial durante todo o fim de semana, mas tenho que desistir e deixar que outras pessoas vejam isso.
Então, no windows, vagrant e ansible, posso compartilhar minhas coisas, se quiser.

Fatos:
versão mais recente do repo no guia.
usando o fedora 24 como imagens na caixa virtual com o vagrant

Então, seguindo o guia, eu fiz funcionar, com setenforce permissivo, kubeadm é executado com calico. No meu caso, tenho uma pequena máquina para executar o ansible, configurando um mestre e um nó.

Primeiro tentei com a aplicação de setenforce, e fiquei preso no famoso, "esperando o avião de controle ficar pronto", e então usei um novo terminal para examiná-lo. Parece que na verdade o etcd está entrando em conflito com o selinux devido aos tipos de diferenças. No manifesto estático, no código em kubernetes / cmd / kubeadm / app / master / manifest.go, posso ver que ele é executado com o tipo spc_t, enquanto tudo é executado no docker, o próprio etcd é executado em svirt_sandbox_file_t, então sim, entra em conflito . Acho que tem a ver com os volumes anexados ou com o processo de tentar gravar no volume no host mestre.

Vejo problemas semelhantes com os scripts de rede de pod.

Alguém alguma ideia?

Apenas tentando fazer isso funcionar com o SElinux desde o início;)

Obrigado,

Comentários muito úteis

Sim @eparis está correto. Tenho que obter um patch para docker para lidar com a etiquetagem corretamente. Precisamos permitir a flexibilidade do usuário (ou seja, a capacidade de quebrar seu sistema se ele assim escolher).

O caso padrão deve ser que todos os processos de contêiner que compartilham o mesmo namespace IPC compartilham o mesmo rótulo SELinux, mas se um usuário pedir para substituir o rótulo, isso deve ser permitido.

Todos 85 comentários

@dgoodwin

@coeki Não acho que documentamos tecnicamente as instalações do Fedora, presumo que você usou os repositórios Centos7. Qual docker você usou, o do Fedora ou do Docker Inc? Você poderia incluir detalhes sobre as negações?

spc_t deve estar correto de acordo com http://danwalsh.livejournal.com/2016/10/03/

@jasonbrooks , você tem alguma opinião sobre isso, potencial precipitação de https://github.com/kubernetes/kubernetes/pull/37327

Vou tentar encontrar algum tempo para ver se consigo reproduzir esta semana.

Reproduzido:

type=AVC msg=audit(1484057408.459:2715): avc:  denied  { entrypoint } for  pid=16812 comm="exe" path="/usr/local/bin/etcd" dev="dm-6" ino=4194436 scontext=system_u:system_r:spc_t:s0:c133,c303 tcontext=system_u:object_r:svirt_sandbox_file_t:s0:c133,c303 tclass=file permissive=0

Não acontece no CentOS 7 até onde eu sei.

Oi,

Sim, esse é o tipo de erro que estou vendo. Para esclarecimento, sim, usei o repositório Centos e usei o docker do repositório Fedoras.

Vou fazer uma verificação rápida se isso acontece com o Centos7 ainda hoje.

Obrigado,

Oi,

Na verdade também acontece no centos7:

type = AVC msg = audit (1484065309.021: 634): avc: denied {entrypoint} para pid = 12204 comm = "exe" path = "/ usr / local / bin / etcd" dev = "dm-9" ino = 4194436 scontext = system_u: system_r: spc_t: s0: c390, c679 tcontext = system_u: object_r: svirt_sandbox_file_t: s0: c390, c679 tclass = arquivo
type = AVC msg = audit (1484065310.113: 637): avc: denied {entrypoint} para pid = 12263 comm = "exe" path = "/ usr / local / bin / etcd" dev = "dm-9" ino = 4194436 scontext = system_u: system_r: spc_t: s0: c220, c274 tcontext = system_u: object_r: svirt_sandbox_file_t: s0: c220, c274 tclass = file
type = AVC msg = audit (1484065323.851: 661): avc: denied {entrypoint} para pid = 12550 comm = "exe" path = "/ usr / local / bin / etcd" dev = "dm-9" ino = 4194436 scontext = system_u: system_r: spc_t: s0: c425, c863 tcontext = system_u: object_r: svirt_sandbox_file_t: s0: c425, c863 tclass = arquivo

Em relação à postagem de Dan Walsh, também vi http://danwalsh.livejournal.com/75011.html , então acho que as coisas mudaram.

Outras coisas que estou vendo:

[ root @ localhost vagrant] # ls -Z / var / lib / | container grep
drwx ----- x. root root system_u: object_r: container_var_lib_t: s0 docker
drwxr-xr-x. root root system_u: object_r: container_var_lib_t: s0 etcd
[ root @ localhost vagrant] # ls -Z / var / lib / | grep kubelet
drwxr-x ---. root root system_u: object_r: var_lib_t: s0 kubelet

[ root @ localhost vagrant] # ls -Z / var / lib / kubelet / pods / 3a26566bb004c61cd05382212e3f978f / containers / etcd /
-rw-r - r--. root root system_u: object_r: svirt_sandbox_file_t: s0: c425, c863 00cb813c
-rw-r - r--. root root system_u: object_r: svirt_sandbox_file_t: s0: c220, c274 066b8a86
-rw-r - r--. root root system_u: object_r: svirt_sandbox_file_t: s0: c390, c679 0c8e84af
-rw-r - r--. root root system_u: object_r: svirt_sandbox_file_t: s0: c12, c477 342bd480
-rw-r - r--. root root system_u: object_r: svirt_sandbox_file_t: s0: c215, c768 995f6946
-rw-r - r--. root root system_u: object_r: svirt_sandbox_file_t: s0: c23, c405 e184aa90
-rw-r - r--. root root system_u: object_r: svirt_sandbox_file_t: s0: c65, c469 eb05320c

O mesmo no Centos e no Fedora. Não tenho certeza de qual é o caminho a seguir, mas acho que não precisamos mais especificar os tipos SElinux em nenhum manifesto. Pelo menos para o kubeadm, a rede de pod é outra história.

Pensamentos?

Obrigado,

Estou cutucando isso agora.

Obrigado @jasonbrooks.

FWIW CentOS7 foi limpo para mim com:

(root<strong i="8">@centos1</strong> ~) $ kubeadm reset
[preflight] Running pre-flight checks
[reset] Stopping the kubelet service
[reset] Unmounting mounted directories in "/var/lib/kubelet"
[reset] Removing kubernetes-managed containers
[reset] No etcd manifest found in "/etc/kubernetes/manifests/etcd.json", assuming external etcd.
[reset] Deleting contents of stateful directories: [/var/lib/kubelet /etc/cni/net.d]
[reset] Deleting contents of config directories: [/etc/kubernetes/manifests /etc/kubernetes/pki]
[reset] Deleting files: [/etc/kubernetes/admin.conf /etc/kubernetes/kubelet.conf]
(root<strong i="9">@centos1</strong> ~) $ getenforce
Enforcing
(root<strong i="10">@centos1</strong> ~) $ rpm -qa | grep kube
kubelet-1.5.1-0.x86_64
kubeadm-1.6.0-0.alpha.0.2074.a092d8e0f95f52.x86_64
kubectl-1.5.1-0.x86_64
kubernetes-cni-0.3.0.1-0.07a8a2.x86_64
(root<strong i="11">@centos1</strong> ~) $ ls -lZ /var/lib | grep docker
drwx-----x. root    root    system_u:object_r:docker_var_lib_t:s0 docker/
drwxr-xr-x. root    root    system_u:object_r:docker_var_lib_t:s0 etcd/
drwxr-xr-x. root    root    system_u:object_r:docker_var_lib_t:s0 kubeadm-etcd/
(root<strong i="12">@centos1</strong> ~) $ rpm -qa | grep selinux
selinux-policy-targeted-3.13.1-60.el7_2.3.noarch
libselinux-2.2.2-6.el7.x86_64
docker-selinux-1.10.3-46.el7.centos.10.x86_64
libselinux-utils-2.2.2-6.el7.x86_64
libselinux-python-2.2.2-6.el7.x86_64
selinux-policy-3.13.1-60.el7_2.3.noarch

O init do kubeadm estava funcionando e este era o ambiente com o qual eu estava testando para verificar se as coisas estavam bem.

Então pensei em verificar se minhas máquinas vagrant estavam executando a política mais recente e isso pegou um monte de atualizações selinux, após o que o init do kubeadm agora falha com a negação fornecida por @coeki. Portanto, algo deu errado com a política mais recente. Depois da minha atualização:

(root<strong i="17">@centos1</strong> ~) $ rpm -qa | grep selinux
libselinux-2.5-6.el7.x86_64
docker-selinux-1.10.3-46.el7.centos.14.x86_64
selinux-policy-targeted-3.13.1-102.el7_3.7.noarch
libselinux-python-2.5-6.el7.x86_64
selinux-policy-3.13.1-102.el7_3.7.noarch
libselinux-utils-2.5-6.el7.x86_64
container-selinux-1.10.3-59.el7.centos.x86_64

Veja isso. CentOS 7 com docker-selinux:

$ sesearch -T -s docker_t | grep spc_t
   type_transition docker_t docker_share_t : process spc_t; 
   type_transition docker_t unlabeled_t : process spc_t; 
   type_transition docker_t docker_var_lib_t : process spc_t;

E depois de instalar o container-selinux:

$ sesearch -T -s docker_t | grep spc_t
   type_transition container_runtime_t container_var_lib_t : process spc_t; 
   type_transition container_runtime_t container_share_t : process spc_t;

Sim, adicionei exclude=container-selinux ao meu repositório fedora-updates e o init kubeadm é concluído conforme o esperado.

ping @rhatdan

Portanto, devemos documentar exclude=container-selinux como uma solução para ter o SELinux ativado ( setenforce 1 ) e executar o kubeadm?

Estou pensando que precisaremos de uma correção selinux para resolver isso.

Em 10 de janeiro de 2017, 22:41, "Lucas Käldström" [email protected] escreveu:

Portanto, devemos documentar exclude = container-selinux como uma solução para ter
SELinux ativado (setenforce 1) e executando kubeadm?

-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/kubernetes/kubeadm/issues/107#issuecomment-271791032 ,
ou silenciar o tópico
https://github.com/notifications/unsubscribe-auth/AAG52vBqKyMAcSj62oGqazI2hWETd-RPks5rRHmZgaJpZM4Le4yP
.

Depois de ler a postagem mencionada de Dan Walsh (http://danwalsh.livejournal.com/75011.html) um pouco melhor, ou há um erro ao aliar os tipos docker_t ao novo nome genérico para os tipos de contêiner container_t ou não ser puxado ainda.

Outra linha de pensamento. Não tenho certeza de como os contêineres do docker são iniciados pelo kubernetes, mas uma correção também pode ser lançar os contêineres com os novos tipos de contêiner.

Ignore a última observação, é o tempo de execução do contianer do sistema operacional, é claro, então sim a observação de

@ lsm5 podemos obter uma versão atualizada do container-selinux para o Fedora 24. Parece estar um pouco desatualizado.

@rhatdan @ lsm5 também está ruim no CentOS 7 mais recente

Qual versão do docker, docker-selinux, container-selinux o Centos 7 tem?

De cima:

(root<strong i="6">@centos1</strong> ~) $ rpm -qa | grep selinux
libselinux-2.5-6.el7.x86_64
docker-selinux-1.10.3-46.el7.centos.14.x86_64
selinux-policy-targeted-3.13.1-102.el7_3.7.noarch
libselinux-python-2.5-6.el7.x86_64
selinux-policy-3.13.1-102.el7_3.7.noarch
libselinux-utils-2.5-6.el7.x86_64
container-selinux-1.10.3-59.el7.centos.x86_64

No meu comentário acima, você também pode ver as versões anteriores que eu tinha onde tudo estava funcionando, e então começa a falhar após uma atualização do yum para essas versões.

@dgoodwin você pode experimentar o container-selinux mais recente para CentOS 7? Você pode obtê-lo usando este repo:

[virt7-docker-common-candidate]
name=virt7-docker-common-candidate
baseurl=https://cbs.centos.org/repos/virt7-docker-common-candidate/x86_64/os/
enabled=1
gpgcheck=0

Veja: https://wiki.centos.org/Cloud/Docker

Ainda falhando @ lsm5

(root<strong i="7">@centos1</strong> ~) $ rpm -qa | grep selinux                                                                                                     
libselinux-2.5-6.el7.x86_64
selinux-policy-targeted-3.13.1-102.el7_3.7.noarch
libselinux-python-2.5-6.el7.x86_64
selinux-policy-3.13.1-102.el7_3.7.noarch
container-selinux-2.2-3.el7.noarch
libselinux-utils-2.5-6.el7.x86_64

type=AVC msg=audit(1484146410.625:156): avc:  denied  { entrypoint } for  pid=2831 comm="exe" path="/usr/local/bin/etcd" dev="dm-8" ino=8388868 scontext=system_u:system_r:spc_t:s0:c590,c748 tcontext=system_u:object_r:svirt_sandbox_file_t:s0:c590,c748 tclass=file
type=AVC msg=audit(1484146437.147:168): avc:  denied  { entrypoint } for  pid=3102 comm="exe" path="/usr/local/bin/etcd" dev="dm-9" ino=8388868 scontext=system_u:system_r:spc_t:s0:c73,c888 tcontext=system_u:object_r:svirt_sandbox_file_t:s0:c73,c888 tclass=file
type=AVC msg=audit(1484146454.690:174): avc:  denied  { entrypoint } for  pid=3269 comm="exe" path="/usr/local/bin/etcd" dev="dm-9" ino=8388868 scontext=system_u:system_r:spc_t:s0:c184,c206 tcontext=system_u:object_r:svirt_sandbox_file_t:s0:c184,c206 tclass=file
type=AVC msg=audit(1484146479.755:179): avc:  denied  { entrypoint } for  pid=3375 comm="exe" path="/usr/local/bin/etcd" dev="dm-9" ino=8388868 scontext=system_u:system_r:spc_t:s0:c245,c784 tcontext=system_u:object_r:svirt_sandbox_file_t:s0:c245,c784 tclass=file
type=AVC msg=audit(1484146529.400:190): avc:  denied  { entrypoint } for  pid=3637 comm="exe" path="/usr/local/bin/etcd" dev="dm-9" ino=8388868 scontext=system_u:system_r:spc_t:s0:c893,c1013 tcontext=system_u:object_r:svirt_sandbox_file_t:s0:c893,c1013 tclass=file

Você pode ter certeza de que o container-selinux foi instalado com sucesso?

dnf reinstalar o container-selinux

Eu tentei com a última versão do container-selinux ontem no CentOS
e também tentei o container-selinux que está em teste de atualizações para f25,
o mesmo problema.

Em 11 de janeiro de 2017 07:32, "Daniel J Walsh" [email protected] escreveu:

Você pode ter certeza de que o container-selinux foi instalado com sucesso?

dnf reinstalar o container-selinux

-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/kubernetes/kubeadm/issues/107#issuecomment-271899571 ,
ou silenciar o tópico
https://github.com/notifications/unsubscribe-auth/AAG52tRhNh6En1hfbZJzzGISzNUnhVfKks5rRPYUgaJpZM4Le4yP
.

Acho que esse bloqueio está falhando silenciosamente.

optional_policy (`
virt_stub_svirt_sandbox_file ()
virt_transition_svirt_sandbox (spc_t, system_r)
virt_sandbox_entrypoint (spc_t)
virt_sandbox_domtrans (container_runtime_t, spc_t)
')

Ainda falhando após a reinstalação.

Estou configurando uma máquina CENTOS para verificar o que está errado.

Obrigado pela ajuda a todos, seria legal se pudéssemos ter setenforce 1 trabalhando com kubeadm no próximo lançamento;)

Oi,

Tentei com o fedora 25 cloud base, o mesmo resultado que em, não instalando, mas com mensagens diferentes:

horário-> sábado, 21 de janeiro 13:55:37 de 2017

type = AVC msg = audit (1485006937.554: 8062): avc: denied {create} for pid = 676 comm = "etcd" name = "data" scontext = system_u: system_r: container_t: s0: c358, c612 tcontext = system_u: object_r : container_var_lib_t: s0 tclass = dir permissivo = 0

horário-> sáb 21 jan 13:57:08 2017

type = AVC msg = audit (1485007028.572: 8075): avc: denied {create} for pid = 1181 comm = "etcd" name = "data" scontext = system_u: system_r: container_t: s0: c358, c612 tcontext = system_u: object_r : container_var_lib_t: s0 tclass = dir permissivo = 0

horário-> sábado, 21 de janeiro 13:59:53 de 2017
type = AVC msg = audit (1485007193.515: 8088): avc: denied {create} for pid = 1780 comm = "etcd" name = "data" scontext = system_u: system_r: container_t: s0: c358, c612 tcontext = system_u: object_r : container_var_lib_t: s0 tclass = dir permissivo = 0

[ root @ master-01 vagrant] # rpm -qa | grep selinux
libselinux-python3-2.5-13.fc25.x86_64
selinux-policy-3.13.1-225.6.fc25.noarch
libselinux-2.5-13.fc25.x86_64
libselinux-utils-2.5-13.fc25.x86_64
rpm-plugin-selinux-4.13.0-6.fc25.x86_64
selinux-policy-oriented-3.13.1-225.6.fc25.noarch
libselinux-python-2.5-13.fc25.x86_64
container-selinux-2.2-2.fc25.noarch

Opa, desculpe pela marcação na última postagem, não tenho ideia de como isso aconteceu;)

@coeki é por causa do # no início dessas linhas. Eu sugiro recuar as linhas com quatro espaços, o que permite ao GH saber que é o código.

@jberkus obrigado, vou manter isso em mente.

Vou experimentar o Fedora Atômico, que é um jogo totalmente novo para mim. Mas como @rhatdan disse que funciona com isso, estou curioso. Vou relatar minhas descobertas, se conseguir fazer isso funcionar;)

Isso mostra que você montou o volume em um diretório do host para o contêiner do docker, sem reetiquetar. Acho que este é um problema conhecido no K8s e supostamente corrigido nas versões mais recentes.

Acabei de testar isso com f25 e o guia kubeadm daqui . Ele está preso em [apiclient] Created API client, waiting for the control plane to become ready

[root@fedora-1 ~]# rpm -q docker container-selinux kubelet kubeadm
docker-1.12.6-5.git037a2f5.fc25.x86_64
container-selinux-2.2-2.fc25.noarch
kubelet-1.5.1-0.x86_64
kubeadm-1.6.0-0.alpha.0.2074.a092d8e0f95f52.x86_64
[root@fedora-1 ~]# ausearch -m avc -ts recent
----
time->Wed Jan 25 18:47:12 2017
type=AVC msg=audit(1485388032.826:415): avc:  denied  { create } for  pid=9080 comm="etcd" name="data" scontext=system_u:system_r:container_t:s0:c159,c642 tcontext=system_u:object_r:container_var_lib_t:s0 tclass=dir permissive=0
----
time->Wed Jan 25 18:52:43 2017
type=AVC msg=audit(1485388363.049:459): avc:  denied  { create } for  pid=9940 comm="etcd" name="data" scontext=system_u:system_r:container_t:s0:c159,c642 tcontext=system_u:object_r:container_var_lib_t:s0 tclass=dir permissive=0

Tenho uma versão modificada ajustada para funcionar com o atomic neste copr , que inclui a v.1.5.2, mas também foi afetada.

Se eu voltar para a última versão do docker para o fedora antes da transição do docker-selinux para o container-selinux, o kubeadm funcionará bem com a aplicação do selinux:

# rpm -q docker docker-selinux
docker-1.12.1-13.git9a3752d.fc25.x86_64
docker-selinux-1.12.1-13.git9a3752d.fc25.x86_64

Tente instalar o container-selinux a partir do teste de atualizações, embora eu ainda ache que o problema aqui é com o kubernetes lidando com a rotulagem.

Aqui está container-selinux-2.4-1.fc25.noarch :

time->Thu Jan 26 02:49:26 2017
type=AVC msg=audit(1485416966.739:468): avc:  denied  { create } for  pid=9778 comm="etcd" name="data" scontext=system_u:system_r:container_t:s0:c213,c267 tcontext=system_u:object_r:container_var_lib_t:s0 tclass=dir permissive=0
----
time->Thu Jan 26 02:50:13 2017
type=AVC msg=audit(1485417013.023:512): avc:  denied  { create } for  pid=11274 comm="etcd" name="data" scontext=system_u:system_r:container_t:s0:c164,c200 tcontext=system_u:object_r:container_var_lib_t:s0 tclass=dir permissive=1
----
time->Thu Jan 26 02:50:13 2017
type=AVC msg=audit(1485417013.023:513): avc:  denied  { create } for  pid=11274 comm="etcd" name=".touch" scontext=system_u:system_r:container_t:s0:c164,c200 tcontext=system_u:object_r:container_var_lib_t:s0 tclass=file permissive=1
----
time->Thu Jan 26 02:50:13 2017
type=AVC msg=audit(1485417013.023:514): avc:  denied  { write open } for  pid=11274 comm="etcd" path="/var/etcd/data/.touch" dev="dm-0" ino=33776166 scontext=system_u:system_r:container_t:s0:c164,c200 tcontext=system_u:object_r:container_var_lib_t:s0 tclass=file permissive=1
----
time->Thu Jan 26 02:50:13 2017
type=AVC msg=audit(1485417013.023:515): avc:  denied  { unlink } for  pid=11274 comm="etcd" name=".touch" dev="dm-0" ino=33776166 scontext=system_u:system_r:container_t:s0:c164,c200 tcontext=system_u:object_r:container_var_lib_t:s0 tclass=file permissive=1
----
time->Thu Jan 26 02:50:13 2017
type=AVC msg=audit(1485417013.023:516): avc:  denied  { read } for  pid=11274 comm="etcd" path="/var/etcd/data/member/snap/db" dev="dm-0" ino=498029 scontext=system_u:system_r:container_t:s0:c164,c200 tcontext=system_u:object_r:container_var_lib_t:s0 tclass=file permissive=1
----
time->Thu Jan 26 02:50:13 2017
type=AVC msg=audit(1485417013.023:517): avc:  denied  { lock } for  pid=11274 comm="etcd" path="/var/etcd/data/member/snap/db" dev="dm-0" ino=498029 scontext=system_u:system_r:container_t:s0:c164,c200 tcontext=system_u:object_r:container_var_lib_t:s0 tclass=file permissive=1
----
time->Thu Jan 26 02:50:13 2017
type=AVC msg=audit(1485417013.041:518): avc:  denied  { rename } for  pid=11274 comm="etcd" name="wal.tmp" dev="dm-0" ino=17291587 scontext=system_u:system_r:container_t:s0:c164,c200 tcontext=system_u:object_r:container_var_lib_t:s0 tclass=dir permissive=1

O que eu não entendo é como a mesma versão do kubernetes que não funciona com o container-selinux atual ou em teste funciona bem com o docker e docker-selinux mais antigos. O container_t está permitindo tudo que spc_t costumava permitir?

@jasonbrooks se você

Se for algo assim:

  "SecurityOpt": [
                "seccomp=unconfined",
                "label:type:spc_t",
                "label=user:system_u",
                "label=role:system_r",
                "label=type:svirt_lxc_net_t",
                "label=level:s0:c803,c806"
            ],

Você pode estar encontrando um problema separado que surge com o Docker 1.12+, no qual pmorie está trabalhando aqui: https://github.com/kubernetes/kubernetes/pull/40179

@dgoodwin Acabei de fazer uma nova instalação no fedora 25 e posso confirmar tudo o que @jasonbrooks está vendo.

saída do docker inspecione o contêiner etcd:

"SecurityOpt": [
            "seccomp=unconfined",
            "label:type:spc_t",
            "label=user:system_u",
            "label=role:system_r",
            "label=type:container_t",
            "label=level:s0:c122,c403"
        ],

rpm -q container-selinux:

container-selinux-2.2-2.fc25.noarch

Um pouco mais de informação. Ao usar docker-1.12.1-13.git9a3752d.fc25.x86_64 e docker-selinux (que é docker api v1.24), aqui estão as opções de segurança do contêiner etcd:

"SecurityOpt": [
                "seccomp=unconfined",
                "label:type:spc_t"
            ],

Com docker-1.12.6-5.git037a2f5.fc25.x86_64 (também docker api v1.24) e container-selinux, as opções de segurança são:

"SecurityOpt": [
                "seccomp=unconfined",
                "label:type:spc_t",
                "label=user:system_u",
                "label=role:system_r",
                "label=type:container_t",
                "label=level:s0:c306,c898"
            ],

Fazendo a transição de volta para esse problema porque acredito que ainda temos problemas com o selinux de contêiner com o Docker 1.12.

Se você aplicar a correção de https://github.com/kubernetes/kubernetes/issues/37807, isso corrigirá o problema do separador de rótulos acima para que todos os rótulos apareçam com =. No entanto, o problema permanece, container_t continua a ser adicionado após spc_t e o pod será negado.

O reprodutor mais simples que posso encontrar é apenas um cluster de hack local e a criação do manifesto abaixo:

Fedora 25, kubernetes devel com os seguintes pacotes:

docker-1.12.6-5.git037a2f5.fc25.x86_64
container-selinux-2.4-1.fc25.noarch
$ sudo ALLOW_SECURITY_CONTEXT=1 PATH=$PATH:/home/dgoodwin/go/src/k8s.io/kubernetes/third_party/etcd:/home/dgoodwin/go/bin hack/local-up-cluster.sh

in another terminal:

$ kubectl --kubeconfig /var/run/kubernetes/admin.kubeconfig create -f https://gist.githubusercontent.com/dgoodwin/1c19d2ad184ff792f786fec3cd137d0b/raw/beaaaa466b1073cacf4ec92f8ade9da28ad3233e/etcd.json



md5-4ae8d3f78540a9a1aead6709cda723e4



type=AVC msg=audit(1485449563.680:10995): avc:  denied  { create } for  pid=17157 comm="etcd" name=".touch" scontext=system_u:system_r:container_t:s0:c632,c788 tcontext=system_u:object_r:container_var_lib_t:s0 tclass=file permissive=0



md5-cefed6e5c6deb76a7e4f6a58d8b17b81



            "SecurityOpt": [
                "seccomp=unconfined",
                "label=type:spc_t",
                "label=user:system_u",
                "label=role:system_r",
                "label=type:container_t",
                "label=level:s0:c632,c788"
            ],

container_t está substituindo o spc_t que solicitamos no manifesto, como você pode ver aqui: https://gist.githubusercontent.com/dgoodwin/1c19d2ad184ff792f786fec3cd137d0b/raw/beaaaa466b1073cacf4eccd92f8ade9da28ad3233e/etcd

CC @pweil @eparis @pmorie @rhatdan

O container-selinux não tem nada a ver com isso. Parece que é definitivamente um problema do docker. Você deve conseguir instalar a versão anterior do docker com o container-selinux e aposto que o comportamento antigo retornará.

Parece funcionar corretamente do cliente.

docker run -d --security-opt label = type: spc_t fedora sleep 50

            "SecurityOpt": [
                "label=type:spc_t"
            ],

Mas isso mostra bugs semelhantes, mas não todo o outro conteúdo

docker run -ti --security-opt label = type: spc_t --security-opt label = type: container_t fedora sleep 50

            "SecurityOpt": [
                "label=type:spc_t",
                "label=type:container_t"
            ],

@rhatdan @mrunalp com reprodutor @dgoodwin consegui descobrir o que está causando isso para projectatomic / docker com 1.12.6 - que é este patch https://github.com/projectatomic/docker/commit/07f6dff6273f98a2da8731b87f8dd98d86a5d6ff

Reverter isso aparentemente corrige o problema. No entanto, esse patch parece ser necessário e o docker upstream tem esse patch em sua versão mais recente do docker 1.13.0 (então o upstream tem esse mesmo problema no 1.13, mas não no upstream 1.12.6).

@rhatdan qual é o material esperado que entra em SecurityOpt se você especificar mais de um rótulo com o sinalizador security-opt na execução do docker?

docker run -ti --security-opt label = type: spc_t --security-opt label = type: container_t fedora sleep 50

você deseja que a opção de segurança seja apenas container_t ou spc_t? Quer dizer, deve ser um ou outro certo? ambos não podem coexistir certo?

Não tenho certeza se este é um problema do docker ou um problema do kubernetes pela leitura do patch acima, parece que o contêiner de pausa está sendo executado sob confinamento e estamos unindo o processo do contêiner a um contêiner em execução.

O problema parece simples, porém, aqui está a configuração usada para criar a pausa e o contêiner etcd (com o contêiner etcd juntando-se ao namespace ipc do contêiner de pausa):

Jan 28 12:55:23 runcom.usersys.redhat.com dockerd-current[4199]: time="2017-01-28T12:55:23.362797988+01:00" level=debug msg="form data: {\"AttachStderr\":false,\"AttachStdin\":false,\"AttachStdout\":false,\"Cmd\":null,\"Domainname\":\"\",\"Entrypoint\":null,\"Env\":[\"KUBERNETES_PORT=tcp://10.0.0.1:443\",\"KUBERNETES_PORT_443_TCP=tcp://10.0.0.1:443\",\"KUBERNETES_PORT_443_TCP_PROTO=tcp\",\"KUBERNETES_PORT_443_TCP_PORT=443\",\"KUBERNETES_PORT_443_TCP_ADDR=10.0.0.1\",\"KUBERNETES_SERVICE_HOST=10.0.0.1\",\"KUBERNETES_SERVICE_PORT=443\",\"KUBERNETES_SERVICE_PORT_HTTPS=443\"],\"HostConfig\":{\"AutoRemove\":false,\"Binds\":null,\"BlkioDeviceReadBps\":null,\"BlkioDeviceReadIOps\":null,\"BlkioDeviceWriteBps\":null,\"BlkioDeviceWriteIOps\":null,\"BlkioWeight\":0,\"BlkioWeightDevice\":null,\"CapAdd\":null,\"CapDrop\":null,\"Cgroup\":\"\",\"CgroupParent\":\"\",\"ConsoleSize\":[0,0],\"ContainerIDFile\":\"\",\"CpuCount\":0,\"CpuPercent\":0,\"CpuPeriod\":0,\"CpuQuota\":0,\"CpuShares\":2,\"CpusetCpus\":\"\",\"CpusetMems\":\"\",\"Devices\":[],\"DiskQuota\":0,\"Dns\":[\"8.8.8.8\"],\"DnsOptions\":null,\"DnsSearch\":[\"vutbr.cz\",\"usersys.redhat.com\"],\"ExtraHosts\":null,\"GroupAdd\":null,\"IOMaximumBandwidth\":0,\"IOMaximumIOps\":0,\"IpcMode\":\"\",\"Isolation\":\"\",\"KernelMemory\":0,\"Links\":null,\"LogConfig\":{\"Config\":null,\"Type\":\"\"},\"Memory\":0,\"MemoryReservation\":0,\"MemorySwap\":-1,\"MemorySwappiness\":null,\"NetworkMaximumBandwidth\":0,\"NetworkMode\":\"\",\"OomKillDisable\":null,\"OomScoreAdj\":-998,\"PidMode\":\"\",\"PidsLimit\":0,\"PortBindings\":{},\"Privileged\":false,\"PublishAllPorts\":false,\"ReadonlyRootfs\":false,\"RestartPolicy\":{\"MaximumRetryCount\":0,\"Name\":\"\"},\"SecurityOpt\":[\"seccomp=unconfined\"],\"ShmSize\":6.7108864e+07,\"StorageOpt\":null,\"UTSMode\":\"\",\"Ulimits\":null,\"UsernsMode\":\"\",\"VolumeDriver\":\"\",\"VolumesFrom\":null},\"Hostname\":\"etcd\",\"Image\":\"gcr.io/google_containers/pause-amd64<strong i="6">@sha256</strong>:163ac025575b775d1c0f9bf0bdd0f086883171eb475b5068e7defa4ca9e76516\",\"Labels\":{\"io.kubernetes.container.hash\":\"f932fb66\",\"io.kubernet
Jan 28 12:55:23 runcom.usersys.redhat.com dockerd-current[4199]: es.container.name\":\"POD\",\"io.kubernetes.container.restartCount\":\"0\",\"io.kubernetes.container.terminationMessagePath\":\"\",\"io.kubernetes.container.terminationMessagePolicy\":\"\",\"io.kubernetes.pod.name\":\"etcd\",\"io.kubernetes.pod.namespace\":\"default\",\"io.kubernetes.pod.terminationGracePeriod\":\"30\",\"io.kubernetes.pod.uid\":\"a63cff8a-e550-11e6-8c99-507b9d4141fa\"},\"NetworkingConfig\":null,\"OnBuild\":null,\"OpenStdin\":false,\"StdinOnce\":false,\"Tty\":false,\"User\":\"\",\"Volumes\":null,\"WorkingDir\":\"\"}"


Jan 28 12:55:23 runcom.usersys.redhat.com dockerd-current[4199]: time="2017-01-28T12:55:23.948539974+01:00" level=debug msg="form data: {\"AttachStderr\":false,\"AttachStdin\":false,\"AttachStdout\":false,\"Cmd\":null,\"Domainname\":\"\",\"Entrypoint\":[\"etcd\",\"--listen-client-urls=http://127.0.0.1:3379\",\"--advertise-client-urls=http://127.0.0.1:3379\",\"--data-dir=/var/lib/etcd\"],\"Env\":[\"KUBERNETES_SERVICE_PORT=443\",\"KUBERNETES_SERVICE_PORT_HTTPS=443\",\"KUBERNETES_PORT=tcp://10.0.0.1:443\",\"KUBERNETES_PORT_443_TCP=tcp://10.0.0.1:443\",\"KUBERNETES_PORT_443_TCP_PROTO=tcp\",\"KUBERNETES_PORT_443_TCP_PORT=443\",\"KUBERNETES_PORT_443_TCP_ADDR=10.0.0.1\",\"KUBERNETES_SERVICE_HOST=10.0.0.1\"],\"HostConfig\":{\"AutoRemove\":false,\"Binds\":[\"/etc/ssl/certs:/etc/ssl/certs\",\"/var/lib/etcd:/var/lib/etcd\",\"/etc/kubernetes:/etc/kubernetes/:ro\",\"/var/lib/kubelet/pods/a63cff8a-e550-11e6-8c99-507b9d4141fa/volumes/kubernetes.io~secret/default-token-gvxcc:/var/run/secrets/kubernetes.io/serviceaccount:ro,Z\",\"/var/lib/kubelet/pods/a63cff8a-e550-11e6-8c99-507b9d4141fa/etc-hosts:/etc/hosts:Z\",\"/var/lib/kubelet/pods/a63cff8a-e550-11e6-8c99-507b9d4141fa/containers/etcd/692fbb22:/dev/termination-log:Z\"],\"BlkioDeviceReadBps\":null,\"BlkioDeviceReadIOps\":null,\"BlkioDeviceWriteBps\":null,\"BlkioDeviceWriteIOps\":null,\"BlkioWeight\":0,\"BlkioWeightDevice\":null,\"CapAdd\":null,\"CapDrop\":null,\"Cgroup\":\"\",\"CgroupParent\":\"\",\"ConsoleSize\":[0,0],\"ContainerIDFile\":\"\",\"CpuCount\":0,\"CpuPercent\":0,\"CpuPeriod\":0,\"CpuQuota\":0,\"CpuShares\":204,\"CpusetCpus\":\"\",\"CpusetMems\":\"\",\"Devices\":[],\"DiskQuota\":0,\"Dns\":null,\"DnsOptions\":null,\"DnsSearch\":null,\"ExtraHosts\":null,\"GroupAdd\":null,\"IOMaximumBandwidth\":0,\"IOMaximumIOps\":0,\"IpcMode\":\"container:2b4df020a63fa9796c860a065135e06affd372d38dc9e323ca66c0fe010de469\",\"Isolation\":\"\",\"KernelMemory\":0,\"Links\":null,\"LogConfig\":{\"Config\":null,\"Type\":\"\"},\"Memory\":0,\"MemoryReservation\":0,\"MemorySwap\":-1,\"MemorySwappiness\":null,\"NetworkMaximumBandwidth\":0,\"NetworkMode\":\"con
Jan 28 12:55:23 runcom.usersys.redhat.com dockerd-current[4199]: tainer:2b4df020a63fa9796c860a065135e06affd372d38dc9e323ca66c0fe010de469\",\"OomKillDisable\":null,\"OomScoreAdj\":999,\"PidMode\":\"\",\"PidsLimit\":0,\"PortBindings\":null,\"Privileged\":false,\"PublishAllPorts\":false,\"ReadonlyRootfs\":false,\"RestartPolicy\":{\"MaximumRetryCount\":0,\"Name\":\"\"},\"SecurityOpt\":[\"seccomp=unconfined\",\"label:type:spc_t\"],\"ShmSize\":6.7108864e+07,\"StorageOpt\":null,\"UTSMode\":\"\",\"Ulimits\":null,\"UsernsMode\":\"\",\"VolumeDriver\":\"\",\"VolumesFrom\":null},\"Hostname\":\"\",\"Image\":\"gcr.io/google_containers/etcd-amd64<strong i="7">@sha256</strong>:b7b54201ba7ae22e1b7993d86d90615646a736a23abd8561f6012bb0e3dcc075\",\"Labels\":{\"io.kubernetes.container.hash\":\"f46ae33b\",\"io.kubernetes.container.name\":\"etcd\",\"io.kubernetes.container.restartCount\":\"0\",\"io.kubernetes.container.terminationMessagePath\":\"/dev/termination-log\",\"io.kubernetes.container.terminationMessagePolicy\":\"File\",\"io.kubernetes.pod.name\":\"etcd\",\"io.kubernetes.pod.namespace\":\"default\",\"io.kubernetes.pod.terminationGracePeriod\":\"30\",\"io.kubernetes.pod.uid\":\"a63cff8a-e550-11e6-8c99-507b9d4141fa\"},\"NetworkingConfig\":null,\"OnBuild\":null,\"OpenStdin\":false,\"StdinOnce\":false,\"Tty\":false,\"User\":\"\",\"Volumes\":null,\"WorkingDir\":\"\"}"

Você pode ver (bem, descobrir) acima que o contêiner de pausa é criado sem o rótulo spc_t . Em vez disso, o contêiner etcd é criado com o rótulo spc_t .
No docker, quando um contêiner se junta ao namespace ipc de outro, ele obtém rótulos selinux do contêiner de destino. Nesse caso, o docker obtém os rótulos do contêiner de pausa, que é container_t . Em seguida, ele o anexa aos rótulos de segurança do etcd, que é spc_t . Eventualmente você tem ambos e as coisas explodem.

Então, @rhatdan , minha pergunta é, o que temos que fazer? o kubernetes deve executar o contêiner de pausa com spc_t também para que não seja container_t ou o contêiner etcd deve substituir o rótulo do contêiner de pausa se o etcd tiver um? (neste caso, tem spc_t ).

Espero que tudo esteja claro.

Se o aplicativo estiver sendo especificado para ser executado como spc_t, a pausa e todos os contêineres deverão ser executados como spc_t.

O problema do docker é dizer que o label: type : spc_t está sendo passado? Em vez de label = type: spc_t ? Portanto, é um desses problemas que está causando o problema.

Descobri isso com @rhatdan offline. O problema é que o contêiner de pausa também deve estar executando com spc_t basicamente.

@dgoodwin você sabe onde as opções de segurança de um pod são transmitidas para criar o contêiner de pausa? Essas opções de segurança do pod também devem ser aplicadas ao contêiner de pausa ou tudo explode porque esses rótulos podem se comunicar entre si.

Descobri que a opção de segurança do pod é nula aqui https://gist.githubusercontent.com/dgoodwin/1c19d2ad184ff792f786fec3cd137d0b/raw/beaaaa466b1073cacf4ec92f8ade9da28ad3233e/etcd.json, mesmo se houver um contêiner containers .

Como vocês extrairiam o rótulo selinux de um contêiner em containers em PodSpec? os contêineres em containers em PodSpec precisam ter uma forma de concordar apenas com o rótulo selinux _a_ e esse rótulo deve ser usado também para o contêiner de infra.

Pode haver um bug no runc, embora ao definir os rótulos de processo inicial, eu acho. encontrei

@runcom Bug estaria no docker ou no k8s. runc está simplesmente aplicando tudo o que é transmitido. Estamos garantindo que todos os recipientes do pod recebem o mesmo rótulo?

@runcom Bug estaria no docker ou no k8s. runc é simples aplicando apenas o que for transmitido. Estamos garantindo que todos os recipientes do pod recebem o mesmo rótulo?

Quero dizer, há outro bug com rótulos selinux _in docker_. O rótulo não foi aplicado ao processo corretamente.

Certo, o problema é que os contêineres em um pod precisam ter o mesmo rótulo selinux e não faz sentido ter rótulos diferentes para cada recipiente em um pod. Já existe um rótulo selinux de nível de pod e cada contêiner deve usar isso, até mesmo o infra-contêiner.

Alguém concorda com isso? Nesse caso, por que você pode definir um rótulo selinux para contêineres em um pod? Isso deve ser um erro para mim.

@liggitt @pmorie não tenho certeza de quem mais ... agora SecurityContext é um objeto de API container . Mas docker, @runcom e @rhatdan estão dizendo que deve ser um objeto de nível pod ...

Precisamos movê-lo de container para pod ? O que seria um problema de API, obviamente, mas se o docker simplesmente não puder lidar com isso no nível do contêiner ...

Acho que, para ser preciso, devo dizer que pode ser definido em pod e container . Mas se container é sempre ignorado e apenas compartilhado com o contêiner pause (que eu acredito que só está definido no nível pod ), devemos nos livrar dele no Nível container ?

@eparis , que tal ter um no nível do pod e permitir a substituição no contêiner no futuro, se tivermos uma política para isso?

Acredito que seja porque você pode ter vários recipientes e, se algum deles especificar um rótulo diferente, qual você escolheria? Acho que o ponto principal é que o pod como uma unidade só deve definir esse tipo de opções. Os contêineres em um pod estão vinculados às restrições desse pod, não importa o que seja, certo?

Acredito que hoje o contexto de segurança de nível de pod (se definido) é aplicado a todos os contêineres. Se um contexto de segurança no nível do contêiner for definido, o kube tentará sobrescrever o contexto no nível do pod. O que estou ouvindo de vocês é que o contexto de segurança de nível de contêiner é sempre substituído pelo contexto de pause contêiner. e o contêiner pause é sempre == o contexto de segurança no nível do pod. Se não houvesse contexto de segurança no nível do pod, o contêiner de pausa obtém o padrão do docker e, portanto, os (outros) contextos de segurança no nível do contêiner são ignorados ...

portanto, hoje o contexto de segurança do contêiner é inútil, confuso e nunca funcionou ...

O docker deve começar a rejeitar as definições de contêiner que tentam definir rótulos selinux que serão ignorados (por causa de algum namespace compartilhado)? Normalmente o SELinux rejeita situações inválidas em vez de levar o usuário a acreditar que possui propriedades de segurança que não possui.

Sim, podemos apertar o docker para rejeitar configuração SELinux inválida se houver namespaces compartilhados.

@smarterclayton você provavelmente também deveria ler isto. Basicamente, as definições de selinux no nível do contêiner funcionaram no passado, mas foram quebradas por 1.12.5 e 1.13

(digitei errado e editei o último comentário). CONTAINER definições de nível de selinux nunca funcionaram.

Acabei de tentar várias combinações, começando com docker-1.12.1-13.git9a3752d.fc25.x86_64
e container-selinux-2.2-2.fc25.noarch, de fato, container-selinux não fez diferença.

As coisas funcionaram até docker-1.12.4.

Fui ver o que mudou entre .3 e .4 e parece que vocês estão no caso: https://github.com/docker/docker/pull/26792/commits/4c10c2ded38031b20f5a0a409dd24643625fa878 :)

Uma correção foi feita para docker-1.13 que foi portado de volta para docker-1.12, o que revela um bug no k8s. Basicamente, o pod e todos os contêineres nele precisam ser executados no mesmo contexto SELinux. Atualmente k8s não está configurando spc_t para o contêiner de pausa. Quando o processo do contêiner é adicionado ao contêiner de pausa, ele está compartilhando o mesmo namespace IPC. O Docker agora atribui o rótulo SELinux do contêiner de pausa ao contêiner recém-criado, que é o comportamento esperado. Em um POD, precisamos ter todos os contêineres funcionando com o mesmo rótulo SELinux. Se corrigirmos o k8s para atribuir o rótulo ao criar o POD, tudo funcionará.

@eparis Acho que teoricamente poderíamos permitir que vários rótulos sejam atribuídos e verificar no docker se um rótulo está definido antes de definir o rótulo do recipiente para corresponder ao recipiente ao qual está se juntando ao namespace IPC.

Eu pude ver onde você pode querer executar o contêiner principal bloqueado, mas talvez o contêiner do carro lateral com uma política mais frouxa.

Mover o securityContext do contêiner para a especificação do pod permite que o contêiner seja executado corretamente. Vou enviar um patch para o kubeadm para mover isso para um nível acima enquanto isso é resolvido. Obrigado a todos pela ajuda para descobrir o que está errado e onde.

Sim, muito obrigado por esta investigação! Sou um novato no selinux (nunca usei, sou mais um cara do debian), então esse esforço vale seu peso em ouro.

Acho que estamos esperando uma resolução para isso no k8s v1.6, certo?

Além disso, os provedores de rede como weave, flannel, etc. adicionam essas regras selinux para que suas montagens de hostpath funcionem corretamente também? Se for esse o caso, temos que avisá-los a tempo para o próximo lançamento.

Obrigado a todos por darem uma olhada nisso. Então, para recapitular, diga-me se eu li errado:

1 Problema com o formato do rótulo ":" vs "=" trabalhado aqui: # https://github.com/kubernetes/kubernetes/pull/40179
2 Problema com etiquetas sendo anexadas duas vezes, também tratado no PR acima
3 Análise de rótulos conforme relatado por @runcom , tratada aqui # https://github.com/opencontainers/runc/pull/1303
4 Discussão mais ampla sobre se as operações de segurança devem funcionar no nível do contêiner dentro de um pod ou apenas no pod.

@luxas primeiro eu estava tentando consertar o kubeadm e depois dar uma olhada no que exatamente dá errado com os provedores de rede como weave, flannel, canal, calico e romana, provavelmente os mesmos problemas, mas teremos que identificar primeiro, eu acho, para que possamos dizer a eles o que corrigir.

3 Análise de rótulos conforme relatado por @runcom , tratada aqui # opencontainers / runc # 1303

isso é apenas para docker> 1.12.6 - docker no Fedora / RHEL tem 1.12.6 que aplica o rótulo corretamente

Acredito que hoje o contexto de segurança de nível de pod (se definido) é aplicado a todos os contêineres. Se um contexto de segurança de nível de contêiner for definido, o Kube tenta sobrescrever o contexto de nível de pod

Isto está correto. Isso é feito no provedor de contexto de segurança pelo método DetermineEffectiveSecurityContext .

Basicamente, as definições de selinux no nível do contêiner funcionaram no passado, mas foram quebradas por 1.12.5 e 1.13

Sim, podemos apertar o docker para rejeitar configuração SELinux inválida se houver namespaces compartilhados.

@pmorie @mrunalp @eparis - ajude-me a entender a direção correta para o provedor de SC neste cenário. Parece que sempre compartilhamos o namespace IPC com o contêiner de pausa que:

  1. se houver algum rótulo selinux em um contêiner, ele precisa ser aplicado ao contêiner de pausa para compartilhar o namespace IPC
  2. configurações por contêiner realmente não fazem sentido se houver mais de um contêiner no pod com configurações SELinux e essas configurações não corresponderem?

se o item 2 for verdadeiro, então acho que é um forte argumento ter apenas configurações de nível de pod.

Eu diria que o docker precisa iniciar o contêiner de pausa com o contexto de segurança de nível de pod (se definido). Ele precisa iniciar os contêineres reais com o contexto de segurança do contêiner (se definido), retroceder para o contexto do nível do pod (se definido) e, em seguida, retroceder para "compartilhado com pausa". (se indefinido)

Não entendo por que o namespace IPC compartilhado deve ser relevante para esta discussão. Se o usuário define uma combinação de contextos que o selinux não permite que funcionem, então as coisas não deveriam funcionar. Mas o docker nunca deve "sobrescrever" nada que o usuário tenha solicitado.

Eu diria que o docker precisa iniciar o contêiner de pausa com o contexto de segurança de nível de pod (se definido). Ele precisa iniciar os contêineres reais com o contexto de segurança do contêiner (se definido), retroceder para o contexto do nível do pod (se definido) e, em seguida, retroceder para "compartilhado com pausa". (se indefinido)

Então eu acho que não tem nada a ver do lado do provedor. Ele já deve estar definindo as configurações do contêiner de pausa para o nível de pod SC se definido e os contêineres reais obtêm a mesclagem de substituições de pod + contêiner, o que significa que ele deve compartilhar as configurações com pausa se as coisas forem definidas no nível do pod e não no nível do contêiner.

Se o usuário define uma combinação de contextos que o selinux não permite que funcionem, então as coisas não deveriam funcionar. Mas o docker nunca deve "sobrescrever" nada que o usuário tenha solicitado.

Aceita. Obrigado!

Sim @eparis está correto. Tenho que obter um patch para docker para lidar com a etiquetagem corretamente. Precisamos permitir a flexibilidade do usuário (ou seja, a capacidade de quebrar seu sistema se ele assim escolher).

O caso padrão deve ser que todos os processos de contêiner que compartilham o mesmo namespace IPC compartilham o mesmo rótulo SELinux, mas se um usuário pedir para substituir o rótulo, isso deve ser permitido.

O problema neste caso, embora eu não consiga identificar, parece um pouco mais complexo.
As opções de segurança não são substituídas, mas adicionadas duas vezes.

Você pode perceber um pouco quando essa correção não é aplicada:

1 Problema com o formato do rótulo ":" vs "=" trabalhado aqui: # kubernetes / kubernetes # 40179

docker inspecionar o contêiner de pausa:

"SecurityOpt": [
            "seccomp=unconfined",
            "label:type:spc_t"
        ],

Docker inspecionar o contêiner etcd:

  "SecurityOpt": [
            "seccomp=unconfined",
            "label:type:spc_t",
            "label=user:system_u",
            "label=role:system_r",
            "label=type:spc_t",
            "label=level:s0:c23,c719"

O rótulo com o formato "rótulo:" vem do manifesto com o qual iniciamos a implantação do pod etcd. Pelo menos eu acho que sim.

Kubelet ou docker parece adicionar os outros, que meio que fazem sentido para os arquivos de imagem colocados em / var / lib / docker / containers e / var / lib / kubelet / pods

A partir da discussão em # kubernetes / kubernetes # 40179, sabemos que o docker não está impedindo a adição de mais opções de segurança do que deveria ser permitido.
Mas onde ou como esse acréscimo está ocorrendo, não sei dizer.

@eparis @rhatdan Você poderia ajudar a verificar este problema também? Por que seLinuxOptions no nível do pod e no nível do contêiner tem resultados diferentes? obrigado https://github.com/kubernetes/kubernetes/issues/37809

Tenho uma solicitação pull para ajudar a corrigir esse problema no docker
https://github.com/docker/docker/pull/30652

Já descrevemos o problema.

Na janela de encaixe padrão, se você adicionar um contêiner com um rótulo e, em seguida, adicionar outro contêiner ao qual deseja associar o mesmo namespace IPC, o docker pegará o rótulo do primeiro contêiner e o atribuirá ao segundo. Dessa forma, o SELinux não bloqueará o acesso ao IPC criado pelo primeiro contêiner que precisa ser usado pelo segundo contêiner.

O rótulo SELinux type / mcs no nível do pod define o rótulo para o contêiner pause . O SELinux Type / MCS Label no rótulo do contêiner o define para cada contêiner que está se juntando ao pause contêiner.
Se o Kubernetes não definir um rótulo para o contêiner pause ele será rotulado como algo como container_t: s0: c1, c2. Em seguida, o kubernetes tenta adicionar um contêiner com um rótulo como spc_t: s0. Em versões anteriores do docker, o docker veria que o campo security-opt foi definido e não chamaria o código para mesclar os rótulos SELinux. Mas isso estava causando problemas com as pessoas definindo seccomp, basicamente não obteríamos o comportamento esperado de dois contêineres compartilhando o mesmo rótulo SELinux, se qualquer campo sem rótulo fosse definido no security-opt. Um patch foi mesclado upstream para eliminar a verificação de security-opt . Isso introduzia um bug onde se um usuário especificasse um rótulo SELinux security-opt de um contêiner que estava se juntando a outro contêiner para ignorar a opção de segurança.

Conclusão:

Docker antigo, se o contêiner pause / POD viesse sem rótulo, ele começaria com container_t: s0: c1, c2. Se um novo contêiner foi enviado para se juntar ao contêiner pause , com spc_t: s0. O Docker lançaria o segundo contêiner com spc_t: s0, e k8s estava feliz. Após a correção, o segundo contêiner acabou com o container_t mais restritivo: s0: c1, c2 e k8s estava infeliz. A correção correta para o problema no lado k8s é definir o rótulo pause/POD como spc_t: s0 e o contêiner adicionado corresponderá a spc_t: s0.

Com o meu patch acima, permitiremos que os usuários especifiquem rótulos selinux alternativos para cada contêiner adicionado, mas isso só deve ser feito por pessoas que entendem como funciona o confinamento do SELinux. IE Você pode querer configurar um pod de vários contêineres em que um contêiner tenha mais / menos direitos do que o contêiner ao qual está ingressando.

O patch docker teria corrigido o problema do k8s, também, mas não elimina o fato de que o contêiner de pausa provavelmente deveria estar rodando com o mesmo rótulo SELinux dos contêineres que o juntam.

@rhatdan muito obrigado

Então ......... como testar? @dgoodwin @jasonbrooks @rhatdan @jessfraz?

Me desculpe, não sou muito versado em coisas de construção, mas estou disposto a fazê-lo .... Eu tenho alguma pista, mas qualquer ajuda é bem-vinda.
kubernetes / kubernetes # 40179 movido ..... então, como faço para incluir isso?

Obrigado

Ok descobri no fim de semana, mas ainda não está funcionando.

Ok, compilar o kubeadm e o kubelet (esqueci-me desta parte, daí o meu comentário mais recente) a partir do branch master com kubernetes / kubernetes # 40903 mesclado e funciona com a aplicação de selinux, mesmo com o weave em execução, embora o weave não esteja a funcionar corretamente. Esse é um problema de tecer para lidar mais tarde, assim como com os outros provedores que ainda tenho que testar.
Mas pelo menos nenhuma negação do selinux com a aplicação do selinux.

Em relação às entradas duplas referenciadas em kubernetes / kubernetes # 37807:

  "SecurityOpt": [
            "seccomp=unconfined",
            "label=type:spc_t",
            "label=user:system_u",
            "label=role:system_r",
            "label=type:spc_t",
            "label=level:s0:c210,c552"

Acho que isso decorre de alguma validação quando DetermineEffectiveSecurityContext é executado, como @pweil- mencionado, e apenas adicionado, em vez de substituído como opção de segurança do docker. Como o docker é executado com todas as opções passadas, mas usa apenas as últimas opções de segurança passadas, isso parece funcionar. Não tenho certeza se esse é o comportamento esperado para docker, mas isso é uma questão diferente. @rhatdan pode querer dar uma outra olhada nisso, em relação ao docker / docker # 30652

Não tenho certeza se devemos fechar o problema, até obtermos os rpms do repositório oficial, testar novamente e assim por diante, testar a rede do pod primeiro e corrigi-lo, atualizar os documentos etc., antes de fechar. Então deixe-me saber.

Obrigado a todos por consertar isso :)

Isso parece correto, embora com o patch que tenho para o docker upstream você acabaria com apenas um campo "label = type: spc_t ".

@rhatdan pergunta, porque eu construo o docker com o seu patch, bem, talvez eu não tenha feito isso direito, mas acho que sim. E ainda vejo isso.

este comportamento não mudou:
docker run -ti --security-opt label = type: container_t --security-opt label = type: spc_t fedora sleep 5

 "MountLabel": "system_u:object_r:container_file_t:s0:c118,c497",
    "ProcessLabel": "system_u:system_r:spc_t:s0:c118,c497",

recorte

"SecurityOpt": [
"label = type: container_t ",
"rótulo = tipo: spc_t "

ele roda com o seu patch, nenhum deles sabe.

O Docker aceita isso, o patch está quebrando isso? Existe um caso de uso lógico em que o docker deva ser capaz de fazer isso?

A partir desse problema, se o docker mudar isso, vendo que nós (kubernetes pod runtime) acabamos dando rótulos duplos, que eu acho que vêm da validação no kubelet, se você quebrar o fato, o docker aceita mais opções, então deveria ... bem, quebra novamente.

Veja se é lógico, devemos ser capazes de executar um pod com opções de segurança diferentes para contêineres dentro de um pod, e acho que essa era a intenção, o que deveria ser possível, mas é necessário um alinhamento. O Docker e o kubernetes não podem ter expectativas diferentes sobre isso.

Posso estar errado, adicionando @eparis @dgoodwin @jasonbrooks @luxas @ pweil- @pmorie

Minha mudança não foi para impedir isso, embora provavelmente devêssemos. Minha mudança foi bloquear o ingresso do contêiner no namespace IPC ou no namespace pid de outro

# docker run -d --name test fedora sleep 10
# docker run -d security-opt label=type:spc_t --ipc container:test fedora cat /proc/self/attr/current

O segundo contêiner deve ser executado como spc_t. Onde o código antigo o teria executado como container_t. Isso basicamente imitaria dois contêineres em execução no mesmo pod com rótulos SELinux diferentes.

Obrigado @rhatdan por esclarecer.

Fechando este, pois as alterações habilitadas para rbac para rede de pod são rastreadas # 143

Não tenho certeza sobre os rótulos duplos, parece interação entre kubernetes / kubelet e docker, conforme mencionado acima.

Enfim, arquivou isso para docker # https://github.com/docker/docker/issues/31328

Obrigado a todos,

Estou correndo com Enforcing e não tenho problemas com flanela, para sua informação. Estou me perguntando se configurações específicas do SELinux o quebram e outras não? Não é um especialista em SELinux aliás.

Esta página foi útil?
0 / 5 - 0 avaliações