Kubernetes: Suportar o sinalizador do usuário do docker exec no kubectl exec

Criado em 16 ago. 2016  ·  97Comentários  ·  Fonte: kubernetes/kubernetes

Parece que docker exec está sendo usado como back-end para kubectl exec . docker exec tem o sinalizador --user , que permite que você execute um comando como um usuário específico. Essa mesma funcionalidade não existe no Kubernetes.

Nosso caso de uso é que criamos pods e executamos código não confiável neles. No entanto, há momentos em que, após a criação do pod, precisamos executar programas que precisam de acesso root (eles precisam acessar portas privilegiadas, etc).

Não queremos executar o código não confiável como root no contêiner, o que nos impede de apenas escalar as permissões para todos os programas.

Procurei referências a esse problema, mas só encontrei esta resposta do StackOverflow do ano passado - http://stackoverflow.com/questions/33293265/execute-command-into-kubernetes-pod-as-other-user .

Existem algumas soluções alternativas para isso, como configurar um servidor no contêiner que recebe comandos ou usar o padrão como root, mas passar para outro usuário antes de executar o código não confiável. No entanto, essas soluções alternativas quebram boas abstrações do Kubernetes/Docker e introduzem falhas de segurança.

arekubectl sicli sinode

Comentários muito úteis

Um caso de uso adicional - você está se preocupando com a segurança para que todos os processos executados dentro do contêiner não sejam privilegiados. Mas agora algo inesperadamente não está funcionando e você quer entrar como root para, por exemplo, instalar utilitários de depuração e descobrir o que está errado no sistema ativo.

Todos 97 comentários

SGTM. @kubernetes/kubectl alguma opinião sobre isso?

Não é irracional, mas precisaríamos de uma política de segurança de pod para controlar a entrada do usuário e provavelmente teríamos que proibir o usuário pelo nome (já que não permitimos isso para contêineres - você deve especificar o UID).

@sttts e @ncdc re exec

Caso de uso legítimo

alguma atualização disso?

Minha imagem de contêiner de aplicativo é criada usando buildpacks. Eu gostaria de abrir uma concha. Quando o faço, sou root, e todos os env vars estão definidos. Mas o ambiente gerado pelo buildpack não está lá. Se eu abrir um shell de login para o usuário do aplicativo ( su -l u22055 ), tenho meu ambiente de aplicativo, mas agora as vars env do kubernetes estão ausentes.

Eu pensei que su -l não copiou env vars? Você tem que fazer a cópia explicitamente
você mesmo ou use um comando diferente.

Em terça-feira, 11 de outubro de 2016 às 17h26, Michael Elsdörfer < [email protected]

escrevi:

Minha imagem de contêiner de aplicativo é criada usando buildpacks. gostaria de abrir um
Concha. Quando o faço, sou root, e todos os env vars estão definidos. Mas o
ambiente gerado pelo buildpack não está lá. Se eu abrir um shell de login para
o usuário do aplicativo (su -l u22055) Eu tenho meu ambiente de aplicativo, mas agora o
kubernetes env vars estão ausentes.


Você está recebendo isso porque está em uma equipe que foi mencionada.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/kubernetes/kubernetes/issues/30656#issuecomment -253085398,
ou silenciar o thread
https://github.com/notifications/unsubscribe-auth/ABG_p7sIu20xnja2HsbPUUgD1m4gXqVAks5qzCksgaJpZM4Jk3n0
.

@miracle2k - Você já tentou su -m -l u22055 ? -m deve preservar as variáveis ​​de ambiente.

@adarshaj @smarterclayton Obrigado pelas dicas. su -m tem seus próprios problemas (o diretório inicial está errado), mas eu fiz funcionar nesse meio tempo. O ponto é - é por isso que eu postei aqui - é que eu gostaria de ver "kubectl exec" fazer a coisa certa. Talvez até use o usuário que o arquivo docker define.

Aqui está um exemplo de como eu preciso dessa funcionalidade.

A imagem oficial do Jenkins é executada como o usuário Jenkins. Tenho um disco permanente anexado que preciso redimensionar. Se o kubectl tivesse o --user eu poderia atacar como root e resize2fs. Infelizmente sem ele é uma dor extrema.

Um caso de uso adicional - você está se preocupando com a segurança para que todos os processos executados dentro do contêiner não sejam privilegiados. Mas agora algo inesperadamente não está funcionando e você quer entrar como root para, por exemplo, instalar utilitários de depuração e descobrir o que está errado no sistema ativo.

Instalar coisas para fins de depuração também é meu caso de uso. Atualmente eu uso ssh nos nós que executam o kubernetes e uso docker exec diretamente.

Qual é o status disso? Esta funcionalidade seria muito útil

