helm을 배워보자 4일차 - 디버깅과 release, rollback

0

helm

목록 보기
4/8

Templating와 Dry runs

helm이 release를 설치할 대 program은 여러 단계를 거친다. chart를 load하고 value들을 파싱하여 program에 configuration을 전달하고, chart는 metadata를 읽는다. 이때 chart에는 template문법으로 특정 value들을 가리키고 있는데, 이 template에 value를 전달하여 렌더링하는 과정이 수행되는 것이다. template가 value를 기반으로 렌더링되어 yaml파일이 만들어지면 helm은 yaml의 구조를 분석하고 파싱하여 kubernetes object로 만들어준다. 만약, 잘못된 kubernetes object yaml파일이 만들어지면 error를 발생시킨다.

이 과정을 간단히 말하자면 다음과 같다.

  1. 전체 chart와 chart에 의존된 dependency들을 load한다.
  2. value들을 parse한다.
  3. chart안의 template들을 value와 함께 렌더링하여 kuberntes object yaml파일로 만든다.
  4. 만들어진 kubernetes object yaml파일의 data가 정확한 지 검사한다.
  5. kubernetes에 해당 yaml파일을 전달한다.

위의 과정에서 만약 template에 value를 넣어 렌더링한 kuberntes object yaml파일이 정합성 검사에서 실패해버리면, helm 작업이 실패한다. 매번 template 문법을 적용하고 value를 넣어 실행하여 정합성이 맞는 지 test하기에는 무리가 있으므로, --dry-runhelm template을 사용하는 것이 좋다.

--dry-run flag

--dry-run flag는 helm install, hem upgrade에서 사용이 가능한데, helm이 chart를 load하고 value를 가져오고, template를 value와 함께 렌더링하고, yaml파일로 만들어주는 과정을 거치되, 결과 yaml file을 kubernetes에 전달하는 것이 아니라, stdout에 전달하는 것이다. 따라서 실제 kuberntes object가 만들어지지는 않고, yaml file의 결과가 어떻게 나오는 지 확인하기 좋은 명령어이다.

가령 drupal 설치 시에 --dry-run을 실행해보도록 하자.

helm install mysite bitnami/drupal --values values.yaml --set \
drupalEmail=foo@example.com --dry-run

NAME: mysite
LAST DEPLOYED: Tue Jul  2 14:43:51 2024
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
HOOKS:
MANIFEST:
...
# Source: drupal/templates/svc.yaml
apiVersion: v1
kind: Service
metadata:
  name: mysite-drupal
  namespace: "default"
  labels:
    app.kubernetes.io/instance: mysite
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: drupal
    app.kubernetes.io/version: 10.3.0
    helm.sh/chart: drupal-18.21.12
spec:
  type: LoadBalancer
  sessionAffinity: None
  externalTrafficPolicy: "Cluster"
  ports:
    - name: http
      port: 80
      targetPort: http
    - name: https
      port: 443
      targetPort: https
  selector:
    app.kubernetes.io/instance: mysite
    app.kubernetes.io/name: drupal

...

chart의 설치될 installation(인스턴스)에 대한 이름, namespace, status 등을 나타내준다. 그리고 이 아래부터 template와 value를 이용하여 렌더링된 yaml파일이 stdout에 나온다.

--dry-run을 통해서 cluster에 배포하기 전에 helm에서 배포될 결과가 무엇인 지 예측해볼 수 있고, template문법이 잘못되었는 지, value값이 잘 들어갔는 지 등을 확인할 수 있다. 즉, debug용으로 사용한다는 것이다.

그러나, 사람들은 몇 가지 실수를 했는데 --dry-run으로 만든 결과를 검토한 다음 kubernetes에 전송하여 object를 만드려고하는 시도들이 많았다. --dry-run은 debug를 위해 만들어졌음으로 이러한 사용에는, 몇 가지 문제점들이 있는데 다음과 같다.

  1. --dry-runyaml 파일이 아닌 data들도 렌더링된 template 파일과 혼합되어 만들어지기 때문에, 바로 결과를 kubectl로 보내면 yaml파일이 아닌 data들이 걸러지지 않아 error를 발생시킨다.
  2. upgrade에서 사용하는 --dry-run 결과는 install에서 사용하는 --dry-run과 다를 수 있으므로 혼란을 야기할 수 있다.
  3. --dry-run을 실행할 때에도 kubernetes API server에게 verification을 요구한다. 이는 debug용 --dry-run임에도 불구하고 kubernetes credential을 필요로 한다는 것이다.
  4. --dry-run은 cluster specific한 template engine에 정보들을 넣어므로, 렌더링 결과가 cluster specific할 수 있다.

