Cassandra-Secrets in Hashicorp Vault speichern

Cassandra-Secrets in Hashicorp Vault speichern

Mit diesem Feature können Sie Cassandra-DB-Anmeldedaten für Apigee Hybrid in Hashicorp Vault, einem externen Secret Manager, speichern. Externe Secret Manager ermöglichen Ihnen die Verwaltung der Speicherung von Secrets in Kubernetes, einschließlich der Verwaltung von Datenstandorten und detaillierter Zugriffssteuerung.

Vor Apigee Hybrid Version 1.10 war die einzige Möglichkeit, Passwörter für Cassandra-Nutzer bereitzustellen, das Passwort in overrides.yaml anzugeben. Diese Passwörter werden in Kubernetes-Secrets gespeichert. Beispiel:

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

Mit Hashicorp Vault können Sie diese Passwörter über die Kubernetes Secrets Store CSI Driver API (SecretProviderClass) bereitstellen. So kann Kubernetes mehrere Secrets, Schlüssel und Zertifikate in einem externen Vault bereitstellen.

Cassandra-Nutzer und -Passwörter

Für die folgenden Cassandra-Nutzer müssen Sie Secrets erstellen. Ändern Sie die Standardwerte so, dass sie den Sicherheitsrichtlinien Ihrer Organisation entsprechen.

Cassandra-Nutzer Standard-Nutzername Standardpasswort
Admin admin_user "********"
DDL ddl_user "********"
Standard cassandra Hinweis: Der Standardnutzername muss immer "cassandra" sein. "********"
DML dml_user "********"
JMX "jmxuser" "********"
Jolokia "apigee" "********"

Weitere Informationen finden Sie unter cassandra-Konfigurationsattribut.

Externe Secret-Integration konfigurieren

Die Einrichtung der Vault-Integration für Apigee Hybrid umfasst die folgenden Verfahren:

  • In den ersten beiden Verfahren interagieren Sie direkt mit Vault.
  • Im dritten und vierten Verfahren wenden Sie die Konfigurationen auf Ihren Kubernetes-Cluster an.

Gehen Sie folgendermaßen vor, um die Secrets in Vault zu erstellen und der Hybrid-Installation Zugriff darauf zu gewähren.

Vault-Secrets, -Richtlinien und -Rollen erstellen

  1. Prüfen Sie, ob der aktuelle Kubernetes-Kontext auf Ihren Cluster gesetzt ist:
    kubectl config current-context
  2. Verwenden Sie die Vault API, die Vault CLI oder die Vault-Benutzeroberfläche, um die Cassandra-Secrets zu erstellen. Die von Ihnen erstellten Secret-Werte müssen mit den Cassandra-Nutzernamen und -Passwörtern übereinstimmen, die derzeit in Ihrem Cluster verwendet werden.
    • Secret-Schlüssel: Jeder beliebige Secret-Schlüssel (oder eine Kombination mehrerer Schlüssel) kann verwendet werden, zum Beispiel:
      secret/data/apigee/cassandra
    • Secret-Daten: Apigee Hybrid erwartet Paare aus Nutzername und Passwort für die folgenden Cassandra-Nutzer:
      Cassandra-Nutzer
      Admin
      DDL
      Standard
      DML
      JMX
      Jolokia
      Diese Werte für Nutzername und Passwort können auf eine beliebige Anzahl von Secret-Schlüsseln verteilt werden.
    • Vault-Befehlszeile: Der folgende Befehl zeigt, wie ein einzelnes Secret mit allen erforderlichen Nutzernamen und Passwörtern erstellt wird:
      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"
      Die Standardnutzernamen lauten für jeden Nutzer:
      Cassandra-Nutzer Standardwert
      Admin admin_user
      DDL ddl_user
      Standard cassandra
      DML dml_user
      JMX jmxuser
      Jolokia apigee
  3. Erstellen Sie in Vault eine Richtlinie, um Zugriff auf das gerade erstellte Secret zu gewähren.
    1. Erstellen Sie eine Richtliniendatei apigee-cassandra-auth.txt (vorgeschlagener Name) mit folgendem Inhalt:
      path "secret/data/apigee/cassandra" {
        capabilities = ["read"]
      }
      Wenn Sie mehrere Secrets erstellt haben, muss der Richtliniendatei jedes Secret hinzugefügt werden:
      path "secret/data/apigee/cassandra/admin" {
        capabilities = ["read"]
      }
      
      path "secret/data/apigee/cassandra/ddl" {
        capabilities = ["read"]
      }
    2. Wenden Sie die Richtlinie auf Vault an:
      vault policy write apigee-cassandra-auth apigee-cassandra-auth.txt

      Sie können die Richtlinie auch mit einer Standardeingabe erstellen, anstatt aus einer Datei zu lesen:

      echo 'path "secret/data/apigee/cassandra" { capabilities = ["read"] }' | vault policy write apigee-cassandra-auth -
  4. Binden Sie die Richtlinie an die Apigee Cassandra-Kubernetes-Dienstkonten.
    1. Legen Sie die folgenden Umgebungsvariablen fest:
      export ORG_NAME=APIGEE_ORG_NAME
      export ENVS_LIST=LIST_OF_APIGEE-ENVS
      export APIGEE_NAMESPACE=YOUR_APIGEE_NAMESPACE
      export NAMESPACES=apigee-system,${APIGEE_NAMESPACE}

      Dabei gilt:

      • ORG_NAME ist der Name Ihrer Apigee-Organisation.
      • ENVS_LIST ist eine durch Kommas getrennte Liste Ihrer Apigee-Umgebungen, z. B. dev,prod.
      • APIGEE_NAMESPACE ist Ihr Apigee-Namespace. Der Standardwert ist apigee.
      • NAMESPACES ist eine durch Kommas getrennte Liste von Namespaces für Apigee, apigee-system und Ihren Apigee-Namespace.
    2. Erstellen Sie ein Script mit folgendem Inhalt: Das Script kann einen beliebigen Namen haben. Im folgenden Beispiel lautet der Name des Scripts 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. Führen Sie das Script aus und weisen Sie die Ausgabe der Variable SERVICE_ACCOUNT_NAMES zu. Dadurch wird eine durch Kommas getrennte Liste von Kubernetes-Dienstkontonamen erstellt.
      export SERVICE_ACCOUNT_NAMES=$(./create-vault-cassandra-role)

      Prüfen Sie, ob die Variable mit der Liste gefüllt wurde:

      echo $SERVICE_ACCOUNT_NAMES
    4. Verwenden Sie die Vault-Befehlszeile, um eine Rolle zu erstellen, die die Richtlinie an Kubernetes-Dienstkonten bindet:
      vault write auth/kubernetes/role/cassandra \
          bound_service_account_names=${SERVICE_ACCOUNT_NAMES} \
          bound_service_account_namespaces=${NAMESPACES} \
          policies=apigee-cassandra-auth \
          ttl=1m

