# Helm을 사용하여 마이크로서비스 배포

본 실습 에서는 `kubectl`을 사용하여 모든 작업을 수동으로 수행하는 대신 사용자 지정 Helm 차트를 사용하여 마이크로 서비스를 배포하는 방법을 확인합니다.

{% hint style="info" %}
차트 템플릿 작업에 대한 자세한 내용은 [Helm 문서](https://docs.helm.sh/chart_template_guide/)를 참조 하십시오.
{% endhint %}

## 1. 차트 생성

Helm 차트는 다음과 유사한 구조를 갖습니다.

```
/eksdemo
  /Chart.yaml  # a description of the chart
  /values.yaml # defaults, may be overridden during install or upgrade
  /charts/     # May contain subcharts
  /templates/  # the template files themselves
  ...
```

이 템플릿을 따르고 다음 명령을 사용하여 **eksdemo**라는 새 차트를 만듭니다.

```
cd ~/environment
helm create eksdemo
```

## 2. 사용자 기본값 지정

새로 생성 된 **eksdemo** 디렉토리를 보면 여러 파일과 디렉토리를 볼 수 있습니다. 특히 /templates 디렉토리 안에 다음이 표시됩니다.

* `deployment.yaml` : 쿠버네티스 배포를 만들기 위한 기본 매니페스트.
* `_helpers.tpl` : 차트 전체에서 재 사용 할 수 있는 템플릿 도우미를 배치하는 공간.
* `ingress.yaml` : 서비스 용 쿠버네티스 수신 객체를 만들기 위한 기본 매니페스트.
* `NOTES.txt` : 차트의 “도움말 텍스트”. 사용자가 helm 설치를 실행할 때 표시 됩니다.
* `serviceaccount.yaml` : 서비스 계정을 만들기 위한 기본 매니페스트.
* `service.yaml` : 배포를 위한 서비스 엔드 포인트를 만들기 위한 기본 매니페스트.
* `tests /`: 차트에 대한 테스트를 포함하는 폴더

직접 사용할 파일을 만들 것이므로 기본 파일을 삭제 합니다.

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

차트를 설명 할 새 Chart.yaml 파일을 만듭니다.

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

```

다음으로 각 마이크로 서비스의 manifest 파일을 *servicename*.yaml로 템플릿 디렉터리에 복사합니다.

```
#create subfolders for each template type
mkdir -p ~/environment/eksdemo/templates/deployment
mkdir -p ~/environment/eksdemo/templates/service

# Copy and rename frontend manifests
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

# Copy and rename crystal manifests
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

# Copy and rename nodejs manifests
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

```

템플릿 디렉토리의 모든 파일은 템플릿 엔진을 통해 전송 됩니다. 이는 현재 쿠버네티스에 있는 그대로 전송되는 일반 YAML 파일입니다.

## 3. values.yaml 파일 만들기

하드 코딩 된 값을 제거하여 더 많은 사용자 정의를 가능하게 하기 위해 일부 값을 `template directives`로 대체 해 보겠습니다.

Cloud9 편집기에서 \~/environment/eksdemo/templates/deployment/frontend.yaml을 엽니다.

* `spec`에서 **replicas : 1**을 찾아 으로 바꿉니다:

  ```
  {{ .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 }}   |

{% hint style="info" %}
frontend.yaml, crystal.yaml, nodejs.yaml 파일에 대해서 모두 적용해야 합니다.
{% endhint %}

![](/files/-MhCm7vO7X4nJtwlLI-y)

템플릿 기본값으로 values.yaml 파일을 생성합니다. 다음 코드을 실행하여 `template directives`를 기본값으로 채웁니다

```
cat <<EoF > ~/environment/eksdemo/values.yaml
# Default values for eksdemo.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.

# Release-wide Values
replicas: 3
version: 'latest'

# Service Specific Values
nodejs:
  image: brentley/ecsdemo-nodejs
crystal:
  image: brentley/ecsdemo-crystal
frontend:
  image: brentley/ecsdemo-frontend
EoF

```

## 4. EKSDEMO 차트 배포

실제로 배포하지 않고 차트의 구문과 유효성을 테스트 하기 위해 `--dry-run` 플래그를 사용하여 검증합니다.

다음 명령은 렌더링 된 템플릿을 빌드하고 출력 합니다.&#x20;

```
helm install --debug --dry-run workshop ~/environment/eksdemo
```

템플릿으로 생성 된 값이 올바른지 확인 합니다.

템플릿을 테스트 했으므로 이제 차트를 배포해 보겠습니다.

```
helm install workshop ~/environment/eksdemo
```

이전에 [nginx Helm 차트에서 보았던 것](https://main.dccvg1wka0oik.amplifyapp.com/helm_root/helm_nginx/)과 유사합니다. 명령의 출력에는 다음과 유사한 배포 상태, 개정, namespace 등에 대한 정보가 포함됩니다.

![](/files/-MhCoCpafRj4_DKUT18l)

기본 서비스, 포드 및 배포를 검토하려면 다음을 실행 합니다:

```
kubectl get svc,po,deploy
```

## 5. 서비스 테스트

eksdemo 차트가 생성 한 서비스를 테스트하기 위해 차트를 배포 할 때 생성 된 ELB의 엔드포인트 이름을 가져 옵니다.

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

해당 주소를 복사하여 브라우저의 새 탭에 붙여 넣으십시오. 다음과 유사한 내용이 표시 되어야 합니다.

![](/files/-MhCvbtd2eHaUR0A4sil)

## 6. 롤백

배포 중에 실수가 발생하면 Helm을 사용하여 쉽게 실행을 취소 하거나 이전에 배포한 버전으로 “롤백” 할 수 있습니다.

**values.yaml**을 열고 `nodejs.image` 아래의 image : **brentley/ecsdemo-nodejs-non-existing**으로 수정 합니다. 이 이미지는 존재하지 않으므로 배포가 중단 될 것입니다. 업데이트 된 데모 애플리케이션 차트를 배포합니다.

```
helm upgrade workshop ~/environment/eksdemo
```

롤링 업그레이드는 새 이미지로 새 nodejs 파드를 만드는 것으로 시작 됩니다. 새로운 `ecsdemo-nodejs` 파드는 존재하지 않는 이미지를 가져 오지 못합니다. `kubectl get pods`를 실행하여 `ImagePullBackOff` 오류를 확인합니다.

```
kubectl get pods
```

![](/files/-MhCx-nW3ePjDFe68oDA)

`helm status workshop`을 실행하여 `LAST DEPLOYED` 타임 스탬프를 확인 합니다.

```
helm status workshop
```

이것은`helm history workshop`의 마지막 항목과 일치해야 합니다.

```
helm history workshop
```

![](/files/-MhCxUeE_0DEYwUF6igz)

실패한 업그레이드에 대해서 이전 애플리케이션 버전으로 롤백합니다.(모든 버전으로 롤백 가능함)

```
# rollback to the 1st revision
helm rollback workshop 1
```

다음을 사용하여 `workshop` 릴리스 상태를 확인 합니다:

```
helm status workshop
```

오류가 사라 졌는지 확인 합니다.

![](/files/-MhCyfYVxN1heoIUb0_K)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://wjlee81.gitbook.io/amazon-eks/helm/helm-1.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
