참고 : 

컨테이너화된 웹 애플리케이션 배포  |  Kubernetes Engine  |  Google Cloud

 

컨테이너화된 웹 애플리케이션 배포  |  Kubernetes Engine  |  Google Cloud

의견 보내기 컨테이너화된 웹 애플리케이션 배포 이 튜토리얼에서는 웹 애플리케이션을 Docker 컨테이너 이미지에 패키징하고 Google Kubernetes Engine(GKE) 클러스터에서 이 컨테이너 이미지를 실행하

cloud.google.com

 

이 튜토리얼에서는 웹 애플리케이션을 Docker 컨테이너 이미지에 패키징하고 Google Kubernetes Engine(GKE) 클러스터에서 이 컨테이너 이미지를 실행하는 방법을 설명합니다. 그러면 사용자는 사용자 니즈에 따라 확장 가능한 부하 분산된 복제본 세트로서 웹 애플리케이션을 배포하게 됩니다.

 

목표

  • 샘플 웹 애플리케이션을 Docker 이미지로 패키징합니다.
  • Artifact Registry에 Docker 이미지 업로드
  • GKE 클러스터 만들기
  • 샘플 앱을 클러스터에 배포
  • 배포의 자동 확장 관리
  • 샘플 앱을 인터넷에 노출
  • 샘플 앱의 새 버전을 배포합니다.

시작하기 전에

다음 단계에 따라 Kubernetes Engine API를 사용을 설정합니다.

좌측 메뉴의 "API 및 서비스" - "사용 설정된 API 및 서비스" 메뉴를 클릭합니다. 

우측에 화면이 나타나면 "API 서비스 사용 설정"을 클릭합니다.

검색창에 "Artifact Registry" 입력합니다. 검색 결과인 Artifact Registry API를 클릭한 후 "사용"을 클릭합니다.

검색창에 "Kubernetes Engine API"를 입력합니다. 검색 결과인 Kubernetes Engine API를 클릭한 후 "사용"을 클릭합니다.

Google Cloud Console의 프로젝트 선택기 페이지에서 Google Cloud 프로젝트를 선택하거나 만듭니다.

 

Artifact Registry and Google Kubernetes Engine API를 사용 설정합니다.

 

- gcloud cli 설치

gcloud CLI를 사용하여 Kubernetes 명령줄 도구를 설치

Docker Community Edition(CE)을 워크스테이션에 설치합니다

Git 소스 제어 도구를 설치하여 GitHub에서 샘플 애플리케이션을 가져옵니다.

 

 

저장소 만들기

이 문서에서는 Artifact Registry에 이미지를 저장하고 레지스트리에서 배포합니다. Artifact Registry는 Google Cloud에서 권장되는 Container Registry입니다. 이 문서에서는 hello-repo라는 저장소를 만듭니다.

 

PROJECT_ID 환경 변수를 Google Cloud 프로젝트 ID<PROJECT_ID>로 설정합니다. 컨테이너 이미지를 빌드하고 저장소에 푸시할 때 이 환경 변수를 사용합니다.

export PROJECT_ID=<PROJECT_ID>

Google Cloud CLI의 프로젝트 ID를 설정합니다.

$ gcloud config set project $PROJECT_ID
Updated property [core/project].

다음 명령어를 사용하여 hello-repo 저장소를 만듭니다. REGION을 asia-northeast3과 같은 저장소의 리전으로 바꿉니다.

gcloud artifacts repositories create hello-repo \
   --repository-format=docker \
   --location=REGION \
   --description="Docker repository"

 사용 가능한 위치 목록을 보려면 다음 명령어를 실행합니다.

gcloud artifacts locations list

 

컨테이너 이미지 빌드

이 문서에서는 샘플 웹 애플리케이션인 hello-app을 배포합니다. 이 애플리케이션은 Go로 작성된 웹 서버로, 모든 요청에 대해 포트 8080에서 Hello, World!로 응답합니다.

GKE는 Docker 이미지를 애플리케이션 배포 형식으로 허용합니다. hello-app을 GKE에 배포하기 전에 hello-app 소스 코드를 Docker 이미지로 패키징해야 합니다.

Docker 이미지를 빌드하려면 소스 코드와 Dockerfile이 있어야 합니다. Dockerfile에는 이미지 빌드 방법에 대한 안내가 포함되어 있습니다.

다음 명령어를 실행하여 hello-app 소스 코드와 Dockerfile을 다운로드합니다

git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
cd kubernetes-engine-samples/hello-app