이러한 문제점 때문에 helmhelm template를 도입하게 된 것이다.

helm template 명령어

--dry-run이 디버깅용으로 만들어진 반면에 helm template는 helm의 template 렌더링 과정을 설치, 업그레이드 로직과 분리한 것이다. --dry-run과 달리 helm template는 다음의 특징을 가진다.

  1. helm template 중에 helm은 절대 remote kubernetes api server에 접근하지 않는다.
  2. template 명령어는 항상 installation과 같이 동작한다.
  3. kubernetes server와 상호작용해야하는 template 함수나 지시자들은 default data로 반환된다.
  4. chart는 오직 default kubernetes kinds에만 접근할 수 있다.

마지막 4번째 줄에 집중해보면 default kuberntes kinds에만 접근할 수 있다고 한다. 즉, CRD와 같은 custom resource definition에는 접근할 수 없다는 것인데, chart를 정제하기 전에 CRD를 kubernetes API server로부터 fetch받아서 렌더링하기 때문이다. 즉, helm template는 kubernetes API server와 상호작용하지 않으므로 CRD에 대한 정보를 요구할 수 없는 것이다.

이러한 4가지 특성 덕분에 helm template는 항상 같은 output을 만들어낸다. 또한, kubernetes API server와 상호작용하지 않으므로 kubernetes cluster에 접근할 필요없는 CI pipeline에서 사용하기 좋다.

helm template의 결과는 또한 --dry-run과 다른데, 다음을 보도록 하자.

helm template mysite bitnami/drupal --values values.yaml --set \
> drupalEmail=foo@example.com
---
# Source: drupal/charts/mariadb/templates/networkpolicy.yaml
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: mysite-mariadb
  namespace: "default"
  labels:
    app.kubernetes.io/instance: mysite
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: mariadb
    app.kubernetes.io/version: 11.3.2
    helm.sh/chart: mariadb-18.2.4
spec:
  podSelector:
    matchLabels:
      app.kubernetes.io/instance: mysite
      app.kubernetes.io/managed-by: Helm
      app.kubernetes.io/name: mariadb
      app.kubernetes.io/version: 11.3.2
      helm.sh/chart: mariadb-18.2.4
  policyTypes:
    - Ingress
    - Egress
  egress:
    - {}
  ingress:
    - ports:
        - port: 3306
        - port: 3306
---
...

helm template를 사용하면 kubernetes cluster에게서 검증을 받지 않는 output이 나오게 된다. 따라서 helm의 검증만 받았기 때문에 일부 error가 있을 수 있다. --validate flag를 붙이면 kubernetes cluster에게서 검증을 받지만 이 경우에 kubeconfig file을 통해 cluster에 대한 접근을 허락받아야 한다.

helm template 명령어는 helm install을 따라하는 다양한 flag들이 존재한다. 따라서, helm install을 사용하기 전에 helm template를 통해서 output을 검사받을 수 있다.

따라서 정리하자면 helm template는 helm chart를 yaml파일로 렌더링되는 것을 검사하기 위함이고, --dry-run은 helm install, upgrade되어 kubernetes에 적재되는 결과를 디버깅하는 것이다.

Release에 대하여

먼저 helm installation에 대한 5가지 단계를 확인해보도록 하자.

  1. chart를 로드한다.
  2. value를 파싱한다.
  3. template를 실행한다.
  4. yaml file을 렌더링한다.
  5. yaml file을 kubernetes로 전달한다.

1~4단계는 사실상 local에서 data를 표현하는 방법이다. 즉, 1~4단계는 모두 helm에서 작업이 이루어진다는 것이다.

그러나, 마지막 5번째 단계에서는 helm은 yaml file를 kubernetes로 보낸다. 이 다음 helm과 kubernetes는 release가 수락되거나 거절되기까지 앞 뒤로 통신하게된다.

