Google Kubernetes Engine의 Kubernetes에 ASP.NET Core 앱 배포

1. 개요

ASP.NET Core는 C# 프로그래밍 언어를 사용하여 최신 클라우드 기반 인터넷 연결 애플리케이션을 빌드하기 위한 새로운 오픈소스 및 크로스 플랫폼 프레임워크입니다.

Kubernetes는 노트북에서 고가용성 다중 노드 클러스터, 퍼블릭 클라우드에서 온프레미스 배포, 가상 머신에서 베어 메탈까지 다양한 환경에서 실행할 수 있는 오픈소스 프로젝트입니다.

이 실습에서는 Kubernetes Engine에서 실행되는 Kubernetes에 간단한 ASP.NET Core 앱을 배포합니다. 이 Codelab은 Google Cloud Shell에서 ASP.NET Core 앱 빌드 및 실행 Codelab을 기반으로 합니다. 이 실습을 시작하기 전에 해당 실습을 먼저 수행하는 것이 좋습니다.

이 Codelab의 목표는 코드 (여기서는 간단한 Hello World ASP.NET Core 앱)를 Kubernetes에서 실행되는 복제된 애플리케이션으로 변환하는 것입니다. 머신에서 개발한 코드를 가져와서 Docker 컨테이너 이미지로 변환한 다음 Google Kubernetes Engine에서 이미지를 실행합니다.

다음은 이 Codelab에서 작동하는 다양한 부분의 다이어그램으로, 각 부분이 어떻게 구성되는지 이해하는 데 도움이 됩니다. Codelab을 진행하면서 참고 자료로 사용하세요. 마지막에 다다를 때쯤이면 모두 이해가 될 것입니다 (하지만 지금은 무시해도 됩니다).

7dbdc973aceef1af.jpeg

이 Codelab의 목적상 Kubernetes Engine (Compute Engine에서 실행되는 Kubernetes의 Google 호스팅 버전)과 같은 관리형 환경을 사용하면 기본 인프라를 설정하기보다는 Kubernetes를 경험하는 데 더 집중할 수 있습니다.

개발용 노트북과 같은 로컬 머신에서 Kubernetes를 실행하는 데 관심이 있다면 Minikube를 살펴봐야 합니다. 이는 개발 및 테스트 목적으로 단일 노드 Kubernetes 클러스터의 간단한 설정을 제공합니다. 원한다면 Minikube를 사용하여 이 Codelab을 진행할 수 있습니다.

학습할 내용

  • 간단한 ASP.NET Core 앱을 Docker 컨테이너로 패키징하는 방법
  • Google Kubernetes Engine (GKE)에서 Kubernetes 클러스터를 만드는 방법
  • ASP.NET Core 앱을 포드에 배포하는 방법
  • 포드에 외부 트래픽을 허용하는 방법
  • 서비스를 확장하고 업그레이드를 출시하는 방법
  • Kubernetes 그래픽 대시보드를 실행하는 방법

필요한 항목

본 가이드를 어떻게 사용하실 계획인가요?

읽기만 할 계획입니다. 읽은 다음 연습 활동을 완료할 계획입니다.

귀하의 Google Cloud Platform 사용 경험을 평가해 주세요.

<ph type="x-smartling-placeholder"></ph> 초보자 중급 숙련도

2. 설정 및 요구사항

