외부 Cassandra 데이터 스토어 사용

이 주제에서는 Apigee Hybrid 런타임을 다른 Kubernetes 클러스터의 Cassandra 데이터 스토어에 연결하는 방법을 설명합니다. 이 구성에서는 런타임 클러스터에 Cassandra 포드가 없습니다. 이 구성의 이름은 외부 데이터 저장소 모드입니다.

2개 클러스터 토폴로지

외부 데이터 스토어 모드는 다음 두 Kubernetes 클러스터를 사용합니다.

  • Cassandra 클러스터는 Cassandra 링을 실행합니다. 하이브리드 런타임 구성요소를 실행하지 않습니다.
  • 런타임 클러스터는 하이브리드 런타임 구성요소를 실행하지만 Cassandra 포드가 없습니다. 런타임 구성요소는 네트워크를 통해 Cassandra 클러스터의 Cassandra 링에 연결됩니다.

Apigee 연산자는 두 클러스터에서 모두 실행됩니다. 각 클러스터에 cert-manager, Apigee 커스텀 리소스 정의 (CRD), apigee-operator 차트를 설치합니다. 다음 표는 각 클러스터의 구성요소를 보여줍니다.

구성요소 Cassandra 클러스터 런타임 클러스터
cert-manager 예 예
Apigee CRD 및 apigee-operator 차트 예 예
apigee-datastore 차트 예, Cassandra 포드 사용 예, replicaCount: 0 사용 및 Cassandra 포드 없음
apigee-telemetry, apigee-redis, apigee-ingress-manager, apigee-org, apigee-env, apigee-virtualhost과 같은 기타 모든 하이브리드 차트 아니요 예

Apigee 연산자는 클러스터마다 다른 작업을 실행합니다.

  • Cassandra 클러스터에서 운영자는 Cassandra 포드를 만듭니다. 또한 링을 확장할 때와 같이 Cassandra 수명 주기를 관리합니다.
  • 런타임 클러스터에서 연산자는 Cassandra 포드를 만들지 않습니다. Cassandra 클러스터의 Cassandra 링을 가리키는 헤드리스 서비스와 엔드포인트 객체를 만듭니다. 동적 엔드포인트 동기화를 사용 설정하면 런타임 클러스터의 작업자도 Cassandra 클러스터에서 Cassandra 엔드포인트를 읽습니다.

설정 개요

다음 순서대로 단계를 실행합니다. 순서가 중요합니다. 런타임 클러스터가 인증서를 발급하기 전에 공유 인증 기관 (CA)이 런타임 클러스터에 있어야 합니다. 자세한 내용은 연산자를 설치하기 전에 Apigee CA 공유를 참고하세요.

  1. Cassandra 클러스터에 cert-manager, Apigee CRD, apigee-operator 차트, apigee-datastore 차트를 설치합니다.
  2. Cassandra 클러스터의 Cassandra 포드가 준비되었는지 확인합니다.
  3. 런타임 클러스터에 cert-manager를 설치합니다.
  4. Cassandra 클러스터에서 런타임 클러스터로 apigee-ca 보안 비밀을 복사합니다. 런타임 클러스터에 apigee-operator 차트를 설치하기 전에 이 단계를 실행하세요.
  5. 런타임 클러스터에서 하이브리드 런타임 구성요소를 설치합니다. apigee-datastore 차트에 외부 데이터 스토어 재정의를 사용합니다. Cassandra 클러스터와 동일한 Cassandra 사용자 인증 정보를 사용합니다.
  6. (권장) 동적 엔드포인트 동기화를 사용 설정합니다.
  7. 연결을 확인합니다.

각 차트를 설치하는 단계는 Helm을 사용하여 Apigee Hybrid 설치를 참고하세요.

시작하기 전에

