Archiviazione dei secret di Cassandra in Hashicorp Vault

Archiviazione dei secret di Cassandra in Hashicorp Vault

Questa funzionalità ti consente di archiviare le credenziali del database Cassandra per Apigee Hybrid in Hashicorp Vault, un gestore di secret esterno. I gestori dei secret esterni ti consentono di gestire la modalità di archiviazione dei secret in Kubernetes, inclusa la gestione della residenza dei dati e dei controlli dell'accesso granulari.

Prima della versione 1.10 di Apigee Hybrid, l'unico modo per fornire le password per gli utenti Cassandra era specificare la password in overrides.yaml. Queste password sono archiviate nei secret di Kubernetes. Ad esempio:

cassandra:
  auth:
    default:
      password: "********"
    admin:
      password: "********"
    ddl:
      password: "********"
    dml:
      password: "********"
    jmx:
      username: "jmxuser"
      password: "********"
    jolokia:
      username: "apigee"
      password: "********"

Utilizzando Hashicorp Vault, puoi fornire queste password tramite l'API Kubernetes Secrets Store CSI Driver (SecretProviderClass). Ciò consente a Kubernetes di montare più secret, chiavi e certificati archiviati in un Vault esterno.

Utenti e password Cassandra

Dovrai creare secret per i seguenti utenti Cassandra. Modifica i valori predefiniti in modo che siano conformi alle norme di sicurezza della tua organizzazione.

Utente Cassandra Nome utente predefinito Password predefinita
Amministratore admin_user "********"
DDL ddl_user "********"
Predefinito cassandra Nota:il nome utente predefinito deve essere sempre "cassandra". "********"
DML dml_user "********"
JMX "jmxuser" "********"
Jolokia "apigee" "********"

Per ulteriori informazioni, consulta la proprietà di configurazione cassandra.

Configura l'integrazione dei secret esterni

La configurazione dell'integrazione di Vault per Apigee hybrid è costituita dalle seguenti procedure.

  • Nelle prime due procedure, interagisci direttamente con Vault.
  • Nelle procedure terza e quarta, applichi le configurazioni al cluster Kubernetes.

Utilizza le seguenti procedure per creare i secret in Vault e consentire all'installazione ibrida di accedervi.

