쿠버네티스 외부에 존재하는 Vault
의 Secret 정보
를 쿠버네티스
가 가져와서 쿠버네티스의 Secret
으로 변환해주는 방법을 공유하려 한다. 개념 위주보다는 실습 위주로 공유드리려 한다.
실습 결과는 아래와 같다. 참고로 쿠버네티스는 이미 기존에 설치되어있다고 간주하고 진행한다.
Vault
서버 실행$ mkdir vault
$ cd vault
$ cat > docker-compose.yaml << EOF
version: '3.8'
services:
vault:
image: hashicorp/vault:1.18
container_name: vault
environment:
VAULT_DEV_ROOT_TOKEN_ID: root
VAULT_DEV_LISTEN_ADDRESS: "0.0.0.0:8200"
VAULT_TOKEN: root
VAULT_ADDR: http://127.0.0.1:8200
ports:
- "8200:8200"
cap_add:
- IPC_LOCK
command: |
vault server -dev -dev-root-token-id=root
EOF
# 도커를 통한 vault 서버 실행
$ docker compose up -d
Vault
서버 세팅# vault 서버에 접속
$ docker compose exec -it vault sh
# appRole 을 통한 인증이 가능하도록 변경
$ vault auth enable -path=approle-k8s approle
# kvv2 버전의 시크릿이 생성가능하도록 함
$ vault secrets enable -path=kvv2 kv-v2
# 정책 파일 생성 (시크릿를 읽을 수 있는 권한)
$ tee webapp.json <<EOF
path "kvv2/data/webapp/config" {
capabilities = ["read", "list"]
}
EOF
# 정책 생성
$ vault policy write webapp webapp.json
# 정책을 사용하는 Role 생성
$ vault write auth/approle-k8s/role/vault-secrets-operator token_policies=webapp
# Role ID 획득
$ vault read auth/approle-k8s/role/vault-secrets-operator/role-id
>
Key Value
--- -----
role_id 7240f33d-2377-f405-b4e0-6c2fae5e3754
# 획득한 role ID 저장해둔다.
$ role_id=7240f33d-2377-f405-b4e0-6c2fae5e3754
# Role 에 대한 Secret ID 생성
$ vault write -f auth/approle-k8s/role/vault-secrets-operator/secret-id
>
Key Value
--- -----
secret_id d4f40551-e67f-0e06-3e45-a7fcffbf347a
secret_id_accessor 350d65ae-400d-162c-c7c4-01cd1f424510
secret_id_num_uses 0
secret_id_ttl 0s
# 생성한 Secret ID 저장해둔다.
$ secret_id=d4f40551-e67f-0e06-3e45-a7fcffbf347a
# Secret 생성
$ vault kv put kvv2/webapp/config username="wepapp-user" password="wepapp-password"
# 세팅 완료
$ exit
Kubernetes
서버 세팅# 쿠버네티스 입장에서 Vault를 바라볼 수 있는 경로를 변수에 추가한다.
# 나의 경우 호스트서버에 쿠버네티스와 Vault 서버가 설치되어있어서 아래와 같이 지정하였다.
$ VAULT_HOST="http://$(hostname -I | awk '{print $1}'):8200"
$ echo $VAULT_HOST
>
http://192.168.0.213:8200
# helm repo 추가
$ helm repo add hashicorp https://helm.releases.hashicorp.com
$ helm repo update
# value.yaml 작성
$ cat > custom-value.yaml << EOF
defaultVaultConnection:
enabled: true
skipTLSVerify: true
address: "http://$(hostname -I | awk '{print $1}'):8200"
EOF
# vault-secrets-operator 설치
$ helm upgrade --install vault-secrets-operator hashicorp/vault-secrets-operator \
--set-string "defaultVaultConnection.address=$VAULT_HOST" \
-n vault-secrets-operator-system \
--create-namespace \
--values custom-value.yaml
# 이전에 만들어둔 role_id 와 sercet_id 를 환경변수에 추가한다.
$ role_id=7240f33d-2377-f405-b4e0-6c2fae5e3754
$ secret_id=d4f40551-e67f-0e06-3e45-a7fcffbf347a
# app Namespace 를 생성한다.
$ kubectl create ns app
# Vault 인증 컴포넌트 둘을 생성한다.
$ cat > vault-object.yaml << EOF
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultAuth
metadata:
name: static-auth
namespace: app
spec:
method: appRole
mount: approle-k8s
appRole:
roleId: "$(echo $role_id)"
secretRef: vault-approle-secret
---
apiVersion: v1
kind: Secret
metadata:
name: vault-approle-secret
namespace: app
type: Opaque
stringData:
id: "$(echo $secret_id)"
EOF
# 적용한다.
$ kubectl apply -f vault-object.yaml
# 시크릿 생성용 컴포넌트 파일을 생성한다.
cat > static-secret.yaml <<EOF
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultStaticSecret
metadata:
name: secretkvv2-vso
namespace: app
spec:
type: kv-v2
# mount path of vault
mount: kvv2
# path of the vault secret
path: webapp/config
# dest k8s secret
destination:
name: secretkv
create: true
# static secret refresh interval
refreshAfter: 30s
# Name of the CRD to authenticate to Vault
vaultAuthRef: static-auth
EOF
# static-secret.yaml 을 적용한다.
$ kubectl apply -f static-secret.yaml
# 시크릿이 정상적으로 생성된 것을 확인한다.
$ kubtctl get secret -n app secretkv
NAME TYPE DATA AGE
secretkv Opaque 3 5m41s