CSI-Treiber und Vault-Anbieter installieren

Apigee Hybrid v1.12.3 unterstützt die folgenden Helm-Diagrammversionen:

Software Version
CSI-Treiber für Secrets-Speicher v1.3.4
Vault v0.25.0
  1. Folgen Sie der Installationsanleitung für den CSI-Treiber für den Secrets-Speicher, um den CSI-Treiber auf Ihrem Cluster zu installieren. Der CSI-Treiber hat ein Helm-Diagramm für die Installation.
  2. Folgen Sie der Anleitung unter Vault-CSI-Anbieter installieren, um den Vault-CSI-Anbieter zu installieren, falls Sie ihn noch nicht installiert haben.

SecretProviderClass-Objekt erstellen

Die Ressource SecretProviderClass teilt dem CSI-Treiber mit, mit welchem Anbieter beim Anfordern von Secrets kommuniziert werden soll. Die Cassandra-Nutzeranmeldedaten müssen über dieses Objekt konfiguriert werden. Die folgende Tabelle zeigt die von Apigee Cassandra erwarteten Dateinamen (objectName):

Cassandra-Nutzer Erwartete Namen der Secret-Dateien
Admin adminUsername, adminPassword
DDL ddlUsername, ddlPassword
Standard cassandra, defaultPassword
DML dmlUsername, dmlPassword
JMX jmxUsername, jmxPassword
Jolokia jolokiaUsername, jolokiaPassword
  1. Erstellen Sie eine YAML-Datei für die SecretProviderClass. Der Dateiname kann ein beliebiger Name sein, z. B. spc.yaml. Verwenden Sie die folgende SecretProviderClass-Vorlage, um diese Ressource zu konfigurieren:
    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. Wenden Sie die SecretProviderClass auf die Namespaces apigee und apigee-system an. In den folgenden Befehlen sind die Namespaces apigee und apigee-system. Ersetzen Sie diese Werte, wenn Sie andere Namespaces verwenden:
    kubectl -n apigee apply -f spc.yaml
    kubectl -n apigee-system apply -f spc.yaml

