Cassandra 문제 해결 가이드

이 주제에서는 Cassandra Datastore 문제를 해결하기 위해 취할 수 있는 조치를 설명합니다. Cassandra는 하이브리드 런타임 아키텍처cassandra 구성요소에서 실행되는 영구 Datastore입니다. 런타임 서비스 구성 개요도 참조하세요.

Cassandra Pod가 대기중 상태로 멈춰 있음

증상

시작하면 Cassandra Pod가 대기중 상태로 유지됩니다.

오류 메시지

kubectl를 사용하여 Pod 상태를 보면 하나 이상의 Cassandra Pod가 Pending 상태로 멈춰 있습니다. Pending 상태는 Kubernetes가 노드에서 pod를 예약할 수 없음을 나타냅니다. pod는 생성 불가합니다. 예를 들면 다음과 같습니다.

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
...

가능한 원인

Pod가 대기중 상태로 멈춰 있는 이유는 여러 가지일 수 있습니다. 예를 들면 다음과 같습니다.

원인 설명
리소스 부족 Pod를 만드는 데 사용할 수 있는 CPU 또는 메모리가 부족합니다.
볼륨이 생성되지 않음 Pod는 영구 볼륨이 생성될 때까지 대기합니다.

진단

오류 원인을 파악하기 위해 kubectl을 사용하여 Pod를 설명합니다. 예를 들면 다음과 같습니다.

kubectl -n namespace describe pods pod_name

예를 들면 다음과 같습니다.

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

출력에 다음 문제 중 하나가 나타날 수 있습니다.

  • 리소스 부족이 문제가 될 경우 CPU 또는 메모리가 부족하다는 경고 메시지가 표시됩니다.
  • Pod에 바인딩되지 않은 즉각적인 PersistentVolumeClaim(PVC)이 있음을 나타내는 오류 메시지가 나타날 경우 Pod에서 영구 볼륨을 만들 수 없다는 의미입니다.

해결 방법

리소스 부족

CPU 및 메모리 리소스가 충분하도록 Cassandra 노드 풀을 수정합니다. 자세한 내용은 노드 풀 크기 조정을 참조하세요.

영구 볼륨이 생성되지 않음

영구 볼륨 문제가 있다고 판단되면 PersistentVolumeClaim(PVC)을 설명하여 해당 문제가 생성되지 않는 이유를 확인합니다.

  1. 클러스터의 PVC를 나열합니다.
    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. 실패한 pod의 PVC를 설명합니다. 예를 들어 다음 명령어는 Pod apigee-cassandra-default-0에 바인딩된 PVC를 설명합니다.
    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

    이 예시에서는 이름이 apigee-sc인 StorageClass가 존재하지 않습니다. 이 문제를 해결하려면 기본 StorageClass 변경에 설명된 대로 클러스터에 누락된 StorageClass를 만듭니다.

Pod 디버깅도 참조하세요.

Cassandra Pod가 CrashLoopBackoff 상태로 멈춰 있음

증상

시작하면 Cassandra Pod가 CrashLoopBackoff 상태로 유지됩니다.

오류 메시지

kubectl를 사용하여 Pod 상태를 보면 하나 이상의 Cassandra Pod가 CrashLoopBackoff 상태가 됩니다. 이 상태는 Kubernetes가 Pod를 만들 수 없음을 나타냅니다. 예를 들면 다음과 같습니다.

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
...

가능한 원인

Pod가 CrashLoopBackoff 상태로 멈춰 있는 이유는 여러 가지일 수 있습니다. 예를 들면 다음과 같습니다.

원인 설명
데이터 센터가 이전 데이터 센터와 다름 이 오류는 이전 클러스터의 데이터가 있는 영구 볼륨이 Cassandra Pod에 있으며 새 Pod가 이전 클러스터에 조인할 수 없음을 나타냅니다. 이러한 현상은 보통 비활성 영구 볼륨이 동일한 Kubernetes 노드에 있는 이전 Cassandra 클러스터에서 지속될 때 발생합니다. 이 문제는 클러스터에서 Cassandra를 삭제하고 다시 만드는 경우에 발생할 수 있습니다.
Truststore 디렉터리를 찾을 수 없음 이 오류는 Cassandra Pod가 TLS 연결을 생성할 수 없음을 나타냅니다. 이러한 현상은 제공된 키와 인증서가 유효하지 않거나 누락되거나 다른 문제가 있을 때 발생합니다.

진단