Crea secret, policy e ruoli di Vault

  1. Verifica che il contesto Kubernetes attuale sia impostato sul tuo cluster:
    kubectl config current-context
  2. Utilizza l'API, la CLI o la UI di Vault per creare i secret di Cassandra. I valori segreti che crei devono corrispondere ai nomi utente e alle password di Cassandra attualmente utilizzati nel tuo cluster.
    • Chiave segreta: è possibile utilizzare qualsiasi chiave segreta (o combinazione di più chiavi), ad esempio:
      secret/data/apigee/cassandra
    • Dati secret: Apigee Hybrid prevede coppie di nome utente e password per i seguenti utenti Cassandra:
      Utenti Cassandra
      Amministratore
      DDL
      Predefinito
      DML
      JMX
      Jolokia
      Questi valori di nome utente e password possono essere distribuiti su un numero qualsiasi di chiavi segrete.
    • Interfaccia a riga di comando di Vault: il comando seguente mostra come creare un singolo secret contenente tutti i nomi utente e le password richiesti:
      vault kv put secret/apigee/cassandra \
          adminUsername="ADMIN_USERNAME" \
          adminPassword="ADMIN_PASSWORD" \
          ddlUsername="DDL_USERNAME" \
          ddlPassword="DDL_PASSWORD" \
          defaultUsername="cassandra" \
          defaultPassword="DEFAULT_PASSWORD" \
          dmlUsername="DML_USERNAME" \
          dmlPassword="DML_PASSWORD" \
          jmxUsername="JMX_USERNAME" \
          jmxPassword="JMX_PASSWORD" \
          jolokiaUsername="JOLOKIA_USERNAME" \
          jolokiaPassword="JOLOKIA_PASSWORD"
      I nomi utente predefiniti per ogni utente sono i seguenti:
      Utente Cassandra Valore predefinito
      Amministratore admin_user
      DDL ddl_user
      Predefinito cassandra
      DML dml_user
      JMX jmxuser
      Jolokia apigee
  3. In Vault, crea una policy per concedere l'accesso al secret che hai appena creato.
    1. Crea un file di criteri (nome suggerito: apigee-cassandra-auth.txt) con il seguente contenuto:
      path "secret/data/apigee/cassandra" {
        capabilities = ["read"]
      }
      Se hai creato più secret, ciascuno deve essere aggiunto al file delle policy:
      path "secret/data/apigee/cassandra/admin" {
        capabilities = ["read"]
      }
      
      path "secret/data/apigee/cassandra/ddl" {
        capabilities = ["read"]
      }
    2. Applica il criterio a Vault:
      vault policy write apigee-cassandra-auth apigee-cassandra-auth.txt

      È possibile creare il criterio utilizzando l'input standard anziché la lettura da un file:

      echo 'path "secret/data/apigee/cassandra" { capabilities = ["read"] }' | vault policy write apigee-cassandra-auth -
  4. Associa il criterio ai service account Kubernetes di Apigee Cassandra.
    1. Definisci le seguenti variabili di ambiente:
      export ORG_NAME=APIGEE_ORG_NAME
      export ENVS_LIST=LIST_OF_APIGEE-ENVS
      export APIGEE_NAMESPACE=YOUR_APIGEE_NAMESPACE

      Dove:

      • ORG_NAME è il nome della tua organizzazione Apigee.
      • ENVS_LIST È un elenco separato da virgole dei tuoi ambienti Apigee, ad esempio dev,prod.
      • APIGEE_NAMESPACE è il tuo spazio dei nomi Apigee. Il valore predefinito è apigee.
    2. Crea uno script con i seguenti contenuti. Lo script può avere qualsiasi nome. Nel seguente esempio, il nome dello script è create-vault-cassandra-role.sh:
      # create-vault-cassandra-role.sh
      
      ORG=ORG_NAME  # ORG name
      ENVS=ENVS_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}
      
      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
      
    3. Esegui lo script e assegna l'output alla variabile SERVICE_ACCOUNT_NAMES. Verrà creato un elenco di nomi di account di servizio Kubernetes separati da virgole.
      export SERVICE_ACCOUNT_NAMES=$(./create-vault-cassandra-role)

      Controlla che la variabile sia stata compilata con l'elenco:

      echo $SERVICE_ACCOUNT_NAMES
    4. Utilizza la CLI Vault per creare un ruolo che associa la policy ai service account Kubernetes:
      vault write auth/kubernetes/role/cassandra \
          bound_service_account_names=${SERVICE_ACCOUNT_NAMES} \
          bound_service_account_namespaces=${APIGEE_NAMESPACE} \
          policies=apigee-cassandra-auth \
          ttl=1m

Installa il driver CSI e il provider Vault

Apigee hybrid v1.13.4 supporta le seguenti versioni del grafico Helm:

Software Versione
Driver CSI Secrets Store v1.4.4
Vault 1.17.2
  1. Segui le istruzioni di installazione del driver CSI Secrets Store per installare il driver CSI sul cluster. Il driver CSI ha un grafico Helm per l'installazione.
  2. Segui le istruzioni riportate in Installazione del provider CSI Vault per installare il provider CSI Vault, se non l'hai già fatto.

Crea l'oggetto SecretProviderClass

La risorsa SecretProviderClass indica al driver CSI con quale provider comunicare quando richiede i secret. Le credenziali degli utenti Cassandra devono essere configurate tramite questo oggetto. La tabella seguente mostra i nomi file (objectNames) previsti da Apigee Cassandra:

