1. 개요
ASP.NET Core는 C# 프로그래밍 언어를 사용하여 최신 클라우드 기반 및 인터넷 연결 애플리케이션을 빌드하기 위한 오픈소스 크로스 플랫폼 프레임워크입니다.
Kubernetes는 컨테이너화된 애플리케이션의 배포, 확장, 관리를 자동화하는 오픈소스 시스템입니다. Istio는 서비스를 연결, 보호, 관리, 모니터링하기 위한 개방형 프레임워크입니다.
실습의 첫 번째 부분에서는 Google Kubernetes Engine (GKE)에서 실행되는 Kubernetes에 간단한 ASP.NET Core 앱을 배포하고 Istio에서 관리하도록 구성합니다.
실습의 두 번째 부분에서는 측정항목, 추적, 동적 트래픽 관리, 장애 주입 등 Istio의 기능을 자세히 살펴봅니다.
학습할 내용
- Docker 컨테이너에서 간단한 ASP.NET Core 앱을 만들고 패키징하는 방법
- Google Kubernetes Engine (GKE)으로 Kubernetes 클러스터를 만드는 방법
- GKE의 Kubernetes 클러스터에 Istio를 설치하는 방법
- ASP.NET Core 앱을 배포하고 Istio에서 관리하도록 트래픽을 구성하는 방법
필요한 항목
본 가이드를 어떻게 사용하실 계획인가요?
귀하의 Google Cloud Platform 사용 경험을 평가해 주세요.
2. 설정 및 요건
자습형 환경 설정
- Cloud 콘솔에 로그인하고 새 프로젝트를 만들거나 기존 프로젝트를 다시 사용합니다. 아직 Gmail이나 Google Workspace 계정이 없는 경우 계정을 만들어야 합니다.



모든 Google Cloud 프로젝트에서 고유한 이름인 프로젝트 ID를 기억하세요(위의 이름은 이미 사용되었으므로 사용할 수 없습니다). 이 ID는 나중에 이 Codelab에서 PROJECT_ID라고 부릅니다.
- 그런 후 Google Cloud 리소스를 사용할 수 있도록 Cloud Console에서 결제를 사용 설정해야 합니다.
이 Codelab 실행에는 많은 비용이 들지 않습니다. 이 가이드를 마친 후 비용이 결제되지 않도록 리소스 종료 방법을 알려주는 '삭제' 섹션의 안내를 따르세요. Google Cloud 신규 사용자에게는 미화$300 상당의 무료 체험판 프로그램에 참여할 수 있는 자격이 부여됩니다.
Cloud Shell 시작
Google Cloud를 노트북에서 원격으로 실행할 수 있지만, 이 Codelab에서는 Google Cloud에서 실행되는 명령줄 환경인 Google Cloud Shell을 사용합니다.
Cloud Shell 활성화
- Cloud Console에서 Cloud Shell 활성화
를 클릭합니다.

이전에 Cloud Shell을 시작하지 않았으면 설명이 포함된 중간 화면 (스크롤해야 볼 수 있는 부분)이 제공됩니다. 이 경우 계속을 클릭합니다 (이후 다시 표시되지 않음). 이 일회성 화면은 다음과 같습니다.

Cloud Shell을 프로비저닝하고 연결하는 작업은 몇 분이면 끝납니다.

이 가상 머신에는 필요한 개발 도구가 모두 포함되어 로드됩니다. 영구적인 5GB 홈 디렉터리를 제공하고 Google Cloud에서 실행되므로 네트워크 성능과 인증이 크게 개선됩니다. 이 Codelab에서 대부분의 작업은 브라우저나 Chromebook만 사용하여 수행할 수 있습니다.
Cloud Shell에 연결되면 인증이 완료되었고 프로젝트가 해당 프로젝트 ID로 이미 설정된 것을 볼 수 있습니다.
- 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`
- 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에서 미리보기'를 선택합니다.

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

앱이 실행 중인지 확인한 후 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의 웹 미리보기 기능을 다시 활용합니다.

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

앱이 Docker 컨테이너에서 로컬로 제대로 실행되는지 확인한 후 Ctrl-> C를 사용하여 실행 중인 컨테이너를 중지할 수 있습니다.
이제 이미지가 의도한 대로 작동하므로 모든 Google Cloud 프로젝트는 물론 Google Cloud Platform 외부에서도 액세스할 수 있는 Docker 이미지용 비공개 저장소인 Google Container Registry로 이미지를 푸시할 수 있습니다.
docker push gcr.io/${GOOGLE_CLOUD_PROJECT}/hello-dotnet:v1
모든 것이 정상적으로 진행되면 잠시 후 Container Registry 섹션에 컨테이너 이미지가 표시됩니다. 이제 Kubernetes가 액세스하고 조정할 수 있는 프로젝트 전체 Docker 이미지가 생겼습니다.

관심이 있다면 다음 링크로 이동하여 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 섹션에 표시됩니다.

이 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
제공된 명령어를 복사하여 bin 디렉터리를 PATH에 추가하여 istioctl를 사용할 수 있습니다.
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 사이드카가 자동으로 삽입됩니다.
이 작업을 수행하려면 마이크로서비스에 사용하는 네임스페이스('default')에 대해 사이드카 삽입을 사용 설정해야 합니다. 라벨을 적용하여 이를 수행합니다.
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-ingressgateway 및 istio-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>로 이동하여 앱을 볼 수 있습니다.

10. 축하합니다.
Google Kubernetes Engine (GKE)에서 실행되는 Kubernetes에 간단한 ASP.NET Core 앱을 배포하고 Istio에서 관리하도록 구성했습니다.
'Istio의 이점이 무엇인가요?'라고 궁금해하실 수 있습니다. 좋은 질문입니다. 지금까지는 Istio로 이 앱을 관리하는 것이 유리하지 않습니다. 실습의 두 번째 부분에서는 측정항목, 추적, 동적 트래픽 관리, 서비스 시각화, 결함 주입과 같은 Istio의 기능을 자세히 살펴봅니다.
다음 단계
- Istio를 사용하여 GKE에 ASP.NET Core 앱 배포 (2부)
- Istio에 대해 자세히 알아보세요.
- Kubernetes에 대해 자세히 알아보세요.
- Google Kubernetes Engine에 관해 자세히 알아보세요.
- Google Cloud Platform의.NET에 대해 자세히 알아보세요.
라이선스
이 작업물은 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