5번째 단계 동안에 helm은 release의 상태를 관찰해야한다. 게다가 다수들이 같은 특정 application installation에 대해서 작업을 할 수 있을 수 있기 때문에, helm은 다수의 유저들이 해당 정보들을 볼 수 있는 방법으로 state를 관찰해야한다.

helm은 이러한 feature를 release records로 제공해준다.

Release Records

helm에서는 helm chart를 배포하면 secret에 release정보를 남긴다고 하였다.

kubectl get secret
NAME                           TYPE                                  DATA   AGE
default-token-g777k            kubernetes.io/service-account-token   3      6m
mysite-drupal                  Opaque                                1      2m20s
mysite-mariadb                 Opaque                                2      2m20s
sh.helm.release.v1.mysite.v1   helm.sh/release.v1                    1      2m20s

sh.helm.release.v1.mysite.v1을 보면 helm.sh/release.v1이라는 special한 secret type을 가진다. 이는 helm secret이라는 것을 명시적으로 알려준다. helm은 해당 chart에 대한 version을 추적하기 위해서 이러한 secret을 자동으로 만들어내는 것이다.

helm upgrade를 실행하면 version에 대한 secert이 계속 생기는 것을 볼 수 있다.

helm upgrade mysite bitnami/drupal
...
helm upgrade mysite bitnami/drupal
...
kubectl get secrets
NAME                           TYPE                                  DATA   AGE
default-token-g777k            kubernetes.io/service-account-token   3      8m43s
mysite-drupal                  Opaque                                1      5m3s
mysite-mariadb                 Opaque                                2      5m3s
sh.helm.release.v1.mysite.v1   helm.sh/release.v1                    1      5m3s
sh.helm.release.v1.mysite.v2   helm.sh/release.v1                    1      20s
sh.helm.release.v1.mysite.v3   helm.sh/release.v1       

설치 후에 upgrade를 실행한 만큼 release record들이 계속 생기는 것을 볼 수 있다. 기본적으로 helm은 10개의 release record가 넘어가면 예전 것부터 삭제하여 총 10개의 갯수를 유지한다.

각 release record들은 다시 kuberntes object를 생성할 만큼 충분한 정보들과 metadata를 가지고 있어 helm rollback을 통해서 언제든 해당 revision으로 돌아갈 수 있다.

가령, kubectl을 통해서 release를 확인하면 다음과 같이 볼 수 있다.

apiVersion: v1
data:
  release: SDRzSUFBQU... # Lots of Base64-encoded data removed
kind: Secret
metadata:
  creationTimestamp: "2020-08-11T18:37:26Z"
  labels:
    modifiedAt: "1597171046"
    name: mysite
    owner: helm
    status: deployed
    version: "3"
  name: sh.helm.release.v1.mysite.v3
  namespace: default
  resourceVersion: "1991"
  selfLink: /api/v1/namespaces/default/secrets/sh.helm.release.v1.mysite.v3
  uid: cbb8b457-e331-467b-aa78-1e20360b5be6
type: helm.sh/release.v1

metadata.labels는 해당 helm chart에 대한 metadata이다. 더 정확히는 release에 관한 데이터가 맞다.

위에서 data.release가 바로 blob으로 표현된 gzip data인 것이다. 해당 gzip data는 chartrelease에 대한 정보들이 압축되어 들어있는 것이다.

labels 정보를 보면 name에 어떤 chart로 올라갔는 지 나오고, statusdeployed라면 배포되어있는 상태라고 생각하면 된다. version3이므로 version 2의 경우는 statussuperseded로 되어있을 것이다. 이는 최신 버전으로 version 2가 대체되었다는 것이다.

