Istio를 사용하여 Google Kubernetes Engine에 ASP.NET Core 앱 배포 (1부)

1. 개요

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

Kubernetes는 컨테이너화된 애플리케이션의 배포, 확장, 관리를 자동화하는 오픈소스 시스템입니다. Istio는 서비스를 연결, 보안, 관리, 모니터링할 수 있는 개방형 프레임워크입니다.

실습의 첫 번째 부분에서는 Google Kubernetes Engine (GKE)에서 실행되는 Kubernetes에 간단한 ASP.NET Core 앱을 배포하고 이를 Istio에서 관리하도록 구성합니다.

실습 2부에서는 측정항목, 추적, 동적 트래픽 관리, 결함 주입 등과 같은 Istio의 기능을 더 자세히 살펴봅니다.

학습할 내용

  • Docker 컨테이너에서 간단한 ASP.NET Core 앱을 만들고 패키징하는 방법
  • Google Kubernetes Engine (GKE)으로 Kubernetes 클러스터를 만드는 방법입니다.
  • GKE의 Kubernetes 클러스터에 Istio를 설치하는 방법
  • ASP.NET Core 앱을 배포하고 Istio에서 관리하도록 트래픽을 구성하는 방법

필요한 항목

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

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

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

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

2. 설정 및 요건

자습형 환경 설정

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

96a9c957bc475304.png

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

모든 Google Cloud 프로젝트에서 고유한 이름인 프로젝트 ID를 기억하세요(위의 이름은 이미 사용되었으므로 사용할 수 없습니다). 이 ID는 나중에 이 Codelab에서 PROJECT_ID라고 부릅니다.

  1. 그런 후 Google Cloud 리소스를 사용할 수 있도록 Cloud Console에서 결제를 사용 설정해야 합니다.

이 Codelab 실행에는 많은 비용이 들지 않습니다. 이 가이드를 마친 후 비용이 결제되지 않도록 리소스 종료 방법을 알려주는 '삭제' 섹션의 안내를 따르세요. Google Cloud 신규 사용자에게는 미화$300 상당의 무료 체험판 프로그램에 참여할 수 있는 자격이 부여됩니다.

Cloud Shell 시작

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

Cloud Shell 활성화

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

bce75f34b2c53987.png

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

70f315d7b402b476.png

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

fbe3a0674c982259.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 웹페이지가 표시됩니다.

f579a9baedc108a9.png

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

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

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

앱의 기본 디렉터리에 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:5.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:5.0-alpine 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 웹페이지가 표시됩니다.

f579a9baedc108a9.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가 액세스하고 조정할 수 있으며, 이 이미지는 몇 분 후에 확인할 수 있습니다.

73558f3a54ce1c0c.png

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

6. Istio로 Kubernetes/GKE 클러스터 만들기

먼저 Kubernetes Engine API를 사용 설정했는지 확인합니다.

gcloud services enable container.googleapis.com

Kubernetes 클러스터 만들기 원하는 경우 거주 지역과 가까운 지역으로 변경할 수 있습니다.

gcloud container clusters create hello-istio \
  --cluster-version=latest \
  --machine-type=n1-standard-2 \
  --num-nodes=4 \
  --region europe-west1

클러스터가 설정되는 동안 잠시 기다립니다. Google Cloud Platform 콘솔의 Kubernetes Engine 섹션에 표시됩니다.

e46fd9c6ee82bcc4.png

이 Codelab에서는 istio.io에서 Istio를 다운로드하고 설치합니다. GKE용 Istio 부가기능Anthos Service Mesh를 비롯한 다른 설치 옵션도 있습니다. 이 이후의 애플리케이션 단계는 모든 Istio 설치에서 작동합니다.

먼저 Istio 클라이언트와 샘플을 다운로드해 보겠습니다. Istio 릴리스 페이지는 여러 OS에 대한 다운로드 아티팩트를 제공합니다. 여기서는 편리한 명령을 사용하여 현재 플랫폼의 최신 릴리스를 다운로드하고 추출할 수 있습니다.

curl -L https://istio.io/downloadIstio | sh -

이 스크립트는 다운로드된 Istio 버전을 알려줍니다.

Istio has been successfully downloaded into the istio-1.8.1 folder on your system.

설치 디렉터리에는 샘플 애플리케이션과 istioctl 클라이언트 바이너리가 포함되어 있습니다. 해당 디렉터리로 변경합니다.

cd istio-1.8.1

istioctl를 사용할 수 있도록 제공된 명령어를 복사하여 붙여넣어 bin 디렉터리를 PATH에 추가합니다.