자습형 환경 설정

  1. Google Cloud Console에 로그인하여 새 프로젝트를 만들거나 기존 프로젝트를 재사용합니다. 아직 Gmail이나 Google Workspace 계정이 없는 경우 계정을 만들어야 합니다.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • 프로젝트 이름은 이 프로젝트 참가자의 표시 이름입니다. 이는 Google API에서 사용하지 않는 문자열이며 언제든지 업데이트할 수 있습니다.
  • 프로젝트 ID는 모든 Google Cloud 프로젝트에서 고유해야 하며, 변경할 수 없습니다(설정된 후에는 변경할 수 없음). Cloud 콘솔이 고유한 문자열을 자동으로 생성합니다. 보통은 그게 뭔지 상관하지 않습니다. 대부분의 Codelab에서는 프로젝트 ID (일반적으로 PROJECT_ID로 식별됨)를 참조해야 합니다. 생성된 ID가 마음에 들지 않으면 무작위로 다른 ID를 생성할 수 있습니다. 또는 직접 시도해 보고 사용 가능한지 확인할 수도 있습니다. 이 단계 이후에는 변경할 수 없으며 프로젝트 기간 동안 유지됩니다.
  • 참고로 세 번째 값은 일부 API에서 사용하는 프로젝트 번호입니다. 이 세 가지 값에 대한 자세한 내용은 문서를 참고하세요.
  1. 다음으로 Cloud 리소스/API를 사용하려면 Cloud 콘솔에서 결제를 사용 설정해야 합니다. 이 Codelab 실행에는 많은 비용이 들지 않습니다. 이 튜토리얼이 끝난 후에 요금이 청구되지 않도록 리소스를 종료하려면 만든 리소스를 삭제하거나 전체 프로젝트를 삭제하면 됩니다. Google Cloud 새 사용자에게는 미화 $300 상당의 무료 체험판 프로그램에 참여할 수 있는 자격이 부여됩니다.

Cloud Shell 시작

Google Cloud를 노트북에서 원격으로 실행할 수 있지만, 이 Codelab에서는 Cloud에서 실행되는 명령줄 환경인 Google Cloud Shell을 사용합니다.

Cloud Shell 활성화

  1. Cloud Console에서 Cloud Shell 활성화853e55310c205094.png를 클릭합니다.

55efc1aaa7a4d3ad.png

이전에 Cloud Shell을 시작한 적이 없는 경우 기능을 설명하는 중간 화면 (스크롤해야 볼 수 있는 부분)이 표시됩니다. 이 경우 계속을 클릭합니다 (다시 표시되지 않음). 이 일회성 화면은 다음과 같습니다.

92662c6a846a5c.png

Cloud Shell을 프로비저닝하고 연결하는 데 몇 분 정도만 걸립니다.

9f0e51b578fecce5.png

가상 머신에는 필요한 개발 도구가 모두 들어 있습니다. 영구적인 5GB 홈 디렉터리를 제공하고 Google Cloud에서 실행되므로 네트워크 성능과 인증이 크게 개선됩니다. 이 Codelab에서 대부분의 작업은 브라우저나 Chromebook만 사용하여 수행할 수 있습니다.

Cloud Shell에 연결되면 인증이 완료되었고 프로젝트가 해당 프로젝트 ID로 이미 설정된 것을 볼 수 있습니다.

  1. Cloud Shell에서 다음 명령어를 실행하여 인증되었는지 확인합니다.
gcloud auth list

명령어 결과

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Cloud Shell에서 다음 명령어를 실행하여 gcloud 명령어가 프로젝트를 알고 있는지 확인합니다.
gcloud config list project

명령어 결과

[core]
project = <PROJECT_ID>

또는 다음 명령어로 설정할 수 있습니다.

gcloud config set project <PROJECT_ID>

명령어 결과

Updated property [core/project].

3. Cloud Shell에서 ASP.NET Core 앱 만들기

Cloud Shell 프롬프트에서 버전을 확인하여 dotnet 명령줄 도구가 이미 설치되어 있는지 확인할 수 있습니다. 그러면 설치된 dotnet 명령줄 도구의 버전이 출력됩니다.

dotnet --version

다음으로 새로운 기본 ASP.NET Core 웹 앱을 만듭니다.

dotnet new mvc -o HelloWorldAspNetCore

그러면 프로젝트가 생성되고 해당 종속 항목이 복원됩니다. 다음과 비슷한 메시지가 표시됩니다.

Restore completed in 11.44 sec for HelloWorldAspNetCore.csproj.

Restore succeeded.

4. ASP.NET Core 앱 실행

앱을 실행할 준비가 거의 다 되었습니다. 앱 폴더로 이동합니다.

cd HelloWorldAspNetCore

마지막으로 앱을 실행합니다.

dotnet run --urls=http://localhost:8080

애플리케이션이 8080 포트에서 수신을 시작합니다.

Hosting environment: Production
Content root path: /home/atameldev/HelloWorldAspNetCore
Now listening on: http://[::]:8080
Application started. Press Ctrl+C to shut down.

