Vault Agent Injector

Vault Agent Injector

Vault Agent 주입기(Injection)가 파드에 Vault 시크릿을 주입하는 방식과 주요 개념을 다룹니다.

출처: 문서

본문

Vault Agent Injector는 Vault Agent 템플릿을 사용해 Vault 시크릿을 공유 메모리 볼륨에 렌더링하는 Vault Agent 컨테이너를 파드 명세에 추가하도록 파드 스펙을 변경해요. 시크릿을 공유 볼륨에 렌더링함으로써 파드 안의 컨테이너들은 Vault를 알지 못해도 Vault 시크릿을 사용할 수 있어요.

injector는 쿠버네티스 Mutation Webhook Controller예요. 컨트롤러는 파드 이벤트를 가로채, 요청 안에 어노테이션이 있으면 파드에 변경(mutation)을 적용합니다. 이 기능은 vault-k8s 프로젝트가 제공하며, Vault Helm 차트로 자동 설치·구성할 수 있어요.

지원되는 쿠버네티스 버전

IBM이 다음 쿠버네티스 마이너 릴리스에 대해 Vault를 테스트하고 검증합니다. IBM은 다른 쿠버네티스 버전과의 Vault는 지원하지 않지만, 동작할 수는 있어요.

  • 1.36
  • 1.35
  • 1.34
  • 1.33
  • 1.32

개요 (Overview)

Vault Agent Injector는 쿠버네티스의 파드 CREATE·UPDATE 이벤트를 가로채 동작해요. 컨트롤러는 이벤트를 파싱해 vault.hashicorp.com/agent-inject: true 메타데이터 어노테이션을 찾습니다. 찾으면 컨트롤러는 다른 어노테이션을 바탕으로 파드 스펙을 변경해요.

변경 (Mutations)

최소한, 파드의 모든 컨테이너는 공유 메모리 볼륨을 마운트하도록 구성됩니다. 이 볼륨은 /vault/secrets에 마운트되며, Vault Agent 컨테이너가 파드의 다른 컨테이너와 시크릿을 공유하는 데 사용돼요.

다음으로 두 종류의 Vault Agent 컨테이너를 주입할 수 있어요: initsidecar. init 컨테이너는 다른 컨테이너가 시작되기 전에 공유 메모리 볼륨을 요청한 시크릿으로 미리 채웁니다. sidecar 컨테이너는 파드가 실행되는 동안 같은 위치에 계속 인증하고 시크릿을 렌더링해요. 어노테이션으로 초기화·사이드카 컨테이너를 비활성화할 수 있어요.

마지막으로, Vault Agent 컨테이너에 선택적으로 마운트할 수 있는 볼륨이 두 종류 더 있어요. 하나는 클라이언트·CA(인증 기관) 인증서와 키 같은 TLS 요구사항을 담은 시크릿 볼륨이에요. 이 볼륨은 TLS로 Vault 서버의 진위를 통신·검증할 때 유용합니다. 다른 하나는 Vault Agent 구성 파일을 담은 설정 맵(configuration map) 입니다. 이 볼륨은 제공된 어노테이션 이상으로 Vault Agent를 커스터마이즈할 때 유용해요.

Vault 인증 (Authenticating with Vault)

Vault Agent Injector를 사용할 때 Vault에 인증하는 기본 방법은 파드에 연결된 서비스 어카운트입니다. 다른 인증 방법은 어노테이션으로 구성할 수 있어요.

쿠버네티스 인증을 쓰려면 서비스 어카운트가 Vault 역할에 바인딩되어야 하고, 원하는 시크릿에 대한 접근 권한을 부여하는 정책도 필요해요.

쿠버네티스 인증 방식으로 Vault Agent Injector를 사용하려면 서비스 어카운트가 있어야 해요. 서비스 어카운트가 정의되지 않았다면 파드에 제공되는 기본 서비스 어카운트에 Vault 역할을 바인딩하는 것은 권장되지 않습니다.

시크릿 요청 (Requesting secrets)

Vault Agent 컨테이너가 시크릿을 렌더링하도록 구성하는 방법은 두 가지예요.

  • vault.hashicorp.com/agent-inject-secret 어노테이션, 또는
  • Vault Agent 구성 파일을 담은 설정 맵.

한 번에 한 가지 방법만 사용할 수 있어요.

어노테이션으로 시크릿 구성

어노테이션으로 시크릿 주입을 구성하려면 사용자가 다음을 제공해야 해요.

  • 하나 이상의 secret 어노테이션, 그리고
  • 그 시크릿에 접근하는 데 사용하는 Vault 역할.

어노테이션은 다음 형식이어야 해요.

vault.hashicorp.com/agent-inject-secret-<UNIQUE_NAME>: /path/to/secret