Utente Cassandra Nomi dei file secret previsti
Amministratore adminUsername, adminPassword
DDL ddlUsername, ddlPassword
Predefinito cassandra, defaultPassword
DML dmlUsername, dmlPassword
JMX jmxUsername, jmxPassword
Jolokia jolokiaUsername, jolokiaPassword
  1. Crea un file YAML per il tuo SecretProviderClass. Il nome del file può essere qualsiasi, ad esempio: spc.yaml. Utilizza il seguente modello SecretProviderClass per configurare questa risorsa:
    apiVersion: secrets-store.csi.x-k8s.io/v1
    kind: SecretProviderClass
    metadata:
      name: apigee-cassandra-auth-spc
    spec:
      provider: vault
      parameters:
        roleName: apigee-cassandra-auth  # the roleName should match the vault role you created earlier in this procedure
    
        # vaultAddress is the endpoint your Vault server is running at.
        # If Vault is running in the same cluster as Apigee, the format will generally be:
        # http://vault.<namespace>.svc.cluster.local:<vaultServicePort>
        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 Cassandra 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.
        # For example, if the Vault secret is located at `secret/data/apigee/cassandra`
        # and you want to specify the admin password, you would use the following:
        # - objectName: "adminPassword"
        #   secretPath: "secret/data/apigee/cassandra"
        #   secretKey: "key within Vault secret specifying the admin password"
        objects: |
          - objectName: "adminUsername"
            secretPath: ""
            secretKey: ""
          - objectName: "adminPassword"
            secretPath: ""
            secretKey: ""
          - objectName: "defaultUsername"
            secretPath: ""
            secretKey: ""
          - objectName: "defaultPassword"
            secretPath: ""
            secretKey: ""
          - objectName: "ddlUsername"
            secretPath: ""
            secretKey: ""
          - objectName: "ddlPassword"
            secretPath: ""
            secretKey: ""
          - objectName: "dmlUsername"
            secretPath: ""
            secretKey: ""
          - objectName: "dmlPassword"
            secretPath: ""
            secretKey: ""
          - objectName: "jolokiaUsername"
            secretPath: ""
            secretKey: ""
          - objectName: "jolokiaPassword"
            secretPath: ""
            secretKey: ""
          - objectName: "jmxUsername"
            secretPath: ""
            secretKey: ""
          - objectName: "jmxPassword"
            secretPath: ""
            secretKey: ""
  2. Applica SecretProviderClass allo spazio dei nomi apigee:
    kubectl -n $APIGEE_NAMESPACE apply -f spc.yaml

Abilita il secret esterno per Cassandra

  1. All'interno di overrides.yaml, aggiungi la seguente configurazione per attivare l'utilizzo di secret esterni per Cassandra:
    cassandra:
      auth:
        secretProviderClass: apigee-cassandra-auth-spc  # The name of the SecretProviderClass created in spc.yaml.

    Vedi cassandra.auth.secretProviderClass.

  2. Utilizza helm upgrade per applicare la modifica ai componenti apigee-operator e apigee-datastore:
    • Il controller del datastore in apigee-operator partecipa al ritiro di Cassandra e alla replica dei dati durante l'espansione della regione. Queste attività richiedono le credenziali JMX e Jolokia.
      helm upgrade operator apigee-operator/ \
        --namespace $APIGEE_NAMESPACE \
        --atomic \
        -f overrides.yaml
    • apigee-datastore fornisce le credenziali che i componenti downstream come apigee-runtime, Synchronizer e MART utilizzano per connettersi a Cassandra.
      helm upgrade datastore apigee-datastore/ \
        --namespace $APIGEE_NAMESPACE \
        --atomic \
        -f overrides.yaml
  3. Verifica che vengano utilizzati i secret esterni. Quando i secret esterni sono attivati, vengono aggiunti nuovi Volume, Volume Mount e Environment Variable, che fanno riferimento ai secret.
    • Verifica il deployment di apigee-controller-manager.

      Verifica che esista un Volume denominato apigee-external-secrets e che faccia riferimento al SecretProviderClass creato sopra:

      kubectl -n $APIGEE_NAMESPACE get deployment apigee-controller-manager -o jsonpath='{.spec.template.spec.volumes[?(@.name=="apigee-external-secrets")]}'

      Output di esempio:

      {
        "csi": {
          "driver": "secrets-store.csi.k8s.io",
          "readOnly": true,
          "volumeAttributes": {
            "secretProviderClass": "apigee-cassandra-auth-spc"
          }
        },
        "name": "apigee-external-secrets"
      }

      Verifica che esista un VolumeMount denominato apigee-external-secrets:

      kubectl -n $APIGEE_NAMESPACE get deployment apigee-controller-manager -o jsonpath='{.spec.template.spec.containers[?(@.name=="manager")].volumeMounts[?(@.name=="apigee-external-secrets")]}'

      Output di esempio:

      {
        "mountPath": "/opt/apigee/externalsecrets",
        "name": "apigee-external-secrets",
        "readOnly": true
      }

      Verifica che esistano Environment Variable che fanno riferimento a secret esterni:

      kubectl -n $APIGEE_NAMESPACE get deployment apigee-controller-manager -o jsonpath='{.spec.template.spec.containers[?(@.name=="manager")].env}'

      Output di esempio:

      [
        ...
        {
          "name": "CASSANDRA_JOLOKIA_USERNAME_PATH",
          "value": "/opt/apigee/externalsecrets/jolokiaUsername"
        },
        {
          "name": "CASSANDRA_JOLOKIA_PASSWORD_PATH",
          "value": "/opt/apigee/externalsecrets/jolokiaPassword"
        }
      ]