Eu não verifiquei, mas os sinalizadores globais --as e --as-group ajudam aqui? Eles trabalham com exec ? cc @liggitt

Eu não verifiquei, mas os sinalizadores globais --as e --as-group ajudam aqui? Eles ainda trabalham com exec? cc @liggitt

Não, isso tem a ver com se identificar para a API do kubernetes, não passando para informar o uid escolhido para a chamada do exec

A falta do sinalizador do usuário é um aborrecimento. O caso de uso é que eu tenho um contêiner que é executado como um usuário sem privilégios, monto um volume nele, mas a pasta do volume não é de propriedade do usuário. Não há opção para montar o volume com permissões especificadas. Não posso usar um script de ponto de entrada para alterar as permissões porque isso é executado como o usuário sem privilégios. Eu não posso usar um gancho lifecycle.preStart porque isso é executado como o usuário sem privilégios também. kubectl exec -u root poderia fazer isso, se a opção '-u' existisse.

Eu acho que isso deve ser uma permissão RBAC adicional, para permitir/bloquear 'exec' como diferente do usuário do contêiner.

Idealmente, os ganchos do ciclo de vida devem poder ser executados como root no contêiner, mesmo quando o contêiner não o fizer. No momento, a melhor alternativa é provavelmente executar um contêiner init na mesma montagem; uma espécie de sobrecarga para iniciar um contêiner separado e montar volumes, quando na verdade eu só preciso de um comando de uma linha como root no início do contêiner.

/sig cli

+1 para este recurso. Não ter isso torna a depuração das coisas muito mais dolorosa.

+1 para este recurso. Eu tenho que reconstruir meu contêiner docker e garantir que o arquivo do Docker tenha a raiz USER como a última linha, depois depure e desative isso.

linha de comando docker parece ter um sinalizador --user

johnjjung, se você tiver acesso ssh ao nó, poderá se conectar ao contêiner usando o docker com o sinalizador de usuário, o que pode economizar um pouco de tempo.

Hmm, incrível, deixe-me tentar isso

Em 10 de julho de 2017, 11:34 -0400, BenAbineriBubble [email protected] , escreveu:

johnjjung, se você tiver acesso ssh ao nó, poderá se conectar ao contêiner usando o docker com o sinalizador de usuário, o que pode economizar um pouco de tempo.

Você está recebendo isso porque comentou.
Responda a este e-mail diretamente, visualize-o no GitHub ou silencie a conversa.

+1 realmente um problema, eu tenho que ssh e depois executar o docker exec, tão irritante

/cc @frobware

+1 por favor. Não quero mais usar o docker exec -u como solução alternativa.

+1 - kubectl exec é uma economia de tempo tão grande em relação ao docker exec, que me faz chorar toda vez que tenho que voltar ao docker exec para especificar o usuário.

considerações:

  • uid precisaria fazer parte da interface exec para CRI, e todos os tempos de execução precisariam suportá-lo
  • precisaria descobrir o que a verificação de autorização seria restrições da política de segurança do pod wrt em uids

+1, pois isso evitará soluções alternativas inseguras das quais infelizmente temos o hábito (ou seja, definindo o runAsUser como root ... e esquecendo de reverter o valor ao implantar public 😮 ).

+1

+1 para mim, realmente preciso --user sinalizador para fazer login em um pod e fazer alterações sem reimplantar o contêiner com root como usuário executado

Este problema parece ter um suporte bastante forte, há algo que possa ser feito para priorizá-lo? (sim, sim, patches aceitos :))

+1 que seria útil para ter essa capacidade de executar com um usuário definido

Eu acho que a implementação disso pode ser complicada por causa de questões de segurança? Por exemplo, se o Dockerfile foi inicialmente definido como um usuário não root, você deve permitir que ele execute comandos como um usuário root agora? -- Como o sinalizador de usuário do docker lidou com isso? Se eles lidaram com isso adequadamente, acho que só precisamos corrigir o comando kubectl exec para passar isso adiante.

Alguém pode me dizer se essa é uma estratégia apropriada? Então eu posso começar em um PR

@johnjjung Sim, acredito que a estratégia aqui é corrigir o kubectl exec para passar o sinalizador docker --user.

Além disso, as preocupações de segurança parecem menores, pois temos autenticação implícita do GCP para conectar a partir do kubectl.

Além disso, as preocupações de segurança parecem menores, pois temos autenticação implícita do GCP para conectar a partir do kubectl.

Como assim? Existem controles sobre qual usuário é permitido na especificação do pod. Eu esperaria controles equivalentes sobre qualquer ID de usuário especificado em uma chamada exec. Eu tenho perguntas semelhantes sobre se um exec pode ser executado como root quando o contêiner original não era. Nesse caso, não podemos expor isso sem pensar em como o contexto de segurança do pod e os controles da política de segurança do pod se aplicariam a essa nova opção