환경이 다음 요구사항을 충족하는지 확인합니다.

  • Cassandra에 대한 네트워크 연결 런타임 클러스터는 TCP 포트 9042에서 Cassandra 포드에 연결해야 합니다. 두 클러스터를 공유 VPC 또는 클러스터 간 비공개 연결이 있는 네트워크에 배치합니다.
  • 하나의 리전. 두 클러스터를 동일한 리전에 배치합니다. 클러스터 간 왕복 시간이 각 런타임 요청의 지연 시간에 추가됩니다.
  • 두 클러스터의 cert-manager 각 클러스터에서 cert-manager는 런타임과 Cassandra 간의 mTLS 연결을 위한 인증서를 발급합니다. Cassandra 클러스터와 런타임 클러스터에 cert-manager를 설치합니다.
  • 각 Cassandra 포드로 연결되는 경로 Cassandra 클라이언트 드라이버는 각 Cassandra 포드에 직접 연결됩니다. 런타임 클러스터는 하나의 주소에만 연결되는 것이 아니라 각 Cassandra 포드의 IP 주소에 연결되어야 합니다. 링 앞에 있는 부하 분산기 또는 단일 가상 IP 주소는 이 요구사항을 충족하지 않습니다.
  • Kubernetes API 서버에 대한 네트워크 연결 이 요구사항은 동적 엔드포인트 동기화를 사용하는 경우에만 적용됩니다. 런타임 클러스터는 Cassandra 클러스터의 Kubernetes API 서버에 연결해야 합니다.

연산자를 설치하기 전에 Apigee CA 공유

런타임 클러스터에 cert-manager를 설치합니다. 그런 다음 Cassandra 클러스터에서 런타임 클러스터로 CA 보안 비밀을 복사합니다.

kubectl --context CASSANDRA_CLUSTER -n cert-manager get secret apigee-ca -o yaml \
  | grep -v -E '^\s+(resourceVersion|uid|creationTimestamp|selfLink):' \
  | kubectl --context RUNTIME_CLUSTER -n cert-manager apply -f -

다음을 바꿉니다.

  • CASSANDRA_CLUSTER: Cassandra 클러스터의 kubectl 컨텍스트입니다.
  • RUNTIME_CLUSTER: 런타임 클러스터의 kubectl 컨텍스트입니다.

grep 명령어는 Cassandra 클러스터에 속하는 메타데이터 필드를 삭제합니다. Kubernetes API 서버는 resourceVersion 값이 있는 객체를 만들지 않습니다.

멀티 리전 설치는 동일한 공유 CA 원칙을 사용합니다. 유사한 복사 단계는 루트 CA 인증서 순환을 참고하세요. Cassandra mTLS 구성은 Cassandra용 인증 구성을 참고하세요.

두 클러스터에서 동일한 Cassandra 사용자 인증 정보 사용

두 클러스터의 재정의 파일에서 다음 방법 중 하나를 사용하세요.

  • cassandra.auth(default, admin, ddl, dml, jmx, jolokia)에서 동일한 사용자 이름과 비밀번호를 설정합니다.
  • cassandra.auth.secret을 설정합니다. 각 클러스터에서 시크릿에는 동일한 사용자 및 비밀번호가 포함되어야 합니다. 보안 비밀 만들기를 참고하세요.
  • cassandra.auth.secretProviderClass을 동일한 보안 비밀 스토어를 읽는 SecretProviderClass로 설정합니다. Hashicorp Vault에 Cassandra 보안 비밀 저장을 참고하세요.

Cassandra 클러스터에서 사용자 인증 정보 보안 비밀을 복사하지 않습니다. 런타임 클러스터의 차트는 재정의에서 보안 비밀을 만듭니다. 인증 실패를 확인하려면 연결 확인을 참고하세요.

외부 데이터 스토어 구성

런타임 클러스터에서 apigee-datastore 차트는 Cassandra 포드를 만들면 안 됩니다. Cassandra 클러스터의 Cassandra 링을 가리켜야 합니다. 다음 cassandra 설정을 런타임 클러스터의 재정의 파일에 추가합니다.

