Adicionar um Container Sidecar

KubernetesBeginner
Pratique Agora

Introdução

Um container sidecar é executado no mesmo Pod que um container de aplicação e oferece suporte à aplicação enquanto ela está em execução. Isso é diferente de um container init, que deve ser concluído antes que a aplicação inicie. Sidecars são comumente usados para envio de logs, proxy, sincronização ou outros comportamentos auxiliares que devem compartilhar o ciclo de vida do Pod.

Neste laboratório, você criará um Pod multi-container com um container de aplicação que grava linhas de log em um volume emptyDir compartilhado e um container sidecar que monitora esse arquivo. Você inspecionará ambos os containers, lerá os logs do sidecar e, em seguida, aplicará o mesmo padrão de sidecar em um template de Deployment.

Preparar um Namespace para Sidecar

Nesta etapa, você preparará um namespace limpo para praticar o uso de sidecars.

Comece em /home/labex/project. Você escreverá um manifesto de Pod e um manifesto de Deployment neste diretório.

mkdir -p /home/labex/project
cd /home/labex/project

Verifique se o servidor da API do Kubernetes está acessível. Se a VM acabou de iniciar e o nó ainda não está pronto, aguarde alguns segundos e execute o comando novamente.

kubectl get nodes --request-timeout=5s

A saída esperada inclui:

NAME         STATUS   ROLES           AGE   VERSION
labex-v135   Ready    control-plane   ...   v1.35...

Aguarde até que o Pod de rede do cluster esteja pronto (Ready) antes de criar cargas de trabalho.

kubectl wait --namespace kube-system --for=condition=Ready pod -l k8s-app=calico-node --timeout=120s

Saída esperada:

pod/calico-node-... condition met

Crie um namespace chamado ckad-prep-sidecar:

kubectl create namespace ckad-prep-sidecar

Defina este namespace como o namespace do contexto atual:

kubectl config set-context --current --namespace=ckad-prep-sidecar

Confirme o namespace atual:

kubectl config view --minify --output 'jsonpath={..namespace}'; echo

Saída esperada:

ckad-prep-sidecar

Criar um Pod Multi-Container

Nesta etapa, você criará um Pod com um container de aplicação e um container sidecar.

Ambos os containers montam o mesmo volume emptyDir em /var/log/shared. O container da aplicação grava linhas de log em /var/log/shared/app.log. O container sidecar é executado ao mesmo tempo e usa tail -f para transmitir esse arquivo. O comando touch cria o arquivo antes que o tail -f inicie, para que o sidecar possa aguardar com segurança, mesmo que a aplicação ainda não tenha gravado sua primeira linha.

Crie o arquivo sidecar-pod.yaml:

cat > sidecar-pod.yaml <<'EOF'
apiVersion: v1
kind: Pod
metadata:
  name: sidecar-demo
  labels:
    app: sidecar-demo
spec:
  terminationGracePeriodSeconds: 0
  volumes:
  - name: shared-logs
    emptyDir: {}
  containers:
  - name: app
    image: busybox:1.36
    command:
    - /bin/sh
    - -c
    - 'i=1; while true; do echo "app-line-${i}" >> /var/log/shared/app.log; i=$((i+1)); sleep 2; done'
    volumeMounts:
    - name: shared-logs
      mountPath: /var/log/shared
  - name: log-sidecar
    image: busybox:1.36
    command:
    - /bin/sh
    - -c
    - 'touch /var/log/shared/app.log; tail -n +1 -f /var/log/shared/app.log'
    volumeMounts:
    - name: shared-logs
      mountPath: /var/log/shared
EOF

Aplique o manifesto:

kubectl apply -f sidecar-pod.yaml

Saída esperada:

pod/sidecar-demo created

Aguarde até que o Pod esteja pronto (Ready). Um Pod multi-container só está pronto quando todos os seus containers regulares estiverem prontos.

kubectl wait --for=condition=Ready pod/sidecar-demo --timeout=120s

Saída esperada:

pod/sidecar-demo condition met

Liste os nomes dos containers no Pod:

kubectl get pod sidecar-demo -o 'jsonpath={.spec.containers[*].name}{"\n"}'