@liggitt Isso não é diferente de definir o usuário no próprio Dockerfile e, ainda assim, ainda poder executar como root com o sinalizador de usuário do Docker.

A principal preocupação do Docker parece ser impedir o acesso root de _dentro_ de um contêiner _running_, caso ele seja comprometido. Em algum momento, a confiança deve ser dada para realmente permitir que os usuários desenvolvam e trabalhem com a ferramenta.

Por exemplo, se o Dockerfile foi inicialmente definido como um usuário não root, você deve permitir que ele execute comandos como um usuário root agora? -- Como o sinalizador de usuário do docker lidou com isso?

@johnjjung é como @jordanwilson230 diz, o argumento do docker runtime substitui a diretiva Dockerfile. Em cima da minha cabeça, é assim que a maioria dos argumentos de tempo de execução funciona (como números de porta).

Eu tenho perguntas semelhantes sobre se um exec pode ser executado como root quando o contêiner original não foi

@liggitt Apenas para esclarecer, a função do ID do usuário definido na especificação do pod não será alterada e continuará a ter o efeito pretendido. O contêiner (e seus processos) será lançado como esse usuário. O problema levantado aqui foi permitir aos usuários (já) autenticados uma opção manual para executar com root -- ou qualquer usuário, principalmente para fins de depuração.

O problema levantado aqui foi permitir aos usuários (já) autenticados uma opção manual para executar com root -- ou qualquer usuário, principalmente para fins de depuração.

E meu ponto é que os controles que temos hoje para impedir que um usuário execute um contêiner como root precisariam ser aplicados aqui também para impedi-los de executar com root.

@liggitt Desculpe, não sei explicar de maneira mais clara. Em relação ao seu comentário acima, tente isso:

  • ssh no nó executando seu pod (meu pod está executando o Kafka, com o usuário kafka também definido no pod.spec)
    jordan@gke-my-default-pool-dsioiaag-i9f3 ~ $ docker exec -it -u root myKafkaContainer bash root@kafka-0:/# echo "I've exec'd into my container as $(whoami) despite defining the kafka user in pod.spec...." I've exec'd into my container as root despite defining the kafka user in pod.spec.... root@kafka-0:/#
    Tendo estabelecido que isso já é possível do ponto de vista do GKE (embora de uma maneira muito irritante), em quais novas preocupações de segurança você está pensando? Esta questão não é reinventar a roda, é fornecer uma conveniência.

Tendo estabelecido que isso já é possível do ponto de vista do GKE (embora de uma maneira muito irritante), em quais novas preocupações de segurança você está pensando?

O problema é expor o poder por meio da API do kubernetes que não existe hoje. É normal que um usuário tenha permissão para executar cargas de trabalho por meio da API e não tenha acesso ssh ao nó.

É ótimo ter função via API, desde que:

  1. os administradores de cluster têm a capacidade de controlar via política se é permitido
  2. a forma como essa política é expressa é coerente com a política existente (neste caso, seria idealmente feito com base no mesmo mecanismo PodSecurityPolicy)
  3. a nova função não abre um buraco em um sistema previamente protegido (desativado por padrão ou é bloqueado com base na política existente)

@liggitt Absolutamente certo. Assim, tendo reduzido o escopo das implicações de segurança para o acesso _node_, nós ( @johnjjung e outros) podemos finalmente começar a usar essa discussão para substância acionável. Iniciei um plug-in kubectl para execução como root na plataforma GKE. Levará um pouco de tempo para eu me locomover até a AWS e outros. @johnjjung você ainda está disposto a pegar no seu lado?

@liggitt Acabei de ver a edição que você fez, que será útil no futuro. Obrigado.

Para discussão relacionada, consulte a proposta para permitir a execução de contêineres arbitrários, incluindo IDs de usuário especificados separadamente, em um pod existente - https://github.com/kubernetes/community/pull/1269

Quanto mais os aspectos de segurança do que você deseja executar se afastam do contêiner original, mais importante é que toda a especificação possa ser validada pelos mecanismos de admissão existentes como um contêiner coerente

@jordanwilson230 Estive revisando a base de código, encontrei os pontos de integrações para comandos kubectl exec, que é um bom ponto de partida, não tenho certeza de onde teria que fazer alterações na outra base de código do kubernetes onde podemos permitir o docker - vc sinaliza. Dito isto, acho que posso começar em algum lugar por aí e voltar a esse problema com administradores de cluster/políticas de segurança de pod, etc... Um passo de cada vez.

Se alguém souber onde fazer as alterações para onde o kubernetes executa os sinalizadores docker --user , isso seria útil.

