Hashicorp Vault에 서비스 계정 키 저장

Hashicorp Vault에 서비스 계정 보안 비밀 저장

이 기능을 사용하면 외부 보안 비밀 관리자인 Hashicorp Vault에 Apigee Hybrid의 Google 서비스 계정 인증서를 저장할 수 있습니다. 외부 보안 비밀 관리자를 사용하면 데이터 상주 관리와 세분화된 액세스 제어 관리 등 Kubernetes에 데이터가 저장되는 방식을 관리할 수 있습니다.

GKE 클러스터에서 워크로드 아이덴티티 또는 EKS 및 AKS에서 워크로드 아이덴티티 제휴를 사용하지 않는 경우 Apigee Hybrid 구성요소는 태스크를 수행할 수 있도록 Google 서비스 계정을 인증해야 합니다. Apigee Hybrid에서 Google 서비스 계정 키를 저장하고 참조하는 방법에는 세 가지가 있습니다.

  • 하드 드라이브에 저장된 서비스 계정 인증서 파일(.json 파일). serviceAccountPath 구성 속성을 사용한 재정의에서 이를 참조하세요. 예를 들면
    logger:
      serviceAccountPath: service-accounts/myhybridorg-apigee-logger.json
    
    입니다.
  • 하드 드라이브에 저장된 서비스 계정 인증서 파일(.json 파일). serviceAccountPath 구성 속성을 사용한 재정의에서 이를 참조하세요. 서비스 계정 정보를 참조하세요.
  • Kubernetes 보안 비밀에 저장된 서비스 계정 인증서. serviceAccountRef 구성 속성을 사용한 재정의에서 이를 참조하세요. Kubernetes 보안 비밀에 데이터 저장도 참조하세요.
  • 이 가이드에 설명된 Hashicorp Vault에 저장된 서비스 계정 인증서. serviceAccountSecretProviderClass 구성 속성을 사용한 재정의에서 이를 참조하세요.

Vault에 서비스 계정 보안 비밀을 저장하도록 설정

CSI 드라이버 및 Vault 제공업체 설치

Helm을 사용하여 클러스터에 CSI 드라이버를 아직 설치하지 않았으면 Secrets Store CSI 드라이버: 설치 안내를 따릅니다. 자세한 내용은 Vault 문서의 Vault CSI 제공업체 설치를 참조하세요.

Apigee Hybrid에서 지원하는 최소 CSI 드라이버 버전은 Apigee Hybrid 지원 플랫폼 및 버전을 참조하세요.

Vault 보안 비밀, 정책, 역할 만들기

