Kubernetes manifest를 Nomad job specification으로 변환
Kubernetes manifest를 Nomad job specification으로 변환
Kubernetes와 Nomad의 워크로드는 둘 다 선언적 스펙 파일로 정의돼요. Kubernetes 워크로드 스펙 파일은 manifest 로 알려져 있고 YAML로 작성해요. Nomad 워크로드 스펙 파일은 job specification 또는 jobspec 으로 알려져 있고 HCL로 만들어요.
이 페이지는 Kubernetes manifest로 정의된 예시 애플리케이션을 사용해 동등한 Nomad jobspec을 만드는 과정을 안내해요.
출처: 문서
본문
예시 Kubernetes 애플리케이션 검토 (Review an example Kubernetes application)
다음 예시 애플리케이션은 AWS EKS 문서의 Linux에 샘플 애플리케이션 배포 가이드에서 가져온 거예요.
이 애플리케이션은 각각 포트 8080에서 리슨하는 NGINX 컨테이너 세 개와, 포트 80에서 리슨하며 요청을 NGINX 컨테이너로 전달하는 서비스 하나를 포함해요. 컨테이너는 amd64 또는 arm64 아키텍처의 Linux 노드에서 실행돼요. 이 애플리케이션은 Deployment manifest와 Service manifest로 구성돼요.
sample-app.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: eks-sample-linux-deployment
namespace: eks-sample-app
labels:
app: eks-sample-linux-app
spec:
replicas: 3
selector:
matchLabels:
app: eks-sample-linux-app
template:
metadata:
labels:
app: eks-sample-linux-app
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/arch
operator: In
values:
- amd64
- arm64
containers:
- name: nginx
image: public.ecr.aws/nginx/nginx:1.23
ports:
- name: http
containerPort: 8080
imagePullPolicy: IfNotPresent
nodeSelector:
kubernetes.io/os: linux
apiVersion: v1
kind: Service
metadata:
name: eks-sample-linux-service
namespace: eks-sample-app
labels:
app: eks-sample-linux-app
spec:
selector:
app: eks-sample-linux-app
ports:
- protocol: TCP
port: 80
targetPort: 8080
Nomad jobspec 시작 방법 (How to start a Nomad jobspec)
변환 프로세스를 시작하려면 job, group, task 블록을 포함하는 jobspec 파일의 프레임워크를 만들어요.
sample-app.nomad.acl
job "eks-sample-linux-deployment" {
group "nginx-group" {
task "nginx" {
}
}
}
이 예시들의 명명 체계는 동등한 구성 속성을 강조하기 위해 원래 Kubernetes manifest와 같은 eks- 접두사를 사용해요. 이 경우 Nomad job 리소스의 이름은 Kubernetes Deployment name과 같아요.
NGINX 컨테이너 집합을 배포하려면 group 블록을 구성해요. count 속성은 Nomad에 동일한 컨테이너 세 개를 만들도록 지시하고, network 블록은 포트 8080을 활성화하고 http라는 이름으로 태스크 구성에 동적으로 사용할 수 있게 해요. 각 컨테이너는 config 블록에 정의된 이미지와 구성을 사용하고, driver 속성은 Nomad에 Docker 런타임을 사용하도록 지시해요. 태스크 구성은 또한 그룹 레벨에 정의된 http 포트를 사용해요.
sample-app.nomad.acl
job "eks-sample-linux-deployment" {
group "nginx-group" {
count = 3
network {
port "http" {
to = 8080
}
}
task "nginx" {
driver = "docker"
config {
image = "public.ecr.aws/nginx/nginx:1.23"
ports = ["http"]
}
}
}
}
워크로드가 실행되는 곳 제한 (Limit where the workloads run)
Nomad는 워크로드 요구 사항에 따라 constraints와 affinities를 태스크, 그룹 또는 잡 레벨에서 설정할 수 있게 해요.
예시 Kubernetes 애플리케이션은 amd64 또는 arm64 아키텍처의 노드에서 실행되도록 스케줄링 중에 실행되는 affinity를 구성해요. linux 런타임은 컨테이너의 nodeSelector 구성에 설정돼요.
Nomad에서는 affinity 블록을 job 정의에 추가해요. 각 affinity는 각 아키텍처가 선택될 동등한 기회를 가지도록 가중치 50으로 설정돼요. 그런 다음 task 블록에 constraint를 설정해요.
sample-app.nomad.acl
job "eks-sample-linux-deployment" {
affinity {
attribute = "${attr.cpu.arch}"
value = "amd64"
weight = 50
}
affinity {
attribute = "${attr.cpu.arch}"
value = "arm64"
weight = 50
}
group "nginx-group" {
count = 3
network {
port "http" {
to = 8080
}
}
task "nginx" {
driver = "docker"
constraint {
attribute = "${attr.kernel.name}"
value = "linux"
}
config {
image = "public.ecr.aws/nginx/nginx:1.23"
ports = ["http"]
}
}
}
}
잡 타입 설정 (Set job type)
Nomad는 service, system, batch, system batch 잡 타입을 지원해요. 이 예시 애플리케이션은 service예요. 잡 타입에 대한 자세한 내용은 문서의 Nomad job schedulers를 참고하세요.
잡 타입을 설정한 다음 네임스페이스와 사용자 정의 레이블을 포함한 잡 메타데이터를 job 블록에 추가해요. 네임스페이스를 사용하려면 잡을 실행하기 전에 네임스페이스 객체를 구성해야 해요.
sample-app.nomad.acl
job "eks-sample-linux-deployment" {
type = "service"
namespace = "eks-sample-app"
datacenters = ["*"]
meta {
app = "eks-sample-linux-app"
}
affinity {
attribute = "${attr.cpu.arch}"
value = "amd64"
weight = 50
}
affinity {
attribute = "${attr.cpu.arch}"
value = "arm64"
weight = 50
}
group "nginx-group" {
count = 3
network {
port "http" {
to = 8080
}
}
task "nginx" {
driver = "docker"
constraint {
attribute = "${attr.kernel.name}"
value = "linux"
}
config {
image = "public.ecr.aws/nginx/nginx:1.23"
ports = ["http"]
}
}
}
}
마지막으로 Nomad가 세 컨테이너를 모두 노출하도록 service 블록을 group 구성에 추가해요.
Nomad에는 내장 서비스 디스커버리가 있어 그룹 레벨에 service 블록을 추가하면 서비스 이름이 그룹의 task 블록에 정의된 세 할당 중 어느 것으로든 트래픽을 보낼 수 있어요. 그룹 레벨에 service 블록을 추가하면 Consul service mesh 통합을 사용할 수도 있게 돼요.
sample-app.nomad.acl
job "eks-sample-linux-deployment" {
type = "service"
namespace = "eks-sample-app"
datacenters = ["*"]
meta {
app = "eks-sample-linux-app"
}
affinity {
attribute = "${attr.cpu.arch}"
value = "amd64"
weight = 50
}
affinity {
attribute = "${attr.cpu.arch}"
value = "arm64"
weight = 50
}
group "nginx-group" {
count = 3
network {
port "http" {
to = 8080
}
}
service {
name = "eks-sample-linux-service"
provider = "nomad"
port = "80"
}
task "nginx" {
driver = "docker"
constraint {
attribute = "${attr.kernel.name}"
value = "linux"
}
config {
image = "public.ecr.aws/nginx/nginx:1.23"
ports = ["http"]
}
}
}
}
이제 Nomad jobspec이 완성되었고, CLI 또는 Web UI로 Nomad에서 잡을 실행할 수 있어요. 테스트 환경이 필요하면 HashiCorp의 Nomad sandbox를 사용해 호스팅 세션을 시작하세요.
예시 코드 비교 (Example code comparisons)
이 구성 스니펫들은 manifest 또는 jobspec의 일부를 나타내요. 추가 명확성을 위해 탭에 나란히 표시돼 있어요.
네임스페이스 (Namespace)
| Kubernetes | Nomad |
|---|
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: eks-sample-app
job "eks-sample-linux-deployment" {
namespace = "eks-sample-app"
}
메타데이터 (Metadata)
메타데이터는 배포 또는 잡의 이름과 사용자 정의 메타데이터를 포함해요.
| Kubernetes | Nomad |
|---|
apiVersion: apps/v1
kind: Deployment
metadata:
name: eks-sample-linux-deployment
namespace: eks-sample-app
labels:
app: eks-sample-linux-app
job "eks-sample-linux-deployment" {
meta {
app = "eks-sample-linux-app"
}
}
컨테이너 스펙과 count (Container specification and count)
| Kubernetes | Nomad |
|---|
apiVersion: apps/v1
kind: Deployment
spec:
replicas: 3
template:
spec:
containers:
- name: nginx
image: public.ecr.aws/nginx/nginx:1.23
ports:
- name: http
containerPort: 8080
job "eks-sample-linux-deployment" {
group "nginx-group" {
count = 3
task "nginx" {
driver = "docker"
config {
image = "public.ecr.aws/nginx/nginx:1.23"
ports = "80"
}
}
}
}
Affinity
| Kubernetes | Nomad |
|---|
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/arch
operator: In
values:
- amd64
- arm64
job "eks-sample-linux-deployment" {
affinity {
attribute = "${attr.cpu.arch}"
value = "amd64"
weight = 50
}
affinity {
attribute = "${attr.cpu.arch}"
value = "arm64"
weight = 50
}
}
노드 선택기와 제약 조건 (Node selector and constraint)
| Kubernetes | Nomad |
|---|
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
nodeSelector:
kubernetes.io/os: linux
job "eks-sample-linux-deployment" {
group "nginx-group" {
task "nginx" {
constraint {
attribute = "${attr.kernel.name}"
value = "linux"
}
}
}
}
서비스 (Service)
Kubernetes는 kind가 Service로 설정된 별도의 구성 manifest로 서비스를 정의한다는 점에 유의하세요. Nomad jobspec은 서비스와 태스크 정의를 모두 포함해요.
| Kubernetes | Nomad |
|---|
apiVersion: v1
kind: Service
metadata:
name: eks-sample-linux-service
namespace: eks-sample-app
labels:
app: eks-sample-linux-app
spec:
selector:
app: eks-sample-linux-app
ports:
- protocol: TCP
port: 80
targetPort: 8080
job "eks-sample-linux-deployment" {
group "nginx-group" {
service {
name = "eks-sample-linux-service"
provider = "nomad"
port = "80"
}
}
}
다음 단계 (Next steps)
Nomad 잡과 통합에 대해 계속 배우려면 다음 리소스를 확인하세요:
- 더 고급 서비스 디스커버리를 위해 Use Nomad's Consul integration
- Vault 통합에 대해 배우고 Nomad 잡에서 동적 시크릿을 사용하는 방법
- Nomad Variables를 사용해 Nomad에서 구성 데이터를 저장·조회하는 방법
- 잡 스펙에서 사용 가능한 블록에 대해 Nomad job specification 참조