Olá @johnjjung. Era uma vez (<1.6), o Kubernetes kubelets usava o Docker diretamente e podia apenas passar opções como essa. Agora existe uma interface padrão para suportar vários tempos de execução, CRI. São os recursos do CRI que determinam quais instruções podem ser passadas para os tempos de execução, como o Docker.

O Kubernetes informa aos vários tempos de execução do contêiner ( dockershim +Docker+ containerd , cri-containerd + containerd , rkt, cri-o, lxd, Frakti etc.) o que fazer fazer usando a interface CRI . Diretamente para implementações de tempo de execução de cri-o ou por meio de um shim como dockershim ou cri-containerd . Portanto, para poder fazer o que queremos aqui (adicionar processos a contêineres existentes em execução como um usuário diferente do qual o contêiner foi iniciado), primeiro você precisa estender a especificação CRI para oferecer suporte a essa opção (por exemplo, talvez ExecSync precisa de uma opção de uid e LinuxContainerSecurityContext não precisa proibi-la. Acho que @liggitt disse isso acima ).

Em seguida, cada um dos tempos de execução de contêiner ou shims de tempo de execução pode prosseguir e implementar suporte para ele. Para o Docker, isso significa estender a implementação dockershim para dar suporte à adição à especificação/interface CRI. No entanto, espero que dockershim +Docker seja preterido em favor de cri-containerd + containerd dentro de mais alguns lançamentos, então provavelmente é melhor focar em cri-containerd .

image

http://blog.kubernetes.io/2017/11/containerd-container-runtime-options-kubernetes.html

https://github.com/kubernetes/community/blob/master/contributors/devel/container-runtime-interface.md

Também relevante para esta discussão como a proposta de containers de depuração . Deve permitir que você execute uma segunda imagem de contêiner no mesmo espaço do Pod usando um novo comando kubectl debug . Possivelmente o container adicional pode ser executado como um usuário diferente?

@whereisaaron seu post é uma grande ajuda. Obrigado por escrever tudo isso em detalhes.

@whereisaaron obrigado pelos detalhes. Se estou entendendo você, parece que a proposta de depuração (se for aprovada) pode ser o melhor lugar para colocar isso no final do dia. Não tenho certeza se foi aprovado para ser trabalhado, mas basicamente permite que você anexe um contêiner de sua escolha a esse pod para depurar esse pod (o que parece incrível), mas isso permite alterar seu usuário dentro do contêiner original? Além disso, isso significa que devo esperar ou seguir em frente com um patch usando o cri-containerd?

Parece que uma das razões pelas quais isso ainda não foi implementado foi porque há vários repositórios com vários grupos trabalhando em diferentes áreas.

@johnjjung Acredito que o contêiner de depuração foi aprovado para ser implementado como um recurso 'alfa' no Kubernetes 1.9 (desativado, a menos que você ative explicitamente o recurso). Eu não acho que eles fizeram isso em 1.9 embora. Então provavelmente não até 1.10 ou mais tarde.

Pelo que entendi, os contêineres de depuração são executados como um processo dentro do Pod de destino 'sendo depurado', portanto, eles estão no mesmo contexto de segurança do kernel que o Pod, eles apenas têm sua própria imagem/sistema de arquivos de contêiner. Assim, você pode depurar qualquer processo e montar todos os volumes que o pod tiver. Mas como você está no mesmo contexto de segurança, gostaria de saber se você está preso ao mesmo limite imposto pelo kernel no uid que você pode usar no Pod ou não? Não tenho certeza, você teria que perguntar ao pessoal do #sig-node que está trabalhando nisso.

Em relação à extensão do CRI, acho que você precisaria de muito suporte do #sig-node para fazer isso, além de nenhuma objeção dos vários projetos de tempo de execução, como cri-containerd e cri-o , que podem então tem que implementar o suporte.

Não tive muito tempo hoje, mas para aqueles que executam no GKE, criei um plug-in kubectl ad-hoc para executar com o sinalizador de usuário [-u]:

https://github.com/jordanwilson230/kubectl-plugins

Sinta-se à vontade para modificar/copiar esse plugin ou todos eles executando o script de instalação. Apenas uma solução ad-hoc até que @johnjjung e outros possam assumir mais.

Tenha uma solução alternativa que não seja específica do GCP. Isso não usa SSH e requer apenas o funcionamento do kubectl.

https://github.com/mikelorant/kubectl-exec-user

O pod do kubectl-exec-user verifica se a pessoa que o usa tem acesso ao contêiner que está sendo solicitado para o shell?

Ele volta para o acesso que a API do kubernetes permite. Ele só funcionará se o RBAC permitir que um contêiner monte um soquete docker de nós.

Considere minha solução uma maneira criativa de sair de um contêiner para o nó sem exigir SSH. Todas as mesmas condições de segurança precisam ser consideradas, mas pelo menos respeitam as restrições do servidor da API do kubernetes.

