Hashicorp Vault에 Cassandra 보안 비밀 저장
이 기능을 사용하면 외부 보안 비밀 관리자인 Hashicorp Vault에 Apigee Hybrid의 Cassandra DB 사용자 인증 정보를 저장할 수 있습니다. 외부 보안 비밀 관리자를 사용하면 데이터 상주 관리와 세분화된 액세스 제어 관리 등 Kubernetes에 보안 비밀이 저장되는 방식을 관리할 수 있습니다.
Apigee Hybrid 버전 1.10 이전에는 Cassandra 사용자에게 비밀번호를 제공하는 유일한 방법은 override.yaml에 비밀번호를 지정하는 것이었습니다. 이러한 비밀번호는 Kubernetes 보안 비밀에 저장됩니다. 예를 들면 다음과 같습니다.
cassandra: auth: default: password: "********" admin: password: "********" ddl: password: "********" dml: password: "********" jmx: username: "jmxuser" password: "********" jolokia: username: "apigee" password: "********"
Hashicorp Vault를 사용하면 Kubernetes Secrets Store CSI Driver 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에 적용합니다.
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 v1.14.0에서는 다음 Helm 차트 버전을 지원합니다.
소프트웨어 | 버전 |
---|---|
Secrets Store CSI 드라이버 | v1.3.4 |
Vault | v0.25.0 |
- Secrets Store CSI 드라이버 설치 안내에 따라 CSI 드라이버를 클러스터에 설치합니다. CSI 드라이버에는 설치를 위한 Helm 차트가 있습니다.
- Vault CSI 제공업체를 아직 설치하지 않았으면 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
는 Cassandra에 연결할 때apigee-runtime
, 동기화 담당자, MART와 같은 다운스트림 구성요소에서 사용하는 사용자 인증 정보를 제공합니다.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 보안 비밀로 롤백
- 비외부 보안 비밀로 되돌리려면
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를 사용하는 경우 이 섹션은 디버깅을 위한 클라이언트 컨테이너 만들기 문제 해결 섹션의 안내를 대체합니다.
이 섹션에서는 cqlsh
와 같이 Cassandra 디버깅 유틸리티에 액세스할 수 있는 클라이언트 컨테이너를 만드는 방법을 설명합니다. 이러한 유틸리티는 Cassandra 테이블을 쿼리할 수 있고 디버깅 목적에 유용할 수 있습니다.
클라이언트 컨테이너 만들기
클라이언트 컨테이너를 만들려면 다음 단계를 따르세요.
- 컨테이너에서
apigee-cassandra-user-setup
포드의 TLS 인증서를 사용합니다. 첫 번째 단계는 이 인증서 이름을 가져오는 것입니다.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.14.0" 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