본문 바로가기
Cloud/EKS

EKS 클러스터 생성부터 서비스 배포까지 6. HELM

by J's Note 2023. 11. 22.

목차

EKS 클러스터 생성부터 서비스 배포까지 1. 쿠버네티스, EKS 기초

EKS 클러스터 생성부터 서비스 배포까지 2. EKS 환경 세팅하기

EKS 클러스터 생성부터 서비스 배포까지 3. eksctl을 사용하여 EKS실행하기, 노드그룹 설정하기

EKS 클러스터 생성부터 서비스 배포까지 4. K8s 대시보드 배포

EKS 클러스터 생성부터 서비스 배포까지 5. 마이크로서비스 배포

EKS 클러스터 생성부터 서비스 배포까지 6. HELM

HELM 및 리소스 설치

helm을 사용하면 복잡한 쿠버네티스 애플리케이션의 정의, 설치 및 업그레이드가 용이합니다.

  • 복잡성 관리
  • 차트는 가장 복잡한 앱도 설명하고 반복 가능한 애플리케이션 설치를 제공하며 단일 권한 지점 역할을 합니다.
  • 쉬운 업데이트
  • 전체 업그레이드 및 사용자 지정 후크를 사용하여 업데이트의 어려움을 해소하세요.
  • 단순 공유
  • 차트는 공용 또는 개인 서버에서 버전 관리, 공유 및 호스팅이 쉽습니다.
  • 롤백
  • helm rollback 이전 버전의 릴리스로 쉽게 롤백하는 데 사용됩니다 .

HELM CLI 설치

구성을 시작하기전 helm cli를 설치해야합니다.

cd ~/environment
curl <https://raw.githubusercontent.com/kubernetes/helm/master/scripts/get> > get_helm.sh
chmod +x get_helm.sh

./get_helm.sh

⛔ helm init 명령을 실행하라고 표시되지만 저희는 RBAC을 사용할것이므로 Tiler를 따로 설치해야합니다. 이를 실행하지 않도록 하며 실행한경우 helm reset --force 명령을 사용하여 초기화합니다.

RBAC을 사용하여 helm 액세스 구성

helm은 쿠버네티스 클러스터에 대한 권한이 필요한 Tiler라는 서비스를 사용하므로 Tiler가 사용할 서비스 계정을 구축해야합니다. 구축한 이후 클러스터에 적용하도록 하겠습니다.

cat <<EoF > ~/environment/rbac.yaml
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: tiller
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: tiller
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
  - kind: ServiceAccount
    name: tiller
    namespace: kube-system
EoF

생성된 rbac.yaml 파일을 클러스터에 적용합니다.

kubectl apply -f ~/environment/rbac.yaml

helm cli를 사용하여 helm을 설치합니다.

helm init --service-account tiller

이제 클러스터에 Triller 가 설치되어 클러스터의 리소스를 관리할 수 있는 액세스 권한을 가지게 되었습니다.

helm을 사용하여 nginx 배포

helm은 차트라는 패키징 형식을 사용합니다. 차트는 k8s의 리소스를 설명하는 파일입니다.

차트는 독립형 웹 서버(우리가 만들려는 것)와 같은 것을 설명하는 간단할 수도 있지만 더 복잡할 수도 있습니다. 예를 들어 웹 서버, 데이터베이스, 프록시를 포함하는 전체 웹 애플리케이션 스택을 나타내는 차트입니다.

kubectl을 통해 k8s 리소스를 수동으로 설치하는 대신 Helm을 사용하면 오타나 기타 운영자 오류가 발생할 가능성을 줄이면서 사전 정의된 차트를 더 빠르게 설치할 수 있습니다.

helm의 로컬 차트 목록을 업데이트 하도록 하겠습니다.

helm repo update

업데이트가 완료되었다면 차트검색을 실행해보도록 하겠습니다.

helm search

키워드 인수를 추가하여 nginx를 검색해보겠습니다.

helm search nginx

