在 Hashicorp Vault 中儲存 Cassandra 密鑰
這項功能可讓您在外部密碼管理工具 Hashicorp Vault 中,儲存 Apigee Hybrid 的 Cassandra 資料庫憑證。外部密鑰管理工具可讓您管理密鑰在 Kubernetes 中的儲存方式,包括管理資料落地和精細的存取控制。
在 Apigee Hybrid 1.10 版之前,為 Cassandra 使用者提供密碼的唯一方法,是在 overrides.yaml 中指定密碼。這些密碼會儲存在 Kubernetes Secret 中。例如:
cassandra: auth: default: password: "********" admin: password: "********" ddl: password: "********" dml: password: "********" jmx: username: "jmxuser" password: "********" jolokia: username: "apigee" password: "********"
您可以使用 Hashicorp Vault,透過 Kubernetes Secrets Store CSI 驅動程式 API (SecretProviderClass
) 提供這些密碼。這樣一來,Kubernetes 就能掛接儲存在外部 Vault 中的多個密鑰、金鑰和憑證。
Cassandra 使用者和密碼
您需要為下列 Cassandra 使用者建立密碼。變更預設值,以符合貴機構的安全性政策。
Cassandra 使用者 | 預設使用者名稱 | 預設密碼 |
---|---|---|
管理員 | admin_user |
"********" |
DDL | ddl_user |
"********" |
預設 | cassandra 注意:預設使用者名稱一律為「cassandra」 |
"********" |
DML | dml_user |
"********" |
JMX | "jmxuser" |
"********" |
Jolokia | "apigee" |
"********" |
詳情請參閱 Cassandra 設定屬性。
設定外部密鑰整合
為 Apigee Hybrid 設定 Vault 整合功能時,請按照下列程序操作。
- 在前兩個程序中,您會直接與 Vault 互動。
- 在第三和第四個程序中,您會將設定套用至 Kubernetes 叢集。
請按照下列程序在 Vault 中建立密鑰,並允許混合式安裝存取這些密鑰。
建立 Vault 密鑰、政策和角色
-
確認目前的 Kubernetes 內容已設為叢集:
kubectl config current-context
-
使用 Vault API、CLI 或 UI 建立 Cassandra 密鑰。您建立的密碼值必須與叢集中目前使用的 Cassandra 使用者名稱和密碼相符。
-
私密金鑰:可以使用任何私密金鑰 (或多個金鑰的組合),例如:
secret/data/apigee/cassandra
-
私密資料:Apigee Hybrid 需要下列 Cassandra 使用者的使用者名稱和密碼配對:
Cassandra 使用者 管理員 DDL 預設 DML JMX Jolokia -
Vault CLI:下列指令說明如何建立單一密碼,其中包含所有必要的使用者名稱和密碼:
每個使用者的預設使用者名稱如下: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"
Cassandra 使用者 預設值 管理員 admin_user
DDL ddl_user
預設 cassandra
DML dml_user
JMX jmxuser
Jolokia apigee
-
私密金鑰:可以使用任何私密金鑰 (或多個金鑰的組合),例如:
-
在 Vault 中建立政策,授予您剛建立的密鑰存取權。
-
建立政策檔案 (建議名稱:
apigee-cassandra-auth.txt
),並在當中加入下列內容: 如果您建立了多個密鑰,則必須將每個密鑰新增至政策檔案:path "secret/data/apigee/cassandra" { capabilities = ["read"] }
path "secret/data/apigee/cassandra/admin" { capabilities = ["read"] } path "secret/data/apigee/cassandra/ddl" { capabilities = ["read"] }
-
對保管箱套用政策:
vault policy write apigee-cassandra-auth apigee-cassandra-auth.txt
您可以透過標準輸入建立政策,不必從檔案讀取:
echo 'path "secret/data/apigee/cassandra" { capabilities = ["read"] }' | vault policy write apigee-cassandra-auth -
-
建立政策檔案 (建議名稱:
-
將政策繫結至 Apigee Cassandra Kubernetes 服務帳戶。
- 定義下列環境變數:
export ORG_NAME=APIGEE_ORG_NAME
export ENVS_LIST=LIST_OF_APIGEE-ENVS
export APIGEE_NAMESPACE=YOUR_APIGEE_NAMESPACE
其中:
- ORG_NAME 是指 Apigee 機構的名稱。
- ENVS_LIST 是以半形逗號分隔的 Apigee 環境清單,例如
dev,prod
。 - APIGEE_NAMESPACE 是您的 Apigee 命名空間。預設值為
apigee
。
- 建立含有以下內容的指令碼。指令碼可以有任何名稱。在以下範例中,指令碼名稱為
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
- 執行指令碼,並將輸出內容指派給 SERVICE_ACCOUNT_NAMES 變數。
這會建立以半形逗號分隔的 Kubernetes 服務帳戶名稱清單。
export SERVICE_ACCOUNT_NAMES=$(./create-vault-cassandra-role)
確認變數是否已填入清單:
echo $SERVICE_ACCOUNT_NAMES
-
使用 Vault CLI 建立角色,將政策繫結至 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
- 定義下列環境變數:
安裝 CSI 驅動程式和 Vault 供應商
Apigee Hybrid 1.13.4 版支援下列 Helm 圖表版本:
軟體 | 版本 |
---|---|
Secrets Store CSI 驅動程式 | v1.4.4 |
保管箱 | 1.17.2 |
- 請按照 Secrets Store CSI 驅動程式安裝操作說明,在叢集上安裝 CSI 驅動程式。CSI 驅動程式有 Helm 資訊套件可供安裝。
- 如果尚未安裝,請按照「安裝 Vault CSI 供應商」一文的說明進行安裝。
建立 SecretProviderClass 物件
SecretProviderClass
資源會告知 CSI 驅動程式,要求密碼時要與哪個供應商通訊。Cassandra 使用者的憑證必須透過這個物件設定。下表顯示 Apigee Cassandra 預期的檔案名稱 (objectName
):
Cassandra 使用者 | 預期密鑰檔案名稱 |
---|---|
管理員 | adminUsername 、adminPassword |
DDL | ddlUsername 、ddlPassword |
預設 | cassandra 、defaultPassword |
DML | dmlUsername 、dmlPassword |
JMX | jmxUsername 、jmxPassword |
Jolokia | jolokiaUsername 、jolokiaPassword |
- 為
SecretProviderClass
建立 YAML 檔案。檔案名稱可以是任何名稱,例如spc.yaml
。請使用下列SecretProviderClass
範本設定這項資源: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: ""
- 將
SecretProviderClass
套用至apigee
命名空間:kubectl -n $APIGEE_NAMESPACE apply -f spc.yaml
為 Cassandra 啟用外部密鑰
- 在
overrides.yaml
中,新增下列設定,為 Cassandra 啟用外部密鑰使用功能:cassandra: auth: secretProviderClass: apigee-cassandra-auth-spc # The name of the SecretProviderClass created in spc.yaml.
- 使用
helm upgrade
將變更套用至apigee-operator
和apigee-datastore
元件:apigee-operator
中的資料儲存控制器會在區域擴充期間,參與 Cassandra 停用和資料複寫作業。執行這些工作時,需要 JMX 和 Jolokia 憑證。helm upgrade operator apigee-operator/ \ --namespace $APIGEE_NAMESPACE \ --atomic \ -f overrides.yaml
apigee-datastore
提供憑證,供apigee-runtime
、Synchronizer 和 MART 等下游元件連線至 Cassandra 時使用。helm upgrade datastore apigee-datastore/ \ --namespace $APIGEE_NAMESPACE \ --atomic \ -f overrides.yaml
-
確認是否使用外部密鑰。啟用外部密鑰後,系統會新增參照密鑰的
Volume
、Volume Mount
和Environment Variable
。- 驗證
apigee-controller-manager
部署作業。確認名為
apigee-external-secrets
的Volume
存在,並參照上方建立的SecretProviderClass
: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" }
確認名為
apigee-external-secrets
的VolumeMount
存在: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 }
確認是否有參照外部密鑰的
Environment Variable
: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" } ]
- 驗證
回溯至 K8s Secret
- 如要還原為非外部密鑰,請移除
overrides.yaml
中的secretProviderClass
設定,並使用先前的設定:cassandra: auth: secretProviderClass: apigee-cassandra-auth-spc # remove this line
- 使用
helm upgrade
將變更套用至apigee-operator
和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
疑難排解:建立用戶端容器以進行偵錯
如果您使用 Vault,本節內容會取代疑難排解章節中的操作說明,請參閱「建立用於偵錯的用戶端容器」。
本節說明如何建立用戶端容器,從中存取 Cassandra 偵錯公用程式,例如 cqlsh
。這些公用程式可讓您查詢 Cassandra 資料表,有助於偵錯。
建立用戶端容器
如要建立用戶端容器,請按照下列步驟操作:
- 容器會使用 Pod 中的 TLS 憑證。
apigee-cassandra-user-setup
第一步是擷取這個憑證名稱:kubectl get secrets -n APIGEE_NAMESPACE --field-selector type=kubernetes.io/tls | grep apigee-cassandra-user-setup | awk '{print $1}'
這項指令會傳回憑證名稱。例如:
apigee-cassandra-user-setup-rg-hybrid-b7d3b9c-tls
。 - 開啟新檔案,並將下列 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
- 使用
.yaml
副檔名儲存檔案。例如:my-spec.yaml
。 - 將規格套用至叢集:
kubectl apply -f my-spec.yaml -n $APIGEE_NAMESPACE
- 登入容器:
kubectl exec -n CASSANDRA_CLIENT_NAME -it -- bash
- 使用下列指令連線至 Cassandra
cqlsh
介面。請完全按照畫面所示輸入指令: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
正在刪除用戶端 Pod
使用下列指令刪除 Cassandra 用戶端 Pod:
kubectl delete pods -n $APIGEE_NAMESPACE cassandra-client