release life cycle 동안에 release는 여러 status를 거칠 수 있다. status를 정리한 다음을 보도록 하자.

  1. pending-install: kuberntes에 manifest를 전달하기 전에 helm은 release를 만듦으로서 installation(혹은 인스턴스)을 만들 것을 요구하는데, 이 상태가 바로 pending-install이다.
  2. deployed: kuberntes가 helm으로부터 manifest를 받아 수락하고, helm은 release record를 업데이트한다. 이 때의 status가 바로 deployed이다.
  3. pending-upgrade: helm upgrade가 시작되면 installation에 대한 새로운 release가 만들어지고, 새로운 release에 대한 status가 pending-upgrade가 된다.
  4. upgrade가 동작할 때, 마지막으로 배포된 release는 status가 superseded 으로 마킹된다. 새롭게 만들어진 release는 pending-upgrade에서 deployed로 바뀐다.
  5. pending-rollback: rollback이 만들어지면 새로운 release가 만들어지고, kubernetes가 release manifest를 수락하기 전까지 새로운 release의 status는 pending-rollback이 된다. 이 후에 kuberntes가 manifest를 배포 완료하면, 새롭게 만들어진 release는 deployed가 되고, 이전 release는 superseded가 된다.
  6. uninstalling: helm uninstall이 실행될 때, 가장 최근 release가 읽어지고, 해당 release의 status는 uninstalling이 된다.
  7. uninstalled: 만약 helm uninstall 시에 history를 지우지 않는 명령어를 쓰면, 마지막 release의 status는 uninstalled가 된다.
  8. failed: 마지막으로, helm에 의해 요청된 manifest를 kubernetes에서 거절하면 helm은 해당 release를 failed로 마킹한다.

Relases list

helm list를 사용하면 현재 배포된 release에 대한 status정보를 얻을 수 있다. 참고로 helm listhelm ls는 단축어 관계로 같은 결과를 내보낸다.

helm list
ME     	NAMESPACE REVISION  UPDATED       STATUS  	CHART           	APP V...
mysite   	default  	3   2020-08-11... deployed  drupal-7.0.0      9.0.0
wordpress   default  	2   2020-08-12... deployed  wordpress-9.3.11  5.4.2

STATUS를 통해서 현재 release의 정보를 볼 수 있는 것을 알 수 있다.

한 번 wordpressfailed status로 만들어보도록 하자.

helm upgrade wordpress bitnami/wordpress --set image.pullPolicy=NoSuchPolicy
Error: UPGRADE FAILED: cannot patch "wordpress" with kind Deployment:
Deployment.apps "wordpress" is invalid:
spec.template.spec.containers[0].imagePullPolicy: Unsupported value:
"NoSuchPolicy": supported values: "Always", "IfNotPresent", "Never"

kubernetes에서 image를 찾지못하여 error를 발생시키는 것이다. helm ls를 통해서 확인해보도록 하자.

helm ls
NAME      NAMESPACE REVISION  UPDATED     STATUS    CHART             APP VER...
mysite   	default  	3         2020-08-11  deployed  drupal-7.0.0      9.0.0
wordpress   default  	3         2020-08-12  failed    wordpress-9.3.11  5.4.2

wordpress installation이 failed로 된 것을 볼 수 있다. 재밌는 것은 failed되었지만 REVISION은 올라갔다. 이는 새로운 release가 생겼기 때문인데, 이에 대해서는 history와 rollbacks를 설명할 때 더 자세히 설명하겠다.

helm get을 통한 release 정보 확인하기

helm get은 특정 release에 대한 자세한 정보를 제공해준다.

helm get에는 5가지 하위 명령어가 있는데 hooks, manifests, notes, values, all 등이 있다.

helm get notes를 사용하면 release notes를 알려준다.

helm get notes mysite
NOTES:

*******************************************************************
*** PLEASE BE PATIENT: Drupal may take a few minutes to install ***
*******************************************************************

1. Get the Drupal URL:

  You should be able to access your new Drupal installation through

  http://drupal.local/
...

위 output은 helm installhelm upgrade를 실행하였을 때, 마지막에 보이는 output과 동일하다. helm get notes를 통하여 가져올 수 있는 것이다.

가장 유용한 명령어로는 helm chart를 만들 때, 사용했던 value를 볼 수 있는 helm get values 명령어이다.

helm get values wordpress
USER-SUPPLIED VALUES:
image:
  pullPolicy: NoSuchPolicy

위에서 wordpress에 넣은 value값으로 pullpolicyNoSuchPolicy로 넣었다. 이는 revision 3이었는데, 만약 revision 2에 대한 value정보들 얻고 싶다면 다음과 같이 쓸 수 있다.

