Google Kubernetes Engine에서 .NET Core 앱 배포 및 업데이트

1. 개요

Microsoft .NET Core는 컨테이너에서 기본적으로 실행할 수 있는 .NET의 오픈소스 교차 플랫폼 버전입니다. .NET Core는 GitHub에서 제공되며 Microsoft와 .NET 커뮤니티에서 유지관리합니다. 이 실습에서는 컨테이너화된 .NET Core 앱을 Google Kubernetes Engine (GKE)에 배포합니다.

이 실습에서는 개발자의 로컬 환경에서 애플리케이션을 개발한 후 프로덕션에 배포하는 일반적인 개발 패턴을 따릅니다. 실습의 첫 번째 부분에서는 Cloud Shell에서 실행되는 컨테이너를 사용하여 .NET Core 앱의 예시를 검증합니다. 유효성 검사가 완료되면 GKE를 사용하여 Kubernetes에 앱이 배포됩니다. 실습에는 GKE 클러스터를 만드는 단계가 포함되어 있습니다.

실습의 두 번째 부분에서는 해당 앱 인스턴스를 실행하는 컨테이너의 호스트 이름을 표시하는 앱이 약간 변경됩니다. 그런 다음 업데이트된 애플리케이션이 Cloud Shell에서 검증되고 새 버전을 사용하도록 배포가 업데이트됩니다. 다음 그림은 이 실습의 활동 순서를 보여줍니다.

데모 시퀀스 다이어그램

비용

이 실습을 정확히 작성된 대로 실행하면 다음 서비스에 대한 일반 비용이 적용됩니다.

2. 설정 및 요구사항

기본 요건

이 실습을 완료하려면 Google Cloud 계정과 프로젝트가 필요합니다. 새 프로젝트를 만드는 방법에 관한 자세한 내용은 이 Codelab을 참고하세요.

이 실습에서는 Google Cloud 콘솔을 통해 사용할 수 있으며 gcloud, Docker와 같은 유용한 도구가 사전 구성되어 있는 Cloud Shell에서 실행되는 Docker를 사용합니다. Cloud Shell에 액세스하는 방법은 아래와 같습니다. 오른쪽 상단의 Cloud Shell 아이콘을 클릭하여 콘솔 창의 하단 창에 표시합니다.

Cloud Shell

GKE 클러스터의 대체 구성 옵션 (선택사항)

이 실습에는 Kubernetes 클러스터가 필요합니다. 다음 섹션에서는 간단한 구성으로 GKE 클러스터를 만듭니다. 이 섹션에서는 GKE를 사용하여 Kubernetes 클러스터를 빌드할 때 사용할 수 있는 대체 구성 옵션을 제공하는 몇 가지 gcloud 명령어를 보여줍니다. 예를 들어 아래 명령어를 사용하면 다양한 머신 유형, 영역, GPU (가속기)를 식별할 수 있습니다.

  • gcloud compute machine-types list 명령어를 사용하여 머신 유형을 나열합니다.
  • gcloud compute accelerator-types list 명령어를 사용하여 GPU를 나열합니다.
  • 다음 명령어를 사용하여 컴퓨팅 영역을 나열합니다. gcloud compute zones list
  • 모든 gcloud 명령어에 대한 도움말 보기 gcloud container clusters --help
    • 예를 들어 Kubernetes 클러스터 만들기에 관한 세부정보를 제공합니다. gcloud container clusters create --help

GKE의 전체 구성 옵션 목록은 이 문서를 참고하세요.

Kubernetes 클러스터 생성 준비

Cloud Shell에서는 일부 환경 변수를 설정하고 gcloud 클라이언트를 구성해야 합니다. 다음 명령어를 사용하여 이를 수행할 수 있습니다.

export PROJECT_ID=YOUR_PROJECT_ID
export DEFAULT_ZONE=us-central1-c

gcloud config set project ${PROJECT_ID}
gcloud config set compute/zone ${DEFAULT_ZONE}

GKE 클러스터 만들기

이 실습에서는 Kubernetes에 .NET Core 앱을 배포하므로 클러스터를 만들어야 합니다. 다음 명령어를 사용하여 GKE를 통해 Google Cloud에 새 Kubernetes 클러스터를 만듭니다.

