1 - Melhores Práticas de Configuração
Esse documento destaca e consolida as melhores práticas de configuração apresentadas em todo o guia de usuário, na documentação de introdução e nos exemplos.
Este é um documento vivo. Se você pensar em algo que não está nesta lista, mas pode ser útil para outras pessoas, não hesite em criar uma issue ou submeter um PR.
Dicas Gerais de Configuração
-
Ao definir configurações, especifique a versão mais recente estável da API.
-
Os arquivos de configuração devem ser armazenados em um sistema de controle antes de serem enviados ao cluster. Isso permite que você reverta rapidamente uma alteração de configuração, caso necessário. Isso também auxilia na recriação e restauração do cluster.
-
Escreva seus arquivos de configuração usando YAML ao invés de JSON. Embora esses formatos possam ser usados alternadamente em quase todos os cenários, YAML tende a ser mais amigável.
-
Agrupe objetos relacionados em um único arquivo sempre que fizer sentido. Geralmente, um arquivo é mais fácil de gerenciar do que vários. Veja o guestbook-all-in-one.yaml como exemplo dessa sintaxe.
-
Observe também que vários comandos
kubectl
podem ser chamados em um diretório. Por exemplo, você pode chamarkubectl apply
em um diretório de arquivos de configuração. -
Não especifique valores padrões desnecessariamente: configurações simples e mínimas diminuem a possibilidade de erros.
-
Coloque descrições de objetos nas anotações para permitir uma melhor análise.
"Naked" Pods comparados a ReplicaSets, Deployments, e Jobs
-
Se você puder evitar, não use "naked" Pods (ou seja, se você puder evitar, pods não vinculados a um ReplicaSet ou Deployment). Os "naked" pods não serão reconfigurados em caso de falha de um nó.
Criar um Deployment, que cria um ReplicaSet para garantir que o número desejado de Pods esteja disponível e especifica uma estratégia para substituir os Pods (como RollingUpdate), é quase sempre preferível do que criar Pods diretamente, exceto para alguns cenários explícitos de restartPolicy:Never. Um Job também pode ser apropriado.
Services
-
Crie o Service antes de suas cargas de trabalho de backend correspondentes (Deployments ou ReplicaSets) e antes de quaisquer cargas de trabalho que precisem acessá-lo. Quando o Kubernetes inicia um contêiner, ele fornece variáveis de ambiente apontando para todos os Services que estavam em execução quando o contêiner foi iniciado. Por exemplo, se um Service chamado
foo
existe, todos os contêineres vão receber as seguintes variáveis em seu ambiente inicial:FOO_SERVICE_HOST=<o host em que o Service está executando> FOO_SERVICE_PORT=<a porta em que o Service está executando>
Isso implica em um requisito de pedido - qualquer Service
que um Pod
quer acessar precisa ser criado antes do Pod
em si, ou então as variáveis de ambiente não serão populadas. O DNS não possui essa restrição.
-
Um cluster add-on opcional (embora fortemente recomendado) é um servidor DNS. O servidor DNS monitora a API do Kubernetes buscando novos
Services
e cria um conjunto de DNS para cada um. Se o DNS foi habilitado em todo o cluster, então todos osPods
devem ser capazes de fazer a resolução deServices
automaticamente. -
Não especifique um
hostPort
para um Pod a menos que isso seja absolutamente necessário. Quando você vincula um Pod a umhostPort
, isso limita o número de lugares em que o Pod pode ser agendado, porque cada combinação de <hostIP
,hostPort
,protocol
> deve ser única. Se você não especificar ohostIP
eprotocol
explicitamente, o Kubernetes vai usar0.0.0.0
como ohostIP
padrão eTCP
comoprotocol
padrão.Se você precisa de acesso a porta apenas para fins de depuração, pode usar o apiserver proxy ou o
kubectl port-forward
.Se você precisa expor explicitamente a porta de um Pod no nó, considere usar um Service do tipo NodePort antes de recorrer a
hostPort
. -
Evite usar
hostNetwork
pelos mesmos motivos dohostPort
. -
Use headless Services (que tem um
ClusterIP
ouNone
) para descoberta de serviço quando você não precisar de um balanceador de cargakube-proxy
.
Usando Labels
- Defina e use labels que identifiquem atributos semânticos da sua aplicação ou Deployment, como
{ app: myapp, tier: frontend, phase: test, deployment: v3 }
. Você pode usar essas labels para selecionar os Pods apropriados para outros recursos; por exemplo, um Service que seleciona todos os Podstier: frontend
, ou todos os componentes deapp: myapp
. Veja o app guestbook para exemplos dessa abordagem.
Um Service pode ser feito para abranger vários Deployments, omitindo labels específicas de lançamento de seu seletor. Quando você precisar atualizar um serviço em execução sem downtime, use um Deployment.
Um estado desejado de um objeto é descrito por um Deployment, e se as alterações nesse spec forem aplicadas o controlador do Deployment altera o estado real para o estado desejado em uma taxa controlada.
-
Use as labels comuns do Kubernetes para casos de uso comuns. Essas labels padronizadas enriquecem os metadados de uma forma que permite que ferramentas, incluindo
kubectl
e a dashboard, funcionem de uma forma interoperável. -
Você pode manipular labels para depuração. Como os controladores do Kubernetes (como ReplicaSet) e Services se relacionam com os Pods usando seletor de labels, remover as labels relevantes de um Pod impedirá que ele seja considerado por um controlador ou que seja atendido pelo tráfego de um Service. Se você remover as labels de um Pod existente, seu controlador criará um novo Pod para substituí-lo. Essa é uma maneira útil de depurar um Pod anteriormente "ativo" em um ambiente de "quarentena". Para remover ou alterar labels interativamente, use
kubectl label
.
Imagens de Contêiner
A imagePullPolicy e tag da imagem afetam quando o kubelet tenta puxar a imagem especificada.
-
imagePullPolicy: IfNotPresent
: a imagem é puxada apenas se ainda não estiver presente localmente. -
imagePullPolicy: Always
: sempre que o kubelet inicia um contêiner, ele consulta o registry da imagem do contêiner para verificar o resumo de assinatura da imagem. Se o kubelet tiver uma imagem do contêiner com o mesmo resumo de assinatura armazenado em cache localmente, o kubelet usará a imagem em cache, caso contrário, o kubelet baixa(pulls) a imagem com o resumo de assinatura resolvido, e usa essa imagem para iniciar o contêiner. -
imagePullPolicy
é omitido se a tag da imagem é:latest
ou seimagePullPolicy
é omitido é automaticamente definido comoAlways
. Observe que não será utilizado paraifNotPresent
se o valor da tag mudar. -
imagePullPolicy
é omitido se uma tag da imagem existe mas não:latest
:imagePullPolicy
é automaticamente definido comoifNotPresent
. Observe que isto não será atualizado paraAlways
se a tag for removida ou alterada para:latest
. -
imagePullPolicy: Never
: presume-se que a imagem exista localmente. Não é feita nenhuma tentativa de puxar a imagem.
Nota: Para garantir que seu contêiner sempre use a mesma versão de uma imagem, você pode especificar seu resumo de assinatura; substitua<nome-da-imagem>:<tag>
por<nome-da-imagem>@<hash>
(por exemplo,image@sha256:45b23dee08af5e43a7fea6c4cf9c25ccf269ee113168c19722f87876677c5cb2
). Esse resumo de assinatura identifica exclusivamente uma versão específica de uma imagem, então isso nunca vai ser atualizado pelo Kubernetes a menos que você mude o valor do resumo de assinatura da imagem.
Nota: Você deve evitar o uso da tag:latest
em produção, pois é mais difícil rastrear qual versão da imagem está sendo executada e mais difícil reverter adequadamente.
Nota: A semântica de cache do provedor de imagem subjacente torna até mesmoimagePullPolicy: Always
eficiente, contanto que o registro esteja acessível de forma confiável. Com o Docker, por exemplo, se a imagem já existe, a tentativa de baixar(pull) é rápida porque todas as camadas da imagem são armazenadas em cache e nenhum download de imagem é necessário.
Usando kubectl
-
Use
kubectl apply -f <directory>
. Isso procura por configurações do Kubernetes em todos os arquivos.yaml
,.yml
em<directory>
e passa isso paraapply
. -
Use labels selectors para operações
get
edelete
em vez de nomes de objetos específicos. Consulte as seções sobre label selectors e usando Labels efetivamente. -
Use
kubectl create deployment
ekubectl expose
para criar rapidamente Deployments e Services de um único contêiner. Consulte Use um Service para acessar uma aplicação em um cluster para obter um exemplo.
2 - Organizando o acesso ao cluster usando arquivos kubeconfig
Utilize arquivos kubeconfig para organizar informações sobre clusters, usuários, namespaces e mecanismos de autenticação. A ferramenta de linha de comando kubectl
faz uso dos arquivos kubeconfig para encontrar as informações necessárias para escolher e se comunicar com o serviço de API de um cluster.
Nota: Um arquivo que é utilizado para configurar o acesso aos clusters é chamado de kubeconfig. Esta á uma forma genérica de referenciamento para um arquivo de configuração desta natureza. Isso não significa que existe um arquivo com o nomekubeconfig
.
Por padrão, o kubectl
procura por um arquivo de nome config
no diretório $HOME/.kube
Você pode especificar outros arquivos kubeconfig através da variável de ambiente KUBECONFIG
ou adicionando a opção --kubeconfig
.
Para maiores detalhes na criação e especificação de um kubeconfig, veja o passo a passo em Configurar Acesso para Múltiplos Clusters.
Suportando múltiplos clusters, usuários e mecanismos de autenticação
Imagine que você possua inúmeros clusters, e seus usuários e componentes se autenticam de várias formas. Por exemplo:
- Um kubelet ativo pode se autenticar utilizando certificados
- Um usuário pode se autenticar através de tokens
- Administradores podem possuir conjuntos de certificados os quais provém acesso aos usuários de forma individual.
Através de arquivos kubeconfig, você pode organizar os seus clusters, usuários, e namespaces. Você também pode definir contextos para uma fácil troca entre clusters e namespaces.
Contexto
Um elemento de contexto em um kubeconfig é utilizado para agrupar parâmetros de acesso em um nome conveniente. Cada contexto possui três parâmetros: cluster, namespace, e usuário.
Por padrão, a ferramenta de linha de comando kubectl
utiliza os parâmetros do contexto atual para se comunicar com o cluster.
Para escolher o contexto atual:
kubectl config use-context
A variável de ambiente KUBECONFIG
A variável de ambiente KUBECONFIG
possui uma lista dos arquivos kubeconfig. Para Linux e Mac, esta lista é delimitada por vírgula. No Windows, a lista é delimitada por ponto e vírgula. A variável de ambiente KUBECONFIG
não é um requisito obrigatório - caso ela não exista o kubectl
utilizará o arquivo kubeconfig padrão localizado no caminho $HOME/.kube/config
.
Se a variável de ambiente KUBECONFIG
existir, o kubectl
utilizará uma configuração que é o resultado da combinação dos arquivos listados na variável de ambiente KUBECONFIG
.
Combinando arquivos kubeconfig
Para inspecionar a sua configuração atual, execute o seguinte comando:
kubectl config view
Como descrito anteriormente, a saída poderá ser resultado de um único arquivo kubeconfig, ou poderá ser o resultado da junção de vários arquivos kubeconfig.
Aqui estão as regras que o kubectl
utiliza quando realiza a combinação de arquivos kubeconfig:
-
Se o argumento
--kubeconfig
está definido, apenas o arquivo especificado será utilizado. Apenas uma instância desta flag é permitida.Caso contrário, se a variável de ambiente
KUBECONFIG
estiver definida, esta deverá ser utilizada como uma lista de arquivos a serem combinados, seguindo o fluxo a seguir:- Ignorar arquivos vazios.
- Produzir erros para aquivos cujo conteúdo não for possível desserializar.
- O primeiro arquivo que definir um valor ou mapear uma chave determinada, será o escolhido.
- Nunca modificar um valor ou mapear uma chave.
Exemplo: Preservar o contexto do primeiro arquivo que definir
current-context
. Exemplo: Se dois arquivos especificarem umred-user
, use apenas os valores do primeirored-user
. Mesmo se um segundo arquivo possuir entradas não conflitantes sobre a mesma entradared-user
, estas deverão ser descartadas.
Para um exemplo de definição da variável de ambiente
KUBECONFIG
veja Definido a variável de ambiente KUBECONFIG.Caso contrário, utilize o arquivo kubeconfig padrão encontrado no diretório
$HOME/.kube/config
, sem qualquer tipo de combinação. -
Determine o contexto a ser utilizado baseado no primeiro padrão encontrado, nesta ordem:
- Usar o conteúdo da flag
--context
caso ela existir. - Usar o
current-context
a partir da combinação dos arquivos kubeconfig.
Um contexto vazio é permitido neste momento.
- Usar o conteúdo da flag
-
Determinar o cluster e o usuário. Neste ponto, poderá ou não existir um contexto. Determinar o cluster e o usuário no primeiro padrão encontrado de acordo com a ordem à seguir. Este procedimento deverá executado duas vezes: uma para definir o usuário a outra para definir o cluster.
- Utilizar a flag caso ela existir:
--user
ou--cluster
. - Se o contexto não estiver vazio, utilizar o cluster ou usuário deste contexto.
O usuário e o cluster poderão estar vazios neste ponto.
- Utilizar a flag caso ela existir:
-
Determinar as informações do cluster atual a serem utilizadas. Neste ponto, poderá ou não existir informações de um cluster.
Construir cada peça de informação do cluster baseado nas opções à seguir; a primeira ocorrência encontrada será a opção vencedora:
- Usar as flags de linha de comando caso existirem:
--server
,--certificate-authority
,--insecure-skip-tls-verify
. - Se algum atributo do cluster existir a partir da combinação de kubeconfigs, estes deverão ser utilizados.
- Se não existir informação de localização do servidor falhar.
- Usar as flags de linha de comando caso existirem:
-
Determinar a informação atual de usuário a ser utilizada. Construir a informação de usuário utilizando as mesmas regras utilizadas para o caso de informações de cluster, exceto para a regra de técnica de autenticação que deverá ser única por usuário:
- Usar as flags, caso existirem:
--client-certificate
,--client-key
,--username
,--password
,--token
. - Usar os campos
user
resultado da combinação de arquivos kubeconfig. - Se existirem duas técnicas conflitantes, falhar.
- Usar as flags, caso existirem:
-
Para qualquer informação que ainda estiver ausente, utilizar os valores padrão e potencialmente solicitar informações de autenticação a partir do prompt de comando.
Referências de arquivos
Arquivos e caminhos referenciados em um arquivo kubeconfig são relativos à localização do arquivo kubeconfig.
Referências de arquivos na linha de comando são relativas ao diretório de trabalho vigente.
No arquivo $HOME/.kube/config
, caminhos relativos são armazenados de forma relativa, e caminhos absolutos são armazenados de forma absoluta.