helm get values wordpress --revision 2
USER-SUPPLIED VALUES:
image:
  tag: latest

만약 user가 입력한 value말고도 전체적인 value자체를 보고 싶다면 --all 명령어를 사용하면 된다.

helm get values wordpress --all
COMPUTED VALUES:
affinity: {}
allowEmptyPassword: true
allowOverrideNone: false
customHTAccessCM: null
customLivenessProbe: {}
customReadinessProbe: {}
externalDatabase:
  database: bitnami_wordpress
  host: localhost
  password: ""
  port: 3306
...

--all 명령어 시에 알파벳 순서로 완전한 value 집합을 가져와준다.

참고로 helm get values는 현재 배포된 chart에 사용된 value가 무엇인지를 보여주는 것이다. 만약, 배포되기전 chart의 default value 자체가 무엇이었는 지를 보고싶다면 helm inspect values CHARTNAME을 사용하면된다. 가령 chart가 bitnami/wordpress였다면 helm inspect values bitnami/wordpress를 사용하여 default configuration을 확인하면 된다.

helm get manifest를 사용하면 helm이 chart template사용하여 만들어낸 kubernetes yaml manifest 파일을 볼 수 있다.

helm get manifest wordpress
# Source: wordpress/charts/mariadb/templates/secrets.yaml
apiVersion: v1
kind: Secret
metadata:
  name: wordpress-mariadb
  labels:
    app: "mariadb"
    chart: "mariadb-7.5.1"
    release: "wordpress"
    heritage: "Helm"
type: Opaque
...

한 가지 조심해야할 점은, 현재 배포된 installation에 대한 manifest가 아니라는 것이다. 즉, template엔진에 의해서 만들어진 manifest를 반환할 뿐이다. 아래는 실제 kubectl을 통해서 배포된 Secret 정보를 가져온 것이다.

kubectl get secret wordpress-mariadb -o yaml

apiVersion: v1
kind: Secret
metadata:
  annotations:
    meta.helm.sh/release-name: wordpress
    meta.helm.sh/release-namespace: default
  creationTimestamp: "2020-08-12T16:45:00Z"
  labels:
    app: mariadb
    app.kubernetes.io/managed-by: Helm
    chart: mariadb-7.5.1
    heritage: Helm
    release: wordpress
  managedFields:
  - apiVersion: v1
    fieldsType: FieldsV1
...

몇 가지 field들은 kuberntes 상에서 동작하면서 추가된 field들이다. managedFields , creationTimestamp와 같은 field들이 그렇다. 그런데, 이는 위에서 helm get manifest로는 볼 수 없다. 이를 통해 알 수 있는 것은 helm get manifest는 현재 deploy된 installation의 manifest를 가져오는 것이 아니다.

정리하자면 helm get 명령어로 각 relase에 대한 정보들을 알 수 있고, helm이 kubernetes에 전달한 manifest, value들을 알 수 있다는 것이다.

History and Rollbacks

helm list를 통해서 현재 배포된 installation들이 무엇이 있는 지 보도록 하자.

helm list
NAME     	NAMESPACE   REVISION  UPDATED     STATUS    CHART             APP VER...
mysite      default  	3         2020-08-11  deployed  drupal-7.0.0      9.0.0
wordpress   default  	3         2020-08-12  failed    wordpress-9.3.11  5.4.2

각각 3개의 release가 있는 것을 볼 수 있다. 특히 wordpressfailed 상태인데, 해당 release에 어떤 일이 있었는 지 확인해보도록 하자.

helm history wordpress
REVISION UPDATED       STATUS     CHART             APP VER  DESCRIPTION
1        Wed Aug 12... superseded wordpress-9.3.11  5.4.2    Install complete
2        Wed Aug 12... deployed  	wordpress-9.3.11  5.4.2    Upgrade complete
3        Wed Aug 12... failed    	wordpress-9.3.11  5.4.2    Upgrade \
  "wordpress" failed: cannot patch "wordpress" with kind Deployment: \
  Deployment.apps "wordpress" is invalid: \
  spec.template.spec.containers[0].imagePullPolicy: Unsupported value: \
  "NoSuchPolicy": supported values: "Always", "IfNotPresent", "Never"