cassandra:
  # No Cassandra pods in the runtime cluster.
  replicaCount: 0
  properties:
    # A comma-separated list of the Cassandra pod IP addresses.
    externalHost: "CASSANDRA_IP_ADDRESSES"
  storage:
    # Required, even with replicaCount: 0.
    storageSize: "10Gi"

각 항목의 의미는 다음과 같습니다.

  • CASSANDRA_IP_ADDRESSES는 Cassandra 클러스터에 있는 Cassandra 포드의 IP 주소 목록으로, 쉼표로 구분됩니다. 예를 들면 10.0.0.1:9042,10.0.0.2:9042,10.0.0.3:9042입니다. :9042 접미사는 선택사항입니다. 목록을 가져오려면 다음 명령어를 실행합니다.
    kubectl --context CASSANDRA_CLUSTER -n APIGEE_NAMESPACE get pods -l app=apigee-cassandra \
      -o jsonpath='{.items[*].status.podIP}' | tr ' ' ','
  • APIGEE_NAMESPACE: Apigee 네임스페이스 기본값은 apigee입니다.
  • replicaCount: 0는 런타임 클러스터에 Cassandra 포드를 만들지 않도록 연산자에게 지시합니다. 작업자는 externalHost 주소를 가리키는 헤드리스 서비스와 엔드포인트 객체를 만듭니다.
  • cassandra.properties.externalHost는 쉼표로 구분된 Cassandra IP 주소 목록입니다. 각 주소에는 :port 접미사가 있을 수 있지만 연산자는 포트를 무시하고 항상 포트 9042를 사용합니다. 연산자는 IP 주소만 허용합니다. 호스트 이름과 DNS 이름을 무시하고 무시된 각 항목에 대해 로그에 경고를 작성합니다.
  • cassandra.storage.storageSize는 필수이지만 런타임 클러스터는 Cassandra용 PersistentVolume을 생성하지 않습니다. ApigeeDatastore 검증 웹훅은 항상 storageSize을 확인합니다. 유효한 수량을 사용합니다(예: 10Gi).

링을 확장할 때와 Kubernetes가 포드를 다시 예약할 때 포드 IP 주소가 변경됩니다. 그러면 externalHost의 목록이 잘못됩니다. 따라서 동적 엔드포인트 동기화를 사용하는 것이 좋습니다. 동적 엔드포인트 동기화는 Cassandra 포드 IP 주소 목록을 자동으로 최신 상태로 유지합니다. 간단한 설치나 첫 번째 설정의 경우에만 externalHost를 단독으로 사용하세요.

동적 엔드포인트 동기화로 엔드포인트를 최신 상태로 유지

externalHost만 사용하는 경우 Cassandra 링이 변경될 때마다 재정의를 수정해야 합니다. 동적 엔드포인트 동기화를 사용하면 이 수동 단계가 필요하지 않습니다. 런타임 클러스터의 작업자는 준비된 Cassandra 엔드포인트를 Cassandra 클러스터에서 정기적으로 읽습니다. 그런 다음 이러한 엔드포인트를 런타임 클러스터의 엔드포인트 객체에 복사합니다.

동적 엔드포인트 동기화를 사용하는 것이 좋습니다. 링을 확장하거나 Kubernetes에서 포드를 다시 예약할 때마다 포드 IP 주소가 변경됩니다. 동적 엔드포인트 동기화는 Cassandra 헤드리스 서비스의 준비된 포드의 IP 주소를 읽습니다. 따라서 런타임 클러스터의 엔드포인트 객체에는 항상 현재 Cassandra 포드 IP 주소가 포함됩니다.

동적 엔드포인트 동기화를 사용하더라도 externalHost는 여전히 필요합니다. 연산자는 다음 두 가지 조건에서 이를 사용합니다.

  • Cassandra 클러스터에서 첫 번째 읽기가 성공하기 전
  • Cassandra 클러스터에서 읽기가 실패하고 이전 성공적인 읽기에서 엔드포인트가 없는 경우