Rollback al secret K8s

  1. Per ripristinare i secret non esterni, rimuovi la configurazione secretProviderClass in overrides.yaml e utilizza la configurazione precedente:
    cassandra:
          auth:
            secretProviderClass: apigee-cassandra-auth-spc # remove this line
  2. Utilizza helm upgrade per applicare la modifica ai componenti apigee-operator e apigee-datastore:
    helm upgrade operator apigee-operator/ \
      --namespace $APIGEE_NAMESPACE \
      --atomic \
      -f overrides.yaml
    helm upgrade datastore apigee-datastore/ \
      --namespace $APIGEE_NAMESPACE \
      --atomic \
      -f overrides.yaml

Risoluzione dei problemi: crea un contenitore client per il debug

Se utilizzi Vault, questa sezione sostituisce le istruzioni della sezione per la risoluzione dei problemi Crea un contenitore client per il debug.

Questa sezione spiega come creare un container client da cui puoi accedere alle utilità di debug di Cassandra come cqlsh. Queste utilità consentono di eseguire query sulle tabelle Cassandra e possono essere utili per il debug.

Crea il container client

Per creare il contenitore client:

  1. Il container utilizza il certificato TLS del pod apigee-cassandra-user-setup. Il primo passaggio consiste nel recuperare il nome del certificato:
    kubectl get secrets -n APIGEE_NAMESPACE --field-selector type=kubernetes.io/tls | grep apigee-cassandra-user-setup | awk '{print $1}'

    Questo comando restituisce il nome del certificato. Ad esempio: apigee-cassandra-user-setup-rg-hybrid-b7d3b9c-tls.

  2. Apri un nuovo file e incolla la seguente specifica del pod:
    apiVersion: v1
      kind: Pod
      metadata:
        labels:
        name: CASSANDRA_CLIENT_NAME   # For example: my-cassandra-client
        namespace: $APIGEE_NAMESPACE
      spec:
        containers:
        - name: CASSANDRA_CLIENT_NAME
          image: "gcr.io/apigee-release/hybrid/apigee-hybrid-cassandra-client:1.13.4"
          imagePullPolicy: Always
          command:
          - sleep
          - "3600"
          env:
          - name: CASSANDRA_SEEDS
            value: apigee-cassandra-default.apigee.svc.cluster.local
          - name: APIGEE_DML_USERNAME_PATH
            value: /opt/apigee/externalsecrets/dmlUsername
          - name: APIGEE_DML_PASSWORD_PATH
            value: /opt/apigee/externalsecrets/dmlPassword
          volumeMounts:
          - mountPath: /opt/apigee/ssl
            name: tls-volume
            readOnly: true
          - name: apigee-external-secrets
            mountPath: /opt/apigee/externalsecrets
            readOnly: true
        volumes:
        - name: tls-volume
          secret:
            defaultMode: 420
            secretName: apigee-cassandra-user-setup-vaibhavhybridor-8b3e61d-tls
        - name: apigee-external-secrets
          csi:
            driver: secrets-store.csi.k8s.io
            readOnly: true
            volumeAttributes:
              secretProviderClass: apigee-cass-password
        serviceAccount: apigee-cassandra-default
        serviceAccountName: apigee-cassandra-default
        restartPolicy: Never
  3. Salva il file con estensione .yaml. Ad esempio: my-spec.yaml.
  4. Applica la specifica al tuo cluster:
    kubectl apply -f my-spec.yaml -n $APIGEE_NAMESPACE
  5. Accedi al container:
    kubectl exec -n CASSANDRA_CLIENT_NAME -it -- bash
  6. Connettiti all'interfaccia Cassandra cqlsh con i seguenti comandi. Inserisci i comandi esattamente come mostrato:
    APIGEE_DML_USER=$(cat "$APIGEE_DML_USERNAME_PATH")
    export APIGEE_DML_USER
    APIGEE_DML_PASSWORD=$(cat "$APIGEE_DML_PASSNAME_PATH")
    export APIGEE_DML_PASSWORD
    cqlsh ${CASSANDRA_SEEDS} -u ${APIGEE_DML_USER} -p ${APIGEE_DML_PASSWORD} --ssl

Eliminazione del pod client

Utilizza questo comando per eliminare il pod client Cassandra:

kubectl delete pods -n $APIGEE_NAMESPACE cassandra-client