잡 스펙의 `lifecycle` 블록
잡 스펙의 lifecycle 블록
lifecycle 블록은 태스크 그룹의 수명주기 안에서 태스크를 언제 실행할지 설정해 Nomad의 태스크 의존성을 표현하는 데 사용해요.
출처: 문서
본문
| 배치 | job -> group -> task -> **lifecycle** |
|---|
메인 태스크는 lifecycle 블록이 없는 태스크예요. 라이프사이클 태스크 훅은 메인 태스크와의 관계에서 다른 태스크를 언제 실행할지 지정해요. 태스크가 언제 시작되는지 나타내는 라이프사이클 훅은 세 가지가 있어요:
- prestart 태스크는 즉시 시작돼요.
- poststart 태스크는 메인 태스크가 실행된 후 시작돼요.
- poststop 태스크는 메인 태스크가 종료된 후 시작돼요.
태스크는 메인 태스크의 지속 시간 동안 실행될 것으로 예상되는 일시적(ephemeral) 태스크인지 "사이드카" 태스크인지를 나타내는 추가 매개변수로 실행될 수 있어요. sidecar 플래그가 없으면 태스크가 일시적이며 성공적으로 완료되면 재시작되지 않아야 함을 나타내요.
lifecycle 블록은 Nomad가 할당에서 태스크를 중지하는 순서도 제어해요. Nomad는 먼저 그룹의 shutdown_delay를 기다려요. 그런 다음 있으면 leader 태스크를 중지해요. 그다음 Nomad는 non-sidecar·non-poststop 태스크를 중지하고, 마지막으로 sidecar 태스크를 중지해요.
Nomad의 태스크 의존성에 대해 더 알아보세요.
매개변수 (Parameters)
-
hook(string: <required>)- 그룹의 수명주기 안에서 태스크를 언제 실행해야 하는지 지정. 다음 훅을 사용할 수 있어요: -
sidecar(bool: false)- 태스크가 태스크 그룹 안에서 일시적인지 장수인지 제어. 라이프사이클 태스크가 일시적(sidecar = false)이면 성공적으로 완료된 후 재시작되지 않아요. 라이프사이클 태스크가 장수(sidecar = true)이고 종료되면 할당이 실행 중인 한 재시작돼요.
예시 (Examples)
다음은 전형적인 라이프사이클 패턴의 예시를 포함해요.
Init 태스크 패턴 (Init task pattern)
Init 태스크는 template이나 artifact로는 쉽게 수행할 수 없는 초기화 단계를 수행하는 데 유용해요. 예: 다른 서비스를 기다리거나 복잡한 초기화를 수행하는 경우.
다음 예시에서 init 태스크는 업스트림 데이터베이스 서비스가 예상 포트에서 리슨할 때까지 메인 태스크가 시작되는 것을 막아요:
task "wait-for-db" {
lifecycle {
hook = "prestart"
sidecar = false
}
driver = "exec"
config {
command = "sh"
args = ["-c", "while ! nc -z db.service.local.consul 8080; do sleep 1; done"]
}
}
task "main-app" {
...
}
컴패니언 사이드카 패턴 (Companion sidecar pattern)
컴패니언 또는 사이드카 태스크는 보조 작업을 수행하기 위해 메인 태스크와 함께 실행돼요. 흔한 예는 프록시와 로그 전송기(log shipper)예요. 이 태스크들은 더 밀접한 파일시스템·네트워킹 결합 때문에 같은 태스크 그룹에서 실행되는 이점이 있어요.
task "fluentd" {
lifecycle {
hook = "poststart"
sidecar = true
}
driver = "docker"
config {
image = "fluentd/fluentd"
}
template {
destination = "local/fluentd.conf"
data = ...
}
}
task "main-app" {
...
}
정리 태스크 패턴 (Cleanup task pattern)
Poststop 태스크는 메인 태스크가 중지된 후 실행돼요. 메인 태스크에서 사용할 수 없는 후처리를 수행하거나 메인 태스크의 실패에서 복구하는 데 유용해요.
아래 예시는 메인 태스크가 중지되었을 때 알림을 게시하는 챗봇을 보여줘요:
task "main-app" {
...
}
task "announce" {
lifecycle {
hook = "poststop"
}
driver = "docker"
config {
image = "alpine/httpie"
command = "http"
args = [
"POST",
"https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX",
"text='All done!'"
]
}
}