helm history 명령어를 사용하여 wordpress release에 대한 history를 깔끔하게 보여준다. 심지어는 failed되었을 때 왜 실패했는 지에 대한 error msg도 상세하게 전달해준다.

현재 failed 상태이므로 wordpress installation을 다시 정상적인 상태로 복구하기 위해, release 2로 rollback하도록 하자.

helm rollback wordpress 2
Rollback was a success! Happy Helming!

주의할 것은 rollback은 이전 release로 그대로 돌아가는 것이 아니다. 즉, snapshot을 찍고, 그 snapshot상태로 그대로 되돌아가는 것이 아니라는 것이다. 그저 해당 release에서 만들었던 kubernetes manifest를 다시 가져와서 실행시켜두는 것이 전부이다.

rollback 이후에 helm history를 다시 실행시켜보도록 하자.

REVISION  UPDATED       STATUS      CHART             APP VER  DESCRIPTION
1         Wed Aug 12... superseded  wordpress-9.3.11  5.4.2    Install complete
2         Wed Aug 12... superseded  wordpress-9.3.11  5.4.2    Upgrade complete
3         Wed Aug 12... failed      wordpress-9.3.11  5.4.2    Upgrade \
  "wordpress" failed: cannot patch "wordpress" with kind Deployment: \
  Deployment.apps "wordpress" is invalid: \
  spec.template.spec.containers[0].imagePullPolicy: Unsupported value: \
  "NoSuchPolicy": supported values: "Always", "IfNotPresent", "Never"
4         Wed Aug 12... deployed    wordpress-9.3.11  5.4.2    Rollback to 2

rollback 시에 이전 release의 kuberntes manifest를 다시 실행시킨다해도, release를 다시 2로 돌아가는 것이 아니다. 새로운 release가 만들어지고 status도 바뀐다. release 2는 deployed에서 superseded로 바뀐 것을 볼 수 있고, release 4는 deployed로 바뀐 것을 볼 수 있다. 이를 통해 release는 증가만 할 뿐, 다시 rollback한다고 적어지지 않는다는 것을 알 수 있다.

helm rollback에는 몇 가지 문제점이 있는데, 만약 kubernetes object들을 손으로 직접 수정하는 경우 발생하는 문제들이 있다. helm과 kubernetes는 손으로 직접 수정한 부분들에 대해서 rollback하려는 release와 충돌만 하지 않으면, 그대로 보존하려고 할 것이다. 그러나, 최악의 경우는 손으로 직접 수정한 부분들이 override되고 나머지는 merge될 수 있는데 이는 configuration에 있어서 일관성이 없어지는 문제가 발생한다.

따라서, helm으로 project를 관리한다면 굳이 직접 손으로 configuration을 수정할 필요도 없고, 추천도 하지 않는다.

History 보존과 Rolling back

helm uninstall 명령어를 사용하면 release 정보들이 모두 삭제되고 installation도 삭제되는 것을 볼 수 있었다. 그러나 --keep-history 옵션을 사용하면 helm uninstall 이후에도 installation의 history가 남게되는 것을 볼 수 있다.

helm uninstall wordpress --keep-history
release "wordpress" uninstalled

helm history를 살펴보도록 하자.

helm history wordpress
REVISION UPDATED       STATUS     	CHART             APP V  DESCRIPTION
1        Wed Aug 12... superseded 	wordpress-9.3.11  5.4.2  Install complete
2        Wed Aug 12... superseded 	wordpress-9.3.11  5.4.2  Upgrade complete
3        Wed Aug 12... failed     	wordpress-9.3.11  5.4.2  Upgrade \
  "wordpress" failed: cannot patch "wordpress" with kind Deployment: \
  Deployment.apps "wordpress" is invalid: \
  spec.template.spec.containers[0].imagePullPolicy: Unsupported value: \
  "NoSuchPolicy": supported values: "Always", "IfNotPresent", "Never"
4        Wed Aug 12... uninstalled  wordpress-9.3.11  5.4.2  Uninstall complete

남아있는 것을 볼 수 있다.

만약 --keep-history 옵션 없이 helm uninstall을 실행했다면 다음과 같이 나온다.