Cassandra 오류 로그를 확인하여 문제의 원인을 파악합니다.

  1. Pod를 나열하여 실패한 Cassandra Pod의 ID를 가져옵니다.
    kubectl get pods -n namespace
  2. 실패한 Pod의 로그를 확인합니다.
    kubectl logs pod_id -n namespace

해결 방법

Pod 로그에서 다음 단서를 확인합니다.

데이터 센터가 이전 데이터 센터와 다름

이 로그 메시지가 표시되는 경우:

Cannot start node if snitch's data center (us-east1) differs from previous data center
  • 클러스터에 비활성 또는 이전 PVC가 있는지 확인하고 삭제합니다.
  • 새로 설치한 경우 PVC를 모두 삭제하고 설정을 다시 시도합니다. 예를 들면 다음과 같습니다.
    kubectl -n namespace get pvc
    kubectl -n namespace delete pvc cassandra-data-apigee-cassandra-default-0

Truststore 디렉터리를 찾을 수 없음

이 로그 메시지가 표시되는 경우:

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

재정의 파일에 제공된 키와 인증서가 올바르고 유효한지 확인합니다. 예를 들면 다음과 같습니다.

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

노드 장애

증상

시작하면 Cassandra Pod가 대기중 상태로 유지됩니다. 이 문제는 기본 노드 오류를 나타낼 수 있습니다.

진단

  1. 실행되고 있지 않은 Cassandra Pod를 확인합니다.
    $ 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. 워커 노드를 확인합니다. NotReady 상태인 워커 노드는 실패한 노드입니다.
    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

해결 방법

  1. 클러스터에서 죽은 Cassandra Pod를 삭제합니다.
    $ kubectl exec -it apigee-cassandra-default-0 -- nodetool status
    $ kubectl exec -it apigee-cassandra-default-0 -- nodetool removenode deadnode_hostID
  2. 죽은 노드에서 VolumeClaim을 삭제하여 어피니티로 인해 Cassandra Pod가 죽은 노드에서 가동되지 않도록 합니다.
    kubectl get pvc -n your_namespace
    kubectl delete pvc volumeClaim_name -n your_namespace
  3. 볼륨 템플릿을 업데이트하고 새로 추가된 노드의 PersistentVolume을 만듭니다. 다음은 볼륨 템플릿 예시입니다.
    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. 값을 새 호스트 이름/IP로 바꾸고 템플릿을 적용합니다.
    kubectl apply -f volume-template.yaml

디버깅을 위한 클라이언트 컨테이너 만들기

이 섹션에서는 cqlsh와 같이 Cassandra 디버깅 유틸리티에 액세스할 수 있는 클라이언트 컨테이너를 만드는 방법을 설명합니다. 이러한 유틸리티는 Cassandra 테이블을 쿼리할 수 있고 디버깅 목적에 유용할 수 있습니다.

클라이언트 컨테이너 만들기

클라이언트 컨테이너를 만들려면 다음 단계를 따르세요.

  1. 컨테이너에는 apigee-cassandra-user-setup Pod의 TLS 인증서가 사용됩니다. 첫 번째 단계는 이 인증서 이름을 가져오는 것입니다.
    kubectl get secrets -n apigee |grep "kubernetes.io/tls"|grep apigee-cassandra-user-setup|awk '{print $1}'

    이 명령어는 인증서 이름을 반환합니다. 예를 들면 apigee-cassandra-user-setup-rg-hybrid-b7d3b9c-tls입니다.

  2. 그런 후 Datastore 보안 비밀 이름을 가져옵니다.
    kubectl get secrets -n apigee | grep "datastore.*-creds" | awk '{print $1}' 
  3. 새 파일을 열고 다음 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. .yaml 확장으로 파일을 저장합니다. 예를 들면 my-spec.yaml입니다.
  5. 클러스터에 사양을 적용합니다.
    kubectl apply -f your-spec-file.yaml -n apigee
  6. 컨테이너에 로그인합니다.
    kubectl exec -n apigee cassandra-client -it -- bash
  7. 다음 명령어를 사용하여 Cassandra cqlsh 인터페이스에 연결합니다. 명령어를 다음과 같이 정확하게 입력합니다.
    cqlsh ${CASSANDRA_SEEDS} -u ${APIGEE_DML_USER} -p ${APIGEE_DML_PASSWORD} --ssl

클라이언트 Pod 삭제

다음 명령어를 사용하여 Cassandra 클라이언트 Pod를 삭제합니다.

kubectl delete pods -n apigee cassandra-client