Almacenar datos en un gestor de secretos externo

Almacenar datos en un gestor de secretos externo

En esta guía se explica cómo almacenar y gestionar los siguientes tipos de información en el servicio de almacenamiento de secretos externo HashiCorp Vault en lugar de en el archivo overrides.yaml.

  • Salt de hash AX
  • Contraseña de Redis
  • Claves de cifrado

Para almacenar otros tipos de información en Vault, consulta los siguientes artículos:

Requisitos previos

Procedimiento

  1. Crea los secretos, las políticas y los roles de Vault.
    1. Usa la interfaz de usuario o las APIs de Vault para crear secretos y conceder permisos a las cuentas de servicio de Kubernetes de Apigee para leer esos secretos, tal como se describe aquí. Los secretos deben constar de una clave y uno o varios valores, tal como se muestra en la siguiente tabla:
      Clave secreta Datos secretos
      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. En Vault, crea políticas que concedan acceso a los secretos:
      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. Crea una secuencia de comandos llamada generate-encoded-sas.sh con el siguiente contenido:
      # 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. Ejecuta la secuencia de comandos para generar la lista de nombres de cuentas de servicio a las que se van a vincular las políticas:
      chmod +x ./generate-encoded-sas.sh
      ./generate-encoded-sas.sh
      

      En el resultado se deben mostrar los nombres de las cuentas de servicio codificados.

    5. Crea roles de Vault que vinculen las cuentas de servicio de Apigee necesarias mediante las políticas.
      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. Crea objetos SecretProviderClass.
    1. Añade los siguientes secretos a través de los recursos SecretProviderClass. Estos recursos indican al controlador CSI con qué proveedor debe comunicarse al solicitar secretos. En la siguiente tabla se muestran los nombres de archivo (objectNames) que espera Apigee hybrid:
      Secreto Nombres de archivo secretos esperados
      AX Hash Salt
      • ax-hash-salt
      Redis
      • redis-password
      Claves de cifrado de la organización
      • kmsEncryptionKey
      • kvmEncryptionKey
      • contractEncryptionKey
      Claves de cifrado de Env
      • kmsEncryptionKey
      • kvmEncryptionKey
      • envKvmEncryptionKey
      • cacheEncryptionKey
    2. Utilice las siguientes plantillas de SecretProviderClass para configurar estos recursos:
      # 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 es el endpoint en el que se ejecuta tu servidor de Vault. Si Vault se ejecuta en el mismo clúster y espacio de nombres que Apigee, el formato será http://vault.APIGEE_NAMESPACE.svc.cluster.local:VAULT_SERVICE_PORT.

    3. Aplica lo anterior a SecretProviderClasses en el espacio de nombres APIGEE_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. Habilita el secreto externo para AX Hash Salt.
    1. En el archivo overrides.yaml, añade la siguiente configuración para habilitar el uso de secretos externos para AX Hash Salt:
      axHashSaltSecretProviderClass: apigee-axhashsalt-spc
    2. Aplica el cambio actualizando el gráfico de Helm org:
      helm upgrade org apigee-org/ \
        --namespace APIGEE_NAMESPACE \
        -f overrides.yaml
  4. Habilita el secreto externo de la contraseña de Redis.
    1. En el archivo overrides.yaml, añade la siguiente configuración para habilitar el uso de secretos externos para la contraseña de Redis:
      redis:
        auth:
          secretProviderClass: apigee-redis-spc
    2. A continuación, aplica los cambios actualizando los gráficos operator y redis en el siguiente orden:
      helm upgrade operator apigee-operator/ \
        --namespace APIGEE_NAMESPACE \
        -f overrides.yaml
      helm upgrade redis apigee-redis/ \
        --namespace APIGEE_NAMESPACE \
        -f overrides.yaml
      
  5. Habilita el secreto externo para las claves de cifrado.
    1. En el archivo overrides.yaml, añade la siguiente configuración para habilitar el uso de secretos externos en las claves de cifrado a nivel de organización:
      encryptionKeySecretProviderClass: apigee-orgencryptionkeys-spc
    2. Aplica el cambio actualizando el gráfico de Helm org:
      helm upgrade org apigee-org/ \
        --namespace APIGEE_NAMESPACE \
        -f overrides.yaml
    3. En el archivo overrides.yaml de cada entorno, añade la siguiente configuración para las claves de cifrado específicas del entorno:
      envs:
      - name: ENV_NAME
        encryptionKeySecretProviderClass: apigee-envencryptionkeys-spc
    4. Aplica el cambio actualizando el gráfico de Helm env una vez por cada entorno:
      helm upgrade ENV_NAME apigee-env/ \
        --namespace APIGEE_NAMESPACE \
        --set env=ENV_NAME \
        -f overrides.yaml
      

Restauración

AX Hash Salt

  1. En el archivo overrides.yaml, elimina la configuración que habilitaba el uso de secretos externos para el salt del hash de AX:
    # Comment out or delete the following line:
    # axHashSaltSecretProviderClass: apigee-axhashsalt-spc
  2. Aplica el cambio actualizando el gráfico de Helm org:
    helm upgrade org apigee-org/ \
      --namespace APIGEE_NAMESPACE \
      -f overrides.yaml

Contraseña de Redis

  1. En el archivo overrides.yaml, elimina la configuración que habilitaba el uso de secretos externos para la contraseña de Redis:
    redis:
      auth:
      # Comment out or delete the following line:
      # secretProviderClass: apigee-redis-spc
  2. A continuación, aplica los cambios actualizando los gráficos redis y operator en el siguiente orden:
    helm upgrade redis apigee-redis/ \
      --namespace APIGEE_NAMESPACE \
      -f overrides.yaml
    helm upgrade operator apigee-operator/ \
      --namespace APIGEE_NAMESPACE \
      -f overrides.yaml
    

Claves de encriptado

  1. En el archivo overrides.yaml, elimina la configuración que habilitaba el uso de secretos externos para las claves de cifrado del entorno:
    envs:
      - name: ENV_NAME
      # Comment out or delete the following line:
      # encryptionKeySecretProviderClass: apigee-envencryptionkeys-spc
  2. Aplica el cambio actualizando el gráfico de Helm env una vez por cada entorno:
    helm upgrade ENV_NAME apigee-env/ \
      --namespace APIGEE_NAMESPACE \
      --set env=ENV_NAME \
      -f overrides.yaml
    
  3. En el archivo overrides.yaml, elimina la configuración que habilitaba el uso de secretos externos para las claves de cifrado de la organización:
    # Comment out or delete the following line:
    # encryptionKeySecretProviderClass: apigee-orgencryptionkeys-spc
    
  4. A continuación, actualiza el gráfico de org Helm:
    helm upgrade org apigee-org/ \
      --namespace APIGEE_NAMESPACE \
      -f overrides.yaml