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

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

목표

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

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

시작하기 전에

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

옵션 A: Google Cloud Shell 사용

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

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

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

    Google Cloud Platform Console

    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에서 샘플 애플리케이션을 가져옵니다.

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

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

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

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

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

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

PROJECT_ID 환경 변수를 Google Cloud 프로젝트 ID로 설정합니다. 이 변수는 컨테이너 이미지를 프로젝트의 Container Registry와 연결하는 데 사용됩니다.

    export PROJECT_ID=[PROJECT_ID]
    

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

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

이 명령어는 현재 디렉터리에서 Dockerfile을 사용하여 이미지를 빌드하고 gcr.io/my-project/hello-app:v1과 같은 이름으로 태그를 지정하도록 Docker에 지시합니다. 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를 사용하여 애플리케이션을 클러스터에 배포하고 애플리케이션의 수명 주기를 관리합니다.

gcloud 도구에 대한 프로젝트 IDCompute Engine 영역 옵션을 설정합니다.

    gcloud config set project $PROJECT_ID
    gcloud config set compute/zone [COMPUTE_ENGINE_ZONE]

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

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

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

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

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

다음 명령어를 실행하여 애플리케이션을 배포합니다.

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

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

    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 플래그는 hello-app 컨테이너가 수신 대기하는 포트 번호를 지정합니다.

애플리케이션의 외부 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-app=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

다음 단계