hello-app의 Docker 이미지를 빌드하고 태그를 지정합니다. REGION은 각자가 생성하고자 하는 리전을 지정합니다. 본 문서에서는 asia-northeast3 로 지정했습니다.

docker build -t REGION-docker.pkg.dev/${PROJECT_ID}/hello-repo/hello-app:v1 .

이 명령어는 현재 디렉터리에서 Dockerfile을 사용하여 이미지를 빌드하고, 로컬 환경에 저장하고, asia-northeast3-docker.pkg.dev/my-project/hello-repo/hello-app:v1과 같은 이름으로 태그를 지정하도록 Docker에 지시합니다. 다음 섹션에서 이미지가 Artifact Registry로 푸시됩니다.

PROJECT_ID 변수는 컨테이너 이미지를 Google Cloud 프로젝트의 hello-repo 저장소와 연결합니다.

asia-northeast3-docker.pkg.dev 프리픽스는 저장소의 리전 호스트인 Artifact Registry 를 나타냅니다.

 

GCP 콘솔에서 좌측 메뉴에서 "Artifact Registry"를 클릭하면 저장소 목록이 나타납니다.

docker images 명령어를 실행하여 빌드가 성공했는지 확인합니다
docker images

REPOSITORY                                                              TAG          IMAGE ID       CREATED          SIZE
asia-northeast3-docker.pkg.dev/pjt-aicallbot-prd/hello-repo/hello-app   v1           8b9a9caee254   24 minutes ago   11.5MB
<none>                                                                  <none>       a66d4b996c65   24 minutes ago   263MB
alpine                                                                  latest       e9adb5357e84   6 days ago       5.57MB
golang                                                                  1.8-alpine   4cb86d3661bf   4 years ago      257MB

 

로컬에서 컨테이너 실행

로컬 PC Docker 엔진을 사용하여 컨테이너 이미지를 테스트합니다. REGION은 각자가 생성하고자 하는 REGION을 지정합니다. 본 문서에서는 asia-northeast3 로 지정했습니다.

docker run --rm -p 8080:8080 REGION-docker.pkg.dev/${PROJECT_ID}/hello-repo/hello-app:v1

브라우저에 http://localhost:8080 을 입력하면 아래와 같은 화면이 나타납니다.

[참고사항]

아래와 같이 오류가 발생하면 

C:\Program Files (x86)\Google\Cloud SDK\git_dir\hello-app>docker run --rm -p 8080:8080 asia-northeast3-docker.pkg.dev/pjt-aicallbot-prd/hello-repo/hello-app:v1
Unable to find image 'asia-northeast3-docker.pkg.dev/pjt-aicallbot-prd/hello-repo/hello-app:v1' locally
docker: Error response from daemon: Head "https://asia-northeast3-docker.pkg.dev/v2/pjt-aicallbot-prd/hello-repo/hello-app/manifests/v1": 
denied: Permission "artifactregistry.repositories.downloadArtifacts" denied on resource "projects/pjt-aicallbot-prd/locations/asia-northeast3/repositories/hello-repo" (or it may not exist).
See 'docker run --help'.

gcloud auth configure-docker REGION-docker.pkg.dev 를 수행합니다. REGION은 각자의 REGION 정보에 맞도록 변경합니다. 본 문서에서는 asia-northeast3 를 지정합니다.

hello-app> gcloud auth configure-docker asia-northeast3-docker.pkg.dev
Adding credentials for: asia-northeast3-docker.pkg.dev
After update, the following will be written to your Docker config file located at [C:\Users\LGCNS\.docker\config.json]:
 {
  "credHelpers": {
    "asia-northeast3-docker.pkg.dev": "gcloud"
  }
}

Do you want to continue (Y/n)?  Y
Docker configuration file updated.

 

Cloud Shell을 사용할 경우 웹 미리보기 버튼 

을 클릭한 후 "8080 포트에서 미리보기" 메뉴를 선택합니다. 

브라우저 창이 열리고 아래와 같은 내용이 브라우저에 표시됩니다.

또는 새로운 터미널 창(Cloud Shell 탭)을 열고 다음 명령어를 실행하여 'Hello, World!'로 요청에 응답하는지 확인합니다.

curl http://localhost:8080

성공적인 응답을 확인하면 docker run 명령어가 실행 중인 탭에서 Ctrl+C 키를 눌러 컨테이너를 종료합니다.

 

Artifact Registry에 Docker 이미지 푸시

