컨테이너식 웹 애플리케이션 배포

이 가이드에서는 Docker 컨테이너 이미지로 웹 애플리케이션을 패키징하고 이 컨테이너 이미지를 사용자의 요구에 따라 확장할 수 있는 부하 분산 복제본 집합으로 Google Kubernetes Engine 클러스터에서 실행하는 방법을 살펴봅니다.

목표

GKE에서 애플리케이션을 패키징하고 배포하려면 다음을 수행해야 합니다.

  1. 앱을 Docker 이미지로 패키징하기
  2. 머신에서 로컬로 컨테이너 실행하기(선택사항)
  3. 이미지를 레지스트리에 업로드하기
  4. 컨테이너 클러스터 만들기
  5. 앱을 클러스터에 배포하기
  6. 앱을 인터넷에 노출하기
  7. 배포 확장하기
  8. 앱의 새 버전 배포하기

시작하기 전에

다음 단계에 따라 Kubernetes Engine API를 사용 설정합니다.
  1. Google Cloud Platform Console에서 Kubernetes Engine 페이지로 이동합니다.
  2. 프로젝트를 만들거나 선택합니다.
  3. API 및 관련 서비스가 사용 설정될 때까지 기다립니다. 몇 분 정도 걸릴 수 있습니다.
  4. Google Cloud Platform 프로젝트에 결제가 사용 설정되어 있는지 확인하세요.

    결제 사용 설정 방법 알아보기

옵션 A: Google Cloud Shell 사용

이 가이드에서 사용되는 gcloud, docker, kubectl 명령줄 도구와 함께 사전 설치되는 Google Cloud Shell을 사용하여 이 가이드를 진행할 수 있습니다. Cloud Shell을 사용하는 경우, 이러한 명령줄 도구를 워크스테이션에 설치할 필요가 없습니다.

Google Cloud Shell을 사용하려면 다음을 수행합니다.

  1. Google Cloud Platform Console로 이동합니다.
  2. 콘솔 창의 상단에서 Cloud Shell 활성화 버튼을 클릭합니다.

    Google Cloud Platform Console

    콘솔 하단의 새로운 프레임 내에 Cloud Shell 세션이 열리면서 명령줄 프롬프트가 표시됩니다.

    Cloud Shell 세션

옵션 B: 로컬로 명령줄 도구 사용

워크스테이션에서 이 가이드를 따르려면 다음 도구를 설치해야 합니다.

  1. gcloud 명령줄 도구가 포함된 Google Cloud SDK를 설치합니다.
  2. gcloud 명령줄 도구를 사용하여 Kubernetes 명령줄 도구를 설치합니다. kubectl은 GKE 클러스터의 클러스터 조정 시스템인 Kubernetes와 통신하는 데 사용됩니다.

    gcloud components install kubectl
  3. Docker Community Edition(CE)을 워크스테이션에 설치합니다. 이것은 애플리케이션의 컨테이너 이미지를 빌드하는 데 사용됩니다.

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

gcloud 명령줄 도구의 기본값 설정

gcloud 명령줄 도구에서 프로젝트 IDCompute Engine 영역(zone) 옵션을 입력하는 시간을 절약하기 위해 기본값을 설정할 수 있습니다.
gcloud config set project [PROJECT_ID]
gcloud config set compute/zone us-central1-b

1단계: 컨테이너 이미지 빌드

GKE는 Docker 이미지를 애플리케이션 배포 형식으로 허용합니다. Docker 이미지를 빌드하려면 애플리케이션과 Dockerfile이 있어야 합니다.

이 가이드에서는 Go로 작성된 웹 서버인 hello-app이라는 샘플 웹 애플리케이션을 배포합니다. 이 애플리케이션은 포트 80에서 모든 요청에 'Hello, World!' 메시지로 응답합니다.

이 애플리케이션은 이미지를 빌드하는 방법에 대한 안내가 포함된 Dockerfile을 사용하여 Docker 이미지로 패키징됩니다. 이후에 이 Dockerfile을 사용하여 애플리케이션을 패키징합니다.

hello-app 소스 코드를 다운로드하려면 다음 명령어를 실행하세요.

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

아래 명령어를 실행하여 gcloud에서 구성된 프로젝트 ID를 검색해 셸에서 PROJECT_ID 환경 변수를 설정합니다.

export PROJECT_ID="$(gcloud config get-value project -q)"

PROJECT_ID의 값은 컨테이너 이미지를 비공개 Container Registry로 푸시하기 위해 컨테이너 이미지에 태그를 지정하는 데 사용됩니다.

이 애플리케이션의 컨테이너 이미지를 빌드하고 업로드를 위해 태그를 지정하려면 다음 명령어를 실행하세요.

