템플릿으로 CLI 출력 포맷팅

템플릿으로 CLI 출력 포맷팅 (Format CLI output with templates)

중급에서 고급 수준으로 Nomad를 사용할 때는 다른 시스템과 연동하거나 Nomad가 생성하는 출력을 사용자 정의해야 할 거예요. -t 플래그는 API를 기반으로 출력을 생성하는 여러 Nomad 명령에 Go의 text/template 형식의 템플릿을 전달하는 강력한 방법이에요. 이를 통해 특정 요구 사항에 맞게 출력을 필터링하고 사용자 정의할 수 있어요.

-t 플래그를 허용하는 명령은 다음과 같아요:

이 가이드는 템플릿 엔진에 반환되는 객체를 탐색하는 방법과 템플릿 구문을 사용해 출력을 사용자 정의 형태로 포맷하는 방법을 가르쳐줘요.

출처: 문서

본문

전제 조건 (Prerequisites)

이 가이드는 다음을 가정해요:

  • Go의 text/template 구문에 익숙하다고 가정. Go template syntax 레퍼런스에서 더 배울 수 있어요.
  • 활성 워크로드가 있는 Nomad 클러스터에 대해 이 명령들을 실행하고 있다고 가정. sudo nomad agent -dev로 시작한 dev 에이전트를 사용해 최소 환경을 만들고 적어도 하나의 Nomad 잡을 실행할 수 있어요. nomad init -short로 샘플 Docker 잡을 만들거나 자신의 Nomad 잡을 제공할 수 있어요.

셸별 구문에 유의 (Note the shell-specific syntax)

-t 플래그를 사용할 때는 셸 환경에 따라 문자열 리터럴을 올바르게 처리해야 해요. POSIX 셸에서는 다음을 단일 따옴표로 실행할 수 있어요:

$ nomad node status  -t '{{printf "%#+v" .}}'

Windows 셸(예: PowerShell)에서는 단일 따옴표를 사용하되 매개변수 안의 큰 따옴표는 다음과 같이 이스케이프하세요:

PS> nomad node status  -t '{{printf \"%#+v\" .}}'

이 가이드에서 스니펫 위의 탭을 사용해 적절한 이스케이프가 적용된 예시를 선택할 수 있어요.

객체 발견 시작 (Start discovering objects)

printf 함수와 "%#+v" 형식 문자열은 익숙하지 않은 템플릿 컨텍스트를 탐색할 때 중요한 도구예요.

다음 명령을 실행해 템플릿에 전달되는 컨텍스트를 Go 객체 형식으로 출력해요.

Posix Shells PowerShell
$ nomad node status -t '{{printf "%#+v" .}}'
PS> nomad node status -t '{{printf \"%#+v\" .}}'
[]*api.NodeListStub{(*api.NodeListStub)(0xc0003fa160), (*api.NodeListStub)(0xc0003fa0b0), (*api.NodeListStub)(0xc0003fa000)}

출력은 컨텍스트가 api.NodeListStub 객체에 대한 포인터(*) 목록([])으로 구성되었음을 나타내요. 목록은 또한 클러스터의 서버 상태에 있는 각 클라이언트 노드에 대해 NodeListStub 객체 하나를 보여줘요.

목록에 대해 range 제어를 사용해 이 api.NodeListStub 객체를 탐색할 수 있어요.