export PATH="$PATH:/home/<YOURHOMEID>/istio-1.8.1/bin"

클러스터에서 Istio를 사용할 준비가 되었는지 확인하여 istioctl를 사용할 수 있는지 확인합니다.

istioctl x precheck

Install Pre-Check passed! The cluster is ready for Istio installation.라는 메시지가 표시됩니다.

데모 프로필로 Istio를 설치합니다.

istioctl install --set profile=demo

이제 Istio가 클러스터에 설치되었습니다.

자동 사이드카 삽입

Istio를 사용하기 위해 애플리케이션을 변경할 필요는 없습니다. 서비스를 구성하고 실행하면 Envoy 사이드카가 서비스의 각 포드에 자동으로 삽입됩니다.

그렇게 하려면 마이크로서비스에 사용하는 네임스페이스('기본값')에 사이드카 삽입을 사용 설정해야 합니다. 라벨을 적용하면 됩니다.

kubectl label namespace default istio-injection=enabled

라벨이 성공적으로 적용되었는지 확인하려면 다음 명령어를 실행합니다.

kubectl get namespace -L istio-injection

출력을 통해 사이드카 삽입이 기본 네임스페이스에 사용 설정되어 있음을 확인할 수 있습니다.

NAME              STATUS   AGE    ISTIO-INJECTION
default           Active   3m     enabled
istio-system      Active   63s    disabled
...

7. 설치 확인

Istio에는 istiod 제어 영역과 '나머지 인터넷의 사이드카 프록시'라고 할 수 있는 인그레스 및 이그레스 게이트웨이라는 세 가지 서비스가 제공되며 각각 이름이 istio-ingressgatewayistio-egressgateway입니다.

kubectl get svc -n istio-system

다음과 비슷한 결과가 출력됩니다.

NAME                   TYPE           CLUSTER-IP      EXTERNAL-IP                                                                     AGE
istio-egressgateway    ClusterIP      10.55.252.182   <none>
istio-ingressgateway   LoadBalancer   10.55.250.185   35.233.118.42
istiod                 ClusterIP      10.55.253.217   <none>

인그레스 게이트웨이의 유형은 LoadBalancer이므로 인터넷에서 액세스할 수 있습니다. 나머지는 클러스터 내에서만 액세스할 수 있어야 합니다

그런 다음 해당 Kubernetes 포드가 배포되고 모든 컨테이너가 작동되어 실행 중인지 확인합니다.

kubectl get pods -n istio-system

모든 포드가 실행 중이면 계속 진행할 수 있습니다.

NAME                                    READY   STATUS
istio-egressgateway-674988f895-m6tk4    1/1     Running
istio-ingressgateway-6996f7dcc8-7lvm2   1/1     Running
istiod-6bf5fc8b64-j79hj                 1/1     Running
  • istiod: Istio 제어 영역입니다. 프록시 사이드카, 서비스 검색, 인증서 배포, 사이드카 삽입의 구성 및 프로그래밍을 처리합니다.
  • ingress gateway: 클러스터 외부에서 수신되는 요청을 처리합니다.
  • egress gateway: 클러스터 외부의 엔드포인트로 나가는 요청을 처리합니다.

8. 애플리케이션 배포

이제 Istio가 설치되어 실행 중임을 확인했으므로 ASP.NET Core 앱을 배포할 수 있습니다.

배포 및 서비스

먼저 원하는 편집기 (vim, nano,emacs 또는 Cloud Shell의 코드 편집기)를 사용하여 aspnetcore.yaml 파일을 만들고 앱의 Kubernetes 배포 및 서비스를 정의합니다.

apiVersion: v1
kind: Service
metadata:
  name: aspnetcore-service
  labels:
    app: aspnetcore
spec:
  ports:
  - port: 8080
    name: http
  selector:
    app: aspnetcore
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: aspnetcore-v1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: aspnetcore
      version: v1
  template:
    metadata:
      labels:
        app: aspnetcore
        version: v1
    spec:
      containers:
      - name: aspnetcore
        image: gcr.io/YOUR-PROJECT-ID/hello-dotnet:v1
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080

이 파일의 콘텐츠는 애플리케이션을 배포하기 위한 표준 배포 및 서비스이며 Istio 관련 내용이 포함되어 있지 않습니다.

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

kubectl apply -f aspnetcore.yaml
service "aspnetcore-service" created
deployment.extensions "aspnetcore-v1" created

포드가 실행 중인지 확인합니다.

