Guía de solución de problemas de Cassandra

En este tema, se analizan los pasos que puedes seguir para solucionar problemas con el almacén de datos Cassandra. Cassandra es un almacén de datos persistente que se ejecuta en el componente cassandra de la arquitectura del entorno de ejecución híbrida. Consulta también Descripción general de la configuración del servicio del entorno de ejecución.

Los pods de Cassandra están atascados en el estado pendiente

Síntoma

Cuando se inician, los pods de Cassandra permanecen en el estado Pending.

Mensaje de error

Cuando usas kubectl para ver los estados de los pods, verás que uno o más pods de Cassandra están atascados en el estado Pending. El estado Pending indica que Kubernetes no puede programar el pod en un nodo: el pod no se puede crear. Por ejemplo:

kubectl get pods -n namespace

NAME                                     READY   STATUS      RESTARTS   AGE
adah-resources-install-4762w             0/4     Completed   0          10m
apigee-cassandra-default-0               0/1     Pending     0          10m
...

Causas posibles

Un pod atascado en el estado Pending puede producirse por varias causas. Por ejemplo:

Causa Descripción
Recursos insuficientes No hay CPU ni memoria disponibles para crear el pod.
No se creó el volumen. El pod está esperando a que se cree el volumen persistente.

Diagnóstico

Usa kubectl para describir el pod a fin de determinar el origen del error. Por ejemplo:

kubectl -n namespace describe pods pod_name

Por ejemplo:

kubectl -n apigee describe pods apigee-cassandra-default-0

Puede que la salida muestre uno de estos problemas posibles:

  • Si el problema es que no hay recursos suficiente, verás un mensaje de advertencia que indica que la CPU o la memoria son insuficientes.
  • Si el mensaje de error indica que el pod tiene PersistentVolumeClaims (PVC) inmediatos desvinculados, significa que el pod no puede crear su volumen persistente.

Solución

Recursos insuficientes

Modifica el grupo de nodos de Cassandra para que tenga recursos suficientes de CPU y memoria. Consulta Cambia el tamaño de un grupo de nodos para obtener más detalles.

No se creó el volumen persistente.

Si determinas que hay un problema con el volumen persistente, describe el PersistentVolumeClaim (PVC) para determinar por qué no se está creando:

  1. Obtén una lista de los PVC en el clúster:
    kubectl -n namespace get pvc
    
    NAME                                        STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
    cassandra-data-apigee-cassandra-default-0   Bound    pvc-b247faae-0a2b-11ea-867b-42010a80006e   10Gi       RWO            standard       15m
    ...
  2. Describe el PVC para el pod que falla. Por ejemplo, el siguiente comando describe el PVC vinculado al pod apigee-cassandra-default-0:
    kubectl apigee describe pvc cassandra-data-apigee-cassandra-default-0
    
    Events:
      Type     Reason              Age                From                         Message
      ----     ------              ----               ----                         -------
      Warning  ProvisioningFailed  3m (x143 over 5h)  persistentvolume-controller  storageclass.storage.k8s.io "apigee-sc" not found

    Ten en cuenta que, en este ejemplo, no existe la StorageClass llamada apigee-sc. Para resolver este problema, crea la StorageClass faltante en el clúster, como se explica en Cambia la StorageClass predeterminada.

Consulta también Depura pods.

Los pods de Cassandra están atascados en el estado CrashLoopBackoff.

Síntoma

Cuando se inician, los pods de Cassandra permanecen en el estado CrashLoopBackoff.

Mensaje de error

Cuando usas kubectl para ver los estados de los Pods, verás que uno o más pods de Cassandra tienen el estado CrashLoopBackoff. Este estado indica que Kubernetes no puede crear el pod. Por ejemplo:

kubectl get pods -n namespace

NAME                                     READY   STATUS            RESTARTS   AGE
adah-resources-install-4762w             0/4     Completed         0          10m
apigee-cassandra-default-0               0/1     CrashLoopBackoff  0          10m
...

Causas posibles

