태스크에서 Nomad 변수 사용하기
태스크에서 Nomad 변수 사용하기 (Use Nomad variables in tasks)
이 튜토리얼에서는 template 블록을 통해 태스크에서 Nomad 변수에 접근해요. 태스크는 자신의 변수에 접근할 수 있는 암묵적 ACL 정책을 가지며, ACL 정책에 작업, 그룹, 태스크 필드를 추가해 이러한 권한을 확장할 수 있어요.
출처: 문서
본문
Note: 변수에 대한 접근은 항상 ACL(액세스 제어 목록)로 보호해야 해요. 변수에 대한 ACL 정책 작성은 Nomad 변수 액세스 제어 튜토리얼에서 다뤄요.
Nomad 변수 기능과 관련 개념에 대한 완전한 문서는 변수 참조 문서, 키 관리 문서, 워크로드 신원 문서를 참조하세요.
자동 접근 (Automatic access)
각 태스크의 워크로드 신원은 nomad/jobs/ 접두사 뒤에 작업 ID, 태스크 그룹 이름, 태스크 이름이 이어지는 Nomad 소유 경로에서 발견되는 변수에 대한 자동 읽기 및 목록 접근을 부여해요.
Nomad 변수 액세스 제어 튜토리얼을 완료했다면 "prod" 네임스페이스와 "prod-ops" 정책과 연결된 토큰이 있을 거예요. 아니라면 이 섹션에서 관리 토큰을 사용하고 "prod" 네임스페이스를 만들 수 있어요.
$ nomad namespace apply -description "production environment" prod
Successfully applied namespace "prod"!
이 튜토리얼에서는 "prod" 네임스페이스에서 작업할 거예요. NOMAD_NAMESPACE 변수를 설정해 명령줄이 모든 변수를 해당 네임스페이스에 쓰도록 해요.
export NOMAD_NAMESPACE=prod
서로 다른 작업, 그룹, 태스크가 어떻게 접근할 수 있는지 확인하기 위해 다음 변수들을 만들어요.
nomad var put nomad/jobs password=passw0rd1
nomad var put nomad/jobs/example person_to_greet=alice
nomad var put nomad/jobs/example/web foo=1 bar=2 baz=3
nomad var put nomad/jobs/example/web/httpd port=8001
nomad var put nomad/jobs/example/web/sidecar password=passw0rd2
다음 작업 명세를 만들어요. 이 작업 example은 두 태스크 httpd와 sidecar가 있는 하나의 그룹 web을 가져요. 앞서 작성한 모든 변수에 접근하는 템플릿을 포함해요.
job "example" {
datacenters = ["dc1"]
group "web" {
network {
port "www" {
to = 8001
}
}
task "httpd" {
driver = "docker"
config {
image = "busybox:1"
command = "httpd"
args = ["-v", "-f", "-p", "0.0.0.0:${PORT}", "-h", "${NOMAD_ALLOC_DIR}/data"]
ports = ["www"]
}
template {
destination = "${NOMAD_SECRETS_DIR}/env.txt"
env = true
data = <<EOT
PORT={{ with nomadVar "nomad/jobs/example/web/httpd" }}{{ .port }}{{ end }}
EOT
}
template {
destination = "${NOMAD_ALLOC_DIR}/data/index.html"
change_mode = "noop"
data = <<EOT
<!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8"><title>Hello Variables - Index</title></head>
<body>
<p>Hello, {{ with nomadVar "nomad/jobs/example" }}{{ .person_to_greet }}{{ end }}!</p>
<p>Here is the group variable:</p>
<ul>
{{- with nomadVar "nomad/jobs/example/web" -}}
{{- range $k, $v := . }}
<li>{{ $k }}={{ $v }}</li>
{{- end }}
{{- end }}
</ul>
<p><a href="/sidecar.html">View the output from the sidecar task.</a></p>
</body>
</html>
EOT
}
}
task "sidecar" {
driver = "docker"
config {
image = "busybox:1"
command = "sleep"
args = ["300"]
}
template {
destination = "${NOMAD_ALLOC_DIR}/data/sidecar.html"
change_mode = "noop"
data = <<EOT
<!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8"><title>Hello Variables - Sidecar</title></head>
<body>
<p>The task has access to the following variables:</p>
<ul>
{{- range nomadVarList "nomad" }}
<li>{{ .Path }}</li>
{{- end }}
</ul>
<p><a href="/">View the index page.</a></p>
</body>
</html>
EOT
}
}
}
}
이 작업을 실행하고 배포가 완료될 때까지 기다린 다음 할당 짧은 ID를 기록해요. 이 예제에서 할당 짧은 ID는 ec6dc2e4예요.
$ nomad job run ./example.nomad.hcl
==> 2022-09-19T11:42:20-04:00: Monitoring evaluation "0d8a7587"
2022-09-19T11:42:20-04:00: Evaluation triggered by job "example"
2022-09-19T11:42:20-04:00: Evaluation within deployment: "b58da4d8"
2022-09-19T11:42:20-04:00: Allocation "ec6dc2e4" created: node "9063a25f", group "web"
2022-09-19T11:42:20-04:00: Evaluation status changed: "pending" -> "complete"
==> 2022-09-19T11:42:20-04:00: Evaluation "0d8a7587" finished with status "complete"
==> 2022-09-19T11:42:20-04:00: Monitoring deployment "b58da4d8"
✓ Deployment "b58da4d8" successful
2022-09-19T11:42:32-04:00
ID = b58da4d8
Job ID = example
Job Version = 0
Status = successful
Description = Deployment completed successfully
Deployed
Task Group Desired Placed Healthy Unhealthy Progress Deadline
web 1 1 1 0 2022-09-19T15:52:31Z
먼저 nomad alloc exec를 사용해 httpd 태스크로 들어가 컨테이너에서 실행 중인 프로세스의 명령줄 인수를 보여줘요.
$ nomad alloc exec -task httpd ec6dc2e4 ps -ef
PID USER TIME COMMAND
1 root 0:00 httpd -v -f -p 0.0.0.0:8001 -h /alloc/data
8 root 0:00 ps -ef
포트 번호가 다음 템플릿에서 env 필드를 사용해 렌더링한 환경 변수로 보간되었음을 주목하세요:
template {
destination = "${NOMAD_SECRETS_DIR}/env.txt"
env = true
data = <<EOT
PORT={{ with nomadVar "nomad/jobs/example/web/httpd" }}{{ .port }}{{ end }}
EOT
}
포트 8001에서 httpd 태스크가 제공하는 웹 페이지를 방문해요. macOS에서 Nomad를 실행하고 Docker for Mac으로 Docker 태스크를 실행한다면 localhost 주소에서 웹 페이지에 접근할 수 있어요.
원격 Linux 호스트나 Vagrant 박스에 배포한다면 nomad alloc status를 실행했을 때 나오는 IP 주소를 사용할 수 있어요:
$ nomad alloc status ec6dc2e4
...
Allocation Addresses (mode = "bridge"):
Label Dynamic Address
*www yes 127.0.0.1:21976 -> 8001
curl을 사용할 수도 있어요:
$ curl 127.0.0.1:21976
<!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8"><title>Hello Variables - Index</title></head>
<body>
<p>Hello, alice!</p>
<p>Here is the group variable:</p>
<ul>
<li>bar=2</li>
<li>baz=3</li>
<li>foo=1</li>
</ul>
<p><a href="/sidecar.html">View the output from the sidecar task.</a></p>
</body>
</html>
이것은 작업 "example"에 접근 가능한 nomad/jobs/example의 변수와 작업 "example" 내 그룹 "web"에 접근 가능한 nomad/jobs/example/web의 변수를 읽는 이 템플릿 블록에 해당해요.
template {
destination = "${NOMAD_ALLOC_DIR}/data/index.html"
change_mode = "noop"
data = <<EOT
<!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8"><title>Hello Variables - Index</title></head>
<body>
<p>Hello, {{ with nomadVar "nomad/jobs/example" }}{{ .person_to_greet }}{{ end }}!</p>
<p>Here is the group variable:</p>
<ul>
{{- with nomadVar "nomad/jobs/example/web" -}}
{{- range $k, $v := . }}
<li>{{ $k }}={{ $v }}</li>
{{- end }}
{{- end }}
</ul>
<p><a href="/sidecar.html">View the output from the sidecar task.</a></p>
</body>
</html>
EOT
sidecar 태스크가 렌더링한 웹 페이지를 방문해요:
curl -s http://127.0.0.1:21976/sidecar.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8"><title>Hello Variables - Sidecar</title></head>
<body>
<p>The task has access to the following variables:</p>
<ul>
<li>nomad/jobs</li>
<li>nomad/jobs/example</li>
<li>nomad/jobs/example/web</li>
<li>nomad/jobs/example/web/sidecar</li>
</ul>
<p><a href="/">View the index page.</a></p>
</body>
</html>
이것은 이 태스크가 자신의 네임스페이스에서 접근할 수 있는 모든 변수를 나열하는 다음 템플릿 블록에 해당해요:
template {
destination = "${NOMAD_ALLOC_DIR}/data/sidecar.html"
change_mode = "noop"
data = <<EOT
<!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8"><title>Hello Variables - Sidecar</title></head>
<body>
<p>The task has access to the following variables:</p>
<ul>
{{- range nomadVarList "nomad" }}
<li>{{ .Path }}</li>
{{- end }}
</ul>
<p><a href="/">View the index page.</a></p>
</body>
</html>
EOT
}
nomad/jobs/example/httpd가 목록에 나타나지 않는다는 점에 주목하세요. nomad/jobs/another-example에 변수를 추가해도 목록에 나타나지 않아요. nomad/jobs/example/sidecar를 다른 네임스페이스에 추가한다면 목록에 나타나지 않아요.
워크로드 연결 ACL 정책 (Workload associated ACL policies)
많은 작업이 공유하는 경로의 변수에 대한 태스크 접근을 허용해야 할 수도 있어요. 예를 들어 클러스터의 모든 작업이 타사 모니터링 공급업체의 공유 API 키가 필요할 수 있어요. 태스크의 워크로드 신원과 연결된 정책을 만들어 이러한 변수 시크릿에 대한 접근을 제공할 수 있어요. 전체 문서는 워크로드 연결 ACL 정책을 참조하세요.
shared라는 새 네임스페이스를 만들어요.
$ nomad namespace apply shared
Successfully applied namespace "shared"!
shared 네임스페이스에 vendor/foo/bar라는 변수를 만들어요.
nomad var put -namespace shared vendor/foo/bar user=me password=passw0rd1
앞서 작성한 태스크에 shared 네임스페이스의 모든 시크릿 접근 권한을 부여하려면 다음 정책 파일 shared-policy.hcl을 만들어요.
namespace "shared" {
variables {
path "*" {
capabilities = ["read"]
}
}
}
이제 정책을 만들고 nomad acl policy apply 명령에 적절한 플래그를 지정해 example 작업의 web 그룹에 있는 httpd 태스크와 연결해요.
nomad acl policy apply \
-namespace prod -job example -group web -task httpd \
shared-policy ./shared-policy.hcl
정책을 조회해 워크로드와 연결되었는지 확인할 수 있어요.
$ nomad acl policy info shared-policy
Name = shared-policy
Description = <none>
CreateIndex = 390
ModifyIndex = 390
Associated Workload
Namespace = prod
JobID = example
Group = web
Task = httpd
Rules
namespace "shared" {
variables {
path "*" {
capabilities = ["read"]
}
}
}
httpd 태스크의 템플릿을 변경해요.
template {
destination = "alloc/index.html"
data = <<EOT
<!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8"><title>Hello Variables - Index</title></head>
<body>
<p>Hello, {{ with nomadVar "nomad/jobs/example" }}{{ .person_to_greet }}{{ end }}!</p>
<p>Here is the shared variable:</p>
<ul>
{{- with nomadVar "vendor/foo/bar@shared" }}
{{- range $k, $v := . }}
<li>{{ $k }}={{ $v }}</li>
{{- end }}
{{- end }}
</ul>
</body>
</html>
EOT
작업을 업데이트하고 배포가 완료될 때까지 기다려요.
nomad job run ./example.nomad.hcl
httpd 태스크가 제공하는 웹 페이지를 방문해요.
curl -s http://127.0.0.1:8001/index.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8"><title>Hello Variables - Index</title></head>
<body>
<p>Hello, alice!</p>
<p>Here is the shared variable:</p>
<ul>
<li>password=passw0rd1</li>
<li>user=me</li>
</ul>
</body>
</html>
태스크 변수 업데이트하기 (Updating task variables)
변수의 값을 업데이트하면 그 값을 읽는 템플릿에서도 업데이트돼요.
"password" 필드가 변경되도록 공유 변수를 업데이트해요.
nomad var put -namespace shared -force vendor/foo/bar user=me password=passw0rd2
몇 순간 후 템플릿에서 값이 업데이트돼요.
curl -s http://127.0.0.1:8001/index.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8"><title>Hello Variables - Index</title></head>
<body>
<p>Hello, alice!</p>
<p>Here is the shared variable:</p>
<ul>
<li>password=passw0rd2</li>
<li>user=me</li>
</ul>
</body>
</html>
템플릿 change_mode를 사용해 값이 변경될 때 Nomad의 동작을 지정할 수 있어요.
다음 단계 (Next steps)
Nomad 변수는 템플릿 블록의 함수를 사용해 데이터를 Nomad 작업에 내보내므로, Nomad Pack으로 Nomad의 템플릿에 대해 더 알아보는 것을 고려해 보세요.