외부 Secret Manager에 데이터 저장

외부 Secret Manager에 데이터 저장

이 가이드에서는 overrides.yaml 파일 대신 외부 보안 비밀 스토리지 서비스인 Hashicorp Vault에 다음 유형의 정보를 저장하고 관리하는 방법을 설명합니다.

  • AX Hash Salt
  • Redis 비밀번호
  • 암호화 키

Vault에 다른 유형의 정보를 저장하려면 다음을 참조하세요.

기본 요건

절차

  1. Vault 보안 비밀, 정책, 역할을 만듭니다.
    1. Vault UI 또는 API를 사용하여 보안 비밀을 만들고 여기에 설명된 대로 Apigee Kubernetes 서비스 계정에 이러한 보안 비밀을 읽을 수 있는 권한을 부여합니다. 보안 비밀은 다음 표에 표시된 것처럼 키와 하나 이상의 값으로 구성되어야 합니다.
      보안 비밀 키 보안 비밀 데이터
      secret/data/apigee/axhashsalt
      {
        "ax-hash-salt": "AX_HASH_SALT_VALUE"
      }
      secret/data/apigee/redis
      {
        "redis-password": "REDIS_PASSWORD_VALUE"
      }
      secret/data/apigee/orgencryptionkeys
      {
        "kmsEncryptionKey": "KMS_ENCRYPTION_KEY_VALUE"
        "kvmEncryptionKey": "KVM_ENCRYPTION_KEY_VALUE"
        "contractEncryptionKey": "CONTRACT_ENCRYPTION_KEY_VALUE"
      }
      secret/data/apigee/envencryptionkeys
      {
        "cacheEncryptionKey": "CACHE_ENCRYPTION_KEY_VALUE"
        "kvmEncryptionKey": "KVM_ENCRYPTION_KEY_VALUE"
        "envKvmEncryptionKey": "ENV_KVM_ENCRYPTION_KEY_VALUE"
        "kmsEncryptionKey": "KMS_ENCRYPTION_KEY_VALUE"
      }
    2. Vault 내에서 보안 비밀에 대해 액세스 권한을 부여하는 정책을 만듭니다.
      cat axhashsalt-auth-policy.txt
      path "secret/data/apigee/axhashsalt" {
        capabilities = ["read"]
      }
      cat redis-auth-policy.txt
      path "secret/data/apigee/redis" {
        capabilities = ["read"]
      }
      cat orgencryptionkeys-auth-policy.txt
      path "secret/data/apigee/orgencryptionkeys" {
        capabilities = ["read"]
      }
      cat envencryptionkeys-auth-policy.txt
      path "secret/data/apigee/envencryptionkeys" {
        capabilities = ["read"]
      }
      
      vault policy write apigee-axhashsalt-auth axhashsalt-auth-policy.txt
      vault policy write apigee-redis-auth redis-auth-policy.txt
      vault policy write apigee-orgencryptionkeys-auth orgencryptionkeys-auth-policy.txt
      vault policy write apigee-envencryptionkeys-auth envencryptionkeys-auth-policy.txt
      
    3. 다음 콘텐츠가 포함된 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-redis-default,apigee-redis-envoy-default,apigee-mart-${ORG_ENCODE},apigee-mint-task-scheduler-${ORG_ENCODE}"
      
      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-runtime-${ENV_ENCODE},apigee-synchronizer-${ENV_ENCODE}
      done
      
      echo $NAMES
      
    4. 스크립트를 실행하여 정책을 바인딩할 서비스 계정 이름 목록을 생성합니다.
      chmod +x ./generate-encoded-sas.sh
      ./generate-encoded-sas.sh
      

      출력에 인코딩된 서비스 계정 이름이 표시됩니다.

    5. 정책을 사용하여 필요한 Apigee 서비스 계정을 바인딩하는 Vault 역할을 만듭니다.
      vault write auth/kubernetes/role/apigee-axhashsalt \
      	bound_service_account_names=BOUND_SA_NAMES \
      	bound_service_account_namespaces=APIGEE_NAMESPACE \
      	policies=apigee-axhashsalt-auth \
      	ttl=1m
      
      vault write auth/kubernetes/role/apigee-redis \
      	bound_service_account_names=BOUND_SA_NAMES \
      	bound_service_account_namespaces=APIGEE_NAMESPACE \
      	policies=apigee-redis-auth \
      	ttl=1m
      
      vault write auth/kubernetes/role/apigee-orgencryptionkeys \
      	bound_service_account_names=BOUND_SA_NAMES \
      	bound_service_account_namespaces=APIGEE_NAMESPACE \
      	policies=apigee-orgencryptionkeys-auth \
      	ttl=1m
      
      vault write auth/kubernetes/role/apigee-envencryptionkeys \
      	bound_service_account_names=BOUND_SA_NAMES \
      	bound_service_account_namespaces=APIGEE_NAMESPACE \
      	policies=apigee-envencryptionkeys-auth \
      	ttl=1m
      
      
  2. SecretProviderClass 객체를 만듭니다.
    1. SecretProviderClass 리소스를 통해 다음 보안 비밀을 추가합니다. 이러한 리소스는 보안 비밀을 요청할 때 CSI 드라이버에 통신할 제공업체를 알려줍니다. 다음 표에서는 Apigee Hybrid에서 예상하는 파일 이름(objectNames)을 보여줍니다.
      보안 비밀 예상 보안 비밀 파일 이름
      AX Hash Salt
      • ax-hash-salt
      Redis
      • redis-password
      조직 암호화 키
      • kmsEncryptionKey
      • kvmEncryptionKey
      • contractEncryptionKey
      환경 암호화 키
      • kmsEncryptionKey
      • kvmEncryptionKey
      • envKvmEncryptionKey
      • cacheEncryptionKey
    2. 다음 SecretProviderClass 템플릿을 사용하여 리소스를 구성합니다.
      # axhashsalt-spc.yaml
      
      apiVersion: secrets-store.csi.x-k8s.io/v1
      kind: SecretProviderClass
      metadata:
        name: apigee-axhashsalt-spc
      spec:
        provider: vault
        parameters:
          roleName: apigee-axhashsalt
          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: "ax-hash-salt"
              secretPath: ""
              secretKey: ""
      
      # redis-spc.yaml
      
      apiVersion: secrets-store.csi.x-k8s.io/v1
      kind: SecretProviderClass
      metadata:
        name: apigee-redis-spc
      spec:
        provider: vault
        parameters:
          roleName: apigee-redis
          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: "redis-password"
              secretPath: ""
              secretKey: ""
      
      # orgencryptionkeys-spc.yaml
      
      apiVersion: secrets-store.csi.x-k8s.io/v1
      kind: SecretProviderClass
      metadata:
        name: apigee-orgencryptionkeys-spc
      spec:
        provider: vault
        parameters:
          roleName: apigee-orgencryptionkeys
          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: "kmsEncryptionKey"
              secretPath: ""
              secretKey: ""
            - objectName: "kvmEncryptionKey"
              secretPath: ""
              secretKey: ""
            - objectName: "contractEncryptionKey"
              secretPath: ""
              secretKey: ""
      
      # envencryptionkeys-spc.yaml
      
      apiVersion: secrets-store.csi.x-k8s.io/v1
      kind: SecretProviderClass
      metadata:
        name: apigee-envencryptionkeys-spc
      spec:
        provider: vault
        parameters:
          roleName: apigee-envencryptionkeys
          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: "cacheEncryptionKey"
              secretPath: ""
              secretKey: ""
            - objectName: "kvmEncryptionKey"
              secretPath: ""
              secretKey: ""
            - objectName: "envKvmEncryptionKey"
              secretPath: ""
              secretKey: ""
            - objectName: "kmsEncryptionKey"
              secretPath: ""
              secretKey: ""
      

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

    3. 위의 SecretProviderClassesAPIGEE_NAMESPACE 네임스페이스에 적용합니다.
      kubectl -n APIGEE_NAMESPACE apply -f axhashsalt-spc.yaml
      kubectl -n APIGEE_NAMESPACE apply -f redis-spc.yaml
      kubectl -n APIGEE_NAMESPACE apply -f orgencryptionkeys-spc.yaml
      kubectl -n APIGEE_NAMESPACE apply -f envencryptionkeys-spc.yaml
      
  3. AX Hash Salt에 대해 외부 보안 비밀을 사용 설정합니다.
    1. overrides.yaml 파일 내에서 다음 구성을 추가하여 AX Hash Salt에 대해 외부 보안 비밀 사용을 사용 설정합니다.
      axHashSaltSecretProviderClass: apigee-axhashsalt-spc
    2. org Helm 차트를 업그레이드하여 변경사항을 적용합니다.
      helm upgrade org apigee-org/ \
        --namespace APIGEE_NAMESPACE \
        -f overrides.yaml
  4. Redis 비밀번호에 대해 외부 보안 비밀을 사용 설정합니다.
    1. overrides.yaml 파일 내에서 다음 구성을 추가하여 Redis 비밀번호에 대해 외부 보안 비밀 사용을 사용 설정합니다.
      redis:
        auth:
          secretProviderClass: apigee-redis-spc
    2. 그런 후 다음 순서에 따라 operatorredis 차트를 업그레이드하여 변경사항을 적용합니다.
      helm upgrade operator apigee-operator/ \
        --namespace APIGEE_NAMESPACE \
        -f overrides.yaml
      helm upgrade redis apigee-redis/ \
        --namespace APIGEE_NAMESPACE \
        -f overrides.yaml
      
  5. 암호화 키에 대해 외부 보안 비밀을 사용 설정합니다.
    1. overrides.yaml 파일 내에서 다음 구성을 추가하여 조직 수준 암호화 키에 대해 외부 보안 비밀 사용을 사용 설정합니다.
      encryptionKeySecretProviderClass: apigee-orgencryptionkeys-spc
    2. org Helm 차트를 업그레이드하여 변경사항을 적용합니다.
      helm upgrade org apigee-org/ \
        --namespace APIGEE_NAMESPACE \
        -f overrides.yaml
    3. 각 환경의 overrides.yaml 파일 내에 환경별 암호화 키에 대해 다음 구성을 추가합니다.
      envs:
      - name: ENV_NAME
        encryptionKeySecretProviderClass: apigee-envencryptionkeys-spc
    4. 각 환경에 대해 env Helm 차트를 한 번씩 업그레이드하여 변경사항을 적용합니다.
      helm upgrade ENV_NAME apigee-env/ \
        --namespace APIGEE_NAMESPACE \
        --set env=ENV_NAME \
        -f overrides.yaml
      