Un pod atascado en el estado CrashLoopBackoff puede producirse por varias causas. Por ejemplo:

Causa Descripción
El centro de datos difiere del centro de datos anterior Este error indica que el pod de Cassandra tiene un volumen persistente que contiene datos de un clúster anterior, y los pods nuevos no pueden unirse al clúster anterior. Esto suele ocurrir cuando los volúmenes persistentes inactivos persisten desde el clúster anterior de Cassandra en el mismo nodo de Kubernetes. Este problema puede ocurrir si borras y vuelves a crear Cassandra en el clúster.
No se encontró el directorio de Truststore. Este error indica que el pod de Cassandra no puede crear una conexión TLS. Por lo general, esto sucede cuando faltan las claves y los certificados proporcionados, o si no son válidos o tienen otros problemas.

Diagnóstico

Revisa el registro de errores de Cassandra para determinar la causa del problema.

  1. Enumera los pods para obtener el ID del pod de Cassandra que está fallando:
    kubectl get pods -n namespace
  2. Verifica el registro del Pod que falla:
    kubectl logs pod_id -n namespace

Solución

Busca las siguientes pistas en el registro del Pod:

El centro de datos difiere del centro de datos anterior

Si ves este mensaje de registro, haz lo siguiente:

Cannot start node if snitch's data center (us-east1) differs from previous data center
  • Verifica si hay algún PVC obsoleto o antiguo en el clúster y bórralo.
  • Si se trata de una instalación nueva, borra todos los PVC y vuelve a intentar la configuración. Por ejemplo:
    kubectl -n namespace get pvc
    kubectl -n namespace delete pvc cassandra-data-apigee-cassandra-default-0

No se encontró el directorio de Truststore.

Si ves este mensaje de registro, haz lo siguiente:

Caused by: java.io.FileNotFoundException: /apigee/cassandra/ssl/truststore.p12
(No such file or directory)

Verifica que la clave y los certificados, si se proporcionan en tu archivo de anulación, sean correctos y válidos. Por ejemplo:

cassandra:
  sslRootCAPath: path_to_root_ca-file
  sslCertPath: path-to-tls-cert-file
  sslKeyPath: path-to-tls-key-file

Falla del nodo

Síntoma

Cuando se inician, los pods de Cassandra permanecen en el estado Pending. Este problema puede indicar una falla subyacente en el nodo.

Diagnóstico

  1. Determina qué Pods de Cassandra no se están ejecutando:
    $ kubectl get pods -n your_namespace
        NAME                  READY   STATUS    RESTARTS   AGE
        cassandra-default-0   0/1     Pending   0          13s
        cassandra-default-1   1/1     Running   0          8d
        cassandra-default-2   1/1     Running   0          8d
  2. Verifica los nodos trabajadores. Si uno está en el estado NotReady, ese es el nodo que falló:
    kubectl get nodes -n your_namespace
    NAME                          STATUS   ROLES          AGE   VERSION
    ip-10-30-1-190.ec2.internal   Ready    <none>   8d    v1.13.2
    ip-10-30-1-22.ec2.internal    Ready    master   8d    v1.13.2
    ip-10-30-1-36.ec2.internal    NotReady <none>   8d    v1.13.2
    ip-10-30-2-214.ec2.internal   Ready    <none>   8d    v1.13.2
    ip-10-30-2-252.ec2.internal   Ready    <none>   8d    v1.13.2
    ip-10-30-2-47.ec2.internal    Ready    <none>   8d    v1.13.2
    ip-10-30-3-11.ec2.internal    Ready    <none>   8d    v1.13.2
    ip-10-30-3-152.ec2.internal   Ready    <none>   8d    v1.13.2
    ip-10-30-3-5.ec2.internal     Ready    <none>   8d    v1.13.2

