Kubernetes cluster 를 생성하고, 사용자의 Application 을 설치하기 전 몇가지 plug-in/middleware 를 설치 해야 합니다. 예를 들면.. cert-manager, nginx-ingress, metrics-server, prometheus, grafana 같은 것들이 있습니다.
이것들을 설치하기 위해서는 여러 방법이 있지만 Helm Chart 로 설치 하는 것이 가장 빠르고, 쉽다고 생각 합니다.
하지만,
- 설치하는 환경마다 변수 관리를 해야 합니다.
- CRD/CR 를 먼저 설치 해야 하는 경우도 있습니다.
- Chart 마다 Dependency 가 있어서 순서가 필요할 수 있습니다.
- 그리고 이 모든것을 위하여 IaC 가 필요 합니다.
이것을 해결 할 수 있는 Tool 이 helmfile 입니다.
장점
- 설치 Environment 마다 변수를 Code 에 관리할 수 있습니다.
- Chart 가 설치 되는 동안 대기할 수 있습니다.
- Hook 을 통해 Chart 를 설치 하기전 특정 작업을 수행할 수 있습니다. (CRD 설치 등)
- 세트를 구성하여 여러 Chart 를 한번에 설치/관리가 가능 합니다.
- apply 명령을 통해 변경된 경우에만 적용할 수 있습니다.
Tool 설치
Mac 을 예로 들겠습니다.
kubectl
, helm
, helmfile
을 설치 합니다.
AWS Cloud 에 배포 할 경우 awscli
를 설치 합니다.
기존 설치 되었던 chart 와 비교를 위해 helm-diff
plug-in 을 설치 합니다.
brew install kubernetes-cli
brew install helm
brew install helmfile
pip install --upgrade --user awscli
helm plugin install https://github.com/databus23/helm-diff --version master
helmfile
cert-manager
를 예를 틀어 보겠습니다.
(이미 Kubernetes cluster 가 생성되어 있고, 권한이 있다고 가정 합니다.)
다음과 같은 구조로 파일을 생성 합니다.
.
├── helmfiles.yaml
├── environments
│ ├── default.yaml
│ ├── eks-demo.yaml
├── releases
│ ├── cert-manager.yaml
│ ├── cert-manager.yaml.gotmpl
│ ├── cert-manager-issuers.yaml.gotmpl
helmfiles.yaml
메인 파일 입니다. environments, helmfiles 를 정의 합니다.
environments:
default:
values:
- environments/default.yaml
eks-demo:
values:
- environments/eks-demo.yaml
helmfiles:
- releases/cert-manager.yaml
default.yaml
environments 를 정의 하지 않았을때 적용 될 환경 파일 입니다.
demo-env.yaml
demo-env
라는 Cluster 에 적용할 환경 파일 입니다.
cert-manager:
issuer-email: my@domain.com
cert-manager.yaml
helm repository 로 jetstack
, incubator
를 등록 합니다.
environments 은 default
, eks-demo
를 등록 합니다.
releases 에 chart 정보를 입력 합니다.
Hook 을 통해 cert-manager 를 생성하기 전 kubectl apply -f ../00-crds.yaml
을 실행 합니다.
cert-manager.yaml.gotmpl
를 values 로 사용하여 jetstack/cert-manager
를 생성 합니다.
cert-manager-issuers.yaml.gotmpl
를 values 로 사용하여 ClusterIssuer
를 생성 합니다.
repositories:
- name: jetstack
url: https://charts.jetstack.io
- name: incubator
url: https://kubernetes-charts-incubator.storage.googleapis.com
environments:
default:
values:
- ../../environments/default.yaml
eks-demo:
values:
- ../../environments/eks-demo.yaml
releases:
- name: cert-manager
namespace: kube-ingress
chart: jetstack/cert-manager
version: ~v0.13.0
installed: true
wait: true
hooks:
- events: ["presync"]
showlogs: true
command: "/bin/sh"
args:
- -c
- kubectl apply --validate=false -f https://raw.githubusercontent.com/jetstack/cert-manager/release-0.13/deploy/manifests/00-crds.yaml
values:
- cert-manager.yaml.gotmpl
- name: cert-manager-issuers
namespace: kube-ingress
chart: incubator/raw
version: ~0.1.0
installed: true
# wait: true
# force: true
# recreatePods: true
values:
- cert-manager-issuers.yaml.gotmpl
cert-manager.yaml.gotmpl
nameOverride: cert-manager
rbac:
create: true
ingressShim:
defaultIssuerName: letsencrypt-issuer
defaultIssuerKind: ClusterIssuer
cert-manager-issuers.yaml.gotmpl
acme.email
에 demo-env.yaml
에서 정의한 cert-manager.issuer-email
값을 치환 합니다.
resources:
- apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
name: letsencrypt-issuer
spec:
acme:
# The ACME server URL
server: https://acme-v02.api.letsencrypt.org/directory
# Email address used for ACME registration
email: '{ { .Values | getOrNil "cert-manager.issuer-email" | default "issuer@example.com" } }'
# Name of a secret used to store the ACME account private key
privateKeySecretRef:
name: letsencrypt-issuer
solvers:
# An empty 'selector' means that this solver matches all domains
- selector: {}
http01:
ingress:
class: nginx
실행
- sync : 선언된 모든 chart 를 재설치 합니다.
- apply : 변경된 chart 만 재설치 합니다.
- destroy : 모든 chart 를 삭제 합니다.
helmfile sync
helmfile destroy
helmfile -f helmfile.yaml -e eks-demo apply
helmfile -f helmfile.yaml -e eks-demo destroy