Saída esperada:

app log-sidecar

Inspecionar a Colaboração do Sidecar

Nesta etapa, você confirmará que ambos os containers estão em execução e que o sidecar está transmitindo o arquivo de log da aplicação.

Primeiro, inspecione a prontidão (readiness) dos containers. A saída imprime o nome de cada container e se ele está pronto.

kubectl get pod sidecar-demo -o 'jsonpath={range .status.containerStatuses[*]}{.name}{" "}{.ready}{"\n"}{end}'

A saída esperada inclui:

app true
log-sidecar true

Leia os logs do container da aplicação. A aplicação grava no stdout padrão apenas quando o comando shell inicia; suas linhas repetidas vão para o arquivo compartilhado.

kubectl logs sidecar-demo -c app --tail=5

O container da aplicação pode não imprimir linhas repetidas no stdout. A evidência importante está no arquivo compartilhado e nos logs do sidecar.

Leia o arquivo compartilhado através do container da aplicação:

kubectl exec sidecar-demo -c app -- sh -c 'tail -n 3 /var/log/shared/app.log'

A saída esperada inclui as linhas de log da aplicação:

app-line-...
app-line-...
app-line-...

Agora, leia os logs do sidecar. Como o sidecar monitora o mesmo arquivo, seus logs devem incluir o mesmo tipo de linhas.

kubectl logs sidecar-demo -c log-sidecar --tail=3

A saída esperada inclui:

app-line-...
app-line-...
app-line-...

Adicionar o Padrão Sidecar a um Deployment

Nesta etapa, você colocará o padrão sidecar em um template de Deployment.

Pods isolados são úteis para aprendizado, mas as aplicações geralmente são executadas por meio de controladores. Um Deployment pode criar Pods de substituição, e cada Pod de substituição incluirá tanto o container da aplicação quanto o container sidecar do template.

Crie o arquivo sidecar-deployment.yaml:

cat > sidecar-deployment.yaml <<'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
  name: sidecar-worker
spec:
  replicas: 1
  selector:
    matchLabels:
      app: sidecar-worker
  template:
    metadata:
      labels:
        app: sidecar-worker
    spec:
      terminationGracePeriodSeconds: 0
      volumes:
      - name: shared-logs
        emptyDir: {}
      containers:
      - name: app
        image: busybox:1.36
        command:
        - /bin/sh
        - -c
        - 'i=1; while true; do echo "worker-line-${i}" >> /var/log/shared/worker.log; i=$((i+1)); sleep 2; done'
        volumeMounts:
        - name: shared-logs
          mountPath: /var/log/shared
      - name: log-sidecar
        image: busybox:1.36
        command:
        - /bin/sh
        - -c
        - 'touch /var/log/shared/worker.log; tail -n +1 -f /var/log/shared/worker.log'
        volumeMounts:
        - name: shared-logs
          mountPath: /var/log/shared
EOF

Aplique o Deployment:

kubectl apply -f sidecar-deployment.yaml

Saída esperada:

deployment.apps/sidecar-worker created

Aguarde até que o Deployment esteja disponível:

kubectl wait --for=condition=Available deployment/sidecar-worker --timeout=120s

Saída esperada:

deployment.apps/sidecar-worker condition met

Encontre o Pod criado pelo Deployment:

worker_pod="$(kubectl get pods -l app=sidecar-worker -o 'jsonpath={.items[0].metadata.name}')"
echo "$worker_pod"

A saída esperada mostra um nome de Pod gerado:

sidecar-worker-...

Leia os logs do sidecar a partir do Pod criado pelo Deployment:

kubectl logs "$worker_pod" -c log-sidecar --tail=3

A saída esperada inclui:

worker-line-...
worker-line-...
worker-line-...

Resumo

Você criou um Pod multi-container com um container de aplicação e um container sidecar, usou um volume emptyDir para compartilhar um arquivo de log, confirmou que ambos os containers são executados juntos e moveu o mesmo padrão de sidecar para um template de Deployment. Agora você sabe quando um sidecar é adequado: ele oferece suporte à aplicação enquanto ela está em execução.