Essa seção da documentação contém páginas que mostram como executar tarefas individuais.
Essas tarefas são organizadas em uma curta sequência de etapas e passos que te auxiliam a entender conceitos básicos.
Se você desejar adicionar uma tarefa, verifique como criar um Pull Request para a documentação.
Esta página mostra como executar tarefas automatizadas usando o objeto CronJob no kubernetes.
Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
Cron jobs requerem um arquivo de configuração. Aqui está um manifesto para CronJob que executa uma tarefa de demonstração simples a cada minuto:
apiVersion: batch/v1
kind: CronJob
metadata:
name: hello
spec:
schedule: "* * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
imagePullPolicy: IfNotPresent
command:
- /bin/sh
- -c
- date; echo Hello from the Kubernetes cluster
restartPolicy: OnFailure
Execute o exemplo de CronJob usando o seguinte comando:
kubectl create -f https://k8s.io/examples/application/job/cronjob.yaml
A saída é semelhante a esta:
cronjob.batch/hello created
Após criar o cron job, obtenha o status usando este comando:
kubectl get cronjob hello
A saída é semelhante a esta:
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
hello */1 * * * * False 0 <none> 10s
Como você pode ver pelos resultados do comando, o cron job ainda não agendou ou executou uma tarefa ainda. Observe que a tarefa será criada em cerca de um minuto:
kubectl get jobs --watch
A saída é semelhante a esta:
NAME COMPLETIONS DURATION AGE
hello-4111706356 0/1 0s
hello-4111706356 0/1 0s 0s
hello-4111706356 1/1 5s 5s
Agora você viu uma tarefa em execução agendada pelo cron job "hello". Você pode parar de observá-lo e visualizar o cron job novamente para ver que ele agendou a tarefa:
kubectl get cronjob hello
A saída é semelhante a esta:
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
hello */1 * * * * False 0 50s 75s
Você deve ver que o cron job hello agendou uma tarefa com sucesso no tempo especificado em
LAST SCHEDULE. Existem atualmente 0 tarefas ativas, o que significa que a tarefa foi concluída ou falhou.
Agora, encontre os pods da última tarefa agendada criada e veja a saída padrão de um dos pods.
# Replace "hello-4111706356" with the job name in your system
pods=$(kubectl get pods --selector=job-name=hello-4111706356 --output=jsonpath={.items[*].metadata.name})
Veja os logs do pod:
kubectl logs $pods
A saída é semelhante a esta:
Fri Feb 22 11:02:09 UTC 2019
Hello from the Kubernetes cluster
Quando você não precisar mais de um cron job, exclua-o com kubectl delete cronjob <cronjob name>:
kubectl delete cronjob hello
Excluindo o cron job remove todas as tarefas e pods que ele criou e impede a criação de novas tarefas. Você pode ler mais sobre como remover tarefas em garbage collection.
A ferramenta de linha de comando do Kubernetes, kubectl,
permite que você execute comandos nos clusters Kubernetes.
Você pode usar o kubectl para instalar aplicações, inspecionar e gerenciar recursos
de cluster e visualizar os logs.
Para obter mais informações, incluindo uma lista completa de operações kubectl,
consulte a documentação de referência do kubectl.
Kubectl é instalável em uma variedade de plataformas Linux, macOS e Windows. Encontre seu sistema operacional preferido abaixo.
O kind permite que você execute o Kubernetes no
seu computador local. Esta ferramenta requer que você tenha o
Docker instalado e configurado.
A página de Início Rápido mostra
o que você precisa fazer para começar a trabalhar com o kind.
Acesse o guia de início rápido do kind
Assim como o kind, o minikube é uma ferramenta
que permite executar o Kubernetes localmente. O minikube executa um cluster Kubernetes
local tudo-em-um ou com vários nós no seu computador pessoal
(incluindo PCs Windows, macOS e Linux) para que você possa experimentar o Kubernetes
ou para o trabalho de desenvolvimento diário.
Você pode seguir o guia de início oficial se o seu foco é instalar a ferramenta.
Depois de instalar o minikube, você pode usá-lo para executar uma aplicação de exemplo.
Você pode usar a ferramenta kubeadm para criar e gerenciar clusters Kubernetes. Esta ferramenta executa as ações necessárias para obter um cluster mínimo viável e seguro em funcionamento de maneira amigável ao usuário.
Instalando a ferramenta kubeadm mostra como instalar o kubeadm. Uma vez instalado, você pode usá-lo para criar um cluster.
Acesse o guia instalando a ferramenta kubeadm
Você deve usar uma versão do kubectl que esteja próxima da versão do seu cluster. Por exemplo, um cliente v1.35 pode se comunicar com as versões v1.34, v1.35 e v1.36 da camada de gerenciamento. Usar a versão compatível mais recente do kubectl ajuda a evitar problemas inesperados.
Existem os seguintes métodos para instalar o kubectl no macOS:
Baixe a última versão:
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/darwin/amd64/kubectl"
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/darwin/arm64/kubectl"
Para baixar uma versão específica, substitua a parte $(curl -L -s https://dl.k8s.io/release/stable.txt)
do comando com a versão específica da versão.
Por exemplo, para baixar a versão 1.35.0 no Intel macOS, digite:
curl -LO "https://dl.k8s.io/release/v1.35.0/bin/darwin/amd64/kubectl"
E para macOS no Apple Silicon, digite:
curl -LO "https://dl.k8s.io/release/v1.35.0/bin/darwin/arm64/kubectl"
Valide o binário (opcional).
Baixe o arquivo de checksum do kubectl:
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/darwin/amd64/kubectl.sha256"
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/darwin/arm64/kubectl.sha256"
Valide o binário do kubectl com o arquivo de checksum:
echo "$(cat kubectl.sha256) kubectl" | shasum -a 256 --check
Se for válido, a saída será:
kubectl: OK
Se houver falha na validação, o shasum vai retornar uma saída diferente de zero semelhante a:
kubectl: FAILED
shasum: WARNING: 1 computed checksum did NOT match
Torne o binário do kubectl executável.
chmod +x ./kubectl
Mova o binário do kubectl para um diretório que esteja no PATH do seu sistema.
sudo mv ./kubectl /usr/local/bin/kubectl
sudo chown root: /usr/local/bin/kubectl
/usr/local/bin está configurado na sua variável de ambiente PATH.Teste para validar que a versão instalada está atualizada:
kubectl version --client
Ou se preferir, use o seguinte comando para uma visão mais detalhada sobre a versão do Kubernetes:
kubectl version --client --output=yaml
Depois de instalar e validar o kubectl, delete o arquivo de checksum:
rm kubectl.sha256
Se você está no macOS e usando o gerenciador de pacote Homebrew, você pode instalar o kubectl usando o Homebrew.
Execute o comando de instalação:
brew install kubectl
ou
brew install kubernetes-cli
Teste para validar se a versão instalada está atualizada:
kubectl version --client
Se você está no macOS, usando o gerenciador de pacotes Macports, você pode instalar o kubectl utilizando o Macports.
Execute o comando de instalação:
sudo port selfupdate
sudo port install kubectl
Teste para validar se a versão instalada está atualizada:
kubectl version --client
Para que o kubectl encontre e acesse um cluster Kubernetes, ele precisa de um
arquivo kubeconfig,
que é criado automaticamente quando você cria um cluster usando
kube-up.sh
ou instala com sucesso um cluster Minikube.
Por padrão, a configuração kubectl está localizada em ~/.kube/config.
Verifique se o kubectl está configurado corretamente obtendo o estado do cluster:
kubectl cluster-info
Se você receber uma URL de resposta, o kubectl está configurado corretamente para acessar seu cluster.
Se você receber uma mensagem semelhante à seguinte, o kubectl não está configurado corretamente ou não consegue se conectar a um cluster Kubernetes.
The connection to the server <server-name:port> was refused - did you specify the right host or port?
Por exemplo, se você pretende executar um cluster Kubernetes no seu laptop (localmente), precisará que uma ferramenta como o Minikube seja instalada primeiro, para em seguida executar novamente os comandos indicados acima.
Se o comando kubectl cluster-info retornar a URL de resposta, mas você não conseguir
acessar seu cluster, use o comando abaixo para verificar se ele está configurado
corretamente:
kubectl cluster-info dump
No Kubernetes 1.26, o kubectl removeu os autenticadores embutidos para as distribuições de Kubernetes dos provedores de nuvem abaixo. Estes provedores lançaram plugins para o kubectl que fornecem autenticação específica para a nuvem. Para instruções, veja as seguintes documentações de cada provedor:
Também podem haver outras razões para que a mesma mensagem de erro ocorra, não relacionadas a esta mudança.
O kubectl oferece recursos de autocompletar para Bash, Zsh, Fish e PowerShell, o que pode economizar muita digitação.
Abaixo estão os procedimentos para configurar o autocompletar para Bash, Fish e Zsh.
O script de autocompletar do kubectl para Bash pode ser gerado com o comando kubectl completion bash.
O script permite habilitar o autocompletar do kubectl no seu shell.
No entanto, o script autocompletar depende do bash-completion, o que significa que você precisa instalar este software primeiro.
As instruções abaixo sugerem que você esteja utilizando o Bash 4.1+. Você pode verificar a versão do seu Bash com o comando:
echo $BASH_VERSION
Se a versão do Bash for muito antiga, você pode instalar ou atualizar utilizando o Homebrew:
brew install bash
Recarregue seu shell e verifique se a versão desejada foi instalada e está em uso:
echo $BASH_VERSION $SHELL
O Homebrew normalmente instala os pacotes em /usr/local/bin/bash.
Você pode testar se o bash-completion v2 está instalado, utilizando type _init_completion.
Se não, você pode instalar utilizando o Homebrew:
brew install bash-completion@2
Como indicado na saída deste comando, adicione a seguinte linha em seu arquivo ~/.bash_profile:
brew_etc="$(brew --prefix)/etc" && [[ -r "${brew_etc}/profile.d/bash_completion.sh" ]] && . "${brew_etc}/profile.d/bash_completion.sh"
Recarregue seu shell e verifique que o bash-completion v2 está instalado corretamente utilizando type _init_completion.
Agora você precisa garantir que o script de autocompletar do kubectl seja carregado em todas as suas sessões de shell. Existem várias maneiras de fazer isso:
Carregue o script de autocompletar no seu arquivo ~/.bash_profile:
echo 'source <(kubectl completion bash)' >>~/.bash_profile
Adicione o script de autocompletar ao diretório /usr/local/etc/bash_completion.d:
kubectl completion bash >/usr/local/etc/bash_completion.d/kubectl
Se você tiver um alias para o kubectl, pode estender o autocompletar do shell para funcionar com esse alias:
echo 'alias k=kubectl' >>~/.bash_profile
echo 'complete -o default -F __start_kubectl k' >>~/.bash_profile
Se você tiver instalado o kubectl com o Homebrew(conforme explicado
aqui),
então o script de autocompletar do kubectl deverá estar pronto em /usr/local/etc/bash_completion.d/kubectl.
Neste caso, você não precisa fazer mais nada.
BASH_COMPLETION_COMPAT_DIR, é por isso que os dois últimos métodos funcionam.Em todos os casos, após recarregar seu shell, o autocompletar do kubectl deve estar funcionando.
O script de autocompletar do kubectl para Fish pode ser gerado com o comando kubectl completion fish. O script permite habilitar o autocompletar do kubectl no seu shell.
Para fazer isso em todas as suas sessões do shell, adicione a seguinte linha ao seu arquivo ~/.config/fish/config.fish:
kubectl completion fish | source
Depois de recarregar seu shell, o autocompletar do kubectl deve estar funcionando.
O script de autocompletar do kubectl para Zsh pode ser gerado com o comando kubectl completion zsh. Este script habilita o autocompletar do kubectl no seu shell.
Para fazer isso em todas as suas sessões de shell, adicione a seguinte linha no arquivo ~/.zshrc:
source <(kubectl completion zsh)
Se você tiver um alias para kubectl, o autocompletar funcionará automaticamente com ele.
Depois de recarregar seu shell, o autocompletar do kubectl deve estar funcionando.
Se você ver um erro similar a 2: command not found: compdef, adicione o seguinte bloco ao início do seu arquivo ~/.zshrc:
autoload -Uz compinit
compinit
kubectl convert pluginUm plugin para a ferramenta Kubernetes de linha de comando kubectl, que permite converter manifestos entre diferentes versões da API.
Isso pode ser particularmente útil para migrar manifestos para uma versão não obsoleta com a versão mais recente da API Kubernetes.
Para mais informações, visite Migrar para APIs não obsoletas
Faça download da versão mais recente com o comando:
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/darwin/amd64/kubectl-convert"
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/darwin/arm64/kubectl-convert"
Valide o binário (opcional).
Faça download do arquivo checksum de verificação do kubectl-convert:
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/darwin/amd64/kubectl-convert.sha256"
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/darwin/arm64/kubectl-convert.sha256"
Valide o binário kubectl-convert com o arquivo de verificação:
echo "$(cat kubectl-convert.sha256) kubectl-convert" | shasum -a 256 --check
Se for válido, a saída será:
kubectl-convert: OK
Se a verificação falhar, o sha256 exibirá o status diferente de zero e a saída será semelhante a:
kubectl-convert: FAILED
shasum: WARNING: 1 computed checksum did NOT match
Torne o binário do kubectl-convert um executável.
chmod +x ./kubectl-convert
Mova o binário do kubectl-convert para o PATH do sistema.
sudo mv ./kubectl-convert /usr/local/bin/kubectl-convert
sudo chown root: /usr/local/bin/kubectl-convert
/usr/local/bin está no PATH em suas configurações de variáveis ambiente.Verifique se o plugin foi instalado com sucesso.
kubectl convert --help
Se você não encontrar nenhum erro, isso quer dizer que o plugin foi instalado com sucesso.
Após instalar o plugin, limpe os arquivos de instalação:
rm kubectl-convert kubectl-convert.sha256
Dependendo da forma que você instalou o kubectl, use um dos métodos abaixo.
Localize o binário do kubectl no seu sistema:
which kubectl
Remova o binário kubectl:
sudo rm <path>
Substitua <path> com o PATH do binário kubectl conforme os passos anteriores. Por exemplo, sudo rm /usr/local/bin/kubectl.
Se você instalou o kubectl utilizando Homebrew, execute o comando a seguir:
brew remove kubectl
Você deve usar uma versão do kubectl que esteja próxima da versão do seu cluster. Por exemplo, um cliente v1.35 pode se comunicar com as versões v1.34, v1.35 e v1.36 da camada de gerenciamento. Usar a versão compatível mais recente do kubectl ajuda a evitar problemas inesperados.
Existem os seguintes métodos para instalar o kubectl no Linux:
Faça download da versão mais recente com o comando:
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/arm64/kubectl"
Para fazer o download de uma versão específica, substitua a parte $(curl -L -s https://dl.k8s.io/release/stable.txt) do comando pela versão específica.
Por exemplo, para fazer download da versão 1.35.0 no Linux x86-64, digite:
curl -LO https://dl.k8s.io/release/v1.35.0/bin/linux/amd64/kubectl
E para Linux ARM64, digite:
curl -LO https://dl.k8s.io/release/v1.35.0/bin/linux/arm64/kubectl
Valide o binário (opcional)
Faça download do arquivo checksum de verificação do kubectl:
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl.sha256"
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/arm64/kubectl.sha256"
Valide o binário kubectl em relação ao arquivo de verificação:
echo "$(cat kubectl.sha256) kubectl" | sha256sum --check
Se válido, a saída será:
kubectl: OK
Se a verificação falhar, o sha256 exibirá o status diferente de zero e a saída será semelhante a:
kubectl: FAILED
sha256sum: WARNING: 1 computed checksum did NOT match
Instale o kubectl
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
Se você não tiver acesso root no sistema de destino, ainda poderá instalar o kubectl no diretório ~/.local/bin:
chmod +x kubectl
mkdir -p ~/.local/bin
mv ./kubectl ~/.local/bin/kubectl
# e depois adicione ~/.local/bin na variável $PATH
Teste para garantir que a versão que você instalou esteja atualizada:
kubectl version --client
Ou use isso para visualizar mais detalhes da versão:
kubectl version --client --output=yaml
Atualize o índice do apt e instale os pacotes necessários para utilizar o repositório apt do Kubernetes:
sudo apt-get update
# apt-transport-https pode ser um pacote simbólico; se for o caso, você pode ignorá-lo
sudo apt-get install -y apt-transport-https ca-certificates curl gnupg
Faça download da chave de assinatura pública para os repositórios de pacote do Kubernetes. A mesma chave de assinatura é usada para todos os repositórios, então você pode desconsiderar a versão na URL:
# Se a pasta `/etc/apt/keyrings` não existir, ela deve ser criada antes do comando curl, leia a nota abaixo.
# sudo mkdir -p -m 755 /etc/apt/keyrings
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.35/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
sudo chmod 644 /etc/apt/keyrings/kubernetes-apt-keyring.gpg # permitir que programas APT sem acesso privilegiado leiam este keyring
/etc/apt/keyrings não existe por padrão, e ela deve ser criada antes do comando curl.Adicione o repositório apt do Kubernetes. Se você quiser usar uma versão do Kubernetes diferente de v1.35,
substitua v1.35 com a versão menor desejada no comando a seguir:
# Isto substitui qualquer configuração existente na pasta /etc/apt/sources.list.d/kubernetes.list
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.35/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo chmod 644 /etc/apt/sources.list.d/kubernetes.list # ajuda ferramentas tais como command-not-found a funcionar corretamente
/etc/apt/sources.list.d/kubernetes.list antes de rodar apt-get update e apt-get upgrade. Este procedimento está descrito com mais detalhes em Mudando o Repositório de Pacotes do Kubernetes (em inglês).Atualize o índice do apt com o novo repositório e instale o kubectl:
sudo apt-get update
sudo apt-get install -y kubectl
Adicione o repositório yum do Kubernetes. Se você quiser usar uma versão do
Kubernetes diferente de v1.35, substitua v1.35
pela versão menor desejada no comando a seguir.
# Isto substitui qualquer configuração existente na pasta /etc/yum.repos.d/kubernetes.repo
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.35/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.35/rpm/repodata/repomd.xml.key
EOF
/etc/yum.repos.d/kubernetes.repo antes de rodar yum update. Este procedimento está descrito com mais detalhes em Mudando o Repositório de Pacotes do Kubernetes (em inglês).Instale o kubectl usando yum:
sudo yum install -y kubectl
Adicione o repositório zypper do Kubernetes. Se você quiser instalar uma versão
diferente de v1.35, substitua v1.35 pela versão
menor desejada no comando a seguir.
# Isto substitui qualquer configuração existente no arquivo /etc/zypp/repos.d/kubernetes.repo
cat <<EOF | sudo tee /etc/zypp/repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.35/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.35/rpm/repodata/repomd.xml.key
EOF
/etc/zypp/repos.d/kubernetes.repo
antes de rodar zypper update. Este procedimento está descrito com mais detalhes em Mudando o Repositório de Pacotes do Kubernetes (em inglês).Atualize o zypper e confirme a adição do novo repositório:
sudo zypper update
Quando esta mensagem aparecer, pressione 't' ou 'a':
New repository or package signing key received:
Repository: Kubernetes
Key Fingerprint: 1111 2222 3333 4444 5555 6666 7777 8888 9999 AAAA
Key Name: isv:kubernetes OBS Project <isv:kubernetes@build.opensuse.org>
Key Algorithm: RSA 2048
Key Created: Thu 25 Aug 2022 01:21:11 PM -03
Key Expires: Sat 02 Nov 2024 01:21:11 PM -03 (expires in 85 days)
Rpm Name: gpg-pubkey-9a296436-6307a177
Note: Signing data enables the recipient to verify that no modifications occurred after the data
were signed. Accepting data with no, wrong or unknown signature can lead to a corrupted system
and in extreme cases even to a system compromise.
Note: A GPG pubkey is clearly identified by its fingerprint. Do not rely on the key's name. If
you are not sure whether the presented key is authentic, ask the repository provider or check
their web site. Many providers maintain a web page showing the fingerprints of the GPG keys they
are using.
Do you want to reject the key, trust temporarily, or trust always? [r/t/a/?] (r): a
Instale o kubectl usando zypper:
sudo zypper install -y kubectl
Se você estiver no Ubuntu ou em outra distribuição Linux que suporte o gerenciador de pacotes snap, o kubectl está disponível como um aplicativo snap.
snap install kubectl --classic
kubectl version --client
Se você estiver no Linux e usando o gerenciador de pacotes Homebrew, o kubectl está disponível para instalação.
brew install kubectl
kubectl version --client
Para que o kubectl encontre e acesse um cluster Kubernetes, ele precisa de um
arquivo kubeconfig,
que é criado automaticamente quando você cria um cluster usando
kube-up.sh
ou instala com sucesso um cluster Minikube.
Por padrão, a configuração kubectl está localizada em ~/.kube/config.
Verifique se o kubectl está configurado corretamente obtendo o estado do cluster:
kubectl cluster-info
Se você receber uma URL de resposta, o kubectl está configurado corretamente para acessar seu cluster.
Se você receber uma mensagem semelhante à seguinte, o kubectl não está configurado corretamente ou não consegue se conectar a um cluster Kubernetes.
The connection to the server <server-name:port> was refused - did you specify the right host or port?
Por exemplo, se você pretende executar um cluster Kubernetes no seu laptop (localmente), precisará que uma ferramenta como o Minikube seja instalada primeiro, para em seguida executar novamente os comandos indicados acima.
Se o comando kubectl cluster-info retornar a URL de resposta, mas você não conseguir
acessar seu cluster, use o comando abaixo para verificar se ele está configurado
corretamente:
kubectl cluster-info dump
No Kubernetes 1.26, o kubectl removeu os autenticadores embutidos para as distribuições de Kubernetes dos provedores de nuvem abaixo. Estes provedores lançaram plugins para o kubectl que fornecem autenticação específica para a nuvem. Para instruções, veja as seguintes documentações de cada provedor:
Também podem haver outras razões para que a mesma mensagem de erro ocorra, não relacionadas a esta mudança.
O kubectl oferece recursos de autocompletar para Bash, Zsh, Fish e PowerShell, o que pode economizar muita digitação.
Abaixo estão os procedimentos para configurar o autocompletar para Bash, Fish e Zsh.
O script de autocompletar do kubectl para Bash pode ser gerado com o comando kubectl completion bash. O script permite habilitar o autocompletar do kubectl no seu shell.
No entanto, o script autocompletar depende do bash-completion, o que significa que você precisa instalar este software primeiro (executando type _init_completion você pode testar se tem o bash-completion instalado).
O bash-completion é fornecido por muitos gerenciadores de pacotes (veja aqui). Você pode instalar com apt-get install bash-completion ou yum install bash-completion, etc.
Os comandos acima criam /usr/share/bash-completion/bash_completion, que é o script principal de bash-completion. Dependendo do seu gerenciador de pacotes, você tem que adicionar manualmente ao seu arquivo ~/.bashrc.
Para descobrir, recarregue seu shell e execute type _init_completion. Se o comando for bem-sucedido, já está definido, caso contrário, adicione o seguinte ao seu arquivo ~/.bashrc:
source /usr/share/bash-completion/bash_completion
Recarregue o seu shell e verifique se o bash-completion está instalado corretamente digitando type _init_completion.
Agora você precisa garantir que o autocompletar do kubectl esteja ativo em todas as suas sessões shell. Existem duas maneiras pelas quais você pode fazer isso:
echo 'source <(kubectl completion bash)' >>~/.bashrc
kubectl completion bash | sudo tee /etc/bash_completion.d/kubectl > /dev/null
sudo chmod a+r /etc/bash_completion.d/kubectl
Se você tiver um alias para kubectl, você pode estender o autocompletar do shell para trabalhar com esse alias:
echo 'alias k=kubectl' >>~/.bashrc
echo 'complete -o default -F __start_kubectl k' >>~/.bashrc
/etc/bash_completion.d.Todas as abordagens são equivalentes. Depois de recarregar seu shell, o autocompletar do kubectl deve estar funcionando. Para ativar o autocompletar do bash na sessão atual do shell, execute exec bash:
exec bash
O script de autocompletar do kubectl para Fish pode ser gerado com o comando kubectl completion fish. O script permite habilitar o autocompletar do kubectl no seu shell.
Para fazer isso em todas as suas sessões do shell, adicione a seguinte linha ao seu arquivo ~/.config/fish/config.fish:
kubectl completion fish | source
Depois de recarregar seu shell, o autocompletar do kubectl deve estar funcionando.
O script de autocompletar do kubectl para Zsh pode ser gerado com o comando kubectl completion zsh. Este script habilita o autocompletar do kubectl no seu shell.
Para fazer isso em todas as suas sessões de shell, adicione a seguinte linha no arquivo ~/.zshrc:
source <(kubectl completion zsh)
Se você tiver um alias para kubectl, o autocompletar funcionará automaticamente com ele.
Depois de recarregar seu shell, o autocompletar do kubectl deve estar funcionando.
Se você ver um erro similar a 2: command not found: compdef, adicione o seguinte bloco ao início do seu arquivo ~/.zshrc:
autoload -Uz compinit
compinit
kubectl convertUm plugin para a ferramenta Kubernetes de linha de comando kubectl, que permite converter manifestos entre diferentes versões da API.
Isso pode ser particularmente útil para migrar manifestos para uma versão não obsoleta com a versão mais recente da API Kubernetes.
Para mais informações, visite Migrar para APIs não obsoletas
Faça download da versão mais recente com o comando:
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl-convert"
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/arm64/kubectl-convert"
Valide o binário (opcional)
Faça download do arquivo checksum de verificação do kubectl-convert:
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl-convert.sha256"
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/arm64/kubectl-convert.sha256"
Valide o binário kubectl-convert com o arquivo de verificação:
echo "$(cat kubectl-convert.sha256) kubectl-convert" | sha256sum --check
Se válido, a saída será:
kubectl-convert: OK
Se a verificação falhar, o sha256 exibirá o status diferente de zero e a saída será semelhante a:
kubectl-convert: FAILED
sha256sum: WARNING: 1 computed checksum did NOT match
Instale o kubectl-convert
sudo install -o root -g root -m 0755 kubectl-convert /usr/local/bin/kubectl-convert
Verifique se o plugin foi instalado com sucesso
kubectl convert --help
Se não for exibido um erro, isso significa que o plugin foi instalado com sucesso.
Depois de instalar o plugin, remova os arquivos de instalação:
rm kubectl-convert kubectl-convert.sha256
Você deve usar uma versão do kubectl que esteja próxima da versão do seu cluster. Por exemplo, um cliente v1.35 pode se comunicar com as versões v1.34, v1.35 e v1.36 da camada de gerenciamento. Usar a versão compatível mais recente do kubectl ajuda a evitar problemas inesperados.
Existem os seguintes métodos para instalar o kubectl no Windows:
Você tem duas opções para instalar o kubectl em seu dispositivo Windows
Download direto:
Baixe a última versão do patch 1.35 diretamente para sua arquitetura específica visitando a pagina de lançamentos do Kubernetes. Certifique-se de selecionar o binário correto para a sua arquitetura. (e.g., amd64, arm64, etc.).
Usando curl:
Se você tiver o curl instalado, use este comando:
curl.exe -LO "https://dl.k8s.io/release/v1.35.0/bin/windows/amd64/kubectl.exe"
Validar o binário (opcional)
Baixe o arquivo de checksum do kubectl:
curl.exe -LO "https://dl.k8s.io/v1.35.0/bin/windows/amd64/kubectl.exe.sha256"
Valide o binário do kubectl com o arquivo de checksum:
Usando o Prompt de Comando para comparar manualmente a saída do CertUtil ao arquivo de checksum baixado:
CertUtil -hashfile kubectl.exe SHA256
type kubectl.exe.sha256
Usando PowerShell para automatizar a verificação com o operador -eq para obter
um resultado True ou False:
$(Get-FileHash -Algorithm SHA256 .\kubectl.exe).Hash -eq $(Get-Content .\kubectl.exe.sha256)
Adicione (no início ou no final) o diretório do binário kubectl na variável de ambiente PATH.
Teste para garantir que a versão do kubectl seja a mesma que foi baixada:
kubectl version --client
Ou use este comando para uma visão detalhada da versão:
kubectl version --client --output=yaml
kubectl ao PATH. Se você instalou o Docker Desktop anteriormente,
pode ser necessário colocar sua entrada no PATH antes da adicionada pelo instalador do Docker Desktop
ou remover o kubectl do Docker Desktop.Para instalar o kubectl no Windows, você pode usar o gerenciador de pacotes Chocolatey, o instalador de linha de comando Scoop ou o gerenciador de pacotes winget.
choco install kubernetes-cli
scoop install kubectl
winget install -e --id Kubernetes.kubectl
Teste para garantir que a versão que você instalou está atualizada:
kubectl version --client
Navegue até seu diretório pessoal:
# Se você estiver usando o cmd.exe, execute: cd %USERPROFILE%
cd ~
Crie o diretório .kube:
mkdir .kube
Navegue para o diretório .kube que você acabou de criar:
cd .kube
Configure o kubectl para usar um cluster Kubernetes remoto:
New-Item config -type file
Para que o kubectl encontre e acesse um cluster Kubernetes, ele precisa de um
arquivo kubeconfig,
que é criado automaticamente quando você cria um cluster usando
kube-up.sh
ou instala com sucesso um cluster Minikube.
Por padrão, a configuração kubectl está localizada em ~/.kube/config.
Verifique se o kubectl está configurado corretamente obtendo o estado do cluster:
kubectl cluster-info
Se você receber uma URL de resposta, o kubectl está configurado corretamente para acessar seu cluster.
Se você receber uma mensagem semelhante à seguinte, o kubectl não está configurado corretamente ou não consegue se conectar a um cluster Kubernetes.
The connection to the server <server-name:port> was refused - did you specify the right host or port?
Por exemplo, se você pretende executar um cluster Kubernetes no seu laptop (localmente), precisará que uma ferramenta como o Minikube seja instalada primeiro, para em seguida executar novamente os comandos indicados acima.
Se o comando kubectl cluster-info retornar a URL de resposta, mas você não conseguir
acessar seu cluster, use o comando abaixo para verificar se ele está configurado
corretamente:
kubectl cluster-info dump
No Kubernetes 1.26, o kubectl removeu os autenticadores embutidos para as distribuições de Kubernetes dos provedores de nuvem abaixo. Estes provedores lançaram plugins para o kubectl que fornecem autenticação específica para a nuvem. Para instruções, veja as seguintes documentações de cada provedor:
Também podem haver outras razões para que a mesma mensagem de erro ocorra, não relacionadas a esta mudança.
O kubectl oferece suporte ao autocompletar para Bash, Zsh, Fish e PowerShell, o que pode economizar tempo de digitação.
Abaixo estão os procedimentos para configurar o autocompletar no PowerShell.
O script de autocompletar do kubectl para PowerShell, pode ser gerado com o comando kubectl completion powershell.
Para fazer isso em todas as suas sessões de shell, adicione a seguinte linha ao seu arquivo $PROFILE:
kubectl completion powershell | Out-String | Invoke-Expression
Este comando irá regenerar o script de autocompletar toda vez que o PowerShell for iniciado. Você também pode adicionar o script gerado diretamente ao seu arquivo $PROFILE.
Para adicionar o script gerado ao seu arquivo $PROFILE, execute a seguinte linha no prompt do PowerShell:
kubectl completion powershell >> $PROFILE
Após recarregar seu shell, o autocompletar do kubectl deve estar funcionando.
kubectl convertUm plugin para a ferramenta Kubernetes de linha de comando kubectl, que permite converter manifestos entre diferentes versões da API.
Isso pode ser particularmente útil para migrar manifestos para uma versão não obsoleta com a versão mais recente da API Kubernetes.
Para mais informações, visite Migrar para APIs não obsoletas
Baixe a última versão com este comando:
curl.exe -LO "https://dl.k8s.io/release/v1.35.0/bin/windows/amd64/kubectl-convert.exe"
Validar o binário (opcional).
Baixe o arquivo de checksum do kubectl-convert:
curl.exe -LO "https://dl.k8s.io/v1.35.0/bin/windows/amd64/kubectl-convert.exe.sha256"
Valide o binário do kubectl-convert com o arquivo de checksum:
Usando o Prompt de Comando para comparar manualmente a saída do CertUtil ao arquivo de checksum baixado:
CertUtil -hashfile kubectl-convert.exe SHA256
type kubectl-convert.exe.sha256
Usando PowerShell para automatizar a verificação com o operador -eq para obter
um resultado True ou False:
$($(CertUtil -hashfile .\kubectl-convert.exe SHA256)[1] -replace " ", "") -eq $(type .\kubectl-convert.exe.sha256)
Adicione (no início ou no final) o diretório do binário kubectl-convert na variável de ambiente PATH.
Verifique se o plugin foi instalado com sucesso.
kubectl convert --help
Se você não ver um erro, isso significa que o plugin foi instalado com sucesso.
Após instalar o plugin, limpe os arquivos de instalação:
del kubectl-convert.exe
del kubectl-convert.exe.sha256
Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
Um Secret pode conter credenciais de usuário requeridas por Pods para acesso a um banco de dados.
Por exemplo, uma string de conexão de banco de dados é composta por um usuário e senha.
Você pode armazenar o usuário em um arquivo ./username.txt e a senha em um
arquivo ./password.txt na sua máquina local.
echo -n 'admin' > ./username.txt
echo -n '1f2d1e2e67df' > ./password.txt
A opção -n nos comandos acima garante que os arquivos criados não vão conter
uma nova linha extra no final do arquivo de texto. Isso é importante porque
quando o kubectl lê um arquivo e codifica o conteúdo em uma string base64,
o caractere da nova linha extra também é codificado.
O comando kubectl create secret empacota os arquivos em um Secret e cria um
objeto no API server.
kubectl create secret generic db-user-pass \
--from-file=./username.txt \
--from-file=./password.txt
A saída deve ser similar a:
secret/db-user-pass created
O nome da chave padrão é o nome do arquivo. Opcionalmente, você pode definir
o nome da chave usando --from-file=[key=]source. Por exemplo:
kubectl create secret generic db-user-pass \
--from-file=username=./username.txt \
--from-file=password=./password.txt
Você não precisa escapar o caractere especial em senhas a partir de arquivos (--from-file).
Você também pode prover dados para Secret usando a tag --from-literal=<key>=<value>.
Essa tag pode ser especificada mais de uma vez para prover múltiplos pares de chave-valor.
Observe que caracteres especiais como $, \, *, =, e ! vão ser interpretados
pelo seu shell e precisam ser escapados.
Na maioria dos shells, a forma mais fácil de escapar as senhas é usar aspas simples (').
Por exemplo, se sua senha atual é S!B\*d$zDsb=, você precisa executar o comando dessa forma:
kubectl create secret generic db-user-pass \
--from-literal=username=admin \
--from-literal=password='S!B\*d$zDsb='
Você pode verificar se o secret foi criado:
kubectl get secrets
A saída deve ser similar a:
NAME TYPE DATA AGE
db-user-pass Opaque 2 51s
Você pode ver a descrição do Secret:
kubectl describe secrets/db-user-pass
A saída deve ser similar a:
Name: db-user-pass
Namespace: default
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
password: 12 bytes
username: 5 bytes
Os comandos kubectl get e kubectl describe omitem o conteúdo de um Secret por padrão.
Isso para proteger o Secret de ser exposto acidentalmente para uma pessoa não autorizada,
ou ser armazenado em um log de terminal.
Para ver o conteúdo de um Secret que você criou, execute o seguinte comando:
kubectl get secret db-user-pass -o jsonpath='{.data}'
A saída deve ser similar a:
{"password":"MWYyZDFlMmU2N2Rm","username":"YWRtaW4="}
Agora, você pode decodificar os dados de password:
echo 'MWYyZDFlMmU2N2Rm' | base64 --decode
A saída deve ser similar a:
1f2d1e2e67df
Para apagar o Secret que você criou:
kubectl delete secret db-user-pass
kubectlVocê precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
Você pode criar um Secret primeiramente em um arquivo, no formato JSON ou YAML, e depois
criar o objeto. O recurso Secret
contém dois mapas: data e stringData.
O campo data é usado para armazenar dados arbitrários, codificados usando base64. O
campo stringData é usado por conveniência, e permite que você use dados para um Secret
como strings não codificadas.
As chaves para data e stringData precisam ser compostas por caracteres alfanuméricos,
_, - ou ..
Por exemplo, para armazenar duas strings em um Secret usando o campo data, converta
as strings para base64 da seguinte forma:
echo -n 'admin' | base64
A saída deve ser similar a:
YWRtaW4=
echo -n '1f2d1e2e67df' | base64
A saída deve ser similar a:
MWYyZDFlMmU2N2Rm
Escreva o arquivo de configuração do Secret, que será parecido com:
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: YWRtaW4=
password: MWYyZDFlMmU2N2Rm
Perceba que o nome do objeto Secret precisa ser um nome de subdomínio DNS válido.
base64 em Darwin/MacOS, os usuários devem evitar usar a opção -b
para separar linhas grandes. Por outro lado, usuários de Linux devem adicionar a opção
-w 0 ao comando base64 ou o pipe base64 | tr -d '\n' se a opção w não estiver disponívelPara cenários específicos, você pode querer usar o campo stringData ao invés de data.
Esse campo permite que você use strings não-base64 diretamente dentro do Secret,
e a string vai ser codificada para você quando o Secret for criado ou atualizado.
Um exemplo prático para isso pode ser quando você esteja fazendo deploy de uma aplicação que usa um Secret para armazenar um arquivo de configuração, e você quer popular partes desse arquivo de configuração durante o processo de implantação.
Por exemplo, se sua aplicação usa o seguinte arquivo de configuração:
apiUrl: "https://my.api.com/api/v1"
username: "<user>"
password: "<password>"
Você pode armazenar isso em um Secret usando a seguinte definição:
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
stringData:
config.yaml: |
apiUrl: "https://my.api.com/api/v1"
username: <user>
password: <password>
Agora, crie o Secret usando kubectl apply:
kubectl apply -f ./secret.yaml
A saída deve ser similar a:
secret/mysecret created
O campo stringData é um campo de conveniência apenas de leitura. Ele nunca vai ser exibido
ao buscar um Secret. Por exemplo, se você executar o seguinte comando:
kubectl get secret mysecret -o yaml
A saída deve ser similar a:
apiVersion: v1
kind: Secret
metadata:
creationTimestamp: 2018-11-15T20:40:59Z
name: mysecret
namespace: default
resourceVersion: "7225"
uid: c280ad2e-e916-11e8-98f2-025000000001
type: Opaque
data:
config.yaml: YXBpVXJsOiAiaHR0cHM6Ly9teS5hcGkuY29tL2FwaS92MSIKdXNlcm5hbWU6IHt7dXNlcm5hbWV9fQpwYXNzd29yZDoge3twYXNzd29yZH19
Os comandos kubectl get e kubectl describe omitem o conteúdo de um Secret por padrão.
Isso para proteger o Secret de ser exposto acidentalmente para uma pessoa não autorizada,
ou ser armazenado em um log de terminal.
Para verificar o conteúdo atual de um dado codificado, veja decodificando secret.
Se um campo, como username, é especificado em data e stringData,
o valor de stringData é o usado. Por exemplo, dada a seguinte definição do Secret:
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: YWRtaW4=
stringData:
username: administrator
Resulta no seguinte Secret:
apiVersion: v1
kind: Secret
metadata:
creationTimestamp: 2018-11-15T20:46:46Z
name: mysecret
namespace: default
resourceVersion: "7579"
uid: 91460ecb-e917-11e8-98f2-025000000001
type: Opaque
data:
username: YWRtaW5pc3RyYXRvcg==
Onde YWRtaW5pc3RyYXRvcg== é decodificado em administrator.
Para apagar o Secret que você criou:
kubectl delete secret mysecret
kubectlDesde o Kubernetes v1.14, o kubectl provê suporte para gerenciamento de objetos usando Kustomize.
O Kustomize provê geradores de recursos para criar Secrets e ConfigMaps.
Os geradores Kustomize devem ser especificados em um arquivo kustomization.yaml dentro
de um diretório. Depois de gerar o Secret, você pode criar o Secret com kubectl apply.
Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
Você pode criar um Secret definindo um secretGenerator em um
arquivo kustomization.yaml que referencia outros arquivos existentes.
Por exemplo, o seguinte arquivo kustomization referencia os
arquivos ./username.txt e ./password.txt:
secretGenerator:
- name: db-user-pass
files:
- username.txt
- password.txt
Você também pode definir o secretGenerator no arquivo kustomization.yaml
por meio de alguns literais.
Por exemplo, o seguinte arquivo kustomization.yaml contém dois literais
para username e password respectivamente:
secretGenerator:
- name: db-user-pass
literals:
- username=admin
- password=1f2d1e2e67df
Observe que nos dois casos, você não precisa codificar os valores em base64.
Aplique o diretório que contém o arquivo kustomization.yaml para criar o Secret.
kubectl apply -k .
A saída deve ser similar a:
secret/db-user-pass-96mffmfh4k created
Observe que quando um Secret é gerado, o nome do segredo é criado usando o hash dos dados do Secret mais o valor do hash. Isso garante que um novo Secret é gerado cada vez que os dados são modificados.
Você pode verificar que o secret foi criado:
kubectl get secrets
A saída deve ser similar a:
NAME TYPE DATA AGE
db-user-pass-96mffmfh4k Opaque 2 51s
Você pode ver a descrição de um secret:
kubectl describe secrets/db-user-pass-96mffmfh4k
A saída deve ser similar a:
Name: db-user-pass-96mffmfh4k
Namespace: default
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
password.txt: 12 bytes
username.txt: 5 bytes
Os comandos kubectl get e kubectl describe omitem o conteúdo de um Secret por padrão.
Isso para proteger o Secret de ser exposto acidentalmente para uma pessoa não autorizada,
ou ser armazenado em um log de terminal.
Para verificar o conteúdo atual de um dado codificado, veja decodificando secret.
Para apagar o Secret que você criou:
kubectl delete secret db-user-pass-96mffmfh4k
kubectlKubernetes v1.18 [stable]
Esta página mostra como configurar Contas de serviço gerenciadas em grupo (GMSA) para Pods e contêineres que vão executar em nós Windows. Contas de serviço gerenciadas em grupo são um tipo específico de conta do Active Directory que provê gerenciamento automático de senhas, gerenciamento simplificado de service principal name (SPN), e a habilidade de delegar o gerenciamento a outros administradores através de múltiplos servidores.
No Kubernetes, especificações de credenciais GMSA são configuradas dentro do escopo do cluster Kubernetes como recursos personalizados. Os Pods Windows, assim como contêineres individuais dentro de um Pod, podem ser configurados para usar as funções GMSA baseadas em domínio (exemplo: autenticação Kerberos) quando interagirem com outros serviços Windows.
Você precisa ter um cluster Kubernetes, e a ferramenta de linha de comando kubectl
precisa estar configurada para comunicar-se com seu cluster.
O cluster deve possuir nós de carga de trabalho Windows.
Esta seção cobre o conjunto inicial de passos requeridos para cada cluster:
Uma CustomResourceDefinition (CRD) para a especificação de recursos de credencial GMSA precisa ser configurada no cluster, para definir o tipo de recurso do cliente GMSACredentialSpec. Faça o download do YAML do CRD de GMSA
e salve como gmsa-crd.yaml.
A seguir, instale o CRD com kubectl apply -f gmsa-crd.yaml.
Dois webhooks precisam ser configurados no cluster Kubernetes para popular e validar as referências de especificação de credenciais GMSA no nível do Pod ou contêiner:
Um webhook de mutação que expanda as referências para as GMSAs, (por nome a partir de uma especificação de Pod) em uma especificação de credencial completa em formato JSON dentro da especificação do Pod.
Um webhook de validação garante que todas as referências para GMSAs estão autorizadas a serem usadas pela conta de serviço do Pod.
A instalação dos webhooks acima e dos objetos associados requer as etapas abaixo:
Crie um par de chaves de certificado (que será usado para permitir que o contêiner do webhook se comunique com o cluster)
Instale um Secret com o certificado acima.
Crie um Deployment para a lógica principal do webhook.
Crie as configurações de webhook de validação e de mutação, referentes ao Deployment.
Um script
pode ser usado para implantar e configurar os webhooks GMSA e objetos associados
mencionados acima. O script pode ser executado com a opção --dry-run=server
para possibilitar que você possa revisar as alterações antes que sejam aplicadas
no seu cluster.
O template YAML usado pelo script também pode ser usado para implantar os webhooks e objetos associados manualmente (com as substituições apropriadas para os parâmetros).
Antes que os Pods no Kubernetes possam ser configurados para usar GMSAs, as GMSAs apropriadas precisam ser provisionadas no Active Directory como descrito na documentação de GMSA do Windows. Nós de carga de trabalho Windows (que são parte do cluster Kubernetes) precisam ser configurados no Active Directory para acessar as credenciais secretas associadas com a GMSA apropriada, como descrito na documentação de GMSA do Windows.
Com o CRD GMSACredentialSpec instalado (como descrito anteriormente), recursos customizados contendo recursos de especificação de credenciais GMSA podem ser configurados. A especificação de credencial GMSA não contém dados secretos nem sensíveis. É informação que o agente de execução de contêiner pode usar para descrever a apropriada GMSA de um contêiner para o Windows. Especificações de credenciais GMSA podem ser geradas em formato YAML com o utilitário PowerShell script.
A seguir são os passos para gerar a especificação de credencial GMSA YAML manualmente, em formato JSON e então convertê-la para YAML:
Importar o módulo CredentialSpec:
ipmo CredentialSpec.psm1
Crie a especificação da credencial em formato JSON usando New-CredentialSpec.
Para criar a especificação da credencial GMSA nomeada WebApp1,
execute New-CredentialSpec -Name WebApp1 -AccountName WebApp1 -Domain $(Get-ADDomain -Current LocalComputer)
Use Get-CredentialSpec para mostrar o caminho do arquivo JSON.
Converta o arquivo credspec de JSON para o formato YAML e aplique os campos
de cabeçalho necessários apiVersion, kind, metadata e credspec para transformá-lo em
uma instância do recurso customizado GMSACredentialSpec que pode ser configurado no Kubernetes.
A configuração YAML a seguir descreve as especificações de credencial GMSA nomeada
gmsa-WebApp1:
apiVersion: windows.k8s.io/v1
kind: GMSACredentialSpec
metadata:
name: gmsa-WebApp1 #Este é um nome arbitrário, mas será usado como referência
credspec:
ActiveDirectoryConfig:
GroupManagedServiceAccounts:
- Name: WebApp1 #Nome de usuário da conta GMSA
Scope: CONTOSO #Nome de Domínio NETBIOS
- Name: WebApp1 #Nome de usuário da conta GMSA
Scope: contoso.com #Nome de domínio DNS
CmsPlugins:
- ActiveDirectory
DomainJoinConfig:
DnsName: contoso.com #Nome de domínio DNS
DnsTreeName: contoso.com #Nome de domínio DNS raiz
Guid: 244818ae-87ac-4fcd-92ec-e79e5252348a #GUID
MachineAccountName: WebApp1 #Nome de usuário da conta GMSA
NetBiosName: CONTOSO #Nome de domínio NETBIOS
Sid: S-1-5-21-2126449477-2524075714-3094792973 #SID da GMSA
O recurso de especificação de credencial acima deve ser salvo como
gmsa-Webapp1-credspec.yaml e aplicado no cluster usando:
kubectl apply -f gmsa-Webapp1-credspec.yml
Uma ClusterRole precisa ser definida para cada recurso de especificação
de credencial GMSA. Isto autoriza o verbo use em um recurso GMSA específico
por um sujeito, geralmente uma conta de serviço. O exemplo a seguir mostra
um ClusterRole que autoriza o uso de credencial gmsa-WebApp1
acima. Salve o arquivo como gmsa-webapp1-role.yaml e aplique
usando kubectl apply -f gmsa-webapp1-role.yaml
#Criando um Role para ler o credspec
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: webapp1-role
rules:
- apiGroups: ["windows.k8s.io"]
resources: ["gmsacredentialspecs"]
verbs: ["use"]
resourceNames: ["gmsa-WebApp1"]
Uma conta de serviço (com a qual os Pods virão configurados), precisa ser vinculada
ao ClusterRole criado acima. Isto autoriza a conta de serviço a usar a especificação apropriada
de recurso de credencial GMSA. O trecho a seguir mostra a conta de serviço padrão vinculada ao ClusterRole webapp1-role, para usar a especificação
de recurso de credencial gmsa-WebApp1 criada acima.
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: allow-default-svc-account-read-on-gmsa-WebApp1
namespace: default
subjects:
- kind: ServiceAccount
name: default
namespace: default
roleRef:
kind: ClusterRole
name: webapp1-role
apiGroup: rbac.authorization.k8s.io
O campo securityContext.windowsOptions.gmsaCredentialSpecName do Pod, é usado de referência para recursos customizados, em especificações
de certificado GMSA apropriadas em especificações do Pod.
Isto configura todos contêineres do Pod para usar GMSA.
Uma amostra da anotação populada para referir-se a gmsa-WebApp1:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
run: with-creds
name: with-creds
namespace: default
spec:
replicas: 1
selector:
matchLabels:
run: with-creds
template:
metadata:
labels:
run: with-creds
spec:
securityContext:
windowsOptions:
gmsaCredentialSpecName: gmsa-webapp1
containers:
- image: mcr.microsoft.com/windows/servercore/iis:windowsservercore-ltsc2019
imagePullPolicy: Always
name: iis
nodeSelector:
kubernetes.io/os: windows
Contêineres individuais em uma especificação de Pod podem também indicar
a credencial GMSA apropriada, usando o campo securityContext.windowsOptions.gmsaCredentialSpecName por contêiner. Por exemplo:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
run: with-creds
name: with-creds
namespace: default
spec:
replicas: 1
selector:
matchLabels:
run: with-creds
template:
metadata:
labels:
run: with-creds
spec:
containers:
- image: mcr.microsoft.com/windows/servercore/iis:windowsservercore-ltsc2019
imagePullPolicy: Always
name: iis
securityContext:
windowsOptions:
gmsaCredentialSpecName: gmsa-Webapp1
nodeSelector:
kubernetes.io/os: windows
Assim que as especificações do Pod com os campos GMSA preenchidos (como descrito acima) são aplicadas em um cluster, ocorre a seguinte sequência de eventos:
O webhook de mutação resolve e expande todas as referências aos recursos de especificações de credenciais GMSA para o conteúdo das especificações de credenciais GMSA.
O webhook de validação garante que a conta de serviço associada ao Pod, seja autorizada
para o verbo use na especificação GMSA especificada.
O agente de execução de contêiner configura cada contêiner do Windows com a especificação de credencial GMSA especificada, para que o contêiner possa assumir a identidade do GMSA no Active Directory, e tenha acesso aos serviços no domínio usando essa identidade.
hostname ou FQDNSe você estiver enfrentando problemas ao se conectar aos compartilhamentos SMB de Pods usando o hostname ou o FQDN, mas conseguindo acessar os compartilhamentos por meio de seu endereço IPv4, verifique se a chave do registro a seguir está definida nos nós Windows.
reg add "HKLM\SYSTEM\CurrentControlSet\Services\hns\State" /v EnableCompartmentNamespace /t REG_DWORD /d 1
Os Pods em execução precisarão ser recriados para pegar as mudanças de comportamento. Mais informações sobre como essa chave de registro é usada podem ser encontradas aqui
Se você estiver tendo dificuldades para fazer com que o GMSA funcione em seu ambiente, existem algumas etapas de solução de problemas que você pode tentar.
Primeiro, verifique se a especificação de credencial foi passada para o Pod. Para fazer isso,
você precisará rodar kubectl exec em um de seus Pods e verificar
a saída do comando nltest.exe /parentdomain.
No exemplo abaixo, o Pod não recebeu a especificação de credencial corretamente:
kubectl exec -it iis-auth-7776966999-n5nzr powershell.exe
nltest.exe /parentdomain resulta no seguinte erro:
Getting parent domain failed: Status = 1722 0x6ba RPC_S_SERVER_UNAVAILABLE
Se o seu Pod obteve a especificação de credencial corretamente, o próximo passo é
verificar a comunicação com o domínio. Primeiro, de dentro do seu Pod,
execute rapidamente um nslookup para encontrar a raiz do seu domínio.
Isso vai nos dizer 3 coisas:
Se o DNS e o teste de comunicação passarem, em seguida,
você precisará verificar se o Pod estabeleceu um canal de comunicação segura
com o domínio. Para fazer isso, novamente, em seu Pod
execute o comando nltest.exe /query.
nltest.exe /query
Resulta na seguinte saída:
I_NetLogonControl failed: Status = 1722 0x6ba RPC_S_SERVER_UNAVAILABLE
Isso nos diz que, por algum motivo, o Pod não conseguiu se logar no domínio usando a conta definida na especificação de credencial. Você pode tentar reparar o canal seguro executando o seguinte:
nltest /sc_reset:domain.example
Se o comando for bem sucedido, você verá uma saída semelhante a esta:
Flags: 30 HAS_IP HAS_TIMESERV
Trusted DC Name \\dc10.domain.example
Trusted DC Connection Status Status = 0 0x0 NERR_Success
The command completed successfully
Se o excerto acima corrigir o erro, você poderá automatizar a etapa adicionando
o seguinte lifecycle hook à sua especificação de Pod. Se não corrigiu o erro, você
precisará examinar sua especificação de credencial novamente e confirmar que ela está correta e completa.
image: registry.domain.example/iis-auth:1809v1
lifecycle:
postStart:
exec:
command: ["powershell.exe","-command","do { Restart-Service -Name netlogon } while ( $($Result = (nltest.exe /query); if ($Result -like '*0x0 NERR_Success*') {return $true} else {return $false}) -eq $false)"]
imagePullPolicy: IfNotPresent
Se você adicionar a seção lifecycle, mostrada acima à sua especificação de Pod,
o Pod irá executar os comandos listados para reiniciar o serviço netlogon
até que o comando nltest.exe /query execute sem erro.
Kubernetes v1.18 [stable]
Esta página mostra como usar a configuração runAsUserName para Pods
e contêineres que serão executados em nós Windows. Isso é aproximadamente
equivalente à configuração runAsUser específica do Linux, permitindo a você
executar aplicativos em um contêiner com um nome de usuário diferente do padrão.
Você precisa ter um cluster Kubernetes, e a ferramenta de linha de comando Kubectl deve ser configurada para se comunicar com o seu cluster. Espera-se que o cluster tenha nós de carga de trabalho Windows, onde os Pods com contêineres executando as cargas de trabalho do Windows, serão agendados.
Para especificar o nome de usuário com o qual executar os processos de contêiner do Pod,
inclua o campo securityContext (PodSecurityContext)
na especificação do Pod, e dentro dela, o campo WindowsOptions (WindowsSecurityContextOptions)
contendo o campo runAsUserName.
As opções de contexto de segurança do Windows que você especificar para um Pod, se aplicam a todos os contêineres do Pod, inclusive os de inicialização.
Veja abaixo um arquivo de configuração para um Pod do Windows que possui o campo
runAsUserName definido:
apiVersion: v1
kind: Pod
metadata:
name: run-as-username-pod-demo
spec:
securityContext:
windowsOptions:
runAsUserName: "ContainerUser"
containers:
- name: run-as-username-demo
image: mcr.microsoft.com/windows/servercore:ltsc2019
command: ["ping", "-t", "localhost"]
nodeSelector:
kubernetes.io/os: windowsCrie o Pod:
kubectl apply -f https://k8s.io/examples/windows/run-as-username-pod.yaml
Verifique se o contêiner do Pod está em execução:
kubectl get pod run-as-username-pod-demo
Abra um shell para o contêiner em execução:
kubectl exec -it run-as-username-pod-demo -- powershell
Verifique se o shell está executando com o nome de usuário correto:
echo $env:USERNAME
A saída deve ser:
ContainerUser
Para especificar o nome de usuário com o qual executar os processos de um contêiner,
inclua o campo SecurityContext (SecurityContext)
no manifesto do contêiner, e dentro dele, o campo WindowsOptions
(WindowsSecurityContextOptions)
contendo o campo runAsUserName.
As opções de contexto de segurança do Windows que você especificar para um contêiner, se aplicam apenas a esse contêiner individual, e substituem as configurações feitas no nível do Pod.
Aqui está o arquivo de configuração para um pod que possui um contêiner,
e o campo runAsUserName está definido no nível do Pod e no nível do contêiner:
apiVersion: v1
kind: Pod
metadata:
name: run-as-username-container-demo
spec:
securityContext:
windowsOptions:
runAsUserName: "ContainerUser"
containers:
- name: run-as-username-demo
image: mcr.microsoft.com/windows/servercore:ltsc2019
command: ["ping", "-t", "localhost"]
securityContext:
windowsOptions:
runAsUserName: "ContainerAdministrator"
nodeSelector:
kubernetes.io/os: windows
Crie o Pod:
kubectl apply -f https://k8s.io/examples/windows/run-as-username-container.yaml
Verifique se o contêiner do Pod está em execução:
kubectl get pod run-as-username-container-demo
Abra um shell para o contêiner em execução:
kubectl exec -it run-as-username-container-demo -- powershell
Verifique se o shell está executando o usuário correto, (aquele definido no nível do contêiner):
echo $env:USERNAME
A saída deve ser:
ContainerAdministrator
Para usar esse recurso, o valor definido no campo runAsUserName deve ser um nome
de usuário válido. Deve ter o seguinte formato: DOMAIN\USER, onde DOMAIN\
é opcional. Os nomes de usuário do Windows não diferenciam letras maiúsculas
e minúsculas. Além disso, existem algumas restrições em relação ao DOMAIN e USER:
runAsUserName: não pode estar vazio, e não pode conter caracteres
de controle (Valores ASCII : 0x00-0x1F, 0x7F)DOMAIN NetBios, ou um nome de DNS, cada um com suas próprias restrições:
. (ponto),
e não podem conter os seguintes caracteres: \ / : * ? " < > |. (ponto) ou - (traço).USER: deve ter no máximo 20 caracteres, não pode conter somente pontos ou espaços,
e não pode conter os seguintes caracteres: " / \ [ ] : ; | = , + * ? < > @.Exemplos de valores aceitáveis para o campo runAsUserName: ContainerAdministrator,
ContainerUser, NT AUTHORITY\NETWORK SERVICE, NT AUTHORITY\LOCAL SERVICE.
Para mais informações sobre estas limitações, verifique aqui e aqui.
Esta página mostra como configurar os Pods para que, a eles sejam atribuídos particularmente classes de Qualidade de Serviço (QoS). O Kubernetes usa classes QoS para tomar decisões sobre agendamento e despejo de Pods.
Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
Para verificar a versão, digite kubectl version.
Quando o Kubernetes cria um Pod, ele atribui uma dessas classes de QoS ao Pod:
Crie um namespace, assim os seus recursos criados neste exercício estarão isolados do resto do seu cluster.
kubectl create namespace qos-example
GuaranteedPara que um Pod receba uma classe de QoS Guaranteed:
Essas restrições se aplicam igualmente a contêineres de inicialização bem como de aplicativos.
Aqui está o arquivo de configuração para um pod que possui um contêiner. O contêiner tem um limite de memória e um requisito de memória, ambos iguais a 200 MiB. O contêiner tem um limite de CPU e uma solicitação de CPU, ambos iguais a 700 miliCPU:
apiVersion: v1
kind: Pod
metadata:
name: qos-demo
namespace: qos-example
spec:
containers:
- name: qos-demo-ctr
image: nginx
resources:
limits:
memory: "200Mi"
cpu: "700m"
requests:
memory: "200Mi"
cpu: "700m"
Crie o Pod:
kubectl apply -f https://k8s.io/examples/pods/qos/qos-pod.yaml --namespace=qos-example
Veja informações detalhadas sobre o pod:
kubectl get pod qos-demo --namespace=qos-example --output=yaml
A saída mostra que o Kubernetes forneceu ao pod uma classe de QoS Guaranteed. A saída também
verifica se o contêiner do Pod tem um requisito de memória que corresponde ao seu limite de memória, e possui
um requisito de CPU que corresponde ao seu limite de CPU.
spec:
containers:
...
resources:
limits:
cpu: 700m
memory: 200Mi
requests:
cpu: 700m
memory: 200Mi
...
status:
qosClass: Guaranteed
Apague seu Pod:
kubectl delete pod qos-demo --namespace=qos-example
BurstableUm Pod recebe uma classe de QoS Burstable se:
Guaranteed.Aqui está o arquivo de configuração para um Pod que possui um contêiner. O contêiner tem um limite de memória de 200 MiB e um requisito de memória de 100 MiB.
apiVersion: v1
kind: Pod
metadata:
name: qos-demo-2
namespace: qos-example
spec:
containers:
- name: qos-demo-2-ctr
image: nginx
resources:
limits:
memory: "200Mi"
requests:
memory: "100Mi"
Crie o Pod:
kubectl apply -f https://k8s.io/examples/pods/qos/qos-pod-2.yaml --namespace=qos-example
Veja informações detalhadas sobre o Pod:
kubectl get pod qos-demo-2 --namespace=qos-example --output=yaml
A saída mostra que o Kubernetes forneceu ao pod uma classe de QoS Burstable.
spec:
containers:
- image: nginx
imagePullPolicy: Always
name: qos-demo-2-ctr
resources:
limits:
memory: 200Mi
requests:
memory: 100Mi
...
status:
qosClass: Burstable
Apague seu Pod:
kubectl delete pod qos-demo-2 --namespace=qos-example
BestEffortPara que um Pod receba uma classe de QoS BestEffort, os contêineres no pod não devem
ter quaisquer requisitos ou limites de CPU ou memória.
Aqui está o arquivo de configuração para um Pod que possui um contêiner. O contêiner não tem requisitos ou limites de memória ou CPU:
apiVersion: v1
kind: Pod
metadata:
name: qos-demo-3
namespace: qos-example
spec:
containers:
- name: qos-demo-3-ctr
image: nginx
Crie o Pod:
kubectl apply -f https://k8s.io/examples/pods/qos/qos-pod-3.yaml --namespace=qos-example
Veja informações detalhadas sobre o Pod:
kubectl get pod qos-demo-3 --namespace=qos-example --output=yaml
A saída mostra que o Kubernetes forneceu ao Pod uma classe de QoS BestEffort.
spec:
containers:
...
resources: {}
...
status:
qosClass: BestEffort
Apague seu Pod:
kubectl delete pod qos-demo-3 --namespace=qos-example
Aqui está o arquivo de configuração para um Pod que possui dois contêineres. Um contêiner especifica um requisito de memória de 200 MiB. O outro contêiner não especifica nenhum requisito ou limite.
apiVersion: v1
kind: Pod
metadata:
name: qos-demo-4
namespace: qos-example
spec:
containers:
- name: qos-demo-4-ctr-1
image: nginx
resources:
requests:
memory: "200Mi"
- name: qos-demo-4-ctr-2
image: redis
Observe que este Pod atende aos critérios para a classe de QoS Burstable. Isto é, ele não atende aos
critérios para a classe de QoS Guaranteed, e um de seus contêineres tem um requisito de memória.
Crie o Pod:
kubectl apply -f https://k8s.io/examples/pods/qos/qos-pod-4.yaml --namespace=qos-example
Veja informações detalhadas sobre o Pod:
kubectl get pod qos-demo-4 --namespace=qos-example --output=yaml
A saída mostra que o Kubernetes forneceu ao pod uma classe de QoS Burstable:
spec:
containers:
...
name: qos-demo-4-ctr-1
resources:
requests:
memory: 200Mi
...
name: qos-demo-4-ctr-2
resources: {}
...
status:
qosClass: Burstable
Apague seu Pod:
kubectl delete pod qos-demo-4 --namespace=qos-example
Apague seu namespace:
kubectl delete namespace qos-example
Configurar Requisitos e Limites de Memória Padrão Para um Namespace
Configurar Requisitos e Limites Padrão de CPU Para um Namespace
Configurar Restrições de Memória Mínima e Máxima Para um Namespace
Configurar Restrições Mínimas e Máximas de CPU Para um Namespace
Topologia de Controle de Gerenciamento de Politicas em um Nó
Kubernetes v1.35 [alpha](desabilitado por padrão)Esta página explica como alterar os recursos de CPU e memória definidos no nível do Pod sem recriá-lo.
A funcionalidade de redimensionamento de Pod em vigor permite modificar alocações de recursos para um Pod em execução, evitando a interrupção da aplicação. O processo para redimensionar recursos de contêineres individuais é abordado em Redimensionar recursos de CPU e memória atribuídos a contêineres.
Esta página destaca o redimensionamento de recursos em vigor no nível do Pod. Os recursos no nível do Pod são definidos em spec.resources e atuam como o limite superior dos recursos agregados consumidos por todos os contêineres no Pod. A funcionalidade de redimensionamento de recursos em vigor no nível do Pod permite alterar essas alocações agregadas de CPU e memória para um Pod em execução diretamente.
Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
O seu servidor Kubernetes deve estar numa versão igual ou superior a 1.35.Para verificar a versão, digite kubectl version.
Os seguintes feature gates devem estar habilitados para sua camada de gerenciamento e para todos os nós do seu cluster:
InPlacePodLevelResourcesVerticalScalingPodLevelResourcesInPlacePodVerticalScalingNodeDeclaredFeaturesA versão do cliente kubectl deve ser pelo menos v1.32 para usar a flag --subresource=resize.
O mecanismo que o kubelet usa para rastrear e tentar efetuar novamente alterações de recursos é compartilhado entre solicitações de redimensionamento no nível do contêiner e no nível do Pod.
Os status, motivos e prioridades de retentativa são idênticos aos definidos para redimensionamento de contêiner:
Condições de status: O kubelet usa PodResizePending (com motivos como Infeasible ou Deferred) e PodResizeInProgress para comunicar o estado da solicitação.
Prioridade de retentativa: Redimensionamentos adiados são repetidos com base em PriorityClass, depois na classe de QoS (Guaranteed sobre Burstable) e, finalmente, pela duração em que foram adiados.
Rastreamento: Você pode usar os campos observedGeneration para rastrear qual especificação do Pod (metadata.generation) corresponde ao status da última solicitação de redimensionamento processada.
Para uma descrição completa dessas condições e lógica de retentativa, consulte a seção Status de redimensionamento do Pod na documentação de redimensionamento de contêiner.
O redimensionamento de recursos no nível do Pod não suporta nem requer sua própria política de reinicialização.
Sem política no nível do Pod: Alterações nos recursos agregados do Pod (spec.resources) são sempre aplicadas na versão em vigor sem acionar uma reinicialização. Isso ocorre porque os recursos no nível do Pod atuam como uma restrição geral no cgroup do Pod e não gerenciam diretamente o agente de execução da aplicação dentro dos contêineres.
Política de contêiner ainda governa: A resizePolicy ainda deve ser configurada no nível do contêiner (spec.containers[*].resizePolicy). Esta política determina se um contêiner individual é reiniciado quando suas solicitações ou limites de recursos mudam, independentemente de essa alteração ter sido iniciada por um redimensionamento direto no nível do contêiner ou por uma atualização no envelope geral de recursos no nível do Pod.
Para o Kubernetes 1.35, o redimensionamento de recursos no nível do Pod em vigor está sujeito a todas as limitações descritas para o redimensionamento de recursos no nível do contêiner, que você pode encontrar aqui: Redimensionar recursos de CPU e memória atribuídos a contêineres: Limitações.
Além disso, a seguinte restrição é específica para o redimensionamento de recursos no nível do Pod:
Validação de solicitações de contêiner: Um redimensionamento só é permitido se as solicitações de recursos resultantes no nível do Pod (spec.resources.requests) forem maiores ou iguais à soma das solicitações de recursos correspondentes de todos os contêineres individuais dentro do Pod. Isso mantém a disponibilidade mínima garantida de recursos para o Pod.
Validação de limites de contêiner: Um redimensionamento é permitido se os limites de contêineres individuais forem menores ou iguais aos limites de recursos no nível do Pod (spec.resources.limits). O limite no nível do Pod serve como um limite que nenhum contêiner individual pode exceder, mas a soma dos limites de contêineres pode exceder o limite no nível do Pod, permitindo o compartilhamento de recursos entre contêineres dentro do Pod.
Primeiro, crie um Pod projetado para redimensionamento de CPU em vigor e redimensionamento de memória que requer reinicialização.
apiVersion: v1
kind: Pod
metadata:
name: pod-level-resize-demo
spec:
containers:
- name: pause
image: registry.k8s.io/pause:3.9
resizePolicy:
- resourceName: cpu
restartPolicy: NotRequired # Padrão, mas explícito aqui
- resourceName: memory
restartPolicy: RestartContainer
resources:
requests:
cpu: 100m
memory: 100Mi
- name: nginx-server
image: registry.k8s.io/nginx:latest
resizePolicy:
- resourceName: cpu
restartPolicy: RestartContainer
- resourceName: memory
restartPolicy: RestartContainer
resources: # Recursos no nível do Pod
requests:
cpu: 200m
memory: 200Mi
limits:
cpu: 200m
memory: 200Mi
Crie o Pod:
kubectl create -f pod-level-resize.yaml
Este Pod inicia na classe de QoS Guaranteed, pois as solicitações no nível do Pod são iguais aos limites. Verifique seu estado inicial:
# Aguarde um momento para o Pod estar em execução
kubectl get pod pod-level-resize-demo --output=yaml
Observe o spec.resources (200m CPU, 200Mi memória). Note o
status.containerStatuses[0].restartCount (deve ser 0) e
status.containerStatuses[1].restartCount (deve ser 0).
Agora, aumente a solicitação e o limite de CPU no nível do Pod para 300m. Você usa kubectl patch com o argumento de linha de comando --subresource resize.
kubectl patch pod resize-demo --subresource resize --patch \
'{"spec":{"resources":{"requests":{"cpu":"300m"}, "limits":{"cpu":"300m"}}}}'
# Métodos alternativos:
# kubectl -n qos-example edit pod resize-demo --subresource resize
# kubectl -n qos-example apply -f <updated-manifest> --subresource resize --server-side
--subresource resize requer a versão v1.32.0 ou posterior do cliente kubectl.
Versões mais antigas reportarão um erro invalid subresource.Verifique o status do Pod novamente após aplicar o patch:
kubectl get pod pod-level-resize-demo --output=yaml
Você deve ver:
spec.resources.requests e spec.resources.limits agora mostram cpu: 300m.status.containerStatuses[0].restartCount permanece 0, porque a
resizePolicy de CPU era NotRequired.status.containerStatuses[1].restartCount aumentou para 1 indicando que o
contêiner foi reiniciado para aplicar a alteração de CPU. A reinicialização ocorreu no Contêiner 1 apesar do redimensionamento ser aplicado no nível do Pod, devido à relação intrincada entre limites no nível do Pod e políticas no nível do contêiner. Como o Contêiner 1 não especificou um limite de CPU explícito, sua configuração de recursos subjacente (por exemplo, cgroups) adotou implicitamente o limite geral de CPU do Pod como seu limite máximo efetivo de consumo. Quando o limite de CPU no nível do Pod foi alterado de 200m para 300m, essa ação consequentemente mudou o limite implícito aplicado ao Contêiner 1. Como o Contêiner 1 tinha sua resizePolicy explicitamente definida como RestartContainer para CPU, o kubelet foi obrigado a reiniciar o contêiner para aplicar corretamente essa alteração no mecanismo subjacente de aplicação de recursos, confirmando assim que alterar limites no nível do Pod pode acionar políticas de reinicialização de contêiner mesmo quando os limites de contêiner não são definidos diretamente.Exclua o Pod:
kubectl pod-level-resize-demo
Configurar solicitações e limites de memória padrão para um Namespace
Configurar solicitações e limites de CPU padrão para um Namespace
Configurar restrições mínimas e máximas de memória para um Namespace
Configurar restrições mínimas e máximas de CPU para um Namespace
Kubernetes v1.35 [stable]
Esta página mostra como atribuir recursos estendidos a um Contêiner.
Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
Para verificar a versão, digite kubectl version.
Antes de fazer este exercício, faça o exercício em Anunciar recursos estendidos para um Nó. Isso configurará um de seus nós para anunciar um recurso de dongle.
Para solicitar um recurso estendido, inclua o campo resources:requests no seu
manifesto do contêiner. Recursos estendidos são totalmente qualificados
com qualquer domínio fora do *.kubernetes.io/. Nomes de recursos estendidos válidos
tem a forma de example.com/foo, onde example.com é substituído pelo domínio
da sua organização e foo é um nome descritivo de recurso.
Aqui está o arquivo de configuração para um pod que possui um contêiner:
apiVersion: v1
kind: Pod
metadata:
name: extended-resource-demo
spec:
containers:
- name: extended-resource-demo-ctr
image: nginx
resources:
requests:
example.com/dongle: 3
limits:
example.com/dongle: 3
No arquivo de configuração, você pode ver que o contêiner solicita 3 dongles.
Crie um Pod:
kubectl apply -f https://k8s.io/examples/pods/resource/extended-resource-pod.yaml
Verifique se o pod está em execução:
kubectl get pod extended-resource-demo
Descreva o pod:
kubectl describe pod extended-resource-demo
A saída mostra as solicitações de dongle:
Limits:
example.com/dongle: 3
Requests:
example.com/dongle: 3
Aqui está o arquivo de configuração para um pod que possui um contêiner. O contêiner solicita dois dongles.
apiVersion: v1
kind: Pod
metadata:
name: extended-resource-demo-2
spec:
containers:
- name: extended-resource-demo-2-ctr
image: nginx
resources:
requests:
example.com/dongle: 2
limits:
example.com/dongle: 2
O Kubernetes não poderá satisfazer o pedido de dois dongles, porque o primeiro pod usou três dos quatro dongles disponíveis.
Tente criar um pod:
kubectl apply -f https://k8s.io/examples/pods/resource/extended-resource-pod-2.yaml
Descreva o pod:
kubectl describe pod extended-resource-demo-2
A saída mostra que o pod não pode ser agendado, porque não há nó que tenha 2 dongles disponíveis:
Conditions:
Type Status
PodScheduled False
...
Events:
...
... Warning FailedScheduling pod (extended-resource-demo-2) failed to fit in any node
fit failure summary on nodes : Insufficient example.com/dongle (1)
Veja o status do pod:
kubectl get pod extended-resource-demo-2
A saída mostra que o Pod foi criado, mas não está programado para ser executado em um nó. Tem um status de pendente:
NAME READY STATUS RESTARTS AGE
extended-resource-demo-2 0/1 Pending 0 6m
Exclua os Pods que você criou para este exercício:
kubectl delete pod extended-resource-demo
kubectl delete pod extended-resource-demo-2
Esta página mostra como configurar um Pod para usar um Volume para armazenamento.
O sistema de arquivos de um contêiner apenas existe enquanto o contêiner existir.
Então, quando um contêiner termina e reinicia, as alterações do sistema de arquivos
são perdidas.
Para um armazenamento mais consistente, independente do contêiner, você pode usar um
Volume. Isso é especialmente importante para aplicações
stateful, tal como armazenamentos chave-valor (tal como Redis) e bancos de dados.
Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
Para verificar a versão, digite kubectl version.
Neste exercício, você cria um Pod que executa um contêiner. Este Pod tem um Volume do tipo emptyDir que persiste durante a existência do Pod, mesmo que o contêiner termine e reinicie. Aqui está o arquivo de configuração para o pod:
apiVersion: v1
kind: Pod
metadata:
name: redis
spec:
containers:
- name: redis
image: redis
volumeMounts:
- name: redis-storage
mountPath: /data/redis
volumes:
- name: redis-storage
emptyDir: {}
Crie o Pod:
kubectl apply -f https://k8s.io/examples/pods/storage/redis.yaml
Verifique se o contêiner do pod está funcionando, e então procure por mudanças no Pod:
kubectl get pod redis --watch
A saída se parece com isso:
NAME READY STATUS RESTARTS AGE
redis 1/1 Running 0 13s
Em outro terminal, pegue um shell para o contêiner em execução:
kubectl exec -it redis -- /bin/bash
No seu shell, vá para /data/redis, e então crie um arquivo:
root@redis:/data# cd /data/redis/
root@redis:/data/redis# echo Hello > test-file
No seu shell, liste os processos em execução:
root@redis:/data/redis# apt-get update
root@redis:/data/redis# apt-get install procps
root@redis:/data/redis# ps aux
A saída é semelhante a esta:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
redis 1 0.1 0.1 33308 3828 ? Ssl 00:46 0:00 redis-server *:6379
root 12 0.0 0.0 20228 3020 ? Ss 00:47 0:00 /bin/bash
root 15 0.0 0.0 17500 2072 ? R+ 00:48 0:00 ps aux
Em seu shell, encerre o processo do Redis:
root@redis:/data/redis# kill <pid>
Onde <pid> é o process ID (PID) do Redis.
No seu terminal original, preste atenção nas mudanças no Pod do Redis. Eventualmente, você vai ver algo assim:
NAME READY STATUS RESTARTS AGE
redis 1/1 Running 0 13s
redis 0/1 Completed 0 6m
redis 1/1 Running 1 6m
Neste ponto, o Contêiner terminou e reiniciou. Isso porque o Pod do Redis tem uma
restartPolicy
de Always.
Abra um shell dentro do Contêiner reiniciado:
kubectl exec -it redis -- /bin/bash
No seu shell, vá para /data/redis, e verifique se test-file ainda está lá.
root@redis:/data/redis# cd /data/redis/
root@redis:/data/redis# ls
test-file
Exclua o pod que você criou para este exercício:
kubectl delete pod redis
Veja Volume.
Veja Pod.
Além do armazenamento de disco local fornecido por emptyDir, o Kubernetes
suporta muitas soluções de armazenamento diferentes, conectadas via rede, incluindo PD na
GCE e EBS na EC2, que são preferidos para dados críticos e vão lidar com os
detalhes, como montar e desmontar os dispositivos nos Nós. Veja
Volumes para mais detalhes.
Esta página mostra como configurar um Pod para usar um PersistentVolumeClaim para armazenamento. Aqui está o resumo do processo:
Você, como administrador do cluster, faz a criação de um Volume Persistente suportado por armazenamento físico. Você não associa o volume a nenhum Pod.
Você, agora assumindo o papel de desenvolvedor/usuário do cluster, faz a criação de um PersistentVolumeClaim que é automaticamente vinculado ao Volume Persistente adequado.
Você cria um Pod que usa o PersistentVolumeClaim acima para armazenamento.
Você precisa ter um cluster Kubernetes que tenha apenas um nó, e a ferramenta de linha de comando kubectl configurada para se comunicar com seu cluster. Se você ainda não tem um cluster de um único nó, você pode criar um usando o Minikube.
Familiarize-se com o material em Volumes persistentes.
Abra um shell no único nó do seu cluster. A maneira de abrir um shell vai depender de como
você inicializou seu cluster. Por exemplo, se você estiver usando o Minikube,
você pode abrir um shell para o seu nó digitando minikube ssh.
No seu shell desse nó, crie um diretótio /mnt/data:
# Assumindo que o seu nó use "sudo" para executar comandos
# como superusuário
sudo mkdir /mnt/data
content/pt-br/docs/tasks/configure-pod-container/configure-service-account.md
No diretório /mnt/data, crie o arquivo index.html:
# Novamente assumindo que seu nó use "sudo" para executar comandos
# como superusuário
sudo sh -c "echo 'Hello from Kubernetes storage' > /mnt/data/index.html"
sudo, você pode
geralmente fazer isso funcionar substituindo sudo pelo nome da outra ferramenta.Teste se o arquivo index.html existe:
cat /mnt/data/index.html
A saída deve ser:
Hello from Kubernetes storage
Você agora pode fechar o shell do seu nó.
Neste exercício, você cria um Volume Persistente hostPath. O Kubernetes suporta
hostPath para desenvolvimento e teste em um cluster com apenas um nó. Um Volume Persistente
hostPath usa um arquivo ou diretório no nó, para emular um armazenamento conectado pela rede.
Em um cluster de produção, você não usaria hostPath. Em vez disso um administrador
de cluster provisionaria um recurso de rede, como um disco persistente do
Google Compute Engine, um NFS compartilhado, ou um volume do
Amazon Elastic Block Store. Administradores podem também usar classes de armazenamento
para incializar provisionamento dinâmico.
Aqui está o arquivo de configuração para o Volume Persistente hostPath:
apiVersion: v1
kind: PersistentVolume
metadata:
name: task-pv-volume
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/mnt/data"
O arquivo de configuração especifica que o volume está no diretório /mnt/data do nó do cluster.
A configuração também especifica um tamanho de 10 gibibytes e um modo de acesso
ReadWriteOnce, o que significa que o volume pode ser montado como leitura-escrita
pelo único nó. Define o nome da classe de armazenamento
manual para o Volume Persistente, que será usado para vincular requisições
PersistentVolumeClaim à esse Volume Persistente.
Crie o Volume Persistente:
kubectl apply -f https://k8s.io/examples/pods/storage/pv-volume.yaml
Veja informações do Volume Persistente:
kubectl get pv task-pv-volume
A saída mostra que o Volume Persistente tem um STATUS de Available. Isto
significa que ainda não foi vinculado a um PersistentVolumeClaim.
NAME CAPACITY ACCESSMODES RECLAIMPOLICY STATUS CLAIM STORAGECLASS REASON AGE
task-pv-volume 10Gi RWO Retain Available manual 4s
PersistentVolumeClaimO próximo passo é criar um PersistentVolumeClaim. Pods usam PersistentVolumeClaims
para requisitar armazenamento físico. Neste exercício, você vai criar
um PersistentVolumeClaim que requisita um volume com pelo menos três
gibibytes, com acesso de leitura-escrita para pelo menos um nó.
Aqui está o arquivo de configuração para oPersistentVolumeClaim:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: task-pv-claim
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 3Gi
Crie o PersistentVolumeClaim:
kubectl apply -f https://k8s.io/examples/pods/storage/pv-claim.yaml
Após criar o PersistentVolumeClaim, o Kubernetes control plane procura por um
Volume Persistente que satisfaça os requerimentos reivindicados. Se o control plane
encontrar um Volume Persistente adequado, com a mesma classe de armazenamento,
ele liga o volume requisitado.
Olhe novamente o Volume Persistente:
kubectl get pv task-pv-volume
Agora a saída mostra um STATUS de Bound.
NAME CAPACITY ACCESSMODES RECLAIMPOLICY STATUS CLAIM STORAGECLASS REASON AGE
task-pv-volume 10Gi RWO Retain Bound default/task-pv-claim manual 2m
Olhe para o PersistentVolumeClaim:
kubectl get pvc task-pv-claim
A saída mostra que oPersistentVolumeClaim está vinculado ao seu Volume Persistente,
task-pv-volume.
NAME STATUS VOLUME CAPACITY ACCESSMODES STORAGECLASS AGE
task-pv-claim Bound task-pv-volume 10Gi RWO manual 30s
O próximo passo é criar um Pod que usa o seu PersistentVolumeClaim como um volume.
Aqui está o arquivo de configuração para o Pod:
apiVersion: v1
kind: Pod
metadata:
name: task-pv-pod
spec:
volumes:
- name: task-pv-storage
persistentVolumeClaim:
claimName: task-pv-claim
containers:
- name: task-pv-container
image: nginx
ports:
- containerPort: 80
name: "http-server"
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: task-pv-storage
Note que o arquivo de configuração do Pod especifica um PersistentVolumeClaim, mas não
especifica um Volume Persistente. Do ponto de vista do Pod, a reivindicação é de um volume.
Crie o Pod:
kubectl apply -f https://k8s.io/examples/pods/storage/pv-pod.yaml
Verifique se o contêiner no Pod está executando;
kubectl get pod task-pv-pod
Abra o shell do contêiner, executando no seu Pod:
kubectl exec -it task-pv-pod -- /bin/bash
No seu shell, verifique se o nginx está servindo o arquivo index.html do volume
do hostPath:
# Certifique-se de executar esses 3 comandos dentro do shell, na raiz que vem da
# execução "kubectl exec" do passo anterior
apt update
apt install curl
curl http://localhost/
A saída mostra o texto que você escreveu no arquivo index.html no volume do
hostPath:
Hello from Kubernetes storage
Se você vir essa mensagem, configurou com sucesso um pod para
usar o armazenamento de um PersistentVolumeClaim.
Exclua o Pod, o PersistentVolumeClaim e o Volume Persistente:
kubectl delete pod task-pv-pod
kubectl delete pvc task-pv-claim
kubectl delete pv task-pv-volume
Se você ainda não tem um shell aberto no nó em seu cluster, Abra um novo shell da mesma maneira que você fez antes. No shell do seu nó, remova o arquivo e o diretório que você criou:
# Pressupondo que seu nó usa "sudo" para executar comandos
# como superusuário
sudo rm /mnt/data/index.html
sudo rmdir /mnt/data
Você pode agora fechar o shell do seu nó.
apiVersion: v1
kind: Pod
metadata:
name: test
spec:
containers:
- name: test
image: nginx
volumeMounts:
# a mount for site-data
- name: config
mountPath: /usr/share/nginx/html
subPath: html
# another mount for nginx config
- name: config
mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf
volumes:
- name: config
persistentVolumeClaim:
claimName: test-nfs-claim
Você pode realizar a montagem de 2 volumes no seu contêiner nginx:
/usr/share/nginx/html para o website estático
/etc/nginx/nginx.conf para a configuração padrão
Armazenamento configurado com um group ID (GID) possibilita a escrita somente pelos
Pods usando a mesma GID. GIDs incompatíveis ou perdidos causam erros de negação
de permissão. Para reduzir a necessidade de coordenação de usuários, um administrador
pode anotar um Volume Persistente com uma GID. Então a GID é automaticamente
adicionada a qualquer Pod que use um Volume Persistente.
Use a anotação pv.beta.kubernetes.io/gid como a seguir:
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv1
annotations:
pv.beta.kubernetes.io/gid: "1234"
Quando um Pod consome um Volume Persistente que tem uma anotação GID, o GID anotado é aplicado à todos os contêiners no Pod, da mesma forma que as GIDs especificadas no contexto de segurança em que o Pod está. Cada GID, se é originário de uma anotação de Volume Persistente ou da especificação do Pod, é aplicada ao primeiro processo executando em cada contêiner.
Esta página mostra como atribuir um Pod Kubernetes a um nó particular em um cluster Kubernetes.
Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
Para verificar a versão, digite kubectl version.
Liste os nós em seu cluster, juntamente com seus rótulos:
kubectl get nodes --show-labels
A saída é similar a esta:
NAME STATUS ROLES AGE VERSION LABELS
worker0 Ready <none> 1d v1.13.0 ...,kubernetes.io/hostname=worker0
worker1 Ready <none> 1d v1.13.0 ...,kubernetes.io/hostname=worker1
worker2 Ready <none> 1d v1.13.0 ...,kubernetes.io/hostname=worker2
Escolha um de seus nós, e adicione um rótulo a ele:
kubectl label nodes <your-node-name> disktype=ssd
onde <your-node-name> é o nome do seu nó escolhido.
Verifique se seu nó escolhido tem o rótulo disktype=ssd:
kubectl get nodes --show-labels
A saída é similiar a esta:
NAME STATUS ROLES AGE VERSION LABELS
worker0 Ready <none> 1d v1.13.0 ...,disktype=ssd,kubernetes.io/hostname=worker0
worker1 Ready <none> 1d v1.13.0 ...,kubernetes.io/hostname=worker1
worker2 Ready <none> 1d v1.13.0 ...,kubernetes.io/hostname=worker2
Na saída anterior, você pode ver que o nó worker0 tem o rótulo disktype=ssd.
Este arquivo de configuração de pod descreve um pod que tem um seletor de nó,
disktype: ssd. Isto significa que o pod será agendado em um nó que tem o rótulo disktype=ssd.
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
env: test
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
nodeSelector:
disktype: ssd
Use o arquivo de configuração para criar um pod que será agendado no nó escolhido:
kubectl apply -f https://k8s.io/examples/pods/pod-nginx.yaml
Verifique se o pod está executando no nó escolhido:
kubectl get pods --output=wide
A saída é similar a esta:
NAME READY STATUS RESTARTS AGE IP NODE
nginx 1/1 Running 0 13s 10.200.0.4 worker0
Você pode também agendar um pod para um nó específico usando nodeName.
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
nodeName: foo-node # schedule pod to specific node
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
Use o arquivo de configuração para criar um pod que será agendado somente no nó foo-node.
Muitas aplicações dependem da configuração que é usada durante a inicialização do aplicativo ou do agente de execução. Na maioria das vezes, há um requisito para ajustar os valores atribuídos aos parâmetros de configuração. O objeto ConfigMap é a maneira usada no Kubernetes para injetar dados de configuração em Pods de aplicativos. O ConfigMap permite que você desacople os artefatos de configuração do conteúdo da imagem, para manter os aplicativos de contêiner portáveis. Esta página fornece uma série de exemplos de uso, demonstrando como criar ConfigMaps e configurar Pods usando dados armazenados em ConfigMaps.
Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
Para verificar a versão, digite kubectl version.
Você pode usar kubectl create configmap ou um gerador de ConfigMap, em um arquivo kustomization.yaml para criar um ConfigMap. Perceba que o kubectl começou a suportar o kustomization.yaml desde a versão 1.14.
kubectl create configmapUse o comando kubectl create configmap para criar um ConfigMap a partir de diretórios, arquivos, ou valores literais:
kubectl create configmap <map-name> <data-source>
Onde <map-name> é o nome que você quer atribuir ao ConfigMap e <data-source> é o diretório, arquivo, ou o valor literal de onde buscar os dados. O nome de um objeto ConfigMap precisa ser um nome de subdomínio DNS válido. Quando você estiver criando um ConfigMap baseado em um arquivo, a chave no <data-source> é por padrão o nome-base do arquivo, e o valor é por padrão o conteúdo do arquivo.
Você pode usar kubectl describe ou
kubectl get para obter informações
sobre um ConfigMap.
Você pode usar kubectl create configmap para criar um ConfigMap a partir de vários arquivos no mesmo diretório. Quando você está criando um ConfigMap baseado em um diretório, o kubectl identifica arquivos cujo nome-base é uma chave válida no diretório e empacota cada um desses arquivos no novo ConfigMap. Quaisquer entradas existentes no diretório que não sejam arquivos regulares são ignoradas (ex. subdiretórios, links simbólicos, dispositivos, pipes, etc).
Por exemplo:
# Criando o diretório local
mkdir -p configure-pod-container/configmap/
# Baixe os arquivos de amostra no diretório `configure-pod-container/configmap/`
wget https://kubernetes.io/examples/configmap/game.properties -O configure-pod-container/configmap/game.properties
wget https://kubernetes.io/examples/configmap/ui.properties -O configure-pod-container/configmap/ui.properties
# Crie o ConfigMap
kubectl create configmap game-config --from-file=configure-pod-container/configmap/
O comando acima empacota cada arquivo, neste caso, game.properties e ui.properties no diretório configure-pod-container/configmap/ dentro do ConfigMap de nome game-config. Você pode exibir detalhes do ConfigMap usando o seguinte comando:
kubectl describe configmaps game-config
A saída é semelhante a esta:
Name: game-config
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
game.properties:
----
enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30
ui.properties:
----
color.good=purple
color.bad=yellow
allow.textmode=true
how.nice.to.look=fairlyNice
Os arquivos game.properties e ui.properties no diretório configure-pod-container/configmap/ estão representados na seção data do ConfigMap.
kubectl get configmaps game-config -o yaml
A saída é semelhante a esta:
apiVersion: v1
kind: ConfigMap
metadata:
creationTimestamp: 2016-02-18T18:52:05Z
name: game-config
namespace: default
resourceVersion: "516"
uid: b4952dc3-d670-11e5-8cd0-68f728db1985
data:
game.properties: |
enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30
ui.properties: |
color.good=purple
color.bad=yellow
allow.textmode=true
how.nice.to.look=fairlyNice
Você pode usar kubectl create configmap para criar um ConfigMap a partir de um arquivo individual, ou a partir de múltiplos arquivos.
Por exemplo,
kubectl create configmap game-config-2 --from-file=configure-pod-container/configmap/game.properties
Produziria o seguinte ConfigMap:
kubectl describe configmaps game-config-2
Onde a saída é semelhante a esta:
Name: game-config-2
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
game.properties:
----
enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30
Você pode passar o argumento --from-file múltiplas vezes para criar um ConfigMap a partir de múltiplas fontes de dados.
kubectl create configmap game-config-2 --from-file=configure-pod-container/configmap/game.properties --from-file=configure-pod-container/configmap/ui.properties
Você pode exibir detalhes do ConfigMap game-config-2 usando o comando a seguir:
kubectl describe configmaps game-config-2
A saída é semelhante a esta:
Name: game-config-2
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
game.properties:
----
enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30
ui.properties:
----
color.good=purple
color.bad=yellow
allow.textmode=true
how.nice.to.look=fairlyNice
Quando o kubectl cria um ConfigMap a partir de entradas que não são ASCII ou UTF-8, a ferramenta os coloca no campo binaryData do ConfigMap, e não no campo data. Fontes de dados de texto e binário podem ser combinadas em um ConfigMap.
Se você quiser ver o campo binaryData (e seus valores) em um ConfigMap, você pode executar kubectl get configmap -o jsonpath='{.binaryData}' <name>.
Use a opção --from-env-file para criar um ConfigMap a partir de um arquivo de ambiente, por exemplo:
# Os arquivos de ambiente contêm uma lista de variáveis de ambiente.
# Essas regras de sintaxe se aplicam:
# Cada linha em um arquivo de ambiente deve estar em formato VAR=VAL.
# Linhas começando com # (ex. comentários) são ignoradas.
# Linhas em branco são ignoradas.
# Não há manuseio especial de aspas (ex. eles farão parte dos valores do ConfigMap).
# Baixe os arquivos de amostra no diretório `configure-pod-container/configmap/`
wget https://kubernetes.io/examples/configmap/game-env-file.properties -O configure-pod-container/configmap/game-env-file.properties
wget https://kubernetes.io/examples/configmap/ui-env-file.properties -O configure-pod-container/configmap/ui-env-file.properties
# O arquivo de ambiente `game-env-file.properties` se parece como o abaixo
cat configure-pod-container/configmap/game-env-file.properties
enemies=aliens
lives=3
allowed="true"
# Este comentário e a linha vazia acima dela são ignorados
kubectl create configmap game-config-env-file \
--from-env-file=configure-pod-container/configmap/game-env-file.properties
Produziria o seguinte ConfigMap:
kubectl get configmap game-config-env-file -o yaml
onde a saída é semelhante a esta:
apiVersion: v1
kind: ConfigMap
metadata:
creationTimestamp: 2017-12-27T18:36:28Z
name: game-config-env-file
namespace: default
resourceVersion: "809965"
uid: d9d1ca5b-eb34-11e7-887b-42010a8002b8
data:
allowed: '"true"'
enemies: aliens
lives: "3"
A partir do Kubernetes v1.23, o kubectl suporta múltiplas ocorrências do argumento --from-env-file para
criar um ConfigMap para múltiplas fontes de dados.
kubectl create configmap config-multi-env-files \
--from-env-file=configure-pod-container/configmap/game-env-file.properties \
--from-env-file=configure-pod-container/configmap/ui-env-file.properties
Produziria o seguinte ConfigMap:
kubectl get configmap config-multi-env-files -o yaml
Onde a saída é semelhante a esta:
apiVersion: v1
kind: ConfigMap
metadata:
creationTimestamp: 2017-12-27T18:38:34Z
name: config-multi-env-files
namespace: default
resourceVersion: "810136"
uid: 252c4572-eb35-11e7-887b-42010a8002b8
data:
allowed: '"true"'
color: purple
enemies: aliens
how: fairlyNice
lives: "3"
textmode: "true"
Você pode definir uma chave que não seja o nome do arquivo, para usar na seção data do seu ConfigMap quando usar o argumento --from-file:
kubectl create configmap game-config-3 --from-file=<my-key-name>=<path-to-file>
Onde <my-key-name> é a chave que você deseja usar no ConfigMap e <path-to-file> é a localização do arquivo fonte de dados, que você deseja que a chave represente.
Por exemplo:
kubectl create configmap game-config-3 --from-file=game-special-key=configure-pod-container/configmap/game.properties
Produziria o seguinte ConfigMap:
kubectl get configmaps game-config-3 -o yaml
Onde a saída é semelhante a esta:
apiVersion: v1
kind: ConfigMap
metadata:
creationTimestamp: 2016-02-18T18:54:22Z
name: game-config-3
namespace: default
resourceVersion: "530"
uid: 05f8da22-d671-11e5-8cd0-68f728db1985
data:
game-special-key: |
enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30
Você pode usar kubectl create configmap com o argumento --from-literal para definir um valor literal a partir da linha de comando:
kubectl create configmap special-config --from-literal=special.how=very --from-literal=special.type=charm
Você pode passar vários pares de chave-valor. Cada par fornecido na linha de comando é representado como uma entrada separada na seção data do ConfigMap.
kubectl get configmaps special-config -o yaml
A saída é semelhante a esta:
apiVersion: v1
kind: ConfigMap
metadata:
creationTimestamp: 2016-02-18T19:14:38Z
name: special-config
namespace: default
resourceVersion: "651"
uid: dadce046-d673-11e5-8cd0-68f728db1985
data:
special.how: very
special.type: charm
Você também pode criar um ConfigMap a partir de geradores e então aplicá-lo no cluster
para criar objetos no servidor da API.
Você deve especificar os geradores em um arquivo kustomization.yaml dentro de um diretório.
Por exemplo, para gerar um ConfigMap a partir de arquivos configure-pod-container/configmap/game.properties
# Crie um arquivo kustomization.yaml com um ConfigMapGenerator
cat <<EOF >./kustomization.yaml
configMapGenerator:
- name: game-config-4
files:
- configure-pod-container/configmap/game.properties
EOF
Aplique o diretório de kustomization para criar o objeto ConfigMap.
kubectl apply -k .
configmap/game-config-4-m9dm2f92bt created
Você pode verificar se o ConfigMap foi criado, assim:
kubectl get configmap
NAME DATA AGE
game-config-4-m9dm2f92bt 1 37s
kubectl describe configmaps/game-config-4-m9dm2f92bt
Name: game-config-4-m9dm2f92bt
Namespace: default
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"v1","data":{"game.properties":"enemies=aliens\nlives=3\nenemies.cheat=true\nenemies.cheat.level=noGoodRotten\nsecret.code.p...
Data
====
game.properties:
----
enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30
Events: <none>
Observe que o nome gerado para o ConfigMap tem um sufixo anexado, que é o hash do conteúdo. Isso garante que um novo ConfigMap é gerado cada vez que o seu conteúdo é modificado.
Você pode definir uma chave que não seja o nome do arquivo para usar no gerador do ConfigMap.
Por exemplo, para gerar um ConfigMap a partir de arquivos configure-pod-container/configmap/game.properties
com a chave game-special-key
# Criando um arquivo kustomization.yaml com o ConfigMapGenerator
cat <<EOF >./kustomization.yaml
configMapGenerator:
- name: game-config-5
files:
- game-special-key=configure-pod-container/configmap/game.properties
EOF
Aplicar o diretório kustomization para criar o objeto ConfigMap.
kubectl apply -k .
configmap/game-config-5-m67dt67794 created
Este exemplo mostra como criar um ConfigMap a partir de dois literais chave/valor:
special.type=charm e special.how=very, usando Kustomize e kubectl. Para alcançar isso, você pode especificar o gerador
ConfigMap. Crie (ou sobreponha) o arquivo
kustomization.yaml para que ele tenha os seguintes conteúdos:
---
# Conteúdos de um aruivo kustomization.yaml para criar um ConfigMap a partir de literais
configMapGenerator:
- name: special-config-2
literals:
- special.how=very
- special.type=charm
Aplique o diretório kustomization para criar o objeto ConfigMap.
kubectl apply -k .
configmap/special-config-2-c92b5mmcf2 created
Antes de prosseguir, limpe alguns dos ConfigMaps que você fez:
kubectl delete configmap special-config
kubectl delete configmap env-config
kubectl delete configmap -l 'game-config in (config-4,config-5)’
Agora que você aprendeu a definir ConfigMaps, você pode avançar na próxima seção, e aprender como usar esses objetos com Pods.
Defina uma variável de ambiente como um par de chave-valor em um ConfigMap:
kubectl create configmap special-config --from-literal=special.how=very
Atribua o valor special.how definido no ConfigMap para a variável de ambiente SPECIAL_LEVEL_KEY na especificação do pod.
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: registry.k8s.io/busybox
command: [ "/bin/sh", "-c", "env" ]
env:
# Defina a variável de ambiente
- name: SPECIAL_LEVEL_KEY
valueFrom:
configMapKeyRef:
# O ConfigMap contendo o valor que você deseja atribuir ao SPECIAL_LEVEL_KEY
name: special-config
# Especifique a chave associada ao valor
key: special.how
restartPolicy: Never
Crie o Pod:
kubectl create -f https://kubernetes.io/examples/pods/pod-single-configmap-env-variable.yaml
Agora, a saída do Pod inclui a variável de ambiente SPECIAL_LEVEL_KEY=very.
Como no exemplo anterior, crie primeiro o ConfigMap.
apiVersion: v1
kind: ConfigMap
metadata:
name: special-config
namespace: default
data:
special.how: very
---
apiVersion: v1
kind: ConfigMap
metadata:
name: env-config
namespace: default
data:
log_level: INFO
Crie o ConfigMap:
kubectl create -f https://kubernetes.io/examples/configmap/configmaps.yaml
Defina as variáveis de ambiente na especificação do Pod.
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: registry.k8s.io/busybox
command: [ "/bin/sh", "-c", "env" ]
env:
- name: SPECIAL_LEVEL_KEY
valueFrom:
configMapKeyRef:
name: special-config
key: special.how
- name: LOG_LEVEL
valueFrom:
configMapKeyRef:
name: env-config
key: log_level
restartPolicy: Never
Crie o Pod:
kubectl create -f https://kubernetes.io/examples/pods/pod-multiple-configmap-env-variable.yaml
Agora, a saída do Pod inclui as variáveis de ambiente SPECIAL_LEVEL_KEY=very e LOG_LEVEL=INFO.
Criando um ConfigMap contendo vários pares de chave-valor.
apiVersion: v1
kind: ConfigMap
metadata:
name: special-config
namespace: default
data:
SPECIAL_LEVEL: very
SPECIAL_TYPE: charm
Crie o ConfigMap:
kubectl create -f https://kubernetes.io/examples/configmap/configmap-multikeys.yaml
Use envFrom para definir todos os dados do ConfigMap como variáveis de ambiente do contêiner. A chave do ConfigMap torna-se o nome da variável de ambiente no Pod.
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: registry.k8s.io/busybox
command: [ "/bin/sh", "-c", "env" ]
envFrom:
- configMapRef:
name: special-config
restartPolicy: Never
Crie o Pod:
kubectl create -f https://kubernetes.io/examples/pods/pod-configmap-envFrom.yaml
Agora, a saída do Pod inclui as variáveis de ambiente SPECIAL_LEVEL=very e SPECIAL_TYPE=charm.
Você pode usar variáveis de ambiente definidas no ConfigMap no command e args de um contêiner usando a sintaxe de substituição do Kubernetes $(VAR_NAME).
Por exemplo, a seguinte especificação de Pod
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: registry.k8s.io/busybox
command: [ "/bin/echo", "$(SPECIAL_LEVEL_KEY) $(SPECIAL_TYPE_KEY)" ]
env:
- name: SPECIAL_LEVEL_KEY
valueFrom:
configMapKeyRef:
name: special-config
key: SPECIAL_LEVEL
- name: SPECIAL_TYPE_KEY
valueFrom:
configMapKeyRef:
name: special-config
key: SPECIAL_TYPE
restartPolicy: Never
criado pela execução
kubectl create -f https://kubernetes.io/examples/pods/pod-configmap-env-var-valueFrom.yaml
produz a seguinte saída no contêiner test-container:
kubectl logs dapi-test-pod
very charm
Conforme explicado Criando um ConfigMap a partir de arquivos, quando você cria um ConfigMap usando --from-file, o nome do arquivo se torna uma chave armazenada na seção data do ConfigMap. O conteúdo do arquivo se torna o valor da chave.
Os exemplos nesta seção se referem a um ConfigMap de nome' special-config, mostrado abaixo.
apiVersion: v1
kind: ConfigMap
metadata:
name: special-config
namespace: default
data:
SPECIAL_LEVEL: very
SPECIAL_TYPE: charm
Crie o ConfigMap:
kubectl create -f https://kubernetes.io/examples/configmap/configmap-multikeys.yaml
Adicione o nome do ConfigMap debaixo da seção volumes das especificações do Pod.
Isso adiciona os dados do ConfigMap ao diretório especificado como volumeMounts.mountPath (nesse caso, /etc/config).
A seção command lista arquivos do diretório com nomes que correspondem às chaves no ConfigMap.
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: registry.k8s.io/busybox
command: [ "/bin/sh", "-c", "ls /etc/config/" ]
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
# Forneça o nome do ConfigMap que contém os arquivos
# que você deseja adicionar ao contêiner
name: special-config
restartPolicy: Never
Crie o Pod:
kubectl create -f https://kubernetes.io/examples/pods/pod-configmap-volume.yaml
Quando o Pod executa, o comando ls /etc/config/ produz a saída abaixo:
SPECIAL_LEVEL
SPECIAL_TYPE
/etc/config/, eles serão excluídos.binaryData.Use o campo path para especificar o caminho de arquivo desejado para ítens específicos do ConfigMap.
Nesse caso, o item SPECIAL_LEVEL será montado no volume config-volume em /etc/config/keys.
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: registry.k8s.io/busybox
command: [ "/bin/sh","-c","cat /etc/config/keys" ]
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: special-config
items:
- key: SPECIAL_LEVEL
path: keys
restartPolicy: Never
Crie o Pod:
kubectl create -f https://kubernetes.io/examples/pods/pod-configmap-volume-specific-key.yaml
Quando o Pod executar, o comando cat /etc/config/keys produz a saída abaixo:
very
/etc/config/ serão apagados.Você pode projetar chaves para caminhos específicos e permissões específicas em uma base por-arquivo. O guia do usuário Segredos explica a sintaxe.
Uma referência de ConfigMap pode ser marcada opcional. Se o ConfigMap for inexistente, o volume montado estará vazio. Se o ConfigMap existir, mas a chave referenciada é inexistente, o caminho estará ausente no ponto de montagem.
Quando um ConfigMap montado é atualizado, o conteúdo projetado é eventualmente atualizado também. Isso se aplica no caso em que um ConfigMap referenciado opcionalmente passe a existir após o Pod ser iniciado.
O Kubelet verifica se o ConfigMap montado está atualizado em cada sincronização periódica. No entanto, ele usa seu cache local baseado em TTL para obter o valor atual do ConfigMap. Como resultado, o atraso total, desde o momento em que o ConfigMap foi atualizado até o momento em que novas chaves são projetadas para o pod, pode ser tão longo quanto o período de sincronização do Kubelet (1 minuto por padrão) + TTL de cache do ConfigMap (1 minuto por padrão) no kubelet.
O recurso da API ConfigMap armazena dados de configuração como pares de chave-valor. Os dados podem ser consumidos em Pods, ou fornecidos para componentes do sistema, como controladores. O ConfigMap é similar ao Secret, mas fornece um meio de trabalhar com strings que não contêm informações confidenciais. Usuários e componentes do sistema podem armazenar dados de configuração em ConfigMaps.
/etc do Linux e seus conteúdos. Por exemplo, se você criar um Volume Kubernetes a partir de um ConfigMap, cada item de dados no ConfigMap é representado por um arquivo individual no volume.O campo data do ConfigMap contém os dados de configuração. Como mostrado no exemplo abaixo, estes podem ser simples (como propriedades individuais definidas usando --from-literal) ou complexos (como arquivos de configuração ou blobs JSON definidos usando --from-file).
apiVersion: v1
kind: ConfigMap
metadata:
creationTimestamp: 2016-02-18T19:14:38Z
name: example-config
namespace: default
data:
# exemplo de uma propriedade simples definida usando --from-literal
example.property.1: hello
example.property.2: world
# exemplo de uma propriedade complexa definida usando --from-file
example.property.file: |-
property.1=value-1
property.2=value-2
property.3=value-3
Você deve criar um ConfigMap antes de referenciá-lo em uma especificação de Pod (a menos que você marque o ConfigMap como optional). Se você referenciar um ConfigMap que não existe, O Pod não vai iniciar. Da mesma forma, referências a chaves que não existem no ConfigMap impedirão o Pod de iniciar.
Se você usar envFrom para definir variáveis de ambiente do ConfigMap, chaves que são consideradas inválidas serão ignoradas. O Pod poderá iniciar, mas os nomes inválidos serão registrados no log de eventos (InvalidVariableNames). A mensagem de log lista cada chave ignorada. Por exemplo:
kubectl get events
A saída é semelhante a esta:
LASTSEEN FIRSTSEEN COUNT NAME KIND SUBOBJECT TYPE REASON SOURCE MESSAGE
0s 0s 1 dapi-test-pod Pod Warning InvalidEnvironmentVariableNames {kubelet, 127.0.0.1} Keys [1badkey, 2alsobad] from the EnvFrom configMap default/myconfig were skipped since they are considered invalid environment variable names.
O ConfigMap reside em um Namespace específico. Um ConfigMap só pode ser referenciado por Pods residentes no mesmo namespace.
Você não pode usar um ConfigMap para Pods estáticos, porque o kubelet não oferece suporte a isso.
Esta página mostra como atribuir um Pod kubernetes a um nó particular em um cluster Kubernetes utilizando afinidade de nó.
Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
O seu servidor Kubernetes deve estar numa versão igual ou superior a v1.10.Para verificar a versão, digite kubectl version.
Liste os nós em seu cluster, juntamente com seus labels:
kubectl get nodes --show-labels
A saída é semelhante a esta:
NAME STATUS ROLES AGE VERSION LABELS
worker0 Ready <none> 1d v1.13.0 ...,kubernetes.io/hostname=worker0
worker1 Ready <none> 1d v1.13.0 ...,kubernetes.io/hostname=worker1
worker2 Ready <none> 1d v1.13.0 ...,kubernetes.io/hostname=worker2
Escolha um de seus nós e adicione um label a ele:
kubectl label nodes <your-node-name> disktype=ssd
onde <your-node-name> é o nome do seu nó escolhido.
Verifique se seu nó escolhido tem o label disktype=ssd:
kubectl get nodes --show-labels
A saída é semelhante a esta:
NAME STATUS ROLES AGE VERSION LABELS
worker0 Ready <none> 1d v1.13.0 ...,disktype=ssd,kubernetes.io/hostname=worker0
worker1 Ready <none> 1d v1.13.0 ...,kubernetes.io/hostname=worker1
worker2 Ready <none> 1d v1.13.0 ...,kubernetes.io/hostname=worker2
Na saída anterior, você pode ver que o nó worker0 tem o label
disktype=ssd.
Este manifesto descreve um Pod que possui uma afinidade de nó requiredDuringSchedulingIgnoredDuringExecution com o label disktype: ssd.
Isso significa que o Pod será alocado apenas em um nó que tenha o label disktype=ssd.
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: disktype
operator: In
values:
- ssd
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
Aplique o manifesto para criar um Pod que será alocado no nó escolhido:
kubectl apply -f https://k8s.io/examples/pods/pod-nginx-required-affinity.yaml
Verifique se o Pod está executando no nó escolhido:
kubectl get pods --output=wide
A saída é semelhante a esta:
NAME READY STATUS RESTARTS AGE IP NODE
nginx 1/1 Running 0 13s 10.200.0.4 worker0
Este manifesto descreve um Pod que possui uma afinidade de nó requiredDuringSchedulingIgnoredDuringExecution com o label disktype: ssd.
Isso significa que o Pod será alocado de preferência em um nó com o label disktype=ssd.
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: disktype
operator: In
values:
- ssd
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
Aplique o manifesto para criar um Pod que será alocado no nó escolhido:
kubectl apply -f https://k8s.io/examples/pods/pod-nginx-preferred-affinity.yaml
Verifique se o Pod está executando no nó escolhido:
kubectl get pods --output=wide
A saída é semelhante a esta:
NAME READY STATUS RESTARTS AGE IP NODE
nginx 1/1 Running 0 13s 10.200.0.4 worker0
Saiba mais sobre Afinidade de nó.
Esta página mostra como configurar o compartilhamento de namespace de processos para um Pod. Quando O compartilhamento de namespace de processos está ativado, os processos em um Contêiner são visíveis para todos os outros Contêineres no mesmo Pod.
Você pode usar este recurso para configurar Contêineres de cooperação, como um manipulador de log
sidecar de contêiner, ou para solucionar problemas em imagens de contêiner que não
incluem utilitários de depuração como um shell.
Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
O compartilhamento de namespace de processos é ativado usando o campo shareProcessNamespace da
.spec para um Pod. Por exemplo:
Crie o pod nginx no seu cluster:
kubectl apply -f https://k8s.io/examples/pods/share-process-namespace.yaml
Conecte ao shell do contêiner e execute o comando ps:
kubectl exec -it nginx -c shell -- /bin/sh
Se você não vir um prompt de comando, tente pressionar Enter. No shell do Contêiner execute:
# execute este comando dentro do "shell" do contêiner
ps ax
A saída é semelhante a esta:
PID USER TIME COMMAND
1 root 0:00 /pause
8 root 0:00 nginx: master process nginx -g daemon off;
14 101 0:00 nginx: worker process
15 root 0:00 sh
21 root 0:00 ps ax
Você pode sinalizar processos em outros Contêineres. Por exemplo, mandando SIGHUP ao
nginx para restartar o processo worker. Isso requer a capacidade SYS_PTRACE.
# execute este comando dentro do "shell" do contêiner
kill -HUP 8 # substitua o "8" pelo PID do processo principal do nginx, se necessário
ps ax
A saída é semelhante a esta:
PID USER TIME COMMAND
1 root 0:00 /pause
8 root 0:00 nginx: master process nginx -g daemon off;
15 root 0:00 sh
22 101 0:00 nginx: worker process
23 root 0:00 ps ax
É até possível acessar o sistema de arquivos de outro contêiner usando o link
/proc/$pid/root.
# execute este comando dentro do "shell" do contêiner
# substitua o "8" pelo PID do processo Nginx, se necessario
head /proc/8/root/etc/nginx/nginx.conf
A saída é semelhante a esta:
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
Os Pods compartilham muitos recursos, por isso faz sentido que eles também compartilhem um namespace de processo. Alguns Contêineres podem esperar serem isolados de outros, no entanto, por isso, é importante entender as diferenças:
O processo de contêiner não tem mais o PID 1. Alguns Contêineres recusam
começar sem o PID 1 (por exemplo, contêineres usando systemd) ou executando comandos
como kill -HUP 1 para sinalizar o processo de Contêiner. Em pods com um
namespace de processos compartilhado, kill -HUP 1 irá sinalizar a sandbox
(/pause no exemplo acima).
Os processos são visíveis para outros contêineres no Pod. Isso inclui todas
informações visíveis em /proc, como senhas que foram passadas como argumentos
ou variáveis de ambiente. Estes são protegidos apenas por permissões regulares do Unix.
Sistema de arquivos do Contêiner são visíveis para outros Contêineres do pod através do link
/proc/$pid/root. Isso facilita a depuração, mas também significa
que os segredos do sistema de arquivos, são protegidos apenas por permissões de sistema de arquivos.
Pods Estáticos são gerenciados diretamente pelo daemon kubelet em um nó específico,
sem o servidor de API
observando-os.
Ao contrário dos pods que são gerenciados pelo Control Plane (por exemplo, uma
Implantação);
em vez disso, o kubelet observa cada Pod estático
(e reinicia-os se falharem).
Pods estáticos estão sempre ligados a um Kubelet em um nó específico.
O Kubelet tenta automaticamente criar um mirror Pod no servidor de API do Kubernetes para cada Pod estático. Isso significa que os pods em execução em um nó são visíveis no servidor de API, mas não podem ser controlados a partir daí. Aos nomes de Pods será sufixados com o nome de host do nó, com um hífem a esquerda.
especificação de um Pod estático não pode referir-se à outros objetos da API
(ex., ServiceAccount,
ConfigMap,
Secret, etc).Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
Para verificar a versão, digite kubectl version.
Esta página assume que você está usando um CRI-O para executar os Pods, e que seus nós estão executando o sistema operacional Fedora. Instruções para outras distribuições, ou instalações de Kubernetes, podem variar.
Você pode configurar um Pod estático com um arquivo de configuração hospedado no sistema de arquivos ou um arquivo de configuração hospedado na Web.
Os manifestos, são definições de Pod padrão em formato JSON ou YAML em um diretório específico. Use o campo staticPodPath: <diretório> no
arquivo de configuração do kubelet,
que periodicamente varre o diretório e cria/exclui Pods estáticos conforme os arquivos YAML/JSON aparecem/desaparecem.
Observe que o Kubelet ignorará os arquivos começando com pontos ao varrer o diretório especificado.
Por exemplo, como iniciar um servidor Web simples como um Pod estático
Escolha um nó onde você deseja executar um Pod estático. Neste exemplo, é my-node1.
ssh my-node1
Escolha um diretório, digamos /etc/kubernetes/manifests e coloque uma definição de pod para um servidor web lá, por exemplo /etc/kubernetes/manifests/static-web.yaml:
# Execute este comando no nó onde o Kubelet está funcionando
mkdir -p /etc/kubernetes/manifests/
cat <<EOF >/etc/kubernetes/manifests/static-web.yaml
apiVersion: v1
kind: Pod
metadata:
name: static-web
labels:
role: myrole
spec:
containers:
- name: web
image: nginx
ports:
- name: web
containerPort: 80
protocol: TCP
EOF
Configure seu kubelet no nó para usar este diretório executando-o com o argumento --pod-manifest-path=/etc/kubernetes/manifests/. No Fedora, edite o arquivo /etc/kubernetes/kubelet para incluir esta linha:
KUBELET_ARGS="--cluster-dns=10.254.0.10 --cluster-domain=kube.local --pod-manifest-path=/etc/kubernetes/manifests/"
ou adicione o campo staticPodPath: <o diretótio> no
arquivo de configuração do kubelet.
Reinicie o kubelet. No Fedora, você poderia executar:
# Execute este comando no nó onde o kubelet está funcionando
systemctl restart kubelet
O Kubelet baixa periodicamente um arquivo especificado pelo argumento --manifest-url=<URL>
e interpreta-o como um arquivo JSON/YAML que contém as definições do Pod.
Similar ao que manifestos hospedados no sistema de arquivos fazem, o kubelet
reexamina o manifesto em um agendamento. Se houver alterações na lista de Pods estáticos, o kubelet aplica-os.
Para usar esta abordagem:
Crie um arquivo YAML e armazene-o em um servidor da Web, para que você possa passar o URL desse arquivo para o Kubelet.
apiVersion: v1
kind: Pod
metadata:
name: static-web
labels:
role: myrole
spec:
containers:
- name: web
image: nginx
ports:
- name: web
containerPort: 80
protocol: TCP
Configure o kubelet no seu nó selecionado para usar este manifesto da Web, executando-o com --manifest-url=<manifest-url>. No Fedora, edite /etc/kubernetes/kubelet para incluir esta linha:
KUBELET_ARGS="--cluster-dns=10.254.0.10 --cluster-domain=kube.local --manifest-url=<manifest-url>"
Reinicie o Kubelet. No Fedora, você usaria:
# Execute este comando no nó onde o kubelet está funcionando
systemctl restart kubelet
Quando o kubelet começa, inicia automaticamente todos os pods estáticos definidos. Como você definiu um Pod estático e reiniciou o kubelet, o novo pod estático deveria já estar em execução.
Você pode ver os Contêineres em execução (incluindo os Pods estáticos) ao executar (no Nó):
# Execute este comando no nó onde o kubelet está funcionando
crictl ps
A saída pode ser algo como:
CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID
129fd7d382018 docker.io/library/nginx@sha256:... 11 minutes ago Running web 0 34533c6729106
crictl mostra a URI da imagem e o checksum SHA-256. O NAME vai parecer mais como:
docker.io/library/nginx@sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31.Você pode ver o Pod espelho no servidor de API:
kubectl get pods
NAME READY STATUS RESTARTS AGE
static-web 1/1 Running 0 2m
Os Rótulos dos pods estáticos são propagados no Pod espelho. Você pode usar esses rótulos como seletores via normal, etc.
Se você tentar usar o kubectl para excluir o Pod espelho do servidor de API,
o kubelet não remove o Pod estático:
kubectl delete pod static-web
pod "static-web" deleted
Você pode ver que o Pod ainda está funcionando:
kubectl get pods
NAME READY STATUS RESTARTS AGE
static-web 1/1 Running 0 4s
De volta ao seu nó, onde o kubelet está funcionando, você pode tentar parar o Contêiner manualmente. Você verá que, depois de algum tempo, o Kubelet notará e reiniciará o Pod automaticamente:
# Execute esses comandos no nó onde o Kubelet está funcionando
crictl stop 129fd7d382018 # substitua pelo ID do seu contêiner
sleep 20
crictl ps
CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID
89db4553e1eeb docker.io/library/nginx@sha256:... 19 seconds ago Running web 1 34533c6729106
O Kubelet em execução varre periodicamente o diretório configurado (/etc/kubernetes/manifests em nosso exemplo) por alterações, e adiciona/remove os pods à medida que os arquivos aparecem/desaparecem neste diretório.
# Pressupondo que você esteja usando a configuração de Pod estático hospedada no sistema de arquivos
# Execute esses comandos no nó onde o Kubelet está funcionando
#
mv /etc/kubelet.d/static-web.yaml /tmp
sleep 20
crictl ps
# Você vê que nenhum contêiner nginx está funcionando
#
mv /tmp/static-web.yaml /etc/kubelet.d/
sleep 20
crictl ps
CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID
f427638871c35 docker.io/library/nginx@sha256:... 19 seconds ago Running web 1 34533c6729106
O Kubernetes fornece um controlador de admissão embutido para garantir os padrões de segurança do Pod. Você pode configurar esse controlador de admissão para definir padrões e isenções em todo o cluster.
Após uma release alfa no Kubernetes v1.22, o controlador de admissão Pod Security Admission tornou-se disponível por padrão no Kubernetes v1.23, no estado beta. Da versão 1.25 em diante o controlador de admissão Pod Security Admission está publicamente disponível.
Para verificar a versão, digite kubectl version.
Se você não estiver utilizando o Kubernetes 1.35, você pode verificar a documentação da versão do Kubernetes que você está utilizando.
pod-security.admission.config.k8s.io/v1 requer o Kubernetes v1.25
ou superior.
Para as versões v1.23 e v1.24, utilize v1beta1.
Para a versão v1.22, utilize v1alpha1.apiVersion: apiserver.config.k8s.io/v1 # veja a nota de compatibilidade
kind: AdmissionConfiguration
plugins:
- name: PodSecurity
configuration:
apiVersion: pod-security.admission.config.k8s.io/v1beta1
kind: PodSecurityConfiguration
# Padrões aplicados quando o label de modo não é especificado.
#
# O valor para o label Level deve ser uma das opções abaixo:
# - "privileged" (padrão)
# - "baseline"
# - "restricted"
#
# O valor para o label Version deve ser uma das opções abaixo:
# - "latest" (padrão)
# - versão específica no formato "v1.35"
defaults:
enforce: "privileged"
enforce-version: "latest"
audit: "privileged"
audit-version: "latest"
warn: "privileged"
warn-version: "latest"
exemptions:
# Lista de usuários autenticados a eximir.
usernames: []
# Lista de RuntimeClasses a eximir.
runtimeClasses: []
# Lista de namespaces a eximir.
namespaces: []
--admission-control-config-file do kube-apiserver.Os namespaces podem ser rotulados para aplicar os Padrões de segurança de pod. As três políticas privilegiado, linha de base e restrito cobrem amplamente o espectro de segurança e são implementados pela segurança de Pod controlador de admissão.
O seu servidor Kubernetes deve estar numa versão igual ou superior a v1.22.
Para verificar a versão, digite kubectl version.
PodSecurity do portal de funcionalidades
esteja habilitada.baseline de pod com rótulos em namespaceEste manifesto define um Namespace my-baseline-namespace que:
baseline.restricted.baseline e restricted à v1.35.apiVersion: v1
kind: Namespace
metadata:
name: my-baseline-namespace
labels:
pod-security.kubernetes.io/enforce: baseline
pod-security.kubernetes.io/enforce-version: v1.35
# Estamos definindo-os para o nosso nível _desejado_ `enforce`.
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/audit-version: v1.35
pod-security.kubernetes.io/warn: restricted
pod-security.kubernetes.io/warn-version: v1.35
kubectl labelenforce (ou version) é adicionada ou modificada,
O plugin de admissão testará cada Pod no namespace contra a nova política.
Violações são devolvidas ao usuário como avisos.É útil aplicar a flag --dry-run ao avaliar inicialmente as alterações
do perfil de segurança para namespaces. As verificações padrão de segurança
do pod ainda serão executadas em modo dry run, dando-lhe informações sobre
como a nova política trataria os pods existentes, sem realmente atualizar a política.
kubectl label --dry-run=server --overwrite ns --all \
pod-security.kubernetes.io/enforce=baseline
Se você está apenas começando com os padrões de segurança de pod, um primeiro passo
adequado seria configurar todos namespaces com anotações de auditoria para um
nível mais rigoroso, como baseline:
kubectl label --overwrite ns --all \
pod-security.kubernetes.io/audit=baseline \
pod-security.kubernetes.io/warn=baseline
Observe que isso não está aplicando as definições de nível, para que os namespaces que não foram explicitamente avaliados possam ser distinguidos. Você pode listar os namespaces sem um nível aplicado, explicitamente definido, usando este comando:
kubectl get namespaces --selector='!pod-security.kubernetes.io/enforce'
Você pode atualizar um namespace específico também. Este comando adiciona a política
enforce=restricted ao my-existing-namespace, fixando a política que restringe
à versão v1.35.
kubectl label --overwrite ns my-existing-namespace \
pod-security.kubernetes.io/enforce=restricted \
pod-security.kubernetes.io/enforce-version=v1.35
Essa página mostra como utilizar o Cilium para NetworkPolicy.
Para saber mais sobre o Cilium, leia o artigo Introdução ao Cilium (em inglês).
Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
Para verificar a versão, digite kubectl version.
Para familiarizar-se com o Cilium você poderá seguir o guia Guia de Primeiros Passos do Cilium no Kubernetes (em inglês) e realizar uma instalação básica do Cilium através de um DaemonSet no minikube.
Inicie o minikube, a versão mínima exigida é >= v1.5.2, com os seguintes argumentos:
minikube version
minikube version: v1.5.2
minikube start --network-plugin=cni
Para o minikube, você poderá instalar o Cilium utilizando a ferramenta de linha de comando (CLI). Para isso, primeiro faça o download da última versão do CLI com o seguinte comando:
curl -LO https://github.com/cilium/cilium-cli/releases/latest/download/cilium-linux-amd64.tar.gz
Em seguida extraia o arquivo baixado para o diretório /usr/local/bin com os comandos:
sudo tar xzvfC cilium-linux-amd64.tar.gz /usr/local/bin
rm cilium-linux-amd64.tar.gz
Após executar os passos acima, você poderá instalar o Cilium utilizando o comando abaixo:
cilium install
O Cilium irá detectar as configurações do cluster automaticamente, criará e instalará os componentes apropriados para que a instalação seja bem sucedida. Os componentes são:
cilium-ca e os certificados para o Hubble (camada de observabilidade do Cilium).Após a instalação, você poderá visualizar o status geral do Deployment do Cilium com o comando cilium status.
Confira a saída esperada da opção status aqui.
O restante do guia de primeiros passos utiliza como base uma aplicação de exemplo para explicar como aplicar políticas de segurança tanto para L3/L4 (como endereço de IP + porta), quanto para L7 (como HTTP).
Para instruções detalhadas de como fazer o deploy do Cilium em produção, acesse: Guia de Instalação do Cilium no Kubernetes (em inglês).
Essa documentação inclui detalhes sobre os requisitos, instruções e exemplos de DaemonSet para produção.
Ao realizar o deploy do Cilium no cluster, Pods são adicionados ao namespace kube-system. Para ver essa lista de Pods execute:
kubectl get pods --namespace=kube-system -l k8s-app=cilium
Você verá uma lista de Pods similar a essa:
NAME READY STATUS RESTARTS AGE
cilium-kkdhz 1/1 Running 0 3m23s
...
Um Pod cilium roda em cada um dos nós do seu cluster e garante as políticas de rede no tráfego de/para Pods naquele nó usando o Linux BPF.
Uma vez que seu cluster estiver rodando, você pode seguir o artigo Declarar uma Network Policy (em inglês) para testar as políticas de NetworkPolicy do Kubernetes com o Cilium. Divirta-se! Se tiver dúvidas, nos contate usando o Canal Slack do Cilium.
Às vezes, as coisas dão errado. Este guia tem como objetivo ajudá-lo a corrigir esses problemas. Ele está dividido em duas seções:
Você também deve verificar os problemas conhecidos da versão que está utilizando.
Se o seu problema não for resolvido por nenhum dos guias acima, há várias maneiras de obter ajuda da comunidade Kubernetes.
A documentação neste site foi estruturada para fornecer respostas a uma ampla gama de perguntas. Conceitos explicam a arquitetura do Kubernetes e como cada componente funciona, enquanto Configuração oferece instruções práticas para começar. Tarefas mostram como realizar tarefas comumente utilizadas, e os Tutoriais são guias mais abrangentes de cenários reais, específicos da indústria ou de desenvolvimento completo de ponta a ponta.
A seção de Referência fornece documentação detalhada sobre a API do Kubernetes e as interfaces de linha de comando (CLIs), como kubectl.
Se você tem dúvidas relacionadas ao desenvolvimento de software para sua aplicação conteinerizada, você pode perguntar no Stack Overflow.
Se você tem perguntas sobre Kubernetes relacionadas à gestão do cluster ou configuração, você pode perguntar no Server Fault.
Também existem vários sites mais específicos na rede Stack Exchange que podem ser o lugar certo para perguntar sobre Kubernetes em áreas como DevOps, Engenharia de Software ou Segurança da Informação.
Alguém da comunidade pode já ter feito uma pergunta semelhante ou pode ser capaz de ajudar com o seu problema.
A equipe do Kubernetes também monitora os posts marcados como Kubernetes. Se não houver perguntas existentes que ajudem, certifique-se de que sua pergunta está no escopo do Stack Overflow, Server Fault, ou do site da rede Stack Exchange que você escolheu, e leia as orientações sobre como fazer uma nova pergunta, antes de postar uma nova!
Muitas pessoas da comunidade Kubernetes estão no Slack do Kubernetes no canal #kubernetes-users.
O Slack requer registro; você pode solicitar um convite, e o registro está aberto para todos.
Sinta-se à vontade para entrar e fazer qualquer tipo de pergunta.
Após se registrar, acesse a organização Kubernetes no Slack via seu navegador ou pelo aplicativo dedicado do Slack.
Depois de registrado, explore a lista crescente de canais para vários assuntos de interesse.
Por exemplo, novos usuários do Kubernetes podem querer entrar no canal #kubernetes-novice.
Desenvolvedores devem entrar no canal #kubernetes-contributors.
Também existem muitos canais específicos por país/idioma. Sinta-se à vontade para entrar nesses canais para suporte localizado e informações:
| País | Canais |
|---|---|
| China | #cn-users, #cn-events |
| Finlândia | #fi-users |
| França | #fr-users, #fr-events |
| Alemanha | #de-users, #de-events |
| Índia | #in-users, #in-events |
| Itália | #it-users, #it-events |
| Japão | #jp-users, #jp-events |
| Coreia | #kr-users |
| Países Baixos | #nl-users |
| Noruega | #norw-users |
| Polônia | #pl-users |
| Rússia | #ru-users |
| Espanha | #es-users |
| Suécia | #se-users |
| Turquia | #tr-users, #tr-events |
Você é bem-vindo para participar do fórum oficial do Kubernetes: discuss.kubernetes.io.
Se você encontrou o que parece ser um bug ou deseja solicitar uma nova funcionalidade, use o sistema de rastreamento de problemas no GitHub.
Antes de registrar um problema, pesquise os problemas existentes para verificar se sua questão já foi abordada.
Se for relatar um bug, inclua informações detalhadas sobre como reproduzir o problema, como:
kubectl versionEste documento contém um conjunto de recursos para solucionar problemas em aplicações conteinerizadas. Ele aborda questões comuns relacionadas a recursos do Kubernetes (como Pods, Services e StatefulSets), orientações para interpretar mensagens de término de contêineres e métodos para depurar contêineres em execução.
Este guia foi criado para ajudar os usuários a depurar aplicações implantadas no Kubernetes que não estão se comportando corretamente. Este não é um guia para quem deseja depurar seu cluster. Para isso, você deve conferir este guia.
O primeiro passo na solução de problemas é a triagem. Qual é o problema? São seus Pods, seu Replication Controller ou seu Service?
O primeiro passo para depurar um Pod é examiná-lo. Verifique o estado atual do Pod e eventos recentes com o seguinte comando:
kubectl describe pods ${POD_NAME}
Observe o estado dos contêineres no pod. Todos estão em Running?
Houve reinicializações recentes?
Continue a depuração dependendo do estado dos pods.
Se um Pod estiver preso em Pending, significa que ele não pode ser alocado em um nó.
Geralmente, isso ocorre porque há recursos insuficientes de algum tipo, impedindo a alocação.
Verifique a saída do comando kubectl describe ... mencionado acima.
Deve haver mensagens do escalonador explicando por que o Pod não pode ser alocado. As razões incluem:
Você não tem recursos suficientes: Pode ser que você tenha esgotado a capacidade de CPU ou Memória no seu cluster. Nesse caso, você precisa excluir Pods, ajustar as solicitações de recursos ou adicionar novos nós ao cluster. Consulte o documento Recursos de Computação para mais informações.
Você está usando hostPort: Quando você vincula um Pod a um hostPort, há um número limitado de locais onde esse Pod pode ser alocado.
Na maioria dos casos, hostPort é desnecessário, tente usar um objeto Service para expor seu Pod.
Se você realmente precisar de hostPort, então só poderá alocar tantos Pods quanto o número de nós no seu cluster Kubernetes.
Se um Pod estiver preso no estado Waiting, significa que ele foi alocado para um nó de trabalho,
mas não pode ser executado nessa máquina. Novamente, as informações do comando kubectl describe ...
devem fornecer detalhes úteis.
A causa mais comum para Pods em estado Waiting é a falha ao baixar a imagem.
Há três coisas que você deve verificar:
docker pull .Se um Pod estiver preso no estado Terminating, significa que uma solicitação de exclusão foi emitida,
mas a camada de gerenciamento não conseguiu remover o objeto do Pod.
Isso geralmente ocorre se o Pod possui um finalizer e há um admission webhook instalado no cluster que impede a camada de gerenciamento de remover o finalizer.
Para identificar esse cenário, verifique se seu cluster possui algum ValidatingWebhookConfiguration ou MutatingWebhookConfiguration que tenha como alvo
operações UPDATE para recursos pods.
Se o webhook for fornecido por um terceiro:
UPDATE.Se você for o autor do webhook:
UPDATE. Por exemplo, mudanças em contêineres geralmente não são permitidas.Depois que seu Pod for alocado, você pode usar os métodos descritos em Depurando Pods em Execução para depuração.
Se o seu pod não está se comportando como esperado, pode haver um erro na descrição do pod
(por exemplo, no arquivo mypod.yaml em sua máquina local) que foi ignorado silenciosamente
ao criar o pod. Muitas vezes, uma seção da descrição do pod pode estar aninhada incorretamente
ou um nome de chave pode ter sido digitado incorretamente, fazendo com que a chave seja ignorada.
Por exemplo, se você digitou commnd em vez de command, o pod será criado,
mas não usará o comando que você pretendia.
A primeira coisa a fazer é excluir seu pod e tentar criá-lo novamente usando a opção --validate.
Por exemplo, execute kubectl apply --validate -f mypod.yaml.
Se você digitou command incorretamente como commnd, verá um erro como este:
I0805 10:43:25.129850 46757 schema.go:126] unknown field: commnd
I0805 10:43:25.129973 46757 schema.go:129] this may be a false alarm, see https://github.com/kubernetes/kubernetes/issues/6842
pods/mypod
A próxima coisa a verificar é se o pod no servidor da API corresponde ao pod que você pretendia criar
(por exemplo, no arquivo yaml em sua máquina local).
Por exemplo, execute kubectl get pods/mypod -o yaml > mypod-on-apiserver.yaml em seguida,
compare manualmente a descrição original do pod, mypod.yaml com a versão obtida do servidor da API, mypod-on-apiserver.yaml.
Normalmente, a versão do "servidor da API" terá algumas linhas extras que não estão na versão original,
o que é esperado. No entanto, se houver linhas na versão original que não aparecem na versão do servidor da API,
isso pode indicar um problema na especificação do seu pod.
Replication Controllers são bastante diretos. Eles podem criar pods ou não. Se não conseguirem criar pods, consulte as instruções acima para depurar seus pods.
Você também pode usar kubectl describe rc ${CONTROLLER_NAME} para examinar eventos
relacionados ao replication controller.
Os Services fornecem balanceamento de carga entre um conjunto de pods. Existem vários problemas comuns que podem fazer com que os Services não funcionem corretamente. As instruções a seguir devem ajudar na depuração de problemas com Services.
Primeiro, verifique se há endpoints para o Service.
Para cada objeto Service, o servidor da API disponibiliza um recurso endpoints.
Você pode visualizar esse recurso com o seguinte comando:
kubectl get endpoints ${SERVICE_NAME}
Certifique-se de que os endpoints correspondem ao número de pods que você espera que sejam membros do seu service. Por exemplo, se seu Service estiver associado a um contêiner Nginx com 3 réplicas, você deve esperar ver três endereços IP diferentes nos endpoints do Service.
Se os endpoints estiverem ausentes, tente listar os pods usando os rótulos que o Service utiliza. Por exemplo, imagine que você tenha um Service com os seguintes rótulos:
...
spec:
- selector:
name: nginx
type: frontend
Você pode usar:
kubectl get pods --selector=name=nginx,type=frontend
para listar os pods que correspondem a esse seletor. Verifique se a lista corresponde aos pods que você espera que forneçam seu Service.
Além disso, certifique-se de que o containerPort do pod corresponde ao targetPort do service.
Consulte Depurando Services para mais informações.
Se nenhuma das soluções acima resolver seu problema, siga as instruções no
documento de Depuração de Services
para garantir que seu Service está em execução, possui Endpoints e que seus Pods
estão realmente respondendo; além disso, verifique se o DNS está funcionando,
as regras do iptables estão configuradas corretamente e se o kube-proxy não está com problemas.
Você também pode consultar o documento de solução de problemas para mais informações.
Um problema que surge com bastante frequência em novas instalações do Kubernetes é que um Service não está funcionando corretamente. Você implantou seus Pods através de um Deployment (ou outro controlador de carga de trabalho) e criou um Service, mas não recebe nenhuma resposta ao tentar acessá-lo. Este documento, esperançosamente, ajudará você a descobrir o que está errado.
Para muitas etapas aqui, você desejará ver o que um Pod em execução no cluster está enxergando. A maneira mais simples de fazer isso é executar um Pod interativo com busybox:
kubectl run -it --rm --restart=Never busybox --image=gcr.io/google-containers/busybox sh
Se você já tem um Pod em execução que prefere usar, você pode executar um comando nele usando:
kubectl exec <POD-NAME> -c <CONTAINER-NAME> -- <COMMAND>
Para os propósitos deste passo a passo, vamos executar alguns Pods. Como você provavelmente está depurando seu próprio Service, pode substituir os detalhes pelos seus próprios ou seguir junto para obter um segundo ponto de referência.
kubectl create deployment hostnames --image=registry.k8s.io/serve_hostname
deployment.apps/hostnames created
Os comandos kubectl exibirão o tipo e o nome do recurso criado ou modificado,
que podem então ser usados em comandos subsequentes.
Vamos escalar o deployment para 3 réplicas.
kubectl scale deployment hostnames --replicas=3
deployment.apps/hostnames scaled
Observe que isso é o mesmo que se você tivesse iniciado o Deployment com o seguinte YAML:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: hostnames
name: hostnames
spec:
selector:
matchLabels:
app: hostnames
replicas: 3
template:
metadata:
labels:
app: hostnames
spec:
containers:
- name: hostnames
image: registry.k8s.io/serve_hostname
O rótulo "app" é definido automaticamente pelo kubectl create deployment como o nome do Deployment.
Você pode confirmar que seus Pods estão em execução:
kubectl get pods -l app=hostnames
NAME READY STATUS RESTARTS AGE
hostnames-632524106-bbpiw 1/1 Running 0 2m
hostnames-632524106-ly40y 1/1 Running 0 2m
hostnames-632524106-tlaok 1/1 Running 0 2m
Você também pode confirmar que seus Pods estão respondendo. Você pode obter a lista de endereços IP dos Pods e testá-los diretamente.
kubectl get pods -l app=hostnames \
-o go-template='{{range .items}}{{.status.podIP}}{{"\n"}}{{end}}'
10.244.0.5
10.244.0.6
10.244.0.7
O contêiner de exemplo usado neste passo a passo serve seu próprio hostname via HTTP na porta 9376, mas se você estiver depurando sua própria aplicação, deverá usar o número da porta na qual seus Pods estão escutando.
De dentro de um Pod:
for ep in 10.244.0.5:9376 10.244.0.6:9376 10.244.0.7:9376; do
wget -qO- $ep
done
Isso deve produzir algo como:
hostnames-632524106-bbpiw
hostnames-632524106-ly40y
hostnames-632524106-tlaok
Se você não estiver recebendo as respostas esperadas neste ponto, seus Pods
podem não estar íntegro ou podem não estar ouvindo na porta que você pensa
que estão. Você pode achar útil usar kubectl logs para ver o que está
acontecendo ou, talvez, seja necessário executar kubectl exec diretamente
em seus Pods e depurar a partir daí.
Supondo que tudo tenha ocorrido conforme o esperado até agora, você pode começar a investigar por que seu Service não está funcionando.
O leitor atento terá notado que você ainda não criou um Service – isso é intencional. Esse é um passo que às vezes é esquecido e é a primeira coisa a verificar.
O que aconteceria se você tentasse acessar um Service inexistente? Se você tiver outro Pod que consome esse Service pelo nome, obteria algo como:
wget -O- hostnames
Resolving hostnames (hostnames)... failed: Name or service not known.
wget: unable to resolve host address 'hostnames'
A primeira coisa a verificar é se esse Service realmente existe:
kubectl get svc hostnames
No resources found.
Error from server (NotFound): services "hostnames" not found
Vamos criar o Service. Como antes, isso faz parte do passo a passo – você pode usar os detalhes do seu próprio Service aqui.
kubectl expose deployment hostnames --port=80 --target-port=9376
service/hostnames exposed
E ler de volta:
kubectl get svc hostnames
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hostnames ClusterIP 10.0.1.175 <none> 80/TCP 5s
Agora você sabe que o Service existe.
Como antes, isso é o mesmo que se você tivesse iniciado o Service com YAML:
apiVersion: v1
kind: Service
metadata:
labels:
app: hostnames
name: hostnames
spec:
selector:
app: hostnames
ports:
- name: default
protocol: TCP
port: 80
targetPort: 9376
Para destacar toda a gama de configurações, o Service que você criou aqui usa um número de porta diferente dos Pods. Para muitos Services do mundo real, esses valores podem ser os mesmos.
Se você implantou alguma regra de Network Policy Ingress que possa afetar o
tráfego de entrada para os Pods hostnames-*, elas precisam ser revisadas.
Consulte a documentação sobre Network Policies para mais detalhes.
Uma das formas mais comuns de os clientes consumirem um Service é através de um nome DNS.
A partir de um Pod no mesmo Namespace:
nslookup hostnames
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
Name: hostnames
Address 1: 10.0.1.175 hostnames.default.svc.cluster.local
Se isso falhar, talvez seu Pod e Service estejam em Namespaces diferentes. Tente um nome qualificado pelo namespace (novamente, de dentro de um Pod):
nslookup hostnames.default
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
Name: hostnames.default
Address 1: 10.0.1.175 hostnames.default.svc.cluster.local
Se isso funcionar, você precisará ajustar sua aplicação para usar um nome qualificado pelo namespace ou executar sua aplicação e o Service no mesmo Namespace. Se isso ainda falhar, tente um nome totalmente qualificado:
nslookup hostnames.default.svc.cluster.local
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
Name: hostnames.default.svc.cluster.local
Address 1: 10.0.1.175 hostnames.default.svc.cluster.local
Observe o sufixo aqui: "default.svc.cluster.local". O "default" é o Namespace no qual você está operando. O "svc" indica que este é um Service. O "cluster.local" é o domínio do seu cluster, que PODE ser diferente no seu próprio cluster.
Você também pode tentar isso a partir de um Node no cluster:
nslookup hostnames.default.svc.cluster.local 10.0.0.10
Server: 10.0.0.10
Address: 10.0.0.10#53
Name: hostnames.default.svc.cluster.local
Address: 10.0.1.175
Se você conseguir fazer uma consulta de nome totalmente qualificado, mas não
uma relativa, precisará verificar se o arquivo /etc/resolv.conf no seu Pod
está correto. De dentro de um Pod:
cat /etc/resolv.conf
Você deve ver algo como:
nameserver 10.0.0.10
search default.svc.cluster.local svc.cluster.local cluster.local example.com
options ndots:5
A linha nameserver deve indicar o Service DNS do seu cluster. Isso é passado
para o kubelet com a flag --cluster-dns.
A linha search deve incluir um sufixo apropriado para que o nome do Service
seja encontrado. Neste caso, ele está procurando Services no Namespace local
("default.svc.cluster.local"), Services em todos os Namespaces ("svc.cluster.local"),
e, por último, nomes no cluster ("cluster.local"). Dependendo da sua instalação,
você pode ter registros adicionais depois disso (até um total de 6). O sufixo
do cluster é passado para o kubelet com a flag --cluster-domain. Ao longo
deste documento, assumimos que o sufixo do cluster é "cluster.local". Seu
cluster pode estar configurado de forma diferente, e, nesse caso, você deve
ajustar isso em todos os comandos anteriores.
A linha options deve definir ndots com um valor alto o suficiente para que
sua biblioteca cliente de DNS considere os caminhos de pesquisa. O Kubernetes
define isso como 5 por padrão, o que é suficiente para cobrir todos os nomes
DNS que ele gera.
Se as etapas anteriores ainda falharem, as consultas DNS não estão funcionando para seu Service. Você pode dar um passo atrás e verificar o que mais não está funcionando. O Service principal do Kubernetes deve sempre funcionar. De dentro de um Pod:
nslookup kubernetes.default
Server: 10.0.0.10
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
Name: kubernetes.default
Address 1: 10.0.0.1 kubernetes.default.svc.cluster.local
Se isso falhar, consulte a seção kube-proxy deste documento ou até volte ao início e comece novamente, mas, em vez de depurar seu próprio Service, depure o Service de DNS.
Supondo que você tenha confirmado que o DNS está funcionando, o próximo passo
é testar se o seu Service funciona pelo endereço IP. A partir de um Pod no seu
cluster, acesse o IP do Service (obtido com kubectl get acima).
for i in $(seq 1 3); do
wget -qO- 10.0.1.175:80
done
Isso deve produzir algo como:
hostnames-632524106-bbpiw
hostnames-632524106-ly40y
hostnames-632524106-tlaok
Se o seu Service estiver funcionando, você deverá obter respostas corretas. Caso contrário, há várias possíveis causas para o problema. Continue lendo.
Pode parecer óbvio, mas você deve realmente verificar duas ou três vezes se seu Service está correto e corresponde à porta do seu Pod. Leia novamente seu Service e verifique:
kubectl get service hostnames -o json
{
"kind": "Service",
"apiVersion": "v1",
"metadata": {
"name": "hostnames",
"namespace": "default",
"uid": "428c8b6c-24bc-11e5-936d-42010af0a9bc",
"resourceVersion": "347189",
"creationTimestamp": "2015-07-07T15:24:29Z",
"labels": {
"app": "hostnames"
}
},
"spec": {
"ports": [
{
"name": "default",
"protocol": "TCP",
"port": 80,
"targetPort": 9376,
"nodePort": 0
}
],
"selector": {
"app": "hostnames"
},
"clusterIP": "10.0.1.175",
"type": "ClusterIP",
"sessionAffinity": "None"
},
"status": {
"loadBalancer": {}
}
}
spec.ports[]?targetPort está correto para seus Pods (alguns Pods usam uma porta diferente da do Service)?protocol da porta está correto para seus Pods?Se você chegou até aqui, já confirmou que seu Service está corretamente definido e resolvido pelo DNS. Agora, vamos verificar se os Pods que você executou estão realmente sendo selecionados pelo Service.
Anteriormente, você viu que os Pods estavam em execução. Você pode verificar novamente:
kubectl get pods -l app=hostnames
NAME READY STATUS RESTARTS AGE
hostnames-632524106-bbpiw 1/1 Running 0 1h
hostnames-632524106-ly40y 1/1 Running 0 1h
hostnames-632524106-tlaok 1/1 Running 0 1h
O argumento -l app=hostnames é um seletor de rótulo configurado no Service.
A coluna "AGE" indica que esses Pods têm cerca de uma hora de idade, o que implica que estão funcionando corretamente e não estão falhando.
A coluna "RESTARTS" indica que esses Pods não estão falhando frequentemente ou sendo reiniciados. Reinicializações frequentes podem causar problemas intermitentes de conectividade. Se a contagem de reinicializações for alta, leia mais sobre como depurar pods.
Dentro do sistema Kubernetes, existe um loop de controle que avalia o seletor de cada Service e salva os resultados em um objeto Endpoints correspondente.
kubectl get endpoints hostnames
NAME ENDPOINTS
hostnames 10.244.0.5:9376,10.244.0.6:9376,10.244.0.7:9376
Isso confirma que o controlador de endpoints encontrou os Pods corretos para
seu Service. Se a coluna ENDPOINTS estiver com <none>, você deve verificar
se o campo spec.selector do seu Service realmente seleciona os valores de
metadata.labels nos seus Pods. Um erro comum é ter um erro de digitação ou
outra inconsistência, como o Service selecionando app=hostnames, mas o
Deployment especificando run=hostnames, como em versões anteriores à 1.18,
onde o comando kubectl run também poderia ser usado para criar um Deployment.
Neste ponto, você já sabe que seu Service existe e selecionou seus Pods. No início deste passo a passo, você verificou os próprios Pods. Vamos verificar novamente se os Pods estão realmente funcionando – você pode ignorar o mecanismo do Service e ir diretamente para os Pods, conforme listado nos Endpoints acima.
De dentro de um Pod:
for ep in 10.244.0.5:9376 10.244.0.6:9376 10.244.0.7:9376; do
wget -qO- $ep
done
Isso deve produzir algo como:
hostnames-632524106-bbpiw
hostnames-632524106-ly40y
hostnames-632524106-tlaok
Você espera que cada Pod na lista de Endpoints retorne seu próprio hostname. Se isso não acontecer (ou se o comportamento correto for diferente para seus próprios Pods), você deve investigar o que está acontecendo.
Se você chegou até aqui, seu Service está em execução, possui Endpoints e seus Pods estão realmente respondendo. Neste ponto, todo o mecanismo de proxy do Service pode ser o problema. Vamos confirmá-lo, parte por parte.
A implementação padrão dos Services, e a mais usada na maioria dos clusters, é o kube-proxy. Esse é um programa que roda em cada nó e configura um dos mecanismos disponíveis para fornecer a abstração de Service. Se seu cluster não usa kube-proxy, as próximas seções não se aplicarão, e você precisará investigar qual implementação de Services está em uso.
Confirme que o kube-proxy está rodando nos seus Nodes. Executando diretamente
em um Node, você deve obter algo como o seguinte:
ps auxw | grep kube-proxy
root 4194 0.4 0.1 101864 17696 ? Sl Jul04 25:43 /usr/local/bin/kube-proxy --master=https://kubernetes-master --kubeconfig=/var/lib/kube-proxy/kubeconfig --v=2
Em seguida, confirme que ele não está falhando em algo óbvio, como contatar o
master. Para isso, você precisará verificar os logs. O acesso aos logs depende
do sistema operacional do Node. Em alguns sistemas, é um arquivo, como
/var/log/kube-proxy.log, enquanto em outros, os logs podem ser acessados com
journalctl. Você deve ver algo como:
I1027 22:14:53.995134 5063 server.go:200] Running in resource-only container "/kube-proxy"
I1027 22:14:53.998163 5063 server.go:247] Using iptables Proxier.
I1027 22:14:54.038140 5063 proxier.go:352] Setting endpoints for "kube-system/kube-dns:dns-tcp" to [10.244.1.3:53]
I1027 22:14:54.038164 5063 proxier.go:352] Setting endpoints for "kube-system/kube-dns:dns" to [10.244.1.3:53]
I1027 22:14:54.038209 5063 proxier.go:352] Setting endpoints for "default/kubernetes:https" to [10.240.0.2:443]
I1027 22:14:54.038238 5063 proxier.go:429] Not syncing iptables until Services and Endpoints have been received from master
I1027 22:14:54.040048 5063 proxier.go:294] Adding new service "default/kubernetes:https" at 10.0.0.1:443/TCP
I1027 22:14:54.040154 5063 proxier.go:294] Adding new service "kube-system/kube-dns:dns" at 10.0.0.10:53/UDP
I1027 22:14:54.040223 5063 proxier.go:294] Adding new service "kube-system/kube-dns:dns-tcp" at 10.0.0.10:53/TCP
Se você vir mensagens de erro sobre a impossibilidade de contatar o master, deve verificar novamente a configuração do seu Node e as etapas de instalação.
O kube-proxy pode rodar em diferentes modos. No log listado acima, a linha
Using iptables Proxier indica que o kube-proxy está rodando no modo
"iptables". O outro modo mais comum é o "ipvs".
No modo "iptables", você deve ver algo como o seguinte em um Node:
iptables-save | grep hostnames
-A KUBE-SEP-57KPRZ3JQVENLNBR -s 10.244.3.6/32 -m comment --comment "default/hostnames:" -j MARK --set-xmark 0x00004000/0x00004000
-A KUBE-SEP-57KPRZ3JQVENLNBR -p tcp -m comment --comment "default/hostnames:" -m tcp -j DNAT --to-destination 10.244.3.6:9376
-A KUBE-SEP-WNBA2IHDGP2BOBGZ -s 10.244.1.7/32 -m comment --comment "default/hostnames:" -j MARK --set-xmark 0x00004000/0x00004000
-A KUBE-SEP-WNBA2IHDGP2BOBGZ -p tcp -m comment --comment "default/hostnames:" -m tcp -j DNAT --to-destination 10.244.1.7:9376
-A KUBE-SEP-X3P2623AGDH6CDF3 -s 10.244.2.3/32 -m comment --comment "default/hostnames:" -j MARK --set-xmark 0x00004000/0x00004000
-A KUBE-SEP-X3P2623AGDH6CDF3 -p tcp -m comment --comment "default/hostnames:" -m tcp -j DNAT --to-destination 10.244.2.3:9376
-A KUBE-SERVICES -d 10.0.1.175/32 -p tcp -m comment --comment "default/hostnames: cluster IP" -m tcp --dport 80 -j KUBE-SVC-NWV5X2332I4OT4T3
-A KUBE-SVC-NWV5X2332I4OT4T3 -m comment --comment "default/hostnames:" -m statistic --mode random --probability 0.33332999982 -j KUBE-SEP-WNBA2IHDGP2BOBGZ
-A KUBE-SVC-NWV5X2332I4OT4T3 -m comment --comment "default/hostnames:" -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-X3P2623AGDH6CDF3
-A KUBE-SVC-NWV5X2332I4OT4T3 -m comment --comment "default/hostnames:" -j KUBE-SEP-57KPRZ3JQVENLNBR
Para cada porta de cada Service, deve haver uma regra em KUBE-SERVICES e
uma cadeia KUBE-SVC-<hash>. Para cada endpoint do Pod, deve haver um pequeno
número de regras nessa cadeia KUBE-SVC-<hash> e uma cadeia KUBE-SEP-<hash>
com algumas regras dentro dela. As regras exatas podem variar dependendo da sua
configuração específica (incluindo node-ports e load-balancers).
No modo "ipvs", você deve ver algo como o seguinte em um Node:
ipvsadm -ln
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
...
TCP 10.0.1.175:80 rr
-> 10.244.0.5:9376 Masq 1 0 0
-> 10.244.0.6:9376 Masq 1 0 0
-> 10.244.0.7:9376 Masq 1 0 0
...
Para cada porta de cada Service, além de qualquer NodePort, IP externo e IP de
load-balancer, o kube-proxy criará um servidor virtual. Para cada endpoint de
Pod, ele criará servidores reais correspondentes. Neste exemplo, o Service
hostnames (10.0.1.175:80) tem 3 endpoints (10.244.0.5:9376,
10.244.0.6:9376, 10.244.0.7:9376).
Supondo que você tenha identificado um dos casos acima, tente novamente acessar seu Service pelo IP a partir de um dos seus Nodes:
curl 10.0.1.175:80
hostnames-632524106-bbpiw
Se isso ainda falhar, verifique os logs do kube-proxy em busca de linhas
específicas como:
Setting endpoints for default/hostnames:default to [10.244.0.5:9376 10.244.0.6:9376 10.244.0.7:9376]
Se você não encontrar essas mensagens nos logs, tente reiniciar o kube-proxy
com a flag -v definida como 4 e, em seguida, verifique os logs novamente.
Isso pode parecer improvável, mas acontece e deveria funcionar corretamente.
Esse problema pode ocorrer quando a rede não está configurada corretamente para
tráfego "hairpin", geralmente quando o kube-proxy está rodando no modo
iptables e os Pods estão conectados por meio de uma rede bridge. O Kubelet
expõe um parâmetro hairpin-mode na linha de comando
que permite que os endpoints de um Service realizem balanceamento de carga para
si mesmos ao tentar acessar seu próprio VIP do Service. O parâmetro
hairpin-mode deve estar configurado como hairpin-veth ou promiscuous-bridge.
As etapas comuns para solucionar esse problema são as seguintes:
hairpin-mode está configurado como hairpin-veth ou
promiscuous-bridge. Você deve ver algo semelhante ao seguinte. No exemplo
abaixo, hairpin-mode está definido como promiscuous-bridge:ps auxw | grep kubelet
root 3392 1.1 0.8 186804 65208 ? Sl 00:51 11:11 /usr/local/bin/kubelet --enable-debugging-handlers=true --config=/etc/kubernetes/manifests --allow-privileged=True --v=4 --cluster-dns=10.0.0.10 --cluster-domain=cluster.local --configure-cbr0=true --cgroup-root=/ --system-cgroups=/system --hairpin-mode=promiscuous-bridge --runtime-cgroups=/docker-daemon --kubelet-cgroups=/kubelet --babysit-daemons=true --max-pods=110 --serialize-image-pulls=false --outofdisk-transition-frequency=0
hairpin-mode efetivo. Para isso, será necessário verificar o
log do kubelet. O acesso aos logs depende do sistema operacional do Node. Em
alguns sistemas, ele está em um arquivo como /var/log/kubelet.log, enquanto
em outros, os logs podem ser acessados com journalctl. Observe que o modo
hairpin efetivo pode não corresponder à flag --hairpin-mode devido a
questões de compatibilidade. Verifique se há linhas de log contendo a palavra-chave
hairpin no kubelet.log. Deve haver linhas indicando o modo hairpin efetivo,
como algo semelhante ao seguinte:I0629 00:51:43.648698 3252 kubelet.go:380] Hairpin mode set to "promiscuous-bridge"
hairpin-veth, certifique-se de que o Kubelet
tem permissão para operar em /sys no Node. Se tudo estiver funcionando
corretamente, você deve ver algo como:for intf in /sys/devices/virtual/net/cbr0/brif/*; do cat $intf/hairpin_mode; done
1
1
1
1
promiscuous-bridge, certifique-se de que o
Kubelet tem permissão para manipular a bridge Linux no Node. Se a bridge cbr0
for usada e configurada corretamente, você deve ver:ifconfig cbr0 |grep PROMISC
UP BROADCAST RUNNING PROMISC MULTICAST MTU:1460 Metric:1
Se você chegou até aqui, algo muito estranho está acontecendo. Seu Service
está rodando, tem Endpoints e seus Pods estão realmente respondendo. O DNS
está funcionando e o kube-proxy não parece estar com problemas. E, mesmo
assim, seu Service não está funcionando. Informe-nos o que está acontecendo,
para que possamos ajudar a investigar!
Entre em contato conosco pelo Slack, Fórum ou GitHub.
Visite o documento de visão geral de solução de problemas para mais informações.
Esta tarefa mostra como depurar um StatefulSet.
kubectl
configurada para se comunicar com seu cluster.Para listar todos os Pods que pertencem a um StatefulSet e possuem o rótulo app.kubernetes.io/name=MyApp definido, você pode usar o seguinte comando:
kubectl get pods -l app.kubernetes.io/name=MyApp
Se você notar que algum dos Pods listados está no estado Unknown ou Terminating por um longo período, consulte a tarefa Excluindo Pods de um StatefulSet para obter instruções sobre como lidar com esses casos.
Você pode depurar Pods individuais em um StatefulSet utilizando o guia Depuração de Pods.
Saiba mais sobre depuração de um Init Container.
Esta página mostra como escrever e ler uma mensagem de término do contêiner.
Mensagens de término fornecem uma maneira para os contêineres registrarem informações sobre eventos fatais em um local onde possam ser facilmente recuperadas e exibidas por ferramentas como painéis e softwares de monitoramento. Na maioria dos casos, as informações incluídas em uma mensagem de término também devem ser registradas nos logs do Kubernetes.
Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
Neste exercício, você cria um Pod que executa um único contêiner. O manifesto para esse Pod especifica um comando que é executado quando o contêiner é iniciado:
apiVersion: v1
kind: Pod
metadata:
name: termination-demo
spec:
containers:
- name: termination-demo-container
image: debian
command: ["/bin/sh"]
args: ["-c", "sleep 10 && echo Sleep expired > /dev/termination-log"]
Crie um Pod com base no arquivo de configuração YAML:
kubectl apply -f https://k8s.io/examples/debug/termination.yaml
No arquivo YAML, nos campos command e args, é possível ver que o
contêiner dorme por 10 segundos e, em seguida, escreve "Sleep expired"
no arquivo /dev/termination-log. Após escrever a mensagem "Sleep expired",
o contêiner é encerrado.
Exiba informações sobre o Pod:
kubectl get pod termination-demo
Repita o comando anterior até que o Pod não esteja mais em execução.
Exiba informações detalhadas sobre o Pod:
kubectl get pod termination-demo --output=yaml
A saída inclui a mensagem "Sleep expired":
apiVersion: v1
kind: Pod
...
lastState:
terminated:
containerID: ...
exitCode: 0
finishedAt: ...
message: |
Sleep expired
...
Use um template Go para filtrar a saída, de modo que inclua apenas a mensagem de término:
kubectl get pod termination-demo -o go-template="{{range .status.containerStatuses}}{{.lastState.terminated.message}}{{end}}"
Se você estiver executando um Pod com vários contêineres, pode usar um template Go para incluir o nome do contêiner. Dessa forma, você pode descobrir qual dos contêineres está falhando:
kubectl get pod multi-container-pod -o go-template='{{range .status.containerStatuses}}{{printf "%s:\n%s\n\n" .name .lastState.terminated.message}}{{end}}'
O Kubernetes recupera mensagens de término do arquivo especificado no campo
terminationMessagePath de um contêiner, que tem o valor padrão de /dev/termination-log.
Ao personalizar esse campo, você pode instruir o Kubernetes a usar um arquivo diferente.
O Kubernetes usa o conteúdo do arquivo especificado para preencher a mensagem de status
do contêiner, tanto em casos de sucesso quanto de falha.
A mensagem de término deve ser um breve status final, como uma mensagem de falha de asserção. O kubelet trunca mensagens que excedam 4096 bytes.
O tamanho total da mensagem entre todos os contêineres é limitado a 12KiB,
sendo dividido igualmente entre cada contêiner.
Por exemplo, se houver 12 contêineres (initContainers ou containers),
cada um terá 1024 bytes disponíveis para a mensagem de término.
O caminho padrão para a mensagem de término é /dev/termination-log.
Não é possível definir o caminho da mensagem de término após o lançamento de um Pod.
No exemplo a seguir, o contêiner grava mensagens de término em
/tmp/my-log para que o Kubernetes possa recuperá-las:
apiVersion: v1
kind: Pod
metadata:
name: msg-path-demo
spec:
containers:
- name: msg-path-demo-container
image: debian
terminationMessagePath: "/tmp/my-log"
Além disso, os usuários podem definir o campo terminationMessagePolicy de um contêiner
para uma personalização adicional. Esse campo tem como valor padrão "File",
o que significa que as mensagens de término são recuperadas apenas do arquivo
de mensagem de término.
Ao definir terminationMessagePolicy como "FallbackToLogsOnError", você instrui
o Kubernetes a usar o último trecho do log de saída do contêiner caso o arquivo
de mensagem de término esteja vazio e o contêiner tenha encerrado com erro.
A saída do log é limitada a 2048 bytes ou 80 linhas, o que for menor.
terminationMessagePath em Container.Esta página mostra como investigar problemas relacionados à execução de contêineres de inicialização.
As linhas de comando de exemplo abaixo referem-se ao pod como <pod-name> e aos contêineres de inicialização como <init-container-1> e
<init-container-2>.
Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
Para verificar a versão, digite kubectl version.
Exiba o status do seu pod:
kubectl get pod <pod-name>
Por exemplo, um status de Init:1/2 indica que uma das duas inicializações de contêineres
concluíram com sucesso:
NAME READY STATUS RESTARTS AGE
<pod-name> 0/1 Init:1/2 0 7s
Consulte Entendendo sobre o status do pod para obter mais exemplos de valores de status e seus significados.
Veja informações mais detalhadas sobre a execução de contêineres de inicialização:
kubectl describe pod <pod-name>
Por exemplo, um pod com dois contêineres de inicialização pode mostrar o seguinte:
Init Containers:
<init-container-1>:
Container ID: ...
...
State: Terminated
Reason: Completed
Exit Code: 0
Started: ...
Finished: ...
Ready: True
Restart Count: 0
...
<init-container-2>:
Container ID: ...
...
State: Waiting
Reason: CrashLoopBackOff
Last State: Terminated
Reason: Error
Exit Code: 1
Started: ...
Finished: ...
Ready: False
Restart Count: 3
...
Você também pode acessar programaticamente os status dos contêineres de inicialização,
lendo o campo status.initContainerStatuses nas especificações do pod:
kubectl get pod nginx --template '{{.status.initContainerStatuses}}'
Este comando retornará as mesmas informações acima em JSON bruto.
Passe o nome do contêiner de inicialização junto com o nome do Pod para acessar seus logs.
kubectl logs <pod-name> -c <init-container-2>
Contêineres de inicialização que executam comandos de script de shell imprimem
à medida que são executados. Por exemplo, você pode fazer isso no Bash executando set -x no início do script.
Um status do Pod começando com Init: resume o status da execução de contêineres de inicialização.
A tabela abaixo descreve alguns valores de status de exemplo que você pode ver durante a depuração de contêineres de inicialização.
| Status | Significado |
|---|---|
Init:N/M |
O pod tem contêineres de inicialização M e N que foram concluídas até agora. |
Init:Error |
Um contêiner de inicialização falhou ao executar. |
Init:CrashLoopBackOff |
Um contêiner de inicialização falhou repetidamente. |
Pending |
O pod ainda não começou a executar o contêiner de inicialização. |
PodInitializing ou Running |
O pod já concluiu a execução dos contêineres de inicialização. |
Esta página explica como depurar Pods em execução (ou com falha) em um Nó.
kubectl.kubectl describe pod para obter detalhes sobre os PodsNeste exemplo, usaremos um Deployment para criar dois Pods, semelhante ao exemplo anterior.
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
resources:
limits:
memory: "128Mi"
cpu: "500m"
ports:
- containerPort: 80
Crie o deployment executando o seguinte comando:
kubectl apply -f https://k8s.io/examples/application/nginx-with-request.yaml
deployment.apps/nginx-deployment created
Verifique o status do Pod com o seguinte comando:
kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-67d4bdd6f5-cx2nz 1/1 Running 0 13s
nginx-deployment-67d4bdd6f5-w6kd7 1/1 Running 0 13s
Podemos obter muito mais informações sobre cada um desses Pods usando kubectl describe pod. Por exemplo:
kubectl describe pod nginx-deployment-67d4bdd6f5-w6kd7
Name: nginx-deployment-67d4bdd6f5-w6kd7
Namespace: default
Priority: 0
Node: kube-worker-1/192.168.0.113
Start Time: Thu, 17 Feb 2022 16:51:01 -0500
Labels: app=nginx
pod-template-hash=67d4bdd6f5
Annotations: <none>
Status: Running
IP: 10.88.0.3
IPs:
IP: 10.88.0.3
IP: 2001:db8::1
Controlled By: ReplicaSet/nginx-deployment-67d4bdd6f5
Containers:
nginx:
Container ID: containerd://5403af59a2b46ee5a23fb0ae4b1e077f7ca5c5fb7af16e1ab21c00e0e616462a
Image: nginx
Image ID: docker.io/library/nginx@sha256:2834dc507516af02784808c5f48b7cbe38b8ed5d0f4837f16e78d00deb7e7767
Port: 80/TCP
Host Port: 0/TCP
State: Running
Started: Thu, 17 Feb 2022 16:51:05 -0500
Ready: True
Restart Count: 0
Limits:
cpu: 500m
memory: 128Mi
Requests:
cpu: 500m
memory: 128Mi
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-bgsgp (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
kube-api-access-bgsgp:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional: <nil>
DownwardAPI: true
QoS Class: Guaranteed
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 34s default-scheduler Successfully assigned default/nginx-deployment-67d4bdd6f5-w6kd7 to kube-worker-1
Normal Pulling 31s kubelet Pulling image "nginx"
Normal Pulled 30s kubelet Successfully pulled image "nginx" in 1.146417389s
Normal Created 30s kubelet Created container nginx
Normal Started 30s kubelet Started container nginx
Aqui você pode ver informações de configuração sobre o(s) contêiner(es) e o Pod (rótulos, requisitos de recursos, etc.), assim como informações de status sobre o(s) contêiner(es) e o Pod (estado, prontidão, contagem de reinicializações, eventos, etc.).
O estado do contêiner pode ser Waiting, Running ou Terminated. Dependendo do estado, informações adicionais serão fornecidas -- aqui você pode ver que, para um contêiner no estado Running, o sistema informa quando o contêiner foi iniciado.
Ready informa se o contêiner passou na última verificação de prontidão. (Neste caso, o contêiner não possui uma verificação de prontidão configurada; o contêiner é considerado pronto se nenhuma verificação de prontidão for configurada.)
Restart Count informa quantas vezes o contêiner foi reiniciado; essa informação pode ser útil para detectar loops de falha em contêineres configurados com a política de reinício 'Always'.
Atualmente, a única condição (campo Condition) associada a um Pod é a condição binária Ready, que indica se o Pod pode atender a solicitações e deve ser adicionado aos pools de balanceamento de carga de todos os serviços correspondentes.
Por fim, você verá um log dos eventos recentes relacionados ao seu Pod. "From" indica o componente que está registrando o evento. "Reason" e "Message" informam o que aconteceu.
Um cenário comum que você pode detectar usando eventos é quando você criou um Pod que não pode ser alocado em nenhum Nó. Por exemplo, o Pod pode solicitar mais recursos do que estão disponíveis em qualquer Nó, ou pode especificar um seletor de rótulo que não corresponde a nenhum Nó. Vamos supor que criamos a instalação anterior com 5 réplicas (em vez de 2) e solicitando 600 milicores em vez de 500, em um cluster de quatro Nós onde cada máquina (virtual) possui 1 CPU. Nesse caso, um dos Pods não conseguirá ser alocado. (Observe que, devido aos Pods de complemento do cluster, como fluentd, skydns, etc., que são executados em cada Nó, se solicitássemos 1000 milicores, nenhum dos Pods poderia ser alocado.)
kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-1006230814-6winp 1/1 Running 0 7m
nginx-deployment-1006230814-fmgu3 1/1 Running 0 7m
nginx-deployment-1370807587-6ekbw 1/1 Running 0 1m
nginx-deployment-1370807587-fg172 0/1 Pending 0 1m
nginx-deployment-1370807587-fz9sd 0/1 Pending 0 1m
Para descobrir por que o Pod nginx-deployment-1370807587-fz9sd não está em execução, podemos usar kubectl describe pod no Pod em estado Pending e verificar seus eventos:
kubectl describe pod nginx-deployment-1370807587-fz9sd
Name: nginx-deployment-1370807587-fz9sd
Namespace: default
Node: /
Labels: app=nginx,pod-template-hash=1370807587
Status: Pending
IP:
Controllers: ReplicaSet/nginx-deployment-1370807587
Containers:
nginx:
Image: nginx
Port: 80/TCP
QoS Tier:
memory: Guaranteed
cpu: Guaranteed
Limits:
cpu: 1
memory: 128Mi
Requests:
cpu: 1
memory: 128Mi
Environment Variables:
Volumes:
default-token-4bcbi:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-4bcbi
Events:
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
1m 48s 7 {default-scheduler } Warning FailedScheduling pod (nginx-deployment-1370807587-fz9sd) failed to fit in any node
fit failure on node (kubernetes-node-6ta5): Node didn't have enough resource: CPU, requested: 1000, used: 1420, capacity: 2000
fit failure on node (kubernetes-node-wul5): Node didn't have enough resource: CPU, requested: 1000, used: 1100, capacity: 2000
Aqui você pode ver o evento gerado pelo escalonador informando que o Pod falhou ao ser alocado pelo motivo FailedScheduling (e possivelmente outros). A mensagem nos informa que não havia recursos suficientes para o Pod em nenhum dos Nós.
Para corrigir essa situação, você pode usar kubectl scale para atualizar seu Deployment e especificar quatro ou menos réplicas. (Ou você pode deixar um Pod em estado Pending, o que é inofensivo.)
Eventos como os que você viu no final de kubectl describe pod são armazenados no etcd e fornecem informações de alto nível sobre o que está acontecendo no cluster. Para listar todos os eventos, você pode usar
kubectl get events
mas você deve lembrar que os eventos são associados a namespaces. Isso significa que, se você estiver interessado em eventos de um objeto dentro de um namespace específico (por exemplo, o que aconteceu com os Pods no namespace my-namespace), você precisa fornecer explicitamente um namespace ao comando:
kubectl get events --namespace=my-namespace
Para ver eventos de todos os namespaces, você pode usar o argumento --all-namespaces.
Além de kubectl describe pod, outra maneira de obter informações adicionais sobre um Pod (além do que é fornecido por kubectl get pod) é usar a opção de formato de saída -o yaml com kubectl get pod. Isso fornecerá, no formato YAML, ainda mais informações do que kubectl describe pod — essencialmente, todas as informações que o sistema possui sobre o Pod.
Aqui, você verá itens como anotações (que são metadados no formato chave-valor sem as restrições dos rótulos, utilizadas internamente pelos componentes do sistema Kubernetes), política de reinício, portas e volumes.
kubectl get pod nginx-deployment-1006230814-6winp -o yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: "2022-02-17T21:51:01Z"
generateName: nginx-deployment-67d4bdd6f5-
labels:
app: nginx
pod-template-hash: 67d4bdd6f5
name: nginx-deployment-67d4bdd6f5-w6kd7
namespace: default
ownerReferences:
- apiVersion: apps/v1
blockOwnerDeletion: true
controller: true
kind: ReplicaSet
name: nginx-deployment-67d4bdd6f5
uid: 7d41dfd4-84c0-4be4-88ab-cedbe626ad82
resourceVersion: "1364"
uid: a6501da1-0447-4262-98eb-c03d4002222e
spec:
containers:
- image: nginx
imagePullPolicy: Always
name: nginx
ports:
- containerPort: 80
protocol: TCP
resources:
limits:
cpu: 500m
memory: 128Mi
requests:
cpu: 500m
memory: 128Mi
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: kube-api-access-bgsgp
readOnly: true
dnsPolicy: ClusterFirst
enableServiceLinks: true
nodeName: kube-worker-1
preemptionPolicy: PreemptLowerPriority
priority: 0
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
serviceAccount: default
serviceAccountName: default
terminationGracePeriodSeconds: 30
tolerations:
- effect: NoExecute
key: node.kubernetes.io/not-ready
operator: Exists
tolerationSeconds: 300
- effect: NoExecute
key: node.kubernetes.io/unreachable
operator: Exists
tolerationSeconds: 300
volumes:
- name: kube-api-access-bgsgp
projected:
defaultMode: 420
sources:
- serviceAccountToken:
expirationSeconds: 3607
path: token
- configMap:
items:
- key: ca.crt
path: ca.crt
name: kube-root-ca.crt
- downwardAPI:
items:
- fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
path: namespace
status:
conditions:
- lastProbeTime: null
lastTransitionTime: "2022-02-17T21:51:01Z"
status: "True"
type: Initialized
- lastProbeTime: null
lastTransitionTime: "2022-02-17T21:51:06Z"
status: "True"
type: Ready
- lastProbeTime: null
lastTransitionTime: "2022-02-17T21:51:06Z"
status: "True"
type: ContainersReady
- lastProbeTime: null
lastTransitionTime: "2022-02-17T21:51:01Z"
status: "True"
type: PodScheduled
containerStatuses:
- containerID: containerd://5403af59a2b46ee5a23fb0ae4b1e077f7ca5c5fb7af16e1ab21c00e0e616462a
image: docker.io/library/nginx:latest
imageID: docker.io/library/nginx@sha256:2834dc507516af02784808c5f48b7cbe38b8ed5d0f4837f16e78d00deb7e7767
lastState: {}
name: nginx
ready: true
restartCount: 0
started: true
state:
running:
startedAt: "2022-02-17T21:51:05Z"
hostIP: 192.168.0.113
phase: Running
podIP: 10.88.0.3
podIPs:
- ip: 10.88.0.3
- ip: 2001:db8::1
qosClass: Guaranteed
startTime: "2022-02-17T21:51:01Z"
Primeiro, veja os logs do contêiner afetado:
kubectl logs ${POD_NAME} ${CONTAINER_NAME}
Se o seu contêiner tiver falhado anteriormente, você pode acessar o log da falha do contêiner anterior com:
kubectl logs --previous ${POD_NAME} ${CONTAINER_NAME}
Se a imagem do contêiner incluir ferramentas de depuração, como é o caso de imagens baseadas nos sistemas operacionais Linux e Windows, você pode executar comandos dentro de um contêiner específico usando kubectl exec:
kubectl exec ${POD_NAME} -c ${CONTAINER_NAME} -- ${CMD} ${ARG1} ${ARG2} ... ${ARGN}
-c ${CONTAINER_NAME} é opcional. Você pode omití-lo para Pods que contêm apenas um único contêiner.Como exemplo, para visualizar os logs de um pod Cassandra em execução, você pode executar:
kubectl exec cassandra -- cat /var/log/cassandra/system.log
Você pode executar um shell conectado ao seu terminal usando os argumentos -i e -t com kubectl exec, por exemplo:
kubectl exec -it cassandra -- sh
Para mais detalhes, veja Obter um Shell em um Contêiner em Execução.
Kubernetes v1.25 [stable]
Contêineres efêmeros são úteis para uma solução de problemas
interativa quando kubectl exec não é suficiente, como no caso de um contêiner que falhou ou uma imagem de contêiner
que não inclui ferramentas de depuração, como ocorre com imagens distroless.
Você pode usar o comando kubectl debug para adicionar contêineres efêmeros a um Pod em execução.
Primeiro, crie um Pod para o exemplo:
kubectl run ephemeral-demo --image=registry.k8s.io/pause:3.1 --restart=Never
Os exemplos nesta seção usam a imagem do contêiner pause porque ela não contém ferramentas de depuração, mas esse método funciona com todas as imagens de contêiner.
Se você tentar usar kubectl exec para criar um shell, verá um erro, pois não há um shell nesta imagem de contêiner.
kubectl exec -it ephemeral-demo -- sh
OCI runtime exec failed: exec failed: container_linux.go:346: starting container process caused "exec: \"sh\": executable file not found in $PATH": unknown
Em vez disso, você pode adicionar um contêiner de depuração usando kubectl debug.
Se você especificar o argumento -i/--interactive, o kubectl conectará automaticamente ao console do Contêiner Efêmero.
kubectl debug -it ephemeral-demo --image=busybox:1.28 --target=ephemeral-demo
Defaulting debug container name to debugger-8xzrl.
If you don't see a command prompt, try pressing enter.
/ #
Este comando adiciona um novo contêiner busybox e o anexa. O parâmetro --target define o namespace de processo de outro contêiner.
Ele é necessário aqui porque kubectl run não habilita o compartilhamento do namespace de processo no Pod que ele cria.
--target deve ser suportado pelo Agente de execução do Contêiner. Quando não for suportado, o Contêiner Efêmero pode não ser iniciado ou pode ser iniciado com um namespace de processo isolado, de modo que ps não revelará processos em outros contêineres.Você pode visualizar o estado do contêiner efêmero recém-criado usando kubectl describe:
kubectl describe pod ephemeral-demo
...
Ephemeral Containers:
debugger-8xzrl:
Container ID: docker://b888f9adfd15bd5739fefaa39e1df4dd3c617b9902082b1cfdc29c4028ffb2eb
Image: busybox
Image ID: docker-pullable://busybox@sha256:1828edd60c5efd34b2bf5dd3282ec0cc04d47b2ff9caa0b6d4f07a21d1c08084
Port: <none>
Host Port: <none>
State: Running
Started: Wed, 12 Feb 2020 14:25:42 +0100
Ready: False
Restart Count: 0
Environment: <none>
Mounts: <none>
...
Use kubectl delete para remover o Pod quando terminar:
kubectl delete pod ephemeral-demo
Às vezes, as opções de configuração do Pod dificultam a solução de problemas em determinadas situações.
Por exemplo, você não pode executar kubectl exec para depurar seu contêiner se a imagem do contêiner
não incluir um shell ou se sua aplicação falhar na inicialização.
Nesses casos, você pode usar kubectl debug para criar uma cópia do Pod com valores de configuração
modificados para facilitar a depuração.
Adicionar um novo contêiner pode ser útil quando sua aplicação está em execução, mas não se comporta como esperado e você deseja adicionar ferramentas adicionais de depuração ao Pod.
Por exemplo, talvez as imagens do contêiner da sua aplicação sejam baseadas em busybox, mas você precise de ferramentas de depuração que não estão incluídas no busybox.
Você pode simular esse cenário usando kubectl run:
kubectl run myapp --image=busybox:1.28 --restart=Never -- sleep 1d
Execute este comando para criar uma cópia de myapp chamada myapp-debug, adicionando um novo contêiner Ubuntu para depuração:
kubectl debug myapp -it --image=ubuntu --share-processes --copy-to=myapp-debug
Defaulting debug container name to debugger-w7xmf.
If you don't see a command prompt, try pressing enter.
root@myapp-debug:/#
kubectl debug gera automaticamente um nome para o contêiner caso você não escolha um usando a opção --container.-i faz com que kubectl debug anexe ao novo contêiner por padrão.
Você pode impedir isso especificando --attach=false. Se sua sessão for desconectada, você pode se reconectar usando kubectl attach.--share-processes permite que os contêineres deste Pod visualizem processos
de outros contêineres no mesmo Pod. Para mais informações sobre como isso funciona, veja Compartilhar o Namespace de Processos entre Contêineres em um Pod.Não se esqueça de limpar o Pod de depuração quando terminar de usá-lo:
kubectl delete pod myapp myapp-debug
Às vezes, é útil alterar o comando de um contêiner, por exemplo, para adicionar uma opção de depuração ou porque a aplicação está falhando.
Para simular uma aplicação com falha, use kubectl run para criar um contêiner que termine imediatamente:
kubectl run --image=busybox:1.28 myapp -- false
Você pode ver, usando kubectl describe pod myapp, que este contêiner está falhando:
Containers:
myapp:
Image: busybox
...
Args:
false
State: Waiting
Reason: CrashLoopBackOff
Last State: Terminated
Reason: Error
Exit Code: 1
Você pode usar kubectl debug para criar uma cópia deste Pod com o comando alterado para um shell interativo:
kubectl debug myapp -it --copy-to=myapp-debug --container=myapp -- sh
If you don't see a command prompt, try pressing enter.
/ #
Agora você tem um shell interativo que pode usar para realizar tarefas como verificar caminhos do sistema de arquivos ou executar manualmente o comando do contêiner.
--container, caso contrário, kubectl debug
criará um novo contêiner para executar o comando especificado.-i faz com que kubectl debug anexe ao contêiner por padrão.
Você pode impedir isso especificando --attach=false. Se sua sessão for
desconectada, você pode se reconectar usando kubectl attach.Não se esqueça de limpar o Pod de depuração quando terminar de usá-lo:
kubectl delete pod myapp myapp-debug
Em algumas situações, pode ser necessário alterar um Pod com comportamento inesperado, substituindo suas imagens de contêiner de produção por uma imagem contendo uma versão de depuração ou utilitários adicionais.
Como exemplo, crie um Pod usando kubectl run:
kubectl run myapp --image=busybox:1.28 --restart=Never -- sleep 1d
Agora use kubectl debug para criar uma cópia e alterar a imagem do contêiner para ubuntu:
kubectl debug myapp --copy-to=myapp-debug --set-image=*=ubuntu
A sintaxe de --set-image usa o mesmo formato container_name=image que kubectl set image.
*=ubuntu significa alterar a imagem de todos os contêineres para ubuntu.
Não se esqueça de limpar o Pod de depuração quando terminar de usá-lo:
kubectl delete pod myapp myapp-debug
Se nenhuma dessas abordagens funcionar, você pode identificar o Nó onde o Pod está sendo executado e criar um Pod nesse Nó.
Para criar um shell interativo em um Nó usando kubectl debug, execute:
kubectl debug node/mynode -it --image=ubuntu
Creating debugging pod node-debugger-mynode-pdx84 with container debugger on node mynode.
If you don't see a command prompt, try pressing enter.
root@ek8s:/#
Ao criar uma sessão de depuração em um Nó, tenha em mente que:
kubectl debug gera automaticamente o nome do novo Pod com base no nome do Nó./host.chroot /host pode não funcionar.--profile=sysadmin.Não se esqueça de limpar o Pod de depuração quando terminar de usá-lo:
kubectl delete pod node-debugger-mynode-pdx84
Ao usar kubectl debug para depurar um Nó por meio de um Pod de depuração, um Pod por meio de um Contêiner Efêmero ou um Pod copiado, você pode aplicar um perfil a eles.
Ao aplicar um perfil, propriedades específicas, como securityContext, são definidas, permitindo a adaptação a diferentes cenários.
Existem dois tipos de perfis: perfil estático e perfil personalizado.
Um perfil estático é um conjunto de propriedades predefinidas que podem ser aplicadas usando a opção --profile.
Os perfis disponíveis são os seguintes:
| Profile | Description |
|---|---|
| legacy | Um conjunto de propriedades para retrocompatibilidade com o comportamento da versão 1.22 |
| general | Um conjunto razoável de propriedades genéricas para cada processo de depuração |
| baseline | Um conjunto de propriedades compatível com PodSecurityStandard baseline policy |
| restricted | Um conjunto de propriedades compatível com PodSecurityStandard restricted policy |
| netadmin | Um conjunto de propriedades incluindo privilégios de Administrador de Rede |
| sysadmin | Um conjunto de propriedades incluindo privilégios de Administrador do Sistema (root) |
--profile, o perfil legacy será usado por padrão, mas há planos para sua descontinuação em um futuro próximo.
Portanto, é recomendável usar outros perfis, como general.Suponha que você crie um Pod e queira depurá-lo.
Primeiro, crie um Pod chamado myapp como exemplo:
kubectl run myapp --image=busybox:1.28 --restart=Never -- sleep 1d
Em seguida, depure o Pod usando um Contêiner Efêmero.
Se o Contêiner Efêmero precisar de privilégios, você pode usar o perfil sysadmin:
kubectl debug -it myapp --image=busybox:1.28 --target=myapp --profile=sysadmin
Targeting container "myapp". If you don't see processes from this container it may be because the container runtime doesn't support this feature.
Defaulting debug container name to debugger-6kg4x.
If you don't see a command prompt, try pressing enter.
/ #
Verifique as capacidades do processo do Contêiner Efêmero executando o seguinte comando dentro do contêiner:
/ # grep Cap /proc/$$/status
...
CapPrm: 000001ffffffffff
CapEff: 000001ffffffffff
...
Isso significa que o processo do contêiner recebeu todas as capacidades de um contêiner privilegiado ao aplicar o perfil sysadmin.
Veja mais detalhes sobre capacidades.
Você também pode verificar que o Contêiner Efêmero foi criado como um contêiner privilegiado:
kubectl get pod myapp -o jsonpath='{.spec.ephemeralContainers[0].securityContext}'
{"privileged":true}
Remova o Pod quando terminar de usá-lo:
kubectl delete pod myapp
Kubernetes v1.32 [stable]
Você pode definir uma especificação parcial de contêiner para depuração como um perfil personalizado,
em formato YAML ou JSON, e aplicá-lo usando a opção --custom.
name, image, command, lifecycle e volumeDevices da especificação do contêiner.
Ele também não suporta a modificação da especificação do Pod.Crie um Pod chamado myapp como exemplo:
kubectl run myapp --image=busybox:1.28 --restart=Never -- sleep 1d
Crie um perfil personalizado no formato YAML ou JSON.
Aqui, crie um arquivo no formato YAML chamado custom-profile.yaml:
env:
- name: ENV_VAR_1
value: value_1
- name: ENV_VAR_2
value: value_2
securityContext:
capabilities:
add:
- NET_ADMIN
- SYS_TIME
Execute este comando para depurar o Pod usando um Contêiner Efêmero com o perfil personalizado:
kubectl debug -it myapp --image=busybox:1.28 --target=myapp --profile=general --custom=custom-profile.yaml
Você pode verificar que o Contêiner Efêmero foi adicionado ao Pod de destino com o perfil personalizado aplicado:
kubectl get pod myapp -o jsonpath='{.spec.ephemeralContainers[0].env}'
[{"name":"ENV_VAR_1","value":"value_1"},{"name":"ENV_VAR_2","value":"value_2"}]
kubectl get pod myapp -o jsonpath='{.spec.ephemeralContainers[0].securityContext}'
{"capabilities":{"add":["NET_ADMIN","SYS_TIME"]}}
Remova o Pod quando terminar de usá-lo:
kubectl delete pod myapp
Esta página mostra como usar kubectl exec para obter um shell em um contêiner em execução.
Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
Neste exercício, você cria um Pod que possui um contêiner. O contêiner executa a imagem do nginx. Aqui está o arquivo de configuração para o Pod:
apiVersion: v1
kind: Pod
metadata:
name: shell-demo
spec:
volumes:
- name: shared-data
emptyDir: {}
containers:
- name: nginx
image: nginx
volumeMounts:
- name: shared-data
mountPath: /usr/share/nginx/html
hostNetwork: true
dnsPolicy: Default
Crie o Pod:
kubectl apply -f https://k8s.io/examples/application/shell-demo.yaml
Verifique se o contêiner está em execução:
kubectl get pod shell-demo
Obtenha um shell no contêiner em execução:
kubectl exec --stdin --tty shell-demo -- /bin/bash
--) separa os argumentos que você deseja passar para o comando dos argumentos do kubectl.No seu shell, liste o diretório raiz:
# Execute isso dentro do contêiner
ls /
No seu shell, experimente outros comandos. Aqui estão alguns exemplos:
# Você pode executar esses comandos de exemplo dentro do contêiner
ls /
cat /proc/mounts
cat /proc/1/maps
apt-get update
apt-get install -y tcpdump
tcpdump
apt-get install -y lsof
lsof
apt-get install -y procps
ps aux
ps aux | grep nginx
Veja novamente o arquivo de configuração do seu Pod. O Pod
possui um volume emptyDir, e o contêiner monta esse volume
em /usr/share/nginx/html.
No seu shell, crie um arquivo index.html no diretório /usr/share/nginx/html:
# Execute isso dentro do contêiner
echo 'Hello shell demo' > /usr/share/nginx/html/index.html
No seu shell, envie uma solicitação GET para o servidor nginx:
# Execute isso no shell dentro do seu contêiner
apt-get update
apt-get install curl
curl http://localhost/
A saída exibe o texto que você escreveu no arquivo index.html:
Hello shell demo
Quando terminar de usar o shell, digite exit.
exit # Para sair do shell no contêiner
Em uma janela de comando comum, fora do seu shell, liste as variáveis de ambiente no contêiner em execução:
kubectl exec shell-demo -- env
Experimente executar outros comandos. Aqui estão alguns exemplos:
kubectl exec shell-demo -- ps aux
kubectl exec shell-demo -- ls /
kubectl exec shell-demo -- cat /proc/1/mounts
Se um Pod tiver mais de um contêiner, use --container ou -c para
especificar um contêiner no comando kubectl exec. Por exemplo,
suponha que você tenha um Pod chamado my-pod, e esse Pod tenha dois contêineres
chamados main-app e helper-app. O seguinte comando abriria um
shell no contêiner main-app.
kubectl exec -i -t my-pod --container main-app -- /bin/bash
-i e -t são equivalentes às opções longas --stdin e --ttykubectl execEsta documentação é sobre solução de problemas em clusters; assumimos que você já descartou sua aplicação como a causa raiz do problema que está enfrentando. Consulte o guia de solução de problemas em aplicações para dicas sobre depuração de aplicações. Você também pode visitar o documento de visão geral de solução de problemas para mais informações.
Para solução de problemas do kubectl, consulte Solução de problemas do kubectl.
A primeira coisa a depurar no seu cluster é se todos os seus nós estão registrados corretamente.
Execute o seguinte comando:
kubectl get nodes
E verifique se todos os nós que você espera ver estão presentes e se todos estão no estado Ready.
Para obter informações detalhadas sobre a integridade geral do seu cluster, você pode executar:
kubectl cluster-info dump
Às vezes, durante a depuração, pode ser útil verificar o status de um nó -- por exemplo, porque
você notou um comportamento estranho de um Pod que está executando no nó, ou para descobrir por que um Pod
não será alocado no nó. Assim como com os Pods, você pode usar kubectl describe node e kubectl get node -o yaml para recuperar informações detalhadas sobre os nós. Por exemplo, aqui está o que você verá se
um nó estiver indisponível (desconectado da rede, ou o kubelet morre e não reinicia, etc.). Observe
os eventos que mostram que o nó está NotReady, e também observe que os pods não estão mais em execução
(eles são removidos após cinco minutos de status NotReady).
kubectl get nodes
NAME STATUS ROLES AGE VERSION
kube-worker-1 NotReady <none> 1h v1.23.3
kubernetes-node-bols Ready <none> 1h v1.23.3
kubernetes-node-st6x Ready <none> 1h v1.23.3
kubernetes-node-unaj Ready <none> 1h v1.23.3
kubectl describe node kube-worker-1
Name: kube-worker-1
Roles: <none>
Labels: beta.kubernetes.io/arch=amd64
beta.kubernetes.io/os=linux
kubernetes.io/arch=amd64
kubernetes.io/hostname=kube-worker-1
kubernetes.io/os=linux
node.alpha.kubernetes.io/ttl: 0
volumes.kubernetes.io/controller-managed-attach-detach: true
CreationTimestamp: Thu, 17 Feb 2022 16:46:30 -0500
Taints: node.kubernetes.io/unreachable:NoExecute
node.kubernetes.io/unreachable:NoSchedule
Unschedulable: false
Lease:
HolderIdentity: kube-worker-1
AcquireTime: <unset>
RenewTime: Thu, 17 Feb 2022 17:13:09 -0500
Conditions:
Type Status LastHeartbeatTime LastTransitionTime Reason Message
---- ------ ----------------- ------------------ ------ -------
NetworkUnavailable False Thu, 17 Feb 2022 17:09:13 -0500 Thu, 17 Feb 2022 17:09:13 -0500 WeaveIsUp Weave pod has set this
MemoryPressure Unknown Thu, 17 Feb 2022 17:12:40 -0500 Thu, 17 Feb 2022 17:13:52 -0500 NodeStatusUnknown Kubelet stopped posting node status.
DiskPressure Unknown Thu, 17 Feb 2022 17:12:40 -0500 Thu, 17 Feb 2022 17:13:52 -0500 NodeStatusUnknown Kubelet stopped posting node status.
PIDPressure Unknown Thu, 17 Feb 2022 17:12:40 -0500 Thu, 17 Feb 2022 17:13:52 -0500 NodeStatusUnknown Kubelet stopped posting node status.
Ready Unknown Thu, 17 Feb 2022 17:12:40 -0500 Thu, 17 Feb 2022 17:13:52 -0500 NodeStatusUnknown Kubelet stopped posting node status.
Addresses:
InternalIP: 192.168.0.113
Hostname: kube-worker-1
Capacity:
cpu: 2
ephemeral-storage: 15372232Ki
hugepages-2Mi: 0
memory: 2025188Ki
pods: 110
Allocatable:
cpu: 2
ephemeral-storage: 14167048988
hugepages-2Mi: 0
memory: 1922788Ki
pods: 110
System Info:
Machine ID: 9384e2927f544209b5d7b67474bbf92b
System UUID: aa829ca9-73d7-064d-9019-df07404ad448
Boot ID: 5a295a03-aaca-4340-af20-1327fa5dab5c
Kernel Version: 5.13.0-28-generic
OS Image: Ubuntu 21.10
Operating System: linux
Architecture: amd64
Container Runtime Version: containerd://1.5.9
Kubelet Version: v1.23.3
Kube-Proxy Version: v1.23.3
Non-terminated Pods: (4 in total)
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits Age
--------- ---- ------------ ---------- --------------- ------------- ---
default nginx-deployment-67d4bdd6f5-cx2nz 500m (25%) 500m (25%) 128Mi (6%) 128Mi (6%) 23m
default nginx-deployment-67d4bdd6f5-w6kd7 500m (25%) 500m (25%) 128Mi (6%) 128Mi (6%) 23m
kube-system kube-proxy-dnxbz 0 (0%) 0 (0%) 0 (0%) 0 (0%) 28m
kube-system weave-net-gjxxp 100m (5%) 0 (0%) 200Mi (10%) 0 (0%) 28m
Allocated resources:
(Total limits may be over 100 percent, i.e., overcommitted.)
Resource Requests Limits
-------- -------- ------
cpu 1100m (55%) 1 (50%)
memory 456Mi (24%) 256Mi (13%)
ephemeral-storage 0 (0%) 0 (0%)
hugepages-2Mi 0 (0%) 0 (0%)
Events:
...
kubectl get node kube-worker-1 -o yaml
apiVersion: v1
kind: Node
metadata:
annotations:
node.alpha.kubernetes.io/ttl: "0"
volumes.kubernetes.io/controller-managed-attach-detach: "true"
creationTimestamp: "2022-02-17T21:46:30Z"
labels:
beta.kubernetes.io/arch: amd64
beta.kubernetes.io/os: linux
kubernetes.io/arch: amd64
kubernetes.io/hostname: kube-worker-1
kubernetes.io/os: linux
name: kube-worker-1
resourceVersion: "4026"
uid: 98efe7cb-2978-4a0b-842a-1a7bf12c05f8
spec: {}
status:
addresses:
- address: 192.168.0.113
type: InternalIP
- address: kube-worker-1
type: Hostname
allocatable:
cpu: "2"
ephemeral-storage: "14167048988"
hugepages-2Mi: "0"
memory: 1922788Ki
pods: "110"
capacity:
cpu: "2"
ephemeral-storage: 15372232Ki
hugepages-2Mi: "0"
memory: 2025188Ki
pods: "110"
conditions:
- lastHeartbeatTime: "2022-02-17T22:20:32Z"
lastTransitionTime: "2022-02-17T22:20:32Z"
message: Weave pod has set this
reason: WeaveIsUp
status: "False"
type: NetworkUnavailable
- lastHeartbeatTime: "2022-02-17T22:20:15Z"
lastTransitionTime: "2022-02-17T22:13:25Z"
message: kubelet has sufficient memory available
reason: KubeletHasSufficientMemory
status: "False"
type: MemoryPressure
- lastHeartbeatTime: "2022-02-17T22:20:15Z"
lastTransitionTime: "2022-02-17T22:13:25Z"
message: kubelet has no disk pressure
reason: KubeletHasNoDiskPressure
status: "False"
type: DiskPressure
- lastHeartbeatTime: "2022-02-17T22:20:15Z"
lastTransitionTime: "2022-02-17T22:13:25Z"
message: kubelet has sufficient PID available
reason: KubeletHasSufficientPID
status: "False"
type: PIDPressure
- lastHeartbeatTime: "2022-02-17T22:20:15Z"
lastTransitionTime: "2022-02-17T22:15:15Z"
message: kubelet is posting ready status
reason: KubeletReady
status: "True"
type: Ready
daemonEndpoints:
kubeletEndpoint:
Port: 10250
nodeInfo:
architecture: amd64
bootID: 22333234-7a6b-44d4-9ce1-67e31dc7e369
containerRuntimeVersion: containerd://1.5.9
kernelVersion: 5.13.0-28-generic
kubeProxyVersion: v1.23.3
kubeletVersion: v1.23.3
machineID: 9384e2927f544209b5d7b67474bbf92b
operatingSystem: linux
osImage: Ubuntu 21.10
systemUUID: aa829ca9-73d7-064d-9019-df07404ad448
Por enquanto, investigar mais profundamente o cluster requer fazer login nas máquinas relevantes. Veja abaixo as localizações
dos arquivos de log relevantes. Em sistemas baseados em systemd, você pode precisar usar journalctl ao invés de examinar arquivos de log.
/var/log/kube-apiserver.log - Servidor de API, responsável por servir a API/var/log/kube-scheduler.log - Agendador, responsável por tomar decisões de alocação/var/log/kube-controller-manager.log - um componente que executa a maioria dos
controladores embutidos do Kubernetes, com a notável exceção da alocação
(o kube-scheduler lida com a alocação)./var/log/kubelet.log - logs do kubelet, responsável por executar contêineres no nó/var/log/kube-proxy.log - logs do kube-proxy, que é responsável por direcionar tráfego para endpoints de ServiceEsta é uma lista incompleta de coisas que podem dar errado e como ajustar a configuração do seu cluster para mitigar os problemas.
Ação: Use a funcionalidade de reinicialização automática de VM do provedor IaaS para VMs IaaS
Ação: Use armazenamento confiável de provedores IaaS (por exemplo, GCE PD ou volume AWS EBS) para VMs com servidor de API + etcd
Ação: Use configuração de alta disponibilidade
Ação: Fazer snapshot de PDs/volumes EBS do servidor de API periodicamente
Ação: usar replication controller e services na frente dos pods
Ação: aplicações (contêineres) projetadas para tolerar reinicializações inesperadas
kubectl debug node para depurar nós do Kubernetescrictl para depurar nós do Kubernetestelepresence para desenvolver e depurar serviços localmenteEsta documentação é sobre investigar e diagnosticar
problemas relacionados ao kubectl.
Se você encontrar problemas ao acessar o kubectl ou ao conectar-se ao seu cluster, este
documento descreve vários cenários comuns e possíveis soluções para ajudar
a identificar e resolver a causa provável.
kubectl instalado - veja instale as ferramentasCertifique-se de que você instalou e configurou o kubectl corretamente em sua máquina local.
Verifique a versão do kubectl para garantir que esteja atualizada e compatível com seu cluster.
Verifique a versão do kubectl:
kubectl version
Você verá uma saída similar:
Client Version: version.Info{Major:"1", Minor:"27", GitVersion:"v1.27.4",GitCommit:"fa3d7990104d7c1f16943a67f11b154b71f6a132", GitTreeState:"clean",BuildDate:"2023-07-19T12:20:54Z", GoVersion:"go1.20.6", Compiler:"gc", Platform:"linux/amd64"}
Kustomize Version: v5.0.1
Server Version: version.Info{Major:"1", Minor:"27", GitVersion:"v1.27.3",GitCommit:"25b4e43193bcda6c7328a6d147b1fb73a33f1598", GitTreeState:"clean",BuildDate:"2023-06-14T09:47:40Z", GoVersion:"go1.20.5", Compiler:"gc", Platform:"linux/amd64"}
Se você vir Unable to connect to the server: dial tcp <server-ip>:8443: i/o timeout,
ao invés de Server Version, você precisa solucionar problemas de conectividade do kubectl com seu cluster.
Certifique-se de que você instalou o kubectl seguindo a
documentação oficial para instalar o kubectl, e que você
configurou adequadamente a variável de ambiente $PATH.
O kubectl requer um arquivo kubeconfig para conectar-se a um cluster Kubernetes. O
arquivo kubeconfig geralmente está localizado no diretório ~/.kube/config. Certifique-se
de que você tem um arquivo kubeconfig válido. Se você não tiver um arquivo kubeconfig, você pode
obtê-lo do seu administrador do Kubernetes, ou pode copiá-lo do diretório /etc/kubernetes/admin.conf
da camada de gerenciamento do seu Kubernetes. Se você implantou seu
cluster Kubernetes em uma plataforma de nuvem e perdeu seu arquivo kubeconfig, você pode
recriá-lo usando as ferramentas do seu provedor de nuvem. Consulte a
documentação do provedor de nuvem para recriar um arquivo kubeconfig.
Verifique se a variável de ambiente $KUBECONFIG está configurada corretamente. Você pode definir
a variável de ambiente $KUBECONFIG ou usar o parâmetro --kubeconfig com o kubectl
para especificar o diretório de um arquivo kubeconfig.
Se você está usando uma Rede Privada Virtual (VPN) para acessar seu cluster Kubernetes, certifique-se de que sua conexão VPN está ativa e estável. Às vezes, desconexões da VPN podem levar a problemas de conexão com o cluster. Reconecte-se à VPN e tente acessar o cluster novamente.
Se você está usando autenticação baseada em token e o kubectl está retornando um erro relacionado ao token de autenticação ou endereço do servidor de autenticação, valide se o token de autenticação do Kubernetes e o endereço do servidor de autenticação estão configurados adequadamente.
Se o kubectl está retornando um erro relacionado à autorização, certifique-se de que você está usando as credenciais de usuário válidas. E que você tem a permissão para acessar o recurso que você solicitou.
O Kubernetes suporta múltiplos clusters e contextos. Certifique-se de que você está usando o contexto correto para interagir com seu cluster.
Listar contextos disponíveis:
kubectl config get-contexts
Alternar para o contexto apropriado:
kubectl config use-context <context-name>
O servidor kube-apiserver é o componente central de um cluster Kubernetes. Se o servidor de API ou o balanceador de carga que executa na frente dos seus servidores de API não estiver acessível ou não estiver respondendo, você não conseguirá interagir com o cluster.
Verifique se o host do servidor de API está acessível usando o comando ping. Verifique a
conectividade de rede e firewall do cluster. Se você estiver usando um provedor de nuvem para implantar
o cluster, verifique o status de verificação de saúde do seu provedor de nuvem para o
servidor de API do cluster.
Verifique o status do balanceador de carga (se usado) para garantir que esteja íntegro e encaminhando tráfego para o servidor de API.
base64 e openssl versão 3.0 ou superior.O servidor de API do Kubernetes serve apenas requisições HTTPS por padrão. Nesse caso, problemas de TLS podem ocorrer por várias razões, como expiração de certificado ou validade da cadeia de confiança.
Você pode encontrar o certificado TLS no arquivo kubeconfig, localizado no diretório
~/.kube/config. O atributo certificate-authority contém o certificado CA e o
atributo client-certificate contém o certificado do cliente.
Verificar a expiração destes certificados:
kubectl config view --flatten --output 'jsonpath={.clusters[0].cluster.certificate-authority-data}' | base64 -d | openssl x509 -noout -dates
saída:
notBefore=Feb 13 05:57:47 2024 GMT
notAfter=Feb 10 06:02:47 2034 GMT
kubectl config view --flatten --output 'jsonpath={.users[0].user.client-certificate-data}'| base64 -d | openssl x509 -noout -dates
saída:
notBefore=Feb 13 05:57:47 2024 GMT
notAfter=Feb 12 06:02:50 2025 GMT
Algumas ferramentas auxiliares de autenticação do kubectl fornecem acesso fácil aos clusters Kubernetes. Se você usou tais ferramentas auxiliares e está enfrentando problemas de conectividade, certifique-se de que as configurações necessárias ainda estão presentes.
Verificar configuração do kubectl para detalhes de autenticação:
kubectl config view
Se você usou anteriormente uma ferramenta auxiliar (por exemplo, kubectl-oidc-login), certifique-se de que ela ainda esteja
instalada e configurada corretamente.
Para escalonar uma aplicação e fornecer um serviço confiável, você precisa entender como a aplicação se comporta quando é implantada. Você pode examinar o desempenho da aplicação em um cluster Kubernetes examinando os contêineres, pods, services, e as características do cluster geral. O Kubernetes fornece informações detalhadas sobre o uso de recursos de uma aplicação em cada um desses níveis. Essas informações permitem que você avalie o desempenho da sua aplicação e onde os gargalos podem ser removidos para melhorar o desempenho geral.
No Kubernetes, o monitoramento de aplicações não depende de uma única solução de monitoramento. Em clusters novos, você pode usar pipelines de métricas de recursos ou métricas completas para coletar estatísticas de monitoramento.
O pipeline de métricas de recursos fornece um conjunto limitado de métricas relacionadas aos
componentes do cluster, como o controlador
Horizontal Pod Autoscaler,
bem como o utilitário kubectl top.
Essas métricas são coletadas pelo
metrics-server leve, de curto prazo e em memória,
e são expostas via API metrics.k8s.io.
O metrics-server descobre todos os nós no cluster e
consulta o kubelet de cada nó para
uso de CPU e memória. O kubelet atua como uma ponte entre a camada de gerenciamento do Kubernetes e
os nós de carga de trabalho, gerenciando os pods e contêineres executando em uma máquina. O kubelet
traduz cada pod em seus contêineres integrantes e busca estatísticas de uso
de contêineres individuais do agente de execução de contêiner através da interface do agente
de execução de contêiner. Se você usa um agente de execução de contêiner que utiliza cgroups e
namespaces do Linux para implementar contêineres, e o agente de execução de contêiner não publica
estatísticas de uso, então o kubelet pode consultar essas estatísticas diretamente
(usando código do cAdvisor).
Não importa como essas estatísticas chegam, o kubelet então expõe as estatísticas agregadas de
uso de recursos do pod através da API de Métricas de Recursos do metrics-server.
Esta API é servida em /metrics/resource/v1beta1 nas portas autenticadas e
somente leitura do kubelet.
Um pipeline de métricas completas oferece acesso a métricas mais ricas. O Kubernetes pode
responder a essas métricas automaticamente escalonando ou adaptando o cluster
baseado no seu estado atual, usando mecanismos como o Horizontal Pod
Autoscaler. O pipeline de monitoramento busca métricas do kubelet e
então as expõe ao Kubernetes através de um adaptador que implemente a API
custom.metrics.k8s.io ou external.metrics.k8s.io.
O Kubernetes é projetado para funcionar com OpenMetrics, que é um dos Projetos de Monitoramento CNCF de Observabilidade e Análise, construído sobre e estendendo cuidadosamente o formato de exposição do Prometheus de maneiras quase 100% retrocompatíveis.
Se você der uma olhada no CNCF Landscape, você pode ver vários projetos de monitoramento que podem funcionar com o Kubernetes coletando dados de métricas e usando isso para ajudá-lo a observar seu cluster. Cabe a você selecionar a ferramenta ou ferramentas que atendam às suas necessidades. O landscape da CNCF para observabilidade e análise inclui uma mistura de software de código aberto, software-como-serviço pago e outros produtos comerciais.
Quando você projeta e implementa um pipeline de métricas completas, você pode tornar esses dados de monitoramento disponíveis de volta ao Kubernetes. Por exemplo, um HorizontalPodAutoscaler pode usar as métricas processadas para determinar quantos Pods executar para um componente da sua carga de trabalho.
A integração de um pipeline de métricas completas na sua implementação do Kubernetes está fora do escopo da documentação do Kubernetes devido ao escopo muito amplo de possíveis soluções.
A escolha da plataforma de monitoramento depende fortemente das suas necessidades, orçamento e recursos técnicos. O Kubernetes não recomenda nenhum pipeline de métricas específico; muitas opções estão disponíveis. Seu sistema de monitoramento deve ser capaz de lidar com o padrão de transmissão de métricas OpenMetrics e precisa ser escolhido para se adequar melhor ao design geral e implantação da sua plataforma de infraestrutura.
Aprenda sobre ferramentas adicionais de depuração, incluindo:
execPara o Kubernetes, a API de Métricas oferece um conjunto básico de métricas para dar suporte ao escalonamento automático e casos de uso similares. Esta API disponibiliza informações sobre o uso de recursos para nó e pod, incluindo métricas para CPU e memória. Se você implantar a API de Métricas em seu cluster, os clientes da API do Kubernetes podem então consultar essas informações, e você pode usar os mecanismos de controle de acesso do Kubernetes para gerenciar permissões ao fazê-lo.
O HorizontalPodAutoscaler (HPA) e o VerticalPodAutoscaler (VPA) usam dados da API de métricas para ajustar réplicas e recursos de cargas de trabalho para atender à demanda do cliente.
Você também pode visualizar as métricas de recursos usando o comando
kubectl top.
A Figura 1 ilustra a arquitetura do pipeline de métricas de recursos.
Figura 1. Pipeline de Métricas de Recursos
Os componentes da arquitetura, da direita para a esquerda na figura, consistem no seguinte:
cAdvisor: Daemon para coletar, agregar e expor métricas de contêiner incluído no Kubelet.
kubelet: Agente do nó para gerenciar recursos de contêiner.
As métricas de recursos são acessíveis usando os endpoints da API do kubelet /metrics/resource e /stats.
métricas de recursos no nível do nó: API fornecida pelo kubelet para descobrir e recuperar estatísticas resumidas por nó disponíveis através do endpoint /metrics/resource.
metrics-server: Componente complemento do cluster que coleta e agrega métricas de recursos extraídas de cada kubelet. O servidor de API serve a API de Métricas para uso pelo HPA, VPA e pelo comando kubectl top. O Metrics Server é uma implementação de referência da API de Métricas.
API de Métricas: API do Kubernetes que oferece suporte ao acesso à CPU e memória usadas para escalonamento automático de cargas de trabalho. Para fazer isso funcionar em seu cluster, você precisa de um servidor de extensão de API que forneça a API de Métricas.
Kubernetes 1.8 [beta]
O metrics-server implementa a API de Métricas. Esta API permite que você acesse o uso de CPU e memória para os nós e pods em seu cluster. Seu papel principal é fornecer métricas de uso de recursos para os componentes de escalonamento automático do K8s.
Aqui está um exemplo da solicitação da API de Métricas para um nó minikube direcionada através do jq para facilitar
a leitura:
kubectl get --raw "/apis/metrics.k8s.io/v1beta1/nodes/minikube" | jq '.'
Aqui está a mesma chamada para a API usando curl:
curl http://localhost:8080/apis/metrics.k8s.io/v1beta1/nodes/minikube
Resposta de exemplo:
{
"kind": "NodeMetrics",
"apiVersion": "metrics.k8s.io/v1beta1",
"metadata": {
"name": "minikube",
"selfLink": "/apis/metrics.k8s.io/v1beta1/nodes/minikube",
"creationTimestamp": "2022-01-27T18:48:43Z"
},
"timestamp": "2022-01-27T18:48:33Z",
"window": "30s",
"usage": {
"cpu": "487558164n",
"memory": "732212Ki"
}
}
Aqui está um exemplo da solicitação da API de Métricas para um pod kube-scheduler-minikube contido no
namespace kube-system e direcionada através do jq para facilitar a leitura:
kubectl get --raw "/apis/metrics.k8s.io/v1beta1/namespaces/kube-system/pods/kube-scheduler-minikube" | jq '.'
Aqui está a mesma chamada para a API usando curl:
curl http://localhost:8080/apis/metrics.k8s.io/v1beta1/namespaces/kube-system/pods/kube-scheduler-minikube
Resposta de exemplo:
{
"kind": "PodMetrics",
"apiVersion": "metrics.k8s.io/v1beta1",
"metadata": {
"name": "kube-scheduler-minikube",
"namespace": "kube-system",
"selfLink": "/apis/metrics.k8s.io/v1beta1/namespaces/kube-system/pods/kube-scheduler-minikube",
"creationTimestamp": "2022-01-27T19:25:00Z"
},
"timestamp": "2022-01-27T19:24:31Z",
"window": "30s",
"containers": [
{
"name": "kube-scheduler",
"usage": {
"cpu": "9559630n",
"memory": "22244Ki"
}
}
]
}
A API de Métricas é definida no repositório k8s.io/metrics.
Você deve habilitar a camada de agregação de API
e registrar um APIService
para a API metrics.k8s.io.
Para saber mais sobre a API de Métricas, consulte o design da API de métricas de recursos, o repositório do metrics-server e a API de métricas de recursos.
A CPU é reportada como o uso médio do núcleo medido em unidades de cpu. Uma cpu, no Kubernetes, é equivalente a 1 vCPU/Núcleo para provedores de nuvem, e 1 hyper-thread em processadores Intel de servidor dedicado.
Este valor é derivado obtendo uma taxa sobre um contador cumulativo de CPU fornecido pelo kernel (em kernels Linux e Windows). A janela de tempo usada para calcular a CPU é mostrada no campo window na API de Métricas.
Para saber mais sobre como o Kubernetes aloca e mede recursos de CPU, consulte significado da CPU.
A memória é reportada como o conjunto de trabalho, medido em bytes, no instante em que a métrica foi coletada.
Em um mundo ideal, o "conjunto de trabalho" é a quantidade de memória em uso que não pode ser liberada sob pressão de memória. No entanto, o cálculo do conjunto de trabalho varia por sistema operacional do host, e geralmente faz uso pesado de heurísticas para produzir uma estimativa.
O modelo do Kubernetes para o conjunto de trabalho de um contêiner espera que o agente de execução do contêiner conte a memória anônima associada ao contêiner em questão. A métrica do conjunto de trabalho também inclui tipicamente alguma memória em cache (baseada em arquivo), porque o sistema operacional do host nem sempre pode recuperar páginas.
Para saber mais sobre como o Kubernetes aloca e mede recursos de memória, consulte significado da memória.
O metrics-server obtém métricas de recursos dos kubelets e as expõe no servidor de API do Kubernetes
através da API de Métricas para uso pelo HPA e VPA. Você também pode visualizar essas métricas
usando o comando kubectl top.
O metrics-server usa a API do Kubernetes para rastrear nós e pods em seu cluster. O metrics-server consulta cada nó via HTTP para obter métricas. O metrics-server também constrói uma visão interna dos metadados do pod e mantém um cache da integridade do pod. Essa informação de integridade do pod em cache está disponível através da API de extensão que o metrics-server disponibiliza.
Por exemplo, com uma consulta HPA, o metrics-server precisa identificar quais pods atendem aos seletores de rótulos na implantação.
O metrics-server chama a API do kubelet para coletar métricas de cada nó. Dependendo da versão do metrics-server ele usa:
/metrics/resource na versão v0.6.0+ ou/stats/summary em versões mais antigasPara saber mais sobre o metrics-server, consulte o repositório do metrics-server.
Você também pode consultar o seguinte:
Para saber sobre como o kubelet serve métricas do nó e como você pode acessá-las através da API do Kubernetes, leia Dados de Métricas do Nó.
Node Problem Detector é um daemon para monitoramento e relatório sobre a integridade de um nó.
Você pode executar o Node Problem Detector como um DaemonSet ou como um daemon independente.
O Node Problem Detector coleta informações sobre problemas do nó de vários daemons
e relata essas condições para o servidor de API como Condições
do nó ou como Eventos.
Para aprender como instalar e usar o Node Problem Detector, consulte a documentação do projeto Node Problem Detector.
Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
Alguns provedores de nuvem habilitam o Node Problem Detector como um complemento.
Você também pode habilitar o Node Problem Detector com kubectl ou criando um DaemonSet de complemento.
kubectl fornece o gerenciamento mais flexível do Node Problem Detector.
Você pode sobrescrever a configuração padrão para adequá-la ao seu ambiente ou
para detectar problemas personalizados do nó. Por exemplo:
Crie uma configuração do Node Problem Detector similar a node-problem-detector.yaml:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: node-problem-detector-v0.1
namespace: kube-system
labels:
k8s-app: node-problem-detector
version: v0.1
kubernetes.io/cluster-service: "true"
spec:
selector:
matchLabels:
k8s-app: node-problem-detector
version: v0.1
kubernetes.io/cluster-service: "true"
template:
metadata:
labels:
k8s-app: node-problem-detector
version: v0.1
kubernetes.io/cluster-service: "true"
spec:
hostNetwork: true
containers:
- name: node-problem-detector
image: registry.k8s.io/node-problem-detector:v0.1
securityContext:
privileged: true
resources:
limits:
cpu: "200m"
memory: "100Mi"
requests:
cpu: "20m"
memory: "20Mi"
volumeMounts:
- name: log
mountPath: /log
readOnly: true
volumes:
- name: log
hostPath:
path: /var/log/Inicie o Node Problem Detector com kubectl:
kubectl apply -f https://k8s.io/examples/debug/node-problem-detector.yaml
Se você está usando uma solução personalizada de autoinicialização de cluster e não precisa sobrescrever a configuração padrão, você pode aproveitar o pod de complemento para automatizar ainda mais a implantação.
Crie node-problem-detector.yaml e salve a configuração no diretório do pod de complemento
/etc/kubernetes/addons/node-problem-detector em um nó da camada de gerenciamento.
A configuração padrão é incorporada ao construir a imagem do contêiner do Node Problem Detector.
No entanto, você pode usar um ConfigMap
para sobrescrever a configuração:
Altere os arquivos de configuração em config/
Crie o ConfigMap node-problem-detector-config:
kubectl create configmap node-problem-detector-config --from-file=config/
Altere o node-problem-detector.yaml para usar o ConfigMap:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: node-problem-detector-v0.1
namespace: kube-system
labels:
k8s-app: node-problem-detector
version: v0.1
kubernetes.io/cluster-service: "true"
spec:
selector:
matchLabels:
k8s-app: node-problem-detector
version: v0.1
kubernetes.io/cluster-service: "true"
template:
metadata:
labels:
k8s-app: node-problem-detector
version: v0.1
kubernetes.io/cluster-service: "true"
spec:
hostNetwork: true
containers:
- name: node-problem-detector
image: registry.k8s.io/node-problem-detector:v0.1
securityContext:
privileged: true
resources:
limits:
cpu: "200m"
memory: "100Mi"
requests:
cpu: "20m"
memory: "20Mi"
volumeMounts:
- name: log
mountPath: /log
readOnly: true
- name: config # Sobrescreve o diretório config/ com o volume ConfigMap
mountPath: /config
readOnly: true
volumes:
- name: log
hostPath:
path: /var/log/
- name: config # Define o volume ConfigMap
configMap:
name: node-problem-detector-config
Recrie o Node Problem Detector com o novo arquivo de configuração:
# Se você tem um node-problem-detector em execução, exclua antes de recriar
kubectl delete -f https://k8s.io/examples/debug/node-problem-detector.yaml
kubectl apply -f https://k8s.io/examples/debug/node-problem-detector-configmap.yaml
kubectl.Sobrescrever uma configuração não é suportado se um Node Problem Detector executa como um complemento de cluster.
O gerenciador de complementos não suporta ConfigMap.
Um daemon de problema é um sub-daemon do Node Problem Detector. Ele monitora tipos específicos de problemas do nó e os relata para o Node Problem Detector. Existem vários tipos de daemons de problema suportados.
Um daemon do tipo SystemLogMonitor monitora os logs do sistema e relata problemas e métricas
de acordo com regras predefinidas. Você pode personalizar as configurações para diferentes fontes de log
como filelog,
kmsg,
kernel,
abrt,
e systemd.
Um daemon do tipo SystemStatsMonitor coleta várias estatísticas do sistema relacionadas à integridade como métricas.
Você pode personalizar seu comportamento atualizando seu
arquivo de configuração.
Um daemon do tipo CustomPluginMonitor invoca e verifica vários problemas do nó executando
scripts definidos pelo usuário. Você pode usar diferentes monitores de plugin personalizados para monitorar diferentes
problemas e personalizar o comportamento do daemon atualizando o
arquivo de configuração.
Um daemon do tipo HealthChecker verifica a integridade do kubelet e do agente de execução de contêiner em um nó.
O monitor de log do sistema atualmente suporta logs baseados em arquivo, journald e kmsg. Fontes adicionais podem ser adicionadas implementando um novo observador de log.
Você pode estender o Node Problem Detector para executar qualquer script de monitor escrito em qualquer linguagem desenvolvendo um plugin personalizado. Os scripts de monitor devem estar em conformidade com o protocolo do plugin no código de saída e saída padrão. Para mais informações, consulte a proposta de interface de plugin.
Um exportador relata os problemas do nó e/ou métricas para determinados backends. Os seguintes exportadores são suportados:
Kubernetes exporter: este exportador relata problemas do nó para o servidor de API do Kubernetes. Problemas temporários são relatados como Events e problemas permanentes são relatados como Node Conditions.
Prometheus exporter: este exportador relata problemas do nó e métricas localmente como métricas Prometheus (ou OpenMetrics). Você pode especificar o endereço IP e porta para o exportador usando argumentos de linha de comando.
Stackdriver exporter: este exportador relata problemas do nó e métricas para a API de Monitoramento do Stackdriver. O comportamento de exportação pode ser personalizado usando um arquivo de configuração.
É recomendado executar o Node Problem Detector em seu cluster para monitorar a integridade do nó. Ao executar o Node Problem Detector, você pode esperar sobrecarga adicional de recursos em cada nó. Geralmente isso é aceitável, porque:
O Painel é uma interface de usuário web para o Kubernetes. Através do Painel, você pode implantar aplicações conteinerizadas em um cluster Kubernetes, solucionar problemas em suas aplicações e gerenciar os recursos do cluster.
O Painel oferece uma visão geral das aplicações em execução no seu cluster, além de permitir a criação ou modificação de recursos individuais do Kubernetes (como Deployments, Jobs, DaemonSets, etc.). Por exemplo, você pode escalar um Deployment, iniciar uma atualização contínua (rolling update), reiniciar um pod ou implantar novas aplicações utilizando um assistente de implantação.
O Painel também fornece informações sobre o estado dos recursos do Kubernetes em seu cluster e sobre quaisquer erros que possam ter ocorrido.

A interface de usuário do Painel não é implantada por padrão. Para implantá-la, execute o seguinte comando:
# Adicionando o repositório do kubernetes-dashboard
helm repo add kubernetes-dashboard https://kubernetes.github.io/dashboard/
# Instale o "kubernetes-dashboard" usando helm chart
helm upgrade --install kubernetes-dashboard kubernetes-dashboard/kubernetes-dashboard --create-namespace --namespace kubernetes-dashboard
Para proteger os dados do seu cluster, o Painel é implantado com uma configuração RBAC mínima por padrão. Atualmente, o Painel oferece suporte apenas ao login com um Bearer Token. Para criar um token para esta demonstração, você pode seguir nosso guia de criação de um usuário de exemplo.
Acesse o nosso guia sobre criação de um usuário de exemplo para gerar um token de acesso.
Você pode habilitar o acesso ao Painel usando a ferramenta de linha de comando kubectl,
executando o seguinte comando:
kubectl proxy
O kubectl disponibilizará o Painel em http://localhost:8443/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/.
O acesso à interface é restrito à máquina onde o comando é executado. Consulte kubectl proxy --help para mais opções.
Ao acessar o Painel em um cluster vazio, você verá a página de boas-vindas. Esta página contém um link para este documento, bem como um botão para implantar sua primeira aplicação.
Além disso, você pode visualizar quais aplicações do sistema estão em execução por padrão no namespace kube-system
namespace do seu cluster, como o próprio Painel do Kubernetes.

O Painel permite criar e implantar uma aplicação conteinerizada como um Deployment e um Service opcional através de um assistente simples. Você pode especificar os detalhes da aplicação manualmente ou carregar um arquivo de manifesto em YAML ou JSON contendo a configuração da aplicação.
Clique no botão CRIAR no canto superior direito de qualquer página para iniciar.
O assistente de implantação espera que você forneça as seguintes informações:
O nome da aplicação deve ser único dentro do namespace do Kubernetes selecionado. Ele deve começar com uma letra minúscula, terminar com uma letra minúscula ou um número e conter apenas letras minúsculas, números e hífens (-). O limite é de 24 caracteres. Espaços à esquerda e à direita são ignorados.
Imagem do contêiner (obrigatório): A URL pública de uma imagem de contêiner Docker em qualquer registro de imagens público ou uma imagem privada (comumente hospedada no Google Container Registry ou Docker Hub). A especificação da imagem do container deve terminar com dois pontos (:).
Número de pods (obrigatório): O número desejado de Pods nos quais você deseja que sua aplicação implantada. O valor deve ser um número inteiro positivo.
Um Deployment será criado para manter o número desejado de Pods em seu cluster.
Service (opcional): Para algumas partes da sua aplicação (por exemplo, frontends), você pode querer expor um Service em um endereço de IP externo, possivelmente público, fora do seu cluster (external Service).
Outros Services que são visíveis apenas de dentro do cluster são chamados de Services internos.
Independentemente do tipo de Service, se você optar por criá-lo e seu contêiner escutar em uma porta (entrada), será necessário especificar duas portas. O Serviço será criado mapeando a porta (entrada) para a porta de destino vista pelo contêiner. Este Service direcionará o tráfego para seus Pods implantados. Os protocolos suportados são TCP e UDP. O nome de DNS interno para este Service será o valor especificado como nome da aplicação acima.
Se necessário, você pode expandir a seção Opções avançadas onde você pode especificar mais configurações:
Descrição: O texto inserido aqui será adicionado como uma annotation ao Deployment e exibido nos detalhes da aplicação.
Labels: Por padrão as labels usadas para sua aplicação são o nome e a versão da aplicação. Você pode especificar labels adicionais para serem aplicadas ao Deployment, ao Service (se houver) e aos Pods, como release, tier, environment e track.
Exemplo:
release=1.0
tier=frontend
environment=pod
track=stable
Namespace: O Kubernetes suporta múltiplos clusters virtuais apoiados pelo mesmo cluster físico. Esses clusters virtuais são chamados de namespaces. Eles permitem que você particione os recursos em grupos logicamente nomeados.
O Dashboard oferece todos os namespaces disponíveis em uma lista suspensa e permite que você crie um novo namespace. O nome do namespace pode conter no máximo 63 caracteres alfanuméricos e hífens (-), mas não pode conter letras maiúsculas. Os nomes dos namespaces não devem consistir apenas de números. Se o nome for definido como um número, como 10, o pod será colocado no namespace padrão.
Caso a criação do namespace seja bem-sucedida, ele será selecionado por padrão. Se a criação falhar, o primeiro namespace será selecionado.
Image Pull Secret: Caso a imagem do contêiner Docker especificada seja privada, pode ser necessário fornecer credenciais de pull secret.
O Dashboard oferece todos as secrets disponíveis em uma lista suspensa e permite que você crie uma nova secret.
O nome da secret deve seguir a sintaxe do nome de domínio DNS, por exemplo new.image-pull.secret.
The content of a secret must be base64-encoded and specified in a
O conteúdo de uma secret deve ser codificado em base64 e especificado em um arquivo
.dockercfg.
O nome da secret pode consistir em no máximo 253 caracteres.
Caso a criação da secret de pull de imagem seja bem-sucedida, ele será selecionado por padrão. Se a criação falhar, nenhuma secret será aplicada.
CPU requirement (cores) and Memory requirement (MiB): Você pode especificar os resource limits para o contêiner. Por padrão, os Pods são executados com limits de CPU e memória ilimitados.
Run command and Run command arguments: Por padrão, seus contêiners executam a imagem Docker especificada por padrão entrypoint command. Você pode usar as opções e argumentos de comando para substituir o padrão.
Run as privileged: Esta configuração determina se os processos em privileged containers são equivalentes a processos executados como root no host. Contêiners privilegiados podem fazer uso de capacidades como manipular stack de rede e acessar dispositivos.
Environment variables: O Kubernetes expõe Services por meio
de environment variables.
Você pode compor variáveis de ambiente ou passar argumentos para seus comandos usando os valores das variáveis de ambiente.
Eles podem ser usados em aplicativos para encontrar um Service.
Os valores podem referenciar outras variáveis usando a sintaxe $(VAR_NAME).
O Kubernetes suporta configuração declarativa. Nesse estilo, toda a configuração é armazenada em manifestos (arquivos de configuração YAML ou JSON). Os manifestos utilizam os esquemas de recursos da API do Kubernetes.
Como alternativa à especificação dos detalhes da aplicação no assistente de implantação, você pode definir sua aplicação em um ou mais manifestos e fazer o upload dos arquivos usando o Dashboard.
As seções a seguir descrevem as visualizações da interface do Kubernetes Dashboard; o que elas fornecem e como podem ser usadas.
Quando há objetos do Kubernetes definidos no cluster, o Dashboard os exibe na visualização inicial. Por padrão, apenas objetos do namespace default são exibidos e isso pode ser alterado usando o seletor de namespace localizado no menu de navegação.
O Dashboard exibe a maioria dos tipos de objetos do Kubernetes e os agrupa em algumas categorias de menu.
Para administradores de cluster e namespace, o Dashboard lista Nodes, Namespaces e PersistentVolumes e possui visualizações detalhadas para eles. A visualização da lista de Nodes contém métricas de uso de CPU e memória agregadas em todos os Nodes. A visualização de detalhes mostra as métricas de um Node, sua especificação, status, recursos alocados, eventos e pods em execução no node.
Mostra todas as aplicações em execução no namespace selecionado. A visualização lista as aplicações por tipo de workload (por exemplo: Deployments, ReplicaSets, StatefulSets). Cada tipo de workload pode ser visualizado separadamente. As listas resumem informações acionáveis sobre os workloads, como o número de pods ready para um ReplicaSet ou o uso de memória atual para um Pod.
As visualizações detalhadas dos workloads mostram informações de status e especificação e revelam as relações entre objetos. Por exemplo, Pods que um ReplicaSet está controlando ou novos ReplicaSets e HorizontalPodAutoscalers para Deployments.
Exibe recursos do Kubernetes que permitem expor services para o mundo externo e descobri-los dentro de um cluster. Por essa razão, as visualizações de Service e Ingress mostram os Pods direcionados por eles, endpoints internos para conexões de cluster e endpoints externos para usuários externos.
A visualização de armazenamento exibe recursos PersistentVolumeClaim que são usados por aplicações para armazenar dados.
Exibe todos os recursos do Kubernetes que são usados para a configuração ao vivo de aplicações em execução em clusters. A visualização permite editar e gerenciar objetos de configuração e exibe secrets ocultos por padrão.
Listas de Pods e páginas de detalhes vinculam a um visualizador de logs integrado ao Dashboard. O visualizador permite explorar logs de contêiners pertencentes a um único Pod.

Para mais informações, veja a página do projeto Kubernetes Dashboard.
Esse tópico fala sobre diversas maneiras de interagir com clusters.
Se estiver acessando o Kubernetes API pela primeira vez, recomendamos usar a CLI do Kubernetes, kubectl.
Para acessar um cluster, você precisa saber a localização do cluster e ter credenciais para acessá-lo. Geralmente, isso é configurado automaticamente quando você trabalha com um Guia de instalação ou outra pessoa configurou o cluster e forneceu a você credenciais e uma localização.
Verifique o local e as credenciais que o kubectl conhece com esse comando:
kubectl config view
Muitos dos exemplos fornecem uma introdução ao uso do kubectl e a documentação completa pode ser encontrada no guia de referência do kubectl.
O Kubectl lida com a localização e a autenticação no servidor de API. Se você quiser acessar diretamente a API REST com um cliente http como curl ou wget, ou um navegador, há várias maneiras de localizar e autenticar:
O comando a seguir executa o kubectl em um modo em que ele atua como um proxy reverso. Ele lida com localização do apiserver e da autenticação. Execute-o desta forma:
kubectl proxy --port=8080
Consulte kubectl proxy para obter mais detalhes.
Em seguida, você pode explorar a API com curl, wget ou um navegador, substituindo localhost por [::1] para IPv6, da seguinte forma:
curl http://localhost:8080/api/
O resultado é semelhante a este:
{
"kind": "APIVersions",
"versions": [
"v1"
],
"serverAddressByClientCIDRs": [
{
"clientCIDR": "0.0.0.0/0",
"serverAddress": "10.0.1.149:443"
}
]
}
Use kubectl apply e kubectl describe secret... para criar um token para a conta de serviço padrão com grep/cut:
Primeiro, crie o Secret, solicitando um token para a ServiceAccount padrão:
kubectl apply -f - <<EOF
apiVersion: v1
kind: Secret
metadata:
name: default-token
annotations:
kubernetes.io/service-account.name: default
type: kubernetes.io/service-account-token
EOF
Em seguida, aguarde até que o controlador de token preencha o Secret com um token:
while ! kubectl describe secret default-token | grep -E '^token' >/dev/null; do
echo "waiting for token..." >&2
sleep 1
done
Recupere e use o token gerado:
APISERVER=$(kubectl config view --minify | grep server | cut -f 2- -d ":" | tr -d " ")
TOKEN=$(kubectl describe secret default-token | grep -E '^token' | cut -f2 -d':' | tr -d " ")
curl $APISERVER/api --header "Authorization: Bearer $TOKEN" --insecure
O resultado é semelhante a este:
{
"kind": "APIVersions",
"versions": [
"v1"
],
"serverAddressByClientCIDRs": [
{
"clientCIDR": "0.0.0.0/0",
"serverAddress": "10.0.1.149:443"
}
]
}
Usando jsonpath:
APISERVER=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')
TOKEN=$(kubectl get secret default-token -o jsonpath='{.data.token}' | base64 --decode)
curl $APISERVER/api --header "Authorization: Bearer $TOKEN" --insecure
O resultado é semelhante a este:
{
"kind": "APIVersions",
"versions": [
"v1"
],
"serverAddressByClientCIDRs": [
{
"clientCIDR": "0.0.0.0/0",
"serverAddress": "10.0.1.149:443"
}
]
}
Os exemplos acima usam a opção --insecure. Isso deixa o cluster sujeito a ataques MITM.
Quando o kubectl acessa o cluster, ele usa um certificado raiz guardado
e certificados de cliente para acessar o servidor. (Esses certificados são instalados no diretório
~/.kube). Como os certificados do cluster normalmente são autoassinados, pode ser necessária uma
configuração especial para que seu cliente http use o certificado raiz.
Em alguns clusters, o servidor da API não requer autenticação; ele pode servir
no localhost ou estar protegido por um firewall. Não há um padrão
para isso. A página Controlando Acesso à API do Kubernetes
descreve como um administrador de cluster pode configurar isso.
O Kubernetes suporta oficialmente as bibliotecas de clientes Go e Python.
go get k8s.io/client-go@kubernetes-<kubernetes-version-number>,
consulte INSTALL.md
para obter instruções detalhadas de instalação. Consulte
https://github.com/kubernetes/client-go
para ver quais versões são compatíveis.import "k8s.io/client-go/kubernetes" está correto.O cliente Go pode usar o mesmo arquivo kubeconfig como a CLI do kubectl faz, para localizar e autenticar ao apiserver. Veja esse exemplo.
Se o aplicativo for disponibilizado como um pod no cluster, consulte a próxima seção.
Para usar o cliente Python, execute o seguinte comando:
pip install kubernetes. Consulte a página Python Client Library
para obter mais opções de instalação.
O cliente Python pode usar o mesmo arquivo kubeconfig que a ferramenta kubectl utiliza para localizar e autenticar ao servidor da API. Veja esse exemplo.
Existem bibliotecas de clientes para acessar a API utilizando outras linguagens. Consulte a documentação de outras bibliotecas para saber como elas se autenticam.
Ao acessar a API a partir de um pod, a localização e a autenticação para o servidor de API são um pouco diferentes.
Consulte Acessando a API a partir de um pod para obter mais detalhes.
A seção anterior descreve como se conectar ao servidor da API do Kubernetes. Para obter informações sobre como se conectar a outros serviços em execução em um cluster do Kubernetes, consulte Acessando serviços em execução em clusters.
Os recursos de redirecionamento foram descontinuados e removidos. Em vez disso, use um proxy (veja abaixo).
Há vários proxies diferentes que você pode encontrar ao usar o Kubernetes:
O kube proxy:
Um Proxy/balanceador de carga na frente do(s) servidor(es) da API:
Balanceadores de carga de provedor de nuvem em serviços externos:
LoadBalancerNormalmente, os usuários do Kubernetes não precisam se preocupar com nada além dos dois primeiros tipos. O administrador do cluster normalmente garantirá que os últimos tipos sejam configurados corretamente.
Esta página mostra como configurar o acesso a vários clusters usando arquivos de configuração. Depois que os clusters, os usuários e os contextos forem definidos em um ou mais arquivos de configuração, você pode alternar rapidamente entre os clusters usando o comando kubectl config use-context.
kubeconfig.Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
Para verificar se kubectl está instalado,
execute kubectl version --client. A versão do kubectl deve ter no máximo uma versão menor de diferença da versão do servidor de API do seu cluster.
Suponha que você tenha dois clusters, um para o trabalho de desenvolvimento, chamado development, e outro para o trabalho de teste, chamado test.
No cluster development, seus desenvolvedores de front-end trabalham em um namespace chamado frontend,
e os desenvolvedores de armazenamento trabalham em um namespace chamado storage. Em seu cluster test,
os desenvolvedores trabalham no namespace padrão ou criam namespaces auxiliares conforme
acharem adequado. O acesso ao cluster de desenvolvimento requer autenticação por certificado. O acesso
ao cluster de teste requer autenticação por nome de usuário e senha.
Crie um diretório chamado config-exercise. Em seu diretório
config-exercise, crie um arquivo chamado config-demo com este conteúdo:
apiVersion: v1
kind: Config
preferences: {}
clusters:
- cluster:
name: development
- cluster:
name: test
users:
- name: developer
- name: experimenter
contexts:
- context:
name: dev-frontend
- context:
name: dev-storage
- context:
name: exp-test
Um arquivo de configuração descreve clusters, usuários e contextos. Seu arquivo config-demo
tem a estrutura para descrever dois clusters, dois usuários e três contextos.
Vá para o diretório config-exercise. Digite estes comandos para adicionar detalhes do cluster ao
seu arquivo de configuração:
kubectl config --kubeconfig=config-demo set-cluster development --server=https://1.2.3.4 --certificate-authority=fake-ca-file
kubectl config --kubeconfig=config-demo set-cluster test --server=https://5.6.7.8 --insecure-skip-tls-verify
Adicione detalhes do usuário ao seu arquivo de configuração:
kubectl config --kubeconfig=config-demo set-credentials developer --client-certificate=fake-cert-file --client-key=fake-key-seefile
kubectl config --kubeconfig=config-demo set-credentials experimenter --username=exp --password=some-password
kubectl --kubeconfig=config-demo config unset users.<name>kubectl --kubeconfig=config-demo config unset clusters.<name>kubectl --kubeconfig=config-demo config unset contexts.<name>Adicione detalhes de contexto ao seu arquivo de configuração:
kubectl config --kubeconfig=config-demo set-context dev-frontend --cluster=development --namespace=frontend --user=developer
kubectl config --kubeconfig=config-demo set-context dev-storage --cluster=development --namespace=storage --user=developer
kubectl config --kubeconfig=config-demo set-context exp-test --cluster=test --namespace=default --user=experimenter
Abra seu arquivo config-demo para ver os detalhes adicionados. Como alternativa para abrir o arquivo config-demo, você pode usar o comando config view
kubectl config --kubeconfig=config-demo view
O resultado mostra os dois clusters, dois usuários e três contextos:
apiVersion: v1
clusters:
- cluster:
certificate-authority: fake-ca-file
server: https://1.2.3.4
name: development
- cluster:
insecure-skip-tls-verify: true
server: https://5.6.7.8
name: test
contexts:
- context:
cluster: development
namespace: frontend
user: developer
name: dev-frontend
- context:
cluster: development
namespace: storage
user: developer
name: dev-storage
- context:
cluster: test
namespace: default
user: experimenter
name: exp-test
current-context: ""
kind: Config
preferences: {}
users:
- name: developer
user:
client-certificate: fake-cert-file
client-key: fake-key-file
- name: experimenter
user:
# Nota de documentação (este comentário NÃO faz parte da saída do comando).
# Armazenar senhas na configuração do cliente Kubernetes é arriscado.
# Uma alternativa melhor seria usar um plugin de credenciais
# e armazenar as credenciais separadamente.
# Veja https://kubernetes.io/pt-br/docs/reference/access-authn-authz/authentication/#plugins-de-credenciais-client-go
password: some-password
username: exp
O fake-ca-file, o fake-cert-file e o fake-key-file acima são os espaços reservados
para a localização dos arquivos de certificado. Você precisa alterá-los para a localização real
dos arquivos de certificado em seu ambiente.
Às vezes, você pode querer usar dados codificados em Base64 incorporados aqui, em vez de arquivos de certificado separados.
Nesse caso, é necessário adicionar o sufixo data às chaves, por exemplo,
certificate-authority-data, client-certificate-data, client-key-data.
Cada contexto é uma tripla (cluster, usuário, namespace). Por exemplo, o contexto
dev-frontend diz: "Use as credenciais do usuário developer
para acessar o namespace frontend do cluster development".
Define o contexto atual:
kubectl config --kubeconfig=config-demo use-context dev-frontend
Agora, sempre que você use um comando kubectl, a ação será aplicada ao cluster,
e ao namespace listados no contexto dev-frontend. E o comando usará
as credenciais do usuário listado no contexto dev-frontend.
Para ver apenas as informações de configuração associadas ao
o contexto atual, use a opção --minify.
kubectl config --kubeconfig=config-demo view --minify
O resultado mostra as informações de configuração associadas ao contexto dev-frontend:
apiVersion: v1
clusters:
- cluster:
certificate-authority: fake-ca-file
server: https://1.2.3.4
name: development
contexts:
- context:
cluster: development
namespace: frontend
user: developer
name: dev-frontend
current-context: dev-frontend
kind: Config
preferences: {}
users:
- name: developer
user:
client-certificate: fake-cert-file
client-key: fake-key-file
Agora, suponha que você queira trabalhar por um tempo no cluster de teste.
Altere o contexto atual para exp-test:
kubectl config --kubeconfig=config-demo use-context exp-test
Agora, qualquer comando kubectl que você usar, será aplicado ao namespace padrão do cluster test. E o comando usará as credenciais do usuário
listado no contexto exp-test.
Ver a configuração associada ao novo contexto atual, exp-test.
kubectl config --kubeconfig=config-demo view --minify
Por fim, suponha que você queira trabalhar por um tempo no namespace storage do cluster development.
Altere o contexto atual para dev-storage:
kubectl config --kubeconfig=config-demo use-context dev-storage
Ver a configuração associada ao novo contexto atual, dev-storage.
kubectl config --kubeconfig=config-demo view --minify
Em seu diretório config-exercise, crie um arquivo chamado config-demo-2 com este conteúdo:
apiVersion: v1
kind: Config
preferences: {}
contexts:
- context:
cluster: development
namespace: ramp
user: developer
name: dev-ramp-up
O arquivo de configuração anterior define um novo contexto chamado dev-ramp-up.
Verifique se você tem uma variável de ambiente chamada KUBECONFIG. Em caso afirmativo, salve o valor atual da variável de ambiente KUBECONFIG para que você possa restaurá-lo posteriormente.
Por exemplo:
export KUBECONFIG_SAVED="$KUBECONFIG"
$Env:KUBECONFIG_SAVED=$ENV:KUBECONFIG
A variável de ambiente KUBECONFIG é uma lista de caminhos para arquivos de configuração. A lista é
delimitada por dois pontos para Linux e Mac, e delimitada por ponto e vírgula para Windows. Se você tiver
uma variável de ambiente KUBECONFIG, familiarize-se com os arquivos de configuração
na lista.
Anexe temporariamente duas localizações à sua variável de ambiente KUBECONFIG. Por exemplo:
export KUBECONFIG="${KUBECONFIG}:config-demo:config-demo-2"
$Env:KUBECONFIG=("config-demo;config-demo-2")
Em seu diretório config-exercise, digite este comando:
kubectl config view
O resultado mostra informações mescladas de todos os arquivos listados em sua variável de ambiente KUBECONFIG. Em particular, observe que as informações mescladas têm o contexto dev-ramp-up do arquivo config-demo-2 e os três contextos do arquivo config-demo:
contexts:
- context:
cluster: development
namespace: frontend
user: developer
name: dev-frontend
- context:
cluster: development
namespace: ramp
user: developer
name: dev-ramp-up
- context:
cluster: development
namespace: storage
user: developer
name: dev-storage
- context:
cluster: test
namespace: default
user: experimenter
name: exp-test
Para obter mais informações sobre como os arquivos kubeconfig são mesclados, consulte Organizando o acesso ao cluster usando arquivos kubeconfig
Se você já tiver um cluster e puder usar o kubectl para interagir com o
o cluster, então provavelmente você tem um arquivo chamado config no diretório $HOME/.kube.
Vá para $HOME/.kube e veja quais arquivos estão lá. Normalmente, há um arquivo chamado
config. Também pode haver outros arquivos de configuração nesse diretório. Em um breve momento
familiarize-se com o conteúdo desses arquivos.
Se você tiver um arquivo $HOME/.kube/config e ele ainda não estiver listado em sua variável de ambiente
KUBECONFIG, acrescente-o à sua variável de ambiente KUBECONFIG agora.
Por exemplo:
export KUBECONFIG="${KUBECONFIG}:${HOME}/.kube/config"
$Env:KUBECONFIG="$Env:KUBECONFIG;$HOME\.kube\config"
Visualize as informações de configuração mescladas de todos os arquivos que agora estão listados
em sua variável de ambiente KUBECONFIG. Em seu diretório config-exercise, digite:
kubectl config view
Retorne sua variável de ambiente KUBECONFIG ao seu valor original. Por exemplo:
export KUBECONFIG="$KUBECONFIG_SAVED"
$Env:KUBECONFIG=$ENV:KUBECONFIG_SAVED
Nem sempre é óbvio quais atributos (nome de usuário, grupos) você obterá após a autenticação no cluster. Isso pode ser ainda mais desafiador se você estiver gerenciando mais de um cluster ao mesmo tempo.
Há um subcomando de kubectl para verificar os atributos do sujeito, como o nome de usuário, para o Kubernetes contexto selecionado: kubectl auth whoami.
Leia Acesso da API às informações de autenticação de um cliente para saber mais sobre isso em detalhes.
Esta página mostra como usar o kubectl port-forward para se conectar a um servidor MongoDB em execução em um cluster Kubernetes. Esse tipo de conexão pode ser útil para depuração de bancos de dados.
Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
O seu servidor Kubernetes deve estar numa versão igual ou superior a v1.10.Para verificar a versão, digite kubectl version.
Crie uma Implantação que execute o MongoDB:
kubectl apply -f https://k8s.io/examples/application/mongodb/mongo-deployment.yaml
A saída de um comando bem-sucedido verifica que a implantação foi criada:
deployment.apps/mongo criado
Visualize o status do pod para verificar se ele está pronto:
kubectl get pods
A saída exibe o pod criado:
NAME READY STATUS RESTARTS AGE
mongo-75f59d57f4-4nd6q 1/1 Em execução 0 2m4s
Visualize o status da implantação:
kubectl get deployment
A saída exibe que a implantação foi criada:
NAME READY UP-TO-DATE AVAILABLE AGE
mongo 1/1 1 1 2m21s
A implantação gerencia automaticamente um conjunto de réplicas. Visualize o status do conjunto de réplicas usando:
kubectl get replicaset
Visualize o status do conjunto de réplicas usando:
NAME DESIRED CURRENT READY AGE
mongo-75f59d57f4 1 1 1 3m12s
Crie um serviço para expor o MongoDB na rede:
kubectl apply -f https://k8s.io/examples/application/mongodb/mongo-service.yaml
A saída de um comando bem-sucedido verifica que o serviço foi criado:
service/mongo criado
Verifique o serviço criado::
kubectl get service mongo
A saída exibe o serviço criado:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
mongo ClusterIP 10.96.41.183 <none> 27017/TCP 11s
Verifique se o servidor MongoDB está sendo executado no Pod e ouvindo a porta 27017:
# Altere mongo-75f59d57f4-4nd6q para o nome do Pod
kubectl get pod mongo-75f59d57f4-4nd6q --template='{{(index (index .spec.containers 0).ports 0).containerPort}}{{"\n"}}'
A saída exibe a porta para o MongoDB nesse Pod:
27017
27017 é a porta TCP alocada ao MongoDB na internet.
kubectl port-forward permite usar o nome do recurso, como o nome do pod, para selecionar um pod correspondente para encaminhar a porta.
# Altere mongo-75f59d57f4-4nd6q para o nome do Pod
kubectl port-forward mongo-75f59d57f4-4nd6q 28015:27017
que é o mesmo que
kubectl port-forward pods/mongo-75f59d57f4-4nd6q 28015:27017
ou
kubectl port-forward deployment/mongo 28015:27017
ou
kubectl port-forward replicaset/mongo-75f59d57f4 28015:27017
ou
kubectl port-forward service/mongo 28015:27017
Qualquer um dos comandos acima funciona. A saída é semelhante a esta:
Encaminhamento de 127.0.0.1:28015 -> 27017
Encaminhamento de [::1]:28015 -> 27017
kubectl port-forward não retorna. Para continuar com os exercícios, você precisará abrir outro terminal.Inicie a interface de linha de comando do MongoDB:
mongosh --port 28015
No prompt de comando do MongoDB, digite o comando ping:
db.runCommand( { ping: 1 } )
Uma solicitação de ping bem-sucedida retorna:
{ ok: 1 }
Se você não precisa de uma porta local específica, pode permitir que o kubectl escolha e reserve a porta local e, assim, evitar ter que gerenciar conflitos de porta local, com a sintaxe ligeiramente mais simples:
kubectl port-forward deployment/mongo :27017
A ferramenta kubectl encontra um número de porta local que não está em uso (evitando números de porta baixos, porque esses podem ser usados por outras aplicações). A saída é semelhante a:
Encaminhamento de 127.0.0.1:63753 -> 27017
Encaminhamento de [::1]:63753 -> 27017
As conexões feitas à porta local 28015 são encaminhadas para a porta 27017 do Pod que está executando o servidor MongoDB. Com esta conexão em vigor, você pode usar seu local de trabalho para depurar o banco de dados que está sendo executado no Pod.
kubectl port-forward é implementado apenas para portas TCP.
O suporte ao protocolo UDP é rastreado em
issue 47862.Saiba mais sobre kubectl port-forward.
Esta tarefa mostra como criar um microserviço frontend e um microserviço backend. O microserviço backend é um serviço que envia uma mensagem de saudação. O frontend expõe o backend usando o nginx e um objeto Service do Kubernetes.
hello usando um objeto Deployment.Service) para enviar tráfego para as várias réplicas do microserviço de backend.nginx, também usando um objeto Deployment.Service do tipo LoadBalancer para expor o microserviço de frontend fora do cluster.Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
Para verificar a versão, digite kubectl version.
Esta tarefa utiliza Serviços com balanceadores de carga externos, que necessitam de um ambiente suportado. Se o seu ambiente não suportar isso, você pode substituir por um serviço do tipo NodePort.
O backend é um microserviço simples de saudação. Aqui está o arquivo de configuração para o Deployment do backend:
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend
spec:
selector:
matchLabels:
app: hello
tier: backend
track: stable
replicas: 3
template:
metadata:
labels:
app: hello
tier: backend
track: stable
spec:
containers:
- name: hello
image: "gcr.io/google-samples/hello-go-gke:1.0"
ports:
- name: http
containerPort: 80
...
Crie o Deployment do backend:
kubectl apply -f https://k8s.io/examples/service/access/backend-deployment.yaml
Veja informações sobre o Deployment do backend:
kubectl describe deployment backend
A saída é semelhante a esta:
Name: backend
Namespace: default
CreationTimestamp: Mon, 24 Oct 2016 14:21:02 -0700
Labels: app=hello
tier=backend
track=stable
Annotations: deployment.kubernetes.io/revision=1
Selector: app=hello,tier=backend,track=stable
Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 1 max unavailable, 1 max surge
Pod Template:
Labels: app=hello
tier=backend
track=stable
Containers:
hello:
Image: "gcr.io/google-samples/hello-go-gke:1.0"
Port: 80/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: hello-3621623197 (3/3 replicas created)
Events:
...
helloA chave para enviar solicitações do frontend para o backend é o Service do backend. Um Service cria um endereço IP persistente e uma entrada de nome DNS, para que o microserviço do backend possa ser sempre acessado. Um Service usa seletores para encontrar os Pods para os quais ele roteia o tráfego.
Primeiro, explore o arquivo de configuração do Service:
---
apiVersion: v1
kind: Service
metadata:
name: hello
spec:
selector:
app: hello
tier: backend
ports:
- protocol: TCP
port: 80
targetPort: http
...
No arquivo de configuração, você pode ver que o Service, chamado de hello, roteia o tráfego para Pods que possuem as labels app: hello e tier: backend.
Crie o Service para o backend:
kubectl apply -f https://k8s.io/examples/service/access/backend-service.yaml
Neste ponto, você possui um Deployment chamado backend executando três réplicas do seu aplicativo hello e possui um Service que pode rotear o tráfego para eles. No entanto, esse serviço ainda não pode ser acessado ou resolvido fora do cluster.
Agora que o seu backend está em execução, você pode criar um frontend que seja acessível fora do cluster e se conecte ao backend por meio de solicitações de proxy.
O frontend envia solicitações para os worker Pods do backend usando o nome DNS fornecido ao Serviço do backend. O nome DNS é hello, que é o valor do campo name no arquivo de configuração examples/service/access/backend-service.yaml.
Os Pods no Deployment do frontend executam uma imagem nginx que é configurada para fazer proxy de solicitações para o Serviço de backend hello. Aqui está o arquivo de configuração nginx:
# The identifier Backend is internal to nginx, and used to name this specific upstream
upstream Backend {
# hello is the internal DNS name used by the backend Service inside Kubernetes
server hello;
}
server {
listen 80;
location / {
# The following statement will proxy traffic to the upstream named Backend
proxy_pass http://Backend;
}
}
Similarmente ao backend, o frontend possui um Deployment e um Service. Uma diferença importante a ser notada entre os serviços de backend e frontend é que a configuração do serviço de frontend tem o parâmetro type: LoadBalancer, o que significa que o serviço usa um balanceador de carga fornecido pelo provedor de nuvem e será acessível de fora do cluster.
---
apiVersion: v1
kind: Service
metadata:
name: frontend
spec:
selector:
app: hello
tier: frontend
ports:
- protocol: "TCP"
port: 80
targetPort: 80
type: LoadBalancer
...
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
spec:
selector:
matchLabels:
app: hello
tier: frontend
track: stable
replicas: 1
template:
metadata:
labels:
app: hello
tier: frontend
track: stable
spec:
containers:
- name: nginx
image: "gcr.io/google-samples/hello-frontend:1.0"
lifecycle:
preStop:
exec:
command: ["/usr/sbin/nginx","-s","quit"]
...
Crie o Deployment e o Service para o frontend:
kubectl apply -f https://k8s.io/examples/service/access/frontend-deployment.yaml
kubectl apply -f https://k8s.io/examples/service/access/frontend-service.yaml
A saída mostra que ambos os recursos foram criados:
deployment.apps/frontend created
service/frontend created
Service frontendDepois de criar um Service do tipo LoadBalancer, você pode usar este comando para encontrar o IP externo:
kubectl get service frontend --watch
Isso exibe a configuração do Service frontend e fica monitorando por mudanças. Inicialmente, o IP externo é exibido como <pending>:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
frontend LoadBalancer 10.51.252.116 <pending> 80/TCP 10s
Assim que um IP externo é provisionado, a configuração é atualizada para incluir o novo IP na seção EXTERNAL-IP:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
frontend LoadBalancer 10.51.252.116 XXX.XXX.XXX.XXX 80/TCP 1m
Esse IP agora pode ser usado para interagir com o serviço frontend de fora do cluster.
Agora que o frontend e o backend estão conectados, você pode acessar o endpoint usando o comando curl no IP externo do seu serviço frontend:
curl http://${EXTERNAL_IP} # substitua isto pelo `EXTERNAL-IP` que você viu antes
A saída mostra a mensagem gerada pelo backend:
{"message":"Hello"}
Para excluir os Services, digite este comando:
kubectl delete services frontend backend
Para excluir os Deployments, ReplicaSets e `Pods que estão executando as aplicações frontend e backend, digite este comando:
kubectl delete deployment frontend backend
ServicesConfigMapsServices e PodsEsta página mostra como criar um balanceador de carga externo para um service em execução em um cluster Kubernetes.
Criando um Service, você tem a opção de criar automaticamente um balanceador de carga em nuvem. Isso fornece um endereço IP acessível externamente que envia tráfego para a porta correta nos nós do seu cluster, desde que seu cluster seja executado em um ambiente suportado e esteja configurado com o pacote do provedor de balanceador de carga em nuvem correto.
Você também pode usar um Ingress no lugar de Service.
Para obter mais informações, verifique a documentação do Ingress.
Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
Seu cluster deve estar em execução em uma nuvem ou em outro ambiente que já tenha suporte para configurar balanceadores de carga externos.
Para criar um balanceador de carga externo, adicione a seguinte linha ao manifesto do service:
type: LoadBalancer
Seu manifesto pode se parecer com:
apiVersion: v1
kind: Service
metadata:
name: example-service
spec:
selector:
app: example
ports:
- port: 8765
targetPort: 9376
type: LoadBalancer
Como alternativa, você pode criar o service com o comando kubectl expose e a flag --type=LoadBalancer:
kubectl expose deployment example --port=8765 --target-port=9376 \
--name=example-service --type=LoadBalancer
Esse comando cria um novo service usando os mesmos seletores do recurso referenciado (no caso do exemplo acima, um
Deployment chamado example).
Para obter mais informações, incluindo flags opcionais, consulte a referência do comando kubectl expose reference.
Você pode encontrar o endereço IP criado para o seu service obtendo as informações do service por meio do kubectl:
kubectl describe services example-service
que devem produzir resultados semelhantes a:
Name: example-service
Namespace: default
Labels: app=example
Annotations: <none>
Selector: app=example
Type: LoadBalancer
IP Families: <none>
IP: 10.3.22.96
IPs: 10.3.22.96
LoadBalancer Ingress: 192.0.2.89
Port: <unset> 8765/TCP
TargetPort: 9376/TCP
NodePort: <unset> 30593/TCP
Endpoints: 172.17.0.3:9376
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
O endereço IP do balanceador de carga é listado ao lado de LoadBalancer Ingress.
Se você estiver executando seu service no Minikube, poderá encontrar o endereço IP e a porta designados com:
minikube service example-service --url
Por padrão, o IP de origem visto no contêiner de destino não é o IP de origem original do cliente. Para permitir a preservação do IP do cliente, os seguintes
campos podem ser configurados no .spec do Service:
.spec.externalTrafficPolicy - indica se este Service deseja rotear o tráfego externo para endpoints locais do nó ou em todo o cluster. Existem duas opções disponíveis: Cluster (padrão) e Local. Cluster oculta o IP de origem do cliente e pode causar um segundo salto para outro nó, mas deve ter uma boa distribuição geral de carga. Local preserva o IP de origem do cliente e evita um segundo salto para Service do tipo LoadBalancer e NodePort, mas corre o risco de uma distribuição de tráfego potencialmente desequilibrada.
.spec.healthCheckNodePort - especifica a porta de verificação de integridade
(número de porta numérico) para o service. Se você não especificar
healthCheckNodePort, o controlador de service alocará uma porta do intervalo NodePort do seu cluster.
Você pode configurar esse intervalo definindo uma opção de linha de comando do servidor de API,
--service-node-port-range. O Service usará o valor healthCheckNodePort especificado pelo usuário, se você o especificar, desde que o tipo do Service esteja definido como LoadBalancer e externalTrafficPolicy esteja definido como Local.
A definição externalTrafficPolicy: Local no manifesto do Service ativa esse recurso. Por exemplo:
apiVersion: v1
kind: Service
metadata:
name: example-service
spec:
selector:
app: example
ports:
- port: 8765
targetPort: 9376
externalTrafficPolicy: Local
type: LoadBalancer
Os service de balanceamento de carga de alguns provedores de nuvem não permitem configurar pesos diferentes para cada destino.
Como cada destino recebe o mesmo peso no balanceamento de tráfego para os Nós, o tráfego externo não é distribuído igualmente entre os Pods. Isso ocorre porque o balanceador de carga externo não considera o número de Pods por Nó.
Quando NumServicePods << NumNodes ou NumServicePods >> NumNodes, uma distribuição relativamente próxima da igualdade será observada, mesmo sem pesos.
O tráfego interno Pod-a-Pod deve apresentar um comportamento similar aos services ClusterIP, com a mesma probabilidade entre todos os Pods.
Kubernetes v1.17 [stable]
Em um caso normal, ao excluir um Service do tipo LoadBalancer, os recursos de balanceamento de carga no provedor de nuvem são automaticamente removidos. Porém, existem casos onde esses recursos permanecem ativos, mesmo após a exclusão do Service. Para resolver esse problema, foi introduzida a Proteção por Finalizadores para LoadBalancers de Service. Essa proteção utiliza finalizadores, que são mecanismos que impedem a exclusão de um Serviço até que os recursos de balanceamento de carga associados também sejam removidos.
Para Service do tipo LoadBalancer, o controlador de service utiliza um finalizador chamado service.kubernetes.io/load-balancer-cleanup. Esse finalizador funciona como um mecanismo de segurança, impedindo a exclusão do Service até que o recurso de balanceamento de carga associado seja removido. Essa medida evita a existência de recursos de balanceamento de carga órfãos, mesmo em situações inesperadas, como a falha do controlador de service.
É importante ressaltar que o roteamento e distribuição do tráfego para essa funcionalidade são realizados por um balanceador de carga que não faz parte do cluster Kubernetes.
Quando um Serviço é configurado como LoadBalancer, o Kubernetes garante o acesso interno aos pods do Serviço (como no tipo ClusterIP) e também integra o Serviço com um balanceador de carga externo. A camada de gerenciamento do Kubernetes é responsável por criar o balanceador de carga externo no provedor de nuvem, configurar as verificações de integridade (quando necessárias) e as regras de filtragem de pacotes (quando necessárias). Assim que o provedor de nuvem aloca um endereço IP ao balanceador de carga, a camada de gerenciamento o adiciona ao objeto de Serviço, tornando-o acessível externamente.
Esta página mostra como usar o kubectl para listar todas as imagens de contêineres dos Pods em execução no cluster.
Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
Para verificar a versão, digite kubectl version.
Neste exercício, você usará o kubectl para buscar todos os Pods em execução no cluster e formatar a saída com uma lista dos contêineres por imagem.
kubectl get pods --all-namespaces-o jsonpath={.items[*].spec['initContainers', 'containers'][*].image}.
Isso irá analisar recursivamente o campo image do JSON retornado.
tr, sort, uniq
tr para substituir espaços por quebras de linhasort para ordenar os resultadosuniq para agregar a contagem de imagenskubectl get pods --all-namespaces -o jsonpath="{.items[*].spec['initContainers', 'containers'][*].image}" |\
tr -s '[[:space:]]' '\n' |\
sort |\
uniq -c
O jsonpath é interpretado da seguinte forma:
.items[*]: para cada valor retornado.spec: coleta a especificação do recurso informado['initContainers', 'containers'][*]: para cada contêiner.image: coleta o nome da imagemkubectl get pod nginx,
a parte .items[*] do caminho deve ser omitida porque um único Pod é retornado
e não uma lista de itens.O formato de saída pode ser controlado ainda mais usando a operação range para
iterar sobre os elementos individualmente.
kubectl get pods --all-namespaces -o jsonpath='{range .items[*]}{"\n"}{.metadata.name}{":\t"}{range .spec.containers[*]}{.image}{", "}{end}{end}' |\
sort
Para selecionar apenas os Pods que correspondem a um label específico, use a flag -l.
O comando a seguir seleciona apenas os Pods com o label app=nginx.
kubectl get pods --all-namespaces -o jsonpath="{.items[*].spec.containers[*].image}" -l app=nginx
Para selecionar apenas os Pods de um namespace específico, use a flag namespace.
O comando a seguir seleciona apenas os Pods no namespace kube-system.
kubectl get pods --namespace kube-system -o jsonpath="{.items[*].spec.containers[*].image}"
Como alternativa ao jsonpath, o kubectl suporta o uso de go-templates para formatar a saída:
kubectl get pods --all-namespaces -o go-template --template="{{range .items}}{{range .spec.containers}}{{.image}} {{end}}{{end}}"
Esta página mostra como usar um Volume para realizar a comunicação entre dois contêineres rodando no mesmo Pod. Veja também como permitir que processos se comuniquem por compartilhamento de namespace do processo entre os contêineres.
Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
Para verificar a versão, digite kubectl version.
Neste exercício, você cria um Pod que executa dois contêineres. Os dois contêineres compartilham um volume que eles podem usar para se comunicar. Aqui está o arquivo de configuração para o Pod:
apiVersion: v1
kind: Pod
metadata:
name: two-containers
spec:
restartPolicy: Never
volumes:
- name: shared-data
emptyDir: {}
containers:
- name: nginx-container
image: nginx
volumeMounts:
- name: shared-data
mountPath: /usr/share/nginx/html
- name: debian-container
image: debian
volumeMounts:
- name: shared-data
mountPath: /pod-data
command: ["/bin/sh"]
args: ["-c", "echo Hello from the debian container > /pod-data/index.html"]
No arquivo de configuração, você pode ver que o Pod tem um shared-data chamado
shared-data.
O primeiro contêiner listado no arquivo de configuração executa um servidor nginx.
O caminho de montagem para o volume compartilhado é /usr/share/nginx/html.
O segundo contêiner é baseado na imagem debian e tem um caminho de montagem
/pod-data. O segundo contêiner executa o seguinte comando e é encerrado.
echo Hello from the debian container > /pod-data/index.html
Observe que o segundo contêiner grava o arquivo index.html no diretório raiz do servidor nginx.
Crie o Pod e os dois contêineres:
kubectl apply -f https://k8s.io/examples/pods/two-container-pod.yaml
Veja as informações sobre o Pod e os contêineres:
kubectl get pod two-containers --output=yaml
Aqui está uma parte da saída:
apiVersion: v1
kind: Pod
metadata:
...
name: two-containers
namespace: default
...
spec:
...
containerStatuses:
- containerID: docker://c1d8abd1 ...
image: debian
...
lastState:
terminated:
...
name: debian-container
...
- containerID: docker://96c1ff2c5bb ...
image: nginx
...
name: nginx-container
...
state:
running:
...
Você pode ver que o contêiner debian foi encerrado e o contêiner nginx ainda está em execução.
Obtenha um shell para o contêiner nginx:
kubectl exec -it two-containers -c nginx-container -- /bin/bash
Em seu shell, verifique que o nginx está em execução:
root@two-containers:/# apt-get update
root@two-containers:/# apt-get install curl procps
root@two-containers:/# ps aux
A saída é semelhante a esta:
USER PID ... STAT START TIME COMMAND
root 1 ... Ss 21:12 0:00 nginx: master process nginx -g daemon off;
Lembre-se de que o contêiner debian criou o arquivo index.html no diretório raiz do nginx.
Use curl para enviar uma solicitação GET para o servidor nginx:
root@two-containers:/# curl localhost
A saída mostra que o nginx responde com uma página da web escrita pelo contêiner debian:
Hello from the debian container
O principal motivo pelo qual os pods podem ter vários contêineres é oferecer suporte a aplicações extras que apoiam uma aplicação principal. Exemplos típicos de aplicativos auxiliares são extratores de dados, aplicações para envio de dados e proxies. Aplicativos auxiliares e primários geralmente precisam se comunicar uns com os outros. Normalmente, isso é feito por meio de um sistema de arquivos compartilhado, conforme mostrado neste exercício, ou por meio da interface de rede de loopback, localhost. Um exemplo desse padrão é um servidor web junto com um programa auxiliar que consulta um repositório Git para novas atualizações.
O volume neste exercício fornece uma maneira dos contêineres se comunicarem durante a vida útil do Pod. Se o Pod for excluído e recriado, todos os dados armazenados no volume compartilhado serão perdidos.
Saiba mais sobre padrões para contêineres compostos.
Saiba sobre contêineres compostos para arquitetura modular.
Veja Configurando um Pod para usar um volume para armazenamento.
Veja Configurar um Pod para compartilhar namespace de processo entre contêineres em um Pod
Veja Volume.
Veja Pod.
O Kubernetes oferece um complemento de DNS para os clusters, que a maioria dos ambientes suportados habilitam por padrão. Na versão do Kubernetes 1.11 e posterior, o CoreDNS é recomendado e instalado por padrão com o kubeadm.
Para mais informações sobre como configurar o CoreDNS para um cluster Kubernetes, veja Personalização do Serviço de DNS. Para ver um exemplo que demonstra como usar o DNS do Kubernetes com o kube-dns, consulte Plugin de exemplo para DNS.
Esta página mostra como se conectar aos serviços em execução no cluster Kubernetes.
Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
Para verificar a versão, digite kubectl version.
No Kubernetes, todos nós, Pods e serviços têm seus próprios IPs. Em muitos casos, os IPs dos nós, dos Pods e alguns dos IPs de serviço em um cluster não serão roteáveis, portanto, não estarão acessíveis a partir de uma máquina fora do cluster, como seu computador.
Você tem várias opções para se conectar a nós, Pods e serviços de fora do cluster:
NodePort ou LoadBalancer para tornar o serviço acessível fora do cluster. Consulte a documentação de serviços e
kubectl expose.Normalmente, existem vários serviços que são iniciados em um cluster pelo kube-system. Obtenha uma lista desses serviços com o comando kubectl cluster-info:
kubectl cluster-info
A saída é semelhante a esta:
Kubernetes master is running at https://192.0.2.1
elasticsearch-logging is running at https://192.0.2.1/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy
kibana-logging is running at https://192.0.2.1/api/v1/namespaces/kube-system/services/kibana-logging/proxy
kube-dns is running at https://192.0.2.1/api/v1/namespaces/kube-system/services/kube-dns/proxy
grafana is running at https://192.0.2.1/api/v1/namespaces/kube-system/services/monitoring-grafana/proxy
heapster is running at https://192.0.2.1/api/v1/namespaces/kube-system/services/monitoring-heapster/proxy
Isso mostra a URL referente ao verbo proxy para acessar cada serviço. Por exemplo, este cluster tem os logs a nível de cluster habilitados (usando o Elasticsearch), que pode ser acessado em https://192.0.2.1/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/ se as credenciais adequadas forem passadas ou através do comando kubectl proxy, como por exemplo: http://localhost:8080/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/.
Como mencionado acima, você usa o comando kubectl cluster-info para recuperar a URL do proxy do serviço. Para criar URLs de proxy que incluem endpoints, sufixos e parâmetros de serviço, você adiciona à URL do proxy do serviço:
http://endereço_do_mestre_do_kubernetes/api/v1/namespaces/nome_do_namespace/services/[https:]nome_do_serviço[:nome_da_porta]/proxy
Se você não especificou um nome para a porta, não é necessário especificar nome_da_porta na URL. Você também pode usar o número da porta no lugar do nome_da_porta para portas nomeadas e não nomeadas.
Por padrão, o servidor da API usa um proxy para o seu serviço através de HTTP. Para usar HTTPS, adicione o prefixo https: ao nome do serviço:
http://<endereço_do_mestre_do_kubernetes>/api/v1/namespaces/<nome_do_namespace>/services/<nome_do_serviço>/proxy
Os formatos suportados para o segmento <nome_do_serviço> da URL são:
<nome_do_serviço> - usa um proxy para a porta padrão ou não nomeada usando http<nome_do_serviço>:<nome_da_porta> - usa um proxy para a porta nomeada ou número da porta especificado usando httphttps:<nome_do_serviço>: - usa um proxy para a porta padrão ou não nomeada usando https (observe o dois-pontos no final)https:<nome_do_serviço>:<nome_da_porta> - usa um proxy para a porta nomeada ou número da porta especificado usando httpsPara acessar o endpoint de serviço Elasticsearch _search?q=user:kimchy, você usaria:
http://192.0.2.1/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/_search?q=user:kimchy
Para acessar as informações de integridade do cluster Elasticsearch _cluster/health?pretty=true, você usaria:
https://192.0.2.1/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/_cluster/health?pretty=true
As informações de integridade são semelhantes a estas:
{
"cluster_name" : "kubernetes_logging",
"status" : "yellow",
"timed_out" : false,
"number_of_nodes" : 1,
"number_of_data_nodes" : 1,
"active_primary_shards" : 5,
"active_shards" : 5,
"relocating_shards" : 0,
"initializing_shards" : 0,
"unassigned_shards" : 5
}
Para acessar as informações de integridade do serviço Elasticsearch _cluster/health?pretty=true, você usaria:
https://192.0.2.1/api/v1/namespaces/kube-system/services/https:elasticsearch-logging:/proxy/_cluster/health?pretty=true
Você pode conseguir de colocar um URL de proxy do servidor da API na barra de endereço de um navegador. No entanto:
Esta página mostra como executar uma aplicação usando um objeto Deployment do Kubernetes.
Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
O seu servidor Kubernetes deve estar numa versão igual ou superior a v1.9.Para verificar a versão, digite kubectl version.
Você pode executar uma aplicação criando um objeto Deployment do Kubernetes, e pode descrever um Deployment em um arquivo YAML. Por exemplo, este arquivo YAML descreve um Deployment que executa a imagem do contêiner nginx:1.14.2:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2 # diz ao deployment para executar 2 pods que correspondam ao modelo
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
Crie um Deployment com base no arquivo YAML:
kubectl apply -f https://k8s.io/examples/application/deployment.yaml
Exiba informações sobre o Deployment:
kubectl describe deployment nginx-deployment
A saída é semelhante a esta:
Name: nginx-deployment
Namespace: default
CreationTimestamp: Tue, 30 Aug 2016 18:11:37 -0700
Labels: app=nginx
Annotations: deployment.kubernetes.io/revision=1
Selector: app=nginx
Replicas: 2 desired | 2 updated | 2 total | 2 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 1 max unavailable, 1 max surge
Pod Template:
Labels: app=nginx
Containers:
nginx:
Image: nginx:1.14.2
Port: 80/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: nginx-deployment-1771418926 (2/2 replicas created)
No events.
Liste os Pods criados pelo Deployment:
kubectl get pods -l app=nginx
A saída é semelhante a esta:
NAME READY STATUS RESTARTS AGE
nginx-deployment-1771418926-7o5ns 1/1 Running 0 16h
nginx-deployment-1771418926-r18az 1/1 Running 0 16h
Exiba informações sobre um Pod:
kubectl describe pod <pod-name>
onde <pod-name> é o nome de um dos seus Pods.
Você pode atualizar o Deployment aplicando um novo arquivo YAML. Este arquivo YAML especifica que o Deployment deve ser atualizado para usar o nginx:1.16.1.
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.16.1 # Atualiza a versão do nginx de 1.14.2 para 1.16.1
ports:
- containerPort: 80
Aplique o novo arquivo YAML:
kubectl apply -f https://k8s.io/examples/application/deployment-update.yaml
Observe o Deployment criar Pods com novos nomes e excluir os Pods antigos:
kubectl get pods -l app=nginx
Você pode aumentar o número de Pods no seu Deployment aplicando um novo arquivo YAML. Este arquivo YAML define replicas como 4, o que especifica que o Deployment deve ter quatro Pods:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 4 # Atualiza a contagem de réplicas de 2 para 4
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.16.1
ports:
- containerPort: 80
Aplique o novo arquivo YAML:
kubectl apply -f https://k8s.io/examples/application/deployment-scale.yaml
Verifique que o Deployment possui quatro Pods:
kubectl get pods -l app=nginx
A saída é semelhante a esta:
NAME READY STATUS RESTARTS AGE
nginx-deployment-148880595-4zdqq 1/1 Running 0 25s
nginx-deployment-148880595-6zgi1 1/1 Running 0 25s
nginx-deployment-148880595-fxcez 1/1 Running 0 2m
nginx-deployment-148880595-rwovn 1/1 Running 0 2m
Exclua o Deployment pelo nome:
kubectl delete deployment nginx-deployment
A forma preferida de criar uma aplicação replicada é usar um Deployment, que por sua vez utiliza um ReplicaSet. Antes do Deployment e do ReplicaSet serem adicionados ao Kubernetes, aplicações replicadas eram configuradas usando um Controlador de Replicação (ReplicationController).
Esta página mostra como executar um aplicativo com estado e de instância única no Kubernetes utilizando um PersistentVolume e um Deployment. O aplicativo utilizado é o MySQL.
Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
Para verificar a versão, digite kubectl version.
Você precisa ter um provisionador dinâmico de PersistentVolume com uma StorageClass padrão, ou provisionar PersistentVolumes estaticamente por conta própria para atender aos PersistentVolumeClaims utilizados aqui.
Você pode executar um aplicativo com estado criando um Deployment do Kubernetes e conectando-o a um PersistentVolume existente usando um PersistentVolumeClaim. Por exemplo, este arquivo YAML descreve um Deployment que executa o MySQL e faz referência ao PersistentVolumeClaim. O arquivo define um volume mount para /var/lib/mysql e, em seguida, cria um PersistentVolumeClaim que procura por um volume de 20G. Essa requisição é atendida por qualquer volume existente que atenda aos requisitos ou por um provisionador dinâmico.
Note: A senha é definida no arquivo de configuração yaml, e isso não é seguro. Veja Secrets do Kubernetes para uma solução segura.
apiVersion: v1
kind: Service
metadata:
name: mysql
spec:
ports:
- port: 3306
selector:
app: mysql
clusterIP: None
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql
spec:
selector:
matchLabels:
app: mysql
strategy:
type: Recreate
template:
metadata:
labels:
app: mysql
spec:
containers:
- image: mysql:9
name: mysql
env:
# Em cenários reais, utilize um Secret
- name: MYSQL_ROOT_PASSWORD
value: password
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-persistent-storage
persistentVolumeClaim:
claimName: mysql-pv-claim
apiVersion: v1
kind: PersistentVolume
metadata:
name: mysql-pv-volume
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 20Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/mnt/data"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pv-claim
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
Faça o deploy do PV e do PVC do arquivo YAML:
kubectl apply -f https://k8s.io/examples/application/mysql/mysql-pv.yaml
Faça o deploy do conteúdo do arquivo YAML:
kubectl apply -f https://k8s.io/examples/application/mysql/mysql-deployment.yaml
Exiba informações sobre o Deployment:
kubectl describe deployment mysql
A saída é semelhante a esta:
Name: mysql
Namespace: default
CreationTimestamp: Tue, 01 Nov 2016 11:18:45 -0700
Labels: app=mysql
Annotations: deployment.kubernetes.io/revision=1
Selector: app=mysql
Replicas: 1 desired | 1 updated | 1 total | 0 available | 1 unavailable
StrategyType: Recreate
MinReadySeconds: 0
Pod Template:
Labels: app=mysql
Containers:
mysql:
Image: mysql:9
Port: 3306/TCP
Environment:
MYSQL_ROOT_PASSWORD: password
Mounts:
/var/lib/mysql from mysql-persistent-storage (rw)
Volumes:
mysql-persistent-storage:
Type: PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
ClaimName: mysql-pv-claim
ReadOnly: false
Conditions:
Type Status Reason
---- ------ ------
Available False MinimumReplicasUnavailable
Progressing True ReplicaSetUpdated
OldReplicaSets: <none>
NewReplicaSet: mysql-63082529 (1/1 replicas created)
Events:
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
33s 33s 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set mysql-63082529 to 1
Liste os pods criados pelo Deployment:
kubectl get pods -l app=mysql
A saída é semelhante a esta:
NAME READY STATUS RESTARTS AGE
mysql-63082529-2z3ki 1/1 Running 0 3m
Inspecione o PersistentVolumeClaim:
kubectl describe pvc mysql-pv-claim
A saída é semelhante a esta:
Name: mysql-pv-claim
Namespace: default
StorageClass:
Status: Bound
Volume: mysql-pv-volume
Labels: <none>
Annotations: pv.kubernetes.io/bind-completed=yes
pv.kubernetes.io/bound-by-controller=yes
Capacity: 20Gi
Access Modes: RWO
Events: <none>
O arquivo YAML anterior cria um Service que permite que outros Pods no cluster acessem o banco de dados. A opção clusterIP: None faz com que o nome DNS do Service resolva diretamente para o endereço IP do Pod. Isso é ideal quando você tem apenas um Pod por trás do Service e não pretende aumentar o número de Pods.
Execute um cliente MySQL para se conectar ao servidor:
kubectl run -it --rm --image=mysql:9 --restart=Never mysql-client -- mysql -h mysql -ppassword
Este comando cria um novo Pod no cluster executando um cliente MySQL e o conecta ao servidor por meio do Service. Se a conexão for bem-sucedida, você saberá que seu banco de dados MySQL com estado está em funcionamento.
Waiting for pod default/mysql-client-274442439-zyp6i to be running, status is Pending, pod ready: false
If you don't see a command prompt, try pressing enter.
mysql>
A imagem ou qualquer outra parte do Deployment pode ser atualizada normalmente
com o comando kubectl apply. Aqui estão algumas precauções específicas para aplicativos com estado:
strategy: type: Recreate no arquivo YAML de configuração do Deployment.
Isso instrui o Kubernetes a não usar atualizações graduais. Atualizações graduais não funcionarão, pois não é possível ter mais de um Pod em execução ao mesmo tempo. A estratégia Recreate irá parar o primeiro Pod antes de criar um novo com a configuração atualizada.Exclua os objetos implantados pelo nome:
kubectl delete deployment,svc mysql
kubectl delete pvc mysql-pv-claim
kubectl delete pv mysql-pv-volume
Se você provisionou manualmente um PersistentVolume, também precisará excluí-lo manualmente, assim como liberar o recurso subjacente. Se você usou um provisionador dinâmico, ele exclui automaticamente o PersistentVolume ao detectar que você excluiu o PersistentVolumeClaim. Alguns provisionadores dinâmicos (como os de EBS e PD) também liberam o recurso subjacente ao excluir o PersistentVolume.
Saiba mais sobre objetos Deployment.
Saiba mais sobre implantação de aplicativos
Esta página mostra como executar uma aplicação com estado e replicada usando um StatefulSet. Esta aplicação é um banco de dados MySQL replicado. A topologia de exemplo possui um único servidor primário e múltiplas réplicas, utilizando replicação assíncrona baseada em linhas.
Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
Você precisa ter um provisionador dinâmico de PersistentVolume com uma StorageClass padrão, ou provisionar PersistentVolumes estaticamente por conta própria para atender aos PersistentVolumeClaims utilizados aqui.
A instalação de exemplo do MySQL consiste em um ConfigMap, dois Services e um StatefulSet.
Crie o ConfigMap a partir do seguinte arquivo de configuração YAML:
apiVersion: v1
kind: ConfigMap
metadata:
name: mysql
labels:
app: mysql
app.kubernetes.io/name: mysql
data:
primary.cnf: |
# Aplique esta configuração apenas no primário.
[mysqld]
log-bin
replica.cnf: |
# Aplique esta configuração apenas nas réplicas.
[mysqld]
super-read-only
kubectl apply -f https://k8s.io/examples/application/mysql/mysql-configmap.yaml
Este ConfigMap fornece substituições para o my.cnf que permitem controlar independentemente
a configuração no servidor MySQL primário e em suas réplicas.
Neste caso, você deseja que o servidor primário possa disponibilizar logs de replicação para as réplicas
e que as réplicas rejeitem qualquer escrita que não venha por meio da replicação.
Não há nada de especial no próprio ConfigMap que faça com que diferentes partes sejam aplicadas a diferentes Pods. Cada Pod decide qual parte utilizar durante sua inicialização, com base nas informações fornecidas pelo controlador StatefulSet.
Crie os Services a partir do seguinte arquivo de configuração YAML:
# Service headless para entradas DNS estáveis dos membros do StatefulSet.
apiVersion: v1
kind: Service
metadata:
name: mysql
labels:
app: mysql
app.kubernetes.io/name: mysql
spec:
ports:
- name: mysql
port: 3306
clusterIP: None
selector:
app: mysql
---
# Client service para conectar a qualquer instância MySQL para leituras.
# Para escritas, é necessário conectar-se ao primário: mysql-0.mysql.
apiVersion: v1
kind: Service
metadata:
name: mysql-read
labels:
app: mysql
app.kubernetes.io/name: mysql
readonly: "true"
spec:
ports:
- name: mysql
port: 3306
selector:
app: mysql
kubectl apply -f https://k8s.io/examples/application/mysql/mysql-services.yaml
O Service headless fornece um local para as entradas de DNS que o
controlador do StatefulSet cria para cada
Pod que faz parte do conjunto.
Como o Service headless se chama mysql, os Pods são acessíveis por meio da resolução de <nome-do-pod>.mysql
a partir de qualquer outro Pod no mesmo cluster e namespace do Kubernetes.
O Service de cliente, chamado mysql-read, é um Service normal com seu próprio IP de cluster,
que distribui as conexões entre todos os Pods MySQL que estejam prontos (Ready).
O conjunto de endpoints potenciais inclui o servidor MySQL primário e todas as réplicas.
Observe que apenas consultas de leitura podem utilizar o Service de cliente com balanceamento de carga. Como existe apenas um servidor MySQL primário, os clientes devem se conectar diretamente ao Pod MySQL primário (por meio de sua entrada DNS no Service headless) para executar operações de escrita.
Por fim, crie o StatefulSet a partir do seguinte arquivo de configuração YAML:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
selector:
matchLabels:
app: mysql
app.kubernetes.io/name: mysql
serviceName: mysql
replicas: 3
template:
metadata:
labels:
app: mysql
app.kubernetes.io/name: mysql
spec:
initContainers:
- name: init-mysql
image: mysql:5.7
command:
- bash
- "-c"
- |
set -ex
# Gerar o server-id do MySQL a partir do índice ordinal do pod.
[[ $HOSTNAME =~ -([0-9]+)$ ]] || exit 1
ordinal=${BASH_REMATCH[1]}
echo [mysqld] > /mnt/conf.d/server-id.cnf
# Adicione um deslocamento (offset) para evitar o valor reservado server-id=0.
echo server-id=$((100 + $ordinal)) >> /mnt/conf.d/server-id.cnf
# Copie os arquivos conf.d apropriados do config-map para o emptyDir.
if [[ $ordinal -eq 0 ]]; then
cp /mnt/config-map/primary.cnf /mnt/conf.d/
else
cp /mnt/config-map/replica.cnf /mnt/conf.d/
fi
volumeMounts:
- name: conf
mountPath: /mnt/conf.d
- name: config-map
mountPath: /mnt/config-map
- name: clone-mysql
image: gcr.io/google-samples/xtrabackup:1.0
command:
- bash
- "-c"
- |
set -ex
# Pule a clonagem se os dados já existirem.
[[ -d /var/lib/mysql/mysql ]] && exit 0
# Pule a clonagem no primário (índice ordinal 0).
[[ `hostname` =~ -([0-9]+)$ ]] || exit 1
ordinal=${BASH_REMATCH[1]}
[[ $ordinal -eq 0 ]] && exit 0
# Clone os dados do peer anterior.
ncat --recv-only mysql-$(($ordinal-1)).mysql 3307 | xbstream -x -C /var/lib/mysql
# Prepare o backup.
xtrabackup --prepare --target-dir=/var/lib/mysql
volumeMounts:
- name: data
mountPath: /var/lib/mysql
subPath: mysql
- name: conf
mountPath: /etc/mysql/conf.d
containers:
- name: mysql
image: mysql:5.7
env:
- name: MYSQL_ALLOW_EMPTY_PASSWORD
value: "1"
ports:
- name: mysql
containerPort: 3306
volumeMounts:
- name: data
mountPath: /var/lib/mysql
subPath: mysql
- name: conf
mountPath: /etc/mysql/conf.d
resources:
requests:
cpu: 500m
memory: 1Gi
livenessProbe:
exec:
command: ["mysqladmin", "ping"]
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
readinessProbe:
exec:
# Verifique se é possível executar consultas via TCP (skip-networking está desativado).
command: ["mysql", "-h", "127.0.0.1", "-e", "SELECT 1"]
initialDelaySeconds: 5
periodSeconds: 2
timeoutSeconds: 1
- name: xtrabackup
image: gcr.io/google-samples/xtrabackup:1.0
ports:
- name: xtrabackup
containerPort: 3307
command:
- bash
- "-c"
- |
set -ex
cd /var/lib/mysql
# Determine a posição do binlog dos dados clonados, se houver.
if [[ -f xtrabackup_slave_info && "x$(<xtrabackup_slave_info)" != "x" ]]; then
# O XtraBackup já gerou uma consulta "CHANGE MASTER TO" parcial
# porque estamos clonando de uma réplica existente. (É necessário remover o ponto e vírgula final!)
cat xtrabackup_slave_info | sed -E 's/;$//g' > change_master_to.sql.in
# Ignore o xtrabackup_binlog_info neste caso (não é útil).
rm -f xtrabackup_slave_info xtrabackup_binlog_info
elif [[ -f xtrabackup_binlog_info ]]; then
# Estamos clonando diretamente do primário. Interprete a posição do binlog.
[[ `cat xtrabackup_binlog_info` =~ ^(.*?)[[:space:]]+(.*?)$ ]] || exit 1
rm -f xtrabackup_binlog_info xtrabackup_slave_info
echo "CHANGE MASTER TO MASTER_LOG_FILE='${BASH_REMATCH[1]}',\
MASTER_LOG_POS=${BASH_REMATCH[2]}" > change_master_to.sql.in
fi
# Verifique se é necessário completar a clonagem iniciando a replicação.
if [[ -f change_master_to.sql.in ]]; then
echo "Waiting for mysqld to be ready (accepting connections)"
until mysql -h 127.0.0.1 -e "SELECT 1"; do sleep 1; done
echo "Initializing replication from clone position"
mysql -h 127.0.0.1 \
-e "$(<change_master_to.sql.in), \
MASTER_HOST='mysql-0.mysql', \
MASTER_USER='root', \
MASTER_PASSWORD='', \
MASTER_CONNECT_RETRY=10; \
START SLAVE;" || exit 1
# Em caso de reinício do contêiner, tente isso no máximo uma vez.
mv change_master_to.sql.in change_master_to.sql.orig
fi
# Inicie um servidor para enviar backups quando solicitado pelos peers.
exec ncat --listen --keep-open --send-only --max-conns=1 3307 -c \
"xtrabackup --backup --slave-info --stream=xbstream --host=127.0.0.1 --user=root"
volumeMounts:
- name: data
mountPath: /var/lib/mysql
subPath: mysql
- name: conf
mountPath: /etc/mysql/conf.d
resources:
requests:
cpu: 100m
memory: 100Mi
volumes:
- name: conf
emptyDir: {}
- name: config-map
configMap:
name: mysql
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 10Gi
kubectl apply -f https://k8s.io/examples/application/mysql/mysql-statefulset.yaml
Você pode acompanhar o progresso da inicialização executando:
kubectl get pods -l app=mysql --watch
Após algum tempo, você deverá ver os 3 Pods com o status Running:
NAME READY STATUS RESTARTS AGE
mysql-0 2/2 Running 0 2m
mysql-1 2/2 Running 0 1m
mysql-2 2/2 Running 0 1m
Pressione Ctrl+C para cancelar o watch.
Este manifesto utiliza diversas técnicas para gerenciar Pods com estado como parte de um StatefulSet. A próxima seção destaca algumas dessas técnicas para explicar o que acontece à medida que o StatefulSet cria os Pods.
O controlador de StatefulSet inicia os Pods um de cada vez, na ordem do seu índice ordinal. Ele aguarda até que cada Pod reporte estar Ready antes de iniciar o próximo.
Além disso, o controlador atribui a cada Pod um nome único e estável no formato
<nome-do-statefulset>-<índice-ordinal>, o que resulta em Pods chamados mysql-0, mysql-1 e mysql-2.
O template de Pod no manifesto do StatefulSet acima aproveita essas propriedades para realizar a inicialização ordenada da replicação do MySQL.
Antes de iniciar qualquer um dos contêineres especificados no Pod, o Pod executa primeiro todos os contêineres de inicialização na ordem definida.
O primeiro init container, chamado init-mysql, gera arquivos de configuração
especiais do MySQL com base no índice ordinal.
O script determina seu próprio índice ordinal extraindo-o do final do nome do Pod, que é retornado pelo comando hostname.
Em seguida, ele salva o ordinal (com um deslocamento numérico para evitar valores reservados)
em um arquivo chamado server-id.cnf no diretório conf.d do MySQL.
Isso traduz a identidade única e estável fornecida pelo StatefulSet
para o domínio dos IDs de servidor do MySQL, que exigem as mesmas propriedades.
O script no contêiner init-mysql também aplica primary.cnf ou
replica.cnf do ConfigMap, copiando o conteúdo para o diretório conf.d.
Como a topologia de exemplo consiste em um único servidor MySQL primário e qualquer número de réplicas,
o script atribui o ordinal 0 como o servidor primário, e todos os demais como réplicas.
Combinado com a garantia de ordem de implantação
do controlador StatefulSet, isso garante que o servidor MySQL primário esteja Ready antes de criar as réplicas,
para que elas possam começar a replicar.
De modo geral, quando um novo Pod entra no conjunto como réplica, ele deve assumir que o servidor MySQL primário pode já conter dados. Também deve considerar que os logs de replicação podem não cobrir todo o histórico desde o início. Essas suposições conservadoras são fundamentais para permitir que um StatefulSet em execução possa ser escalonado para mais ou para menos ao longo do tempo, em vez de ficar limitado ao seu tamanho inicial.
O segundo contêiner de inicialização, chamado clone-mysql, realiza uma operação de clonagem em um Pod réplica
na primeira vez que ele é iniciado em um PersistentVolume vazio.
Isso significa que ele copia todos os dados existentes de outro Pod em execução,
de modo que seu estado local fique consistente o suficiente para começar a replicar a partir do servidor primário.
O próprio MySQL não fornece um mecanismo para isso, então o exemplo utiliza uma ferramenta
open source popular chamada Percona XtraBackup.
Durante a clonagem, o servidor MySQL de origem pode sofrer redução de desempenho.
Para minimizar o impacto no servidor MySQL primário, o script instrui cada Pod a clonar a partir do Pod cujo índice ordinal é um a menos.
Isso funciona porque o controlador do StatefulSet sempre garante que o Pod N esteja Ready antes de iniciar o Pod N+1.
Após a conclusão bem-sucedida dos contêineres de inicialização, os contêineres regulares são executados.
Os Pods MySQL consistem em um contêiner mysql, que executa o servidor mysqld,
e um contêiner xtrabackup, que atua como um sidecar.
O sidecar xtrabackup analisa os arquivos de dados clonados e determina se
é necessário inicializar a replicação do MySQL na réplica.
Se for o caso, ele aguarda o mysqld estar pronto e então executa os comandos
CHANGE MASTER TO e START SLAVE com os parâmetros de replicação extraídos dos arquivos clonados pelo XtraBackup.
Assim que uma réplica inicia a replicação, ela memoriza seu servidor MySQL primário e
reconecta-se automaticamente caso o servidor reinicie ou a conexão seja perdida.
Além disso, como as réplicas procuram o servidor primário pelo seu nome DNS estável
(mysql-0.mysql), elas o encontram automaticamente mesmo que ele receba um novo
IP de Pod devido a um reagendamento.
Por fim, após iniciar a replicação, o contêiner xtrabackup fica aguardando conexões de outros
Pods que solicitam a clonagem de dados.
Esse servidor permanece ativo indefinidamente caso o StatefulSet seja escalonado para mais réplicas,
ou caso o próximo Pod perca seu PersistentVolumeClaim e precise refazer a clonagem.
Você pode enviar consultas de teste para o servidor MySQL primário (hostname mysql-0.mysql)
executando um contêiner temporário com a imagem mysql:5.7 e utilizando o cliente mysql.
kubectl run mysql-client --image=mysql:5.7 -i --rm --restart=Never --\
mysql -h mysql-0.mysql <<EOF
CREATE DATABASE test;
CREATE TABLE test.messages (message VARCHAR(250));
INSERT INTO test.messages VALUES ('hello');
EOF
Use o hostname mysql-read para enviar consultas de teste para qualquer servidor que esteja com o status Ready:
kubectl run mysql-client --image=mysql:5.7 -i -t --rm --restart=Never --\
mysql -h mysql-read -e "SELECT * FROM test.messages"
Você deverá obter uma saída semelhante a esta:
Waiting for pod default/mysql-client to be running, status is Pending, pod ready: false
+---------+
| message |
+---------+
| hello |
+---------+
pod "mysql-client" deleted
Para demonstrar que o Service mysql-read distribui as conexões entre os servidores, você pode executar SELECT @@server_id em um loop:
kubectl run mysql-client-loop --image=mysql:5.7 -i -t --rm --restart=Never --\
bash -ic "while sleep 1; do mysql -h mysql-read -e 'SELECT @@server_id,NOW()'; done"
Você deverá ver o valor de @@server_id mudar aleatoriamente, pois um endpoint diferente pode ser selecionado a cada tentativa de conexão:
+-------------+---------------------+
| @@server_id | NOW() |
+-------------+---------------------+
| 100 | 2006-01-02 15:04:05 |
+-------------+---------------------+
+-------------+---------------------+
| @@server_id | NOW() |
+-------------+---------------------+
| 102 | 2006-01-02 15:04:06 |
+-------------+---------------------+
+-------------+---------------------+
| @@server_id | NOW() |
+-------------+---------------------+
| 101 | 2006-01-02 15:04:07 |
+-------------+---------------------+
Você pode pressionar Ctrl+C quando quiser parar o loop, mas é útil mantê-lo rodando em outra janela para que você possa observar os efeitos dos próximos passos.
Para demonstrar a maior disponibilidade ao ler do pool de réplicas em vez de um único servidor,
mantenha o loop do SELECT @@server_id rodando enquanto você força um Pod a sair do estado Ready.
A verificação de prontidão
do contêiner mysql executa o comando mysql -h 127.0.0.1 -e 'SELECT 1'
para garantir que o servidor está ativo e apto a executar consultas.
Uma forma de forçar essa verificação de prontidão a falhar é quebrar esse comando:
kubectl exec mysql-2 -c mysql -- mv /usr/bin/mysql /usr/bin/mysql.off
Esse comando acessa o sistema de arquivos do contêiner real do Pod mysql-2 e renomeia o comando
mysql para que a verificação de prontidão não consiga encontrá-lo.
Após alguns segundos, o Pod deverá indicar que um de seus contêineres não está Ready,
o que você pode verificar executando:
kubectl get pod mysql-2
Procure por 1/2 na coluna READY:
NAME READY STATUS RESTARTS AGE
mysql-2 1/2 Running 0 3m
Neste momento, você deverá ver o loop do SELECT @@server_id continuar rodando, embora ele não mostre mais o valor 102.
Lembre-se de que o script init-mysql definiu o server-id como 100 + $ordinal, então o ID de servidor 102 corresponde ao Pod mysql-2.
Agora, repare o Pod e ele deverá voltar a aparecer na saída do loop após alguns segundos:
kubectl exec mysql-2 -c mysql -- mv /usr/bin/mysql.off /usr/bin/mysql
O StatefulSet também recria Pods caso eles sejam excluídos, de forma semelhante ao que um ReplicaSet faz para Pods sem estado.
kubectl delete pod mysql-2
O controlador do StatefulSet percebe que o Pod mysql-2 não existe mais e cria um novo com o mesmo nome,
vinculado ao mesmo PersistentVolumeClaim.
Você deverá ver o ID de servidor 102 desaparecer da saída do loop por um tempo e depois retornar automaticamente.
Se o seu cluster Kubernetes possui múltiplos Nós, você pode simular uma indisponibilidade de Nó (como durante atualizações) utilizando o comando drain.
Primeiro, determine em qual Nó um dos Pods MySQL está localizado:
kubectl get pod mysql-2 -o wide
O nome do Nó deverá aparecer na última coluna:
NAME READY STATUS RESTARTS AGE IP NODE
mysql-2 2/2 Running 0 15m 10.244.5.27 kubernetes-node-9l2t
Em seguida, drene o Nó executando o comando abaixo, que irá isolá-lo para que nenhum novo Pod seja alocado nele e,
em seguida, irá remover quaisquer Pods existentes.
Substitua <node-name> pelo nome do Nó que você encontrou no passo anterior.
# Veja o aviso acima sobre o impacto em outras cargas de trabalho
kubectl drain <node-name> --force --delete-emptydir-data --ignore-daemonsets
Agora você pode observar o Pod sendo realocado em outro Nó:
kubectl get pod mysql-2 -o wide --watch
Deverá se parecer com isto:
NAME READY STATUS RESTARTS AGE IP NODE
mysql-2 2/2 Terminating 0 15m 10.244.1.56 kubernetes-node-9l2t
[...]
mysql-2 0/2 Pending 0 0s <none> kubernetes-node-fjlm
mysql-2 0/2 Init:0/2 0 0s <none> kubernetes-node-fjlm
mysql-2 0/2 Init:1/2 0 20s 10.244.5.32 kubernetes-node-fjlm
mysql-2 0/2 PodInitializing 0 21s 10.244.5.32 kubernetes-node-fjlm
mysql-2 1/2 Running 0 22s 10.244.5.32 kubernetes-node-fjlm
mysql-2 2/2 Running 0 30s 10.244.5.32 kubernetes-node-fjlm
E novamente, você deverá ver o ID de servidor 102 desaparecer da saída do loop do
SELECT @@server_id por um tempo e depois retornar.
Agora, remova o isolamento do Nó para retorná-lo ao estado normal:
kubectl uncordon <node-name>
Ao utilizar replicação MySQL, você pode aumentar a capacidade de consultas de leitura adicionando réplicas. Para um StatefulSet, isso pode ser feito com um único comando:
kubectl scale statefulset mysql --replicas=5
Acompanhe a criação dos novos Pods executando:
kubectl get pods -l app=mysql --watch
Assim que estiverem ativos, você deverá ver os IDs de servidor 103 e 104 começarem a
aparecer na saída do loop do SELECT @@server_id.
Você também pode verificar se esses novos servidores possuem os dados que você adicionou antes de eles existirem:
kubectl run mysql-client --image=mysql:5.7 -i -t --rm --restart=Never --\
mysql -h mysql-3.mysql -e "SELECT * FROM test.messages"
Waiting for pod default/mysql-client to be running, status is Pending, pod ready: false
+---------+
| message |
+---------+
| hello |
+---------+
pod "mysql-client" deleted
Reduzir o número de réplicas também é um processo transparente:
kubectl scale statefulset mysql --replicas=3
Embora o escalonamento para cima crie novos PersistentVolumeClaims automaticamente, o escalonamento para baixo não exclui esses PVCs automaticamente.
Isso lhe dá a opção de manter esses PVCs inicializados para tornar o escalonamento para cima mais rápido, ou extrair os dados antes de excluí-los.
Você pode ver isso executando:
kubectl get pvc -l app=mysql
O que mostra que todos os 5 PVCs ainda existem, apesar de o StatefulSet ter sido reduzido para 3 réplicas:
NAME STATUS VOLUME CAPACITY ACCESSMODES AGE
data-mysql-0 Bound pvc-8acbf5dc-b103-11e6-93fa-42010a800002 10Gi RWO 20m
data-mysql-1 Bound pvc-8ad39820-b103-11e6-93fa-42010a800002 10Gi RWO 20m
data-mysql-2 Bound pvc-8ad69a6d-b103-11e6-93fa-42010a800002 10Gi RWO 20m
data-mysql-3 Bound pvc-50043c45-b1c5-11e6-93fa-42010a800002 10Gi RWO 2m
data-mysql-4 Bound pvc-500a9957-b1c5-11e6-93fa-42010a800002 10Gi RWO 2m
Se você não pretende reutilizar os PVCs extras, pode excluí-los:
kubectl delete pvc data-mysql-3
kubectl delete pvc data-mysql-4
Cancele o loop SELECT @@server_id pressionando Ctrl+C no terminal correspondente,
ou executando o seguinte comando em outro terminal:
kubectl delete pod mysql-client-loop --now
Exclua o StatefulSet. Isso também inicia a finalização dos Pods.
kubectl delete statefulset mysql
Verifique se os Pods desapareceram. Eles podem levar algum tempo para serem finalizados.
kubectl get pods -l app=mysql
Você saberá que os Pods foram finalizados quando o comando acima retornar:
No resources found.
Exclua o ConfigMap, os Services e os PersistentVolumeClaims.
kubectl delete configmap,service,pvc -l app=mysql
Se você provisionou PersistentVolumes manualmente, também será necessário excluí-los manualmente, assim como liberar os recursos subjacentes. Se você utilizou um provisionador dinâmico, ele exclui automaticamente os PersistentVolumes ao detectar que você excluiu os PersistentVolumeClaims. Alguns provisionadores dinâmicos (como os de EBS e PD) também liberam os recursos subjacentes ao excluir os PersistentVolumes.
Esta tarefa mostra como escalar um StatefulSet. Escalar um StatefulSet refere-se a aumentar ou diminuir o número de réplicas.
Os StatefulSets estão disponíveis apenas no Kubernetes na versão 1.5 ou superior.
Para verificar sua versão do Kubernetes, execute kubectl version.
Nem todas as aplicações com estado escalam de forma adequada. Se você não tem certeza se deve escalar seus StatefulSets, consulte Conceitos de StatefulSet ou Tutorial de StatefulSet para mais informações.
Você deve realizar o redimensionamento apenas quando tiver certeza de que o cluster da sua aplicação com estado está completamente íntegro.
Primeiro, encontre o StatefulSet que você deseja escalar:
kubectl get statefulsets <stateful-set-name>
Altere o número de réplicas do seu StatefulSet:
kubectl scale statefulsets <stateful-set-name> --replicas=<new-replicas>
Alternativamente, você pode fazer atualizações in-place em seus StatefulSets.
Se o seu StatefulSet foi criado inicialmente com kubectl apply,
atualize o .spec.replicas dos manifestos do StatefulSet e, em seguida, execute um kubectl apply:
kubectl apply -f <stateful-set-file-updated>
Caso contrário, edite esse campo com kubectl edit:
kubectl edit statefulsets <stateful-set-name>
Ou use kubectl patch:
kubectl patch statefulsets <stateful-set-name> -p '{"spec":{"replicas":<new-replicas>}}'
Você não pode reduzir o número de réplicas de um StatefulSet enquanto qualquer um dos Pods com estado que ele gerencia não estiver íntegro. A redução do número de réplicas só ocorre depois que esses Pods com estado estiverem em execução e prontos.
Se spec.replicas > 1, o Kubernetes não consegue determinar o motivo de um Pod com estado
não estar íntegro. Isso pode ser resultado de uma falha permanente ou de uma falha transitória.
Uma falha transitória pode ser causada por uma reinicialização necessária devido a uma atualização ou manutenção.
Se o Pod não estiver íntegro devido a uma falha permanente, redimensionar sem corrigir a falha pode levar a um estado em que a quantidade de membros do StatefulSet fique abaixo do número mínimo de réplicas necessário para funcionar corretamente. Isso pode fazer com que seu StatefulSet se torne indisponível.
Se o Pod não estiver íntegro devido a uma falha transitória e o Pod possa voltar a ficar disponível, o erro transitório pode interferir na sua operação de aumento ou redução do número de réplicas. Alguns bancos de dados distribuídos apresentam problemas quando nós entram e saem ao mesmo tempo. Nesses casos, é melhor analisar as operações de redimensionamento no nível da aplicação e realizar o ajuste apenas quando você tiver certeza de que o cluster da sua aplicação com estado está completamente íntegro.
Esta tarefa mostra como deletar um StatefulSet.
Você pode deletar um StatefulSet da mesma forma que deleta outros recursos no Kubernetes:
use o comando kubectl delete e especifique o StatefulSet pelo arquivo ou pelo nome.
kubectl delete -f <file.yaml>
kubectl delete statefulsets <statefulset-name>
Pode ser necessário deletar o serviço headless associado separadamente após o próprio StatefulSet ser deletado.
kubectl delete service <service-name>
Ao deletar um StatefulSet usando o kubectl, o StatefulSet é escalonado para 0.
Todos os Pods que fazem parte dessa carga de trabalho também são deletados.
Se você quiser deletar apenas o StatefulSet e não os Pods, use --cascade=orphan. Por exemplo:
kubectl delete -f <file.yaml> --cascade=orphan
Ao passar --cascade=orphan para o kubectl delete, os Pods gerenciados pelo StatefulSet permanecem mesmo após o objeto StatefulSet ser deletado.
Se os Pods tiverem o rótulo app.kubernetes.io/name=MyApp, você pode deletá-los da seguinte forma:
kubectl delete pods -l app.kubernetes.io/name=MyApp
Deletar os Pods em um StatefulSet não deleta os volumes associados. Isso garante que você tenha a chance de copiar os dados do volume antes de deletá-lo. Deletar o PVC após os pods terem sido finalizados pode acionar a exclusão dos Volumes Persistentes de suporte, dependendo da classe de armazenamento e da política de retenção. Você nunca deve assumir que será possível acessar um volume após a exclusão da requisição (claim).
Para deletar tudo em um StatefulSet, incluindo os pods associados, você pode executar uma série de comandos semelhantes aos seguintes:
grace=$(kubectl get pods <stateful-set-pod> --template '{{.spec.terminationGracePeriodSeconds}}')
kubectl delete statefulset -l app.kubernetes.io/name=MyApp
sleep $grace
kubectl delete pvc -l app.kubernetes.io/name=MyApp
No exemplo acima, os Pods possuem o rótulo app.kubernetes.io/name=MyApp;
substitua pelo seu próprio rótulo, conforme apropriado.
Se você perceber que alguns pods no seu StatefulSet estão presos nos estados 'Terminating' ou 'Unknown' por um longo período de tempo, pode ser necessário intervir manualmente para forçar a exclusão dos pods do servidor de API. Esta é uma tarefa potencialmente perigosa. Consulte Forçar a exclusão de pods de um StatefulSet para mais detalhes.
Saiba mais sobre como forçar a exclusão de pods de um StatefulSet.
Esta página mostra como excluir Pods que fazem parte de um StatefulSet e explica as considerações que devem ser levadas em conta ao fazer isso.
Na operação normal de um StatefulSet, nunca há necessidade de forçar a exclusão de um Pod. O controlador de StatefulSet é responsável por criar, escalar e excluir os membros do StatefulSet. Ele tenta garantir que o número especificado de Pods, do ordinal 0 até N-1, estejam ativos e prontos. O StatefulSet garante que, a qualquer momento, exista no máximo um Pod com uma determinada identidade em execução no cluster. Isso é chamado de semântica no máximo um fornecida por um StatefulSet.
A exclusão forçada manual deve ser realizada com cautela, pois tem o potencial de violar a semântica de no máximo um inerente ao StatefulSet. StatefulSets podem ser usados para executar aplicações distribuídas e em cluster que necessitam de uma identidade de rede estável e armazenamento estável. Essas aplicações frequentemente possuem configurações que dependem de um conjunto fixo de membros com identidades fixas. Ter múltiplos membros com a mesma identidade pode ser desastroso e pode levar à perda de dados (por exemplo, cenário de split brain em sistemas baseados em quórum).
Você pode realizar uma exclusão graciosa de um Pod com o seguinte comando:
kubectl delete pods <pod>
Para que o procedimento acima resulte em uma finalização graciosa, o Pod não deve especificar um
pod.Spec.TerminationGracePeriodSeconds igual a 0. A prática de definir pod.Spec.TerminationGracePeriodSeconds
como 0 segundos é insegura e fortemente desaconselhada para Pods de StatefulSet.
A exclusão graciosa é segura e garantirá que o Pod
seja finalizado de forma adequada antes que o
kubelet remova o nome do Pod do servidor de API.
Um Pod não é excluído automaticamente quando um Nó (Node) se torna inacessível. Os Pods em execução em um Nó inacessível entram no estado 'Terminating' ou 'Unknown' após um timeout. Os Pods também podem entrar nesses estados quando o usuário tenta realizar a exclusão graciosa de um Pod em um Nó inacessível. As únicas formas de remover um Pod nesse estado do servidor de API são as seguintes:
A prática recomendada é utilizar a primeira ou a segunda abordagem. Se um Nó for confirmado como morto (por exemplo, desconectado permanentemente da rede, desligado, etc.), exclua o objeto Nó. Se o Nó estiver sofrendo uma partição de rede, tente resolver o problema ou aguarde até que ele seja resolvido. Quando a partição for sanada, o kubelet concluirá a exclusão do Pod e liberará seu nome no servidor de API.
Normalmente, o sistema conclui a exclusão assim que o Pod não está mais em execução em um Nó ou quando o Nó é excluído por um administrador. Você pode substituir esse comportamento forçando a exclusão do Pod.
Exclusões forçadas não aguardam a confirmação do kubelet de que o Pod foi encerrado. Independentemente de uma exclusão forçada ser bem-sucedida em encerrar um Pod, o nome será imediatamente liberado no servidor de API. Isso permitirá que o controlador do StatefulSet crie um Pod de substituição com a mesma identidade; isso pode levar à duplicação de um Pod ainda em execução e, se esse Pod ainda puder se comunicar com os outros membros do StatefulSet, irá violar a semântica de no máximo um que o StatefulSet foi projetado para garantir.
Ao forçar a exclusão de um Pod de um StatefulSet, você está afirmando que o Pod em questão nunca mais fará contato com outros Pods do StatefulSet e que seu nome pode ser liberado com segurança para que uma substituição seja criada.
Se você deseja excluir um Pod forçadamente usando o kubectl versão >= 1.5, faça o seguinte:
kubectl delete pods <pod> --grace-period=0 --force
Se você estiver usando qualquer versão do kubectl <= 1.4, deve omitir a opção --force e usar:
kubectl delete pods <pod> --grace-period=0
Se mesmo após esses comandos o Pod permanecer no estado Unknown, utilize o seguinte comando
para remover o Pod do cluster:
kubectl patch pod <pod> -p '{"metadata":{"finalizers":null}}'
Sempre realize a exclusão forçada de Pods de StatefulSet com cautela e total conhecimento dos riscos envolvidos.
Saiba mais sobre depuração de um StatefulSet.
Este guia demonstra como acessar a API do Kubernetes de dentro de um Pod.
Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
Ao acessar a API a partir de um Pod, localizar e autenticar-se no servidor de API são processos ligeiramente diferentes do caso de um cliente externo.
A maneira mais fácil de usar a API do Kubernetes a partir de um Pod é utilizar uma das bibliotecas clientes oficiais. Essas bibliotecas conseguem descobrir automaticamente o servidor de API e autenticar-se.
De dentro de um Pod, as formas recomendadas de se conectar à API do Kubernetes são:
Para clientes em Go, utilize a
biblioteca cliente oficial em Go.
A função rest.InClusterConfig() lida automaticamente com a descoberta do host da API e a autenticação.
Veja um exemplo aqui.
Para clientes em Python, utilize a
biblioteca cliente oficial em Python.
A função config.load_incluster_config() lida automaticamente com a descoberta do host da API e a autenticação.
Veja um exemplo aqui.
Há diversas outras bibliotecas disponíveis. Consulte a página de Bibliotecas Clientes.
Em todos os casos, as credenciais da conta de serviço do Pod são utilizadas para se comunicar com segurança com o servidor de API.
Enquanto estiver em execução em um Pod, seu contêiner pode criar uma URL HTTPS para o servidor de API do Kubernetes
obtendo as variáveis de ambiente KUBERNETES_SERVICE_HOST e KUBERNETES_SERVICE_PORT_HTTPS.
O endereço do servidor de API dentro do cluster também é publicado em um Service chamado kubernetes no namespace
default, para que os Pods possam referenciar kubernetes.default.svc como um nome DNS para o servidor de API local.
kubernetes.default.svc;
no entanto, espera-se que a camada de gerenciamento apresente um certificado válido para o nome de host ou endereço
IP representado por $KUBERNETES_SERVICE_HOST.A forma recomendada de autenticar-se no servidor de API é com uma credencial
de conta de serviço.
Por padrão, um Pod é associado a uma conta de serviço, e uma credencial (token) para essa conta de serviço é colocada no
sistema de arquivos de cada contêiner nesse Pod, em /var/run/secrets/kubernetes.io/serviceaccount/token.
Se disponível, um pacote de certificados é colocado no sistema de arquivos de cada contêiner em /var/run/secrets/kubernetes.io/serviceaccount/ca.crt,
e deve ser utilizado para verificar o certificado de serviço do servidor de API.
Por fim, o namespace padrão a ser usado para operações da API com escopo de namespace é colocado em um arquivo em
/var/run/secrets/kubernetes.io/serviceaccount/namespace em cada contêiner.
Se você quiser consultar a API sem utilizar uma biblioteca cliente oficial, pode executar o kubectl proxy
como o comando de um novo contêiner sidecar no Pod.
Dessa forma, o kubectl proxy irá se autenticar na API e expô-la na interface localhost do Pod,
permitindo que outros contêineres no Pod a utilizem diretamente.
É possível evitar o uso do kubectl proxy passando o token de autenticação diretamente para o servidor de API. O certificado interno garante a segurança da conexão.
# Aponte para o nome de host interno do servidor de API
APISERVER=https://kubernetes.default.svc
# Caminho para o token da Conta de Serviço
SERVICEACCOUNT=/var/run/secrets/kubernetes.io/serviceaccount
# Ler o namespace deste Pod
NAMESPACE=$(cat ${SERVICEACCOUNT}/namespace)
# Ler o token de portador da Conta de Serviço
TOKEN=$(cat ${SERVICEACCOUNT}/token)
# Referenciar a autoridade certificadora (CA) interna
CACERT=${SERVICEACCOUNT}/ca.crt
# Explorar a API com o TOKEN
curl --cacert ${CACERT} --header "Authorization: Bearer ${TOKEN}" -X GET ${APISERVER}/api
A saída será semelhante a esta:
{
"kind": "APIVersions",
"versions": ["v1"],
"serverAddressByClientCIDRs": [
{
"clientCIDR": "0.0.0.0/0",
"serverAddress": "10.0.1.149:443"
}
]
}
Kubernetes v1.26 [stable]
A partir do Kubernetes v1.20, o kubelet pode obter dinamicamente as credenciais para um registro de imagem de contêiner usando plugins executáveis. O kubelet e o plugin executável se comunicam por meio de stdio (stdin, stdout e stderr) usando APIs versionadas do Kubernetes. Esses plugins permitem que o kubelet solicite credenciais para um registro de contêiner dinamicamente, em vez de armazenar credenciais estáticas no disco. Por exemplo, o plugin pode se comunicar com um servidor de metadados local para recuperar credenciais de curta duração para uma imagem que está sendo baixada pelo kubelet.
Você pode estar interessado em usar essa funcionalidade se alguma das condições abaixo for verdadeira:
imagePullSecrets não é aceitável.Este guia demonstra como configurar o mecanismo de plugin do provedor de credenciais de imagem do kubelet.
Você precisa de um cluster Kubernetes com nós que suportem plugins de provedor de credenciais do kubelet. Esse suporte está disponível no Kubernetes 1.35; As versões v1.24 e v1.25 do Kubernetes incluíram isso como um recurso beta, ativado por padrão.
Uma implementação funcional de um plugin executável de provedor de credenciais. Você pode criar seu próprio plugin ou usar um fornecido por provedores de nuvem.
Para verificar a versão, digite kubectl version.
Um plugin de provedor de credenciais é um binário executável que será executado pelo kubelet. Certifique-se de que o binário do plugin exista em cada nó do seu cluster e esteja armazenado em um diretório conhecido. O diretório será necessário posteriormente ao configurar as flags do kubelet.
Para usar esse recurso, o kubelet espera que duas flags sejam definidas:
--image-credential-provider-config - o caminho para o arquivo de configuração do plugin de provedor de credenciais.--image-credential-provider-bin-dir - o caminho para o diretório onde estão localizados os binários do plugin de provedor de credenciais.O arquivo de configuração passado para --image-credential-provider-config é lido pelo kubelet para determinar quais plugins executáveis devem ser invocados para quais imagens de contêiner. Aqui está um exemplo de arquivo de configuração que você pode acabar usando se estiver usando o plugin baseado no ECR:
apiVersion: kubelet.config.k8s.io/v1
kind: CredentialProviderConfig
# providers é uma lista de plug-ins auxiliares do provedor de credenciais que serão habilitados pelo kubelet.
# Vários provedores podem corresponder a uma única imagem, caso em que as credenciais
# de todos os provedores serão devolvidos ao kubelet. Se vários provedores forem chamados
# para uma única imagem, os resultados são combinados. Se os provedores retornarem
# chaves de autenticação sobrepostas, o valor do provedor anterior da lista é usado.
providers:
# name é o nome necessário do provedor de credenciais. Deve corresponder ao nome do
# executável do provedor visto pelo kubelet. O executável deve estar no
# diretório bin do kubelet (definido pela flag --image-credential-provider-bin-dir).
- name: ecr
# matchImages é uma lista obrigatória de strings usadas para corresponder às imagens para
# determinar se este provedor deve ser invocado. Se uma das strings corresponder à
# imagem solicitada do kubelet, o plug-in será invocado e terá uma chance
# para fornecer credenciais. Espera-se que as imagens contenham o domínio de registro
# e caminho da URL.
#
# Cada entrada em matchImages é um padrão que pode opcionalmente conter uma porta e um caminho.
# Globs podem ser usados no domínio, mas não na porta ou no caminho. Globs são suportados
# como subdomínios como '*.k8s.io' ou 'k8s.*.io' e domínios de nível superior como 'k8s.*'.
# A correspondência de subdomínios parciais como 'app*.k8s.io' também é suportada. Cada glob só pode corresponder
# a um único segmento de subdomínio, então `*.io` **não** corresponde a `*.k8s.io`.
#
# Existe uma correspondência entre uma imagem e uma matchImage quando todas as opções abaixo são verdadeiras:
# - Ambos contêm o mesmo número de partes de domínio e cada parte faz correspondência.
# - O caminho da URL de um matchImages deve ser um prefixo do caminho do URL da imagem de destino.
# - Se matchImages contiver uma porta, a porta também deverá corresponder à imagem.
#
# Valores de exemplo de matchImages:
# - 123456789.dkr.ecr.us-east-1.amazonaws.com
# - *.azurecr.io
# - gcr.io
# - *.*.registry.io
# - Registry.io:8080/path
matchImages:
- "*.dkr.ecr.*.amazonaws.com"
- "*.dkr.ecr.*.amazonaws.cn"
- "*.dkr.ecr-fips.*.amazonaws.com"
- "*.dkr.ecr.us-iso-east-1.c2s.ic.gov"
- "*.dkr.ecr.us-isob-east-1.sc2s.sgov.gov"
# defaultCacheDuration é a duração padrão em que o plug-in armazenará as credenciais na memória
# se a duração do cache não for fornecida na resposta do plug-in. Este campo é obrigatório.
defaultCacheDuration: "12h"
# Versão de entrada necessária do exec CredentialProviderRequest. O CredentialProviderResponse retornado
# DEVE usar a mesma versão de codificação da entrada. Os valores atualmente suportados são:
# - credentialprovider.kubelet.k8s.io/v1
apiVersion: credentialprovider.kubelet.k8s.io/v1
# Argumentos para passar ao comando quando for executá-lo.
# +optional
args:
- get-credentials
# Env define variáveis de ambiente adicionais para expor ao processo. Esses valores
# são combinados com o ambiente do host, bem como as variáveis que o client-go usa
# para passar o argumento para o plugin.
# +optional
env:
- name: AWS_PROFILE
value: example_profile
O campo providers é uma lista de plugins habilitados usados pelo kubelet. Cada entrada tem alguns campos obrigatórios:
name: o nome do plugin que DEVE corresponder ao nome do binário executável que existe no diretório passado para --image-credential-provider-bin-dir.matchImages: uma lista de strings usadas para comparar com imagens, a fim de determinar se este provedor deve ser invocado. Mais sobre isso abaixo.defaultCacheDuration: a duração padrão em que o kubelet armazenará em cache as credenciais em memória, caso a duração de cache não tenha sido especificada pelo plugin.apiVersion: a versão da API que o kubelet e o plugin executável usarão ao se comunicar.Cada provedor de credenciais também pode receber argumentos opcionais e variáveis de ambiente. Consulte os implementadores do plugin para determinar qual conjunto de argumentos e variáveis de ambiente são necessários para um determinado plugin.
O campo matchImages de cada provedor de credenciais é usado pelo kubelet para determinar se um plugin deve ser invocado
para uma determinada imagem que um Pod está usando. Cada entrada em matchImages é um padrão de imagem que pode opcionalmente conter uma porta e um caminho.
Globs podem ser usados no domínio, mas não na porta ou no caminho. Globs são suportados como subdomínios como *.k8s.io ou k8s.*.io,
e domínios de nível superior como k8s.*. Correspondência de subdomínios parciais como app*.k8s.io também é suportada. Cada glob só pode corresponder
a um único segmento de subdomínio, então *.io NÃO corresponde a *.k8s.io.
Uma correspondência existe entre um nome de imagem e uma entrada matchImage quando todos os itens abaixo são verdadeiros:
matchImages contiver uma porta, então a porta deve corresponder na imagem também.Alguns valores de exemplo de padrões matchImages são:
123456789.dkr.ecr.us-east-1.amazonaws.com*.azurecr.iogcr.io*.*.registry.iofoo.registry.io:8080/pathCredentialProviderConfig na referência da API de configuração do kubelet (v1).Este exemplo demonstra como limitar a quantidade de armazenamento consumido em um namespace.
Os seguintes recursos são usados na demonstração: ResourceQuota, LimitRange, e PersistentVolumeClaim.
Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
Para verificar a versão, digite kubectl version.
O administrador do cluster está operando um cluster em nome de uma população de usuários e o administrador quer controlar quanto armazenamento um único namespace pode consumir para controlar custos.
O administrador gostaria de limitar:
Adicionar um LimitRange a um namespace impõe tamanhos mínimos e máximos para solicitações de armazenamento. O armazenamento é solicitado através do PersistentVolumeClaim. O controlador de admissão que impõe os limites rejeitará qualquer PVC que esteja acima ou abaixo dos valores definidos pelo administrador.
Neste exemplo, um PVC que solicita 10Gi de armazenamento seria rejeitado porque excede o limite máximo de 2Gi.
apiVersion: v1
kind: LimitRange
metadata:
name: storagelimits
spec:
limits:
- type: PersistentVolumeClaim
max:
storage: 2Gi
min:
storage: 1Gi
As requisições de armazenamento mínimas são usadas quando o provedor de armazenamento subjacente exige certos valores mínimos. Por exemplo, os volumes do AWS EBS têm um requisito mínimo de 1 Gi.
Os administradores podem limitar o número de PVCs em um namespace, bem como a capacidade cumulativa desses PVCs. Novos PVCs que excedam qualquer um desses valores máximos serão rejeitados.
Neste exemplo, o sexto PVC no namespace seria rejeitado porque excede a contagem máxima de 5. Alternativamente, uma cota máxima de 5Gi, combinada com o limite máximo de 2Gi acima, não pode ter 3 PVCs, cada um com 2Gi. Isso seria um total de 6Gi solicitados para um namespace limitado a 5Gi.
apiVersion: v1
kind: ResourceQuota
metadata:
name: storagequota
spec:
hard:
persistentvolumeclaims: "5"
requests.storage: "5Gi"
Um LimitRange pode colocar um limite na quantidade de armazenamento solicitado enquanto um ResourceQuota pode efetivamente limitar o armazenamento consumido por um namespace através do número de claims e da capacidade de armazenamento cumulativa. Isso permite que um administrador do cluster planeje o custo de armazenamento do seu cluster sem risco de qualquer projeto exceder sua cota.
Essa página descreve o processo de atualização do CoreDNS e como instalar o CoreDNS ao invés de kube-dns.
Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
O seu servidor Kubernetes deve estar numa versão igual ou superior a v1.9.Para verificar a versão, digite kubectl version.
CoreDNS é um servidor DNS flexível e extensível que pode servir como Kubernetes cluster DNS. Como o Kubernetes, o projeto CoreDNS é hospedado pelo CNCF.
Você pode usar o CoreDNS ao invés de kube-dns no seu cluster substituindo por kube-dns em uma implantação existente, ou usando ferramentas como kubeadm que fará a instalação e a atualização do cluster pra você.
Para instalação manual, ou substituição do kube-dns, veja a documentação no site do CoreDNS.
No Kubernetes versão 1.21, kubeadm removeu o suporte para kube-dns como uma aplicação DNS.
Para kubeadm v1.35, o único Cluster DNS suportado é o CoreDNS.
Você pode migrar para o CoreDNS quando usar o kubeadm para atualizar o cluster que está usando
kube-dns. Neste caso, kubeadm gera a configuração do CoreDNS
("Corefile") baseado no ConfigMap kube-dns, preservando a configuração para
stub domains e upstream name server.
Você pode verificar a versão do CoreDNS que o kubeadm instala para cada versão do Kubernetes na página versão do CoreDNS no Kubernetes.
CoreDNS pode ser atualizado manualmente, caso você queria atualizar somente o CoreDNS ou usar sua própria imagem customizada. Há uma página de instruções e passo-a-passo disponível para garantir uma atualização sem problemas. Certifique-se que a configuração existente do CoreDNS ("Corefile") é mantida quando atualizar o seu cluster.
Se você está atualizando o seu cluster usando a ferramenta kubeadm, o kubeadm
pode cuidar da retenção da configuração existente do CoreDNS automaticamente.
Quando a utilização dos recursos é uma preocupação, pode ser útil ajustar a configuração do CoreDNS. Para mais detalhes, confira documentação para escalonar o CoreDNS.
Você pode configurar o CoreDNS para suportar mais casos de uso do que o
kube-dns suporta modificando a configuração do CoreDNS ("Corefile").
Para mais informações, veja a documentação
do plugin kubernetes do CoreDNS, ou leia o artigo
Custom DNS Entries For Kubernetes (em inglês) no blog do CoreDNS.
Essa página explica como configurar os seus Pod(s) de DNS e personalizar o processo de resolução de DNS no seu cluster.
Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
Seu cluster deve estar executando o complemento CoreDNS.
O seu servidor Kubernetes deve estar numa versão igual ou superior a v1.12.
Para verificar a versão, digite kubectl version.
DNS é um serviço integrado do Kubernetes que é iniciado automaticamente usando o gerenciador de complementos cluster add-on.
kube-dns no campo metadata.name.
O objetivo é garantir maior interoperabilidade com cargas de trabalho que dependiam do nome de serviço legado kube-dns para resolver endereços internos ao cluster.
Usando o service chamado kube-dns abstrai o detalhe de implementação de qual provedor de DNS está sendo executado por trás desse nome comum.Se você estiver executando o CoreDNS como um Deployment, ele geralmente será exposto como um service do Kubernetes com o endereço de IP estático.
O kubelet passa informações de resolução de DNS para cada contêiner com a flag --cluster-dns=<dns-service-ip>.
Os nomes DNS também precisam de domínios. Você configura o domínio local no kubelet com a flag --cluster-domain=<default-local-domain>.
O servidor DNS suporta pesquisas de encaminhamento (registros A e AAAA), pesquisas de porta (registros SRV), pesquisas de endereço de IP reverso (registros PTR) e muito mais. Para mais informações, veja DNS para Serviços e Pods.
Se a dnsPolicy de um Pod estiver definida como default, ele herda a configuração de resolução de nome do nó em que o Pod é executado. A resolução de DNS do Pod deve se comportar da mesma forma que o nó.
Veja Problemas conhecidos.
Se você não quiser isso, ou se quiser uma configuração de DNS diferente para os pods, pode usar a flag --resolv-conf do kubelet. Defina essa flag como "" para impedir que os Pods herdem a configuração do DNS. Defina-a como um caminho de arquivo válido para especificar um arquivo diferente de /etc/resolv.conf para a herança de DNS.
CoreDNS é um servidor oficial de DNS de propósito geral que pode atuar como DNS do cluster, cumprindo com as especificações DNS.
CoreDNS é um servidor DNS que é modular e plugável, com plugins que adicionam novas funcionalidades. O servidor CoreDNS pode ser configurado por um Corefile, que é o arquivo de configuração do CoreDNS. Como administrador de cluster, você pode modificar o ConfigMap que contém o arquivo Corefile do CoreDNS para mudar como o descoberta de serviços DNS se comporta para esse cluster.
No Kubernetes, o CoreDNS é instalado com a seguinte configuração padrão do Corefile:
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns
namespace: kube-system
data:
Corefile: |
.:53 {
errors
health {
lameduck 5s
}
ready
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
ttl 30
}
prometheus :9153
forward . /etc/resolv.conf
cache 30
loop
reload
loadbalance
}
A configuração do Corefile inclui os seguintes plugins do CoreDNS:
http://localhost:8080/health. Nesta sintaxe estendida, lameduck marcará o processo como não-íntegro, esperando por 5 segundos antes que o processo seja encerrado.ttl permite que você defina um TTL personalizado para as respostas. O padrão é 5 segundos. O TTL mínimo permitido é de 0 segundos e o máximo é de 3600 segundos. Definir o TTL como 0 impedirá que os registros sejam armazenados em cache.pods insecure é fornecida para retrocompatibilidade com o kube-dns.pods verified, que retorna um registro A somente se houver um Pod no mesmo namespace com um IP correspondente.pods disabled pode ser usada se você não usar registros de Pod.http://localhost:9153/metrics seguindo o formato Prometheus, também conhecido como OpenMetrics.Você pode modificar o comportamento padrão do CoreDNS modificando o ConfigMap.
O CoreDNS tem a capacidade de configurar domínios Stub e upstream nameservers usando o plugin forward.
Se um operador de cluster possui um servidor de domínio Consul localizado em "10.150.0.1" e todos os nomes Consul possuem o sufixo ".consul.local". Para configurá-lo no CoreDNS, o administrador do cluster cria a seguinte entrada no ConfigMap do CoreDNS.
consul.local:53 {
errors
cache 30
forward . 10.150.0.1
}
Para forçar explicitamente que todas as pesquisas de DNS fora do cluster passem por um nameserver específico em 172.16.0.1, aponte o forward para o nameserver em vez de /etc/resolv.conf.
forward . 172.16.0.1
O ConfigMap final, juntamente com a configuração padrão do Corefile, é:
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns
namespace: kube-system
data:
Corefile: |
.:53 {
errors
health
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
}
prometheus :9153
forward . 172.16.0.1
cache 30
loop
reload
loadbalance
}
consul.local:53 {
errors
cache 30
forward . 10.150.0.1
}