GKE 클러스터에서 컨테이너 이미지를 다운로드하고 실행할 수 있도록 컨테이너 이미지를 레지스트리에 업로드해야 합니다. 이 튜토리얼에서는 Artifact Registry에 컨테이너를 저장합니다.

  1. Artifact Registry에 인증하도록 Docker 명령줄 도구를 구성합니다. REGION은 각자의 리전으로 변경합니다.
    gcloud auth configure-docker REGION-docker.pkg.dev
  2. 방금 빌드한 Docker 이미지를 저장소로 푸시합니다.
    docker push REGION-docker.pkg.dev/${PROJECT_ID}/hello-repo/hello-app:v1

 

GKE 클러스터 만들기

이제 Docker 이미지가 Artifact Registry에 저장되었으므로 GKE 클러스터를 만들어 hello-app을 이미지를 실행합니다. GKE 클러스터는 Kubernetes를 실행하는 VM 인스턴스의 풀로 구성됩니다.

 

방법1. Cloud Shell 에서 클러스터 만들기

GKE 클러스터는 standard 모드와 autopilot 모드가 있습니다. standard 모드 클러스터는 영역(zone) 클러스터이고 autopilot 모드 클러스터는 리전 클러스터입니다. 따라서 각기 모드에 따라 아래와 같이 명령어를 수행해 줍니다.

 

1) 표준 클러스터 모드:

GKE 클러스터를 생성할 영역을 지정합니다.(예: asia-northeast3-a)

아래 COPUTE_ZONE 은 asia-northeast3-a 로 수정합니다.

syntax : gcloud config set compute/zone COMPUTE_ZONE

gcloud config set compute/zone asia-northeast3-a

hello-cluster라는 클러스터를 만듭니다. 

gcloud container clusters create hello-cluster

## 결과
kubeconfig entry generated for hello-cluster.
NAME           LOCATION           MASTER_VERSION   MASTER_IP     MACHINE_TYPE  NODE_VERSION     NUM_NODES  STATUS
hello-cluster  asia-northeast3-a  1.21.9-gke.1002  34.64.81.157  e2-medium     1.21.9-gke.1002  3          RUNNING

다음 명령어를 실행하여 클러스터의 노드를 확인합니다.

kubectl get nodes

 

2) Autopilot 클러스터 모드

GKE 클러스터를 생성할 리전을 지정합니다.(예: asia-northeast3)

아래 COMPUTE_REGION 은 asia-northeast3 로 수정합니다.

syntax : gcloud config set compute/zone COMPUTE_REGION

gcloud config set compute/region asia-northeast3

hello-autopi-cluster라는 클러스터를 만듭니다.

gcloud container clusters create-auto hello-autopi-cluster

[참고] 아래 명령어는 projet, clusters, region 등의 옵션을 추가한 부분이다.

gcloud container --project "pjt-aicallbot-prd" clusters create-auto "autopilot-cluster-1" --region "asia-northeast3" --network "projects/pjt-aicallbot-prd/global/networks/vpc-aicallbot-prd" --subnetwork "projects/pjt-aicallbot-prd/regions/asia-northeast3/subnetworks/sbn-aicallbot-sql-prd-01" 

 

다음 명령어를 실행하여 클러스터의 노드를 확인합니다.

kubectl get nodes

 

방법2. console에서 클러스터 만들기

 

Cloud Console에서 Google Kubernetes Engine 페이지로 이동합니다

만들기를 클릭합니다.

  1. 표준이나 Autopilot 모드를 선택하고 구성을 클릭합니다.
  2. 이름 필드에 hello-cluster 이름을 입력합니다.
  3. 영역 또는 리전을 선택합니다. 표준 클러스터: 위치 유형에서 영역을 선택한 후 영역 드롭다운 목록에서 Compute Engine 영역(예: us-west1-a)을 선택합니다. Autopilot 클러스터: 리전 드롭다운 목록에서 Compute Engine 리전(예: us-west1)을 선택합니다.
  4. 만들기를 클릭합니다. 그러면 GKE 클러스터가 생성됩니다.
  5. 클러스터가 생성될 때까지 기다립니다. 클러스터가 준비되면 클러스터 이름 옆에 녹색 체크표시가 나타납니다.

 

GKE에 샘플 앱 배포

이제 Docker 이미지를 GKE 클러스터에 배포할 준비가 되었습니다.

Kubernetes는 하나 이상의 컨테이너를 포함하는 확장 가능한 단위인 포드로 나타냅니다. Pod는 Kubernetes에서 배포 가능한 최소 단위입니다. 일반적으로 Pod를 클러스터 전체에 걸쳐 함께 확장하고 배포할 수 있는 복제본 집합으로 배포합니다. 복제본 세트를 배포하는 한 가지 방법은 Kubernetes 배포를 사용하는 것입니다.

