ABOUT ME

-

Today
Yesterday
Total
  • [Helm] 가이드 - values(변수)
    공부/쿠버네티스&헬름 2025. 3. 15. 20:56

    변수

    템플릿에서는 튜플이 자주 사용되지는 않지만 튜플을 사용하여 코드를 단순화하고 withrange를 더 효과적으로 사용하는 방법을 살펴보겠습니다.

      {{- with .Values.favorite }}
      drink: {{ .drink | default "tea" | quote }}
      food: {{ .food | upper | quote }}
      release: {{ .Release.Name }}
      {{- end }}

    Release.Namewith 블록에서 제한된 스코프 내에 있지 않습니다. 스코프 문제를 해결하는 한 가지 방법은 현재 스코프에 관계없이 접근할 수 있는 변수에 객체를 할당하는 것입니다.

    Helm 템플릿에서 변수는 다른 객체에 대한 명명된 참조입니다. $name 형태를 따릅니다. 변수는 특수한 할당 연산자 :=를 사용하여 할당됩니다. 위 코드를 Release.Name에 대한 변수를 사용하도록 다시 작성할 수 있습니다.

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: {{ .Release.Name }}-configmap
    data:
      myvalue: "Hello World"
      {{- $relname := .Release.Name -}}
      {{- with .Values.favorite }}
      drink: {{ .drink | default "tea" | quote }}
      food: {{ .food | upper | quote }}
      release: {{ $relname }}
      {{- end }}
    
    ------------
    # Source: mychart/templates/configmap.yaml
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: viable-badger-configmap
    data:
      myvalue: "Hello World"
      drink: "coffee"
      food: "PIZZA"
      release: viable-badger

    변수는 특히 range 루프에서 유용합니다. 리스트와 유사한 객체에서 인덱스와 값을 모두 캡처하는 데 사용할 수 있습니다.

      toppings: |-
        {{- range $index, $topping := .Values.pizzaToppings }}
          {{ $index }}: {{ $topping }}
        {{- end }}  

    range가 먼저 나오고 그 다음 변수들, 그 다음 할당 연산자, 그리고 리스트가 옵니다. 이렇게 하면 정수 인덱스(0부터 시작)가 $index에 할당되고 값이 $topping에 할당됩니다. 이를 실행하면 다음과 같은 결과가 생성됩니다.

      toppings: |-
          0: mushrooms
          1: cheese
          2: peppers
          3: onions    

    키와 값을 모두 가진 데이터 구조의 경우, range를 사용하여 둘 다 얻을 수 있습니다. 예를 들어, 다음과 같이 .Values.favorite를 루프 처리할 수 있습니다.

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: {{ .Release.Name }}-configmap
    data:
      myvalue: "Hello World"
      {{- range $key, $val := .Values.favorite }}
      {{ $key }}: {{ $val | quote }}
      {{- end }}

    이제 첫 번째 반복에서 $keydrink가 되고 $valcoffee가 되며, 두 번째 반복에서는 $keyfood가 되고 $valpizza가 됩니다. 위 코드를 실행하면 다음과 같은 결과가 생성됩니다.

    # Source: mychart/templates/configmap.yaml
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: eager-rabbit-configmap
    data:
      myvalue: "Hello World"
      drink: "coffee"
      food: "pizza"

    변수는 일반적으로 global이 아닙니다. 변수는 선언된 블록의 스코프 내에서만 유효합니다. 앞서 템플릿의 최상위 레벨에서 $relname을 할당했습니다. 이 변수는 전체 템플릿 범위에서 사용할 수 있습니다. 하지만 마지막 예제에서 $key$val{{ range... }}{{ end }} 블록 내부에서만 유효합니다.

    하지만 항상 루트 컨텍스트를 가리키는 하나의 변수가 있습니다. 바로 $입니다. 이는 range 루프 안에서 차트의 릴리스 이름을 알아야 할 때 매우 유용할 수 있습니다.

    {{- range .Values.tlsSecrets }}
    ---
    apiVersion: v1
    kind: Secret
    metadata:
      name: {{ .name }}
      labels:
        # Many helm templates would use `.` below, but that will not work,
        # however `$` will work here
        app.kubernetes.io/name: {{ template "fullname" $ }}
        # I cannot reference .Chart.Name, but I can do $.Chart.Name
        helm.sh/chart: "{{ $.Chart.Name }}-{{ $.Chart.Version }}"
        app.kubernetes.io/instance: "{{ $.Release.Name }}"
        # Value from appVersion in Chart.yaml
        app.kubernetes.io/version: "{{ $.Chart.AppVersion }}"
        app.kubernetes.io/managed-by: "{{ $.Release.Service }}"
    type: kubernetes.io/tls
    data:
      tls.crt: {{ .certificate }}
      tls.key: {{ .key }}
    {{- end }}

    사용자 정의 변수 (_helpers.tpl)

    Helm 템플릿에서 _helpers.tpl 파일은 사용자 정의 템플릿 함수 또는 재사용 가능한 변수 정의를 위한 컨벤션입니다. 이 파일에 정의된 함수나 변수는 다른 템플릿 파일에서 {{ template }} 액션이나 직접적인 변수 참조를 통해 호출하고 사용할 수 있습니다.

    _helpers.tpl를 사용하면 반복적으로 사용되는 템플릿 로직이나 값을 한 곳에 정의하여 코드 중복을 줄이고 유지보수성을 향상시킵니다. 또한 복잡한 로직을 헬퍼 함수로 분리하여 주요 템플릿 파일의 가독성을 높이고 여러 템플릿에서 동일한 로직이나 변수를 사용하도록 강제하여 일관성을 유지할 수 있습니다.

    _helpers.tpl 파일에 다음과 같이 사용자 정의 변수를 정의할 수 있습니다.

    {{- define "mychart.labels" -}}
    app.kubernetes.io/name: {{ include "mychart.name" . }}
    app.kubernetes.io/instance: {{ .Release.Name }}
    app.kubernetes.io/version: {{ .Chart.AppVersion }}
    helm.sh/chart: {{ include "mychart.chart" . }}
    {{- end -}}
    
    {{- define "mychart.fullname" -}}
    {{- $name := default .Chart.Name .Values.nameOverride -}}
    {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
    {{- end -}}
    
    {{- define "mychart.serviceAccountName" -}}
    {{- default (include "mychart.fullname" .) .Values.serviceAccount.name -}}
    {{- end -}}
    • {{- define "..." -}}{{- end -}}: 이 블록은 명명된 템플릿 정의를 나타냅니다. define 뒤의 문자열은 템플릿의 고유한 이름입니다. 일반적으로 차트 이름으로 시작하고 점(.)으로 구분하여 의미를 명확히 합니다.
    • mychart.labels: 이 템플릿은 애플리케이션에 공통적으로 사용될 레이블들을 정의합니다. include 함수를 사용하여 다른 헬퍼 함수 (mychart.name, mychart.chart)의 결과를 포함합니다. .Release.Name, .Chart.AppVersion과 같은 Helm 내장 객체에 접근하여 값을 가져옵니다.
    • mychart.fullname: 이 템플릿은 애플리케이션의 전체 이름을 생성합니다. .Values.nameOverride 값을 확인하여 사용자 정의 이름을 우선적으로 사용하고, 그렇지 않으면 차트 이름을 사용합니다. printf, trunc, trimSuffix와 같은 템플릿 함수를 사용하여 문자열을 조작합니다.
    • mychart.serviceAccountName: 이 템플릿은 서비스 계정 이름을 결정합니다. .Values.serviceAccount.name 값을 확인하여 사용자 정의 이름을 사용하고, 그렇지 않으면 mychart.fullname 헬퍼 함수의 결과를 기본값으로 사용합니다.

    이렇게 정의한 내용을 deployment.yaml 파일에서 _helpers.tpl에 정의된 mychart.labels 템플릿을 사용하여 파드 템플릿의 레이블을 정의할 수 있습니다.

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: {{ include "mychart.fullname" . }}
      labels:
        {{- include "mychart.labels" . | nindent 4 }}
    spec:
      replicas: {{ .Values.replicaCount }}
      selector:
        matchLabels:
          app.kubernetes.io/name: {{ include "mychart.name" . }}
          app.kubernetes.io/instance: {{ .Release.Name }}
      template:
        metadata:
          labels:
            {{- include "mychart.labels" . | nindent 8 }}
        spec:
          serviceAccountName: {{ include "mychart.serviceAccountName" . }}
          containers:
            - name: {{ .Chart.Name }}
              image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
              ports:
                - name: http
                  containerPort: 8080
                  protocol: TCP
    • {{ include "mychart.labels" . | nindent 4 }}: include 함수를 사용하여 mychart.labels 템플릿의 내용을 현재 컨텍스트(.)와 함께 삽입합니다. 파이프라인(|)을 통해 nindent 4 함수로 전달하여 각 줄을 4칸 들여씁니다.
    • {{ include "mychart.fullname" . }}{{ include "mychart.serviceAccountName" . }}: 마찬가지로 include 함수를 사용하여 다른 헬퍼 함수를 호출하고 그 결과를 사용합니다.

    파일명 규칙

    사용자 정의 템플릿 함수(헬퍼 함수)를 정의하는 파일명에 엄격한 규칙은 없지만 _helpers.tpl 이라는 파일명을 사용하는 것은 업계 표준이자 관례입니다.

    _helpers.tpl이라는 이름은 이 파일이 주요 템플릿 파일이 아닌, 재사용 가능한 헬퍼 함수들을 정의하는 곳임을 명확하게 나타며 Helm은 templates 디렉토리 내의 모든 .yaml, .yml, .tpl 확장자를 가진 파일을 템플릿으로 처리합니다. _helpers.tpl 또한 이 규칙에 따라 자동으로 로딩되어 다른 템플릿에서 사용할 수 있게 됩니다. 또한 대부분의 Helm 차트 개발자들이 _helpers.tpl을 헬퍼 함수를 위한 표준 파일명으로 인식하고 있기 때문에, 다른 사람의 코드를 이해하고 협업하는 데 도움이 됩니다.

    기술적으로는 templates 디렉토리 내에 .tpl 확장자를 가진 어떤 파일명이라도 사용하여 사용자 정의 함수를 정의할 수 있습니다. 예를 들어 my-functions.tpl 또는 utils.tpl과 같은 이름을 사용할 수도 있습니다.

    동일한 이름의 함수가 존재할 때

    동일한 이름의 함수가 존재할 때, 나중에 로딩된 파일에 정의된 함수가 먼저 로딩된 함수의 정의를 덮어쓰게 됩니다.

    Helm은 templates 디렉토리 내의 .tpl 파일을 포함한 모든 템플릿 파일을 특정 순서로 로딩합니다. 이 로딩 순서는 파일 시스템의 순서에 따라 결정되며, 정확한 순서를 예측하기는 어려울 수 있습니다. 일반적으로 알파벳 순서로 로딩될 가능성이 높지만, 항상 보장되는 것은 아닙니다. Helm은 템플릿 함수 이름의 중복을 명시적으로 감지하거나 오류를 발생시키지 않습니다. 동일한 이름의 템플릿 함수가 여러 파일에서 정의된 경우, Helm은 파일을 로딩하는 과정에서 나중에 로딩된 파일의 정의로 이전 정의를 묵시적으로 덮어쓰므로 템플릿이 렌더링될 때 해당 이름의 함수가 호출되면, 가장 마지막에 로딩된 파일에 정의된 함수가 실행됩니다.

    따라서 템플릿 함수의 이름을 고유하게 관리하는 것이 중요합니다.

    사용자 정의 함수(_helper.tpl)와 values.yaml 차이

    _helpers.tpl은 프로그래밍 언어의 함수 또는 메서드와 유사합니다. 특정 작업을 수행하는 코드 블록이며 필요할 때 호출하여 결과를 얻습니다.

    values.yaml은 프로그래밍 언어의 설정 파일 또는 환경 변수와 유사합니다. 프로그램의 동작 방식을 제어하는 데이터이며, 프로그램 실행 중에 참조됩니다.

    특징 _helpers.tpl (사용자 정의 함수) values.yaml (설정 값)
    주요 목적 재사용 가능한 템플릿 로직 정의 차트의 설정 값 정의 및 관리
    내용 템플릿 함수 정의 (Helm 템플릿 문법) YAML 형식의 설정 데이터 (키-값 쌍)
    사용 방식 {{ include }} 또는 {{ template }}로 호출 .Values.키 형태로 접근
    성격 실행 가능한 코드 조각 정적인 설정 데이터
    역할 템플릿 로직 단순화, 코드 재사용 차트 구성 유연성 제공, 환경별 설정

    _helpers.tpl은 템플릿의 행동을 정의하는 데 사용되는 반면, values.yaml은 템플릿의 데이터를 제공하는 데 사용됩니다. 이 두 파일은 Helm 차트의 유연성과 관리 용이성을 높이는 데 필수적인 역할을 합니다.

    레퍼런스

    https://helm.sh/docs/chart_template_guide/variables/

    댓글