Consul Template 모드

Consul Template 모드 (Consul Template modes)

Consul Template은 런타임 동작과 프로세스 수명 주기를 바꾸는 여러 모드로 실행할 수 있어요.

출처: 문서

본문

Consul Template은 런타임 동작과 프로세스 수명 주기를 바꾸는 여러 모드로 실행할 수 있습니다.

Once 모드 (Once Mode)

Once 모드로 실행하면 Consul Template은 각 템플릿을 정확히 한 번 실행하고 종료합니다.

Once 모드에서 Consul Template은 모든 의존성이 렌더링될 때까지 기다립니다. 템플릿이 Consul에 존재하지 않는 의존성을 지정하면, once 모드는 Consul이 해당 의존성에 대한 데이터를 반환할 때까지 기다립니다. "반환된 데이터"와 "빈 데이터"는 상호 배타적이지 않다는 점에 유의하세요.

Once 모드로 실행하려면 -once 플래그를 포함하거나 구성 파일에서 활성화하세요.

{{ service "foo" }} 쿼리를 실행하여 "foo"라는 모든 정상 서비스를 반환할 때, "foo"라는 모든 정상 서비스를 Consul에 요청하는 것입니다. 해당 이름의 서비스가 없으면 응답은 빈 배열입니다. 이 응답은 "foo"라는 정상 서비스가 없을 때의 응답과 동일합니다.

Consul Template은 입력 템플릿을 여러 번 처리합니다. 첫 번째 결과가 이후의 의존성에 영향을 줄 수 있기 때문입니다:

{{ range services }}
{{ range service .Name }}
{{ end }}
{{ end }}

이 예제에서 내부 루프는 외부 루프가 응답을 반환할 때까지 평가할 수 없으므로, 각 service를 조회하기 전에 services의 출력을 처리해야 합니다. Consul Template은 템플릿을 렌더링하기 전에 모든 의존성에 대해 Consul에서 응답을 받을 때까지 기다립니다. 응답이 비어 있지 않을 때까지 기다리는 것은 아닙니다.

참고 (Note)

Once 모드는 구성 파일에 지정되거나 명령줄로 전달된 모든 wait 또는 quiescence 타이머를 암시적으로 비활성화합니다.

중복 제거 모드 (De-Duplication Mode)

Consul Template은 템플릿을 구문 분석하여 어떤 데이터가 필요한지 결정한 다음, 해당 데이터의 변경 사항을 위해 Consul을 감시하는 방식으로 작동합니다. 이 프로세스를 통해 Consul Template은 변경이 발생할 때 템플릿을 효율적으로 다시 렌더링할 수 있습니다. 그러나 공통 템플릿을 렌더링하는 많은 Consul Template 인스턴스가 있으면 각 인스턴스가 동일한 데이터를 쿼리하므로 선형적인 작업 중복이 발생할 수 있습니다.

이 패턴을 더 효율적으로 만들기 위해 Consul Template은 인스턴스 간 작업 중복 제거를 지원합니다. -dedup 플래그 또는 최상위 deduplicate 구성 블록으로 이 기능을 활성화할 수 있습니다. 활성화되면 Consul Template은 템플릿별로 리더 선거를 사용하여 단일 노드만 쿼리를 수행하도록 합니다. 결과는 Consul K/V 저장소를 통해 압축된 데이터를 전달하여 동일한 템플릿을 렌더링하는 다른 인스턴스 간에 공유됩니다.

압축된 템플릿에는 Vault 데이터가 저장되지 않는다는 점에 유의하세요. Vault 주변의 ACL은 일반적으로 Consul의 KV 주변의 ACL보다 더 엄격하게 제어되므로, Consul Template은 각 반복마다 Vault에서 비밀을 계속 요청합니다.

중복 제거 모드로 실행할 때는 로컬 템플릿 함수가 올바르게 해석되는 것이 중요합니다.

예를 들어, 다음과 같이 env 헬퍼에 의존하는 로컬 템플릿 함수가 있을 수 있습니다:

{{ key (env "KEY") }}

이 예제의 환경 변수 KEY가 이 템플릿을 중복 제거하는 모든 머신에서 일관되는 것이 중요합니다. 값이 다르면 Consul Template은 템플릿을 해석할 수 없고 템플릿이 성공적으로 렌더링되지 않습니다.

Exec 모드 (Exec Mode)

버전 0.16.0부터 Consul Template은 envconsul과 유사하게 임의의 자식 프로세스를 유지할 수 있습니다.

이 모드는 컨테이너나 Nomad, Kubernetes 같은 스케줄러에서 Consul Template을 실행할 때 가장 유용합니다. 활성화되면 Consul Template은 자식 프로세스의 수명 주기를 생성하고 관리합니다.

