잡 스펙의 `vault` 블록

잡 스펙의 vault 블록

vault 블록은 태스크가 HashiCorp Vault 서버에서 토큰을 요구한다고 명시할 수 있게 해요. Nomad는 태스크를 위한 Vault 토큰을 자동으로 가져오고 태스크의 토큰 갱신을 처리해요. group 레벨에서 지정하면 그 구성이 그룹 안의 모든 태스크에 적용돼요. job 레벨에서 지정하면 그 구성이 잡 안의 모든 태스크에 적용돼요. 여러 vault 블록이 지정되면 task 블록이 가장 높은 우선순위를 차지하고 그다음 group, 그다음 job으로 병합돼요.

출처: 문서

본문

배치 job -> **vault**
job -> group -> **vault**
job -> group -> task -> **vault**
job "docs" {
  group "example" {
    task "server" {
      vault {
        cluster  = "default"
        role     = "prod"

        change_mode   = "signal"
        change_signal = "SIGUSR1"
      }
    }
  }
}

Nomad 클라이언트는 시크릿 디렉터리의 secrets/vault_token에 Vault 토큰을 쓰고 VAULT_TOKEN 환경 변수를 주입하여 태스크에 사용할 수 있게 해요. Nomad 클러스터가 Vault Namespaces를 사용하도록 구성되어 있으면, VAULT_TOKEN이 설정될 때마다 VAULT_NAMESPACE 환경 변수가 주입돼요. 이 동작은 env와 disable_file 매개변수로 변경할 수 있어요.

Nomad가 Vault 토큰을 갱신할 수 없으면(아마 Vault 중단 또는 네트워크 오류로), 클라이언트는 새 Vault 토큰을 가져오려고 시도해요. 성공하면 시크릿 파일의 내용이 디스크에서 업데이트되고 change_mode 매개변수에 설정된 값에 따라 조치가 취해져요.

vault 블록이 지정되면 template 블록도 Vault와 상호작용할 수 있어요.

매개변수 (Parameters)

  • allow_token_expiration (bool: false) - Nomad 클라이언트가 태스크의 Vault 토큰 갱신을 시도하지 않고 만료되도록 두는 것을 지정. 이것은 시크릿이 태스크 시작 시 한 번 요청되거나 수명이 짧은 prestart 태스크에서 요청되는 경우에만 사용해야 해요. 장수 태스크가 template 블록을 통해 Vault 시크릿을 얻는다면 절대 allow_token_expiration=true를 설정해서는 안 돼요. Vault 토큰이 만료되고 템플릿 러너가 vault_retry 시도를 소진할 때까지 Vault에 실패하는 요청을 계속 보낸 다음 태스크가 실패하기 때문이에요.

Nomad가 Vault와 함께 Workload Identity를 사용하도록 구성되면, Nomad 클라이언트는 토큰을 갱신할 수 없을 때(예: Vault auth 메서드가 배치 토큰을 발급하도록 구성된 경우) 자동으로 감지해요. 이 경우 allow_token_expiration 옵션은 클라이언트에 의해 암시적으로 true로 설정돼요. 레거시 Vault 인증 워크플로우는 이를 자동으로 감지할 수 없어요.

  • change_mode (string: "restart") - Vault 토큰이 변경될 때 Nomad가 취해야 할 동작. 가능한 값:

    • "noop" - 아무 조치도 취하지 않음(태스크를 계속 실행).
    • "restart" - 태스크를 재시작.
    • "signal" - 태스크에 설정 가능한 신호를 보냄.
  • change_signal (string: "") - "SIGUSR1" 또는 "SIGINT" 같은 문자열로 태스크에 보낼 신호. change_mode가 signal이면 이 옵션은 필수예요.

  • cluster (string: "default")

Enterprise

- 사용할 Vault 클러스터를 지정. Nomad 클라이언트는 에이전트 구성에서 같은 vault.name으로 구성된 클러스터에서 Vault 토큰을 가져와요. Nomad Community Edition에서는 이 필드가 무시돼요.

  • env (bool: true) - 태스크 시작 시 VAULT_TOKEN과 VAULT_NAMESPACE 환경 변수를 설정해야 하는지 여부.

  • disable_file (bool: false) - Vault 토큰을 secrets/vault_token에 쓸지 여부.

경고

secrets 경로는 image 파일시스템 격리를 사용하는 태스크와 공유되지 않지만, chroot 또는 none 격리를 사용하는 태스크는 여전히 접근할 수 있어요.

Enterprise

- 태스크에 사용할 Vault Namespace를 지정. Nomad 클라이언트는 이 특정 네임스페이스로 범위가 지정된 Vault 토큰을 가져와요.

  • role (string: "") - JWT와 워크로드 아이덴티티를 사용해 Vault에서 토큰을 가져올 때 사용하는 Vault 역할. 지정하지 않으면 클라이언트의 create_from_role 값이 사용돼요.

예시 (Examples)

다음 예시는 vault 블록만 보여줘요. vault 블록은 위에 나열된 배치에서만 유효하다는 점을 기억하세요.

토큰 가져오기 (Retrieve token)

이 예시는 Nomad 클라이언트에 Vault 토큰을 가져오라고 지시해요. 토큰은 표준 환경 변수 VAULT_TOKEN을 통해 태스크에 사용할 수 있고 secrets/vault_token에 디스크로 쓰여져요. 결과 토큰은 "prod" 역할의 Vault 정책을 갖게 돼요.

vault {
  role = "prod"
}

태스크에 신호 보내기 (Signal task)

이 예시는 태스크를 재시작하는 대신 신호를 보내는 것을 보여줘요.

vault {
  role = "prod"

  change_mode   = "signal"
  change_signal = "SIGINT"
}

비공개 토큰과 변경 모드 (Private token and change modes)

이 예시는 Docker처럼 image 격리를 제공하는 드라이버를 사용할 때 태스크와 공유되지 않는 Vault 토큰을 가져와요.

이렇게 하면 Nomad가 태스크의 template 스탠자와 상호작용해 데이터베이스 시크릿, 다른 Vault 토큰 등 모든 종류의 시크릿을 발급하는 강력한 Vault 토큰을 사용하면서, 그 발급 권한을 태스크 자체와 공유하지 않을 수 있어요:

vault {
  role         = "prod"
  change_mode  = "noop"
  env          = false
  disable_file = true
}

template {
  data = <<-EOH
{{with secret "auth/token/create/nomad-job" "policies=examplepolicy"}}{{.Auth.ClientToken}}{{ end }}
EOH

  destination = "${NOMAD_SECRETS_DIR}/examplepolicy.token"
  change_mode = "noop"
  perms       = "600"
}

template {
  data = <<-EOH
{{ with secret "pki_int/issue/nomad-task"
   "common_name=example.service.consul" "ttl=72h"
   "alt_names=localhost" "ip_sans=127.0.0.1"}}
{{ .Data.certificate }}
{{ .Data.private_key }}
{{ end }}
EOH

  destination = "${NOMAD_SECRETS_DIR}/client.crt"
  change_mode = "restart"
  perms       = "600"
}

위 예시는 examplepolicy.token의 template 스탠자에서 change_mode = "noop"를 사용해요. 이는 태스크의 워크로드가 해당 파일의 변경을 감지하고 처리할 책임이 있음을 의미해요. 반면 client.crt의 template 스탠자는 인증서가 재발급될 때마다 Nomad가 태스크를 재시작하도록 구성돼 있어요. change_mode = "restart"(change_mode의 기본값)로 표시돼요.

Vault 네임스페이스 (Vault namespace)

이 예시는 주어진 태스크에 특정 Vault 네임스페이스를 지정하는 것을 보여줘요.

Enterprise

이 기능은 Nomad Enterprise(새 탭에서 열림)가 필요해요.

vault {
  role      = "prod"
  namespace = "engineering/frontend"

  change_mode   = "signal"
  change_signal = "SIGINT"
}

더 알아보기 (Learn more)