노드 풀
노드 풀 (Node Pools)
이 페이지는 Nomad의 노드 풀 기능에 대한 개념 정보를 포함해요.
노드 풀을 사용해 클라이언트를 그룹화하고 인프라를 논리 단위로 분리해서, 작업이 할당 배치를 제어하도록 해요. 멀티 리전 클러스터의 노드 풀 복제, 내장 노드 풀, 노드 풀 패턴, 그리고 스케줄러 구성, 노드 풀 거버넌스, 멀티 리전 작업 같은 엔터프라이즈 기능을 검토해요.
출처: 문서
본문
노드 풀이 없으면 작업의 할당은 클러스터의 모든 적격 클라이언트에 배치될 수 있어요. affinity와 constraint는 특정 노드에 대한 선호도를 표현하는 데 도움이 될 수 있지만, 다른 작업이 특정 노드 집합에 할당을 배치하는 것을 쉽게 막지는 못해요.
nomad node pool apply 명령어로 노드 풀 스펙 파일을 전달해 노드 풀을 만들어요.
# dev-pool.nomad.hcl
node_pool "dev" {
description = "Nodes for the development environment."
meta {
environment = "dev"
owner = "sre"
}
}
$ nomad node pool apply dev-pool.nomad.hcl
Successfully applied node pool "dev"!
그런 다음 클라이언트는 구성 파일에서 node_pool 속성을 설정하거나 동등한 -node-pool 커맨드라인 플래그를 사용해 이 노드 풀에 추가할 수 있어요.
client {
# ...
node_pool = "dev"
# ...
}
이 프로세스를 간소화하기 위해 노드는 온디맨드로 노드 풀을 만들 수 있어요. 클라이언트 구성이 아직 존재하지 않는 노드 풀을 참조하면, Nomad는 클라이언트 등록 시 노드 풀을 자동으로 생성해요.
참고 — 이 동작은 비권위 리전(non-authoritative region)의 클라이언트에는 적용되지 않아요. 자세한 내용은 Multi-region Clusters를 참고해요.
그런 다음 작업은 node_pool 속성을 사용해 노드 풀을 참조할 수 있어요.
job "app-dev" {
# ...
node_pool = "dev"
# ...
}
namespace 속성과 유사하게, 노드 풀은 미리 존재해야 하며 그렇지 않으면 작업 등록이 오류로 끝나요. 주어진 노드 풀의 노드만 배치 대상으로 고려돼요. 사용 가능한 노드가 없으면 배포는 클라이언트가 노드 풀에 추가될 때까지 pending으로 유지돼요.
멀티 리전 클러스터 (Multi-region Clusters)
페더레이션된 멀티 리전 클러스터에서 노드 풀은 권위 리전에서 모든 비권위 리전으로 자동으로 복제되며, 새 노드 풀을 생성하거나 수정하는 요청은 비권위 리전에서 권위 리전으로 전달돼요.
복제 데이터는 한 방향으로만 흐르므로, 비권위 리전의 클라이언트는 노드 풀을 온디맨드로 만들 수 없어요.
아직 존재하지 않는 노드 풀을 참조하는 비권위 리전의 클라이언트는 노드 풀이 생성되어 모든 리전에 복제될 때까지 initializing 상태로 유지돼요.
내장 노드 풀 (Built-in Node Pools)
사용자 생성 노드 풀에 더해, Nomad는 삭제하거나 수정할 수 없는 두 개의 내장 노드 풀을 자동으로 만들어요.
- default — 노드 풀은 Nomad의 선택적 기능이에요. 클라이언트 구성과 작업 파일 모두에서 node_pool 속성은 선택적이에요. 지정하지 않으면 이 값들은 기본 내장 노드 풀을 사용하도록 설정돼요.
- all — 어떤 상황에서는 클라이언트의 노드 풀 구성과 관계없이 클러스터의 모든 클라이언트에 걸쳐 작업을 실행하는 것이 유용할 수 있어요. 이러한 시나리오에서는 클러스터에 등록된 모든 클라이언트를 항상 포함하는 내장 all 노드 풀을 작업이 사용할 수 있어요. 다른 노드 풀과 달리 all 노드 풀은 클라이언트 구성이 아닌 작업에서만 사용할 수 있어요.
Nomad Enterprise — Enterprise
Nomad Enterprise는 노드 풀을 더 강력하고 관리하기 쉽게 만드는 추가 기능을 제공해요.
스케줄러 구성 (Scheduler Configuration)
Nomad Enterprise의 노드 풀은 Nomad 스케줄러의 일부 측면을 커스터마이즈하고 노드 풀별로 특정 전역 구성을 덮어쓸 수 있어요.
이를 통해 메모리 오버서브스크립션(oversubscription) 같은 기능을 격리된 상태로 실험하거나, 주어진 클라이언트 집합에 배포되는 워크로드 유형에 따라 스케줄러 알고리즘을 spread와 binpacking 사이에서 조정할 수 있어요.
내장 all 노드 풀을 사용할 때는 전역 스케줄러 구성이 적용돼요.
자세한 내용은 노드 풀 스펙의 scheduler_config 매개변수를 참고해요.
노드 풀 거버넌스 (Node Pool Governance)
노드 풀과 네임스페이스는 몇 가지 유사점을 공유하는데, 둘 다 리소스를 격리된 논리 단위로 그룹화하는 방법을 제공해요. 작업은 네임스페이스로 그룹화되고 클라이언트는 노드 풀로 그룹화돼요.
노드 풀 거버넌스(Node Pool Governance)를 사용하면 네임스페이스에 기본 노드 풀을 할당해, 해당 네임스페이스에 등록된 모든 작업이 자동으로 사용하게 할 수 있어요. 이 기능은 작업마다 지정할 필요 없이 네임스페이스 구성에서 노드 풀을 추론하므로 작업 관리를 간소화해요.
이 연결은 네임스페이스의 node_pool_config 블록에서 default 속성을 사용해 수행돼요.
namespace "dev" {
description = "Jobs for the development environment."
node_pool_config {
default = "dev"
}
}
이제 dev 네임스페이스의 모든 작업은 dev 노드 풀의 노드에만 할당을 배치하므로, 작업 스펙에서 node_pool 속성을 생략할 수 있어요.
job "app-dev" {
# The "dev" node pool will be used because it is the
# namespace's default node pool.
namespace = "dev"
# ...
}
작업은 다른 node_pool 값을 지정해 네임스페이스 기본 노드 풀을 덮어쓸 수 있어요.
네임스페이스는 allowed와 denied 매개변수로 이 동작을 허용할지 적용하거나 어떤 노드 풀을 사용할 수 있고 사용할 수 없는지 제한할 수 있어요.
namespace "dev" {
description = "Jobs for the development environment."
node_pool_config {
default = "dev"
denied = ["prod", "qa"]
}
}
job "app-dev" {
namespace = "dev"
# Jobs in the "dev" namespace are not allowed to use the
# "prod" node pool and so this job will fail to register.
node_pool = "prod"
# ...
}
멀티 리전 작업 (Multi-region Jobs)
멀티 리전 작업은 각 리전 블록에서 최상위 node_pool 작업 값이나 네임스페이스 기본 노드 풀을 덮어써, 각 리전에서 사용할 서로 다른 노드 풀을 지정할 수 있어요.
job "multiregion" {
node_pool = "dev"
multiregion {
# This region will use the top-level "dev" node pool.
region "north" {}
# While the regions bellow will use their own specific node pool.
region "east" {
node_pool = "dev-east"
}
region "west" {
node_pool = "dev-west"
}
}
# ...
}
노드 풀 패턴 (Node Pool Patterns)
아래 섹션들은 특정 목표를 달성하는 데 사용할 수 있는 몇 가지 노드 풀 패턴을 설명해요.
인프라 및 시스템 작업 (Infrastructure and System Jobs)
이 패턴은 노드 풀을 사용해 특정 작업 집합을 위해 노드를 예약하면서도 시스템 작업은 노드 풀 경계를 넘을 수 있게 하는 예시를 보여줘요.
Nomad 클러스터에는 비즈니스 중심 애플리케이션의 기본 인프라를 제공하는 데 초점을 맞춘 특정 작업이 있는 것이 일반적이에요. 몇 가지 예로는 트래픽 인그레스를 위한 리버스 프록시, CSI 플러그인, 주기적 유지보수 작업이 있어요.
이러한 작업은 자체 네임스페이스에 격리할 수 있지만 스케줄링 요구 사항이 다를 수 있어요.
리버스 프록시(그리고 리버스 프록시만)는 공용 트래픽에 노출되는 클라이언트에서 실행해야 할 수 있고, CSI 컨트롤러 플러그인은 클라우드 리소스와 API에 대한 높은 권한 접근이 있는 클라이언트를 요구할 수 있어요.
CSI 노드 플러그인과 주기적 유지보수 작업 같은 다른 작업은 클러스터의 모든 클라이언트에서 시스템 작업으로 실행해야 할 수 있어요.
노드 풀을 사용해 첫 번째 작업 집합에 필요한 격리를 달성할 수 있고, 내장 all 노드 풀을 사용해 모든 클라이언트에서 실행해야 하는 작업을 처리할 수 있어요. 체계적으로 유지하기 위해 모든 작업은 같은 infra 네임스페이스에 등록돼요.
job "ingress-proxy" {
namespace = "infra"
node_pool = "ingress"
# ...
}
job "csi-controller" {
namespace = "infra"
node_pool = "csi-controllers"
# ...
}
job "csi-nodes" {
namespace = "infra"
node_pool = "all"
# ...
}
job "maintenance" {
type = "batch"
namespace = "infra"
node_pool = "all"
periodic { /* ... */ }
# ...
}
내장 all 노드 풀을 대상으로 할 때 긍정적·부정적 제약 조건을 사용해 배치를 미세 조정해요.
job "maintenance-linux" {
type = "batch"
namespace = "infra"
node_pool = "all"
constraint {
attribute = "${attr.kernel.name}"
value = "linux"
}
constraint {
attribute = "${node.pool}"
operator = "!="
value = "ingress"
}
periodic { /* ... */ }
# ...
}
Nomad Enterprise와 노드 풀 거버넌스를 사용하면 infra 네임스페이스를 기본적으로 특정 네임스페이스를 사용하고 필요한 특정 노드 풀만 허용하도록 구성할 수 있어요.
namespace "infra" {
description = "Infrastructure jobs."
node_pool_config {
default = "infra"
allowed = ["ingress", "csi-controllers", "all"]
}
}
혼합 스케줄링 알고리즘 (Mixed Scheduling Algorithms)
이 패턴은 서로 다른 스케줄링 알고리즘이 노드 풀별로 설정된 예시를 보여줘요.
Nomad가 제공하는 각 스케줄링 알고리즘은 서로 다른 유형의 환경과 워크로드에 가장 적합해요.
binpack 알고리즘은 리소스 사용을 극대화하고 주어진 클라이언트 집합에 가능한 한 많은 워크로드를 채우는 것을 목표로 해요. 이는 인프라가 시간당 과금되고 빠르게 확장·축소될 수 있는 클라우드 환경에 이상적이에요. 워크로드 밀도를 극대화하면 클라우드 인스턴스에서 실행되는 클러스터가 필요한 모든 것을 실행하는 데 필요한 클라이언트 수를 줄일 수 있어요.
spread 알고리즘은 반대 방향으로 동작하며, 사용 가능한 모든 클라이언트를 활용해 밀도와 잠재적인 노이즈 네이버(noisy neighbor) 및 리소스 경합을 줄여요. 이는 클라이언트가 사전 프로비저닝되고 더 느리게 확장되는 온프레미스 배포 같은 환경에 이상적이에요.
혼합 환경의 클러스터는 노드 풀을 사용해 노드 유형별로 스케줄러 알고리즘을 조정할 수 있어요. 클라우드 인스턴스는 binpack 알고리즘을 사용하는 노드 풀에 배치하고, 베어메탈 노드는 spread를 사용하도록 구성된 노드 풀에 배치할 수 있어요.
node_pool "cloud" {
# ...
scheduler_config {
scheduler_algorithm = "binpack"
}
}
node_pool "on-prem" {
# ...
scheduler_config {
scheduler_algorithm = "spread"
}
}
알고리즘을 혼합하는 것이 유용할 수 있는 또 다른 시나리오는 노이즈 네이버에 더 민감한 워크로드(따라서 spread 알고리즘 사용)를 더 밀착해서 채울 수 있는 워크로드(binpack)로부터 분리하는 것이에요.