gcloud container clusters create dotnet-cluster \
  --zone ${DEFAULT_ZONE} \
  --num-nodes=1 \
  --node-locations=${DEFAULT_ZONE},us-central1-b \
  --enable-stackdriver-kubernetes \
  --machine-type=n1-standard-1 \
  --workload-pool=${PROJECT_ID}.svc.id.goog \
  --enable-ip-alias
  • --num-nodes영역당 추가할 노드 수이며 나중에 확장할 수 있습니다.
  • --node-locations는 쉼표로 구분된 영역 목록입니다. 이 경우 위의 환경 변수와 us-central1-b에서 식별한 영역이 사용됩니다.
    • 참고: 이 목록에는 중복 항목이 포함될 수 없습니다.
  • --workload-pool는 GKE 워크로드가 Google Cloud 서비스에 액세스할 수 있도록 워크로드 아이덴티티를 설정합니다.

클러스터가 빌드되는 동안 다음이 표시됩니다.

Creating cluster dotnet-cluster in us-central1-b... Cluster is being deployed...⠼

kubectl 구성

kubectl CLI는 Kubernetes 클러스터와 상호작용하는 기본 방법입니다. 방금 만든 새 클러스터와 함께 사용하려면 클러스터에 대해 인증하도록 구성해야 합니다. 다음 명령어를 사용하여 이를 수행합니다.

$ gcloud container clusters get-credentials dotnet-cluster --zone ${DEFAULT_ZONE}
Fetching cluster endpoint and auth data.
kubeconfig entry generated for dotnet-cluster.

이제 kubectl을 사용하여 클러스터와 상호작용할 수 있습니다.

$ kubectl get nodes
NAME                                            STATUS   ROLES    AGE     VERSION
gke-dotnet-cluster-default-pool-02c9dcb9-fgxj   Ready    <none>   2m15s   v1.16.13-gke.401
gke-dotnet-cluster-default-pool-ed09d7b7-xdx9   Ready    <none>   2m24s   v1.16.13-gke.401

3. 로컬에서 테스트하고 원하는 기능 확인

이 실습에서는 Docker Hub의 공식 .NET 저장소에서 다음 컨테이너 이미지를 사용합니다.

로컬에서 컨테이너를 실행하여 기능 확인

Cloud Shell에서 다음 Docker 명령어를 실행하여 Docker가 올바르게 실행되고 .NET 컨테이너가 예상대로 작동하는지 확인합니다.

$ docker run --rm mcr.microsoft.com/dotnet/samples

      Hello from .NET!
      __________________
                        \
                        \
                            ....
                            ....'
                            ....
                          ..........
                      .............'..'..
                  ................'..'.....
                .......'..........'..'..'....
                ........'..........'..'..'.....
              .'....'..'..........'..'.......'.
              .'..................'...   ......
              .  ......'.........         .....
              .                           ......
              ..    .            ..        ......
            ....       .                 .......
            ......  .......          ............
              ................  ......................
              ........................'................
            ......................'..'......    .......
          .........................'..'.....       .......
      ........    ..'.............'..'....      ..........
    ..'..'...      ...............'.......      ..........
    ...'......     ...... ..........  ......         .......
  ...........   .......              ........        ......
  .......        '...'.'.              '.'.'.'         ....
  .......       .....'..               ..'.....
    ..       ..........               ..'........
            ............               ..............
          .............               '..............
          ...........'..              .'.'............
        ...............              .'.'.............
        .............'..               ..'..'...........
        ...............                 .'..............
        .........                        ..............
          .....
  
Environment:
.NET 5.0.1-servicing.20575.16
Linux 5.4.58-07649-ge120df5deade #1 SMP PREEMPT Wed Aug 26 04:56:33 PDT 2020

웹 앱 기능 확인

샘플 웹 애플리케이션도 Cloud Shell에서 검증할 수 있습니다. 아래 Docker 실행 명령어는 80 포트를 노출하고 이를 localhost 포트 8080에 매핑하는 새 컨테이너를 만듭니다. 이 경우 localhost은 Cloud Shell에 있습니다.