Vault UI 또는 API를 사용하여 보안 비밀을 만들고 Apigee Hybrid에서 이러한 보안 비밀을 읽는 데 사용되는 Kubernetes 서비스 계정에 권한을 부여합니다.

  1. 다음 형식으로 조직 및 환경별 보안 비밀을 만듭니다.
    비밀번호 키보안 비밀 데이터
    secret/data/apigee/orgsakeys
    {
      "cassandraBackup": "***",
      "cassandraRestore": "***",
      "connectAgent": "***",
      "logger": "***",
      "mart": "***",
      "metrics": "***",
      "mint": "***",
      "udca": "***",
      "watcher": "***"
    }
    secret/data/apigee/envsakeys-ENV_NAME
    {
      "runtime": "***",
      "synchronizer": "***",
      "udca": "***". 
    }

    각 쌍의 "***"를 Apigee 구성요소에 해당하는 Google 서비스 계정의 .json 파일 콘텐츠로 바꿉니다. apigee-cassandra-backupapigee-cassandra-restore 모두 apigee-cassandra 서비스 계정을 사용합니다. 예를 들면 다음과 같습니다.

    {
      "cassandraBackup": "{
        "type": "service_account",
        "project_id": "myhybridorg",
        "private_key_id": "PRIVATE_KEY_ID",
        "private_key": "-----BEGIN PRIVATE KEY-----\nPRIVATE_KEY_TEXT\n-----END PRIVATE KEY-----\n",
        "client_email": "apigee-cassandra@myhybridorg.iam.gserviceaccount.com",
        "client_id": "123456789012345678901",
        "auth_uri": "https://accounts.google.com/o/oauth2/auth",
        "token_uri": "https://oauth2.googleapis.com/token",
        "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
        "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/apigee-cassandra%40myhybridorg.iam.gserviceaccount.com",
        "universe_domain": "googleapis.com"
      }",
      "cassandraRestore":...
    ...
    }
        
  2. 조직 보안 비밀에 대한 액세스 권한을 부여합니다. 다음 콘텐츠로 orgsakeys-auth-policy.txt라는 텍스트 파일을 만듭니다.
    path "secret/data/apigee/orgsakeys" {
      capabilities = ["read"]
    }
  3. Vault 내에서 조직 보안 비밀에 대한 액세스 권한을 부여하는 정책을 만듭니다.
    vault policy write apigee-orgsakeys-auth orgsakeys-auth-policy.txt
  4. 각 환경에 대해 다음 콘텐츠가 포함된 envsakeys-ENV_NAME-auth-policy.txt라는 텍스트 파일을 만듭니다.
    path "secret/data/apigee/envsakeys-ENV_NAME" {
      capabilities = ["read"]
    }

    환경마다 이 단계를 반복합니다.

  5. Vault 내에서 환경 보안 비밀에 대한 액세스 권한을 부여하는 정책을 만듭니다.
    vault policy write apigee-envsakeys-ENV_NAME-auth envsakeys-ENV_NAME-auth-policy.txt

    환경마다 이 단계를 반복합니다.

  6. 다음 콘텐츠가 포함된 generate-encoded-sas.sh 스크립트를 만듭니다.
    # generate-encoded-sas.sh
    
    ORG=$APIGEE_ORG            # Apigee organization name
    ENVS=$APIGEE_ENV_LIST      # comma separated env names, for example: dev,prod
    
    ORG_SHORT_NAME=$(echo $ORG | head -c 15)
    ENCODE=$(echo -n $ORG | shasum -a 256 | head -c 7)
    ORG_ENCODE=$(echo "$ORG_SHORT_NAME-$ENCODE")
    NAMES=apigee-manager,apigee-cassandra-default,apigee-cassandra-backup-sa,apigee-cassandra-restore-sa,apigee-cassandra-schema-setup-${ORG_ENCODE},apigee-cassandra-schema-val-${ORG_ENCODE},apigee-cassandra-user-setup-${ORG_ENCODE},apigee-mart-${ORG_ENCODE},apigee-mint-task-scheduler-${ORG_ENCODE},apigee-connect-agent-${ORG_ENCODE},apigee-watcher-${ORG_ENCODE},apigee-udca-${ORG_ENCODE},apigee-metrics-apigee-telemetry,apigee-open-telemetry-collector-apigee-telemetry,apigee-logger-apigee-telemetry
    
    for ENV in ${ENVS//,/ }
    do
      ENV_SHORT_NAME=$(echo $ENV | head -c 15)
      ENCODE=$(echo -n $ORG:$ENV | shasum -a 256 | head -c 7)
      ENV_ENCODE=$(echo "$ORG_SHORT_NAME-$ENV_SHORT_NAME-$ENCODE")
      NAMES+=,apigee-synchronizer-${ENV_ENCODE},apigee-runtime-${ENV_ENCODE}
    done
    
    echo $NAMES
    
  7. 스크립트를 실행하여 정책을 바인딩할 서비스 계정 이름 목록을 생성합니다.
    ./generate-encoded-sas.sh

    출력은 다음 예시와 비슷하게 쉼표로 구분된 Kubernetes 서비스 계정 이름 목록이어야 합니다.

    ./generate-encoded-sas.sh
    apigee-manager,apigee-cassandra-default,apigee-cassandra-backup-sa,
    apigee-cassandra-restore-sa,apigee-cassandra-schema-setup-myhybrido
    rg-5b044c1,apigee-cassandra-schema-val-myhybridorg-5b044c1,apigee-c
    assandra-user-setup-myhybridorg-5b044c1,apigee-mart-myhybridorg-5b0
    44c1,apigee-mint-task-scheduler-myhybridorg-5b044c1,apigee-connect-
    agent-myhybridorg-5b044c1,apigee-watcher-myhybridorg-5b044c1,apigee
    -udca-myhybridorg-5b044c1,apigee-metrics-apigee-telemetry,apigee-op
    en-telemetry-collector-apigee-telemetry,apigee-logger-apigee-teleme
    try,apigee-synchronizer-myhybridorg-dev-ee52aca,apigee-runtime-myhy
    bridorg-dev-ee52aca,apigee-synchronizer-myhybridorg-prod-2d0221c,ap
    igee-runtime-myhybridorg-prod-2d0221c
  8. 출력 텍스트를 복사하여 목록으로 구분합니다. org 서비스 계정 이름용 목록 하나와 각 환경의 env 서비스 계정 이름용 별도 목록입니다. 조직 서비스 계정은 출력 목록에서 최대 apigee-logger-apigee-telemetry까지 먼저 표시됩니다.

    이전 예시의 org 서비스 이름 목록:

    apigee-manager,apigee-cassandra-default,apigee-cassandra-backup-sa,
    apigee-cassandra-restore-sa,apigee-cassandra-schema-setup-myhybrido
    rg-5b044c1,apigee-cassandra-schema-val-myhybridorg-5b044c1,apigee-c
    assandra-user-setup-myhybridorg-5b044c1,apigee-mart-myhybridorg-5b0
    44c1,apigee-mint-task-scheduler-myhybridorg-5b044c1,apigee-connect-
    agent-myhybridorg-5b044c1,apigee-watcher-myhybridorg-5b044c1,apigee
    -udca-myhybridorg-5b044c1,apigee-metrics-apigee-telemetry,apigee-op
    en-telemetry-collector-apigee-telemetry,apigee-logger-apigee-teleme
    try

    env 서비스 계정 이름의 패턴은 apigee-synchronizer-ORG_NAME-ENV_NAME-HASH_TEXTapigee-runtime-ORG_NAME-ENV_NAME-HASH_TEXT입니다. 각 환경에 대해 구분된 목록으로 구분합니다. 예를 들어 이전 예시의 출력은 다음 두 목록으로 구분할 수 있습니다.

    dev 환경:

    apigee-synchronizer-myhybridorg-dev-ee52aca,apigee-runtime-myhybrid
    org-dev-ee52aca

    prod 환경:

    apigee-synchronizer-myhybridorg-prod-2d0221c,apigee-runtime-myhybri
    dorg-prod-2d0221c
  9. 정책을 사용하여 조직별 Apigee 서비스 계정을 바인딩하는 Vault 역할을 만듭니다.
    vault write auth/kubernetes/role/apigee-orgsakeys \
        bound_service_account_names=LIST_OF_ORG_SA_NAMES \
        bound_service_account_namespaces=apigee \
        policies=apigee-orgsakeys-auth \
        ttl=1m
    
  10. 각 환경에 대해 서비스 계정 키에 대한 Vault 역할을 만듭니다.
    vault write auth/kubernetes/role/apigee-envsakeys-ENV_NAME \
        bound_service_account_names=LIST_OF_ENV_NAME_SA_NAMES \
        bound_service_account_namespaces=apigee \
        policies=apigee-envsakeys-ENV_NAME-auth \ 
        ttl=1m
    

    모든 환경에 대해 이 단계를 반복합니다.

SecretProviderClass 객체 만들기

SecretProviderClass 리소스는 보안 비밀을 요청할 때 CSI 드라이버에 통신할 제공업체를 알려줍니다. 서비스 계정 키는 이 객체를 통해 구성해야 합니다. 다음 표에서는 Apigee Hybrid에서 예상하는 파일 이름(objectNames)을 보여줍니다.

서비스 계정예상 보안 비밀 파일 이름
Cassandra 백업 cassandraBackup
Cassandra 복원 cassandraRestore
Connect 에이전트 connectAgent
Logger logger
MART mart
측정항목 metrics
수익 창출 mint
런타임 runtime
동기화 담당자 synchronizer
UDCA udca
감시자 watcher
  1. 조직별 보안 비밀에 대해 이 리소스를 구성하려면 다음 SecretProviderClass 템플릿을 사용합니다.
    apiVersion: secrets-store.csi.x-k8s.io/v1
    kind: SecretProviderClass
    metadata:
      name: apigee-orgsakeys-spc
    spec:
      provider: vault
      parameters:
        roleName: apigee-orgsakeys
        vaultAddress: VAULT_ADDRESS
        # "objectName" is an alias used within the SecretProviderClass to reference
        # that specific secret. This will also be the filename containing the secret.
        # Apigee Hybrid expects these exact values so they must not be changed.
        # "secretPath" is the path in Vault where the secret should be retrieved.
        # "secretKey" is the key within the Vault secret response to extract a value from.
        objects: |
          - objectName: "cassandraBackup"
            secretPath: ""
            secretKey: ""
          - objectName: "cassandraRestore"
            secretPath: ""
            secretKey: ""
          - objectName: "connectAgent"
            secretPath: ""
            secretKey: ""
          - objectName: "logger"
            secretPath: ""
            secretKey: ""
          - objectName: "mart"
            secretPath: ""
            secretKey: ""
          - objectName: "metrics"
            secretPath: ""
            secretKey: ""
          - objectName: "mint"
            secretPath: ""
            secretKey: ""
          - objectName: "udca"
            secretPath: ""
            secretKey: ""
          - objectName: "watcher"
            secretPath: ""
            secretKey: ""
    

    VAULT_ADDRESS는 Vault 서버가 실행 중인 엔드포인트입니다. Vault가 Apigee와 동일한 클러스터에서 실행되는 경우 일반적으로 형식은 http://vault.APIGEE_NAMESPACE.svc.cluster.local:VAULT_SERVICE_PORT입니다.

    템플릿을 spc-org.yaml 파일에 저장합니다.

  2. 조직별 SecretProviderClass를 Apigee 네임스페이스에 적용합니다.
    kubectl -n apigee apply -f spc-org.yaml
  3. 각 환경에 대해 다음 SecretProviderClass 템플릿을 사용하여 환경별 보안 비밀에 대해 이 리소스를 구성합니다. 모든 환경에 대해 이 단계를 반복합니다.
    apiVersion: secrets-store.csi.x-k8s.io/v1
    kind: SecretProviderClass
    metadata:
      name: apigee-envsakeys-ENV_NAME-spc
    spec:
      provider: vault
      parameters:
        roleName: apigee-envsakeys-ENV_NAME
        vaultAddress: VAULT_ADDRESS
        # "objectName" is an alias used within the SecretProviderClass to reference
        # that specific secret. This will also be the filename containing the secret.
        # Apigee Hybrid expects these exact values so they must not be changed.
        # "secretPath" is the path in Vault where the secret should be retrieved.
        # "secretKey" is the key within the Vault secret response to extract a value from.
        objects: |
          - objectName: "runtime"
            secretPath: ""
            secretKey: ""
          - objectName: "synchronizer"
            secretPath: ""
            secretKey: ""
          - objectName: "udca"
            secretPath: ""
            secretKey: ""
    

    VAULT_ADDRESS는 Vault 서버가 실행 중인 엔드포인트입니다. Vault가 Apigee와 동일한 클러스터에서 실행되는 경우 일반적으로 형식은 http://vault.APIGEE_NAMESPACE.svc.cluster.local:VAULT_SERVICE_PORT입니다.

    템플릿을 spc-env-ENV_NAME.yaml 파일에 저장합니다.

  4. 각 환경에 대해 환경별 SecretProviderClass를 Apigee 네임스페이스에 적용합니다.
    kubectl -n apigee apply -f spc-env-ENV_NAME.yaml

    모든 환경에 대해 이 단계를 반복합니다.

Google 서비스 계정에 외부 보안 비밀 사용 설정

  1. 재정의 파일 내에 serviceAccountSecretProviderClassenvs[].serviceAccountSecretProviderClass 구성 속성을 추가하여 Google 서비스 계정에 외부 보안 비밀 사용을 사용 설정합니다. serviceAccountPathserviceAccountPaths 구성 속성을 삭제하거나 주석 처리할 수 있습니다.
    serviceAccountSecretProviderClass: apigee-orgsakeys-spc
    
    envs:
      - name: ENV_NAME
        serviceAccountSecretProviderClass: apigee-envsakeys-ENV_NAME-spc
  2. 각 Helm 차트를 적용합니다.
    helm upgrade datastore apigee-datastore/ \
        --install \
        --namespace apigee \
        --atomic \
        -f overrides.yaml
    
    helm upgrade telemetry apigee-telemetry/ \
        --install \
        --namespace apigee \
        --atomic \
        -f overrides.yaml
    
    helm upgrade redis apigee-redis/ \
        --install \
        --namespace apigee \
        --atomic \
        -f overrides.yaml
    
    helm upgrade ORG_NAME apigee-org/ \
        --install \
        --namespace apigee \
        --atomic \
        -f overrides.yaml
    
  3. 각 환경에 대해 apigee-env 차트를 적용합니다.
    helm upgrade ENV_NAME apigee-env/ \
        --install \
        --namespace apigee \
        --set env=ENV_NAME \
        --atomic \
        -f overrides.yaml
    

서비스 계정 인증서 파일 사용으로 롤백

저장된 Google 서비스 계정 인증서 파일을 사용하도록 롤백해야 하는 경우 다음 절차를 따르세요.

  1. 재정의 파일을 업데이트합니다.
    1. serviceAccountSecretProviderClassenvs:serviceAccountSecretProviderClass 줄을 삭제하거나 주석 처리합니다.
    2. serviceAccountPathserviceAccountPaths 구성 속성을 적절한 서비스 계정 경로와 함께 추가합니다.

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

    # serviceAccountSecretProviderClass: apigee-orgsakeys-spc - (commented out)
    
    cassandra:
      backup:
        serviceAccountPath: service-accounts/myhybridorg-apigee-cassandra.json
      restore:
        serviceAccountPath: service-accounts/myhybridorg-apigee-cassandra.json
    
    connectAgent:
      serviceAccountPath: service-accounts/myhybridorg-apigee-mart.json
    
    envs:
      - name: test
      # serviceAccountSecretProviderClass: apigee-envsakeys-spc - (commented out)
        serviceAccountPaths:
          runtime: service-accounts/myhybridorg-apigee-runtime.json
          synchronizer: service-accounts/myhybridorg-apigee-synchronizer.json
    
    logger:
      serviceAccountPath: service-accounts/myhybridorg-apigee-logger.json
    
    mart:
      serviceAccountPath: service-accounts/myhybridorg-apigee-mart.json
    
    metrics:
      serviceAccountPath: service-accounts/myhybridorg-apigee-metrics.json
    
    udca:
      serviceAccountPath: service-accounts/myhybridorg-apigee-udca.json
    
    watcher:
      serviceAccountPath: service-accounts/myhybridorg-apigee-watcher.json
    
  2. 각 Helm 차트를 적용합니다.
    helm upgrade datastore apigee-datastore/ \
        --install \
        --namespace apigee \
        --atomic \
        -f overrides.yaml
    
    helm upgrade telemetry apigee-telemetry/ \
        --install \
        --namespace apigee \
        --atomic \
        -f overrides.yaml
    
    helm upgrade redis apigee-redis/ \
        --install \
        --namespace apigee \
        --atomic \
        -f overrides.yaml
    
    helm upgrade ORG_NAME apigee-org/ \
        --install \
        --namespace apigee \
        --atomic \
        -f overrides.yaml
    
  3. 각 환경에 대해 apigee-env 차트를 적용합니다.
    helm upgrade ENV_NAME apigee-env/ \
        --install \
        --namespace apigee \
        --set env=ENV_NAME \
        --atomic \
        -f overrides.yaml
    

    모든 환경에 대해 이 단계를 반복합니다.