Stocker des secrets Cassandra dans Hashicorp Vault
Cette fonctionnalité vous permet de stocker les identifiants de base de données Cassandra pour Apigee hybrid dans Hashicorp Vault, un gestionnaire de secrets externe. Les gestionnaires de secrets externes vous permettent de gérer la façon dont les secrets sont stockés dans Kubernetes, y compris la gestion de la résidence des données et des contrôles d'accès précis.
Avant la version 1.10 d'Apigee hybrid, le seul moyen de fournir des mots de passe aux utilisateurs Cassandra était de spécifier le mot de passe dans le fichier overrides.yaml. Ces mots de passe sont stockés dans des secrets Kubernetes. Exemple :
cassandra: auth: default: password: "********" admin: password: "********" ddl: password: "********" dml: password: "********" jmx: username: "jmxuser" password: "********" jolokia: username: "apigee" password: "********"
Avec Hashicorp Vault, vous pouvez fournir ces mots de passe via l'API du pilote CSI Kubernetes Secrets Store (SecretProviderClass
). Cela permet à Kubernetes d'installer plusieurs secrets, clés et certificats stockés dans un Vault externe.
Utilisateurs et mots de passe Cassandra
Vous devrez créer des secrets pour les utilisateurs Cassandra suivants. Modifiez les valeurs par défaut pour qu'elles respectent les règles de sécurité de votre organisation.
Utilisateur Cassandra | Nom d'utilisateur par défaut | Mot de passe par défaut |
---|---|---|
Admin | admin_user |
"********" |
LDD | ddl_user |
"********" |
Par défaut | cassandra Remarque : Le nom d'utilisateur par défaut doit toujours être "cassandra". |
"********" |
LMD | dml_user |
"********" |
JMX | "jmxuser" |
"********" |
Jolokia | "apigee" |
"********" |
Pour en savoir plus, consultez la section Propriété de configuration Cassandra.
Configurer l'intégration de secrets externes
La configuration de l'intégration de Vault pour Apigee hybrid comprend les procédures suivantes.
- Dans les deux premières procédures, vous interagissez directement avec Vault.
- Dans la troisième et la quatrième procédure, vous appliquez les configurations à votre cluster Kubernetes.
Suivez les procédures ci-dessous pour créer les secrets dans Vault et permettre à votre installation hybride d'y accéder.
Créer des secrets, des règles et des rôles Vault
-
Vérifiez que le contexte Kubernetes actuel est défini sur votre cluster :
kubectl config current-context
-
Utilisez l'API, la CLI ou l'interface utilisateur Vault pour créer les secrets Cassandra. Les valeurs du secret que vous créez doivent correspondre aux noms d'utilisateur et aux mots de passe Cassandra actuellement utilisés dans votre cluster.
-
Clé secrète : toute clé secrète (ou combinaison de plusieurs clés) peut être utilisée, par exemple :
secret/data/apigee/cassandra
-
Données secrètes : Apigee Hybrid attend des paires nom d'utilisateur et mot de passe pour les utilisateurs Cassandra suivants :
Utilisateurs Cassandra Admin LDD Par défaut LMD JMX Jolokia -
CLI Vault : la commande suivante montre comment créer un seul secret contenant tous les noms d'utilisateurs et mots de passe requis :
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"
Utilisateur Cassandra Valeur par défaut Admin admin_user
LDD ddl_user
Par défaut cassandra
LMD dml_user
JMX jmxuser
Jolokia apigee
-
Clé secrète : toute clé secrète (ou combinaison de plusieurs clés) peut être utilisée, par exemple :
-
Dans Vault, créez une règle pour accorder l'accès au secret que vous venez de créer.
- Créez un fichier de règles (nom suggéré :
apigee-cassandra-auth.txt
) avec le contenu suivant : Si vous avez créé plusieurs secrets, chaque secret doit être ajouté au fichier de règles :path "secret/data/apigee/cassandra" { capabilities = ["read"] }
path "secret/data/apigee/cassandra/admin" { capabilities = ["read"] } path "secret/data/apigee/cassandra/ddl" { capabilities = ["read"] }
-
Appliquez la règle à Vault :
vault policy write apigee-cassandra-auth apigee-cassandra-auth.txt
Vous pouvez créer la règle en utilisant l'entrée standard plutôt que de lire à partir d'un fichier :
echo 'path "secret/data/apigee/cassandra" { capabilities = ["read"] }' | vault policy write apigee-cassandra-auth -
- Créez un fichier de règles (nom suggéré :
-
Liez la règle aux comptes de service Kubernetes Apigee Cassandra.
- Définissez les variables d'environnement suivantes :
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}
Où :
- ORG_NAME est le nom de votre organisation Apigee.
- ENVS_LIST est une liste de vos environnements Apigee séparés par une virgule, par exemple
dev,prod
. - APIGEE_NAMESPACE est votre espace de noms Apigee. La valeur par défaut est
apigee
. - NAMESPACES est une liste d'espaces de noms séparés par une virgule pour Apigee,
apigee-system
et votre espace de noms Apigee.
- Créez un fichier avec le contenu suivant : Le script peut porter n'importe quel nom. Dans l'exemple suivant, le nom du script est
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
- Exécutez le script et attribuez le résultat à la variable SERVICE_ACCOUNT_NAMES.
Vous obtiendrez une liste de noms de comptes de service Kubernetes séparés par une virgule.
export SERVICE_ACCOUNT_NAMES=$(./create-vault-cassandra-role)
Vérifiez que la variable a bien été renseignée avec la liste :
echo $SERVICE_ACCOUNT_NAMES
-
Utilisez la CLI Vault pour créer un rôle qui lie la règle aux comptes de service Kubernetes :
vault write auth/kubernetes/role/cassandra \ bound_service_account_names=${SERVICE_ACCOUNT_NAMES} \ bound_service_account_namespaces=${NAMESPACES} \ policies=apigee-cassandra-auth \ ttl=1m
- Définissez les variables d'environnement suivantes :
Installer le pilote CSI et le fournisseur Vault
Apigee hybrid v1.12.3 est compatible avec les versions de chart Helm suivantes:
Logiciels | Version |
---|---|
Pilote CSI Secrets Store | v1.3.4 |
Vault | v0.25.0 |
- Suivez les instructions d'installation du pilote CSI Secrets Store pour installer le pilote CSI sur votre cluster. Le pilote CSI dispose d'un chart Helm pour l'installation.
- Suivez les instructions de la page Installer le fournisseur CSI Vault pour installer le fournisseur CSI Vault si ce n'est pas déjà fait.
Créer un objet SecretProviderClass
La ressource SecretProviderClass
indique au pilote CSI avec quel fournisseur il doit communiquer lorsqu'il demande des secrets. Les identifiants des utilisateurs Cassandra doivent être configurés via cet objet. Le tableau suivant présente les noms de fichiers (objectName
) attendus par Apigee Cassandra :
Utilisateur Cassandra | Noms de fichiers de secrets attendus |
---|---|
Admin | adminUsername , adminPassword |
LDD | ddlUsername , ddlPassword |
Par défaut | cassandra , defaultPassword |
LMD | dmlUsername , dmlPassword |
JMX | jmxUsername , jmxPassword |
Jolokia | jolokiaUsername , jolokiaPassword |
- Créez un fichier YAML pour votre
SecretProviderClass
. Le nom du fichier peut être n'importe quel élément, par exemple :spc.yaml
. Utilisez le modèleSecretProviderClass
suivant pour configurer cette ressource :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: ""
- Appliquez
SecretProviderClass
à vos espaces de nomsapigee
etapigee-system
. Dans les commandes suivantes, les espaces de noms sontapigee
etapigee-system
. Remplacez ces valeurs si vous utilisez différents espaces de noms :kubectl -n apigee apply -f spc.yaml
kubectl -n apigee-system apply -f spc.yaml
Activer le secret externe pour Cassandra
- Dans votre
overrides.yaml
, ajoutez la configuration suivante pour activer l'utilisation des secrets externes pour Cassandra :cassandra: auth: secretProviderClass: apigee-cassandra-auth-spc # The name of the SecretProviderClass created in spc.yaml.
Consultez
cassandra.auth.secretProviderClass
. - Utilisez
helm upgrade
pour appliquer la modification aux composantsapigee-operator
etapigee-datastore
:- Le contrôleur de datastore dans
apigee-operator
participe à la mise hors service et à la réplication des données Cassandra lors de l'expansion de la région. Ces tâches nécessitent les identifiants JMX et Jolokia.helm upgrade operator apigee-operator/ \ --namespace apigee-system \ --atomic \ -f overrides.yaml
apigee-datastore
fournit des identifiants qui sont utilisés par les composants en aval tels queapigee-runtime
, le synchronisateur et MART lors de la connexion à Cassandra.helm upgrade datastore apigee-datastore/ \ --namespace apigee \ --atomic \ -f overrides.yaml
- Le contrôleur de datastore dans
-
Vérifiez que les secrets externes sont utilisés. Lorsque les secrets externes sont activés, de nouveaux
Volume
,Volume Mount
etEnvironment Variable
sont ajoutés pour faire référence aux secrets.- Vérifiez le déploiement
apigee-controller-manager
.Vérifiez qu'un objet
Volume
nomméapigee-external-secrets
existe et fait référence à la ressourceSecretProviderClass
créée ci-dessus :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" }
Vérifiez qu'un objet
VolumeMount
nomméapigee-external-secrets
existe :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 }
Vérifiez qu'il existe des
Environment Variable
qui font référence aux secrets externes :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" } ]
- Vérifiez le déploiement
Revenir au secret K8s
- Pour revenir aux secrets non externes, supprimez la configuration
secretProviderClass
dansoverrides.yaml
et utilisez la configuration précédente :cassandra: auth: secretProviderClass: apigee-cassandra-auth-spc # remove this line
- Utilisez
helm upgrade
pour appliquer la modification aux composantsapigee-operator
etapigee-datastore
:helm upgrade operator apigee-operator/ \ --namespace apigee-system \ --atomic \ -f overrides.yaml
helm upgrade datastore apigee-datastore/ \ --namespace apigee \ --atomic \ -f overrides.yaml
Dépannage : Créer un conteneur client pour le débogage
Si vous utilisez Vault, cette section remplace les instructions de la section de dépannage Créer un conteneur client pour le débogage.
Cette section explique comment créer un conteneur client à partir duquel vous pouvez accéder aux utilitaires de débogage Cassandra tels que cqlsh
. Ces utilitaires vous permettent d'interroger les tables Cassandra et peuvent être utiles à des fins de débogage.
Créer le conteneur client
Pour créer le conteneur client, procédez comme suit :
- Le conteneur utilise le certificat TLS du pod
apigee-cassandra-user-setup
. La première étape consiste à extraire ce nom de certificat :kubectl get secrets -n apigee --field-selector type=kubernetes.io/tls | grep apigee-cassandra-user-setup | awk '{print $1}'
Cette commande renvoie le nom du certificat. Exemple :
apigee-cassandra-user-setup-rg-hybrid-b7d3b9c-tls
. - Ouvrez un nouveau fichier et collez-y la spécification de pod suivante :
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
- Enregistrez le fichier avec l'extension
.yaml
. Exemple :my-spec.yaml
. - Appliquez les spécifications à votre cluster comme suit :
kubectl apply -f my-spec.yaml -n apigee
- Connectez-vous au conteneur :
kubectl exec -n CASSANDRA_CLIENT_NAME -it -- bash
- Connectez-vous à l'interface Cassandra
cqlsh
à l'aide des commandes suivantes. Saisissez les commandes exactement comme indiqué ci-dessous :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
Supprimer le pod client
Utilisez la commande suivante pour supprimer le pod client Cassandra :
kubectl delete pods -n apigee cassandra-client