롤링 업데이트 구성하기

롤링 업데이트 구성하기 (Configure rolling updates)

Nomad는 롤링 업데이트를 일급 기능으로 지원해요. 롤링 업데이트를 사용하려면 작업 또는 태스크 그룹에 update 스탠자를 사용해 업데이트 전략에 대한 상위 수준 설명을 주석으로 추가해요. 내부적으로 Nomad는 병렬성 제한, 서비스 상태를 판단하기 위한 Consul 연동, 그리고 배포가 실패할 때 이전의 정상 작업으로 자동 롤백하는 것까지 처리해요.

출처: 문서

본문

작업에 롤링 업데이트 활성화하기 (Enable rolling updates for job)

롤링 업데이트는 작업 명세에 update 스탠자를 추가해 활성화해요. update 스탠자는 작업 수준이나 개별 태스크 그룹에 배치할 수 있어요. 작업 수준에 배치하면 해당 업데이트 전략이 작업의 모든 태스크 그룹에 상속돼요. 작업 수준과 그룹 수준 양쪽에 배치하면 update 스탠자가 병합되며, 그룹 스탠자가 작업 수준 스탠자보다 우선해요. 상속에 대한 자세한 내용은 update 스탠자 문서에서 확인할 수 있어요.

job "geo-api-server" {
  # ...

  group "api-server" {
    count = 6

    # Add an update stanza to enable rolling updates of the service
    update {
      max_parallel     = 2
      min_healthy_time = "30s"
      healthy_deadline = "10m"
    }

    task "server" {
      driver = "docker"

      config {
        image = "geo-api-server:0.1"
      }

      # ...
    }
  }
}

이 예제에서 "api-server" 태스크 그룹에 간단한 update 스탠자를 추가함으로써, 그룹에 대한 업데이트가 롤링 업데이트 전략으로 처리되어야 한다는 것을 Nomad에 알려줘요.

따라서 새 할당을 만들어야 하는 작업 파일에 변경이 생기면, Nomad는 한 번에 2개의 할당을 배포하고 그룹의 새 버전을 더 배포하기 전에 할당이 30초 동안 정상 상태로 실행될 것을 요구해요.

기본적으로 Nomad는 그룹의 모든 태스크가 실행 중이고 태스크가 등록한 서비스 체크가 통과 중인지 확인해 할당 상태를 판단해요.

계획된 변경 사항 확인하기 (Check the planned changes)

위와 동일한 롤링 업데이트 전략으로 구성된 Docker 컨테이너의 버전을 업데이트하기 위해 파일을 변경한다고 가정해보세요.

