본문 바로가기

OSS

Kubernetes에서 Vault Agent Injector로 구성하기(3)

반응형

Vault Agent Injector 설치

Vault Helm Chart를 이용하여 Agent Injector를 구성합니다.

💡 Hashicorp Vault에서는 Agent Injector를 구성할 때 HELM 차트로 구성하는 것을 권장합니다.

💡 Vault Agent Injector에는 Vault 1.3.1 이상이 필요합니다.

 

HashiCorp Helm 리포지토리를 추가합니다.

helm repo add hashicorp <https://helm.releases.hashicorp.com>

 

helm최신 버전을 인식 하도록 모든 리포지토리를 업데이트합니다.

helm repo update

 

values.yaml 파일은 외부 서버를 HCP Vault로 설정 하는 파일을 만듭니다. 이렇게 하면 Vault 에이전트 인젝터가 EKS 클러스터에 배포됩니다.

앞서 VPC Peering을 통해 내부 통신이 가능하여 Cluster Private URL로 설정합니다.

export VAULT_PRIVATE_ADDR=https://vault-cluster-private-vault-xxxxxxxx.xxxxxxxx.z1.hashicorp.cloud:8200
cat > values.yaml << EOF
injector:
   enabled: true
   externalVaultAddr: "${VAULT_PRIVATE_ADDR}"
EOF

 

위에서 만든 values.yaml 파일을 이용하여 Vault Agent를 설치합니다.

helm install vault -f values.yaml hashicorp/vault

아래 명령어로 설치가 정상적으로 되었는지 확인합니다.

kubectl get pods

결과는 다음과 유사합니다.

NAME                                    READY   STATUS    RESTARTS   AGE
vault-agent-injector-6fbdb9d7d4-mtfv2   1/1     Running   0          158m

 

HCP Vault에서 Kubernetes auth 구성

Secret 정보를 받아오기 위한 인증방식을 설정합니다.

# examples
vault auth enable kubernetes

# auth 이름을 변경하고 싶으면 path로 설정
vault auth enable -path=test kubernetes

<aside> 💡 Kubernetes 1.24+ 에서는 vault에서는 auth secret가 자동으로 생성되지 않기 때문에 추가로 생성해야 합니다.

vault에서 인증에 사용할 token를 생성합니다.

cat > vault-auth-secret.yaml << EOF
apiVersion: v1
kind: Secret
metadata:
  name: vault-auth-secret
  annotations:
    kubernetes.io/service-account.name: vault
type: kubernetes.io/service-account-token
EOF

아래 명령어로 secret를 생성합니다.

kubectl apply -f vault-auth-secret.yaml

아래 명령어를 참고하여 token이 정상적으로 생성되었는지 확인합니다. Tokens 항목에 위에서 생성한 vault-auth-secret.yaml의 name 정보로 설정되어있는지 확인합니다.

kubectl describe sa/vault
$ kubectl describe sa/vault
Name:                vault
Namespace:           default
Labels:              app.kubernetes.io/instance=vault
                     app.kubernetes.io/managed-by=Helm
                     app.kubernetes.io/name=vault
                     helm.sh/chart=vault-0.23.0
Annotations:         meta.helm.sh/release-name: vault
                     meta.helm.sh/release-namespace: default
Image pull secrets:  <none>
Mountable secrets:   <none>
**Tokens:              vault-auth-secret**
Events:              <none>

 

 


참고사이트

Vault Agent with Kubernetes | Vault | HashiCorp Developer

 

Vault Agent with Kubernetes | Vault | HashiCorp Developer

This tutorial demonstrates the Auto-Auth method of Vault Agent using Kubernetes auth method on the server side.

developer.hashicorp.com

 

Kubernetes vault auth를 생성하기 전에 필요한 정보를 변수로 설정합니다.

export VAULT_HELM_SECRET_NAME=$(kubectl get secrets --output=json | jq -r '.items[].metadata | select(.name|startswith("vault-auth-")).name')
export TOKEN_REVIEW_JWT=$(kubectl get secret $VAULT_HELM_SECRET_NAME --output='go-template={{ .data.token }}' | base64 --decode)
export KUBE_CA_CERT=$(kubectl config view --raw --minify --flatten \\
    --output 'jsonpath={.clusters[].cluster.certificate-authority-data}' | base64 --decode)
export KUBE_HOST=$(kubectl config view --raw --minify --flatten \\
   -o jsonpath='{.clusters[].cluster.server}')

# 변수 확인
echo $TOKEN_REVIEW_JWT
echo $KUBE_HOST
echo $KUBE_CA_CERT

 

💡 Secret token과 Kubernetes CA Cert, Host 정보를 얻기 위해서는 Kubernetes API Server를 호출할 수 있는 곳에서 진행해야 합니다.

 

위에서 설정한 변수를 이용하여 Vault에 kubernetes auth를 등록합니다.

vault write auth/kubernetes/config \\
   token_reviewer_jwt="$TOKEN_REVIEW_JWT" \\
   kubernetes_host="$KUBE_HOST" \\
   kubernetes_ca_cert="$KUBE_CA_CERT"

# test example
vault write auth/test/config \\
   token_reviewer_jwt="$TOKEN_REVIEW_JWT" \\
   kubernetes_host="$KUBE_HOST" \\
   kubernetes_ca_cert="$KUBE_CA_CERT"

 