Os problemas ficam obsoletos após 90 dias de inatividade.
Marque o problema como recente com /remove-lifecycle stale .
Problemas obsoletos apodrecem após 30 dias adicionais de inatividade e, eventualmente, fecham.

Se este problema for seguro para fechar agora, faça-o com /close .

Envie feedback para sig-testing, kubernetes/test-infra e/ou fejta .
/ciclo de vida obsoleto

/remove-lifecycle obsoleto

Isso seria extremamente bem-vindo. Não é legal ser penalizado por estar atento à segurança e executar todos os processos como não-root. (Reformulando https://github.com/kubernetes/kubernetes/issues/30656#issuecomment-272055993)

/ sinal de nó

Parece haver um PR inacabado que precisa de rebase para este recurso: https://github.com/kubernetes/kubernetes/pull/59092. Existe alguém que poderia pegá-lo e finalizar? CC @louyihua

+1
(Eu me deparo com o mesmo problema que @SimenB - gostaria de instalar coisas para fins de depuração. Adeus, obrigado pela dica "usar docker diretamente" )

Enquanto esperamos que isso seja devidamente suportado, uma solução intermediária pode ser executar o CMD do docker com su-exec (no Dockerfile ou no manifesto do K8s). su-exec pesa apenas 20k (em alpino) e desta forma seu aplicativo será executado sem privilégios, enquanto ainda possui root no kubectl exec.

+1

Eu também apreciaria um sinalizador -u. +1.

Apenas uma ideia:

Por exemplo, algo como --conainer-type seria uma grande vantagem para permitir a passagem de quaisquer argumentos suportados diretamente para a implementação do contêiner underyling:

kubectl exec --container-type=docker -it -u 0 NAME

Isso evitaria ter apenas um subconjunto da funcionalidade subjacente do tempo de execução do contêiner no kubectl. Além disso, economiza esforço, pois não há necessidade de mapear e abstrair os argumentos suportados da camada kubelet até o contêiner para cada tipo de contêiner suportado.

Portanto, em resumo, sem o sinalizador --container-type , apenas os argumentos abstraídos do kubectl podem ser usados ​​e o tipo de contêiner subjacente é completamente transparente. Com o sinalizador, argumentos específicos do contêiner podem ser passados ​​adiante. Cabe ao usuário do kubectl se ele deseja vincular a um tipo de contêiner ou não.

BTW: Obrigado a @SimenB pela dica de ssh no nó e usar o Docker diretamente. Isso resolveu meu problema temporariamente. Usando o Minikube, consegui fazer o seguinte para fazer login como root:
minikube ssh "docker exec -it -u 0 <container-id> bash"
Talvez isso possa ajudar alguém.

Um script de solução alternativa que automatiza o desagradável. Necessário acesso SSH ao nó.

Uso:

```./shell-into-pod-as-root.sh[Concha]
./shell-into-pod-as-root.sh podname
./shell-into-pod-as-root.sh podname sh

Enjoy!

!/usr/bin/env bash

set -xe

POD=$(kubectl describe pod "$1")
NÓ=$(echo "$POD" | grep -m1 Nó | awk -F'/' '{print $2}')
CONTAINER=$(echo "$POD" | grep -m1 'Container ID' | awk -F 'docker://' '{print $2}')

CONTAINER_SHELL=${2:-bash}

definir +e

ssh -t "$NODE" sudo docker exec --user 0 -it "$CONTAINER" "$CONTAINER_SHELL"

if [ "$?" -gt0]; então
definir +x
echo 'SSH no pod falhou. Se você vir uma mensagem de erro semelhante a "arquivo executável não encontrado em $PATH", tente:'
echo "$0 $1 sh"
fi
```

@Nowaker como você lida com namespaces?

Os problemas ficam obsoletos após 90 dias de inatividade.
Marque o problema como recente com /remove-lifecycle stale .
Problemas obsoletos apodrecem após 30 dias adicionais de inatividade e, eventualmente, fecham.

Se este problema for seguro para fechar agora, faça-o com /close .

Envie feedback para sig-testing, kubernetes/test-infra e/ou fejta .
/ciclo de vida obsoleto

/remove-lifecycle obsoleto

Eu também apreciaria um sinalizador -u. +1.

Apenas uma ideia:

Por exemplo, algo como --conainer-type seria uma grande vantagem para permitir a passagem de quaisquer argumentos suportados diretamente para a implementação do contêiner underyling:

kubectl exec --container-type=docker -it -u 0 NAME

Isso evitaria ter apenas um subconjunto da funcionalidade subjacente do tempo de execução do contêiner no kubectl. Além disso, economiza esforço, pois não há necessidade de mapear e abstrair os argumentos suportados da camada kubelet até o contêiner para cada tipo de contêiner suportado.

Portanto, em resumo, sem o sinalizador --container-type , apenas os argumentos abstraídos do kubectl podem ser usados ​​e o tipo de contêiner subjacente é completamente transparente. Com o sinalizador, argumentos específicos do contêiner podem ser passados ​​adiante. Cabe ao usuário do kubectl se ele deseja vincular a um tipo de contêiner ou não.

BTW: Obrigado a @SimenB pela dica de ssh no nó e usar o Docker diretamente. Isso resolveu meu problema temporariamente. Usando o Minikube, consegui fazer o seguinte para fazer login como root:
minikube ssh "docker exec -it -u 0 <container-id> bash"
Talvez isso possa ajudar alguém.

Sim - é trivial usar apenas o docker exec para fazer isso - é principalmente sobre consistência - os contêineres do docker multiusuário são realmente uma piada - um legado da conversão de uma VM em um contêiner.

Estou lidando com isso com grafana no momento - acho que isso vai passar com o tempo.

@bryanhuntesl Há uma discussão sobre soluções alternativas acima, que não exigem ssh'ing manual para um nó. Você também pode tentar este plugin -- https://github.com/jordanwilson230/kubectl-plugins

E se você não quiser permitir que os usuários façam ssh em um nó? Permitir aos usuários acesso ssh a um nó, bem como permitir que eles tenham acesso ao docker, pode ser um risco de segurança. O Docker não sabe nada sobre namespaces ou permissões k8s. Se um usuário pode executar docker exec , ele pode executar em pods de namespace _any_.

SSH não é uma solução adequada, IMHO.

E se você não quiser permitir que os usuários façam ssh em um nó? Permitir aos usuários acesso ssh a um nó, bem como permitir que eles tenham acesso ao docker, pode ser um risco de segurança. O Docker não sabe nada sobre namespaces ou permissões k8s. Se um usuário pode executar docker exec , ele pode executar em pods de namespace _any_.

SSH não é uma solução adequada, IMHO.

Eu apoio essa opinião - usar um mecanismo fora de banda para obter acesso direto está aumentando a área de ataque potencial.

E se você não quiser permitir que os usuários façam ssh em um nó? Permitir aos usuários acesso ssh a um nó, bem como permitir que eles tenham acesso ao docker, pode ser um risco de segurança. O Docker não sabe nada sobre namespaces ou permissões k8s. Se um usuário pode executar docker exec , ele pode executar em pods de namespace _any_.

SSH não é uma solução adequada, IMHO.

Existem soluções que não requerem SSH @gjcarneiro. Além disso, um usuário deve primeiro adicionar sua chave SSH pública nos metadados de computação antes de receber acesso SSH a um nó (se estiver no GCP) @bryanhuntesl.

@liggitt Já se passaram três anos desde que este tópico começou, alguma conclusão?

Não tenho certeza se essa solução já foi mencionada antes, mas o que fizemos como solução alternativa foi que todos os nossos contêineres incluíssem um script que fará o login como o usuário correto. Além de um motd:

Dockerfile:

USER root
RUN echo "su -s /bin/bash www-data" >> /root/.bashrc
# this exit statement here is needed in order to exit from the new shell directly or else you need to type exit twice
RUN echo "exit" >> /root/.bashrc
# /var/www is www-data's home directory
COPY motd.sh /var/www/.bashrc

motd.sh:

RED='\033[0;31m'
YELLOW='\033[0;33m'

echo -e "${RED}"
echo "##################################################################"
echo "#        You've been automatically logged in as www-data.        #"
echo "##################################################################"
echo -e "${YELLOW} "
echo "If you want to login as root instead:"
echo -e "$(if [ "$KUBERNETES_PORT" ]; then echo 'kubectl'; else echo 'docker'; fi) exec -ti $(hostname) -- bash --noprofile -norc"

TEXT_RESET='\033[0m'

echo -e "${TEXT_RESET} "

Os problemas ficam obsoletos após 90 dias de inatividade.
Marque o problema como recente com /remove-lifecycle stale .
Problemas obsoletos apodrecem após 30 dias adicionais de inatividade e, eventualmente, fecham.

Se este problema for seguro para fechar agora, faça-o com /close .

Envie feedback para sig-testing, kubernetes/test-infra e/ou fejta .
/ciclo de vida obsoleto

/remove-lifecycle obsoleto

use o plugin [exec-as] kubectl:

kubectl krew install exec-as

Como mencionado acima, isso realmente precisa de um KEP e uma discussão sobre as implicações de segurança. Não é que seja necessariamente uma má ideia, apenas tem um impacto significativo no sistema e precisa de um design antes que possamos começar a codificar.

Eu ficaria feliz em ajudar a revisar e orientar um KEP para isso, mas definitivamente tem algumas armadilhas e pode demorar um pouco.

@miracle2k - Você já tentou su -m -l u22055 ? -m deve preservar as variáveis ​​de ambiente.

@miracle2k Eu tentei isso (trying to exec as root user) , mas consegui No passwd entry for user '0'

$ su -m -l 0
No passwd entry for user '0'

Olá. Para resolver esse problema, desenvolvi a CLI "kpexec".
Por favor, dê seus feedbacks.

No nó que executa o pod:

docker exec -u 0 -it \
    `kubectl -n NAMESPACE get pod \
          -l label=value \
          -o jsonpath='{range .items[*].status.containerStatuses[*]}{.containerID}{"\n"}{end}' | cut -d/ -f3` \
sh

@cristichiru Para a maioria dos clusters em que operei, não há acesso direto ao shell do Node. Eu suspeito que muitas vezes é o caso de outros também.

Nesses casos, parece que as outras opções apresentadas aqui, como os plugins kubectl, podem ser a única maneira - supondo que não haja acesso ao daemon do docker.

+1

Bem, o modelo KEP está aqui https://github.com/kubernetes/enhancements/tree/master/keps/NNNN-kep-template

Eu imaginei que veria quanto trabalho é escrever um e... sim, eu não sou a pessoa para escrever isso, O modelo me perdeu no item da lista de verificação um **Pick a hosting SIG.** alguém mais familiarizado com o processo quer para iniciar o rascunho? Eu só quero um lugar para colocar meu 👍 em apoio à proposta como usuário ativo do Kubernetes.

Isso pode parecer irreverente, mas vejo cerca de meia dúzia de soluções alternativas bem codificadas / roteirizadas / escritas para esse problema, então claramente _há_ pessoas que estão em melhor posição para redigir soluções técnicas propostas do que eu.

Eu sinto que o Kubernetes se tornou o novo OpenStack, onde nada pode ser alcançado em um prazo razoável por causa do PROCESS .

O caso de uso original do @VikParuchuri aqui é poder depurar/solucionar problemas de contêineres como root, mesmo que o próprio contêiner esteja sendo executado como um usuário não confiável. Bom caso de uso, porque, se resolvido, nos encoraja a executar contêineres como usuários não root. 🎉

Antes de preparar um KEP para docker exec , verifique rapidamente se os contêineres de depuração efêmeros do k8s não abordam esse caso de uso para você.

docker exec --user é apenas uma maneira de abordar esse caso de uso e depende do tempo de execução do docker que está sendo usado. Como o k8s se move para containerd , dockerd e os amigos são opcionais ou nem mesmo instalados, então possivelmente não é uma opção voltada para o futuro?

Outra maneira nativa do k8s de abordar esse caso de uso são os contêineres de depuração efêmeros. Digamos que você tenha um contêiner sendo executado como um usuário não confiável. Os contêineres de depuração permitem que você inicie um contêiner temporário no mesmo espaço de processo que o contêiner de destino, mas executando como root (ou quem quer que seja). Essa abordagem tem algumas vantagens significativas sobre as abordagens exec, em particular, você pode trazer qualquer ferramenta de depuração e utilitários necessários na imagem para o contêiner de depuração. Então, em vez de inchar sua imagem de contêiner de destino com utils e editores, etc., apenas no caso de você precisar executar (🐑 .., culpado!), você pode ter uma boa imagem de contêiner de depuração de canivete suíço e manter suas imagens de aplicativos limpas . Você pode usar bash em seu contêiner de depuração quando seu destino tiver apenas sh . Você pode até depurar contêineres que não têm shell para exec, como contêineres binários únicos ou contêineres sem distro .

Por exemplo, use busybox para depurar um container como root.

kubectl alpha debug -it ephemeral-demo --image=busybox --target=ephemeral-demo

Acho que esse é sem dúvida um modelo melhor, pois trata os contêineres como processos isolados, aos quais você 'anexa' para depuração, em vez de mini-VMs nas quais você usa o shell. A desvantagem é que não acho que você possa inspecionar o sistema de arquivos do destino, a menos que possa compartilhar uma montagem externa ou uma montagem 'vazia'. Você compartilha o namespace do processo com seu destino, para que também possa acessar o sistema de arquivos do contêiner de destino, via /proc/$pid/root .

Os contêineres de depuração efêmeros já navegaram no PROCESS :-) e foram implementados. Esses contêineres são alfa desde ~1.16 e 1.18 kubectl incluem o comando alpha debug . Mais informações aqui:

