Vault KMS 설정
Vault KMS 설정 (KMS setup)
Vault Kubernetes Key Management를 설치·구성해 암호화 키를 관리하고 Vault Enterprise로 저장 데이터를 암호화하는 전체 절차를 다룹니다.
출처: 문서
본문
베타 기능이에요. 베타 기능은 안정적이지만 아직 불완전할 수 있고 변경될 수 있어요. 프로덕션 Vault 배포에 베타 기능을 쓰는 것은 권장하지 않습니다.
Enterprise에요. 적절한 Vault Enterprise 라이선스가 필요합니다.
Vault Kubernetes Key Management를 설정해 암호화 키를 관리하고 Vault Enterprise로 저장 데이터를 암호화해 보아요.
Vault Kubernetes Key Management는 Transit 시크릿 엔진을 사용해 쿠버네티스 데이터 암호화 키(DEK)에 암호화 작업을 수행합니다. 아래 단계는 Vault Kubernetes Key Management와 함께 쓰도록 Vault를 구성해요.
시작하기 전에
- 유효한 라이선스를 가진 Vault Enterprise 서버가 있어야 해요.
- Vault 플러그인을 활성화·구성할 권한이 있어야 해요.
- Vault 정책을 생성·수정할 권한이 있어야 해요.
- 쿠버네티스 컨트롤 플레인 호스트에 접근하고 변경할 수 있어야 해요.
- 쿠버네티스 클러스터의 API 서버 구성과 EncryptionConfig를 수정할 권한이 있어야 해요.
1단계: Transit 플러그인 구성
- Transit 시크릿 엔진을 활성화해요. 예를 들어 k8s-transit 경로에 플러그인을 활성화하려면:
$ vault secrets enable -path k8s-transit transit
Success! Enabled the transit secrets engine at: k8s-transit/
- 명명된 암호화 키를 만들어요. 예를 들어 kms-kek라는 키를 만들려면:
$ vault write -f k8s-transit/keys/kms-kek
Key Value
--- -----
allow_plaintext_backup false
auto_rotate_period 0s
deletion_allowed false
derived false
exportable false
imported_key false
keys map[1:1773195483]
latest_version 1
min_available_version 0
min_decryption_version 1
min_encryption_version 0
name kms-kek
supports_decryption true
supports_derivation true
supports_encryption true
supports_signing false
type aes256-gcm96
- Transit 플러그인이 저장한 암호화 키에 대한 접근을 제어하는 접근 정책 파일 kms-policy.hcl을 만들어요. 예를 들어 최소 필수 권한을 가진 기본 정책을 만들려면:
path "k8s-transit/keys/kms-kek" {
capabilities = ["read"]
}
path "k8s-transit/encrypt/kms-kek" {
capabilities = ["update"]
}
path "k8s-transit/decrypt/kms-kek" {
capabilities = ["update"]
}
path "sys/license/status" {
capabilities = ["read"]
}
- 정책을 Vault에 저장해요. 예를 들어 k8s-kms-policy로 저장하려면:
$ vault policy write k8s-kms-policy ./kms-policy.hcl
Success! Uploaded policy: k8s-kms-policy
2단계: Vault 인증 구성
제한된 인증 지원: 현재 Vault Kubernetes Key Management는 AppRole 인증만 지원합니다.
- AppRole 플러그인을 활성화해요.
$ vault auth enable -path k8s-approle approle
Success! Enabled the approle auth method at: k8s-approle/
- Transit 접근 정책을 사용하는 인증용 명명된 역할을 만들어요. 예를 들어 k8s-kms-role이라는 새 역할을 만들려면:
$ vault write \
auth/k8s-approle/role/k8s-kms-role \
token_policies=k8s-kms-policy
Success! Data written to: auth/k8s-approle/role/k8s-kms-role
- 나중에 Vault Kubernetes Key Management 스태틱 파드를 구성할 때 사용할 새 역할의 시크릿 ID를 생성해요.
$ vault write -f auth/k8s-approle/role/k8s-kms-role/secret-id
Key Value
--- -----
secret_id 00000000-0000-0000-0000-000000000000
secret_id_accessor 11111111-1111-1111-1111-111111111111
secret_id_num_uses 0
secret_id_ttl 0s
- 나중에 Vault Kubernetes Key Management 스태틱 파드를 구성할 때 사용할 역할과 연결된 역할 ID를 가져와요.
$ vault read auth/k8s-approle/role/k8s-kms-role/role-id
Key Value
--- -----
role_id 00000000-0000-0000-0000-000000000000
3단계: 쿠버네티스 구성
Vault Kubernetes Key Management 프로세스인 vault-kube-kms는 유닉스 소켓으로 kube-apiserver 프로세스와 통신해요. 따라서 vault-kube-kms는 컨트롤 플레인 노드에서 스태틱 파드로 실행되어야 해요.
- 노드용 EncryptionConfiguration 파일 encryption-config.yaml을 만들어요. endpoint가 vault-kube-kms 프로세스가 호스트에 유닉스 소켓을 만드는 경로와 일치하는지 확인해요. 예:
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
providers:
- kms:
apiVersion: v2
name: vault-kms
endpoint: unix:///var/run/kmsplugin/kms.sock
timeout: 3s
- identity: {}
-
EncryptionConfiguration 파일을 각 컨트롤 플레인 노드에 저장해요. 모든 컨트롤 플레인 노드에 존재하는 경로를 사용하세요.
/etc/kubernetes/encryption/encryption-config.yaml같은 경로를 권장합니다. -
Transit 플러그인의 AppRole 시크릿 ID를 각 컨트롤 플레인 노드의
/etc/vault-kms/approle-secret-id에 복사해요. -
vault-kube-kms 프로세스용 매니페스트 파일 vault-kms-plugin.yaml을 만들어요. 예:
apiVersion: v1
kind: Pod
metadata:
name: vault-kms-plugin
namespace: kube-system
labels:
tier: control-plane
component: vault-kms-plugin
spec:
priorityClassName: system-node-critical
containers:
- name: vault-kms-plugin
image: <IMAGE>
imagePullPolicy: Never
args:
- --vault-address=<VAULT_ADDRESS>
- --listen-address=unix:///var/run/kmsplugin/kms.sock
- --approle-role-id=<ROLE_ID>
- --approle-secret-id-path=/etc/vault-kms/approle-secret-id
- --transit-mount=k8s-transit
- --transit-key=kms-kek
- --zap-log-level=info
volumeMounts:
- name: kmsplugin-sockdir
mountPath: /var/run/kmsplugin
- name: approle-secret-id
mountPath: /etc/vault-kms/approle-secret-id
readOnly: true
resources:
requests:
cpu: 10m
memory: 32Mi
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
volumes:
- name: kmsplugin-sockdir
hostPath:
path: /var/run/kmsplugin
type: DirectoryOrCreate
- name: approle-secret-id
hostPath:
path: /etc/vault-kms/approle-secret-id
type: File
- 매니페스트 파일을 API 서버를 실행하는 컨트롤 플레인 노드의
/etc/kubernetes/manifests/에 저장해요. API 서버를 여러 개 실행한다면 각 컨트롤 플레인 노드에 vault-kube-kms 프로세스를 배포해서 각 쿠버네티스 API 서버 인스턴스가 자신의 로컬 유닉스 소켓에 연결할 수 있게 해야 해요.
kubelet 프로세스가 매니페스트 파일을 발견하고 vault-kube-kms를 스태틱 파드로 자동 시작해야 합니다.
4단계: 저장 데이터 암호화 활성화
각 컨트롤 플레인에서 저장 데이터 암호화를 활성화하려면 쿠버네티스 API 서버 매니페스트 kube-apiserver.yaml을 업데이트해야 해요.
-
kube-apiserver 컨테이너가
/etc/kubernetes/encryption/encryption-config.yaml의 encryption-config.yaml 암호화 구성 파일을 읽을 수 있는지 확인해요. -
encryption-config.yaml 파일에 연결된 명명된 볼륨으로 매니페스트를 업데이트해요. 예:
volumes:
- name: encryption-config
hostPath:
path: /etc/kubernetes/encryption/encryption-config.yaml
type: File
- encryption-config.yaml 파일을 마운트하도록 매니페스트의 volumeMounts 스탠자를 업데이트해요:
volumeMounts:
- name: encryption-config
mountPath: /etc/kubernetes/encryption/encryption-config.yaml
readOnly: true
- kube-apiserver 명령에 --encryption-provider-config를 추가하고 encryption-config.yaml 파일로 설정해요. 예:
args:
...
- --encryption-provider-config=/etc/kubernetes/encryption/encryption-config.yaml
...
- 매니페스트를 저장해 kubelet이 kube-apiserver 스태틱 파드를 재시작하게 해요.