이 섹션에서는 클러스터에서 hello-app이 실행되도록 Kubernetes 배포를 만듭니다. 이 배포에는 복제본(포드)이 있습니다. 배포 포드 하나에는 컨테이너 하나(hello-app Docker 이미지)만 포함됩니다. 또한 CPU 부하를 기준으로 포드 수를 3개부터 1~5개까지 확장하는 HorizontalPodAutoscaler 리소스를 만듭니다.

 

1. GKE 클러스터에 연결되어 있는지 확인합니다. COMPTE_ZONE 은 클러스터가 생성된 ZONE을 입력합니다.

gcloud container clusters get-credentials hello-cluster --zone COMPUTE_ZONE

## 아래 메시지가 출력됩니다.
Fetching cluster endpoint and auth data.
kubeconfig entry generated for hello-cluster.

2. hello-app Docker 이미지의 Kubernetes 배포를 만듭니다. REGION과 PROJECT_ID는 각자의 환경에 맞게 수정합니다.

kubectl create deployment hello-app --image=REGION-docker.pkg.dev/${PROJECT_ID}/hello-repo/hello-app:v1

3. 배포 복제본의 기준 수를 3으로 설정합니다.

kubectl scale deployment hello-app --replicas=3

4. 배포에 대한 HorizontalPodAutoscaler 리소스를 만듭니다.

kubectl autoscale deployment hello-app --cpu-percent=80 --min=1 --max=5

 

5. 생성된 포드를 보려면 다음 명령어를 실행합니다.

kubectl get pods

 

 

샘플 앱을 인터넷에 노출

포드에는 개별적으로 할당된 IP 주소가 있지만 클러스터 내에서만 이 IP에 연결할 수 있습니다. 또한 GKE 포드는 확장 요구에 따라 시작 또는 중지할 수 있도록 설계되었습니다. 또한 오류로 인해 포드가 다운되면 GKE는 해당 포드를 자동으로 다시 배포하여 매번 새 포드 IP 주소를 할당합니다.

즉, 모든 배포에서 활성 포드 집합에 해당하는 IP 주소 집합은 동적입니다.

1) 포드를 하나의 정적 호스트 이름으로 그룹화하고

2) 클러스터 포드 그룹을 클러스터 외부 인터넷에 노출하는 방법이 필요합니다.

 

Kubernetes 서비스는 이 두 가지 문제를 해결합니다. 서비스 그룹 포드는 클러스터 내의 모든 포드에서 연결할 수 있는 하나의 고정 IP 주소로 그룹화됩니다. 또한 GKE는 고정 IP에 DNS 호스트 이름을 할당합니다. 예를 들면 hello-app.default.svc.cluster.local 입니다.

GKE의 기본 서비스 유형을 ClusterIP라고 하며, 여기서 서비스는 클러스터 내부에서만 연결할 수 있는 IP 주소를 가져옵니다. 클러스터 외부에서 Kubernetes 서비스를 노출하려면 LoadBalancer 유형의 서비스를 만듭니다. 이 유형의 서비스는 인터넷을 통해 연결할 수 있는 포드 모음에 외부 부하 분산기 IP를 생성합니다.

이 섹션에서는 LoadBalancer 유형의 서비스를 사용하여 hello-app 배포를 인터넷에 노출합니다.

 

1. kubectl expose 명령어를 사용하여 hello-app 배포를 위한 Kubernetes 서비스를 생성합니다.

kubectl expose deployment hello-app --name=hello-app-service --type=LoadBalancer --port 80 --target-port 8080

여기에서 --port 플래그는 부하 분산기에 구성된 포트 번호를 지정하고 --target-port 플래그는 hello-app 컨테이너가 리슨하는 포트 번호를 지정합니다.

hello-app pod가 Kubernetes 서비스를 통해 인터넷에 노출됩니다. 

 

2. 다음 명령어를 실행하여 hello-app-service의 서비스 세부정보를 가져옵니다.

kubectl get service

## 출력
NAME                TYPE           CLUSTER-IP    EXTERNAL-IP    PORT(S)        AGE
hello-app-service   LoadBalancer   10.100.1.94   34.64.112.20   80:31390/TCP   4h22m
kubernetes          ClusterIP      10.100.0.1    <none>         443/TCP        8h

 

hello-app-service의 EXTERNAL_IP 주소를 클립보드에 복사합니다(예: 203.0.113.0).

새 브라우저를 열고 클립보드에 복사한 서비스 IP 주소를 붙여 넣습니다. Hello, World! 메시지가 Hostname 필드와 함께 표시됩니다. Hostname은 브라우저에 HTTP 요청을 제공하는 hello-app 포드 세 개 중 하나입니다.

 