Referências:

Obrigado pela resposta atenciosa @whereisaaron :) Acho que captura as coisas muito bem.

Achei que veria quanto trabalho é escrever um e... sim, eu não sou a pessoa para escrever isso, O modelo me perdeu no item um da lista de verificação Escolha um SIG de hospedagem. alguém mais familiarizado com o processo quer iniciar o draft? Eu só quero um lugar para colocar meu 👍 em apoio à proposta como usuário ativo do Kubernetes.

Os KEPs podem ser bastante assustadores, mas quero fornecer um pouco de contexto em torno deles. O próprio Kubernetes é muito grande; mudanças potenciais têm um raio de explosão muito grande, tanto para a base de contribuidores quanto para os usuários. Um novo recurso pode parecer fácil de implementar, mas tem o potencial de impactar amplamente ambos os grupos.

Delegamos a administração de partes da base de código aos SIGs; e é através dos KEPs que um ou mais dos SIGs podem chegar a um consenso sobre um recurso. Dependendo do que o recurso faz, ele pode passar por uma revisão de API, avaliado por questões de escalabilidade etc.

Tudo isso para garantir que o que é produzido tenha as maiores chances de sucesso e seja desenvolvido de forma que o(s) SIG(s) esteja(m) disposto(s) a apoiá-lo. Se o(s) autor(es) original(is) se afastarem, a responsabilidade de mantê-lo é da SIG. Se, digamos, um recurso foi promovido para estável e, em seguida, sinalizado para suspensão de uso, levaria no mínimo um ano para que pudesse ser removido de acordo com a política de suspensão de uso .

