Uso de exec y reenvío de puertos para depuración

KubernetesBeginner
Practicar Ahora

Introducción

El laboratorio anterior se centró en registros (logs) y eventos. Esas son las primeras señales, pero a veces también es necesario inspeccionar un contenedor en ejecución o acceder temporalmente a un Servicio desde su terminal. Kubernetes proporciona dos herramientas comunes para esto: kubectl exec y kubectl port-forward.

En este laboratorio, implementará una pequeña aplicación web, utilizará kubectl exec para inspeccionar archivos y procesos dentro de un Pod, y usará kubectl port-forward para abrir una conexión local temporal al Servicio. El flujo de trabajo es intencionalmente sencillo para que pueda concentrarse en las técnicas de depuración en lugar de en la complejidad de la aplicación.

Preparar un espacio de nombres para depuración

En este paso, preparará un espacio de nombres (namespace) limpio para practicar exec y port-forward.

Comience en /home/labex/project. Mantendrá el manifiesto de la aplicación en este directorio.

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

Compruebe que el servidor de API de Kubernetes sea accesible. Si la máquina virtual acaba de iniciarse y el nodo aún no está listo, espere unos segundos y vuelva 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...

Espere hasta que el Pod de red del clúster esté listo. El reenvío de puertos utiliza la conexión del servidor de API, pero la aplicación aún necesita un Pod y un Servicio en buen estado.

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

Salida esperada:

pod/calico-node-... condition met

Cree un espacio de nombres llamado ckad-prep-debug y establézcalo como el espacio de nombres actual:

kubectl create namespace ckad-prep-debug
kubectl config set-context --current --namespace=ckad-prep-debug

Confirme el espacio de nombres actual:

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

Salida esperada:

ckad-prep-debug

Implementar una pequeña aplicación web

En este paso, implementará una aplicación sencilla para inspeccionar y acceder a ella.

El Pod escribe un archivo index.html y ejecuta httpd de BusyBox en el puerto 8080. Un Servicio llamado debug-web expone los Pods dentro del clúster en el puerto 80. El Servicio se incluye porque kubectl port-forward puede apuntar tanto a un Servicio como a un Pod.

Cree debug-web.yaml:

cat > debug-web.yaml <<'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
  name: debug-web
spec:
  replicas: 2
  selector:
    matchLabels:
      app: debug-web
  template:
    metadata:
      labels:
        app: debug-web
    spec:
      terminationGracePeriodSeconds: 0
      containers:
      - name: web
        image: busybox:1.36
        command:
        - /bin/sh
        - -c
        - |
          mkdir -p /www
          echo "debug-web-ready" > /www/index.html
          httpd -f -p 8080 -h /www
        ports:
        - containerPort: 8080
        readinessProbe:
          httpGet:
            path: /
            port: 8080
          initialDelaySeconds: 1
          periodSeconds: 2
---
apiVersion: v1
kind: Service
metadata:
  name: debug-web
spec:
  selector:
    app: debug-web
  ports:
  - port: 80
    targetPort: 8080
EOF

Aplique el manifiesto y espere a que finalice el despliegue:

kubectl apply -f debug-web.yaml
kubectl rollout status deployment/debug-web --timeout=120s

La salida esperada incluye:

deployment.apps/debug-web created
service/debug-web created
deployment "debug-web" successfully rolled out

Inspeccione los Pods y el Servicio:

kubectl get pods -l app=debug-web
kubectl get service debug-web

La salida esperada incluye dos Pods en ejecución y un Servicio de tipo ClusterIP:

debug-web-...   1/1   Running
debug-web       ClusterIP

Inspeccionar un contenedor en ejecución con exec

En este paso, utilizará kubectl exec para ejecutar comandos dentro de un Pod de la aplicación.

kubectl exec es útil cuando el Pod está en ejecución pero necesita inspeccionar lo que ve el contenedor. No reemplaza a los registros y no debe usarse para realizar correcciones manuales ocultas durante una implementación normal. En un flujo de trabajo de depuración, le ayuda a confirmar archivos, procesos, entorno y el comportamiento de la red local desde dentro del contenedor.

Almacene el nombre de un Pod en una variable de shell:

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

La salida esperada es el nombre de un Pod:

debug-web-...

Ejecute hostname dentro del contenedor. La salida debe coincidir con el nombre del Pod, ya que Kubernetes establece el nombre de host del contenedor a partir del nombre del Pod.

kubectl exec "$POD_NAME" -- hostname

Salida esperada:

debug-web-...

Enumere los procesos en ejecución dentro del contenedor:

kubectl exec "$POD_NAME" -- ps

La salida esperada incluye el proceso httpd:

PID   USER     TIME  COMMAND
...   root     ...   httpd -f -p 8080 -h /www

Lea el archivo servido por el servidor web:

kubectl exec "$POD_NAME" -- cat /www/index.html

Salida esperada:

debug-web-ready

Finalmente, pruebe el servidor web desde dentro del mismo contenedor:

kubectl exec "$POD_NAME" -- wget -qO- http://127.0.0.1:8080

Salida esperada:

debug-web-ready

Probar el Servicio con reenvío de puertos

En este paso, utilizará kubectl port-forward para acceder al Servicio desde su terminal.

El reenvío de puertos crea un túnel temporal desde un puerto local a un Pod o Servicio en el clúster. Es útil para una depuración rápida porque no requiere cambiar el tipo de Servicio, crear un Ingress o abrir acceso externo. Un comando kubectl port-forward en primer plano sigue ejecutándose hasta que lo detiene, por lo que este laboratorio lo inicia en segundo plano, lo prueba y luego lo detiene.

Inicie un reenvío de puertos desde el puerto local 18080 al puerto 80 del Servicio. La salida se escribe en /tmp/debug-web-port-forward.log para que la terminal siga siendo utilizable.

kubectl port-forward service/debug-web 18080:80 > /tmp/debug-web-port-forward.log 2>&1 &
PF_PID=$!
sleep 3
cat /tmp/debug-web-port-forward.log

La salida esperada incluye:

Forwarding from 127.0.0.1:18080 -> 8080

Envíe una solicitud a través del puerto local reenviado:

wget -qO- http://127.0.0.1:18080

Salida esperada:

debug-web-ready

Detenga el proceso de reenvío de puertos en segundo plano. Esta limpieza es importante porque, de lo contrario, el puerto local permanecería en uso.

kill "$PF_PID"
wait "$PF_PID" 2>/dev/null || true

Confirme que el registro de reenvío de puertos registró una conexión gestionada:

cat /tmp/debug-web-port-forward.log

La salida esperada incluye:

Handling connection for 18080

Resumen

Ha practicado dos herramientas de depuración prácticas. Utilizó kubectl exec para inspeccionar el nombre de host, los procesos, los archivos y la respuesta HTTP de localhost de un contenedor en ejecución. También utilizó kubectl port-forward para crear una conexión local temporal a un Servicio de tipo ClusterIP, la probó desde la terminal y detuvo el proceso de reenvío en segundo plano de forma limpia.