선호도(친화성)를 사용한 작업 배치
선호도(친화성)를 사용한 작업 배치 (Job placements with affinities)
affinity 스탠자는 운영자가 특정 유형의 노드에 작업을 배치하는 데 대한 선호도를 표현할 수 있게 해줘요. constraint 스탠자와 affinity 스탠자 사이에는 핵심 차이가 있다는 점에 유의하세요. constraint 스탠자는 속성과 클라이언트 메타데이터에 기반해 작업이 실행되는 위치를 엄격하게 필터링해요. 일치하는 노드가 없으면 배치가 성공하지 않아요. affinity 스탠자는 "소프트 제약(soft constraint)"처럼 작동해요. Nomad는 원하는 affinity를 일치시키려 시도하지만, 노드가 원하는 기준과 일치하지 않더라도 배치가 성공해요. 이것은 여기에서 더 자세히 읽을 수 있는 Nomad 스케줄러의 빈 패킹(bin packing) 알고리즘에 기반한 점수화와 함께 수행돼요.
이 가이드에서 샘플 애플리케이션을 만나게 돼요. 애플리케이션은 데이터센터 dc1과 dc2에서 실행될 수 있지만, dc2에서 실행하려는 강한 선호가 있어요. 원하는 리소스가 dc2에 없으면 dc1에서 워크로드를 배치하는 것도 허용하면서, 스케줄러에 선호도를 알리는 작업 구성 방법을 배우게 돼요.
적절한 weight로 affinity를 지정하면 Nomad 스케줄러가 작업을 배치할 최적의 노드를 찾을 수 있어요. affinity 가중치는 빈 패킹 알고리즘 같은 다른 요소와 함께 배치를 위해 노드를 점수화할 때 포함돼요.
출처: 문서
본문
전제 조건 (Prerequisites)
이 가이드에 설명된 작업을 수행하려면 Consul이 설치된 Nomad 환경이 필요해요. 이 저장소를 사용해 샌드박스 환경을 프로비저닝할 수 있어요. 이 가이드는 서버 노드 1개와 클라이언트 노드 3개가 있는 클러스터를 가정해요.
Tip: 이 가이드는 데모 목적이며 단일 서버 노드만 사용해요. 프로덕션 클러스터에서는 서버 노드 3개 또는 5개를 권장해요.
클라이언트 노드 중 하나를 다른 데이터센터에 배치하기 (Place one of the client nodes in a different datacenter)
노드가 위치한 데이터센터에 기반해 작업 배치 선호도를 표현할 거예요. 클라이언트 노드 중 하나를 선택하고 /etc/nomad.d/nomad.hcl을 편집해 그 위치를 dc2로 변경해요. 필요한 변경이 포함된 예제 구성 파일의 스니펫은 아래와 같아요.
data_dir = "/opt/nomad/data"
bind_addr = "0.0.0.0"
datacenter = "dc2"
# Enable the client
client {
enabled = true
# ...
}
선택한 클라이언트 노드에서 변경 후 Nomad 서비스를 재시작해요.
$ sudo systemctl restart nomad
모든 것이 올바르게 작동했다면 nomad node status 명령을 실행할 때 노드 중 하나가 이제 데이터센터 dc2를 표시할 거예요.
$ nomad node status
ID DC Name Class Drain Eligibility Status
3592943e dc1 ip-172-31-27-159 <none> false eligible ready
3dea0188 dc1 ip-172-31-16-175 <none> false eligible ready
6b6e9518 dc2 ip-172-31-27-25 <none> false eligible ready
affinity가 있는 작업 만들기 (Create a job with an affinity)
redis.nomad.hcl이라는 이름의 파일을 만들고 다음 내용을 넣어요:
job "redis" {
datacenters = ["dc1", "dc2"]
type = "service"
affinity {
attribute = "${node.datacenter}"
value = "dc2"
weight = 100
}
group "cache1" {
count = 4
network {
port "db" {
to = 6379
}
}
service {
name = "redis-cache"
port = "db"
check {
name = "alive"
type = "tcp"
interval = "10s"
timeout = "2s"
}
}
task "redis" {
driver = "docker"
config {
image = "redis:latest"
ports = ["db"]
}
}
}
}
작업이 affinity 스탠자를 사용하고 ${node.datacenter} 속성의 값으로 dc2를 지정한다는 점을 관찰하세요. 또한 weight에 100 값을 사용하는데, 이는 Nomad 스케줄러가 데이터센터 dc2의 노드를 더 높은 점수로 순위를 매기도록 해요. 가중치는 -100에서 100까지(경계 포함) 범위일 수 있다는 점을 명심하세요. 음수 가중치는 반-친화성(anti-affinity) 역할을 하여 Nomad가 기준과 일치하는 노드에 할당을 배치하지 않게 해요.
redis Nomad 작업 등록하기 (Register the redis Nomad job)
다음 명령으로 Nomad 작업을 실행해요:
$ nomad run redis.nomad.hcl
==> Monitoring evaluation "11388ef2"
Evaluation triggered by job "redis"
Allocation "0dfcf0ba" created: node "6b6e9518", group "cache1"
Allocation "89a9aae9" created: node "3592943e", group "cache1"
Allocation "9a00f742" created: node "6b6e9518", group "cache1"
Allocation "fc0f21bc" created: node "3dea0188", group "cache1"
Evaluation status changed: "pending" -> "complete"
==> Evaluation "11388ef2" finished with status "complete"
이 예제의 할당 중 두 개가 노드 6b6e9518에 배치된 것을 주목하세요. 이것은 데이터센터 dc2에 있도록 구성된 노드예요. Nomad 스케줄러는 지정된 affinity 때문에 이 노드를 선택했어요. 모든 할당이 이 노드에 배치되지 않은 이유는 Nomad 스케줄러가 빈 패킹 같은 다른 요소를 점수화에서 고려하기 때문이에요. 이는 같은 작업의 인스턴스를 노드에 너무 많이 배치하지 않도록 돕고 노드 수준 장애 중 용량 감소를 방지해요. 다음 몇 단계에서 점수화를 자세히 살펴볼 거예요.
작업 상태 확인하기 (Check the status of the job)
이 시점에서 작업 상태를 확인하고 할당이 어디에 배치되었는지 검증해요. 다음 명령을 실행해요:
$ nomad status redis
출력의 Summary 섹션에 작업 인스턴스 4개가 실행 중이어야 해요:
...
Summary
Task Group Queued Starting Running Failed Complete Lost
cache1 0 0 4 0 0 0
Allocations
ID Node ID Task Group Version Desired Status Created Modified
0dfcf0ba 6b6e9518 cache1 0 run running 1h44m ago 1h44m ago
89a9aae9 3592943e cache1 0 run running 1h44m ago 1h44m ago
9a00f742 6b6e9518 cache1 0 run running 1h44m ago 1h44m ago
fc0f21bc 3dea0188 cache1 0 run running 1h44m ago 1h44m ago
이 출력을 nomad node status 명령의 결과와 교차 확인해 워크로드의 대부분이 dc2의 노드에 배치되었는지 검증할 수 있어요. 위 출력의 경우 해당 노드는 6b6e9518이에요.
작업 배치에 대한 상세 점수화 정보 얻기 (Obtain detailed scoring information on job placement)
Nomad 스케줄러는 리소스가 사용 가능하더라도 affinity 스탠자에 지정한 노드에 항상 모든 워크로드를 배치하지는 않아요. affinity 점수화가 스케줄링 결정을 내리기 전에 다른 메트릭과도 결합되기 때문이에요. 이 단계에서 그러한 다른 요소 중 일부를 살펴볼 거예요.
이전 단계의 출력을 사용해 dc2의 노드에 배치된 할당을 찾고, nomad alloc status 명령을 -verbose 옵션과 함께 사용해 상세 점수화 정보를 얻어요. 이 예제에서 검사할 할당 ID는 0dfcf0ba예요(할당 ID는 다를 거예요).
$ nomad alloc status -verbose 0dfcf0ba
결과 출력은 맨 아래에 Placement Metrics 섹션을 보여줘요.
...
Placement Metrics
Node binpack job-anti-affinity node-reschedule-penalty node-affinity final score
6b6e9518-d2a4-82c8-af3b-6805c8cdc29c 0.33 0 0 1 0.665
3dea0188-ae06-ad98-64dd-a761ab2b1bf3 0.33 0 0 0 0.33
3592943e-67e4-461f-d888-d5842372a4d4 0.33 0 0 0 0.33
binpack, job-anti-affinity, node-reschedule-penalty, node-affinity 열의 결과가 결합되어 각 노드에 대한 final score 열의 숫자가 나온다는 점에 주목하세요. Nomad 스케줄러는 각 노드의 최종 점수를 사용해 배치 위치를 결정해요.
다음 단계 (Next steps)
affinity 스탠자에서 제공된 가중치(-100에서 100까지의 값)를 실험하고 각 노드에 주어진 최종 점수가 어떻게 변하는지 관찰해요(이전 단계에서와 같이 nomad alloc status 명령 사용).