helm uninstall wordpress
release "wordpress" uninstalled
helm history wordpress
Error: release: not found
helm rollback wordpress 4
Error: release: not found

Install과 Upgrade에 대하여

kubernetes 상에서 object들의 이름을 구분하는 것은 매우 중요한 일이다. kubernetes에서는 이름의 고유성을 토대로 kubernetes object 간의 구분을 하기 때문이다. helm 역시도 이를 위해서 자동으로 접미사를 붙여 이름을 만드는 기능이 있다.

installation의 이름

helm install--generate-name flag를 사용해주면 된다.

helm install bitnami/wordpress --generate-name
NAME: wordpress-1597689085
LAST DEPLOYED: Mon Aug 17 11:31:27 2020
NAMESPACE: default
STATUS: deployed
REVISION: 1

wordpress installation이 생기고, 뒤에 1597689085이 붙은 것을 확인할 수 있다. 이는 installation이 만들어진 시간이라고 생각하면 된다.

random으로 만들어지는 이름을 template문법으로 지정하는 방법도 있다. --name-template 기능을 사용하면 되는데, 가령 랜덤하게 알파멧 소문자 9개로 문자를 만들고 싶다면 다음과 같이 할 수 있다. 단, --generate-name과 함께 사용해야한다.

helm install bitnami/wordpress --generate-name \
  --name-template "foo-{{ randAlpha 9 | lower }}"
NAME: foo-yejpiyjmp
LAST DEPLOYED: Mon Aug 17 11:46:04 2020
NAMESPACE: default

결과로 foo다음으로 -yejpiyjmp가 추가된 것이다.

kubernetes에서는 같은 이름을 가진 object라도 서로 다른 namespace라면 문제없이 배포가 가능하다. 이는 unique함이 있기 때문이다. 그런데, helm에서는 namespace를 지정하고 helm install을 하려고 할 때, namespace가 없다면 error가 발생한다.

helm install drupal bitnami/drupal --namespace mynamespace
Error: create: failed to create: namespaces "mynamespace" not found

위의 예제는 mynamespace namespace가 없기 때문에 발생한 error이다. 이를 해결하기 위해서 helm install이 되면서 namespace가 없다면 namespace를 만들도록 해야한다. 이 때 필요한 옵션이 바로 --create-namespace이다. helm install을 실행할 때, 지정한 namespace가 없다면 생성해주는 것이다.

helm install drupal bitnami/drupal --namespace mynamespace --create-namespace
NAME: drupal
LAST DEPLOYED: Mon Aug 17 11:59:29 2020
NAMESPACE: mynamespace
STATUS: deployed

단, 반대의 명령어는 없다. 즉, helm uninstall--delete-namespace는 없다는 것이다. 따라서 --create-namespace를 사용하기보다는 직접 namespace를 만들어주고 삭제해주는 script를 개발하는 것이 좋다.

helm upgrade --install

현재 helm installation이 있는 지 없는 지 확인하지 않고, helm upgrade를 매번 구동하고 싶을 때가 있을 것이다. 이는 주로 CI/CD program에서 자주 동작한다. 그런데, 문제는 installation이 없는 경우 helm upgrade를 실행하면 error가 발생한다는 것이다.

이러한 문제를 해결하기 위해서 helm upgrade --install 명령어가 있다. 이 명령어를 사용하면 helm installation이 없을 때는 새로 install해주고, 있다면 upgrade를 해준다. 내부 동작은 매우 간단한데, kubernetes에 현재 배포되려는 chart installation의 이름으로된 release가 deployed인지 확인하는 것이 전부이다.

helm upgrade --install wordpress bitnami/wordpress
Release "wordpress" does not exist. Installing it now.
NAME: wordpress
LAST DEPLOYED: Mon Aug 17 13:18:14 2020
NAMESPACE: default
STATUS: deployed
...
helm upgrade --install wordpress bitnami/wordpress
Release "wordpress" has been upgraded. Happy Helming!
NAME: wordpress
LAST DEPLOYED: Mon Aug 17 13:18:43 2020
NAMESPACE: default
STATUS: deployed

문제는 이 명령어만으로는 helm으로 install을 한 것인지 upgrade를 한 것인지 알 수가 없다는 것이다.

0개의 댓글