Como armazenar secrets do Cassandra no Hashicorp Vault
Esse recurso permite armazenar credenciais do Cassandra DB para a Apigee híbrida no Hashicorp Vault, um gerenciador de secrets externo. Com os gerenciadores de secrets externos, você gerencia a forma como os secrets são armazenados no Kubernetes, incluindo o gerenciamento da residência de dados e os controles de acesso refinados.
Antes da versão 1.10 da Apigee híbrida, a única maneira de fornecer senhas para os usuários do Cassandra era especificar a senha em replace.yaml. Essas senhas são armazenadas em secrets do Kubernetes. Por exemplo:
cassandra: auth: default: password: "********" admin: password: "********" ddl: password: "********" dml: password: "********" jmx: username: "jmxuser" password: "********" jolokia: username: "apigee" password: "********"
Com o Hashicorp Vault, é possível fornecer essas senhas por meio da API Kubernetes Secrets Store CSI Driver
(SecretProviderClass
).
Isso permite que o Kubernetes monte vários secrets, chaves e certificados armazenados em um Vault externo.
Usuários e senhas do Cassandra
Você precisará criar secrets para os seguintes usuários do Cassandra. Altere os valores padrão para atender às políticas de segurança da sua organização.
Usuário do Cassandra | Nome de usuário padrão | Senha padrão |
---|---|---|
Administrador | admin_user |
"********" |
DDL | ddl_user |
"********" |
Padrão | cassandra Observação: o nome de usuário padrão precisa ser sempre "cassandra" |
"********" |
DML | dml_user |
"********" |
JMX | "jmxuser" |
"********" |
Jolokia | "apigee" |
"********" |
Consulte a propriedade de configuração do Cassandra para mais informações.
Configurar a integração do secret externo
A configuração da integração do Vault para a Apigee híbrida consiste nos procedimentos a seguir.
- Nos dois primeiros procedimentos, você interage diretamente com o Vault.
- No terceiro e no quarto procedimentos, você vai aplicar as configurações ao cluster do Kubernetes.
Use os procedimentos a seguir para criar os secrets no Vault e permitir que sua instalação híbrida tenha acesso a eles.
Criar secrets, políticas e papéis do Vault
-
Verifique se o contexto atual do Kubernetes está definido como seu cluster:
kubectl config current-context
-
Use a API Vault, a CLI ou a IU para criar os secrets do Cassandra. Os valores de secret criados precisam corresponder aos nomes de usuário e senhas do Cassandra atualmente usados no cluster.
-
Chave de secret: qualquer chave de secret (ou combinação de várias chaves) pode ser usada. Por exemplo:
secret/data/apigee/cassandra
-
Dados de secret: a Apigee híbrida espera os pares de nome de usuário e senha dos seguintes usuários do Cassandra:
Usuários do Cassandra Administrador DDL Padrão DML JMX Jolokia -
CLI do Vault: o comando a seguir mostra como criar uma chave de secret com todos os nomes de usuário e senhas necessários:
Estes são os nomes de usuário padrão de cada usuário: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"
Usuário do Cassandra Valor padrão Administrador admin_user
DDL ddl_user
Padrão cassandra
DML dml_user
JMX jmxuser
Jolokia apigee
-
Chave de secret: qualquer chave de secret (ou combinação de várias chaves) pode ser usada. Por exemplo:
-
No Vault, crie uma política para conceder acesso ao secret que você acabou de criar.
-
Crie um arquivo de política
apigee-cassandra-auth.txt
(nome sugerido) com o seguinte conteúdo: Se você criou vários secrets, adicione cada um deles ao arquivo de política:path "secret/data/apigee/cassandra" { capabilities = ["read"] }
path "secret/data/apigee/cassandra/admin" { capabilities = ["read"] } path "secret/data/apigee/cassandra/ddl" { capabilities = ["read"] }
-
Aplique a política ao Vault:
vault policy write apigee-cassandra-auth apigee-cassandra-auth.txt
É possível criar a política usando a entrada padrão em vez de ler em um arquivo:
echo 'path "secret/data/apigee/cassandra" { capabilities = ["read"] }' | vault policy write apigee-cassandra-auth -
-
Crie um arquivo de política
-
Vincule a política às contas de serviço do Kubernetes do Apigee Cassandra.
- Defina as seguintes variáveis de ambiente:
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}
Em que:
- ORG_NAME é o nome da organização da Apigee;
- ENVS_LIST é uma lista separada por vírgulas dos seus ambientes da Apigee, por
exemplo,
dev,prod
. - APIGEE_NAMESPACE é seu namespace da Apigee. O padrão é
apigee
. - NAMESPACES é uma lista separada por vírgulas de namespaces para a Apigee,
apigee-system
e seu namespace da Apigee.
- Crie um script com os conteúdos a seguir: O script pode ter qualquer nome. No exemplo a seguir, o nome do 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
- Execute o script e atribua a saída à variável SERVICE_ACCOUNT_NAMES.
Isso vai criar uma lista separada por vírgulas de nomes de contas de serviço do Kubernetes.
export SERVICE_ACCOUNT_NAMES=$(./create-vault-cassandra-role)
Verifique se a variável foi preenchida com a lista:
echo $SERVICE_ACCOUNT_NAMES
-
Use a CLI do Vault para criar um papel que vincule a política às contas de serviço
do 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
- Defina as seguintes variáveis de ambiente:
Instalar o driver CSI e o provedor do Vault
A Apigee híbrida v1.12.3 oferece suporte às seguintes versões de gráficos do Helm:
Software | Versão |
---|---|
Driver CSI do Secrets Store | v1.3.4 |
Vault | v0.25.0 |
- Siga as instruções de instalação do driver CSI do Secrets Store para instalar o driver CSI no cluster. O driver CSI tem um gráfico Helm para instalação.
- Siga as instruções em Como instalar o provedor CSI do Vault para instalar o provedor CSI do Vault, se ele ainda não tiver sido instalado.
Criar o objeto SecretProviderClass
O recurso SecretProviderClass
informa ao driver CSI com qual provedor
se comunicar ao solicitar secrets. As credenciais dos usuários do Cassandra precisam ser configuradas
por meio desse objeto. A tabela a seguir mostra os nomes dos arquivos (objectName
s) esperados
pelo Apigee Cassandra:
Usuário do Cassandra | Nomes de arquivos de secrets esperados |
---|---|
Administrador | adminUsername , adminPassword |
DDL | ddlUsername , ddlPassword |
Padrão | cassandra , defaultPassword |
DML | dmlUsername , dmlPassword |
JMX | jmxUsername , jmxPassword |
Jolokia | jolokiaUsername , jolokiaPassword |
- Crie um arquivo YAML para o
SecretProviderClass
. O nome do arquivo pode ser qualquer coisa, por exemplo:spc.yaml
. Use o seguinte modelo 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: ""
- Aplique
SecretProviderClass
aos namespacesapigee
eapigee-system
. Nos comandos a seguir, os namespaces sãoapigee
eapigee-system
. Substitua esses valores se estiver usando namespaces diferentes:kubectl -n apigee apply -f spc.yaml
kubectl -n apigee-system apply -f spc.yaml
Ativar secret externo para Cassandra
- No
overrides.yaml
, adicione a seguinte configuração para ativar o uso de secrets externos para o Cassandra:cassandra: auth: secretProviderClass: apigee-cassandra-auth-spc # The name of the SecretProviderClass created in spc.yaml.
- Use
helm upgrade
para aplicar a mudança aos componentesapigee-operator
eapigee-datastore
:- O controlador de repositório de dados em
apigee-operator
participa da desativação do Cassandra e da replicação de dados durante a expansão da região. Essas tarefas exigem as credenciais JMX e Jolokia.helm upgrade operator apigee-operator/ \ --namespace apigee-system \ --atomic \ -f overrides.yaml
apigee-datastore
fornece credenciais que componentes downstream, comoapigee-runtime
, Sincronizador e MART, usam ao se conectar ao Cassandra.helm upgrade datastore apigee-datastore/ \ --namespace apigee \ --atomic \ -f overrides.yaml
- O controlador de repositório de dados em
-
Verifique se os secrets externos estão sendo usados. Quando os secrets externos são ativados, novos
Volume
s,Volume Mount
s eEnvironment Variable
s são adicionados como referência.- Verifique a implantação
apigee-controller-manager
.Verifique se existe um
Volume
chamadoapigee-external-secrets
e se faz referência aoSecretProviderClass
criado acima: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" }
Verifique se existe um
VolumeMount
chamadoapigee-external-secrets
: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 }
Verifique se há
Environment Variable
s que fazem referência a secrets externos: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" } ]
- Verifique a implantação
Reverter para o secret do K8s
- Para reverter para secrets não externos, remova a configuração
secretProviderClass
emoverrides.yaml
e use a configuração anterior:cassandra: auth: secretProviderClass: apigee-cassandra-auth-spc # remove this line
- Use
helm upgrade
para aplicar a mudança aos componentesapigee-operator
eapigee-datastore
:helm upgrade operator apigee-operator/ \ --namespace apigee-system \ --atomic \ -f overrides.yaml
helm upgrade datastore apigee-datastore/ \ --namespace apigee \ --atomic \ -f overrides.yaml
Solução de problemas: criar um contêiner do cliente para depuração
Se você usa o Vault, esta seção substitui as instruções da seção de solução de problemas Criar um contêiner de cliente para depuração.
Nesta seção, explicamos como criar um contêiner do cliente em que é possível acessar
utilitários de depuração do Cassandra,
como cqlsh
. Esses utilitários permitem consultar tabelas do Cassandra e
podem ser úteis para fins de depuração.
Criar o contêiner do cliente
Para criar o contêiner do cliente, siga estas etapas:
- O contêiner usa o certificado TLS do pod
apigee-cassandra-user-setup
. A primeira etapa é buscar esse nome de certificado:kubectl get secrets -n apigee --field-selector type=kubernetes.io/tls | grep apigee-cassandra-user-setup | awk '{print $1}'
Esse comando retorna o nome do certificado. Por exemplo,
apigee-cassandra-user-setup-rg-hybrid-b7d3b9c-tls
. - Abra um novo arquivo e cole a seguinte especificação de pod nele:
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
- Salve o arquivo com uma extensão
.yaml
. Por exemplo,my-spec.yaml
. - Aplique a especificação ao cluster:
kubectl apply -f my-spec.yaml -n apigee
- Faça login no contêiner:
kubectl exec -n CASSANDRA_CLIENT_NAME -it -- bash
- Conecte-se à interface
cqlsh
do Cassandra com os comandos a seguir. Digite os comandos exatamente como mostrado: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
Como excluir o pod cliente
Use este comando para excluir o pod de cliente do Cassandra:
kubectl delete pods -n apigee cassandra-client