롤백

AX Hash Salt

  1. overrides.yaml 파일에서 AX Hash Salt에 대해 외부 보안 비밀 사용을 사용 설정한 구성을 삭제합니다.
    # Comment out or delete the following line:
    # axHashSaltSecretProviderClass: apigee-axhashsalt-spc
  2. org Helm 차트를 업그레이드하여 변경사항을 적용합니다.
    helm upgrade org apigee-org/ \
      --namespace APIGEE_NAMESPACE \
      -f overrides.yaml

Redis 비밀번호

  1. overrides.yaml 파일 내에서 Redis 비밀번호에 대해 외부 보안 비밀 사용을 사용 설정한 구성을 삭제합니다.
    redis:
      auth:
      # Comment out or delete the following line:
      # secretProviderClass: apigee-redis-spc
  2. 그런 후 다음 순서에 따라 redisoperator 차트를 업그레이드하여 변경사항을 적용합니다.
    helm upgrade redis apigee-redis/ \
      --namespace APIGEE_NAMESPACE \
      -f overrides.yaml
    helm upgrade operator apigee-operator/ \
      --namespace APIGEE_NAMESPACE \
      -f overrides.yaml
    

암호화 키

  1. overrides.yaml 파일 내에서 환경 암호화 키에 대해 외부 보안 비밀 사용을 사용 설정한 구성을 삭제합니다.
    envs:
      - name: ENV_NAME
      # Comment out or delete the following line:
      # encryptionKeySecretProviderClass: apigee-envencryptionkeys-spc
  2. 각 환경에 대해 env Helm 차트를 한 번씩 업그레이드하여 변경사항을 적용합니다.
    helm upgrade ENV_NAME apigee-env/ \
      --namespace APIGEE_NAMESPACE \
      --set env=ENV_NAME \
      -f overrides.yaml
    
  3. overrides.yaml 파일 내에서 조직 암호화 키에 대해 외부 보안 비밀 사용을 사용 설정한 구성을 삭제합니다.
    # Comment out or delete the following line:
    # encryptionKeySecretProviderClass: apigee-orgencryptionkeys-spc
    
  4. 그런 후 org Helm 차트를 업그레이드합니다.
    helm upgrade org apigee-org/ \
      --namespace APIGEE_NAMESPACE \
      -f overrides.yaml