Se houver demanda suficiente por um recurso, geralmente alguém que esteja mais familiarizado com o processo KEP se oferecerá para ajudá-lo e guiá-lo, mas ainda precisa de alguém para conduzi-lo.

De qualquer forma, espero que isso lance pelo menos um pouco de luz sobre por que existe um processo associado à fusão de um recurso. :+1: Se você tiver alguma dúvida, sinta-se à vontade para entrar em contato diretamente.

A desvantagem é que não acho que você possa inspecionar o sistema de arquivos do destino, a menos que possa compartilhar uma montagem externa ou uma montagem 'vazia'.

Para mim, inspecionar o sistema de arquivos como root e executar utilitários que podem interagir com o sistema de arquivos como root é a razão número um para querer obter suporte para o recurso solicitado. Em suma, esta sugestão não resolve o meu problema.

A desvantagem é que não acho que você possa inspecionar o sistema de arquivos do destino

Eu estava errado sobre isso, porque seu contêiner de depuração injetado compartilha o namespace do processo com seu contêiner de destino, você pode acessar o sistema de arquivos de qualquer processo no contêiner de destino do seu contêiner de depuração. E isso inclui os sistemas de arquivos do contêiner e quaisquer sistemas de arquivos montados nesses contêineres.

Os sistemas de arquivos do contêiner são visíveis para outros contêineres no pod por meio do link /proc/$pid/root.