$ docker run -it --rm -p 8080:80 --name aspnetcore_sample mcr.microsoft.com/dotnet/samples:aspnetapp
warn: Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository[60]
      Storing keys in a directory '/root/.aspnet/DataProtection-Keys' that may not be persisted outside of the container. Protected data will be unavailable when container is destroyed.
warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35]
      No XML encryptor configured. Key {64a3ed06-35f7-4d95-9554-8efd38f8b5d3} may be persisted to storage in unencrypted form.
info: Microsoft.Hosting.Lifetime[0]
      Now listening on: http://[::]:80
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Production
info: Microsoft.Hosting.Lifetime[0]
      Content root path: /app

웹 앱이므로 웹브라우저에서 확인하고 검증해야 합니다. 다음 섹션에서는 웹 미리보기를 사용하여 Cloud Shell에서 이 작업을 수행하는 방법을 보여줍니다.

4. '웹 미리보기'를 사용하여 Cloud Shell에서 서비스 액세스

Cloud Shell은 브라우저를 사용하여 Cloud Shell 인스턴스에서 실행되는 프로세스와 상호작용할 수 있는 기능인 웹 미리보기를 제공합니다.

'웹 미리보기'를 사용하여 Cloud Shell에서 앱 보기

Cloud Shell에서 웹 미리보기 버튼을 클릭하고 '포트 8080에서 미리보기' (또는 웹 미리보기에서 사용하도록 설정된 포트)를 선택합니다.

Cloud Shell

그러면 다음과 같은 주소가 있는 브라우저 창이 열립니다.

https://8080-cs-754738286554-default.us-central1.cloudshell.dev/?authuser=0

웹 미리보기를 사용하여 .NET 샘플 애플리케이션 보기

이제 마지막 단계에서 시작한 샘플 앱을 웹 미리보기를 시작하고 제공된 URL을 로드하여 볼 수 있습니다. 예를 들면 다음과 같습니다.

.NET 앱 V1 스크린샷

5. Kubernetes에 배포

YAML 파일 빌드 및 적용

다음 단계에서는 배포와 서비스라는 두 Kubernetes 리소스를 설명하는 YAML 파일이 필요합니다. Cloud Shell에서 dotnet-app.yaml이라는 파일을 만들고 다음 콘텐츠를 추가합니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: dotnet-deployment
  labels:
    app: dotnetapp
spec:
  replicas: 3
  selector:
    matchLabels:
      app: dotnetapp
  template:
    metadata:
      labels:
        app: dotnetapp
    spec:
      containers:
      - name: dotnet
        image: mcr.microsoft.com/dotnet/samples:aspnetapp
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: dotnet-service
spec:
    selector:
      app: dotnetapp
    ports:
      - protocol: TCP
        port: 8080
        targetPort: 80

이제 kubectl을 사용하여 이 파일을 Kubernetes에 적용합니다.

$ kubectl apply -f dotnet-app.yaml
deployment.apps/dotnet-deployment created
service/dotnet-service created

원하는 리소스가 생성되었음을 나타내는 메시지를 확인합니다.

결과 리소스 살펴보기

kubectl CLI를 사용하여 위에서 생성된 리소스를 검사할 수 있습니다. 먼저 배포 리소스를 살펴보고 새 배포가 있는지 확인합니다.

$ kubectl get deployment
NAME                READY   UP-TO-DATE   AVAILABLE   AGE
dotnet-deployment   3/3     3            3           80s

다음으로 ReplicaSet을 살펴보세요. 위 배포로 생성된 ReplicaSet이 있어야 합니다.

$ kubectl get replicaset
NAME                           DESIRED   CURRENT   READY   AGE
dotnet-deployment-5c9d4cc4b9   3         3         3       111s

마지막으로 포드를 살펴봅니다. 배포는 인스턴스가 3개 있어야 한다고 나타냈습니다. 아래 명령어를 실행하면 인스턴스가 3개 표시됩니다. 해당 인스턴스가 실행되는 노드가 표시되도록 -o wide 옵션이 추가됩니다.