앱이 실행 중인지 확인하려면 오른쪽 상단의 웹 미리보기 버튼을 클릭하고 '포트 8080에서 미리보기'를 선택합니다.

Capture.PNG

기본 ASP.NET Core 웹페이지가 표시됩니다.

f42271880ce4d572.png

앱이 실행되는지 확인한 후 Ctrl+C를 눌러 앱을 종료합니다.

5. ASP.NET Core 앱을 Docker 컨테이너로 패키징

다음으로 컨테이너로 실행할 앱을 준비합니다. 첫 번째 단계는 컨테이너와 그 콘텐츠를 정의하는 것입니다.

앱의 기본 디렉터리에 Dockerfile을 만들어 Docker 이미지를 정의합니다.

touch Dockerfile

원하는 편집기 (vim, nano,emacs 또는 Cloud Shell의 코드 편집기)를 사용하여 Dockerfile에 다음을 추가합니다.

# Use Microsoft's official build .NET image.
# https://hub.docker.com/_/microsoft-dotnet-core-sdk/
FROM mcr.microsoft.com/dotnet/sdk:6.0-alpine AS build
WORKDIR /app

# Install production dependencies.
# Copy csproj and restore as distinct layers.
COPY *.csproj ./
RUN dotnet restore

# Copy local code to the container image.
COPY . ./
WORKDIR /app

# Build a release artifact.
RUN dotnet publish -c Release -o out

# Use Microsoft's official runtime .NET image.
# https://hub.docker.com/_/microsoft-dotnet-core-aspnet/
FROM mcr.microsoft.com/dotnet/aspnet:6.0-alpine-amd64 AS runtime
WORKDIR /app
COPY --from=build /app/out ./

# Make sure the app binds to port 8080
ENV ASPNETCORE_URLS http://*:8080

# Run the web service on container startup.
ENTRYPOINT ["dotnet", "HelloWorldAspNetCore.dll"]

Dockerfile에 포함된 중요한 구성 중 하나는 앱이 수신되는 트래픽 (8080)을 수신 대기하는 포트입니다. ASP.NET Core 앱이 수신 대기할 포트를 결정하는 데 사용하는 ASPNETCORE_URLS 환경 변수를 설정하면 됩니다.

Dockerfile을(를) 저장합니다. 이제 이미지를 빌드해 보겠습니다.

docker build -t gcr.io/${GOOGLE_CLOUD_PROJECT}/hello-dotnet:v1 .

이 작업이 완료되면 (모든 것을 다운로드하고 추출하는 데 시간이 소요됨) 이미지가 빌드되고 로컬에 저장되는 것을 확인할 수 있습니다.

docker images

REPOSITORY                             TAG   
gcr.io/yourproject-XXXX/hello-dotnet   v1            

새로 만든 컨테이너 이미지에서 포트 8080에서 로컬로 Docker 컨테이너를 실행하는 다음 명령어를 사용하여 이미지를 로컬에서 테스트합니다.

docker run -p 8080:8080 gcr.io/${GOOGLE_CLOUD_PROJECT}/hello-dotnet:v1

CloudShell의 웹 미리보기 기능을 다시 활용하세요.

2015-11-03 17:20:22.png의 스크린샷

새 탭에 기본 ASP.NET Core 웹페이지가 표시됩니다.

f42271880ce4d572.png

Docker 컨테이너에서 로컬로 앱이 제대로 실행되는지 확인한 후 Ctrl-> C를 사용하여 실행 중인 컨테이너를 중지할 수 있습니다.

이제 이미지가 의도한 대로 작동하므로 모든 Google Cloud 프로젝트는 물론 Google Cloud Platform 외부에서도 액세스할 수 있는 Docker 이미지용 비공개 저장소인 Google Container Registry로 이미지를 푸시할 수 있습니다.

docker push gcr.io/${GOOGLE_CLOUD_PROJECT}/hello-dotnet:v1

모든 것이 잘 진행되고 시간이 조금 지나면 Container Registry 섹션에 컨테이너 이미지가 나열됩니다. 이제 프로젝트 전체에서 사용할 수 있는 Docker 이미지가 생겼습니다. 이 이미지는 Kubernetes가 액세스하고 조정할 수 있으며, 이 이미지는 몇 분 후에 확인할 수 있습니다.

