Introducción
Un contenedor sidecar se ejecuta en el mismo Pod que un contenedor de aplicación y sirve de apoyo a esta mientras se encuentra en funcionamiento. Esto es diferente a un contenedor de inicialización (init container), el cual debe finalizar antes de que la aplicación comience. Los sidecars se utilizan habitualmente para el envío de registros, proxy, sincronización u otras tareas auxiliares que deben compartir el ciclo de vida del Pod.
En este laboratorio, crearás un Pod multi-contenedor con un contenedor de aplicación que escribe líneas de registro en un volumen compartido emptyDir y un contenedor sidecar que realiza el seguimiento de dicho archivo. Inspeccionarás ambos contenedores, leerás los registros del sidecar y, finalmente, aplicarás el mismo patrón sidecar en una plantilla de Deployment.
Preparar un Namespace para el Sidecar
En este paso, prepararás un namespace limpio para practicar con sidecars.
Comienza en /home/labex/project. Escribirás un manifiesto de Pod y un manifiesto de Deployment en este directorio.
mkdir -p /home/labex/project
cd /home/labex/project
Comprueba que el servidor de la API de Kubernetes sea accesible. Si la máquina virtual acaba de iniciarse y el nodo aún no está listo, espera unos segundos y vuelve a ejecutar el comando.
kubectl get nodes --request-timeout=5s
La salida esperada incluye:
NAME STATUS ROLES AGE VERSION
labex-v135 Ready control-plane ... v1.35...
Espera a que el Pod de red del clúster esté listo (Ready) antes de crear cargas de trabajo.
kubectl wait --namespace kube-system --for=condition=Ready pod -l k8s-app=calico-node --timeout=120s
Salida esperada:
pod/calico-node-... condition met
Crea un namespace llamado ckad-prep-sidecar:
kubectl create namespace ckad-prep-sidecar
Establece este namespace como el namespace del contexto actual:
kubectl config set-context --current --namespace=ckad-prep-sidecar
Confirma el namespace actual:
kubectl config view --minify --output 'jsonpath={..namespace}'; echo
Salida esperada:
ckad-prep-sidecar
Crear un Pod multi-contenedor
En este paso, crearás un Pod con un contenedor de aplicación y un contenedor sidecar.
Ambos contenedores montan el mismo volumen emptyDir en /var/log/shared. El contenedor de la aplicación escribe líneas de registro en /var/log/shared/app.log. El contenedor sidecar se ejecuta al mismo tiempo y utiliza tail -f para transmitir ese archivo. El comando touch crea el archivo antes de que tail -f comience, por lo que el sidecar puede esperar de forma segura incluso si la aplicación aún no ha escrito su primera línea.
Crea 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
Aplica el manifiesto:
kubectl apply -f sidecar-pod.yaml
Salida esperada:
pod/sidecar-demo created
Espera hasta que el Pod esté listo (Ready). Un Pod multi-contenedor solo está listo cuando todos sus contenedores regulares están listos.
kubectl wait --for=condition=Ready pod/sidecar-demo --timeout=120s
Salida esperada:
pod/sidecar-demo condition met
Lista los nombres de los contenedores en el Pod:
kubectl get pod sidecar-demo -o 'jsonpath={.spec.containers[*].name}{"\n"}'
Salida esperada:
app log-sidecar
Inspeccionar la colaboración del Sidecar
En este paso, confirmarás que ambos contenedores están ejecutándose y que el sidecar está transmitiendo el archivo de registro de la aplicación.
Primero, inspecciona la disponibilidad (readiness) de los contenedores. La salida muestra el nombre de cada contenedor y si está listo.
kubectl get pod sidecar-demo -o 'jsonpath={range .status.containerStatuses[*]}{.name}{" "}{.ready}{"\n"}{end}'
La salida esperada incluye:
app true
log-sidecar true
Lee los registros del contenedor de la aplicación. La aplicación escribe en la salida estándar (stdout) solo cuando el comando shell comienza; sus líneas repetidas van al archivo compartido.
kubectl logs sidecar-demo -c app --tail=5
Es posible que el contenedor de la aplicación no imprima líneas repetidas en stdout. La evidencia importante se encuentra en el archivo compartido y en los registros del sidecar.
Lee el archivo compartido a través del contenedor de la aplicación:
kubectl exec sidecar-demo -c app -- sh -c 'tail -n 3 /var/log/shared/app.log'
La salida esperada incluye líneas de registro de la aplicación:
app-line-...
app-line-...
app-line-...
Ahora lee los registros del sidecar. Debido a que el sidecar sigue el mismo archivo, sus registros deben incluir el mismo tipo de líneas.
kubectl logs sidecar-demo -c log-sidecar --tail=3
La salida esperada incluye:
app-line-...
app-line-...
app-line-...
Añadir el patrón Sidecar a un Deployment
En este paso, integrarás el patrón sidecar en una plantilla de Deployment.
Los Pods independientes son útiles para aprender, pero las aplicaciones normalmente se ejecutan a través de controladores. Un Deployment puede crear Pods de reemplazo, y cada Pod de reemplazo incluirá tanto el contenedor de la aplicación como el contenedor sidecar definidos en la plantilla.
Crea 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
Aplica el Deployment:
kubectl apply -f sidecar-deployment.yaml
Salida esperada:
deployment.apps/sidecar-worker created
Espera hasta que el Deployment esté disponible:
kubectl wait --for=condition=Available deployment/sidecar-worker --timeout=120s
Salida esperada:
deployment.apps/sidecar-worker condition met
Busca el Pod creado por el Deployment:
worker_pod="$(kubectl get pods -l app=sidecar-worker -o 'jsonpath={.items[0].metadata.name}')"
echo "$worker_pod"
La salida esperada muestra un nombre de Pod generado:
sidecar-worker-...
Lee los registros del sidecar desde el Pod creado por el Deployment:
kubectl logs "$worker_pod" -c log-sidecar --tail=3
La salida esperada incluye:
worker-line-...
worker-line-...
worker-line-...
Resumen
Has creado un Pod multi-contenedor con un contenedor de aplicación y un contenedor sidecar, has utilizado un volumen emptyDir para compartir un archivo de registro, has confirmado que ambos contenedores se ejecutan juntos y has trasladado el mismo patrón sidecar a una plantilla de Deployment. Ahora sabes cuándo es adecuado utilizar un sidecar: cuando se necesita dar soporte a la aplicación mientras esta se encuentra en ejecución.


