Nota perev. : Este artigo pequeno (mas espaçoso!), Escrito por Michael Hausenblas, da equipe OpenShift da Red Hat, gostou tanto que foi adicionado Ă nossa base de conhecimento interna do Kubernetes quase imediatamente apĂłs sua descoberta. E como as informaçÔes apresentadas serĂŁo obviamente Ășteis para a comunidade de TI de lĂngua russa, estamos felizes em publicar sua tradução.
Como vocĂȘ pode imaginar, o tĂtulo desta publicação Ă© uma referĂȘncia ao desenho animado da Pixar de 1998, âA Bug's Lifeâ
(nas bilheterias russas, era chamado de âAdventures of Flickâ ou âLife of an Insectâ - aproximadamente tradução ) . Kubernetes tem muito em comum com trabalhadores e lares. Analisaremos cuidadosamente o ciclo de vida completo da lareira do ponto de vista prĂĄtico - em particular, as maneiras pelas quais vocĂȘ pode influenciar o comportamento na inicialização e desligamento, bem como as abordagens corretas para verificar o status do aplicativo.
Independentemente de vocĂȘ ter criado sob vocĂȘ mesmo ou, melhor ainda, atravĂ©s de um controlador como
Deployment ,
DaemonSet ou
StatefulSet , under pode estar em uma das seguintes fases:
- Pendente : o servidor da API criou um recurso de pod e o salvou no etcd, mas ainda nĂŁo foi planejado e as imagens de seus contĂȘineres nĂŁo foram recebidas do registro;
- Em execução (em funcionamento): under foi atribuĂdo ao nĂł e todos os contĂȘineres foram criados pelo kubelet ;
- Sucedido (concluĂdo com sucesso): a operação de todos os contĂȘineres da lareira foi concluĂda com ĂȘxito e eles nĂŁo serĂŁo reiniciados;
- Falha : todos os contĂȘineres na lareira pararam de funcionar e pelo menos um dos contĂȘineres falhou;
- Desconhecido : o servidor de API nĂŁo conseguiu consultar o status da lareira, geralmente devido a um erro ao interagir com o kubelet .
Ao executar o
kubectl get pod
, observe que a coluna
STATUS
pode mostrar outras (exceto essas cinco) mensagens - por exemplo,
Init:0/1
ou
CrashLoopBackOff
. Isso ocorre porque a fase Ă© apenas parte do estado geral da lareira. Uma boa maneira de descobrir o que exatamente aconteceu Ă© executar o
kubectl describe pod/$PODNAME
e veja a entrada
kubectl describe pod/$PODNAME
Events:
abaixo. Ela exibe uma lista de açÔes relevantes: que a imagem do contĂȘiner foi recebida, foi planejada, o contĂȘiner estĂĄ em um estado
"Ăntegro" .
Agora dĂȘ uma olhada em um exemplo especĂfico do ciclo de vida de uma lareira do inĂcio ao fim, conforme mostrado no diagrama a seguir:

O que aconteceu aqui? Os passos sĂŁo os seguintes:
- Isso nĂŁo Ă© mostrado no diagrama, mas, no inĂcio, um infra-contĂȘiner especial Ă© iniciado e configura os espaços de nomes aos quais os contĂȘineres restantes se unem.
- O primeiro contĂȘiner definido pelo usuĂĄrio que inicia Ă© o contĂȘiner init ; pode ser usado para tarefas de inicialização.
- Em seguida, o contĂȘiner principal e o gancho pĂłs-partida sĂŁo lançados simultaneamente; no nosso caso, isso acontece apĂłs 4 segundos. Ganchos sĂŁo definidos para cada contĂȘiner.
- EntĂŁo, no sĂ©timo segundo, os testes de vivacidade e prontidĂŁo entram em cena novamente para cada contĂȘiner.
- No 11Âș segundo, quando o abate Ă© eliminado, um gancho de parada Ă© acionado e o contĂȘiner principal Ă© eliminado apĂłs um perĂodo de carĂȘncia . Observe que, na realidade, o processo de conclusĂŁo do pod Ă© um pouco mais complicado.
Como cheguei Ă sequĂȘncia acima e ao seu tempo? Para fazer isso, usamos a seguinte
implantação , criada especificamente para rastrear a ordem dos eventos (nĂŁo Ă© muito Ăștil por si sĂł):
kind: Deployment apiVersion: apps/v1beta1 metadata: name: loap spec: replicas: 1 template: metadata: labels: app: loap spec: initContainers: - name: init image: busybox command: ['sh', '-c', 'echo $(date +%s): INIT >> /loap/timing'] volumeMounts: - mountPath: /loap name: timing containers: - name: main image: busybox command: ['sh', '-c', 'echo $(date +%s): START >> /loap/timing; sleep 10; echo $(date +%s): END >> /loap/timing;'] volumeMounts: - mountPath: /loap name: timing livenessProbe: exec: command: ['sh', '-c', 'echo $(date +%s): LIVENESS >> /loap/timing'] readinessProbe: exec: command: ['sh', '-c', 'echo $(date +%s): READINESS >> /loap/timing'] lifecycle: postStart: exec: command: ['sh', '-c', 'echo $(date +%s): POST-START >> /loap/timing'] preStop: exec: command: ['sh', '-c', 'echo $(date +%s): PRE-HOOK >> /loap/timing'] volumes: - name: timing hostPath: path: /tmp/loap
Observe que, para desligar o pod com força quando o contĂȘiner principal estava funcionando, executei o seguinte comando:
$ kubectl scale deployment loap --replicas=0
Observamos uma sequĂȘncia especĂfica de eventos em ação e agora estamos prontos para seguir em frente - para prĂĄticas no campo do gerenciamento do ciclo de vida da lareira. Eles sĂŁo os seguintes:
- Use recipientes init para preparar a lareira para a operação normal. Por exemplo, para obter dados externos, crie tabelas no banco de dados ou aguarde a disponibilidade do serviço do qual depende. Se necessĂĄrio, vocĂȘ pode criar muitos contĂȘineres init e todos eles devem ser concluĂdos com ĂȘxito antes do lançamento de contĂȘineres regulares.
- Sempre adicione
livenessProbe
e readinessProbe
. O primeiro Ă© usado pelo kubelet 'ohm para entender se e quando reiniciar o contĂȘiner e a implantação ' ohm para decidir se a atualização sem interrupção foi bem-sucedida. O segundo Ă© usado pelo serviço para decidir a direção do trĂĄfego para o submarino. Se essas amostras nĂŁo forem definidas, o kubelet para ambas assume que elas foram concluĂdas com ĂȘxito. Isso leva a duas consequĂȘncias: a) a polĂtica de reinicialização nĂŁo pode ser aplicada; b) os contĂȘineres na lareira recebem instantaneamente o trĂĄfego do serviço que estĂŁo enfrentando e mesmo se ainda estiverem ocupados com o processo de inicialização. - Use ganchos para inicializar adequadamente o contĂȘiner e destruĂ-lo completamente. Por exemplo, isso Ă© Ăștil no caso de funcionamento de um aplicativo cujo cĂłdigo fonte vocĂȘ nĂŁo tem acesso ou nĂŁo pode modificar, mas que requer alguma inicialização ou preparação para a conclusĂŁo - por exemplo, limpando as conexĂ”es com o banco de dados. Observe que, ao usar o serviço , o desligamento do servidor de API, do controlador de terminal e do kube-proxy pode levar algum tempo (por exemplo, excluindo as entradas correspondentes das tabelas de ip). Portanto, o tĂ©rmino do seu trabalho pode afetar as solicitaçÔes de aplicativos. FreqĂŒentemente, para resolver esse problema, basta um gancho simples com uma chamada de suspensĂŁo.
- Para necessidades de depuração e para entender em geral por que parou de funcionar, o aplicativo pode gravar em
/dev/termination-log
, e vocĂȘ pode ver as mensagens usando o kubectl describe pod âŠ
Essas configuraçÔes padrão são alteradas por meio de terminationMessagePath
e / ou usando terminationMessagePolicy
na subespecificação - consulte a referĂȘncia da API para obter mais detalhes.
Esta publicação não discute
inicializadores (alguns detalhes sobre eles podem ser encontrados no final deste material - aprox. Transl. ) . Este Ă© um conceito completamente novo introduzido no Kubernetes 1.7. Os inicializadores trabalham dentro do plano de controle (API Server) em vez de estarem no contexto
kubelet e podem ser usados ââpara enriquecer os lares, por exemplo, com contĂȘineres laterais ou imposição de polĂticas de segurança. AlĂ©m disso, os
PodPresets nĂŁo foram considerados, que no futuro podem ser substituĂdos por um conceito mais flexĂvel de inicializadores.
PS do tradutor
Leia também em nosso blog: