잡 스펙의 task 블록

잡 스펙의 task 블록

task 블록은 Docker 컨테이너, 웹 애플리케이션, 배치 처리처럼 개별 작업 단위를 만들어요. 잡 스펙에서 실제로 "무엇을 실행할지"를 정의하는 가장 중요한 조각이에요. 이 블록이 어떤 파라미터를 갖고, 어떻게 쓰이는지 살펴볼게요.

출처: Hashicorp 공식 문서 - task block in the job specification

본문

task 블록은 Docker 컨테이너, 웹 애플리케이션, 배치 처리 같은 개별 작업 단위를 만들어요.

task 블록은 job·group·task 배치(placement)에서만 유효해요. 기본 골격은 이렇게 생겼어요:

job "docs" {
  group "example" {
    task "server" {
      # ...
    }
  }
}

파라미터

  • artifact (Artifact: nil) - 태스크 실행 전에 다운로드할 아티팩트를 정의해요. 여러 아티팩트를 다운로드하려면 여러 번 지정할 수 있어요.

  • config (map<string|string>: nil) - 드라이버 구성(configuration)을 지정해요. 태스크를 시작하기 위해 드라이버에 직접 전달되죠. 구성의 세부 사항은 드라이버마다 다르므로, 자세한 내용은 각 드라이버 문서를 참고해요.

  • consul (Consul: nil) - 태스크에 특화된 Consul 구성 옵션을 지정해요.

  • constraint (Constraint: nil) - 태스크에 사용자 정의 제약 조건을 지정해요. 추가 제약 조건을 정의하려면 여러 번 지정할 수 있어요.

  • affinity (Affinity: nil) - 선호하는 배치 기준(placement criteria)을 정의하려면 여러 번 지정할 수 있어요.

  • dispatch_payload (DispatchPayload: nil) - 태스크가 디스패치 페이로드에 접근할 수 있도록 구성해요.

  • driver - 태스크를 실행하는 데 사용할 태스크 드라이버를 지정해요. 어떤 드라이버가 있는지는 드라이버 문서를 참고해요. 예로 docker, qemu, java, exec가 있어요.

  • env (Env: nil) - 실행 중인 프로세스에 전달될 환경 변수를 지정해요.

  • identity (Identity: nil) - Workload Identity를 태스크에 노출해요.

  • kill_timeout (string: "5s") - 강제 종료 전에 애플리케이션이 정상 종료(gracefully quit)될 때까지 기다릴 시간을 지정해요. Nomad는 먼저 kill_signal을 보내요. 구성된 타임아웃 전에 태스크가 종료되지 않으면 SIGKILL이 태스크에 보내져요. 여기 설정된 값은 태스크를 실행하는 에이전트의 max_kill_timeout 값으로 제한되는데, 기본값은 30초예요.

  • kill_signal (string) - 태스크에 대한 구성 가능한 종료 신호를 지정해요. 기본값은 SIGINT예요(단, docker는 SIGTERM, Windows의 raw_exec는 CTRL_BREAK_EVENT). 신호를 보내는 드라이버(현재 docker, exec, raw_exec, java)에서만 지원돼요.

  • leader (bool: false) - 태스크가 태스크 그룹의 리더 태스크인지 지정해요. true로 설정하면 리더 태스크가 완료될 때 태스크 그룹의 다른 모든 태스크가 정상 종료(gracefully shutdown)돼요. 종료 과정은 shutdown_delay가 설정돼 있으면 먼저 적용하고, 그다음 리더 태스크를 먼저 중지하고, 이어서 비사이드카·비포스트스톱 태스크, 마지막으로 사이드카 태스크를 중지해요. 이 과정이 끝나면 포스트스톱 태스크가 트리거돼요. 태스크 라이프사이클 관리의 전체 설명은 lifecycle 문서를 참고해요.

  • lifecycle (Lifecycle: nil) - 태스크 그룹의 라이프사이클 내에서 태스크가 언제 실행될지 지정해요. Nomad v0.11에서 추가됐어요.

  • logs (Logs: nil) - 태스크의 stdoutstderr에 대한 로깅 구성을 지정해요.

  • meta (Meta: nil) - 사용자 정의 메타데이터로 주석을 다는 키-값 맵을 지정해요.

  • resources (Resources: <required>) - RAM, CPU, 디바이스 같은 최소 리소스 요구 사항을 지정해요.

  • service (Service: nil) - 서비스 디스커버리를 위해 Nomad 또는 Consul과의 통합을 지정해요. Nomad가 태스크가 시작되면 자동으로 등록하고, 태스크가 죽으면 등록을 해제해요.

  • shutdown_delay (string: "0s") - 태스크의 서비스 등록을 Consul이나 Nomad에서 제거한 뒤 종료 신호를 보내기까지 기다릴 시간을 지정해요. 이상적으로 서비스는 종료 신호를 받으면 헬스 체크에 실패할 거예요. 또는 진행 중인(in-flight) 요청이 종료 전에 끝날 시간을 주도록 shutdown_delay를 설정할 수도 있어요. 이 shutdown_delay는 태스크 레벨에서 service 블록으로 정의한 서비스에만 적용돼요. 추가로 태스크 그룹에는 자체 shutdown_delay가 있는데, 그룹 서비스 등록을 해제한 뒤 태스크를 중지하기 전에 기다려요.

  • user (string: <varies>) - 태스크를 실행할 사용자를 지정해요. execjava 드라이버에서는 기본적으로 nobody예요. Docker 이미지는 자체 기본 사용자를 지정해요. 클라이언트는 특정 사용자로 태스크를 실행하도록 허용하는 드라이버를 제한할 수 있어요. UNIX 계열 시스템에서 user를 설정하면 태스크에 제공되는 환경 변수 HOME, USER, LOGNAME에도 영향을 줘요. Windows에서 Nomad가 raw_exec 드라이버에 대한 시스템 서비스로 실행 중일 때는 덜 특권을 가진 서비스 사용자를 지정할 수 있어요. 예로 NT AUTHORITY\LocalService, NT AUTHORITY\NetworkService.

  • template (Template: nil) - 태스크에 대해 렌더링할 템플릿 집합을 지정해요. 템플릿은 환경 변수, Consul, Vault에서 채운 데이터로 정적·동적 구성 모두를 주입하는 데 쓸 수 있어요.

  • vault (Vault: nil) - 태스크가 필요한 Vault 정책 집합을 지정해요. group이나 job 레벨에서 설정한 vault 블록을 덮어써요.

  • volume_mount (VolumeMount: nil) - 그룹 볼륨을 어디에 마운트할지 지정해요.

  • kind (string: <varies>) - 이 필드의 값에 따라 태스크를 관리하기 위해 내부적으로 사용돼요. 초기 사용 사례는 Consul 서비스 메시예요.

예시

아래 예시는 task 블록만 보여줘요. task 블록은 위에서 설명한 배치에서만 유효하다는 점을 기억해 두세요.

Docker 컨테이너

이 예시는 Docker 컨테이너를 서비스로 시작하는 태스크를 정의해요. Docker는 Nomad가 지원하는 많은 드라이버 중 하나일 뿐이에요. 드라이버에 대한 자세한 내용은 Nomad 드라이버 문서를 참고해요.

task "server" {
  driver = "docker"
  config {
    image = "hashicorp/http-echo"
    args  = ["-text", "hello world"]
  }

  resources {
    cpu = 20
  }
}

메타데이터와 환경 변수

이 예시는 사용자 정의 메타데이터와 환경 변수를 사용해 태스크에 정보를 전달해요.

task "server" {
  driver = "exec"
  config {
    command = "/bin/env"
  }

  meta {
    my-key = "my-value"
  }

  env {
    MY_KEY = "${meta.my-key}"
  }

  resources {
    cpu = 20
  }
}

서비스 디스커버리

이 예시는 Consul에 서비스를 만듭니다. Nomad의 서비스 디스커버리에 대한 자세한 내용은 Nomad service discovery 문서를 참고해요.

task "server" {
  driver = "docker"
  config {
    image = "hashicorp/http-echo"
    args  = ["-text", "hello world"]
  }

  service {
    tags = ["default"]

    check {
      type     = "tcp"
      interval = "10s"
      timeout  = "2s"
    }
  }

  resources {
    cpu = 20
  }
}

더 알아보기