$ kubectl get pod -o wide
NAME                                 READY   STATUS    RESTARTS   AGE     IP          NODE                                            NOMINATED NODE   READINESS GATES
dotnet-deployment-5c9d4cc4b9-cspqd   1/1     Running   0          2m25s   10.16.0.8   gke-dotnet-cluster-default-pool-ed09d7b7-xdx9   <none>           <none>
dotnet-deployment-5c9d4cc4b9-httw6   1/1     Running   0          2m25s   10.16.1.7   gke-dotnet-cluster-default-pool-02c9dcb9-fgxj   <none>           <none>
dotnet-deployment-5c9d4cc4b9-vvdln   1/1     Running   0          2m25s   10.16.0.7   gke-dotnet-cluster-default-pool-ed09d7b7-xdx9   <none>           <none>

서비스 리소스 검토

Kubernetes의 서비스 리소스는 부하 분산기입니다. 엔드포인트는 포드의 라벨에 따라 결정됩니다. 이러한 방식으로 위의 kubectl scale deployment 작업을 통해 새 포드가 배포에 추가되면 결과 포드는 해당 서비스에서 처리하는 요청에 즉시 사용할 수 있습니다.

다음 명령어는 서비스 리소스를 표시해야 합니다.

$ kubectl get svc
NAME             TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)    AGE
dotnet-service   ClusterIP   10.20.9.124   <none>        8080/TCP   2m50s
...

다음 명령어를 사용하여 서비스에 대한 자세한 내용을 확인할 수 있습니다.

$ kubectl describe svc dotnet-service
Name:              dotnet-service
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          app=dotnetapp
Type:              ClusterIP
IP:                10.20.9.124
Port:              <unset>  8080/TCP
TargetPort:        80/TCP
Endpoints:         10.16.0.7:80,10.16.0.8:80,10.16.1.7:80
Session Affinity:  None
Events:            <none>

서비스가 ClusterIP 유형입니다. 즉, 클러스터 내의 모든 포드가 서비스 이름 dotnet-service을 IP 주소로 변환할 수 있습니다. 서비스로 전송된 요청은 모든 인스턴스 (포드)에 걸쳐 부하 분산됩니다. 위의 Endpoints 값은 현재 이 서비스에 사용할 수 있는 포드의 IP를 보여줍니다. 이를 위에 출력된 포드의 IP와 비교합니다.

실행 중인 앱 확인

이 시점에서 애플리케이션이 게시되어 사용자 요청을 처리할 수 있습니다. 액세스하려면 프록시를 사용하세요. 다음 명령어는 8080 포트에서 요청을 수락하고 이를 Kubernetes 클러스터에 전달하는 로컬 프록시를 만듭니다.

$ kubectl proxy --port 8080
Starting to serve on 127.0.0.1:8080

이제 Cloud Shell에서 웹 미리보기를 사용하여 웹 애플리케이션에 액세스합니다.

웹 미리보기에서 생성된 URL에 /api/v1/namespaces/default/services/dotnet-service:8080/proxy/을 추가합니다. 결과는 다음과 같습니다.

https://8080-cs-473655782854-default.us-central1.cloudshell.dev/api/v1/namespaces/default/services/dotnet-service:8080/proxy/

Google Kubernetes Engine에 .NET Core 앱을 배포하신 것을 축하드립니다. 다음으로 앱을 변경하고 다시 배포합니다.

6. 앱 수정

이 섹션에서는 인스턴스가 실행 중인 호스트를 표시하도록 애플리케이션을 수정합니다. 이렇게 하면 부하 분산이 작동하고 사용 가능한 포드가 예상대로 응답하는지 확인할 수 있습니다.

소스 코드 가져오기

git clone https://github.com/dotnet/dotnet-docker.git
cd dotnet-docker/samples/aspnetapp/

호스트 이름을 포함하도록 앱 업데이트

vi aspnetapp/Pages/Index.cshtml
    <tr>
        <td>Host</td>
        <td>@Environment.MachineName</td>
    </tr>

새 컨테이너 이미지 빌드 및 로컬 테스트

업데이트된 코드로 새 컨테이너 이미지를 빌드합니다.

docker build --pull -t aspnetapp:alpine -f Dockerfile.alpine-x64 .

이전과 마찬가지로 새 애플리케이션을 로컬로 테스트합니다.