576374602b52f4e4.png

관심이 있다면 Google Cloud Storage에 저장된 컨테이너 이미지를 살펴볼 수 있습니다. https://console.cloud.google.com/storage/browser/에서 전체 링크를 클릭하면 https://console.cloud.google.com/project/PROJECT_ID/storage/browser/ 형식이어야 합니다.

6. Kubernetes 클러스터 만들기

이제 GKE 클러스터를 만들 준비가 되었습니다. 그 전에 웹 콘솔의 Google Kubernetes Engine 섹션으로 이동하여 시스템이 초기화될 때까지 기다립니다 (몇 초 정도 소요됨).

d5f6e3c267feea1a.png

클러스터는 Google에서 관리하는 Kubernetes 마스터 API 서버와 워커 노드 집합으로 구성됩니다. 워커 노드는 Compute Engine 가상 머신입니다.

CloudShell 세션에서 gcloud CLI를 사용하여 클러스터를 만들어 보겠습니다. 가까운 곳 ( 영역 목록)으로 구간을 조정합니다. 완료되는 데 몇 분 정도 걸릴 수 있습니다.

gcloud container clusters create hello-dotnet-cluster --cluster-version=latest --num-nodes 4 --zone europe-west1-b

최종적으로 클러스터가 생성된 것을 볼 수 있습니다.