NAME                            CHART VERSION   APP VERSION     DESCRIPTION                                                 
stable/nginx-ingress            1.41.3          v0.34.1         DEPRECATED! An nginx Ingress controller that uses ConfigM...
stable/nginx-ldapauth-proxy     0.1.6           1.13.5          DEPRECATED - nginx proxy with ldapauth                      
stable/nginx-lego               0.3.1                           Chart for nginx-ingress-controller and kube-lego            
stable/gcloud-endpoints         0.1.2           1               DEPRECATED Develop, deploy, protect and monitor your APIs...

nginx를 검색해보았지만 nginx가 완전히 독립된 웹서버, 즉 오피셜이미지가 아닌것을 확인할 수 있습니다.

Bitnami 차트 저장소를 추가하여 bitnami 차트에서 가져와보도록 하겠습니다.

https://github.com/bitnami/charts

Bitnami 차트를 추가합니다.

helm repo add bitnami <https://charts.bitnami.com/bitnami>

nginx를 다시 검색해보겠습니다.

helm search nginx

NAME                                    CHART VERSION   APP VERSION     DESCRIPTION                                                 
bitnami/nginx                           15.4.0          1.25.3          NGINX Open Source is a web server that can be also used a...
bitnami/nginx-ingress-controller        9.9.2           1.9.3           NGINX Ingress Controller is an Ingress controller that ma...
bitnami/nginx-intel                     2.1.15          0.4.9           DEPRECATED NGINX Open Source for Intel is a lightweight s...
stable/nginx-ingress                    1.41.3          v0.34.1         DEPRECATED! An nginx Ingress controller that uses ConfigM...
stable/nginx-ldapauth-proxy             0.1.6           1.13.5          DEPRECATED - nginx proxy with ldapauth                      
stable/nginx-lego                       0.3.1                           Chart for nginx-ingress-controller and kube-lego            
stable/gcloud-endpoints                 0.1.2           1               DEPRECATED Develop, deploy, protect and monitor your APIs...

bitnami 차트가 추가된것을 확인할 수 있습니다.

bitnami/nginx 설치

이제 helm을 사용하여 독립형 nginx 서버를 설치해보도록 하겠습니다.

helm install mywebserver bitnami/nginx

NAME: mywebserver
LAST DEPLOYED: Thu Nov  9 00:49:16 2023
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
CHART NAME: nginx
CHART VERSION: 15.4.0
APP VERSION: 1.25.3

** Please be patient while the chart is being deployed **
NGINX can be accessed through the following DNS name from within your cluster:

    mywebserver-nginx.default.svc.cluster.local (port 80)

To access NGINX from outside the cluster, follow the steps below:

1. Get the NGINX URL by running these commands:

  NOTE: It may take a few minutes for the LoadBalancer IP to be available.
        Watch the status with: 'kubectl get svc --namespace default -w mywebserver-nginx'

    export SERVICE_PORT=$(kubectl get --namespace default -o jsonpath="{.spec.ports[0].port}" services mywebserver-nginx)
    export SERVICE_IP=$(kubectl get svc --namespace default mywebserver-nginx -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
    echo "<http://$>{SERVICE_IP}:${SERVICE_PORT}"

ELB를 통해 Nginx 웹서버에 접속해보도록 하겠습니다.

kubectl get service mywebserver-nginx -o wide

NAME                TYPE           CLUSTER-IP       EXTERNAL-IP                                                                   PORT(S)        AGE    SELECTOR
mywebserver-nginx   LoadBalancer   10.100.103.232   a3889abd21870417ea5a6ccdcb2ce314-285417704.ap-northeast-2.elb.amazonaws.com   80:30463/TCP   118s   app.kubernetes.io/instance=mywebserver,app.kubernetes.io/name=nginx

EXTERNAL-IP로 접속해보도록 하겠습니다.

HELM 리소스 정리

helm chart를 통해 생성한 내용은 list 명령으로 확인할 수 있습니다.

helm list

NAME            NAMESPACE       REVISION        UPDATED                                 STATUS          CHART           APP VERSION
mywebserver     default         1               2023-11-09 00:49:16.698548808 +0000 UTC deployed        nginx-15.4.0    1.25.3

delete 명령으로 deploy를 지워보도록 하겠습니다.

 

HELM을 사용한 마이크로서비스 배포

helm 을 사용하여 새 차트를 구성할 수 있습니다.

HELM 차트의 구조

일반적으로 helm 차트는 다음과 유사한 구조로 작성되어있습니다.

/eksdemo
  /Chart.yaml
  /values.yam
  /charts/
  /templates/
  ...

Helm | Getting Started

차트 생성

이 템플릿을 따라서 eksdemo 라는 새 차트를 만들어보도록 하겠습니다.

cd ~/environment
helm create eksdemo

~/environment/eksdemo $ tree .
.
├── Chart.yaml
├── charts
├── templates
│   ├── NOTES.txt
│   ├── _helpers.tpl
│   ├── deployment.yaml
│   ├── hpa.yaml
│   ├── ingress.yaml
│   ├── service.yaml
│   ├── serviceaccount.yaml
│   └── tests
│       └── test-connection.yaml
└── values.yaml
  • NOTES.txt: 차트의 "도움말 텍스트"입니다. 이는 helm install을 실행할 때 사용자에게 표시됩니다.
  • deployment.yaml: Kubernetes 배포 생성을 위한 기본 매니페스트
  • service.yaml: 배포를 위한 서비스 엔드포인트를 생성하기 위한 기본 매니페스트
  • _helpers.tpl: 차트 전체에서 재사용할 수 있는 템플릿 도우미를 배치하는 장소

우리는 자체 파일을 만들 예정이므로 상용구 파일을 전부 제거해주겠습니다.

rm -rf ~/environment/eksdemo/templates/
rm ~/environment/eksdemo/Chart.yaml
rm ~/environment/eksdemo/values.yaml

차트를 설명하는 Chart.yaml 파일을 만들어보도록 하겠습니다.

cat <<EoF > ~/environment/eksdemo/Chart.yaml
apiVersion: v1
appVersion: "1.0"
description: A Helm chart for EKS Workshop Microservices application
name: eksdemo
version: 0.1.0
EoF

다음으로 마이크로서비스에 대한 매니페스트 파일을 템플릿 디렉토리에 servicename.yaml 로 복사하겠습니다.

mkdir -p ~/environment/eksdemo/templates/deployment
mkdir -p ~/environment/eksdemo/templates/service

cp ~/environment/ecsdemo-frontend/kubernetes/deployment.yaml ~/environment/eksdemo/templates/deployment/frontend.yaml
cp ~/environment/ecsdemo-frontend/kubernetes/service.yaml ~/environment/eksdemo/templates/service/frontend.yaml

cp ~/environment/ecsdemo-crystal/kubernetes/deployment.yaml ~/environment/eksdemo/templates/deployment/crystal.yaml
cp ~/environment/ecsdemo-crystal/kubernetes/service.yaml ~/environment/eksdemo/templates/service/crystal.yaml

cp ~/environment/ecsdemo-nodejs/kubernetes/deployment.yaml ~/environment/eksdemo/templates/deployment/nodejs.yaml
cp ~/environment/ecsdemo-nodejs/kubernetes/service.yaml ~/environment/eksdemo/templates/service/nodejs.yaml

tree .
.
├── Chart.yaml
├── charts
└── templates
    ├── deployment
    │   ├── crystal.yaml
    │   ├── frontend.yaml
    │   └── nodejs.yaml
    └── service
        ├── crystal.yaml
        ├── frontend.yaml
        └── nodejs.yaml

복사한 yaml파일들에 대해 하드코딩된 값들을 템플릿 지시문으로 바꾸겠습니다.

<aside> 💡 다음 작업은 frontend.yaml, crystal.yaml, nodejs.yaml에 대해 전부 진행해주어야합니다.

</aside>

deployment의 service.yaml을 변경하겠습니다.

spec 을 찾고 replicas를 조정합니다.

replicas: {{ .Values.replicas }}

spec.template.spec.containers.image 항목들을 조정합니다.

Filename Value

frontend.yaml - image: {{ .Values.frontend.image }}:{{ .Values.version }}
crystal.yaml - image: {{ .Values.crystal.image }}:{{ .Values.version }}
nodejs.yaml - image: {{ .Values.nodejs.image }}:{{ .Values.version }}

values.yaml 파일을 만들도록 하겠습니다.

cat <<EoF > ~/environment/eksdemo/values.yaml
replicas: 3
version: 'latest'

nodejs:
  image: brentley/ecsdemo-nodejs
crystal:
  image: brentley/ecsdemo-crystal
frontend:
  image: brentley/ecsdemo-frontend
EoF

차트 배포

테스트를 해보기 위해 dry-run 플래그를 이용하여 차트가 정상적으로 작성되어있는지 확인하겠습니다.

helm install --debug --dry-run workshop ~/environment/eksdemo                                                                                                                                                                        
install.go:214: [debug] Original chart version: ""
install.go:231: [debug] CHART PATH: /home/ubuntu/environment/eksdemo

NAME: workshop
LAST DEPLOYED: Thu Nov  9 01:28:23 2023
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
USER-SUPPLIED VALUES:
{}

COMPUTED VALUES:
crystal:
  image: brentley/ecsdemo-crystal
frontend:
  image: brentley/ecsdemo-frontend
nodejs:
  image: brentley/ecsdemo-nodejs
replicas: 3
version: latest

HOOKS:
MANIFEST:
---
# Source: eksdemo/templates/service/crystal.yaml
apiVersion: v1
kind: Service
metadata:
  name: ecsdemo-crystal
spec:
  selector:
    app: ecsdemo-crystal
  ports:
   -  protocol: TCP
      port: 80
      targetPort: 3000
---
# Source: eksdemo/templates/service/frontend.yaml
apiVersion: v1
kind: Service
metadata:
  name: ecsdemo-frontend
spec:
  selector:
    app: ecsdemo-frontend
  type: LoadBalancer
  ports:
   -  protocol: TCP
      port: 80
      targetPort: 3000
---
# Source: eksdemo/templates/service/nodejs.yaml
apiVersion: v1
kind: Service
metadata:
  name: ecsdemo-nodejs
spec:
  selector:
    app: ecsdemo-nodejs
  ports:
   -  protocol: TCP
      port: 80
      targetPort: 3000
---
# Source: eksdemo/templates/deployment/crystal.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ecsdemo-crystal
  labels:
    app: ecsdemo-crystal
  namespace: default
spec:
  replicas: 3
  selector:
    matchLabels:
      app: ecsdemo-crystal
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: ecsdemo-crystal
    spec:
      containers:
      - image: brentley/ecsdemo-crystal:latest
        imagePullPolicy: Always
        name: ecsdemo-crystal
        ports:
        - containerPort: 3000
          protocol: TCP
---
# Source: eksdemo/templates/deployment/frontend.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ecsdemo-frontend
  labels:
    app: ecsdemo-frontend
  namespace: default
spec:
  replicas: 3
  selector:
    matchLabels:
      app: ecsdemo-frontend
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: ecsdemo-frontend
    spec:
      containers:
      - image: brentley/ecsdemo-frontend:latest
        imagePullPolicy: Always
        name: ecsdemo-frontend
        ports:
        - containerPort: 3000
          protocol: TCP
        env:
        - name: CRYSTAL_URL
          value: "<http://ecsdemo-crystal.default.svc.cluster.local/crystal>"
        - name: NODEJS_URL
          value: "<http://ecsdemo-nodejs.default.svc.cluster.local/>"
---
# Source: eksdemo/templates/deployment/nodejs.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ecsdemo-nodejs
  labels:
    app: ecsdemo-nodejs
  namespace: default
spec:
  replicas: 3
  selector:
    matchLabels:
      app: ecsdemo-nodejs
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: ecsdemo-nodejs
    spec:
      containers:
      - image: brentley/ecsdemo-nodejs:latest
        imagePullPolicy: Always
        name: ecsdemo-nodejs
        ports:
        - containerPort: 3000
          protocol: TCP

에러가 발생하지 않았으므로, 설치해보도록 하겠습니다.

helm install workshop ~/environment/eksdemo
NAME: workshop
LAST DEPLOYED: Thu Nov  9 01:29:18 2023
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
kubectl get services
NAME               TYPE           CLUSTER-IP      EXTERNAL-IP                                                                    PORT(S)        AGE
ecsdemo-crystal    ClusterIP      10.100.17.10    <none>                                                                         80/TCP         63s
ecsdemo-frontend   LoadBalancer   10.100.234.39   a4b7f0b7bddac4fb595005f09f087a74-2048164521.ap-northeast-2.elb.amazonaws.com   80:30400/TCP   63s
ecsdemo-nodejs     ClusterIP      10.100.206.84   <none>                                                                         80/TCP         63s
kubernetes         ClusterIP      10.100.0.1      <none>                                                                         443/TCP        24h

helm list
NAME            NAMESPACE       REVISION        UPDATED                                 STATUS          CHART           APP VERSION
workshop        default         1               2023-11-09 01:29:18.726289414 +0000 UTC deployed        eksdemo-0.1.0   1.0

테스트를 해보도록 하겠습니다. 다음 명령의 output 주소를 복사하여 접속합니다

kubectl get svc ecsdemo-frontend -o jsonpath="{.status.loadBalancer.ingress[*].hostname}"; echo

롤백

배포중에 실수가 발생하거나 이전버전으로 돌려야하는경우 히스토리를 통해 롤백할 수 있습니다.

value.yaml을 열고 node.js 이미지 항목의 이미지 이름을 brentley/ecsdemo-nodejs-non-existing 으로 변경합니다. 이미지가 존재하지 않으므로 배포가 중단될것입니다.

다음 명령을 통해 변경사항을 적용해보도록 하겠습니다.

helm upgrade workshop ~/environment/eksdemo

이미지상태를 확인해보도록 하겠습니다.

kubectl get pods -A
NAMESPACE              NAME                                         READY   STATUS             RESTARTS   AGE
default                ecsdemo-nodejs-6f46c9d7f7-phgw2              0/1     ImagePullBackOff   0          22s

실패한 배포를 롤백해보도록 하겠습니다. 개정버전을 확인합니다.

helm history workshop

REVISION        UPDATED                         STATUS          CHART           APP VERSION     DESCRIPTION     
1               Thu Nov  9 01:29:18 2023        superseded      eksdemo-0.1.0   1.0             Install complete
2               Thu Nov  9 01:35:44 2023        superseded      eksdemo-0.1.0   1.0             Upgrade complete
3               Thu Nov  9 01:36:52 2023        superseded      eksdemo-0.1.0   1.0             Upgrade complete
4               Thu Nov  9 01:37:48 2023        deployed        eksdemo-0.1.0   1.0             Upgrade complete

개정1로 롤백해보도록 하겠습니다.

helm rollback workshop 1

Rollback was a success! Happy Helming!

이미지 상태를 확인합니다.

kubectl get pods -A

NAMESPACE              NAME                                         READY   STATUS    RESTARTS   AGE
default                ecsdemo-nodejs-6c94969d-79hq9                1/1     Running   0          11m
default                ecsdemo-nodejs-6c94969d-gztsr                1/1     Running   0          11m
default                ecsdemo-nodejs-6c94969d-rrjtj                1/1     Running   0          11m

성공적으로 롤백되었습니다.

리소스 정리

다음 명령을 사용하여 생성하였던 helm 차트 릴리즈를 제거할 수 있습니다.