고유 이름은 렌더링된 시크릿의 파일명이 되며, 사용자가 시크릿을 여러 개 정의하면 유일해야 해요. 예를 들어 다음 시크릿 어노테이션을 보겠습니다.

vault.hashicorp.com/agent-inject-secret-foo: database/roles/app
vault.hashicorp.com/agent-inject-secret-bar: consul/creds/app
vault.hashicorp.com/role: 'app'

첫 번째 어노테이션은 /vault/secrets/foo로 렌더링되고, 두 번째는 /vault/secrets/bar로 렌더링돼요.

어노테이션으로 렌더링된 시크릿의 파일 형식을 정할 수 있어요. 예를 들어 다음 시크릿은 /vault/secrets/foo.txt로 렌더링됩니다.

vault.hashicorp.com/agent-inject-secret-foo.txt: database/roles/app
vault.hashicorp.com/role: 'app'

시크릿의 고유 이름은 영숫자 문자, . , _ 또는 -로만 구성되어야 해요.

시크릿 템플릿

Vault Agent는 시크릿 렌더링에 Consultale Template 프로젝트를 사용해요. 템플릿 작성에 대한 자세한 내용은 Consul Template 문서를 참고하세요.

시크릿이 파일에 렌더링되는 방식도 구성 가능해요. 사용할 템플릿을 구성하려면 시크릿의 고유 이름을 사용하는 template 어노테이션을 제공해야 해요. 어노테이션은 다음 형식이어야 합니다.

vault.hashicorp.com/agent-inject-template-<UNIQUE_NAME>: |
  <
    TEMPLATE
    HERE
  >

예를 들어 다음을 보겠습니다.

vault.hashicorp.com/agent-inject-secret-foo: 'database/creds/db-app'
vault.hashicorp.com/agent-inject-template-foo: |
  {{- with secret "database/creds/db-app" -}}
  postgres://{{ .Data.username }}:{{ .Data.password }}@postgres:5432/mydb?sslmode=disable
  {{- end }}
vault.hashicorp.com/role: 'app'

렌더링된 시크릿은 컨테이너 안에서 이렇게 보일 거예요.

$ cat /vault/secrets/foo
postgres://v-kubernet-pg-app-q0Z7WPfVN:***@postgres:5432/mydb?sslmode=disable

기본 템플릿 구분자(delimiter)는 왼쪽·오른쪽 모두 {{}}입니다.

템플릿이 제공되지 않으면 다음의 일반 템플릿이 사용돼요.

{{ with secret "/path/to/secret" }}
    {{ range $k, $v := .Data }}
        {{ $k }}: {{ $v }}
    {{ end }}
{{ end }}

예를 들어 다음 어노테이션은 구성된 경로의 PostgreSQL 시크릿을 기본 템플릿으로 렌더링할 거예요.

vault.hashicorp.com/agent-inject-secret-foo: 'database/roles/pg-app'
vault.hashicorp.com/role: 'app'

렌더링된 시크릿은 컨테이너 안에서 이렇게 보일 거예요.

$ cat /vault/secrets/foo
password: A1a-BUEuQR52oAqPrP1J
username: v-kubernet-pg-app-q0Z7WPfVNqqTJuoDqCTY-1576529094

KV 같은 일부 시크릿은 맵으로 저장돼요. 그 데이터는 .Data.data.<NAME>으로 접근할 수 있습니다.

시크릿 갱신과 업데이트

Vault Agent가 언제 시크릿을 가져오고 갱신하는지에 대한 자세한 내용은 Agent 문서를 참고하세요.

Vault Agent 설정 맵

고급 사용 사례에서는 secret·template 어노테이션 대신 마운트할 Vault Agent 구성 파일을 정의해야 할 수 있어요. Vault Agent Injector는 vault.hashicorp.com/agent-configmap 어노테이션으로 이름을 지정하면 ConfigMap 마운트를 지원해요. 구성 파일은 /vault/configs에 마운트됩니다.

설정 맵은 다음 파일 중 하나 또는 둘 다를 담아야 해요.

  • init 컨테이너가 사용하는 config-init.hcl. exit_after_auth가 true로 설정되어 있어야 해요.
  • sidecar 컨테이너가 사용하는 config.hcl. exit_after_auth가 false로 설정되어 있어야 해요.

Vault Agent configmap 마운트 예제는 여기에서 볼 수 있어요.

Injector 텔레메트리

팁: Helm 차트에서 injector.metrics.enabled를 true로 설정해 injector 메트릭 수집을 시작하세요.

Vault Agent injector는 기본 golang 메트릭 집합에 더해 다음 Prometheus 메트릭을 수집해요.

튜토리얼

단계별 튜토리얼은 Injecting Secrets into Kubernetes Pods via Vault Helm Sidecar 가이드를 참고하세요.

더 알아보기 (Learn more)