Posix Shells PowerShell
$ nomad node status -t '{{range .}}{{printf "%#+v" .}}{{end}}'
PS> nomad node status -t '{{range .}}{{printf \"%#+v\" .}}{{end}}'
&api.NodeListStub{Address:"10.0.2.52", ID:"4f60bc83-71a2-7790-b120-4e55d0e6ed34", Datacenter:"dc1", Name:"nomad-client-2.node.consul", NodeClass:"", Version:"0.12.0", Drain:false, SchedulingEligibility:"eligible", Status:"ready", ...

클러스터 상태에 클라이언트 노드가 많으면 이 출력은 다루기 어려울 거예요. 이 경우 with와 index 함수를 사용해 첫 번째 목록 항목을 얻을 수 있어요.

Posix Shells PowerShell
$ nomad node status -t '{{with index . 0}}{{printf "%#+v" .}}{{end}}'
PS> nomad node status -t '{{with index . 0}}{{printf \"%#+v\" .}}{{end}}'
&api.NodeListStub{Address:"10.0.2.52", ID:"4f60bc83-71a2-7790-b120-4e55d0e6ed34", Datacenter:"dc1", Name:"nomad-client-2.node.consul", NodeClass:"", Version:"0.12.0", Drain:false, SchedulingEligibility:"eligible", Status:"ready", ...
&api.NodeListStub{Address:"10.0.2.52", ID:"4f60bc83-71a2-7790-b120-4e55d0e6ed34", Datacenter:"dc1", Name:"nomad-client-2.node.consul", NodeClass:"", Version:"0.12.0", Drain:false, SchedulingEligibility:"eligible", Status:"ready", ...

마지막으로 클러스터의 각 클라이언트에 대해 Name과 Version을 출력해요.

Posix Shells PowerShell
$ nomad node status -t '{{range .}}{{printf "%s: %s\n" .Name .Version}}{{end}}'
PS> nomad node status -t '{{range .}}{{printf \"%s: %s\n\" .Name .Version}}{{end}}'
nomad-client-2.node.consul: 0.12.0
nomad-client-3.node.consul: 0.12.0
nomad-client-1.node.consul: 0.12.0

조용한 출력 만들기 (Make quiet output)

클러스터의 실행 중인 잡 ID만 보여주고 그 외에는 아무것도 보여주지 않는 축약된 nomad job status 출력 버전을 만들고 싶다고 가정해요.

Posix Shells PowerShell
$ nomad job inspect -t '{{range .}}{{if eq .Status "running"}}{{ println .Name}}{{end}}{{end}}'
PS> nomad job inspect -t '{{range .}}{{if eq .Status \"running\"}}{{ println .Name}}{{end}}{{end}}'

Nomad는 클러스터의 모든 실행 중인 잡의 잡 ID를 출력해요. 예:

fabio
sockshop-carts
sockshop-catalogue
sockshop-frontend
sockshop-infra
sockshop-orders
sockshop-payment
sockshop-shipping
sockshop-user

스스로 도전 (Challenge yourself)

할당은 약간 다른 형태를 가져요. nomad alloc status 명령에서 유사한 출력을 어떻게 만들 수 있을까요? Nomad 클러스터에 실행 중인 할당이 적어도 하나 있는지 확인한 다음, 앞의 printf 기법을 사용해 템플릿에 전달되는 값을 탐색하세요.

printf 명령으로 명령에서 전달받은 컨텍스트를 출력하세요.

Posix Shells PowerShell
$ nomad alloc status -t '{{printf "%#+v" . }}'
PS> nomad alloc status -t '{{printf \"%#+v\" . }}'
[]*api.AllocationListStub ...

가장 먼저 받는 것이 AllocationListStub 객체에 대한 포인터(*) 목록([])이라는 점에 유의하세요.

목록의 각 항목을 순회하려면 range를 사용하세요.

Posix Shells PowerShell
$ nomad alloc status -t '{{range .}}{{printf "%#+v" . }}{{end}}'
PS> nomad alloc status -t '{{range .}}{{printf \"%#+v\" . }}{{end}}'
&api.AllocationListStub{ID:"30663b68-4d8a-aada-4ad2-011b1acae3a1", EvalID:"c5eda90b-f675-048e-b2f7-9ced30e4916b", Name:"sockshop-user.userdb[0]", Namespace:"default", NodeID:"3be35c12-70aa-8816-195e-a4630a457727", NodeName:"nomad-client-3.node.consul", JobID:"sockshop-user", JobType:"service", JobVersion:0x0, ...

실행 중인 할당이 많으면 다루기 어려울 수 있어요. 이 경우 with와 index 함수를 사용해 첫 번째 목록 항목을 얻을 수 있어요.

Posix Shells PowerShell
$ nomad alloc status -t '{{with index . 0}}{{printf "%#+v" . }}{{end}}'
PS> nomad alloc status -t '{{with index . 0}}{{printf \"%#+v\" . }}{{end}}'
&api.AllocationListStub{ID:"30663b68-4d8a-aada-4ad2-011b1acae3a1", EvalID:"c5eda90b-f675-048e-b2f7-9ced30e4916b", Name:"sockshop-user.userdb[0]", Namespace:"default", NodeID:"3be35c12-70aa-8816-195e-a4630a457727", NodeName:"nomad-client-3.node.consul", JobID:"sockshop-user", JobType:"service", JobVersion:0x0, ...

할당의 실행 상태에 대한 통찰을 주는 AllocationListStub 객체의 필드는 DesiredStatus와 ClientStatus예요.

알고 계셨나요? AllocationListStub 객체의 정의와 DesiredStatus 및 ClientStatus의 유효한 값은 Nomad의 api 패키지에 있어요. 잠시 살펴보고 템플릿으로 표시하는 데 관심 있는 다른 정보가 무엇인지 확인해 보세요.

템플릿을 업데이트해 DesiredStatus가 "run"이고 클라이언트 상태가 "running" 또는 "pending"인 항목을 보여주세요.

Posix Shells PowerShell
$ nomad alloc status -t '{{range .}}{{if and (eq .DesiredStatus "run") (or (eq .ClientStatus "running") (eq .ClientStatus "pending"))}}{{println .ID}}{{end}}{{end}}'
PS> nomad alloc status -t '{{range .}}{{if and (eq .DesiredStatus \"run\") (or (eq .ClientStatus \"running\") (eq .ClientStatus \"pending\"))}}{{println .ID}}{{end}}{{end}}'
30663b68-4d8a-aada-4ad2-011b1acae3a1
11b916da-d679-1718-26f3-f6cd499bfdb8
68bcb157-359f-9293-d091-5a8ef71475ad
...

이제 Nomad 클러스터에서 실행 중인 모든 할당의 ID 목록이 생겼어요.

파일에서 템플릿 가져오기 (Retrieve a template from file)

명령줄로 템플릿을 작성하는 것은 템플릿이 더 복잡해질수록 어려워져요.

템플릿을 자체 파일에 작성하면 주석을 사용하고 여러 줄에 걸치고 조건문을 들여쓸 수 있어 자신과 다른 운영자에게 더 읽기 쉽게 만들 수 있어요.

명령에 템플릿 데이터를 포함하기 위한 몇 가지 기법을 사용하는 것을 고려하세요.

Posix Shells

running_jobs.tmpl이라는 파일을 다음 내용으로 만드세요.

{{- /*
  Get Running Jobs
  Run with `nomad job inspect -t "$(cat running_jobs.tmpl)"`
*/ -}}
{{- range . -}}
  {{- if eq .Status "running" -}}
    {{- println .Name -}}
  {{- end -}}
{{- end -}}

이제 subshell을 사용해 파일을 변수로 읽으세요.

$ nomad job inspect -t "$(cat running_jobs.tmpl)"

PowerShell

running_jobs.tmpl이라는 파일을 다음 내용으로 만드세요.

{{- /*
  Get Running Jobs
  Run with:
    $content=Get-Content running_jobs.tmpl -Raw; nomad job inspect -t $content
*/ -}}
{{- range . -}}
  {{- if eq .Status \"running\" -}}
    {{- println .Name -}}
  {{- end -}}
{{- end -}}

이제 subshell을 사용해 파일을 변수로 읽으세요.

PS> $content=Get-Content running_jobs.tmpl -Raw; nomad job inspect -t $content

더 알아보기 (Learn more)

이 가이드에서 다음을 배웠어요:

  • Go의 text/template 구문을 사용해 여러 Nomad 명령의 출력을 사용자 정의.
  • printf 함수를 사용해 템플릿의 컨텍스트에서 사용 가능한 것을 발견.
  • 명령의 일부로 파일에 포함된 템플릿 정의를 사용.

더 알아보기 (Learn more)