k8s - 헬름 차트 문법!
차트 문법
차트는 values.yaml, Chart.yaml, template 으로 구성되는데template 폴더에는 위에서 말한것 처럼 deployment.yaml 파일뿐 아니라 k8s 어플리케이션 배포에 필요한 Service, ConfigMap 등 다양한 리소스가 정의된 yaml 파일이 정의되어 있다.
Chart객체의 경우apiVersion: v2,name: mychart이런식으로 정의되어 있다 하더라도 시작 문자가 대문자여야 한다.Chart.AppVersion,Chart.Version
1 | apiVersion: v1 |
출력 결과는 아래와 같다.
1 | helm install mychart . -n default |
Release 객체는 인스턴스의 정보를 가지며 아래 6가지 객체를 가지고 있음
Release.Name: 릴리스 이름Release.Namespace: 릴리스될 네임스페이스 (manifest에서 오버라이드하지 않은 경우)Release.IsUpgrade: 현재 작업이 업그레이드 또는 롤백인 경우 true 로 설정된다.Release.IsInstall: 현재 작업이 설치일 경우 true 로 설정.Release.Revision: 이 릴리스의 리비전 번호. 설치시에는 이 값이 1이며 업그레이드나 롤백을 수행할 때마다 증가한다.Release.Service: 현재 템플릿을 렌더링하는 서비스. Helm 에서는 항상 Helm 이다.
values.yaml
1 | {{ .Values.replicaCount }} |
변수삽입 문법을 사용하여 values.yaml 파일안의 값들을 template 폴더안의 각종 리소스의 변수로 지정할 수 있다.
일반적으로 dev, prod 2개의 환경으로 자주 운영하며
values_dev.yamlvalues_prod.yaml
위와같이 value 파일을 나누어서 운영한다.-f, -set 옵션을 사용하여 values 의 변수 우선순위를 지정할 수 있다.
1 | helm install mychart . -f values_dev.yaml -set configMapData.log.level=debug |
values 우선순위
-set [key=value]->-f [yaml file]->values.yaml
우측으로 갈수록 우선순위가 낮다.values.yaml위에value_dev.yaml을 덮어씌우고,-set속성으로 정의한key-value를 덮어씌우는 형식
template
template 폴더안에 deployment.yaml, service.yaml 파일을 보면
각종 조건문, 함수, 파이프라인 구문이 존재한다.
해당 구분 문법에 대해 알아본다.
function & pipeline
1 | # values.yaml |
위와같은 values 파일이 있을때 아래와 같이 quote, upper 함수를 사용하여 변환된 문자열로 출력할 수 있다.
1 | {{ quote .Values.func.enabled }} # "true" |
upper 는 입력받은 문자열을 대문자로quote 는 입력받은 자료형에 "" 를 씌어 문자열로 반환한다.
yaml문법상 문자열에""가 별도로 필요하지 않으나 가독성을 위해 사용하는 것은 권장한다.
if, else if, else, end
1 | {{ if 조건문 }} |
조건문에서 사용할만한 함수는 다음과 같다.and, or, ne, not, eq, ge, le, lt, default, empty
if 문에서 false 로 판단하는 자료형 값은 다음과 같다.
1 | Null |
1 | # values.yaml |
위 파일이 있을때 아래와 같이 if 문을 사용해 속성값을 분기처리할 수 있다.
1 | print: |
typeis
if 문에서 객체 type 을 체크하는데 사용하는 함수
1 | # values.yaml |
1 | {{- if typeis 'string' .Values.v1 }} |
주의사항은
String,Boolean이 아닌string,bool이라는 것
공백, 개행 삭제
구문 시작시 - 가 들어가는 이유는 구문이 있는부분에 공백, 개행 이 들어가기 때문
만약 - 를 넣지 않을경우 아래와 같이 출력된다.
1 | print: |
yaml 특성상 앞에 들여쓰기 공백으로 인해 오류가 발생할 수 있음으로 자주 사용한다.
with + 지역변수
부모객체를 가져와 지역변수처럼 사용하는 개념으로
변수명이 복잡하거나 객체의 depth 가 깊을경우 가독성처리를 위해 사용한다.
1 | {{- with .Values.dev }} |
with 의 단점은 scope(.)를 통한 변수참조가 with 에 정의된 객체안에서만 참조 가능하다는 점
외부 객체 참조 불가 문제를 해결하기 위해 지역변수 문법이 있다.
지역변수는 $ 키워드를 사용하여 scope 에 영향을 받지 않기 때문에
내부에서 밖에 정의해둔 변수를 참조할 수 있다.
1 | {{ $locname := .Relase.Name }} |
range + 지역변수
반복문 역할을 하는 함수
1 | # values.yaml |
위와같이 리스트 객체를 정의해 놓았을 때 아래와 같이 사용 가능하다.
1 | range: |
range 에 개별편의를 위해 자체적인 지역변수 를 제공하는데.
1 | # value.yaml |
위와같은 파일이 있을 때 아래처럼 리스트나 맵 형식의 객체에서range 와 지역변수 문법을 사용하면 $index, $key, $value 지역변수를 사용해 반복문 처리를 쉽게 할 수 있다.
1 | range: |
print, printf
타 언어의 print 함수와 똑같다.단순 문자열, 포멧 문자열을 출력할 수 있다.
1 | # values.yaml |
1 | test: {{ print "hello world" }} # hello world |
tenary - 삼항연산자
tenary 함수와 파이프라인을 같이 사용하여 삼항연산자처럼 사용할 수 있다.파이프라인으로부터 넘어온 값이 true 면 첫번째 인자를, false 면 두번째 인자를 출력한다.
1 | # values.yaml |
1 | case1: {{ .Values.case.v1 | tenary "1" "2" }} # "1" |
default
파이프라인으로 넘어온 값이 false 라면 default 의 인자값을 출력한다.
1 | # values.yaml |
1 | data: {{ .Values.v1 | default "hello" }} # hello |
공백문자열은 false 로 취급하기 때문에 default 의 "hello" 인자값을 출력한다.
위에서 다루었던 조건문이 판단하는
false자료형을 참고하여 효율적으로 사용가능
coalesce
다중인자를 가지는 함수로 Null 이 아닌 가장 앞의 인자를 반환하는 함수
1 | # values.yaml |
위와같은 values 파일이 있을때 아래와 같이 coalesce 를 사용할 수 있다.
1 | c1: {{ coalesce .Values.d1 .Values.d2 "text" }} # text |
required
helm 명령을 통해 랜더링할 때 객체에 대한 정보가 없을경우 랜더링을 멈추고 에러를 반환시키고 싶다면 required 함수를 사용
1 | {{ required "A valid foo is required!" .Values.foo }} |
toYaml, indent, nindent
values 에 정의된 객체를 yaml 에 붙여넣는것은 생각보다 불친절하다.
1 | # values.yaml |
일단 바로 해당 객체를 바로 yaml 에 삽입할 수 없고 toYaml 함수를 거쳐 컨버팅을 해야한다.
1 | my: |
컨버팅후 삽입해도 에러가 나는데
아래와 같이 구성되기 때문이다.
1 | my: |
리스트 요소 앞에 공백 4개로 들여쓰기를 지정해야 하기에 아래처럼 수정해야 한다.
1 | my: |
하지만 구문앞에 띄어쓰기가 하나도 없어 yaml 가독성이 안좋아지기 때문에nindent (new line+indent) 를 사용을 권장한다.
1 | my: |
앞의 - 가 공백 뿐 아니라 개행까지 없애주기 때문에 구문이 어디에 위치해 있던지 상관없다.
randAlphaNum, randAlpha, randNumeric, randAscii
랜덤한 문자열을 출력하기 위한 함수
1 | r1: {{ randAlphaNum 5 }} # 0ad2v # 0-9a-zA-Z |
trim, trimePrefix, trimSuffix
문자열 앞의 공백, prefix, suffix 를 생략해주는 함수
1 | t1: {{ time " hello " }} # hello |
trunc, replace, contains, b64enc
문자열 조작을 위한 함수
1 | s1: {{ trunc 5 "hello world" }} # "hello" |
dict, get
dict 함수를 사용하면 dictionary 기능을 하는 객체를 생성 가능하다.key 기반으로 value 를 가져오려면 get 함수 사용
1 | {{- $myDict := dict "key1" "value1" "key2" "value2"}} |
split, splitList, join
split 문자열을 잘라 맵 객체로 만드는 함수splitList 문자열을 잘라 배열 객체로 만드는 함수join 배열을 문자열로 붙이는 함수
1 | {{- $map := split "/" "test/common/word" }} |
first, rest, last
리스트 내부 요소는 first, rest, last 함수로 접근할 수 있다.rest 는 first 를 제외한 요소 리스트를 반환한다(last 포함).
1 | {{- $list := splitList "/" "test/common/word" }} |
index
리스트객체나 맵객체에서 index 함수를 사용하면 인덱스값이나 키값을 사용하여 내부 요소를 가져올수 있다.
1 | colors: |
위와같은 value 파일이 있을경우 아래와 같이 index 함수 사용 가능
1 | colors: {{ index .Values.colors 0 }} # blue |
사실
.Values.my.name.first으로 바로 접근이 가능하지만 특수한 상황에서 index 함수 사용 가능
regexMatch
정규표현식 체크 함수
1 | match1: {{ regexMatch ".*\\.ya?ml$" "config.yaml" }} # true |
include
include 는 정의한 템플릿을 가져오기위해 사용하는 함수로
첫번째 인자에는 가져오고싶은 템플릿 이름
두번째 인자에는 해당 템플릿에 적용할 객체를 넣는다.(만약 적용할 객체가 없다면 . 사용)
1 | include1: {{ include "mychart.include" (dict "key1" "value1") | indent2 }} |
mychart.include 템플릿에 dict 객체를 넘겨서 가져온다.
1 | # _helper.tpl |
만약 템플릿이 위 같이 정의되어 있다면 include1 은 아래와 같은 구조를 가지게 된다.
1 | include1: |
tpl
템플릿 구문을 해석하는 함수, 템플릿 구문 문자열을 스크립트로 실행한 결과를 반환해준다.
values.yaml 에는 템플릿 구문을 사용하지 못한다.
1 | # values.yaml |
1 | t1: {{ .Values.template }} # "{{ .Values.name }}" |
values.yaml 에 정의된 템플릿 구문을 그대로 출력해버린다.
하지만 템플릿 문자열을 해석하는 tpl 함수를 사용하면 템플릿 구문 문자열 을 번역, 실행한 결과를 반환해준다.
사용자 정의 객체 _helpers.tpl
사용자가 직접 객체를 정의하려면 template/_helpers.tpl (template 확장자) 에 정의하면 된다.define 으로 시작해서 end 로 끝난다.
1 | {{/* |
values.yaml 의 nameOverride 이 공백이기 때문에 .Chart.Name 객체를 사용, 쿠버네티스 최대 문자열 길이 63, 그리고 마지막 "-" 문자열을 삭제한다는 내용이다.mychart.name 애는 Chart.yaml 파일에 따라 mychart 문자열로 초기화된다.
1 | {{/* |
mychart.labels 는 여러줄의 yaml 형식의 문자열로 초기화된다.
define 구문 안에 include 를 삽입해서 아래 정의해두었던 mychart.selectorLabels 객체를 그대로 가져오고 기타 속성들을 .Chart, .Release 객체에서 가져온다.
향후 helm template mychart . 명령어로 service리소스에서 사용하는 mychart.labels 객체를 확인해보면 아래와 같이 출력된다.
1 | helm.sh/chart: mychart |
template/service.yaml 파일에서 _helpers.tpl 에 정의된 객체를 사용하는 방식,
최종적으로 출력된 service.yaml 은 아래 참고
1 | apiVersion: v1 |