Solución

  1. Quita el pod inactivo de Cassandra del clúster.
    $ kubectl exec -it apigee-cassandra-default-0 -- nodetool status
    $ kubectl exec -it apigee-cassandra-default-0 -- nodetool removenode deadnode_hostID
  2. Quita la VolumeClaim del nodo inactivo para evitar que el pod de Cassandra intente alcanzar ese nodo debido a la afinidad:
    kubectl get pvc -n your_namespace
    kubectl delete pvc volumeClaim_name -n your_namespace
  3. Actualiza la plantilla de volumen y crea PersistentVolume para el nodo recién agregado. La siguiente es una plantilla de volumen de ejemplo:
    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: cassandra-data-3
    spec:
      capacity:
        storage: 100Gi
      accessModes:
      - ReadWriteOnce
      persistentVolumeReclaimPolicy: Retain
      storageClassName: local-storage
      local:
        path: /apigee/data
      nodeAffinity:
        "required":
          "nodeSelectorTerms":
          - "matchExpressions":
            - "key": "kubernetes.io/hostname"
              "operator": "In"
              "values": ["ip-10-30-1-36.ec2.internal"]
  4. Reemplaza los valores por el nombre de host o IP nuevos y aplica la plantilla:
    kubectl apply -f volume-template.yaml

Crea un contenedor del cliente para depurar

En esta sección, se explica cómo crear un contenedor del cliente desde el que puedes acceder a las utilidades de depuración de Cassandra, como cqlsh. Estas utilidades te permiten consultar tablas de Cassandra y pueden ser útiles para fines de depuración.

Crea el contenedor del cliente

Para crear el contenedor del cliente, sigue estos pasos:

  1. El contenedor usa el certificado TLS del pod apigee-cassandra-user-setup. El primer paso es recuperar este nombre de certificado:
    kubectl get secrets -n apigee |grep "kubernetes.io/tls"|grep apigee-cassandra-user-setup|awk '{print $1}'

    Este comando muestra el nombre del certificado. Por ejemplo: apigee-cassandra-user-setup-rg-hybrid-b7d3b9c-tls.

  2. A continuación, recupera el nombre del secreto del almacén de datos:
    kubectl get secrets -n apigee | grep "datastore.*-creds" | awk '{print $1}' 
  3. Abre un archivo nuevo y pega en él las siguientes especificaciones del pod:
    apiVersion: v1
    kind: Pod
    metadata:
      labels:
      name: cassandra-client-name   # For example: my-cassandra-client
      namespace: apigee
    spec:
      containers:
      - name: cassandra-client-name
        image: "google/apigee-hybrid-cassandra-client:1.5.0"
        imagePullPolicy: Always
        command:
        - sleep
        - "3600"
        env:
        - name: CASSANDRA_SEEDS
          value: apigee-cassandra-default.apigee.svc.cluster.local
        - name: APIGEE_DML_USER
          valueFrom:
            secretKeyRef:
              key: dml.user
              name: default-datastore-creds  # The datastore secret name fetched previously.
        - name: APIGEE_DML_PASSWORD
          valueFrom:
            secretKeyRef:
              key: dml.password
              name: default-datastore-creds  # The datastore secret name fetched previously.
        volumeMounts:
        - mountPath: /opt/apigee/ssl
          name: tls-volume
          readOnly: true
      volumes:
      - name: tls-volume
        secret:
          defaultMode: 420
          secretName: your-secret-name    # For example: apigee-cassandra-user-setup-rg-hybrid-b7d3b9c-tls
      restartPolicy: Never
  4. Guarda el archivo con una extensión .yaml. Por ejemplo: my-spec.yaml.
  5. Aplica la especificación al clúster:
    kubectl apply -f your-spec-file.yaml -n apigee
  6. Accede al contenedor:
    kubectl exec -n apigee cassandra-client -it -- bash
  7. Conéctate a la interfaz cqlsh de Cassandra con el siguiente comando. Ingresa el comando exactamente como se muestra a continuación:
    cqlsh ${CASSANDRA_SEEDS} -u ${APIGEE_DML_USER} -p ${APIGEE_DML_PASSWORD} --ssl

Borra el pod del cliente

Usa este comando para borrar el pod cliente de Cassandra:

kubectl delete pods -n apigee cassandra-client