kubectl get pods
NAME                          READY     STATUS    RESTARTS   AGE
aspnetcore-v1-6cf64748-mddb   2/2       Running   0          34s

게이트웨이 및 VirtualService

인그레스 트래픽이 메시에 도달하도록 허용하려면 게이트웨이VirtualService를 만들어야 합니다.

게이트웨이는 애플리케이션의 인그레스 트래픽을 사용 설정하기 위해 가장 일반적으로 메시의 에지에서 작동하여 HTTP/TCP 트래픽에 대한 부하 분산기를 구성합니다. VirtualService는 서비스 요청이 Istio 서비스 메시 내에서 라우팅되는 방식을 제어하는 규칙을 정의합니다.

aspnetcore-gateway.yaml 파일을 만들어 게이트웨이를 정의합니다.

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: aspnetcore-gateway
spec:
  selector:
    istio: ingressgateway # use istio default controller
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"

aspnetcore-virtualservice.yaml 파일을 만들어 VirtualService를 정의합니다.

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: aspnetcore-virtualservice
spec:
  hosts:
  - "*"
  gateways:
  - aspnetcore-gateway
  http:
  - route:
    - destination:
        host: aspnetcore-service

kubectl 명령어를 실행하여 다음을 포함한 게이트웨이를 배포합니다.

kubectl apply -f aspnetcore-gateway.yaml

이 명령어는 다음 출력을 생성합니다.

gateway.networking.istio.io "aspnetcore-gateway" created

그런 후 다음 명령어를 실행하여 VirtualService를 배포합니다.

kubectl apply -f aspnetcore-virtualservice.yaml

이 명령어는 다음 출력을 생성합니다.

virtualservice.networking.istio.io "aspnetcore-virtualservice" created

모든 것이 실행 중인지 확인합니다.

kubectl get gateway
NAME                      AGE
aspnetcore-gateway   28s
kubectl get virtualservice
NAME                             AGE
aspnetcore-virtualservice   33s

축하합니다. Istio 지원 애플리케이션을 배포했습니다. 다음으로, 사용 중인 애플리케이션을 확인합니다.

9. 애플리케이션 테스트

마침내 애플리케이션이 작동하는 것을 볼 수 있습니다. 게이트웨이의 외부 IP와 포트를 가져와야 합니다. EXTERNAL-IP 아래에 나열되어 있습니다.

kubectl get svc istio-ingressgateway -n istio-system

외부 IP 및 포트를 GATEWAY_URL 변수로 내보냅니다.

export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')

export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].port}')

export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT

curl를 사용하여 앱을 테스트합니다. 서비스는 200의 응답 코드로 응답해야 합니다.

curl -o /dev/null -s -w "%{http_code}\n" http://${GATEWAY_URL}/

또는 브라우저를 열고 http://<gatewayurl>로 이동하여 앱을 볼 수 있습니다.

f579a9baedc108a9.png

10. 축하합니다.

지금까지 Google Kubernetes Engine (GKE)에서 실행되는 Kubernetes에 간단한 ASP.NET Core 앱을 배포하고 Istio에서 관리하도록 구성했습니다.

' Istio의 이점은 무엇인가요?'라고 궁금하실 수 있습니다. 좋은 질문입니다. 지금까지는 Istio가 이 앱을 관리해도 이점이 없습니다. 실습의 두 번째 부분에서는 측정항목, 추적, 동적 트래픽 관리, 서비스 시각화, 결함 주입과 같은 Istio의 기능을 더 자세히 살펴보겠습니다.

다음 단계

라이선스

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

11. 삭제

실습의 두 번째 부분으로 계속 진행하지 않는 경우 앱을 삭제하고 Istio를 제거하거나 Kubernetes 클러스터를 삭제하면 됩니다.

앱 삭제하기

앱을 삭제하는 방법은 다음과 같습니다.

kubectl delete -f aspnetcore-gateway.yaml
Kubectl delete -f aspnetcore-virtualservice.yaml
kubectl delete -f aspnetcore.yaml

앱이 사라졌는지 확인하려면 다음 단계를 따르세요.

kubectl get gateway 
kubectl get virtualservices 
kubectl get pods

Istio 제거

Istio를 삭제하려면 다음 안내를 따르세요.

kubectl delete -f install/kubernetes/istio-demo-auth.yaml

Istio가 사라졌는지 확인하려면 다음 안내를 따르세요.

kubectl get pods -n istio-system

Kubernetes 클러스터 삭제

gcloud container clusters delete hello-istio