$ docker run --rm -it -p 8080:80 aspnetapp:alpine
warn: Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository[60]
      Storing keys in a directory '/root/.aspnet/DataProtection-Keys' that may not be persisted outside of the container. Protected data will be unavailable when container is destroyed.
warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35]
      No XML encryptor configured. Key {f71feb13-8eae-4552-b4f2-654435fff7f8} may be persisted to storage in unencrypted form.
info: Microsoft.Hosting.Lifetime[0]
      Now listening on: http://[::]:80
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Production
info: Microsoft.Hosting.Lifetime[0]
      Content root path: /app

이전과 마찬가지로 웹 미리보기를 사용하여 앱에 액세스할 수 있습니다. 이번에는 호스트 매개변수가 다음과 같이 표시됩니다.

Cloud Shell

Cloud Shell에서 새 탭을 열고 docker ps을 실행하여 컨테이너 ID가 위에 표시된 호스트 값과 일치하는지 확인합니다.

$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                  NAMES
ab85ce11aecd        aspnetapp:alpine    "./aspnetapp"       2 minutes ago       Up 2 minutes        0.0.0.0:8080->80/tcp   relaxed_northcutt

Kubernetes에서 사용할 수 있도록 이미지에 태그를 지정하고 푸시합니다.

Kubernetes가 이미지를 가져올 수 있도록 이미지를 태그하고 푸시해야 합니다. 먼저 컨테이너 이미지를 나열하고 원하는 이미지를 식별합니다.

$ docker image list
REPOSITORY                                         TAG                 IMAGE ID            CREATED             SIZE
aspnetapp                                          alpine              95b4267bb6d0        6 days ago          110MB

그런 다음 이미지에 태그를 지정하고 Google Container Registry로 푸시합니다. 위의 이미지 ID를 사용하면 다음과 같이 표시됩니다.

docker tag 95b4267bb6d0 gcr.io/${PROJECT_ID}/aspnetapp:alpine
docker push gcr.io/${PROJECT_ID}/aspnetapp:alpine

7. 업데이트된 애플리케이션 재배포

YAML 파일 수정

dotnet-app.yaml 파일이 저장된 디렉터리로 다시 변경합니다. YAML 파일에서 다음 줄을 찾습니다.

        image: mcr.microsoft.com/dotnet/core/samples:aspnetapp

위에서 생성되어 gcr.io에 푸시된 컨테이너 이미지를 참조하도록 변경해야 합니다.

        image: gcr.io/PROJECT_ID/aspnetapp:alpine

PROJECT_ID을 사용하도록 수정해야 합니다. 완료되면 다음과 같이 표시됩니다.

        image: gcr.io/myproject/aspnetapp:alpine

업데이트된 YAML 파일 적용

$ kubectl apply -f dotnet-app.yaml
deployment.apps/dotnet-deployment configured
service/dotnet-service unchanged

배포 리소스는 업데이트된 것으로 표시되고 서비스 리소스는 변경되지 않은 것으로 표시됩니다. 업데이트된 포드는 이전과 같이 kubectl get pod 명령어로 확인할 수 있지만 이번에는 -w를 추가하여 모든 변경사항이 발생할 때마다 감시합니다.