docker build -t gcr.io/${PROJECT_ID}/hello-app:v1 .

이 명령어는 Docker에게 현재 디렉토리의 Dockerfile을 사용하여 이미지를 빌드하고 gcr.io/my-project/hello-app:v1과 같은 이름으로 태그를 지정하도록 지시합니다. gcr.io 프리픽스는 이미지가 호스팅될 Google Container Registry를 가리킵니다. 이 명령어를 실행해도 이미지는 아직 업로드되지 않습니다.

docker images 명령어를 실행하여 빌드가 성공적인지 확인할 수 있습니다.

docker images
출력:
REPOSITORY                     TAG                 IMAGE ID            CREATED             SIZE
gcr.io/my-project/hello-app    v1                  25cfadb1bf28        10 seconds ago      54 MB

2단계: 컨테이너 이미지 업로드

GKE가 다운로드하고 실행할 수 있도록 컨테이너 이미지를 레지스트리에 업로드해야 합니다.

먼저 Container Registry에 인증하도록 Docker 명령줄 도구를 구성합니다(한 번만 실행해야 합니다).

gcloud auth configure-docker

이제 Docker 명령줄 도구를 사용하여 이미지를 Container Registry에 업로드할 수 있습니다.

docker push gcr.io/${PROJECT_ID}/hello-app:v1

3단계: 컨테이너를 로컬로 실행(선택사항)

로컬 Docker 엔진을 사용하여 컨테이너 이미지를 테스트하려면 다음 명령어를 실행하세요.

docker run --rm -p 8080:8080 gcr.io/${PROJECT_ID}/hello-app:v1

Cloud Shell을 사용하는 경우, 오른쪽 상단의 '웹 미리보기' 버튼을 클릭하여 브라우저 탭에서 실행되는 애플리케이션을 볼 수 있습니다. 그렇지 않으면 새 터미널 창(또는 Cloud Shell 탭)을 열고 컨테이너가 작동하며 요청에 "Hello, World!"로 응답하는지 확인합니다.

curl http://localhost:8080

성공적 응답을 확인한 후 docker run 명령어가 실행 중인 탭에서 Ctrl+C를 눌러 컨테이너를 종료할 수 있습니다.

4단계: 컨테이너 클러스터 만들기

컨테이너 이미지가 레지스트리에 저장되었으므로 컨테이너 이미지를 실행할 컨테이너 클러스터를 만들어야 합니다. 클러스터는 GKE를 구동하는 오픈소스 클러스터 조정 시스템인 Kubernetes를 실행하는 Compute Engine VM 인스턴스의 풀로 구성됩니다.

GKE 클러스터를 만든 후 Kubernetes를 사용하여 애플리케이션을 클러스터에 배포하고 애플리케이션의 수명 주기를 관리합니다.

다음 명령어를 실행하여 hello-cluster라는 2노드 클러스터를 만듭니다.

gcloud container clusters create hello-cluster --num-nodes=2

클러스터가 생성되려면 몇 분 정도 걸릴 수 있습니다. 명령어가 완료되면 다음 명령어를 실행하고 클러스터의 작업자 VM 인스턴스 3개를 확인합니다.

gcloud compute instances list
출력:
NAME                                          ZONE           MACHINE_TYPE   PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP     STATUS
gke-hello-cluster-default-pool-07a63240-822n  us-central1-b  n1-standard-1               10.128.0.7   35.192.16.148   RUNNING
gke-hello-cluster-default-pool-07a63240-kbtq  us-central1-b  n1-standard-1               10.128.0.4   35.193.136.140  RUNNING

5단계: 애플리케이션 배포

GKE 클러스터에서 애플리케이션을 배포하고 관리하려면 Kubernetes 클러스터 관리 시스템과 통신해야 합니다. 일반적으로는 kubectl 명령줄 도구를 사용하여 이 작업을 수행합니다.

Kubernetes는 애플리케이션을 포드로 나타냅니다. 포드는 컨테이너(또는 긴밀하게 결합된 컨테이너의 그룹)를 나타내는 단위입니다. 포드는 Kubernetes에서 배포 가능한 최소 단위입니다. 이 가이드에서 각 포드에는 hello-app 컨테이너만 포함되어 있습니다.

아래의 kubectl run 명령어를 실행하면 Kubernetes가 클러스터에 hello-web이라는 배포를 만듭니다. 이 배포는 복제본이라고 하는 애플리케이션의 여러 복사본을 관리하고, 이러한 복사본이 클러스터의 개별 노드에서 실행되도록 예약합니다. 이 경우, 배포는 애플리케이션의 포드 하나만 실행합니다.

다음 명령어를 실행하여 포드 8080에서 수신 대기하는 애플리케이션을 배포합니다.

