6.2. Kubernetes KMS v2 구성
etcd의 외부 KMS 암호화를 구성하여 키 관리를 중앙 집중화하고 규정 준수 요구 사항을 충족할 수 있습니다.
Kubernetes KMS v2는 기술 프리뷰 기능 전용입니다. 기술 프리뷰 기능은 Red Hat 프로덕션 서비스 수준 계약(SLA)에서 지원되지 않으며 기능적으로 완전하지 않을 수 있습니다. 따라서 프로덕션 환경에서 사용하는 것은 권장하지 않습니다. 이러한 기능을 사용하면 향후 제품 기능을 조기에 이용할 수 있어 개발 과정에서 고객이 기능을 테스트하고 피드백을 제공할 수 있습니다.
Red Hat 기술 프리뷰 기능의 지원 범위에 대한 자세한 내용은 기술 프리뷰 기능 지원 범위를 참조하십시오.
6.2.1. KMS 암호화 활성화 링크 복사링크가 클립보드에 복사되었습니다!
etcd 데이터에 대한 외부 KMS(Key Management Service) 암호화를 활성화하여 키 관리를 중앙 집중화하고 규정 준수 요구 사항을 충족할 수 있습니다.
사전 요구 사항
-
cluster-admin역할의 사용자로 클러스터에 액세스할 수 있어야 합니다. -
KMSEncryption기능 게이트를 사용하도록TechPreviewNoUpgrade기능 세트를 활성화했습니다. -
컨트롤 플레인 노드에서 액세스할 수 있는
HashiCorp Vault Enterprise인스턴스가 있습니다. Vault Community Edition을 사용할 수 없습니다. - 컨트롤 플레인 노드는 Vault 서버에 대한 네트워크 액세스 권한이 있습니다.
다음을 사용하여 Vault 인스턴스를 구성했습니다.
-
기본
전송/ 마운트 경로에서 사용 가능한 전송보안 엔진 -
aes256-gcm96유형으로 생성된 암호화 키( FIPS 140-3 준수의 경우 권장) - Kubernetes KMS v2 플러그인이 키 정보를 암호화, 암호 해독 및 읽을 수 있도록 Vault 정책
-
정책이 연결된 상태로 구성된 인증 방법(토큰,
AppRole또는userpass)
-
기본
Kubernetes KMS v2 플러그인에는 다음 기능이 있는 Vault 정책이 필요합니다.
path "transit/encrypt/kms-key" {
capabilities = ["update"]
}
path "transit/decrypt/kms-key" {
capabilities = ["update"]
}
path "transit/keys/kms-key" {
capabilities = ["read"]
}
path "auth/token/lookup-self" {
capabilities = ["read"]
}
다른 이름을 사용하는 경우 kms-key 를 Vault Transit 키 이름으로 바꿉니다.
KMS 암호화를 활성화하기 전에 etcd 백업을 생성합니다.
프로세스
각 컨트롤 플레인 호스트에 KMS 플러그인을 정적 Pod로 배포합니다.
-
unix:///var/run/kmsplugin/kms.sock에서 수신 대기하도록 플러그인을 구성합니다. -
정적 Pod의 경우
/var/run/kmsplugin을hostPath로 마운트합니다. - KMS 공급자 연결 세부 정보 및 인증 인증 정보 구성
다음 단계에서는
HashiCorpVault KMS 플러그인을 정적 Pod로 배포하는 방법을 보여줍니다.-
정적 Pod 매니페스트 파일을 생성합니다.
$ cat > /tmp/vault-kms-plugin.yaml <<'EOF' apiVersion: v1 kind: Pod metadata: name: vault-kms-plugin namespace: kube-system labels: app: vault-kms-plugin tier: control-plane spec: priorityClassName: system-node-critical hostNetwork: true containers: - name: vault-kms-plugin image: quay.io/redhat-isv-containers/698df066f8d1ddf179c15ef9:<version> command: - /vault-kubernetes-kms - -vault-address=<https://vault.example.com:8200> - -<vault_namespace>=admin - -auth-method=userpass - -userpass-username=<vault_username> - -userpass-password=<vault_password> - -transit-mount=transit - -transit-key=kms-key - -socket=unix:///var/run/kmsplugin/kms.sock volumeMounts: - name: kmsplugin mountPath: /var/run/kmsplugin resources: requests: cpu: 100m memory: 128Mi limits: cpu: 500m memory: 512Mi securityContext: privileged: true volumes: - name: kmsplugin hostPath: path: /var/run/kmsplugin type: DirectoryOrCreate EOF환경에 맞게 다음 값을 바꿉니다.
- <version>
-
Vault KMS 플러그인 이미지 버전 태그입니다.
0.1.0-beta-ubi를 사용합니다. - <vault_username>
- 인증을 위한 Vault 사용자 이름입니다.
- <vault_password>
- 인증을 위한 Vault 암호입니다.
- https://vault.example.com:8200
- Vault 주소입니다. Vault 서버 URL과 일치하도록 이 필드를 업데이트합니다.
- <vault_namespace>
선택적 필드입니다.
매니페스트는 OpenShift Container Platform에 권장되는 이미지인 Quay.io(
quay.io/redhat-isv-containers/698df066f8d1ddf179c15ef9)의 Red Hat 인증 컨테이너 이미지를 사용합니다.참고
다음 명령을 실행하여 각 컨트롤 플레인 노드에 고정 Pod 매니페스트를 배포합니다.
$ MANIFEST=$(cat /tmp/vault-kms-plugin.yaml | base64) $ for node in $(oc get nodes --selector=node-role.kubernetes.io/master -o name | cut -d/ -f2); do echo "Deploying to $node..." oc debug node/$node -- chroot /host bash -c \ "echo '$MANIFEST' | base64 -d > /etc/kubernetes/manifests/vault-kms-plugin.yaml" donekubelet은
/etc/kubernetes/manifests/에서 정적 Pod를 자동으로 탐지하고 시작합니다.다음 명령을 입력하여 정적 pod가 실행 중인지 확인합니다.
$ oc get pods -n kube-system -o wide | grep vault-kms출력 예
vault-kms-plugin-ip-10-0-16-7.compute.internal 1/1 Running 0 2m 10.0.16.7 vault-kms-plugin-ip-10-0-32-93.compute.internal 1/1 Running 0 2m 10.0.32.93 vault-kms-plugin-ip-10-0-69-106.compute.internal 1/1 Running 0 2m 10.0.69.106정적 Pod 이름에는 노드 이름이 접미사로 포함됩니다. 컨트롤 플레인 노드당 하나의 Pod가 표시되어야 합니다.
다음 명령을 입력하여 컨트롤 플레인 노드에 소켓이 있는지 확인합니다.
$ oc debug node/<node_name> -- chroot /host ls -la /var/run/kmsplugin/kms.sock출력 예
srwxr-xr-x. 1 root root 0 <timestamp> /var/run/kmsplugin/kms.sock참고정적 Pod는 각 노드의 kubelet에 의해 관리되며
oc delete Pod를사용하여 삭제할 수 없습니다. 정적 Pod를 제거하려면 각 컨트롤 플레인 노드의/etc/kubernetes/manifests/에서 매니페스트 파일을 삭제합니다.다음 명령을 입력하여
APIServer사용자 정의 리소스를 편집합니다.$ oc edit apiserver clusterspec.encryption섹션에 KMS 구성을 추가합니다.apiVersion: config.openshift.io/v1 kind: APIServer metadata: name: cluster spec: encryption: type: KMS저장 및 종료합니다.
마이그레이션이 자동으로 시작됩니다.
kube-apiserver,openshift-apiserver및oauth-apiserverOperator가 다시 시작되어 새 버전을 롤아웃합니다.참고openshift-apiserver및인증Operator는 일반적으로 5-10분 내에 마이그레이션을 완료합니다.kube-apiserverOperator는 보수적인 롤아웃 전략을 사용하여 한 번에 하나의 컨트롤 플레인 노드를 업데이트하고 다음 노드로 진행하기 전에 상태 점검을 대기합니다. 이 프로세스는 클러스터 로드에 따라 30분 이상 걸릴 수 있습니다.
검증
다음 명령을 입력하여 암호화 유형을 확인합니다.
$ oc get apiserver cluster -o jsonpath='{.spec.encryption.type}'출력에
KMS가 표시되어야 합니다.다음 명령을 입력하여
kube-apiserver롤아웃 진행 상황을 모니터링합니다.$ oc get kubeapiserver cluster -o jsonpath='{.status.nodeStatuses}' | jq -r '.[] | "\(.nodeName | split(".")[0]): current=\(.currentRevision) target=\(.targetRevision)"'롤아웃 중 출력 예
ip-10-0-16-166: current=10 target=0 ip-10-0-32-93: current=9 target=10 ip-10-0-69-106: current=9 target=0Operator는 한 번에 하나의 노드를 롤아웃합니다. 모든 노드에 동일한
현재리버전이 표시되고target이0이면 롤아웃이 완료됩니다.다음 명령을 입력하여 암호화 마이그레이션 상태를 확인합니다.
$ oc get kubeapiserver cluster -o jsonpath='{.status.conditions[?(@.type=="Encrypted")]}' | jq .완료 시 출력 예
{ "lastTransitionTime": "2026-05-15T17:39:02Z", "message": "All resources encrypted: secrets, configmaps", "reason": "EncryptionCompleted", "status": "True", "type": "Encrypted" }etcd에서 암호화를 확인하기 전에
EncryptionCompleted가 표시되는이유가있는지 확인합니다.etcd에서 보안이 암호화되었는지 확인합니다.
주의암호화를 확인하기 전에
kube-apiserver롤아웃이 모든 컨트롤 플레인 노드에서 완료될 때까지 기다립니다. 롤아웃 중에 API 요청은 노드에 분산되며 일부 노드는 아직 이전 버전에 남아 있지만 Kubernetes KMS v2로 암호화되지 않습니다.다음 명령을 입력하여 테스트 시크릿을 생성합니다.
$ oc create secret generic test-secret --from-literal=key=value -n default다음 명령을 입력하여 etcd pod 이름을 가져옵니다.
$ oc get pods -n openshift-etcd -l app=etcd -o name | head -1다음 명령을 입력하여 etcd의 시크릿 데이터를 확인합니다.
$ oc exec -n openshift-etcd <etcd_pod_name> -- etcdctl get /kubernetes.io/secrets/default/test-secret --print-value-only | hexdump -C | head -1출력은
k8s:enc:kms:v2로 시작한 다음 암호화된 바이너리 데이터로 시작해야 합니다.다음 명령을 입력하여 테스트 시크릿을 삭제합니다.
$ oc delete secret test-secret -n default