읽기가 실패하고 이전에 성공한 읽기에서 가져온 엔드포인트가 있는 경우 작업자는 해당 엔드포인트를 유지합니다. 런타임은 Cassandra에 대한 연결을 유지합니다.

동적 엔드포인트 동기화를 사용 설정하려면 externalEndpointsSync 블록을 런타임 클러스터의 재정의 파일에 추가합니다.

cassandra:
  replicaCount: 0
  properties:
    # The first endpoints, and the fallback if a read fails.
    externalHost: "CASSANDRA_IP_ADDRESSES"
    externalEndpointsSync:
      # A secret in the runtime cluster. Its "kubeconfig" key holds the
      # kubeconfig for the Cassandra cluster.
      secretRef: apigee-remote-cass-kubeconfig
      # The namespace of the Cassandra headless Service in the Cassandra cluster.
      namespace: apigee
      # The Cassandra headless Service in the Cassandra cluster.
      serviceName: apigee-cassandra-default
      # The interval between reads, in seconds. The default is 30.
      intervalSeconds: 30
  storage:
    storageSize: "10Gi"

Cassandra 클러스터에서 읽기 전용 서비스 계정 만들기

런타임 클러스터의 운영자는 kubeconfig를 사용하여 Cassandra 클러스터에 연결합니다. 이 kubeconfig는 최소 권한이 있는 읽기 전용 ServiceAccount을 사용해야 합니다. 이 서비스 계정은 Cassandra 엔드포인트만 읽을 수 있습니다. Cassandra 클러스터의 리소스는 변경할 수 없습니다.

Cassandra 클러스터에서 다음 리소스를 만듭니다.

  • 서비스 계정(예: apigee-endpoint-reader)
  • Cassandra 네임스페이스의 역할 및 RoleBinding 이 역할은 핵심 endpoints에 대한 get, list, watch 동사만 부여합니다. create, update, patch, delete와 같은 다른 동사를 사용하지 마세요. 다른 리소스에 대한 액세스 권한을 부여하지 않습니다.
  • ServiceAccount의 수명이 긴 토큰 보안 비밀입니다.

그런 다음 Cassandra 클러스터의 Kubernetes API 서버용 kubeconfig 파일을 만듭니다. 이 kubeconfig는 ServiceAccount의 토큰을 사용해야 합니다. 런타임 클러스터에서 externalEndpointsSync.secretRef에 설정한 이름으로 보안 비밀을 만듭니다. kubeconfig를 kubeconfig 키에 넣습니다.

kubectl --context RUNTIME_CLUSTER -n APIGEE_NAMESPACE create secret generic \
  apigee-remote-cass-kubeconfig --from-file=kubeconfig=READER_KUBECONFIG_FILE

READER_KUBECONFIG_FILE를 읽기 전용 ServiceAccount의 kubeconfig 파일 경로로 바꿉니다.

kubeconfig에 장기 토큰이 포함되어 있습니다. 이 보안 비밀은 다른 사용자 인증 정보와 마찬가지로 안전하게 보관하세요.

동적 엔드포인트 동기화 모니터링

Cassandra 클러스터에서 읽기가 실패하면 런타임은 연결을 유지합니다. 하지만 읽기가 다시 성공할 때까지 런타임 클러스터의 엔드포인트는 변경되지 않습니다. Cassandra 링이 변경되기 전에 지속적인 오류를 찾을 수 있도록 동기화를 모니터링합니다.