샘플 앱의 새 버전 배포

이 섹션에서는 새 Docker 이미지를 빌드하고 GKE 클러스터에 배포하여 hello-app을 새 버전으로 업그레이드합니다.

GKE의 순차적 업데이트 기능을 사용하면 다운타임 없이 업데이트를 할 수 있습니다. 순차적 업데이트 중에 GKE 클러스터는 기존 hello-app 포드를 새 버전의 Docker 이미지가 포함된 포드로 점진적으로 대체합니다. 업데이트하는 동안 부하 분산기 서비스가 트래픽을 이용 가능한 포드로만 라우팅합니다.

 

1. hello 앱 소스 코드와 Dockerfile을 클론한 Cloud Shell로 돌아갑니다. main.go 파일의 hello() 함수를 업데이트하여 새 버전 2.0.0을 보고하세요.

새 hello-app Docker 이미지를 빌드하고 태그를 지정합니다. REGION과 PROJECT_ID는 각자의 환경에 맞게 수정합니다.

docker build -t REGION-docker.pkg.dev/${PROJECT_ID}/hello-repo/hello-app:v2 .

 

이미지를 Artifact Registry로 내보내기

GCP의 Artifact Registry에서 tag v2 이미지를 확인할 수 있습니다.

docker push REGION-docker.pkg.dev/${PROJECT_ID}/hello-repo/hello-app:v2

만일 아래와 같은 오류가 발생하면

denied: Permission "artifactregistry.repositories.downloadArtifacts" denied on resource "projects/pjt-aicallbot-prd/locations/asia-northeast3/repositories/hello-repo" (or it may not exist)

 

다음 명령어를 수행한 후 위의 명령어를 다시 수행합니다.

gcloud auth configure-docker asia-northeast3-docker.pkg.dev

 

이제 새 Docker 이미지를 사용하도록 hello-app Kubernetes 배포를 업데이트할 준비가 되었습니다.

 

1. kubectl set image 명령어를 사용하여 이미지 업데이트로 기존 hello-app 배포에 순차적 업데이트를 적용합니다.

kubectl set image deployment/hello-app hello-app=REGION-docker.pkg.dev/${PROJECT_ID}/hello-repo/hello-app:v2

v1 이미지 중지를 실행하는 실행 중인 포드와 v2 이미지 시작을 실행하는 새 포드를 확인합니다.

watch kubectl get pods

출력:

NAME                        READY   STATUS    RESTARTS   AGE
hello-app-89dc45f48-5bzqp   1/1     Running   0          2m42s
hello-app-89dc45f48-scm66   1/1     Running   0          2m40s

 

GCP 콘솔에서 "작업부하" 클릭 후 hello-app 를 클릭하여 상세 정보를 확인해 보면 활성 버전과 관리형 Pod의 수정 버전이 2로 변경된 것을 확인할 수 있습니다.

삭제

리소스를 삭제합니다.

 

서비스 삭제: 서비스용으로 생성된 Cloud 부하 분산기를 할당 해제합니다.

kubectl delete service hello-app-service

 

클러스터 삭제: 컴퓨팅 인스턴스, 디스크, 네트워크 리소스와 같이 클러스터를 구성하는 리소스를 삭제합니다.COMPUTE_ZONE은 자신의 ZONE으로 변경합니다.

gcloud container clusters delete hello-cluster --zone COMPUTE_ZONE

 

컨테이너 이미지 삭제: Artifact Registry에 푸시한 Docker 이미지를 삭제합니다.아래 명령어 중 REGION과 PROJECT_ID는 자신의 환경에 맞도록 변경합니다. 

gcloud artifacts docker images delete \     
REGION-docker.pkg.dev/${PROJECT_ID}/hello-repo/hello-app:v1 \     
--delete-tags --quiet

gcloud artifacts docker images delete \     
REGION-docker.pkg.dev/${PROJECT_ID}/hello-repo/hello-app:v2 \     
--delete-tags --quiet

 

** 참고자료 **

GKE 및 기타 Kubernetes 구현에 사용되는 네트워크 모델 비교  |  클라우드 아키텍처 센터  |  Google Cloud

'GCP' 카테고리의 다른 글

GCP - cloud NAT  (0) 2022.03.24
GCP - gcloud 설치 on Windows  (0) 2022.03.24
GCP-interconnect  (0) 2022.03.22
GCP - vpc peering 설정  (0) 2022.03.18
GCP - gcloud 설치 on linux  (0) 2022.03.13

+ Recent posts