Externes Secret für Cassandra aktivieren

  1. Fügen Sie in Ihrer overrides.yaml die folgende Konfiguration hinzu, um die Nutzung eines externen Secrets für Cassandra zu aktivieren:
    cassandra:
      auth:
        secretProviderClass: apigee-cassandra-auth-spc  # The name of the SecretProviderClass created in spc.yaml.

    Weitere Informationen finden Sie unter cassandra.auth.secretProviderClass.

  2. Verwenden Sie helm upgrade, um die Änderung auf die Komponenten apigee-operator und apigee-datastore anzuwenden:
    • Der Datenspeicher-Controller in apigee-operator nimmt an der Cassandra-Außerbetriebnahme und Datenreplikation während der Regionserweiterung teil Für diese Aufgaben sind die JMX- und Jolokia-Anmeldedaten erforderlich.
      helm upgrade operator apigee-operator/ \
        --namespace apigee-system \
        --atomic \
        -f overrides.yaml
    • apigee-datastore stellt Anmeldedaten bereit, die von nachgelagerten Komponenten wie apigee-runtime, Synchronizer und MART verwendet werden, wenn eine Verbindung zu Cassandra hergestellt wird.
      helm upgrade datastore apigee-datastore/ \
        --namespace apigee \
        --atomic \
        -f overrides.yaml
  3. Prüfen Sie, ob externe Secrets verwendet werden. Wenn externe Secrets aktiviert sind, werden neue Volumes, Volume Mounts und Environment Variables hinzugefügt, die auf die Secrets verweisen.
    • apigee-controller-manager-Bereitstellung prüfen

      Prüfen Sie, ob ein Volume namens apigee-external-secrets vorhanden ist und auf die oben erstellte SecretProviderClass verweist:

      kubectl -n apigee-system get deployment apigee-controller-manager -o jsonpath='{.spec.template.spec.volumes[?(@.name=="apigee-external-secrets")]}'
      {
        "csi": {
          "driver": "secrets-store.csi.k8s.io",
          "readOnly": true,
          "volumeAttributes": {
            "secretProviderClass": "apigee-cassandra-auth-spc"
          }
        },
        "name": "apigee-external-secrets"
      }

      Prüfen Sie, ob ein VolumeMount namens apigee-external-secrets vorhanden ist:

      kubectl -n apigee-system get deployment apigee-controller-manager -o jsonpath='{.spec.template.spec.containers[?(@.name=="manager")].volumeMounts[?(@.name=="apigee-external-secrets")]}'
      {
        "mountPath": "/opt/apigee/externalsecrets",
        "name": "apigee-external-secrets",
        "readOnly": true
      }

      Prüfen Sie, ob Environment Variables vorhanden sind, die auf externe Secrets verweisen:

      kubectl -n apigee-system get deployment apigee-controller-manager -o jsonpath='{.spec.template.spec.containers[?(@.name=="manager")].env}'
      [
        ...
        {
          "name": "CASSANDRA_JOLOKIA_USERNAME_PATH",
          "value": "/opt/apigee/externalsecrets/jolokiaUsername"
        },
        {
          "name": "CASSANDRA_JOLOKIA_PASSWORD_PATH",
          "value": "/opt/apigee/externalsecrets/jolokiaPassword"
        }
      ]

Rollback zum K8s-Secret

  1. Wenn Sie zu nicht externen Secrets zurückkehren möchten, entfernen Sie die Konfiguration secretProviderClass in overrides.yaml und verwenden Sie die vorherige Konfiguration:
    cassandra:
          auth:
            secretProviderClass: apigee-cassandra-auth-spc # remove this line
  2. Verwenden Sie helm upgrade, um die Änderung auf die Komponenten apigee-operator und apigee-datastore anzuwenden:
    helm upgrade operator apigee-operator/ \
      --namespace apigee-system \
      --atomic \
      -f overrides.yaml
    helm upgrade datastore apigee-datastore/ \
      --namespace apigee \
      --atomic \
      -f overrides.yaml

Problembehebung: Client-Container zum Debugging erstellen

Wenn Sie Vault verwenden, ersetzt dieser Abschnitt die Anleitung im Abschnitt zur Fehlerbehebung Client-Container zum Debugging erstellen.

In diesem Abschnitt wird erläutert, wie Sie einen Client-Container erstellen, über den Sie auf Cassandra-Debugging-Dienstprogramme wie cqlsh zugreifen können. Diese Dienstprogramme können zum Abfragen von Cassandra-Tabellen und für Fehlerbehebungszwecke nützlich sein.

Client-Container erstellen

So erstellen Sie den Client-Container:

  1. Der Container verwendet das TLS-Zertifikat aus dem Pod apigee-cassandra-user-setup. Der erste Schritt besteht darin, diesen Zertifikatsnamen abzurufen:
    kubectl get secrets -n apigee --field-selector type=kubernetes.io/tls | grep apigee-cassandra-user-setup | awk '{print $1}'

    Dieser Befehl gibt den Zertifikatsnamen zurück. Beispiel: apigee-cassandra-user-setup-rg-hybrid-b7d3b9c-tls.

  2. Öffnen Sie eine neue Datei und fügen Sie folgende Pod-Spezifikation in diese ein:
    apiVersion: v1
      kind: Pod
      metadata:
        labels:
        name: CASSANDRA_CLIENT_NAME   # For example: my-cassandra-client
        namespace: apigee
      spec:
        containers:
        - name: CASSANDRA_CLIENT_NAME
          image: "gcr.io/apigee-release/hybrid/apigee-hybrid-cassandra-client:1.12.3"
          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. Speichern Sie die Datei mit der Erweiterung .yaml. Beispiel: my-spec.yaml
  4. Wenden Sie die Spezifikation auf Ihren Cluster an:
    kubectl apply -f my-spec.yaml -n apigee
  5. Melden Sie sich beim Container an:
    kubectl exec -n CASSANDRA_CLIENT_NAME -it -- bash
  6. Stellen Sie mit den folgenden Befehlen eine Verbindung zur Cassandra-Schnittstelle cqlsh her. Geben Sie die Befehle genau so ein:
    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

Client-Pod löschen

Verwenden Sie diesen Befehl, um den Cassandra-Client-Pod zu löschen:

kubectl delete pods -n apigee cassandra-client