Using HashiCorp Vault with Kubernetes External Secrets: Hands-on Guide
"k8s 클러스터에 springboot application 배포 시리즈"의 시작 포스팅입니다
이번 포스트에서는 minikube에 배포한 Vault로 secret 정보를 관리하고 External Store 방식으로 k8s secret으로 연동해보겠습니다
이전에 포스트한 Kubernetes Vault Deployment: A Hands-on Guide with Minikube 에 k8s에 vault를 배포하는 과정이 포스팅되어있습니다
준비사항: Helm, k8s cluster, Vault
다루는 내용
- ExternalStore로 vault secret과 k8s secret 연동
- 연동과정 중 troubleshooting
ExternalStore로 vault secret와 k8s secret 연동
Vault의 secret을 k8s deployment의 환경변수로 주입하는 다양한 방법중에 "External Secrets Operator"을 이용한 Vault secret을 k8s secret으로 동기화를 다룹니다. ESO는 다양한 provider에 적용할 수 있는 범용 솔루션이어서 ESO로 연동했습니다
일련의 과정을 통해 vault secret와 k8s secret을 동기화합니다
- Vault Secret 추가
- Vault authentication
- ExternalSecretsOperator 설치
- Secret 정의
- SecretStore 정의
- ExternalSecrets 정의
- Deployment에서 환경변수 주입 확인
Vault secret 추가
Kubernetes Vault Deployment: A Hands-on Guide with Minikube 에서 다루었습니다
Vault authentication
다양한 authentication 중 approle을 이용한 인증방식을 통해 kubernetes와 vault의 secret engine을 연동하겠습니다
현재 KV secret engines을 생성후 특정 path로 secret을 생성한 상태입니다. policy를 생성한 후 role 생성시 policy를 연결해줍니다
policy 생성
Dashboard > Policies
Create ACL Policy
How to write a policy 보고 생성합니다
approle 활성화
approle을 사용하려면 활성화해줘야합니다
Dashboard > Access 클릭 > enable new method
enable new method approle을 생성합니다
vault shell에서 role을 생성해줍니다
vault write auth/approle/role/<생성할 role이름> token_policies=<생성한 policy이름>
role 생성 확인
vault read auth/approle/role/dev_role
roleId 확인
vault read /auth/approle/role/dev_role/role-id
secretId 발급
vault write /auth/approle/role/dev_role/secret-id -force
ExternalSecretsOperator 설치
helm repo add external-secrets https://charts.external-secrets.io
helm install external-secrets \
external-secrets/external-secrets \
-n external-secrets \
--create-namespace \
# --set installCRDs=true
Secret 정의
apiVersion: v1
kind: Secret
metadata:
name: vault-approle-secret
type: Opaque
stringData:
secretId: <approle secretId>
SecretStore 정의
apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
name: dev-springboot-app
spec:
provider:
vault:
server: "<Fully Qualified Domain Name>:<PORT>"
path: "<secretEngines이름>"
version: "v2"
auth:
appRole:
path: "approle"
roleId: "roleId"
secretRef:
name: "vault-approle-secret"
key: "secretId"
---
ExternalSecrets 정의
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: dev-springboot-app
spec:
refreshInterval: "15s"
secretStoreRef:
name: dev-springboot-app
kind: SecretStore
target:
name: dev-springboot-app-secret # k8s에 생성될 secret 이름
dataFrom:
- extract:
key: <vault secret path>
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: bitnami/nginx:latest
envFrom:
- secretRef:
name: dev-springboot-app-secret # 이전에 생성한 Secret 이름
Deployment에서 환경변수 주입 확인
연동과정 중 troubleshooting
- SecretStore - appRole authentication
- ExternalSecrets - cannot read secret data from Vault
SecretStore - appRole authentication
secretStore의 spec에서 server와 auth roleId와 secretId를 매핑해야하고, secretId는 secret을 별도로 빼서 적용해주었습니다
ExternalSecrets - cannot read secret data from Vault
external secret이 api로 vault를 찌릅니다 그래서 policy의 path를 지정하는데 보이는 path와 api path가 다르기 때문에 파악하는게 어려웠습니다
예를 들어, secret path가 <secret engine이름>/bbb/** 이면 api path는 <secret engine이름>/data/bbb/** 입니다
이것은 vault-ui에서 secret의 config에서 확인할 수 있습니다
그리고 policy에서 path를 <secret engine이름>/bbb/** 가 아닌 <secret engine이름>/data/bbb/** api path로 맞춰야합니다
ExternalSecret의 spec.dataFrom.extract.key 는 vault에서 보이는 path를 매핑해줘야 합니다
SecretStore의 spec.provider.vault.path: <secret engine name>을 매핑해줘야 합니다
'kubernetes > practical' 카테고리의 다른 글
Hands-On Helm: Deploying Essential Kubernetes Components (1) | 2024.08.27 |
---|---|
Kubernetes Vault Deployment: A Hands-on Guide with Minikube (0) | 2024.08.20 |