$ kubectl get pod -w
NAME                                 READY   STATUS              RESTARTS   AGE
dotnet-deployment-5c9d4cc4b9-cspqd   1/1     Running             0          34m
dotnet-deployment-5c9d4cc4b9-httw6   1/1     Running             0          34m
dotnet-deployment-5c9d4cc4b9-vvdln   1/1     Running             0          34m
dotnet-deployment-85f6446977-tmbdq   0/1     ContainerCreating   0          4s
dotnet-deployment-85f6446977-tmbdq   1/1     Running             0          5s
dotnet-deployment-5c9d4cc4b9-vvdln   1/1     Terminating         0          34m
dotnet-deployment-85f6446977-lcc58   0/1     Pending             0          0s
dotnet-deployment-85f6446977-lcc58   0/1     Pending             0          0s
dotnet-deployment-85f6446977-lcc58   0/1     ContainerCreating   0          0s
dotnet-deployment-5c9d4cc4b9-vvdln   0/1     Terminating         0          34m
dotnet-deployment-85f6446977-lcc58   1/1     Running             0          6s
dotnet-deployment-5c9d4cc4b9-cspqd   1/1     Terminating         0          34m
dotnet-deployment-85f6446977-hw24v   0/1     Pending             0          0s
dotnet-deployment-85f6446977-hw24v   0/1     Pending             0          0s
dotnet-deployment-5c9d4cc4b9-cspqd   0/1     Terminating         0          34m
dotnet-deployment-5c9d4cc4b9-vvdln   0/1     Terminating         0          34m
dotnet-deployment-5c9d4cc4b9-vvdln   0/1     Terminating         0          34m
dotnet-deployment-85f6446977-hw24v   0/1     Pending             0          2s
dotnet-deployment-85f6446977-hw24v   0/1     ContainerCreating   0          2s
dotnet-deployment-5c9d4cc4b9-cspqd   0/1     Terminating         0          34m
dotnet-deployment-5c9d4cc4b9-cspqd   0/1     Terminating         0          34m
dotnet-deployment-85f6446977-hw24v   1/1     Running             0          3s
dotnet-deployment-5c9d4cc4b9-httw6   1/1     Terminating         0          34m
dotnet-deployment-5c9d4cc4b9-httw6   0/1     Terminating         0          34m

위 출력은 지속적 업데이트가 진행되는 동안의 모습을 보여줍니다. 먼저 새 컨테이너가 시작되고 실행되면 이전 컨테이너가 종료됩니다.

실행 중인 앱 확인

이 시점에서 애플리케이션이 업데이트되고 사용자 요청을 처리할 준비가 됩니다. 이전과 마찬가지로 프록시를 사용하여 액세스할 수 있습니다.

$ kubectl proxy --port 8080
Starting to serve on 127.0.0.1:8080

이제 Cloud Shell에서 웹 미리보기를 사용하여 웹 애플리케이션에 액세스합니다.

웹 미리보기에서 생성된 URL에 /api/v1/namespaces/default/services/dotnet-service:8080/proxy/을 추가합니다. 결과는 다음과 같습니다.

https://8080-cs-473655782854-default.us-central1.cloudshell.dev/api/v1/namespaces/default/services/dotnet-service:8080/proxy/

Kubernetes 서비스가 부하를 분산하는지 확인

이 URL을 여러 번 새로고침하면 서비스에서 여러 포드에 요청을 부하 분산하므로 호스트가 변경됩니다. 호스트 값을 위의 Pod 목록과 비교하여 모든 Pod가 트래픽을 수신하는지 확인합니다.

인스턴스 수직 확장

Kubernetes에서 앱을 확장하는 것은 간단합니다. 다음 명령어는 애플리케이션을 최대 6개의 인스턴스로 확장합니다.

$ kubectl scale deployment dotnet-deployment --replicas 6
deployment.apps/dotnet-deployment scaled

이 명령어를 사용하면 새 포드와 현재 상태를 확인할 수 있습니다.

kubectl get pod -w

동일한 브라우저 창을 새로고침하면 이제 트래픽이 모든 새 포드에 분산되는 것을 확인할 수 있습니다.

8. 축하합니다.

이 실습에서는 개발자 환경에서 .NET Core 샘플 웹 애플리케이션을 검증한 후 GKE를 사용하여 Kubernetes에 배포했습니다. 그런 다음 앱이 실행 중인 컨테이너의 호스트 이름을 표시하도록 수정되었습니다. 그런 다음 Kubernetes 배포가 새 버전으로 업데이트되고 앱이 수평 확장되어 추가 인스턴스에 부하가 분산되는 방식이 표시되었습니다.

.NET 및 Kubernetes에 대해 자세히 알아보려면 다음 튜토리얼을 참고하세요. 이러한 실습에서는 더 정교한 라우팅 및 복원력 패턴을 위해 Istio Service Mesh를 도입하여 이 실습에서 배운 내용을 기반으로 합니다.

9. 삭제

의도치 않은 비용이 발생하지 않도록 다음 명령어를 사용하여 이 실습에서 만든 클러스터와 컨테이너 이미지를 삭제합니다.

gcloud container clusters delete dotnet-cluster --zone ${DEFAULT_ZONE}
gcloud container images delete gcr.io/${PROJECT_ID}/aspnetapp:alpine