Creating cluster hello-dotnet-cluster...done.
Created [https://container.googleapis.com/v1/projects/dotnet-atamel/zones/europe-west1-b/clusters/hello-dotnet-cluster].
kubeconfig entry generated for hello-dotnet-cluster.
NAME                  ZONE            MASTER_VERSION  
hello-dotnet-cluster  europe-west1-b  1.10.7-gke.6

이제 Google Kubernetes Engine으로 구동되는 Kubernetes 클러스터가 완벽하게 작동합니다.

eefb8d9b7f39598b.png

이제 컨테이너화된 애플리케이션을 Kubernetes 클러스터에 배포해 보겠습니다. 이제부터 Cloud Shell 환경에 이미 설정된 kubectl 명령줄을 사용합니다. 이 Codelab의 나머지 부분에서는 Kubernetes 클라이언트 및 서버 버전이 모두 1.2 이상이어야 합니다. kubectl version은 명령어의 현재 버전을 표시합니다.

7. 배포 만들기

Kubernetes 포드는 관리 및 네트워킹을 위해 함께 연결된 컨테이너 그룹입니다. 단일 컨테이너 또는 여러 컨테이너를 포함할 수 있습니다. 여기서는 비공개 Container Registry에 저장된 ASP.NET Core 이미지로 빌드된 컨테이너 하나만 사용합니다. 이는 포트 8080에서 내용을 제공합니다.

원하는 편집기 (vim, nano,emacs 또는 Cloud Shell의 코드 편집기)를 사용하여 hello-dotnet.yaml 파일을 만들고 포드의 Kubernetes 배포를 정의합니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    run: hello-dotnet
  name: hello-dotnet
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      run: hello-dotnet
  template:
    metadata:
      labels:
        run: hello-dotnet
    spec:
      containers:
      - name: hello-dotnet
        image: gcr.io/YOUR-PROJECT-ID/hello-dotnet:v1
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080

kubectl를 사용하여 기본 네임스페이스에 배포합니다.

kubectl apply -f hello-dotnet.yaml
deployment.apps/hello-dotnet created

보다시피 deployment 객체를 만들었습니다. 포드를 만들고 확장하는 방법으로 배포를 권장합니다. 여기서 새 배포는 hello-dotnet:v1 이미지를 실행하는 단일 포드 복제본을 관리합니다.

방금 만든 배포를 보려면 다음을 실행하면 됩니다.

kubectl get deployments
NAME         DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
hello-dotnet   1         1         1            1           37s

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

kubectl get pods
NAME                         READY     STATUS    RESTARTS   AGE
hello-dotnet-714049816-ztzrb   1/1       Running   0          57s

이제 몇 가지 흥미로운 kubectl 명령어를 실행해 보겠습니다. 어떤 명령어도 클러스터의 상태를 변경하지 않습니다. 전체 문서는 여기에서 확인할 수 있습니다.

kubectl get pods
kubectl cluster-info
kubectl config view
kubectl get events
kubectl logs <pod-name>

이 시점에서 Kubernetes가 제어하는 컨테이너를 실행해야 하지만 여전히 외부 세계에 액세스할 수 있도록 해야 합니다.

8. 외부 트래픽 허용하기

기본적으로 포드는 클러스터 내에서 내부 IP로만 액세스할 수 있습니다. Kubernetes 가상 네트워크 외부에서 hello-dotnet 컨테이너에 액세스할 수 있도록 하려면 포드를 Kubernetes 서비스로 노출해야 합니다.

Cloud Shell에서 kubectl expose 명령어와 --type="LoadBalancer" 플래그를 함께 사용하여 포드를 공개 인터넷에 노출할 수 있습니다. 이 플래그는 외부에서 액세스 가능한 IP를 만드는 데 필요합니다.

kubectl expose deployment hello-dotnet --type="LoadBalancer" --port=8080

이 명령어에서 사용된 플래그는 기본 인프라가 제공하는 부하 분산기(여기에서는 Compute Engine 부하 분산기)를 사용하도록 명시합니다. 포드를 직접 노출하지 않고 배포를 노출합니다. 이로 인해 배포가 관리하는 모든 포드에 걸쳐 서비스가 트래픽을 부하 분산하게 됩니다. 이번 예시에서는 포드가 1개이지만 나중에 복제본을 더 추가하게 됩니다.

Kubernetes 마스터에서는 Google Cloud Platform 외부에서 서비스에 완전하게 액세스할 수 있도록 부하 분산기, 관련된 Compute Engine 전달 규칙, 타겟 풀 및 방화벽 규칙을 만듭니다.

공개적으로 액세스할 수 있는 서비스의 IP 주소를 찾으려면 kubectl에 모든 클러스터 서비스를 나열하도록 요청하면 됩니다.

kubectl get services
NAME         CLUSTER-IP     EXTERNAL-IP      PORT(S)    AGE
hello-dotnet 10.3.253.62   104.155.20.69   8080/TCP    1m
kubernetes   10.3.240.1     <none>           443/TCP    5m

서비스에 IP 주소가 2개 있으며 둘 다 포트 8080을 제공합니다. 하나는 클라우드 가상 네트워크 내에서만 볼 수 있는 내부 IP입니다. 다른 하나는 외부 부하 분산 IP입니다. 이 예시에서 외부 IP 주소는 104.155.20.69입니다.

이제 브라우저에서 http://<EXTERNAL_IP>:8080 주소로 서비스를 사용할 수 있습니다.

6b053874002827fe.png

이제 컨테이너와 Kubernetes로 이전하면서 적어도 몇 가지 기능을 얻었습니다. 워크로드를 실행할 호스트를 지정할 필요가 없으며 서비스 모니터링 및 재시작의 이점도 누릴 수 있습니다. 새로운 Kubernetes 인프라의 이점에 대해 알아보겠습니다.

9. 서비스 확장

Kubernetes의 강력한 특징 중 하나는 애플리케이션을 손쉽게 확장할 수 있다는 점입니다. 애플리케이션에 용량이 더 필요하다고 가정해 보겠습니다. 복제 컨트롤러에 포드의 새로운 복제본 수를 관리하도록 지시하기만 하면 됩니다.

kubectl scale deployment hello-dotnet --replicas=4
kubectl get deployment
NAME         DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
hello-dotnet   4         4         4            3           16m
kubectl get pods
NAME                         READY     STATUS    RESTARTS   AGE
hello-dotnet-714049816-g4azy   1/1       Running   0          1m
hello-dotnet-714049816-rk0u6   1/1       Running   0          1m
hello-dotnet-714049816-sh812   1/1       Running   0          1m
hello-dotnet-714049816-ztzrb   1/1       Running   0          16m

여기서 선언적 접근 방식에 유의하세요. 새 인스턴스를 시작하거나 중지하는 대신 항상 실행되어야 하는 인스턴스 수를 선언합니다. Kubernetes 조정 루프는 단순히 현재 상황이 요청과 일치하는지 확인하고 필요한 경우 조치를 취합니다.

다음은 Kubernetes 클러스터의 상태를 요약한 다이어그램입니다.

6af0243662464ca9.png

서비스를 매우 쉽게 축소할 수도 있습니다. 포드를 4개에서 2개로 축소하는 방법은 다음과 같습니다.

kubectl scale deployment hello-dotnet --replicas=2
kubectl get pods
NAME                         READY     STATUS    RESTARTS   AGE
hello-dotnet-714049816-g4azy   1/1       Running   0          1m
hello-dotnet-714049816-rk0u6   1/1       Running   0          1m

10. 복원력 테스트

Kubernetes (또는 좀 더 구체적으로 ReplicaSet)는 포드를 감시하고 포드에 문제가 있어 중단이 발생하면 즉시 새 포드를 만듭니다. 이를 테스트하여 어떻게 작동하는지 살펴보겠습니다.

먼저 포드 목록을 가져옵니다.

kubectl get pods
NAME                         READY     STATUS    RESTARTS   AGE
hello-dotnet-714049816-g4azy   1/1       Running   0          1m
hello-dotnet-714049816-rk0u6   1/1       Running   0          1m

포드 이름을 전달하여 포드 중 하나를 삭제합니다.

kubectl delete pod hello-dotnet-714049816-g4azy

포드 목록을 다시 보면 새 포드가 즉시 생성되고 다시 실행되는 것을 확인할 수 있습니다.

kubectl get pods
NAME                         READY     STATUS           RESTARTS   AGE
hello-dotnet-714049816-abczy   1/1    ContainerCreating  0          1m
hello-dotnet-714049816-rk0u6   1/1    Running            0          1m

11. 서비스 업그레이드하기

프로덕션에 배포한 애플리케이션에는 버그 수정이나 추가 기능이 필요합니다. 그 과정을 살펴보겠습니다.

먼저 애플리케이션을 수정해 보겠습니다. Cloud Shell에서 코드 편집기를 엽니다.

f487389b8b1cc105.png

HelloWorldAspNetCore > Views > Home 아래의 Index.cshtml로 이동하여 캐러셀 메시지 중 하나를 업데이트합니다.

다음 줄을 찾습니다.

Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core 

그리고 다음과 같이 변경합니다.

Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core on Google Cloud

변경사항을 저장한 다음 Cloud Shell로 돌아갑니다. HelloWorldAspNetCore, 내에서 Docker 이미지를 빌드합니다.

docker build -t gcr.io/${GOOGLE_CLOUD_PROJECT}/hello-dotnet:v2 . 

Container Registry로 푸시합니다.

docker push gcr.io/${GOOGLE_CLOUD_PROJECT}/hello-dotnet:v2 

이제 Kubernetes가 복제 컨트롤러를 새 버전의 애플리케이션으로 원활하게 업데이트할 준비가 되었습니다. 실행 중인 컨테이너의 이미지 라벨을 변경하려면 기존 hello-dotnet deployment를 수정하고 이미지를 gcr.io/${GOOGLE_CLOUD_PROJECT}/hello-dotnet:v1에서 gcr.io/${GOOGLE_CLOUD_PROJECT}/hello-dotnet:v2로 변경해야 합니다.

이렇게 하려면 kubectl edit 명령어를 사용합니다. 그러면 전체 배포 YAML 구성을 표시하는 텍스트 편집기가 열립니다. 지금 당장 전체 yaml 구성을 이해할 필요는 없으며, 구성의 spec.template.spec.containers.image 필드를 업데이트하면 새 이미지를 사용하도록 포드를 업데이트하도록 배포가 지시된다는 점만 이해하면 됩니다.

kubectl edit deployment hello-dotnet
# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "1"
  creationTimestamp: 2017-01-06T10:05:28Z
  generation: 3
  labels:
    run: hello-dotnet
  name: hello-dotnet
  namespace: default
  resourceVersion: "151017"
  selfLink: /apis/extensions/v1beta1/namespaces/default/deployments/hello-dotnet
  uid: 981fe302-f1e9-11e5-9a78-42010af00005
spec:
  replicas: 4
  selector:
    matchLabels:
      run: hello-dotnet
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
    type: RollingUpdate
  template:
    metadata:
      creationTimestamp: null
      labels:
        run: hello-dotnet
    spec:
      containers:
      - image: gcr.io/PROJECT_ID/hello-dotnet:v1 # Update this line
        imagePullPolicy: IfNotPresent
        name: hello-dotnet
        ports:
        - containerPort: 8080
          protocol: TCP
        resources: {}
        terminationMessagePath: /dev/termination-log
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      securityContext: {}
      terminationGracePeriodSeconds: 30

변경 후 파일을 저장하고 닫습니다 (vi를 사용하므로 'Esc' 키를 누른 다음 :wq를 입력하고 'Enter' 키를 누름).

deployment "hello-dotnet" edited

그러면 배포가 새 이미지로 업데이트되어 새 포드가 새 이미지로 생성되고 이전 포드는 삭제됩니다.

kubectl get deployments
NAME         DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
hello-dotnet   4         5         4            3           1h

이 작업이 진행되는 동안 서비스 사용자에게는 어떠한 중단도 발생하지 않습니다. 잠시 후 사용자가 새 버전의 애플리케이션에 액세스하기 시작합니다.

fb9f41e814dda653.png

순차적 업데이트에 대한 자세한 내용은 Kubernetes 문서를 참조하세요.

이러한 배포, 확장, 업데이트 기능을 통해 환경 (여기서는 GKE/Kubernetes 클러스터)을 설정하고 나면 Kubernetes를 사용하여 인프라 관리보다는 애플리케이션에 집중할 수 있다는 데 동의하실 것입니다.

12. Cloud Build

지금까지 우리는 일반 Docker 명령어 (docker build ...)를 사용하여 컨테이너를 빌드한 다음 이미지를 Google Cloud Platform의 Container Registry로 수동으로 푸시했습니다. 또한 두 단계를 서버 측 Cloud Build로 연기할 수도 있으며, 이렇게 하면 Docker를 로컬에 설치하지 않고도 컨테이너 이미지를 빌드하고 푸시할 수 있습니다.

먼저 API 관리자 > 라이브러리. Cloud Build를 검색하고 Cloud Build API를 클릭합니다.

f8b0239fa7719f29.png

아직 사용 설정되지 않은 경우 API 사용 설정을 클릭합니다. 마지막으로 API가 다음과 같이 사용 설정된 것을 확인할 수 있습니다.

ea6053f9603613b5.png

Cloud Build API가 사용 설정되면 다음 명령어를 실행하여 Container Builder 서비스에서 이미지를 빌드하고 푸시할 수 있습니다.

$ gcloud builds submit --tag gcr.io/${GOOGLE_CLOUD_PROJECT}/hello-dotnet:v3

이미지는 Container Registry에 자동으로 저장됩니다.

13. Kubernetes 그래픽 대시보드 실행

최신 버전의 Kubernetes에서는 그래픽 웹 사용자 인터페이스 (대시보드)가 도입되었습니다. 이 사용자 인터페이스를 사용하면 빠르게 시작할 수 있으며 CLI에 있는 일부 기능을 보다 접근하기 쉽고 검색 가능한 방식으로 시스템과 상호작용할 수 있습니다.

Kubernetes 클러스터 대시보드에 대한 액세스를 구성하려면 Cloud Shell 창에서 다음 명령어를 입력합니다.

gcloud container clusters get-credentials hello-dotnet-cluster \
    --zone europe-west1-b --project ${GOOGLE_CLOUD_PROJECT}
kubectl proxy --port 8081

그런 다음 Cloud Shell 미리보기 기능을 다시 한 번 사용하여 포트 8081로 이동합니다.

port8081.png

그러면 API 엔드포인트에 도달합니다. '승인되지 않음' 메시지가 표시될 수 있습니다 걱정하지 마세요. 대시보드로 이동하려면 '?authuser=3'을 삭제하세요. '/ui'로 바꿉니다.

Kubernetes 그래픽 대시보드를 컨테이너화된 애플리케이션 배포와 클러스터 모니터링 및 관리에 사용합니다.

177789527b650f6b.png

또는 웹 콘솔에서 '연결'을 누르면 제공되는 유사한 안내에 따라 개발 또는 로컬 머신에서 대시보드에 액세스할 수도 있습니다. 클릭합니다.

da1ccc707dd6647.png

a51c7160e237f32f.png

대시보드 사용을 완료한 후 Control + C를 눌러 프록시를 중지할 수 있습니다. 대시보드 투어에 참여하여 Kubernetes 대시보드에 관해 자세히 알아보세요.

14. 로깅

kubectl logs 명령어를 사용하여 Kubernetes 내부에서 실행 중인 컨테이너의 로그를 검색할 수 있습니다. Google Kubernetes Engine을 사용하여 관리형 Kubernetes 클러스터를 실행하면 모든 로그가 자동으로 전달되어 Google Cloud Logging에 저장됩니다. Google Cloud 콘솔에서 Stackdriver로깅 → 로그로 이동하여 포드의 모든 로그 출력을 확인할 수 있습니다.

b63159b959ba5010.png

로깅 콘솔에서 GKE 컨테이너로 이동하면 STDOUT에서 수집된 모든 로그를 볼 수 있습니다.

43e9aab3e02358d5.png

원하는 경우 추가 로그 분석을 위해 로그를 Google BigQuery로 내보내거나 로그 기반 알림을 설정할 수 있습니다. 오늘은 실습 중에 이 작업을 하지 않겠습니다.

15. 축하합니다.

이로써 ASP.NET Core 및 Kubernetes를 사용한 간단한 시작하기 Codelab을 마칩니다. 여기서는 이 기술의 개략적인 사항만 살펴보았으므로, pod, 복제본 컨트롤러, 서비스에 관해 더 자세한 내용을 직접 공부해 보는 것을 권장합니다. 또한 활성 여부 조사(상태 확인)에 관해서도 살펴보고 Kubernetes API를 직접 사용해 보면 더욱 좋습니다.

삭제

작업이 끝났습니다. 비용을 절감하고 클라우드를 효율적으로 사용하기 위해 사용한 리소스를 삭제해 보겠습니다.

배포 (실행 중인 포드도 삭제됨)와 서비스 (외부 부하 분산기도 삭제)를 삭제합니다.

먼저 서비스와 배포를 삭제하면 외부 부하 분산기도 삭제됩니다.

kubectl delete service,deployment hello-dotnet
service "hello-dotnet" deleted
deployment "hello-dotnet" deleted

그런 다음 클러스터를 삭제합니다.

gcloud container clusters delete hello-dotnet-cluster --zone=europe-west1-b
The following clusters will be deleted.
 - [hello-dotnet-cluster] in [europe-west1-b]
Do you want to continue (Y/n)?  Y
Deleting cluster hello-dotnet-cluster...done.                                                                                                                                                                                            
Deleted [https://container.googleapis.com/v1/projects/<PROJECT_ID>/zones/europe-west1-b/clusters/hello-dotnet-cluster].

그러면 클러스터를 실행 중인 모든 Google Compute Engine 인스턴스가 삭제됩니다.

마지막으로 이미지를 호스팅하는 Docker 레지스트리 스토리지 버킷을 삭제합니다.

gsutil ls
gs://artifacts.<PROJECT_ID>.appspot.com/
gsutil rm -r gs://artifacts.${GOOGLE_CLOUD_PROJECT}.appspot.com/
Removing gs://artifacts.<PROJECT_ID>.appspot.com/...
Removing gs://artifacts.<PROJECT_ID>.appspot.com/...

물론 전체 프로젝트를 삭제할 수도 있지만 이 경우 결제 설정이 손실됩니다 (먼저 프로젝트 결제를 사용 중지해야 함). 또한 프로젝트를 삭제하면 현재 결제 주기가 종료된 후에만 모든 결제가 중지됩니다.

학습한 내용

  • 간단한 ASP.NET Core 앱을 Docker 컨테이너로 패키징하는 방법
  • Google Kubernetes Engine에서 Kubernetes 클러스터를 만드는 방법
  • ASP.NET Core 앱을 포드에 배포하는 방법
  • 포드에 외부 트래픽을 허용하는 방법
  • 서비스를 확장하고 업그레이드를 출시하는 방법
  • Kubernetes 그래픽 대시보드를 실행하는 방법

다음 단계

라이선스

이 작업물은 Creative Commons Attribution 2.0 일반 라이선스에 따라 사용이 허가되었습니다.