Kubrnetes service account에서 Vault의 토큰 정보를가져올 수 있게 아래 명령어로 진행합니다.

# examples
vault write auth/kubernetes/role/web \\
    bound_service_account_names=web \\
    bound_service_account_namespaces=default \\
    policies=test/web \\
    ttl=1h

# test example
vault write auth/test/role/management \\
    bound_service_account_names=deploy-backend-test \\
    bound_service_account_namespaces=test \\
    policies=test/management \\
    ttl=1h

 

아래 명령어로 설정이 정상적으로 되었는지 확인합니다.

vault read auth/kubernetes/role/web

 

결과는 다음과 유사합니다.

$ vault read auth/kubernetes/role/web
Key                                 Value
---                                 -----
alias_name_source                   serviceaccount_uid
bound_service_account_names         [web]
bound_service_account_namespaces    [default]
policies                            [test/web]
token_bound_cidrs                   []
token_explicit_max_ttl              0s
token_max_ttl                       0s
token_no_default_policy             false
token_num_uses                      0
token_period                        0s
token_policies                      [test/web]
token_ttl                           1h
token_type                          default
ttl                                 1h

 

테스트

HCP Vault에 저장된 secret 정보를 환경 변수로 읽어옵니다.

테스트를 진행할 deployment와 service account를 생성합니다.

 

💡 annotations 설정 설명:
         agent-inject: true로 설정되었을 경우에 inject가 설정됩니다.
         agent-inject-secret-config: secret/test/web 은 secret 정보가 text파일로 저장될 위치입니다.
         agent-inject-template-config: secret정보가 저장될 때 어떤 형태로 저장될지에 대해 정의합니다.
       

⚠️  config는 변경될 수 있는 name이며 agent-inject-secret의 name과 agent-inject-template의 name이 동일해야 template이 동일한 name에 적용할 수 있습니다.

 

cat > web-deployment.yaml << EOF
apiVersion: v1
kind: ServiceAccount
metadata:
  name: web
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-deployment
  labels:
    app: web
spec:
  replicas: 1
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
      annotations:
        vault.hashicorp.com/agent-inject: 'true'
        vault.hashicorp.com/role: 'web'
        vault.hashicorp.com/namespace: 'admin'
        vault.hashicorp.com/agent-inject-secret-config: 'secret/test/web'
        vault.hashicorp.com/agent-inject-template-config: |
          {{- with secret "secret/test/web" -}}
          {{- range $key, $value := .Data.data }}
          export {{ $key }}='{{ $value }}'
          {{- end }}
          {{- end -}}
    spec:
      serviceAccountName: web
      containers:
        - name: web
          image: alpine:latest
          command:
            ['sh', '-c']
          args:
            ['source /vault/secrets/config && echo ${apiKey}, ${service} && while true; do sleep 10; done']
          ports:
            - containerPort: 8080
EOF

 

아래 명령어로 테스트 pod를 생성합니다.

kubectl apply -f web-deployment.yaml

아래 명령어로 설정이 정상적으로 되었는지 확인합니다.

앞서 설정했던 secrets의 정보가 정상적으로 출력되어야 합니다.

$ kubectl logs -f web-deployment-65f85866f8-k6g4t
Defaulted container "web" out of: web, vault-agent, vault-agent-init (init)
ABC0DEFG9876, web

 

Troubleshooting

Vault secrets 삭제가 불가할 경우 아래 명령어를 참고해서 진행할 수 있습니다.

[ec2-user@ip-10-101-1-41 ~]$ vault secrets disable database
Error disabling secrets engine at database/: Error making API request.

Namespace: admin/
URL: DELETE <https://vault-cluster-public-vault-774c023d.c37731b0.z1.hashicorp.cloud:8200/v1/sys/mounts/database>
Code: 400. Errors:

* failed to revoke "database/creds/product/0SR6XhbupbY22X9zzMo3lTjc.4PgFG" (1 / 1): failed to revoke entry: resp: (*logical.Response)(nil) err: failed to connect to `host=a739aed4783eb4195ad33ab4d0694b41-303514340.ap-northeast-2.elb.amazonaws.com user=postgres database=products`: hostname resolving error (lookup a739aed4783eb4195ad33ab4d0694b41-303514340.ap-northeast-2.elb.amazonaws.com on 127.0.0.53:53: no such host)

 

강제로 삭제해서 삭제 진행

vault lease revoke -force=true -prefix database/creds/produc

 

 

APPENDIX

Vault secret 전체 흐름 설명

Vault Secret을 Kubernetes로 가져오는 방법

Vault Agent Injector 구성에 대한 단계별 설명

Vault Agent Injector Tutorial: Setup Init & Sidecar Agents

반응형

'OSS' 카테고리의 다른 글

[Redis] Redis Hash Set이란?  (0) 2024.07.20
[Redis] Redis란?  (0) 2024.07.20
Kubernetes에서 Vault Agent Injector로 구성하기(2)  (0) 2023.09.10
Kubernetes에서 Vault Agent Injector로 구성하기(1)  (0) 2023.09.07
[OSS] Hashicorp Vault 란?  (0) 2023.09.06