Kubernetes 패키지 매니저 Helm

구글 클라우드 스터디잼을 진행하면서, Helm이라는 Kubernetes용 패키지매니저를 사용했었는데, 해당 패키지 매니저 문서를 살펴보다보니 생각보다 훨씬 이해해야할 것이 많아서 한번 정리를 하게 되었다.

우선 설치부터

Helm이 Kubernetes를 위한 패키지 매니저인만큼, 우선 Kubernetes부터 쓸 줄 알아야하는데, 저도 잘 모르기때문에 일단 해보는 걸로! 여튼 kubernetes가 정상적으로 돌아가는지 확인해봅시다.

$ kubectl config current-context
docker-for-desktop

Docker Desktop을 사용하고 있기 때문에 설정에서 간단하게 enable 시켜주는 것 만으로도 사용할 수 있었다. enable을 시키면 kubernetes를 구동시키기 위해 필요한 것들을 설치해준다.

docker desktop의 kubernetes
docker desktop의 kubernetes

helm 설치

Helm 설치는 OS별로 아주 상세하게 helm 문서 - Installing Helm에 적혀있다. macOS에서는 homebrew가 설치되어 있다면 아래의 명령어로 helm을 설치할 수 있다.

$ brew install kubernetes-helm
Updating Homebrew...
...
...

보안

자 근데 여기서 생각을 해야할 점은 helm의 tiller는 k8s의 cluster위에 올라가기 때문에 production용이나, 다른 사람과 같이 쓰는 cluster에서는 보안을 신경을 써주어야 한다! 하지만 난 개인 노트북에서 연습만 해보고 있으므로, 나중에 보자. 안전하게 Helm 설치하기

tiller 설치

자 그렇게 helm을 설치하고 나면, tiller를 설치해주어야 하는데, tiller는 아래처럼 설치한다.

$ helm init
Creating ...
...
...

Happy Helming!

몇몇 메시지가 뜨면서 잘 설치가 된다. 그리고 tiller를 업그레이드하려면 아래처럼 하면된다.

helm init --upgrade

tiller

자 근데 tiller 얘기를 계속했는데, tiller는 pod 형태로 설치되는 helm의 서버라고 생각하면 된다. helm이 client이고, tiller가 server인 한 쌍의 구조이다.

사용해보자

helm을 설치하고 나면 이제 helm의 chart를 이용해서 설치할 수도 있다.

$ helm repo update
Hang tight while we grab the latest from your chart repositories...
...Skip local chart repository
...Successfully got an update from the "stable" chart repository
Update Complete. ⎈ Happy Helming!⎈

그 전에 위의 명령어처럼 chart의 최신 버전을 들고오도록 해주자.

Chart란

자 근데 chart란 말이 등장하는데 chart는 helm의 패키지의 형식이다. node js를 이용할 때 패키지 매니저를 이용하여 설치되는 패키지를 모듈이라고 부르듯이 k8s에서는 chart라고 부른다. chart에 대한 설명은 kubernetes 문서, 또는 helm/charts repository를 참고해보자.

helm/charts 레포지토리를 열어보면, stable 폴더안의 여러가지 chart들을 볼 수 있을텐데, 그 안의 chart들을 설치하게 된다.

helm install stable/<chart>

예시로 nginx-ingress를 설치해보면 아래와 같이 구동된다.

$ helm install stable/nginx-ingress --name nginx-ingress
NAME:   nginx-ingress
LAST DEPLOYED: Wed Feb  6 17:32:53 2019
NAMESPACE: default
STATUS: DEPLOYED

RESOURCES:
==> v1beta1/ClusterRole
NAME           AGE
nginx-ingress  1s

==> v1beta1/ClusterRoleBinding
NAME           AGE
nginx-ingress  1s

==> v1beta1/Role
NAME           AGE
nginx-ingress  1s

==> v1/ConfigMap
NAME                      DATA  AGE
nginx-ingress-controller  1     1s

==> v1beta1/RoleBinding
NAME           AGE
nginx-ingress  1s

==> v1/Service
NAME                           TYPE          CLUSTER-IP     EXTERNAL-IP  PORT(S)                     AGE
nginx-ingress-controller       LoadBalancer  10.97.232.86   localhost    80:30168/TCP,443:32411/TCP  1s
nginx-ingress-default-backend  ClusterIP     10.107.207.64  <none>       80/TCP                      1s

==> v1beta1/Deployment
NAME                           DESIRED  CURRENT  UP-TO-DATE  AVAILABLE  AGE
nginx-ingress-controller       1        1        1           0          1s
nginx-ingress-default-backend  1        1        1           0          1s

==> v1/Pod(related)
NAME                                            READY  STATUS             RESTARTS  AGE
nginx-ingress-controller-669764bbb9-pfrvv       0/1    ContainerCreating  0         0s
nginx-ingress-default-backend-5455568d9d-lvsth  0/1    ContainerCreating  0         0s

==> v1/ServiceAccount
NAME           SECRETS  AGE
nginx-ingress  1        1s


NOTES:
The nginx-ingress controller has been installed.
It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status by running 'kubectl --namespace default get services -o wide -w nginx-ingress-controller'

An example Ingress that makes use of the controller:

  apiVersion: extensions/v1beta1
  kind: Ingress
  metadata:
    annotations:
      kubernetes.io/ingress.class: nginx
    name: example
    namespace: foo
  spec:
    rules:
      - host: www.example.com
        http:
          paths:
            - backend:
                serviceName: exampleService
                servicePort: 80
              path: /
    # This section is only required if TLS is to be enabled for the Ingress
    tls:
        - hosts:
            - www.example.com
          secretName: example-tls

If TLS is enabled for the Ingress, a Secret containing the certificate and key must also be provided:

  apiVersion: v1
  kind: Secret
  metadata:
    name: example-tls
    namespace: foo
  data:
    tls.crt: <base64 encoded cert>
    tls.key: <base64 encoded key>
  type: kubernetes.io/tls

이 경우 아래처럼 pod과 service가 정상적으로 구동되는 것을 확인할 수 있다.

$ kubectl get pods
NAME                                             READY     STATUS    RESTARTS   AGE
nginx-ingress-controller-669764bbb9-pfrvv        1/1       Running   0          1m
nginx-ingress-default-backend-5455568d9d-lvsth   1/1       Running   0          1m
$ kubectl get svc
NAME                            TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
kubernetes                      ClusterIP      10.96.0.1       <none>        443/TCP                      2d
nginx-ingress-controller        LoadBalancer   10.97.232.86    localhost     80:30168/TCP,443:32411/TCP   1m
nginx-ingress-default-backend   ClusterIP      10.107.207.64   <none>        80/TCP                       1m

다만 원래 EXTERNAL-IP와 같은 경우는 localhost가 아닌 실제 IP가 띄워지지만, 여기서는 docker desktop을 사용하기 때문에 localhost로 구동된다.

삭제하고 싶은 경우 아래처럼 명령어를 입력하면 삭제된다.

$ helm delete nginx-ingress
release "nginx-ingress" deleted
$ kubectl get pods
No resources found.
$ kubectl get svc
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   2d

이것보다 내용이 더 길어지면 힘들 것 같아서, chart만들어 보는 것은 다음 포스트에!

February 6, 2019 에 작성
Tags: cloud kubernetes