Almacena secrets de Cassandra en Hashicorp Vault
Esta función te permite almacenar credenciales de la base de datos de Cassandra para Apigee Hybrid en Hashicorp Vault, un Secret Manager externo. Los Secret Manager externos te permiten administrar cómo se almacenan los objetos Secret en Kubernetes, incluida la administración de la residencia de datos y los controles de acceso detallados.
Antes de la versión 1.10 de Apigee Hybrid, la única forma de proporcionar contraseñas para los usuarios de Cassandra era especificar la contraseña en overrides.yaml. Estas contraseñas se almacenan en secrets de Kubernetes. Por ejemplo:
cassandra: auth: default: password: "********" admin: password: "********" ddl: password: "********" dml: password: "********" jmx: username: "jmxuser" password: "********" jolokia: username: "apigee" password: "********"
Con Hashicorp Vault, puedes proporcionar estas contraseñas a través de la API de Kubernetes Secrets Store CSI Driver (SecretProviderClass
). Esto permite que Kubernetes active varios secrets, claves y certificados almacenados en un Vault externo.
Usuarios y contraseñas de Cassandra
Deberás crear secrets para los siguientes usuarios de Cassandra. Cambia los valores predeterminados para cumplir con las políticas de seguridad de tu organización.
Usuario de Cassandra | Nombre de usuario predeterminado | Contraseña predeterminada |
---|---|---|
Administrador | admin_user |
"********" |
DDL | ddl_user |
"********" |
Predeterminado | cassandra Nota: El nombre de usuario predeterminado siempre debe ser “Cassandra”. |
"********" |
DML | dml_user |
"********" |
JMX | "jmxuser" |
"********" |
Jolokia | "apigee" |
"********" |
Consulta la propiedad de configuración de Cassandra para obtener más información.
Configura la integración de un secret externo
La configuración de la integración de Vault para Apigee Hybrid consta de los siguientes procedimientos.
- En los dos primeros procedimientos, interactúas de forma directa con Vault.
- En el tercer y cuarto procedimiento, aplicas la configuración a tu clúster de Kubernetes.
Usa los siguientes procedimientos para crear los secrets en Vault y permitir que tu instalación híbrida tenga acceso a ellos.
Crea políticas, secrets y roles de Vault
-
Verifica que el contexto actual de Kubernetes esté configurado en tu clúster:
kubectl config current-context
-
Usa la API, la CLI o la IU de Vault para crear los secrets de Cassandra.
Los valores secrets que crees deben coincidir con los nombres de usuario y las contraseñas de Cassandra que se usan en la actualidad en tu clúster.
-
Clave secreta: Se puede usar cualquier clave secreta (o combinación de varias claves), por ejemplo:
secret/data/apigee/cassandra
-
Datos secrets: Apigee Hybrid espera pares de nombre de usuario y contraseña para los siguientes usuarios de Cassandra:
Usuarios de Cassandra Administrador DDL Predeterminado DML JMX Jolokia -
CLI de Vault: El siguiente comando muestra cómo crear un solo secret que contenga todos los nombres de usuario y contraseñas necesarios:
Los nombres de usuario predeterminados para cada usuario son los siguientes: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"
Usuario de Cassandra Valor predeterminado Administrador admin_user
DDL ddl_user
Predeterminado cassandra
DML dml_user
JMX jmxuser
Jolokia apigee
-
Clave secreta: Se puede usar cualquier clave secreta (o combinación de varias claves), por ejemplo:
-
En Vault, crea una política para otorgar acceso al secret que acabas de crear.
- Crea un archivo de texto
apigee-cassandra-auth.txt
(nombre sugerido) con el siguiente contenido: Si creaste varios Secrets, cada uno debe agregarse al archivo de políticas:path "secret/data/apigee/cassandra" { capabilities = ["read"] }
path "secret/data/apigee/cassandra/admin" { capabilities = ["read"] } path "secret/data/apigee/cassandra/ddl" { capabilities = ["read"] }
-
Aplica la política a Vault:
vault policy write apigee-cassandra-auth apigee-cassandra-auth.txt
Es posible crear la política con una entrada estándar en lugar de leer desde un archivo:
echo 'path "secret/data/apigee/cassandra" { capabilities = ["read"] }' | vault policy write apigee-cassandra-auth -
- Crea un archivo de texto
-
Vincula la política a las cuentas de servicio de Kubernetes de Apigee Cassandra.
- Define las siguientes variables de entorno:
export ORG_NAME=APIGEE_ORG_NAME
export ENVS_LIST=LIST_OF_APIGEE-ENVS
export APIGEE_NAMESPACE=YOUR_APIGEE_NAMESPACE
Donde:
- ORG_NAME es el nombre de tu organización de Apigee.
- ENVS_LIST es una lista separada por comas de tus entornos de Apigee, por ejemplo,
dev,prod
. - APIGEE_NAMESPACE es el espacio de nombres de Apigee. El valor predeterminado es
apigee
.
- Crea una secuencia de comandos con el siguiente contenido: La secuencia de comandos puede tener cualquier nombre. En el siguiente ejemplo, el nombre de la secuencia de comandos es
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
- Ejecuta la secuencia de comandos y asigna el resultado a la variable SERVICE_ACCOUNT_NAMES.
Esto creará una lista separada por comas de los nombres de cuentas de servicio de Kubernetes.
export SERVICE_ACCOUNT_NAMES=$(./create-vault-cassandra-role)
Verifica que la variable se haya propagado con la lista:
echo $SERVICE_ACCOUNT_NAMES
-
Usa la CLI de Vault para crear una función que vincule la política a las cuentas de servicio de 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
- Define las siguientes variables de entorno:
Instala el controlador CSI y el proveedor de Vault
Apigee Hybrid v1.13.1 admite las siguientes versiones de gráficos de Helm:
Software | Versión |
---|---|
Controlador de CSI del almacén de secrets | v1.3.4 |
Vault | v0.25.0 |
- Sigue las instrucciones de instalación del controlador de CSI del almacén de secrets para instalar el controlador de CSI en tu clúster. El controlador de CSI tiene un gráfico de Helm para la instalación.
- Sigue las instrucciones en Instala el proveedor de CSI de Vault para instalar el proveedor de CSI de Vault si aún no lo instalaste.
Crea un objeto SecretProviderClass
El recurso SecretProviderClass
le indica al controlador de CSI con qué proveedor se debe comunicar cuando solicita secrets. Las credenciales de los usuarios de Cassandra deben configurarse a través de este objeto. En la siguiente tabla, se muestran los nombres de archivos (objectName
) que espera Apigee Cassandra:
Usuario de Cassandra | Nombres de archivos de secrets esperados |
---|---|
Administrador | adminUsername , adminPassword |
DDL | ddlUsername , ddlPassword |
Predeterminado | cassandra , defaultPassword |
DML | dmlUsername , dmlPassword |
JMX | jmxUsername , jmxPassword |
Jolokia | jolokiaUsername , jolokiaPassword |
- Crea un archivo YAML para tu
SecretProviderClass
. El nombre del archivo puede ser cualquier elemento, por ejemplo:spc.yaml
. Usa la siguiente plantilla deSecretProviderClass
para configurar este recurso: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: ""
- Aplica
SecretProviderClass
a tu espacio de nombresapigee
:kubectl -n $APIGEE_NAMESPACE apply -f spc.yaml
Habilita el secret externo para Cassandra
- En tu
overrides.yaml
, agrega la siguiente configuración para habilitar el uso de secrets externos para Cassandra:cassandra: auth: secretProviderClass: apigee-cassandra-auth-spc # The name of the SecretProviderClass created in spc.yaml.
Consulta
cassandra.auth.secretProviderClass
. - Usa
helm upgrade
para aplicar el cambio a los componentesapigee-operator
yapigee-datastore
:- El controlador del almacén de datos en
apigee-operator
participa en el retiro de servicio de Cassandra y la replicación de datos durante la expansión regional. Estas tareas requieren las credenciales de JMX y Jolokia.helm upgrade operator apigee-operator/ \ --namespace $APIGEE_NAMESPACE> \ --atomic \ -f overrides.yaml
apigee-datastore
proporciona credenciales que los componentes descendentes, comoapigee-runtime
, Synchronizer y MART usan cuando se conectan a Cassandra.helm upgrade datastore apigee-datastore/ \ --namespace $APIGEE_NAMESPACE \ --atomic \ -f overrides.yaml
- El controlador del almacén de datos en
-
Verifica que se usen secrets externos. Cuando se habilitan secrets externos, se agregan nuevos
Volume
,Volume Mount
yEnvironment Variable
, que hacen referencia a los secrets.- Verifica la implementación de
apigee-controller-manager
.Comprueba que exista un
Volume
llamadoapigee-external-secrets
que haga referencia a laSecretProviderClass
creada antes:kubectl -n $APIGEE_NAMESPACE 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" }
Comprueba que exista una
VolumeMount
llamadaapigee-external-secrets
:kubectl -n $APIGEE_NAMESPACE 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 }
Verifica que existan
Environment Variable
que hagan referencia a secrets externos:kubectl -n $APIGEE_NAMESPACE 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" } ]
- Verifica la implementación de
Revierte al Secret K8s
- Para volver a los secrets no externos, quita la configuración
secretProviderClass
enoverrides.yaml
y usa la configuración anterior:cassandra: auth: secretProviderClass: apigee-cassandra-auth-spc # remove this line
- Usa
helm upgrade
para aplicar el cambio a los componentesapigee-operator
yapigee-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
Solución de problemas: Crea un contenedor del cliente para depurar
Si usas Vault, esta sección reemplaza las instrucciones de la sección de solución de problemas, Crea un contenedor de cliente para la depuración.
En esta sección, se explica cómo crear un contenedor de cliente desde el que puedes acceder a las utilidades de depuración de Cassandra, como cqlsh
. Estas utilidades te permiten consultar tablas de Cassandra y pueden ser útiles para fines de depuración.
Crea el contenedor del cliente
Para crear el contenedor del cliente, sigue estos pasos:
- El contenedor usa el certificado TLS del Pod
apigee-cassandra-user-setup
. El primer paso es recuperar este nombre de certificado:kubectl get secrets -n APIGEE_NAMESPACE --field-selector type=kubernetes.io/tls | grep apigee-cassandra-user-setup | awk '{print $1}'
Este comando muestra el nombre del certificado. Por ejemplo:
apigee-cassandra-user-setup-rg-hybrid-b7d3b9c-tls
. - Abre un archivo nuevo y pega en él las siguientes especificaciones 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.1" 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
- Guarda el archivo con una extensión
.yaml
. Por ejemplo:my-spec.yaml
- Aplica las especificaciones a tu clúster:
kubectl apply -f my-spec.yaml -n $APIGEE_NAMESPACE
- Accede al contenedor:
kubectl exec -n CASSANDRA_CLIENT_NAME -it -- bash
- Conéctate a la interfaz
cqlsh
de Cassandra con los siguientes comandos. Ingresa los comandos con exactitud como se muestra: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
Borra el pod del cliente
Usa este comando para borrar el Pod de cliente de Cassandra:
kubectl delete pods -n $APIGEE_NAMESPACE cassandra-client