이 글은 Vault 기본설정(봉인해제, secret 생성, kubernetes 인증, policy 설정 등), kubernetes 클러스터 구성, Helm 설치가 되어 있다고 가정하고, Vault Secrets Operator를 사용하여 컨테이너에서 환경변수로 사용하는 방법을 가이드합니다.
Vault는 비밀 수명주기 관리를 위한 완벽한 솔루션을 제공하지만 개발자와 운영자는 완전히 새로운 도구를 배워야 합니다. 대신 개발자는 Kubernetes를 통해 Secret에 액세스할 수 있는 클라우드 기반 방식을 원하며 Vault를 깊이 이해할 필요가 없습니다.
vault secret operator는 Vault-Injector와 같이 사이드카 컨테이너 형태로 시크릿을 마운트 하는 것이 아닌 vault secret을 가져와서 kubernetes secret과 동기화하여 사용한다.
Vault Secrets Operator
Vault Secrets Operator Tutorials
$ helm install -n vault vault-secrets-operator hashicorp/vault-secrets-operator \
--set "defaultVaultConnection.enabled=true" \
--set "defaultVaultConnection.address=http://vault-internal.vault.svc.cluster.local:8200"
helm으로 VSO를 설치하고, defaultVaultConnection
옵션에 실행중인 vault
를 연결하는 설정을 한다.
$ kubectl get pod -n vault
NAME READY STATUS RESTARTS AGE
vault-0 1/1 Running 0 47m
vault-1 1/1 Running 0 47m
vault-2 1/1 Running 0 47m
vault-vault-secrets-operator-controller-manager-8fcdzd664-rkl89 2/2 Running 0 47m
vault-vault-secrets-operator-controller-manager-8fcdzd664-rkl89 파드는 권한 인증
(RBAC) 컨테이너와 vault secret과 kubernetes secret을 동기화
시켜주는 manager
컨테이너가 실행된다.
$ kubectl get crd
vaultauths.secrets.hashicorp.com 2024-01-30T04:05:08Z
vaultconnections.secrets.hashicorp.com 2024-01-30T04:05:08Z
vaultdynamicsecrets.secrets.hashicorp.com 2024-01-30T04:05:08Z
vaultpkisecrets.secrets.hashicorp.com 2024-01-30T04:05:08Z
vaultstaticsecrets.secrets.hashicorp.com 2024-01-30T04:05:08Z
vaultauths.secrets.hashicorp.com
: Vault 인증 메커니즘 관리를 위한 CRD이며, Kubernetes 클러스터 내에서 실행되는 애플리케이션이 Vault에 안전하게 인증
할 수 있도록 구성 정보를 정의한다.
vaultconnections.secrets.hashicorp.com
: Vault와의 연결 설정을 관리하기 위한 CRD이며, 이는 Kubernetes에서 Vault 서버로의 접속 정보와 방법을 구성하는 데 사용된다.
vaultdynamicsecrets.secrets.hashicorp.com
: 동적 비밀 관리를 위한 CRD이며, Vault는 요청에 따라 동적으로 비밀번호, 인증서 등을 생성할 수 있으며, 이 CRD를 통해 그러한 동적 비밀들의 생성과 관리를 구성할 수 있다.
vaultpkisecrets.secrets.hashicorp.com
: 공개 키 인프라(PKI) 비밀 관리를 위한 CRD이며, 인증서 발급, 갱신 및 취소와 같은 PKI 관련 작업을 자동화하는 데 사용된다.
vaultstaticsecrets.secrets.hashicorp.com
: 정적 비밀 관리를 위한 CRD이며, 정적 비밀은 사전에 정의된 비밀값이며, 이 CRD를 통해 Kubernetes 내에서 Vault에 저장된 정적 비밀을 관리할 수 있다.
여기서 우리가 사용하는 CRD는 3개이다.
1. vaultauths.secrets.hashicorp.com
2. vaultstaticsecrets.secrets.hashicorp.com
3. vaultconnections.secrets.hashicorp.com
여기서 vaultconnections.secrets.hashicorp.com
는 Helm으로 설치할 때 이미 배포가 되어있는 상태이다.
$ vault kv put secret/test id="test" password="passwd"
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultAuth
metadata:
name: static-auth
namespace: vault
spec:
method: kubernetes # Authentication Methods - 쿠버네티스 인증
mount: kubernetes # Authentication Methods Name
kubernetes:
role: test # vault에서 설정한 role name
serviceAccount: test # kubernetes serviceaccount name
audiences: # role을 생성할 때 넣었던 audience 값 입력
- vault
해당 manifest는 쿠버네티스에서 사용할 Vault 인증
을 정의한다.
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultStaticSecret
metadata:
name: test-secret
namespace: vault
spec:
type: kv-v2 # 시크릿 type 입력
# mount path
mount: secret # 마운트 할 Secret Engine name 입력
# path of the secret
path: test # 시크릿을 생성할 때 설정한 secret name을 설정한다.
# dest k8s secret
destination:
name: test-secret # kubernetes secret으로 생성할 kubernetes secret name 입력
create: true # kubernetes secret으로 생성여부
# static secret refresh interval
refreshAfter: 60s # vault secret과 kuberentes secret 동기화 시간 입력
# Name of the CRD to authenticate to Vault
vaultAuthRef: static-auth # 2번에서 생성한 VaultAuth name 입력
kubectl apply -f vault-auth.yaml
kubectl apply -f vault-static-secret.yaml
$ kubectl describe secret test-secret
Name: test-secret
Namespace: vault
Labels: app.kubernetes.io/component=secret-sync
app.kubernetes.io/managed-by=hashicorp-vso
app.kubernetes.io/name=vault-secrets-operator
secrets.hashicorp.com/vso-ownerRefUID=zsqpd2-aa93-4ff8-b487-46c97ad9aa9a
Annotations: <none>
Type: Opaque
Data
====
_raw: 175 bytes
id: 4 bytes
password: 6 bytes
시크릿을 조회해보면 vault secret에서 key, value를 가져와서 자동으로 kubernetes secret을 생성한다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: vault-test
namespace: vault
labels:
app: vault-test
spec:
selector:
matchLabels:
app: vault-test
replicas: 1
template:
metadata:
labels:
app: vault-test
spec:
serviceAccountName: test
containers:
- name: nginx
image: nginx
env:
- name: USER_ID
valueFrom:
secretKeyRef:
name: test-secret
key: id
- name: USER_PASSWORD
valueFrom:
secretKeyRef:
name: test-secret
key: password
secretKeyRef 속성으로 시크릿을 가져와서 env로 사용할 수 있다.