https://kubernetes.io/docs/tasks/configure-pod-container/share-process-namespace/#understanding -process-namespace-sharing

Os problemas ficam obsoletos após 90 dias de inatividade.
Marque o problema como recente com /remove-lifecycle stale .
Problemas obsoletos apodrecem após 30 dias adicionais de inatividade e, eventualmente, fecham.

Se este problema for seguro para fechar agora, faça-o com /close .

Envie feedback para sig-testing, kubernetes/test-infra e/ou fejta .
/ciclo de vida obsoleto

/remove-lifecycle obsoleto

kubectl alpha debug -it ephemeral-demo --image=busybox --target=ephemeral-demo

error: ephemeral containers are disabled for this cluster

@whereisaaron Parece que a maioria dos provedores de nuvem não suporta isso e, no local, podemos apenas ir para um nó e docker exec no contêiner. Então, novamente, a utilidade parece bastante limitada.

Também o acesso via /proc/$pid/root não é o que eu gostaria, gostaria de um acesso direto não via "janela lateral". Por exemplo, executar utilitários como apt/apk _no continer_ não é fácil quando o sistema de arquivos raiz não está onde eles esperam.

Eu tive um problema semelhante: eu precisava criar alguns diretórios, links e adicionar permissão para o usuário não root em uma imagem oficial implantada por um gráfico de leme oficial (jenkins).

Consegui resolvê-lo usando o plugin exec-as.

Com a descontinuação planejada do Docker e a remoção subsequente, quando isso será resolvido? Os contêineres efêmeros ainda estão em alfa. Qual é a alternativa estável sem usar o Docker como CRI?

Além de ser alfa, os contêineres efêmeros são muito mais complicados de usar do que simplesmente kubectl exec --user seria.

Outro caso de uso para isso é a execução manual de scripts em contêineres. Por exemplo, o script de manutenção occ do NextCloud precisa ser executado como www-data. Não há sudo ou similar na imagem, e o doc aconselha usar docker exec -u 33 quando estiver em um ambiente Docker.

Você pode resolver o problema com o nextcloud executando

su -s /bin/bash www-data

Mas isso não é o ideal.

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