런타임 클러스터의 운영자는 다음 신호를 제공합니다.

  • ApigeeDatastore 리소스의 상태에 있는 EndpointSyncDegraded 조건입니다. 이 조건은 연속으로 세 번 읽기에 실패한 후 True가 됩니다. 이유는 RemoteReadFailed 또는 NoReadyRemoteEndpoints입니다. 읽기에 성공하면 조건이 SyncSucceeded 이유로 False가 됩니다.
  • external_endpoint_sync_last_success_timestamp 측정항목 이 측정항목은 마지막으로 성공한 읽기 시간(Unix 초)입니다.
  • external_endpoint_sync_failures_total 측정항목 이 측정항목은 실패한 읽기를 집계합니다.

두 측정항목에는 ApigeeDatastore 리소스의 namespace 및 name 라벨이 있습니다. 연산자는 측정항목 엔드포인트에 이를 표시합니다.

조건을 확인하려면 다음 명령어를 실행합니다.

kubectl --context RUNTIME_CLUSTER -n APIGEE_NAMESPACE get apigeedatastore default \
  -o jsonpath='{.status.conditions}'

EndpointSyncDegraded 조건에 대한 알림을 사용하는 것이 좋습니다. ApigeeDatastore 상태는 작업자가 다시 시작될 때 조건을 유지합니다. 성공적인 읽기만 조건을 False로 설정합니다.

측정항목에 대한 알림도 사용하는 경우 다음 두 표현식 중 하나가 참일 때 알림을 보냅니다.

  • time() - external_endpoint_sync_last_success_timestamp > 300
  • absent(external_endpoint_sync_last_success_timestamp)

작업자는 읽기가 성공한 후에만 측정항목을 설정합니다. 읽기가 실패하는 동안 연산자가 다시 시작되면 측정항목이 누락됩니다. 그러면 첫 번째 표현식은 일치하지 않고 두 번째 표현식만 알림을 전송합니다.

연결 확인하기

런타임 구성요소를 설치한 후 런타임 클러스터에서 다음 검사를 실행합니다.

  1. 런타임 클러스터에 Cassandra 포드가 없는지 확인합니다.

    kubectl --context RUNTIME_CLUSTER -n APIGEE_NAMESPACE get pods -l app=apigee-cassandra

    출력은 No resources found입니다.

  2. 엔드포인트 객체가 Cassandra 링을 가리키는지 확인합니다.

    kubectl --context RUNTIME_CLUSTER -n APIGEE_NAMESPACE get endpoints apigee-cassandra-default

    ENDPOINTS 열에는 Cassandra IP 주소가 표시됩니다. 동적 엔드포인트 동기화를 사용하는 경우 이는 Cassandra 클러스터에서 준비된 Cassandra 포드의 IP 주소입니다.

  3. Cassandra 설정 작업이 완료되었는지 확인합니다.

    kubectl --context RUNTIME_CLUSTER -n APIGEE_NAMESPACE get jobs \
      | grep -E 'apigee-cassandra-(schema|user)-setup'

    COMPLETIONS 열에는 각 작업의 1/1이 표시됩니다. 작업이 완료되지 않으면 작업 로그에서 인증 오류를 확인합니다. 그런 다음 두 클러스터가 동일한 Cassandra 사용자 인증 정보를 사용하는지 확인합니다.

Cassandra 링 확장

Cassandra 클러스터의 Apigee 운영자가 Cassandra 수명 주기를 소유합니다. Cassandra 클러스터에서 Cassandra를 확장합니다. 런타임 클러스터에서 Cassandra를 확장할 수 없습니다.

런타임 클러스터의 Cassandra 링과 동일한 규칙을 준수합니다.

  • Cassandra를 3의 배수로 확장합니다. 이렇게 하면 세 개의 가용성 영역에서 링의 균형이 유지됩니다.
  • 포드 수를 늘리기 전에 Cassandra 클러스터에 충분한 노드 용량이 있는지 확인합니다.
  • 동적 엔드포인트 동기화를 사용하지 않는 경우 각 확장 작업 후에 externalHost를 업데이트합니다.

자세한 내용은 Cassandra 확장을 참고하세요.

다음 단계