요약

SUMMARY

MSA 솔루션을 표준화된 방식으로 배포하려고 Helm 차트 템플릿을 비교했고, Helmet 라이브러리 차트를 감싼 래퍼 차트 구조로 정했다. Bitnami보다 설정이 간결하고 라이선스가 자유롭다는 점이 결정적이었다.

1. 개요

회사 솔루션을 Helm 패키징하려면 공통 포맷이 필요했다. 솔루션이 MSA(Microservices Architecture)라 부서마다 따로 개발하는데, 공통 틀을 안 잡아두면 배포 방식이 부서 수만큼 갈라질 게 뻔했기 때문이다.

2. 선정 배경

공통으로 필요한 Kubernetes 리소스

Manifest 기준으로 이 정도는 거의 매번 필요하다고 봤다.

  • Deployment
  • StatefulSet
  • ConfigMap
  • Secret
  • PVC
  • Service

values.yaml에 미리 있으면 하는 항목

  • fullnameOverride
  • image
  • replicaCount
  • config
  • nodeSelector
  • podAntiAffinity
  • livenessProbe, readinessProbe, startupProbe
  • resources
  • podSecurityContext, containerSecurityContext
  • service
  • persistence

서비스마다 같은 구조의 차트를 쓰되, 서비스별 특성에 맞는 커스터마이징은 열어둬야 했다. 이 둘을 동시에 만족하는 게 관건이었다.

3. 비교

Bitnami 차트

예전에 Bitnami 차트를 많이 써봤는데 쿠버네티스 버전 대응이나 리소스 커버리지가 만족스러웠던 기억이 있어, 차트 템플릿부터 봤다. 실제로 필요에 맞게 커스텀하고 스크립트도 짜봤지만 결국 접었다. 이유는 둘이다.

  • 기능이 너무 많다. 바꿔 말하면 복잡하다.
  • 리포지토리 라이선스가 Apache-2.0이라, 솔루션 차트 프로젝트에 라이선스와 수정 사항을 명시해야 한다.

Helmet 라이브러리 차트

그러다 만난 게 Helmet이라는 차트다. Helm의 라이브러리 차트(Library Chart)(Helm 3에서 도입됐다고 한다)를 이용해, 필요한 리소스만 values에 정의하면 되는 방식이었다.

사용 방식

Helmet을 서브차트로 등록하고 템플릿에서 아래 한 줄만 부르면 된다.

{{ include "helmet.app" . }}

나머지는 values.yaml에서 채운다.

helmet.app 내부 구조

helmet.app은 이렇게 정의돼 있다. values에 값이 있는 리소스만 조건부로 생성하는 구조라, 정의한 것만 렌더된다.

{{- define "helmet.app" -}}
{{- if .Values.configMap.data }}
{{ include "helmet.configmap" . }}
{{- end }}
 
{{- if .Values.image.repository }}
{{ include "helmet.deployment" . }}
{{- end }}
 
{{ include "helmet.persistence" . }}
{{ include "helmet.hpa" . }}
{{ include "helmet.ingress" . }}
 
{{- if or .Values.secret.data .Values.secret.stringData }}
{{ include "helmet.secret" . }}
{{- end }}
 
{{ include "helmet.tls.secrets" . }}
{{ include "helmet.tls.selfsigned" . }}
 
{{- if and .Values.ports .Values.service.ports }}
{{ include "helmet.service" . }}
{{- end }}
 
{{ include "helmet.serviceaccount" . }}
{{ include "helmet.servicemonitor" . }}
{{ include "helmet.cronjob" . }}
{{ include "helmet.podmonitor" . }}
{{- end }}

두 차트 비교

항목Bitnami 차트Helmet 차트
복잡도높음 (기능이 다양함)낮음 (필요한 것만 선택)
values.yaml 크기크고 복잡간결
라이선스 제약Apache-2.0 (고지 의무)비교적 자유로움
커스터마이징제한적유연
학습 곡선가파름완만
유지보수성복잡단순

Bitnami는 기능이 풍부한 게 오히려 오버스펙이었고, 라이선스 고지 의무도 부담스러웠다. 이번 용도에는 Helmet 쪽이 맞았다.

Helmet의 단점과 보완

물론 Helmet도 아쉬운 게 있었다.

  • StatefulSet을 지원하지 않는다.
  • Bitnami의 extraList처럼 차트에 정의되지 않은 리소스를 끼워 넣을 수 없다 (CR을 따로 배포해야 하는 경우 등에 대비).

그래서 Helmet을 래핑(Wrapping)하는 차트를 만들어 이 부분을 채웠다. 최종 구성은 이렇게 됐다.

Application Chart → Helmet Wrapper Chart → Helmet → (Bitnami Common Chart)

4. 선정 사유

이 구조로 간 이유는 이렇다.

  1. 간결성: values.yaml에 필요한 것만 담아 짧아진다.
  2. 선택적 리소스 생성: 정의 안 한 리소스는 안 만들어진다.
  3. 라이선스 자유도: 서브차트 의존성만 걸면 되니 별도 고지가 필요 없다.
  4. 확장성: 래퍼 차트로 StatefulSet과 추가 리소스를 얹을 수 있다.
  5. 표준화: 모든 MSA 서비스가 같은 구조를 쓴다.

구성 자체는 좀 복잡해졌지만, 개발팀 편의성과 배포 표준화를 생각하면 남는 장사라고 봤다.

참고