@@ -2,6 +2,8 @@ job "geo-api-server" {
   group "api-server" {
     task "server" {
       driver = "docker"

       config {
-        image = "geo-api-server:0.1"
+        image = "geo-api-server:0.2"

nomad job plan 명령을 사용하면 스케줄러가 수행할 일련의 단계를 시각화할 수 있어요. 이 출력을 분석해 올바른지 확인할 수 있어요:

$ nomad job plan geo-api-server.nomad.hcl
+/- Job: "geo-api-server"
+/- Task Group: "api-server" (2 create/destroy update, 4 ignore)
  +/- Task: "server" (forces create/destroy update)
    +/- Config {
      +/- image: "geo-api-server:0.1" => "geo-api-server:0.2"
    }

Scheduler dry-run:
- All tasks successfully allocated.

Job Modify Index: 7
To submit the job with version verification run:

nomad job run -check-index 7 geo-api-server.nomad.hcl

When running the job with the check-index flag, the job will only be run if the
job modify index given matches the server-side version. If the index has
changed, another user has modified the job and the plan's results are
potentially invalid.

여기서 Nomad가 먼저 두 개의 할당을 만들고 파괴하며 롤링 업데이트를 시작하고, 그동안 구성된 max_parallel 수에 맞춰 기존 할당 4개를 무시한다는 것을 볼 수 있어요.

배포 검사하기 (Inspect a deployment)

계획을 실행한 후 nomad run을 실행해 업데이트된 작업을 제출할 수 있어요. 실행되면 Nomad는 새 작업의 할당을 한 번에 2개씩 배치하고 이전 작업 2개를 내리며 서비스의 롤링 업데이트를 시작해요.

nomad status를 사용해 롤링 배포의 현재 상태를 검사할 수 있어요:

$ nomad status geo-api-server
ID            = geo-api-server
Name          = geo-api-server
Submit Date   = 07/26/17 18:08:56 UTC
Type          = service
Priority      = 50
Datacenters   = dc1
Status        = running
Periodic      = false
Parameterized = false

Summary
Task Group  Queued  Starting  Running  Failed  Complete  Lost
api-server  0       0         6        0       4         0

Latest Deployment
ID          = c5b34665
Status      = running
Description = Deployment is running

Deployed
Task Group  Desired  Placed  Healthy  Unhealthy
api-server  6        4       2        0

Allocations
ID        Node ID   Task Group  Version  Desired  Status    Created At
14d288e8  f7b1ee08  api-server  1        run      running   07/26/17 18:09:17 UTC
a134f73c  f7b1ee08  api-server  1        run      running   07/26/17 18:09:17 UTC
a2574bb6  f7b1ee08  api-server  1        run      running   07/26/17 18:08:56 UTC
496e7aa2  f7b1ee08  api-server  1        run      running   07/26/17 18:08:56 UTC
9fc96fcc  f7b1ee08  api-server  0        run      running   07/26/17 18:04:30 UTC
2521c47a  f7b1ee08  api-server  0        run      running   07/26/17 18:04:30 UTC
6b794fcb  f7b1ee08  api-server  0        stop     complete  07/26/17 18:04:30 UTC
9bc11bd7  f7b1ee08  api-server  0        stop     complete  07/26/17 18:04:30 UTC
691eea24  f7b1ee08  api-server  0        stop     complete  07/26/17 18:04:30 UTC
af115865  f7b1ee08  api-server  0        stop     complete  07/26/17 18:04:30 UTC

출력은 Nomad가 작업 버전 0에서 1로 롤링 업데이트를 진행하기 위한 배포를 생성했음을 나타내요. 새 작업의 인스턴스 4개를 배치하고 이전 인스턴스 4개를 중지했어요. 배치된 할당 목록을 살펴보면 Nomad가 버전 1의 인스턴스 4개를 배치했지만 그중 2개만 정상으로 간주한다는 점을 확인할 수 있어요. 가장 최근에 배치된 두 할당이 아직 요구되는 30초 동안 정상 상태가 아니기 때문이에요.

배포가 완료될 때까지 기다린 후 명령을 다시 실행해요. 다음과 유사한 출력을 받게 돼요:

$ nomad status geo-api-server
ID            = geo-api-server
Name          = geo-api-server
Submit Date   = 07/26/17 18:08:56 UTC
Type          = service
Priority      = 50
Datacenters   = dc1
Status        = running
Periodic      = false
Parameterized = false

Summary
Task Group  Queued  Starting  Running  Failed  Complete  Lost
cache       0       0         6        0       6         0

Latest Deployment
ID          = c5b34665
Status      = successful
Description = Deployment completed successfully

Deployed
Task Group  Desired  Placed  Healthy  Unhealthy
cache       6        6       6        0

Allocations
ID        Node ID   Task Group  Version  Desired  Status    Created At
d42a1656  f7b1ee08  api-server  1        run      running   07/26/17 18:10:10 UTC
401daaf9  f7b1ee08  api-server  1        run      running   07/26/17 18:10:00 UTC
14d288e8  f7b1ee08  api-server  1        run      running   07/26/17 18:09:17 UTC
a134f73c  f7b1ee08  api-server  1        run      running   07/26/17 18:09:17 UTC
a2574bb6  f7b1ee08  api-server  1        run      running   07/26/17 18:08:56 UTC
496e7aa2  f7b1ee08  api-server  1        run      running   07/26/17 18:08:56 UTC
9fc96fcc  f7b1ee08  api-server  0        stop     complete  07/26/17 18:04:30 UTC
2521c47a  f7b1ee08  api-server  0        stop     complete  07/26/17 18:04:30 UTC
6b794fcb  f7b1ee08  api-server  0        stop     complete  07/26/17 18:04:30 UTC
9bc11bd7  f7b1ee08  api-server  0        stop     complete  07/26/17 18:04:30 UTC
691eea24  f7b1ee08  api-server  0        stop     complete  07/26/17 18:04:30 UTC
af115865  f7b1ee08  api-server  0        stop     complete  07/26/17 18:04:30 UTC

Nomad는 한 번에 두 개의 할당만 변경하고 새로 배치된 할당이 성공적으로 실행되도록 함으로써, 서비스에 다운타임 없이 그룹을 업데이트된 카나리 실행으로 성공적으로 전환했어요. 새로 배치된 할당 중 하나라도 헬스 체크에 실패했다면 Nomad는 배포를 중단하고 새 할당 배치를 멈췄을 거예요. 구성에 따라 Nomad는 배포가 실패하면 이전 작업 정의로 자동 롤백할 수도 있어요.

실패한 배포에서 자동 롤백 사용하기 (Use auto-revert on failed deployments)

새 할당이 비정상인 배포를 수행하는 경우 Nomad는 배포를 실패 처리하고 작업의 새 인스턴스 배치를 중지해요. 선택적으로 배포 실패 시 마지막 안정적인 작업 버전으로 자동 롤백하는 것을 지원해요. Nomad는 제출된 작업의 기록과 해당 작업 버전이 안정적이었는지 여부를 보관해요. 모든 할당이 정상이면 작업이 안정적인 것으로 간주돼요.

이를 활성화하려면 update 스탠자에 auto_revert 매개변수를 추가해요:

update {
  max_parallel     = 2
  min_healthy_time = "30s"
  healthy_deadline = "10m"

  # Enable automatically reverting to the last stable job on a failed
  # deployment.
  auto_revert = true
}

이제 이미지를 "geo-api-server:0.3"으로 업데이트하고 싶지만, 대신 아래와 같이 업데이트하고 작업을 실행한다고 가정해보세요:

@@ -2,6 +2,8 @@ job "geo-api-server" {
   group "api-server" {
     task "server" {
       driver = "docker"

       config {
-        image = "geo-api-server:0.2"
+        image = "geo-api-server:0.33"

nomad job deployments를 실행하면 배포가 실패하고 Nomad가 마지막 안정적인 작업으로 자동 롤백했음을 보여줘요:

$ nomad job deployments geo-api-server
ID        Job ID          Job Version  Status      Description
0c6f87a5  geo-api-server  3            successful  Deployment completed successfully
b1712b7f  geo-api-server  2            failed      Failed due to unhealthy allocations - rolling back to job version 1
3eee83ce  geo-api-server  1            successful  Deployment completed successfully
72813fcf  geo-api-server  0            successful  Deployment completed successfully

Nomad 작업 버전은 단조롭게 증가해요. Nomad가 버전 1의 작업 명세로 롤백했더라도 새 작업 버전을 만들어요. job history 명령을 사용해 작업 버전 간의 차이와 Nomad가 작업을 어떻게 자동 롤백했는지 확인할 수 있어요:

$ nomad job history -p geo-api-server
Version     = 3
Stable      = true
Submit Date = 07/26/17 18:44:18 UTC
Diff        =
+/- Job: "geo-api-server"
+/- Task Group: "api-server"
  +/- Task: "server"
    +/- Config {
      +/- image: "geo-api-server:0.33" => "geo-api-server:0.2"
        }

Version     = 2
Stable      = false
Submit Date = 07/26/17 18:45:21 UTC
Diff        =
+/- Job: "geo-api-server"
+/- Task Group: "api-server"
  +/- Task: "server"
    +/- Config {
      +/- image: "geo-api-server:0.2" => "geo-api-server:0.33"
        }

Version     = 1
Stable      = true
Submit Date = 07/26/17 18:44:18 UTC
Diff        =
+/- Job: "geo-api-server"
+/- Task Group: "api-server"
  +/- Task: "server"
    +/- Config {
      +/- image: "geo-api-server:0.1" => "geo-api-server:0.2"
        }

Version     = 0
Stable      = true
Submit Date = 07/26/17 18:43:43 UTC

이 출력은 롤백된 배포의 과정을 설명해요. 출력의 끝에서 시작해 거꾸로 살펴보면, Nomad가 버전 0이 제출되었음을 보여줘요. 다음으로 버전 1은 geo-api-server를 0.1에서 0.2로 변경하는 이미지 변경이었고 안정적으로 표시되었어요. 버전 2는 작업이 geo-api-server를 0.2에서 0.33으로 업데이트하려 했지만 배포가 실패해 안정적이 되지 못했어요. 마지막으로 버전 3은 Nomad가 실패한 배포를 자동으로 롤백하고 마지막 정상 버전(geo-api-server 버전 0.2)을 재배포할 때 생성돼요.

더 알아보기 (Learn more)