Skip to content

Kubernetes Troubleshooting

El proceso de troubleshooting en kubernetes se refiere a identificar , diagnosticar y resolver problemas en clustes, nodos, pods o contenedores.

De una manera mas amplia tambien incluve un manejo y administracion efectivo de fallas y de toma de medidas cautelares para evitar fallos en los componentes de kubernetes.

Complejidad.

Kubernetes por naturaleza es un sistema muy complejo y esto hace que los problemas que se puedan presentar tambien lo sean, principalmente debido a la gran cantidad de componentes que puede interactuar entre ellos y la cantidad de recursos como tal cuando se posee un cluster productivo.

Existe varios tipos de errores comunes que pueden ser identificados facilmente, entre los que destacan los siguientes.

1.CreateContainerConfigError 2.ImagePullBackOff or ErrImagePull 3.CrashLoopBackOff 4.Kubernetes Node Not Ready

Laboratorio: Kubernetes Troubleshooting

Descripción

Existen una gran cantidad de errores que podemos experimentar en un cluster de kubernetes y en el siguiente laboratorio veremos varios de los errores mas comunes y como identificarlos.

Objetivos

  • Identificar issues comunes en un cluster de kubernetes.
  • Resolver issues comunes en un cluster de kubernetes.

Antes de comenzar

  • Contar con el acceso al ambiente del laboratorio
  • Haber realizado la guía de Instalación Rancher Kubernetes Engine (RKE)
  • Haber realizado la guía de Acceso a rancher y kubernetes cluster

Inicio de laboratorio

  1. Ingrese al CLI del sistema operativo del servidor usado como Bastion con el usuario y la contraseña proporcionados.

Ingresar al cluster de Kubernetes cluster-users con sus respectivas credenciales

Crear un nuevo namespace llamado example-troubleshooting

kubectl create ns example-troubleshooting

Establcer el nuevo namespace por defecto en el contexto actual:

kubectl config set-context --current --namespace=example-troubleshooting
2. Crear un nuevo archivo llamada config-error.yaml con el siguiente contenido.
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: config
  name: config
spec:
  containers:
  - image: nginx:alpine
    name: config
    resources: {}
    env:
      - name: key
        valueFrom:
          configMapKeyRef:
            name: key-config
            key: key
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}
3. Crear un pod utilizando el archivo anterior:
kubectl apply -f config-error.yaml
4. Verificar el estado del pod con el siguiente comando:
kubectl get pods
La salida debe ser parecida a la siguiente:
NAME     READY   STATUS                       RESTARTS   AGE
config   0/1     CreateContainerConfigError   0          8s
5. Podemos observar que el pod no se ha podido crear correctamente y muestra un error de CreateContainerConfigError, para obtener mas informacion de este error vamos a revisar los eventos.
kubectl get events
Vamos a buscar un error como el siguiente:
8m23s       Warning   Failed           pod/config   Error: configmap "key-config" not found
6. Este error nos dice que el configmap key-config que es utilizado por el pod no se encuentra en el cluster y para solucionarlo lo vamos a crear.
kubectl create configmap key-config --from-literal key=value
Obtenemos nuevamente los pods con el comando:
kubectl get pods
Observamos que el pod ya se encuentra disponible y ejecutandose.Finalmente eliminamos el pod

kubectl delete -f config-error.yaml
  1. Para el siguiente caso de troubleshooting vamos a crear un archivo llamado image-error.yaml con el siguiente contenido.
    apiVersion: v1
    kind: Pod
    metadata:
      creationTimestamp: null
      labels:
        run: config
      name: config
    spec:
      containers:
      - image: nginx-alpine
        name: config
        resources: {}
      dnsPolicy: ClusterFirst
      restartPolicy: Always
    status: {}
    
    Luego crearemos el pod con el siguiente comando
    kubectl apply -f image-error.yaml
    
  2. Obtenemos los pods con el comando
    Kubectl get pods
    
    Veremos los pods con el siguiente estado.
    Kubectl get pods
    NAME     READY   STATUS             RESTARTS   AGE
    config   0/1     ImagePullBackOff   0          2m58s
    
  3. Revisamos los eventos con el comando
    kubectl get events
    
    Nos debe de devolver algo parecido a lo siguiente:
    5m52s       Warning   Failed           pod/config   Failed to pull image "nginx-alpine": rpc error: code = Unknown desc = Error response from daemon: pull access denied for nginx-alpine, repository does not exist or may require 'docker login': denied: requested access to the resource is denied
    
  4. Este tipo de errores son bastante comunes , son los conocidos como ImagePullBackoff y significan que la imagen no ha podido ser descargada, esto puede ser por una gran cantidad de razones, empezando por un tag mal escrito o una imagen no existente, tambien que no se ha autenticado si se esta usando un registry privado o incluso que el registry de imagenes no este disponible.

En el caso de este error es debido a que la imagen fue mal escrita, para arreglar este error vamos a abrir el archivo que creamos anteriormente y vamos a cambiar la imagen a lo siguiente.

image: nginx:alpine
11. Actualizamos el pod
kubectl apply -f image-error.yaml
12. Verificamos que el pod se encuentre saludale
kubectl get pods
13. Para la siguiente parte de la guia vamos a crear un nuevo archivo llamado sql.yaml con el siguiente contenido.
apiVersion: apps/v1
kind: Deployment
metadata:
 name: mysql-deployment
spec:
 replicas: 1
 selector:
   matchLabels:
     app: mysql
 template:
   metadata:
     labels:
       app: mysql
   spec:
     containers:
     - name: mysql-container
       image: mysql:8.0
Luego creamos el pod con el comando

kubectl apply -f sql.yaml
  1. Obtenemos el pod con el comando

    kubectl get pods
    
    Observamos que el pod se encuentra en un estado de CrashLoopBackoff
    NAME                                READY   STATUS             RESTARTS       AGE
    mysql-deployment-5b6547d457-rtjk9   0/1     CrashLoopBackOff   6 (115s ago)   8m19s
    

  2. Este estado significa que hay algo mal a nivel de configuracion de la aplicacion o la aplicacion como tal, vamos a diagnosticar el pod con los siguientes pasos.

Primeramente vamos a describir el pod con el comando

kubectl describe pod <POD_NAME>
Y obsevamos el estado y la razon por la que el pod esta en este estado
 State:          Waiting
      Reason:       CrashLoopBackOff
    Last State:     Terminated
      Reason:       Error
      Exit Code:    1
Vemos que se encuentra en CrashloopBackoff y con un exit code de 1, si es diferente a 0 como en este caso indica que hay algo mal con el despliegue.

  1. Esta no es informacion suficiente para diagnosticar, el error, asi que veremos directamente los logs del aplicativo

kubectl logs <POD_NAME>
Veremos algo asi
You need to specify one of the following as an environment variable:
    - MYSQL_ROOT_PASSWORD
    - MYSQL_ALLOW_EMPTY_PASSWORD
    - MYSQL_RANDOM_ROOT_PASSWORD
El error nos dice que necesitamos darle una clave a sql, asi que haremos ese cambio.

  1. Agregar al archivo yaml lo siguiente
    env:
    - name: MYSQL_ROOT_PASSWORD
      value: secret-password
    
    Justo al final manteniendo la identacion.

Finalmente actualizamos el aplicativo.

kubectl apply -f sql.yaml
  1. Obtenemos los pods y vemos que ya se encuentra ejecutandose correctamente.

    kubectl get pods
    

  2. Limpiamos el ambiente

    kubectl delete ns example-troubleshooting