템플릿 함수와 파이프라인
템플릿 함수와 파이프라인 (Template Functions and Pipelines)
이 문서는 Helm 템플릿에서 함수와 파이프라인을 사용해 데이터를 변환하는 방법을 다뤄요. quote, upper, repeat, join, default 함수와 lookup 함수, 연산자 함수를 설명해요.
출처: 문서
본문
⚠️ 이 페이지는 아직 Helm 4용으로 업데이트되지 않았어요. 일부 내용이 부정확하거나 Helm 4에 적용되지 않을 수 있어요. Helm 4의 새 기능, 개선 사항, 호환성 깨짐 변경에 대한 자세한 내용은 Helm 4 개요를 참조하세요.
지금까지 정보를 템플릿에 배치하는 방법을 봤어요. 하지만 그 정보는 수정되지 않은 채 템플릿에 배치돼요. 때로는 제공된 데이터를 우리에게 더 유용하게 만드는 방식으로 변환하고 싶을 수 있어요.
모범 사례부터 시작할게요: .Values 객체의 문자열을 템플릿에 주입할 때는 그 문자열을 따옴표로 감싸야 해요. 템플릿 지시문에서 quote 함수를 호출하면 그렇게 할 수 있어요:
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: "Hello World"
drink: {{ quote .Values.favorite.drink }}
food: {{ quote .Values.favorite.food }}
템플릿 함수는 functionName arg1 arg2... 구문을 따라요. 위 스니펫에서 quote .Values.favorite.drink는 quote 함수를 호출하고 단일 인자를 전달해요.
Helm에는 60개 이상의 함수가 있어요. 그중 일부는 Go 템플릿 언어 자체에서 정의돼요. 나머지 대부분은 Sprig 템플릿 라이브러리의 일부예요. 예시를 진행하면서 그중 많은 함수를 보게 될 거예요.
"Helm 템플릿 언어"를 Helm 전용인 것처럼 말하지만, 실제로는 Go 템플릿 언어와 몇 가지 추가 함수, 그리고 특정 객체를 템플릿에 노출하는 다양한 래퍼의 결합이에요. Go 템플릿에 대한 많은 자료가 템플릿을 배우는 데 도움이 될 수 있어요.
파이프라인 (Pipelines)
템플릿 언어의 강력한 기능 중 하나는 파이프라인의 개념이에요. UNIX에서 온 개념을 활용해, 파이프라인은 일련의 변환을 간결하게 표현하기 위해 일련의 템플릿 명령을 연결하는 도구예요. 즉, 파이프라인은 여러 작업을 순서대로 효율적으로 수행하는 방법이에요. 위 예시를 파이프라인을 사용해 다시 써 봐요.
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: "Hello World"
drink: {{ .Values.favorite.drink | quote }}
food: {{ .Values.favorite.food | quote }}
이 예시에서는 quote ARGUMENT를 호출하는 대신 순서를 뒤집었어요. 파이프라인(|)으로 인자를 함수에 "보냈어요": .Values.favorite.drink | quote. 파이프라인을 사용하면 여러 함수를 함께 연결할 수 있어요:
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: "Hello World"
drink: {{ .Values.favorite.drink | quote }}
food: {{ .Values.favorite.food | upper | quote }}
순서를 뒤집는 것은 템플릿에서 흔한 관행이에요. quote .val보다 .val | quote를 더 자주 보게 될 거예요. 두 관행 모두 괜찮아요.
평가되면 그 템플릿은 다음을 생성해요:
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: trendsetting-p-configmap
data:
myvalue: "Hello World"
drink: "coffee"
food: "PIZZA"
원래의 pizza가 이제 "PIZZA"로 변환된 것에 주목하세요.
이렇게 인자를 파이프라인할 때 첫 번째 평가(.Values.favorite.drink)의 결과가 함수의 마지막 인자로 전송돼요. 두 인자를 취하는 repeat COUNT STRING 함수로 위 drink 예시를 수정해 설명할 수 있어요:
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: "Hello World"
drink: {{ .Values.favorite.drink | repeat 5 | quote }}
food: {{ .Values.favorite.food | upper | quote }}
repeat 함수는 주어진 문자열을 주어진 횟수만큼 반복하므로 다음을 출력으로 얻어요:
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: melting-porcup-configmap
data:
myvalue: "Hello World"
drink: "coffeecoffeecoffeecoffeecoffee"
food: "PIZZA"
파이프라인은 리스트로 작업할 때도 유용해요. 예를 들어 join 함수는 문자열 리스트를 구분자로 단일 문자열로 결합할 수 있어요:
favorite:
drinks:
- coffee
- tea
- water
drinks: {{ .Values.favorite.drinks | join ", " | quote }}
위 코드는 다음을 생성해요:
drinks: "coffee, tea, water"
default 함수 사용하기 (Using the default function)
템플릿에서 자주 사용되는 함수 중 하나는 default 함수예요: default DEFAULT_VALUE GIVEN_VALUE. 이 함수는 값이 생략된 경우를 대비해 템플릿 안에서 기본값을 지정할 수 있게 해줘요. 위 drink 예시를 수정하는 데 사용해 봐요:
drink: {{ .Values.favorite.drink | default "tea" | quote }}
이것을 정상적으로 실행하면 우리의 coffee를 얻을 거예요:
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: virtuous-mink-configmap
data:
myvalue: "Hello World"
drink: "coffee"
food: "PIZZA"
이제 values.yaml에서 favorite drink 설정을 제거할게요:
favorite:
#drink: coffee
food: pizza
이제 helm install --dry-run --debug fair-worm ./mychart를 다시 실행하면 다음 YAML이 생성돼요:
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: fair-worm-configmap
data:
myvalue: "Hello World"
drink: "tea"
food: "PIZZA"
실제 차트에서는 모든 정적 기본값이 values.yaml에 있어야 하며 default 명령을 사용해 반복해서는 안 돼요 (그렇지 않으면 중복이 돼요). 하지만 default 명령은 values.yaml 안에서 선언할 수 없는 계산된 값에 완벽해요. 예를 들어:
drink: {{ .Values.favorite.drink | default (printf "%s-tea" (include "fullname" .)) }}
어떤 곳에서는 default보다 if 조건 가드가 더 적합할 수 있어요. 다음 섹션에서 그것들을 볼 거예요.
템플릿 함수와 파이프라인은 정보를 변환한 다음 YAML에 삽입하는 강력한 방법이에요. 하지만 때로는 단순히 문자열을 삽입하는 것보다 더 정교한 템플릿 로직을 추가하는 것이 필요할 때도 있어요. 다음 섹션에서 템플릿 언어가 제공하는 제어 구조를 살펴볼 거예요.
lookup 함수 사용하기 (Using the lookup function)
lookup 함수는 실행 중인 클러스터의 리소스를 조회하는 데 사용할 수 있어요. lookup 함수의 요지는 lookup apiVersion, kind, namespace, name -> resource or resource list예요.
| 매개변수 | 타입 |
|---|---|
| apiVersion | string |
| kind | string |
| namespace | string |
| name | string |
name과 namespace는 둘 다 선택 사항이며 빈 문자열("")로 전달할 수 있어요. 하지만 네임스페이스 범위 리소스로 작업하는 경우 name과 namespace를 모두 지정해야 해요.
다음과 같은 매개변수 조합이 가능해요:
| 동작 | Lookup 함수 |
|---|---|
| kubectl get pod mypod -n mynamespace | lookup "v1" "Pod" "mynamespace" "mypod" |
| kubectl get pods -n mynamespace | lookup "v1" "Pod" "mynamespace" "" |
| kubectl get pods --all-namespaces | lookup "v1" "Pod" "" "" |
| kubectl get namespace mynamespace | lookup "v1" "Namespace" "" "mynamespace" |
| kubectl get namespaces | lookup "v1" "Namespace" "" "" |
lookup이 객체를 반환하면 딕셔너리를 반환해요. 이 딕셔너리는 특정 값을 추출하기 위해 더 탐색할 수 있어요.
다음 예시는 mynamespace 객체에 존재하는 어노테이션을 반환해요:
(lookup "v1" "Namespace" "" "mynamespace").metadata.annotations
lookup이 객체 목록을 반환하면 items 필드를 통해 객체 목록에 접근할 수 있어요:
{{ range $index, $service := (lookup "v1" "Service" "mynamespace" "").items }}
{{/* 각 서비스로 무언가 하기 */}}
{{ end }}
객체가 발견되지 않으면 빈 값이 반환돼요. 이것으로 객체의 존재를 확인할 수 있어요.
lookup 함수는 Helm의 기존 Kubernetes 연결 구성을 사용해 Kubernetes를 조회해요. API 서버와 상호작용할 때 어떤 오류가 반환되면 (예: 리소스에 접근할 권한이 없어서) Helm의 템플릿 처리가 실패해요.
Helm은 helm template|install|upgrade|delete|rollback --dry-run 작업 중에는 Kubernetes API 서버에 접촉하지 않아야 한다는 점을 기억하세요. 실행 중인 클러스터를 대상으로 lookup을 테스트하려면 클러스터 연결을 허용하는 helm template|install|upgrade|delete|rollback --dry-run=server를 대신 사용해야 해요.
연산자는 함수예요 (Operators are functions)
템플릿에서 연산자(eq, ne, lt, gt, and, or 등)는 모두 함수로 구현돼요. 파이프라인에서 작업은 괄호((, ))로 그룹화할 수 있어요.
이제 함수와 파이프라인에서 조건, 루프, 범위 수정자가 있는 흐름 제어로 넘어갈 수 있어요.