kubectl run hello-web --image=gcr.io/${PROJECT_ID}/hello-app:v1 --port 8080

배포에 의해 생성된 포드를 보려면 다음 명령어를 실행하세요.

kubectl get pods
출력:
NAME                         READY     STATUS    RESTARTS   AGE
hello-web-4017757401-px7tx   1/1       Running   0          3s

6단계: 애플리케이션을 인터넷에 노출

기본적으로 GKE에서 실행하는 컨테이너는 외부 IP 주소가 없기 때문에 인터넷에서 액세스할 수 없습니다. 애플리케이션을 인터넷의 트래픽에 명시적으로 노출해야 하는 경우, 다음 명령어를 실행하세요.

kubectl expose deployment hello-web --type=LoadBalancer --port 80 --target-port 8080

위의 kubectl expose 명령어는 애플리케이션의 pod에 네트워킹 및 IP 지원을 제공하는 서비스 리소스를 만듭니다. GKE는 애플리케이션의 외부 IP와 부하 분산기(청구 대상)를 만듭니다.

--port 플래그는 부하 분산기에서 구성된 포트 번호를 지정하고, --target-port 플래그는 이전 단계의 kubectl run 명령어에 의해 생성된 pod가 사용하는 포트 번호를 지정합니다.

애플리케이션의 외부 IP 주소를 확인한 후 IP 주소를 복사하세요. 애플리케이션에 액세스할 수 있는지 확인하려면 브라우저가 이 URL(예: http://203.0.113.0)을 가리키도록 합니다.

7단계: 애플리케이션 확장

kubectl scale 명령어를 사용하여 애플리케이션의 배포 리소스에 더 많은 복제본을 추가할 수 있습니다. 배포에 복제본 2개를 추가하려면(총 3개) 다음 명령어를 실행하세요.

kubectl scale deployment hello-web --replicas=3

다음 명령어를 실행하면 새 복제본이 클러스터에서 실행되는 것을 볼 수 있습니다.

kubectl get deployment hello-web
출력:
NAME        DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
hello-web   3         3         3            2           1m
kubectl get pods
출력:
NAME                         READY     STATUS    RESTARTS   AGE
hello-web-4017757401-ntgdb   1/1       Running   0          9s
hello-web-4017757401-pc4j9   1/1       Running   0          9s
hello-web-4017757401-px7tx   1/1       Running   0          1m

이제 애플리케이션의 여러 인스턴스가 서로 독립적으로 실행되며, kubectl scale 명령어를 사용하여 애플리케이션의 용량을 조정할 수 있습니다.

이전 단계에서 프로비저닝한 부하 분산기가 이 새로운 복제본으로 트래픽을 자동으로 라우팅하기 시작합니다.

8단계: 앱의 새 버전 배포

GKE의 롤링 업데이트 메커니즘으로 인해 실행 중인 모든 복제본에서 시스템이 이전 컨테이너 이미지의 인스턴스를 새것으로 교체할 때도 애플리케이션은 계속 실행되며 사용 가능합니다.

동일한 소스 코드를 빌드하고 v2로 태그를 지정하여 애플리케이션 v2 버전의 이미지를 만들 수 있습니다. 또는 이미지를 빌드하기 전에 "Hello, World!" 문자열을 "Hello, GKE!"로 변경할 수 있습니다.

docker build -t gcr.io/${PROJECT_ID}/hello-app:v2 .

그런 다음 이미지를 Google Container Registry로 푸시합니다.

docker push gcr.io/${PROJECT_ID}/hello-app:v2

이제 이미지 업데이트로 롤링 업데이트를 기존 배포에 적용합니다.

kubectl set image deployment/hello-web hello-web=gcr.io/${PROJECT_ID}/hello-app:v2

http://[EXTERNAL_IP]에서 애플리케이션을 다시 방문하고 변경사항이 적용되었는지 확인합니다.

삭제

이 가이드에서 사용한 리소스 비용이 Google Cloud Platform 계정에 청구되지 않도록 하는 방법은 다음과 같습니다.

이 가이드를 완료한 후에는 다음 단계에 따라 자신의 계정에 원치 않는 비용이 발생하지 않도록 다음 리소스를 삭제합니다.

  1. 서비스 삭제: 이 단계는 서비스를 위해 생성된 Cloud Load Balancer를 할당 해제합니다.

    kubectl delete service hello-web

  2. 컨테이너 클러스터 삭제: 이 단계에서는 컴퓨팅 인스턴스, 디스크, 네트워크 리소스와 같이 컨테이너 클러스터를 구성하는 리소스를 삭제합니다.

    gcloud container clusters delete hello-cluster

다음 단계

이 페이지가 도움이 되었나요? 평가를 부탁드립니다.

다음에 대한 의견 보내기...

Kubernetes Engine 가이드