Exec 모드에서 Consul Template을 실행하기 위한 구성 옵션은 구성 문서에서 찾을 수 있습니다.

이 모드는 예제를 통해 가장 잘 설명됩니다. 디스크에서 구성 파일을 읽고 해당 구성에서 서버를 생성하는 간단한 애플리케이션을 고려해 보세요.

$ consul-template \
    -template "/tmp/config.ctmpl:/tmp/server.conf" \
    -exec "/bin/my-server -config /tmp/server.conf"

Consul Template이 시작되면 필요한 의존성을 가져와 my-server 바이너리가 사용하는 /tmp/server.conf를 채웁니다. 해당 템플릿이 처음으로 완전히 렌더링된 후 Consul Template은 자식 프로세스를 생성하고 관리합니다. 템플릿 중 하나라도 변경되면 Consul Template은 자식 프로세스에 구성 가능한 reload 신호를 보냅니다. 또한 Consul Template은 수신하는 모든 신호를 자식 프로세스에 프록시합니다. 이를 통해 스케줄러가 프로세스의 수명 주기를 제어할 수 있고 컨테이너 내부에서 실행할 때의 마찰도 줄어듭니다.

명령에 적용되는 것과 동일한 규칙이 여기에도 적용됩니다. 즉, 복잡한 셸 유사 명령을 사용하려면 sh가 PATH에 있는 시스템에서 실행해야 합니다. 이러한 명령은 셸이 모든 셸 구문 분석을 처리하는 sh -c를 사용하여 실행됩니다. 그렇지 않으면 명령이 단일 명령이거나 인수가 있는 목록 형식의 명령이어야 합니다.

참고 (Note)

지원 시스템(*nix, sh 포함)에서는 setpgid 플래그가 실행에 설정되어 모든 신호가 모든 프로세스로 전송되도록 보장합니다.

Exec 모드에는 사용 전에 신중히 고려해야 할 몇 가지 추가 주의 사항이 있습니다:

  • 자식 프로세스가 죽으면 Consul Template 프로세스도 죽습니다. Consul Template은 프로세스를 감독하지 않습니다. 감독은 일반적으로 스케줄러 또는 init 시스템의 책임입니다.
  • 자식 프로세스는 포그라운드에 유지되어야 합니다. 이것은 Consul Template이 프로세스를 관리하고 신호를 보내기 위한 요구 사항입니다.
  • exec 명령은 모든 템플릿이 한 번 이상 렌더링된 후에만 시작됩니다. 단일 Consul Template 프로세스에 여러 템플릿이 있을 수 있으며, 프로세스가 시작되기 전에 모두 렌더링되어야 합니다. 서비스를 성공적으로 시작하려면 프로세스 구성 파일과 개별 사이트 구성을 모두 작성해야 하는 nginx 또는 apache 구성 같은 것을 고려해 보세요.
  • 자식 프로세스가 시작된 후 의존 템플릿의 변경 사항이 있으면 reload 신호가 자식 프로세스로 전송됩니다. reload 신호가 제공되지 않으면 Consul Template은 프로세스를 종료하고 새 인스턴스를 생성합니다. reload 신호는 CLI 또는 구성 파일을 사용하여 지정하고 사용자 지정할 수 있습니다.
  • Consul Template이 정상적으로 중지되면 구성 가능한 kill 신호를 자식 프로세스로 보냅니다. 기본값은 SIGTERM이지만 CLI 또는 구성 파일에서 사용자 지정할 수 있습니다.
  • Consul Template은 정의된 reload_signal 및 kill_signal을 제외하고 수신하는 모든 신호를 자식 프로세스로 전달합니다. 이러한 신호를 비활성화하면 Consul Template이 이를 자식 프로세스로 전달합니다.
  • 각 템플릿에 자체 reload 명령이 있을 수 있지만 exec 명령은 하나만 가질 수 있습니다.
  • 개별 템플릿 reload 명령은 exec 명령과 독립적으로 계속 실행됩니다.

명령 (Commands)

호스트에서 실행할 명령으로 템플릿을 렌더링할 수 있습니다.

환경 (Environment)

명령을 실행할 때 현재 프로세스 환경이 사용되며 추가 환경 변수는 다음과 같습니다:

명령이 실행될 때 이러한 환경 변수는 현재 값으로 내보내집니다. 다른 Consul 도구는 이러한 환경 변수를 읽어 consul maint 또는 consul lock 같은 다른 Consul 도구와의 원활한 통합을 제공합니다. 또한 이러한 환경 변수를 노출하면 고급 사용자가 명령 스크립트를 추가로 사용자 지정할 수 있습니다.

여러 명령 (Multiple Commands)

템플릿 렌더링에서 실행하도록 구성된 명령은 두 가지 형식 중 하나를 취해야 합니다.

첫 번째는 공백으로 구분된 명령과 인수의 목록입니다. 명령은 절대 경로를 사용하거나 실행 환경의 PATH에서 찾을 수 있어야 하며 목록의 첫 번째 항목이어야 합니다. 이 형식은 시스템 호출로 직접 실행할 수 있는 단일 또는 여러 단어 명령을 허용합니다.

예제

command = ["echo", "hello"]
## ...
command = ["/opt/foo-package/bin/run-foo"]
## ...
command = ["foo"]

참고 (Note) 대괄호([])로 표시된 목록 없이 단일 명령을 제공하면 단일 인수가 있는 목록으로 변환됩니다. 예를 들어 command = "foo"는 command = ["foo"]로 변환됩니다.

두 번째는 시스템 셸 기능을 사용하는 단일 따옴표 명령입니다. 이 형식은 실행 파일 검색 경로(예: *nix의 PATH)에 sh라는 셸이 있어야 합니다. 이것은 모든 *nix 시스템의 표준이며 해당 시스템에서는 기본적으로 작동해야 합니다. 예를 들어 Alpine 같은 최소 시스템 없이 실행 파일만 있는 Docker 이미지에서는 작동하지 않습니다. 이 형식을 사용하면 논리 연산자 && 및 ||로 여러 명령을 결합하고, |로 파이프라인을 사용하고, 조건문 등을 사용할 수 있습니다. *nix 시스템에서 셸 sh는 일반적으로 /bin/sh이며 POSIX 셸이거나 POSIX 호환 모드로 실행되는 셸이므로 이 명령에서 POSIX 셸 구문을 고수하는 것이 좋습니다.

예제

command = "/opt/foo && /opt/bar"
##...
command = "if /opt/foo ; then /opt/bar ; fi"

이 방법을 사용하면 필요에 따라 필요한 만큼 많은 셸 명령을 필요한 로직과 함께 실행할 수 있습니다. 너무 길어지면 셸 스크립트로 감싸서 배포하고 실행하는 것을 권장합니다.

셸 명령과 Exec 모드 (Shell Commands and Exec Mode)

시스템 셸 기반 명령을 Exec 모드 프로세스(신호를 전파할 관리 대상 실행 프로세스)에 사용할 때 한 가지 추가 주의 사항이 있습니다. 신호가 올바르게 작동하려면 셸이 실행하는 모든 것이 신호를 처리해야 할 뿐만 아니라 셸 자체도 신호를 처리해야 합니다. 셸은 대부분의 신호를 받으면 종료되므로 이는 사용자가 관리해야 합니다.

일반적인 예제는 SIGHUP 신호가 기본 프로세스의 reload를 트리거하고 셸 프로세스에서 무시되도록 구성하는 것입니다. 두 가지 옵션이 있습니다:

  • trap을 사용하여 신호를 무시합니다.
  • exec를 사용하여 셸을 다른 프로세스로 대체합니다.

trap을 사용하여 신호를 무시하려면 셸에서 trap을 호출하여 작업 없이 신호를 포착합니다. 예를 들어 기본 nginx 프로세스가 있고 셸 명령으로 실행하면서 셸이 HUP 신호를 무시하려면 다음 명령을 사용할 수 있습니다:

command = "trap '' HUP; /usr/sbin/nginx -c /etc/nginx/nginx.conf"

trap '' HUP; 부분은 셸이 HUP 신호를 무시하도록 하기에 충분합니다. trap 명령을 생략하면 nginx가 reload되지만 셸 명령은 종료되고 nginx는 계속 실행되어 관리되지 않은 상태로 남습니다.

대안으로 exec를 사용하면 셸의 프로세스를 하위 프로세스로 대체하여 동일한 PID와 프로세스 그룹을 유지합니다(하위 프로세스를 관리할 수 있게 함). 이것은 trap보다 더 간단하지만 약간 덜 유연하며 다음과 같습니다:

command = "exec /usr/sbin/nginx -c /etc/nginx/nginx.conf"

여기서 nginx 프로세스는 둘러싼 셸 프로세스를 대체하여 신호를 직접 수신하며 consul-template이 관리합니다. 기본적으로 exec는 셸을 방정식에서 제거합니다.

더 구체적인 세부 사항은 셸의 trap 및 exec 문서를 참조하세요.

더 알아보기 (Learn more)