Anthos Service Mesh는 분산 애플리케이션을 관리하고 모니터링하기 위한 강력한 도구입니다. Anthos Service Mesh를 최대한 활용하려면 컨테이너와 Kubernetes를 비롯한 기본 추상화를 이해하면 도움이 됩니다. 이 튜토리얼에서는 Anthos Service Mesh를 설치하기 직전에 소스 코드부터 GKE에서 실행되는 컨테이너까지 Anthos Service Mesh용 애플리케이션을 준비하는 방법을 설명합니다.
Kubernetes 및 서비스 메시 개념에 이미 익숙한 경우 이 튜토리얼을 건너뛰고 Anthos Service Mesh 설치 가이드로 바로 이동하세요.
목표
- 간단한 다중 서비스 'hello world' 애플리케이션 살펴보기
- 소스에서 애플리케이션 실행
- 애플리케이션 컨테이너화
- Kubernetes 클러스터 만들기
- 클러스터에 컨테이너 배포
시작하기 전에
Anthos Service Mesh API를 사용 설정하려면 다음 단계를 따르세요.- Google Cloud 콘솔에서 Kubernetes Engine 페이지로 이동합니다.
- 프로젝트를 만들거나 선택합니다.
- API 및 관련 서비스가 사용 설정될 때까지 기다립니다. 몇 분 정도 걸릴 수 있습니다.
-
Make sure that billing is enabled for your Google Cloud project.
이 튜토리얼에서는 Debian 기반 Linux 운영체제를 실행하는 g1-small Compute Engine 가상 머신(VM)을 프로비저닝하는 Cloud Shell을 사용합니다.
Cloud Shell 준비
Cloud Shell 사용의 장점은 다음과 같습니다.
- Python 2와 Python 3 개발 환경(
virtualenv
포함)이 모두 설정됩니다. - 이 가이드에 사용된
gcloud
,docker
,git
,kubectl
명령줄 도구는 이미 설치되어 있습니다. 다음과 같은 텍스트 편집기를 선택할 수 있습니다.
Cloud Shell 창 상단에 있는 '코드 편집기
'를 클릭하여 액세스할 수 있는Cloud Shell의 명령줄에서 액세스할 수 있는 Eacs, Vim 또는 Nano
In the Google Cloud console, activate Cloud Shell.
At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.
샘플 코드 다운로드
helloserver
소스 코드를 다운로드합니다.git clone https://github.com/GoogleCloudPlatform/anthos-service-mesh-samples
샘플 코드 디렉터리로 변경합니다.
cd anthos-service-mesh-samples/docs/helloserver
멀티 서비스 애플리케이션 살펴보기
샘플 애플리케이션은 Python으로 작성되며 REST를 사용하여 통신하는 두 가지 구성요소가 있습니다.
server
:GET
엔드포인트 하나,/
가 있는 간단한 서버로, 콘솔에 'hello world'를 인쇄합니다.loadgen
: 구성 가능한 초당 요청 수(RPS)와 함께server
로 트래픽을 전송하는 스크립트입니다.
소스에서 애플리케이션 실행
샘플 애플리케이션에 익숙해지려면 Cloud Shell에서 샘플 애플리케이션을 실행하세요.
sample-apps/helloserver
디렉터리에서server
를 실행합니다.python3 server/server.py
시작 시
server
에 다음이 표시됩니다.INFO:root:Starting server...
server
에 요청을 보낼 수 있도록 다른 터미널 창을 엽니다. 를 클릭하여 다른 세션을 엽니다.server
로 요청을 보냅니다.curl http://localhost:8080
server
는 다음과 같이 응답합니다.Hello World!
샘플 코드를 다운로드한 디렉터리에서
loadgen
이 포함된 디렉터리로 변경합니다.cd YOUR_WORKING_DIRECTORY/anthos-service-mesh-samples/docs/helloserver/loadgen
다음의 환경 변수를 만듭니다.
export SERVER_ADDR=http://localhost:8080 export REQUESTS_PER_SECOND=5
virtualenv
를 시작합니다.virtualenv --python python3 env
가상 환경을 활성화합니다.
source env/bin/activate
loadgen
의 요구사항을 설치합니다.pip3 install -r requirements.txt
loadgen
을 실행합니다.python3 loadgen.py
시작 시
loadgen
은 다음과 유사한 메시지를 출력합니다.Starting loadgen: 2019-05-20 10:44:12.448415 5 request(s) complete to http://localhost:8080
다른 터미널 창에서
server
는 다음과 유사한 메시지를 콘솔에 작성합니다.127.0.0.1 - - [21/Jun/2019 14:22:01] "GET / HTTP/1.1" 200 - INFO:root:GET request, Path: / Headers: Host: localhost:8080 User-Agent: python-requests/2.22.0 Accept-Encoding: gzip, deflate Accept: */*
네트워킹 관점에서, 이제 전체 애플리케이션이 동일한 호스트에서 실행됩니다. 따라서
localhost
를 사용하여server
에 요청을 보낼 수 있습니다.loadgen
및server
를 중지하려면 각 터미널 창에Ctrl-c
를 입력합니다.loadgen
터미널 창에서 가상 환경을 비활성화합니다.deactivate
애플리케이션 컨테이너화
GKE에서 애플리케이션을 실행하려면 샘플 애플리케이션(server
및 loadgen
)을 컨테이너에 패키징해야 합니다. 컨테이너는 애플리케이션을 기본 환경에서 격리하도록 패키징하는 방법입니다.
애플리케이션을 컨테이너화하려면 Dockerfile
이 필요합니다. Dockerfile
은 애플리케이션 소스 코드와 종속 항목을 Docker 이미지로 조합하는 데 필요한 명령어를 정의하는 텍스트 파일입니다. 이미지를 빌드한 후에는 Docker Hub 또는 Container Registry와 같은 Container Registry에 업로드합니다.
이 샘플은 server
및 loadgen
모두에 대해 Dockerfile
과 함께 사용되어 이미지를 빌드하는 데 필요한 모든 명령어가 포함되어 있습니다. 다음은 server
의 Dockerfile
입니다.
FROM python:3-slim as base
명령어는 최신 Python 3 이미지를 기본 이미지로 사용하도록 Docker에 지시합니다.COPY . .
명령어는 현재 작업 디렉터리(이 경우에는server.py
)의 소스 파일을 컨테이너의 파일 시스템에 복사합니다.ENTRYPOINT
는 컨테이너를 실행하는 데 사용되는 명령어를 정의합니다. 이 경우 명령어는 소스 코드에서server.py
를 실행하는 데 사용된 명령어와 거의 동일합니다.EXPOSE
명령어는server
가 포트8080
에서 리슨하도록 지정합니다. 이 명령어는 포트를 노출하지 않지만 컨테이너를 실행할 때 포트8080
를 여는 데 필요한 문서의 역할을 합니다.
애플리케이션 컨테이너화 준비
다음 환경 변수를 설정합니다.
PROJECT_ID
를 Google Cloud 프로젝트의 ID로 바꿉니다.export PROJECT_ID="PROJECT_ID"
export GCR_REPO="asm-ready"
PROJECT_ID
및GCR_REPO
값을 사용하여 Docker 이미지를 빌드하고 비공개 Container Registry로 푸시할 때 Docker 이미지에 태그합니다.Google Cloud CLI의 기본 Google Cloud 프로젝트를 설정합니다.
gcloud config set project $PROJECT_ID
Google Cloud CLI의 기본 영역을 설정합니다.
gcloud config set compute/zone us-central1-b
Container Registry 서비스가 Google Cloud 프로젝트에서 사용 설정되어 있는지 확인합니다.
gcloud services enable containerregistry.googleapis.com
server
컨테이너화
샘플
server
가 있는 디렉터리로 변경합니다.cd YOUR_WORKING_DIRECTORY/anthos-service-mesh-samples/docs/helloserver/server/
앞에서 정의한
Dockerfile
및 환경 변수를 사용하여 이미지를 빌드합니다.docker build -t gcr.io/$PROJECT_ID/$GCR_REPO/helloserver:v0.0.1 .
-t
플래그는 Docker 태그를 나타냅니다. 컨테이너를 배포할 때 사용하는 이미지의 이름입니다.이미지를 Container Registry로 내보내기
docker push gcr.io/$PROJECT_ID/$GCR_REPO/helloserver:v0.0.1
loadgen
컨테이너화
샘플
loadgen
가 있는 디렉터리로 변경합니다.cd ../loadgen
이미지를 빌드합니다.
docker build -t gcr.io/$PROJECT_ID/$GCR_REPO/loadgen:v0.0.1 .
이미지를 Container Registry로 내보내기
docker push gcr.io/$PROJECT_ID/$GCR_REPO/loadgen:v0.0.1
이미지 나열
저장소의 이미지 목록을 가져와서 이미지가 푸시되었는지 확인합니다.
gcloud container images list --repository gcr.io/$PROJECT_ID/asm-ready
이 명령어는 방금 푸시한 이미지 이름으로 응답합니다.
NAME gcr.io/PROJECT_ID/asm-ready/helloserver gcr.io/PROJECT_ID/asm-ready/loadgen
GKE 클러스터 만들기
docker run
명령어를 사용하여 Cloud Shell VM에서 이러한 컨테이너를 실행할 수 있습니다. 그러나 프로덕션에서는 더욱 통합된 방식으로 컨테이너를 조정해야 합니다. 예를 들어 컨테이너가 항상 실행되고 있는지 확인하는 시스템과 트래픽 증가를 처리하기 위해 컨테이너의 추가 인스턴스를 확장하고 시작하는 방법이 필요합니다.
GKE를 사용하여 컨테이너식 애플리케이션을 실행할 수 있습니다. GKE는 VM을 클러스터에 연결하여 작동하는 컨테이너 조정 플랫폼입니다. 각 VM을 노드라고 합니다. GKE 클러스터는 Kubernetes 오픈소스 클러스터 관리 시스템을 기반으로 합니다. Kubernetes는 클러스터와 상호작용할 수 있는 메커니즘을 제공합니다.
GKE 클러스터를 만들려면 다음 단계를 따르세요.
클러스터를 만듭니다.
gcloud container clusters create asm-ready \ --cluster-version latest \ --machine-type=n1-standard-4 \ --num-nodes 4
gcloud
명령어는 이전에 설정한 Google Cloud 프로젝트와 영역에 클러스터를 만듭니다. Anthos Service Mesh를 실행하려면 4개 이상의 노드와 n1-standard-4 머신 유형을 사용하는 것이 좋습니다.클러스터를 만드는 명령어는 완료하는 데 몇 분 정도 걸립니다. 클러스터가 준비되면 명령어가 다음과 유사한 메시지를 출력합니다.
NAME LOCATION MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS asm-ready us-central1-b 1.13.5-gke.10 203.0.113.1 n1-standard-2 1.13.5-gke.10 4 RUNNING
클러스터를 관리할 때 사용할 수 있도록
kubectl
명령줄 도구에 사용자 인증 정보를 제공합니다.gcloud container clusters get-credentials asm-ready
이제
kubectl
을 사용하여 Kubernetes와 통신할 수 있습니다. 예를 들어 다음 명령어를 실행하여 노드의 상태를 가져올 수 있습니다.kubectl get nodes
이 명령어는 다음과 비슷한 노드 목록으로 응답합니다.
NAME STATUS ROLES AGE VERSION gke-asm-ready-default-pool-dbeb23dc-1vg0 Ready <none> 99s v1.13.6-gke.13 gke-asm-ready-default-pool-dbeb23dc-36z5 Ready <none> 100s v1.13.6-gke.13 gke-asm-ready-default-pool-dbeb23dc-fj7s Ready <none> 99s v1.13.6-gke.13 gke-asm-ready-default-pool-dbeb23dc-wbjw Ready <none> 99s v1.13.6-gke.13
Kubernetes 주요 개념 이해
다음 다이어그램은 GKE에서 실행되는 애플리케이션을 보여줍니다.
GKE에 컨테이너를 배포하기 전에 몇 가지 주요 Kubernetes 개념을 검토하는 것이 좋습니다. 이 가이드의 끝부분에서는 각 개념을 자세히 알아볼 수 있는 링크를 제공합니다.
노드 및 클러스터: GKE에서 노드는 VM입니다. 다른 Kubernetes 플랫폼에서 노드는 물리적 또는 가상 머신일 수 있습니다. 클러스터는 컨테이너식 애플리케이션을 배포하는 단일 머신으로 함께 처리할 수 있는 노드 집합입니다.
포드: Kubernetes에서는 컨테이너가 포드 내에서 실행됩니다. 포드는 Kubernetes의 기본 단위입니다. 포드에는 하나 이상의 컨테이너가 있습니다. 자체 포드에
server
및loadgen
컨테이너를 각각 배포합니다. 포드가 여러 컨테이너(예: 애플리케이션 서버 및 프록시 서버)를 실행할 때 컨테이너는 단일 항목으로 관리되며 포드의 리소스를 공유합니다.배포: 배포는 동일한 포드 집합을 나타내는 Kubernetes 객체입니다. 배포는 클러스터 노드 간에 분산된 포드의 여러 복제본을 실행합니다. 배포는 실패하거나 응답하지 않는 포드를 자동으로 교체합니다.
Kubernetes Service: GKE에서 애플리케이션 코드를 실행하면
loadgen
과server
사이의 네트워킹이 변경됩니다. Cloud Shell VM에서 서비스를 실행하면localhost:8080
주소를 사용하여server
에 요청을 전송할 수 있습니다. GKE에 배포한 후 Pod는 사용 가능한 노드에서 실행되도록 예약됩니다. 기본적으로 Pod가 실행 중인 노드를 제어할 수 없으므로 Pod에는 안정적인 IP 주소가 없습니다.server
의 IP 주소를 가져오려면 Kubernetes 서비스라는 Pod 외에도 네트워킹 추상화를 정의해야 합니다. Kubernetes 서비스는 포드 집합에 안정적인 네트워킹 엔드포인트를 제공합니다. 서비스 유형이 몇 가지 있습니다.server
는 외부 IP 주소를 노출하는LoadBalancer
를 사용하여 클러스터 외부에서server
에 연결할 수 있습니다.Kubernetes에는 서비스에 DNS 이름(예:
helloserver.default.cluster.local
)을 할당하는 DNS 시스템이 내장되어 있습니다. 따라서 클러스터 내의 Pod가 안정적인 주소로 클러스터의 다른 Pod에 도달할 수 있습니다. 이 DNS 이름은 Cloud Shell에서와 같이 클러스터 외부에서 사용할 수 없습니다.
kubernetes manifests
소스 코드에서 애플리케이션을 실행한 경우 명령형 명령어(python3 server.py
)를 사용한 것입니다.
명령형은 '수행하세요'와 같이 동사 기반입니다.
이와 달리 Kubernetes는 선언적 모델에서 작동합니다. 즉, Kubernetes에게 해야 할 일을 정확하게 알려주는 대신 Kubernetes에 원하는 상태를 제공합니다. 예를 들어 Kubernetes는 필요에 따라 포드를 시작하고 종료하여 실제 시스템 상태가 원하는 상태와 일치하도록 합니다.
매니페스트 집합 또는 YAML 파일에서 원하는 상태를 지정합니다. YAML 파일에는 하나 이상의 Kubernetes 객체 사양이 포함됩니다.
샘플에는 server
및 loadgen
의 YAML 파일이 포함됩니다. 각 YAML 파일은 Kubernetes 배포 객체 및 서비스에 원하는 상태를 지정합니다.
서버
kind
는 객체 유형을 나타냅니다.metadata.name
은 배포 이름을 지정합니다.- 첫 번째
spec
필드에는 원하는 상태에 대한 설명이 포함됩니다. spec.replicas
는 원하는 포드 수를 지정합니다.spec.template
섹션은 포드 템플릿을 정의합니다. 포드 사양에 포함된image
필드는 Container Registry에서 가져올 이미지의 이름입니다.
서비스는 다음과 같이 정의됩니다.
LoadBalancer
: 클라이언트가 안정적인 IP 주소를 가지고 있고 클러스터 외부에 연결할 수 있는 네트워크 부하 분산기의 IP 주소로 요청을 보냅니다.targetPort
:Dockerfile
의EXPOSE 8080
명령어는 실제로 포트를 노출하지 않습니다. 클러스터 외부의server
컨테이너에 도달할 수 있도록 포트8080
를 노출합니다. 이 경우hellosvc.default.cluster.local:80
(짧은 이름:hellosvc
)는helloserver
포드 IP의 포트8080
에 매핑합니다.port
: 클러스터의 다른 서비스가 요청을 보낼 때 사용하는 포트 번호입니다.
부하 생성기
loadgen.yaml
의 배포 객체는 server.yaml
과 비슷합니다. 한 가지 중요한 차이점은 배포 객체에 env
라는 섹션이 포함되어 있다는 것입니다. 이 섹션에서는 이전에 소스에서 애플리케이션을 실행할 때 설정한 loadgen
에 필요한 환경 변수를 정의합니다.
loadgen
은 들어오는 요청을 수락하지 않으므로 type
필드는 ClusterIP
로 설정됩니다. 이 유형은 클러스터의 서비스가 사용할 수 있는 안정적인 IP 주소를 제공하지만 IP 주소가 외부 클라이언트에 노출되지 않습니다.
GKE에 컨테이너 배포
샘플
server
가 있는 디렉터리로 변경합니다.cd YOUR_WORKING_DIRECTORY/anthos-service-mesh-samples/docs/helloserver/server/
텍스트 편집기에서
server.yaml
를 엽니다.image
필드의 이름을 Docker 이미지의 이름으로 바꿉니다.image: gcr.io/PROJECT_ID/asm-ready/helloserver:v0.0.1
PROJECT_ID
를 Google Cloud 프로젝트 ID로 바꿉니다.저장 후
server.yaml
을 닫습니다.YAML 파일을 Kubernetes에 배포합니다.
kubectl apply -f server.yaml
성공하면 명령어가 다음과 같이 응답합니다.
deployment.apps/helloserver created service/hellosvc created
loadgen
이 있는 디렉터리로 변경합니다.cd ../loadgen
텍스트 편집기에서
loadgen.yaml
를 엽니다.image
필드의 이름을 Docker 이미지의 이름으로 바꿉니다.image: gcr.io/PROJECT_ID/asm-ready/loadgen:v0.0.1
PROJECT_ID
를 Google Cloud 프로젝트 ID로 바꿉니다.loadgen.yaml
을 저장한 다음 닫고 텍스트 편집기를 닫습니다.YAML 파일을 Kubernetes에 배포합니다.
kubectl apply -f loadgen.yaml
성공하면 명령어가 다음과 같이 응답합니다.
deployment.apps/loadgenerator created service/loadgensvc created
포드 상태를 확인합니다.
kubectl get pods
이 명령어는 다음과 유사한 상태로 응답합니다.
NAME READY STATUS RESTARTS AGE helloserver-69b9576d96-mwtcj 1/1 Running 0 58s loadgenerator-774dbc46fb-gpbrz 1/1 Running 0 57s
loadgen
포드에서 애플리케이션 로그를 가져옵니다.POD_ID
를 이전 출력의 식별자로 바꿉니다.kubectl logs loadgenerator-POD_ID
hellosvc
의 외부 IP 주소를 가져옵니다.kubectl get service
명령어 응답은 다음 형식과 비슷합니다.
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE hellosvc LoadBalancer 10.81.15.158 192.0.2.1 80:31127/TCP 33m kubernetes ClusterIP 10.81.0.1 <none> 443/TCP 93m loadgensvc ClusterIP 10.81.15.155 <none> 80/TCP 4m52s
hellosvc
로 요청을 보냅니다.EXTERNAL_IP
를hellosvc
의 외부 IP 주소로 바꿉니다.curl http://EXTERNAL_IP
Anthos Service Mesh 준비 완료
이제 애플리케이션이 GKE에 배포되었습니다. loadgen
은 Kubernetes DNS(hellosvc:80
)를 사용하여 server
에 요청을 보낼 수 있으며 외부 IP 주소로 server
에 요청을 보낼 수 있습니다. Kubernetes는 많은 기능을 제공하지만 서비스에 대한 일부 정보가 없습니다.
- 서비스는 어떻게 상호작용하나요? 서비스 간에는 어떤 관계가 있나요? 서비스 간에 트래픽은 어떻게 흐르나요?
loadgen
이server
에 요청을 보내는 것을 알고 있지만 애플리케이션에 익숙하지 않습니다. GKE에서 실행 중인 포드 목록에서는 이러한 질문에 대한 답을 얻을 수 없습니다. - 측정항목:
server
가 수신되는 요청에 응답하는 데 얼마나 걸리나요?server
에 수신되는 RPS(초당 요청 수)는 몇 개인가요? 오류 응답이 있나요? - 보안 정보:
loadgen
과server
간 트래픽은 일반HTTP
인가요, 아니면 mTLS인가요?
Anthos Service Mesh는 이 질문에 대한 답을 제공할 수 있습니다. Anthos Service Mesh는 오픈소스 Istio 프로젝트의 Google Cloud 관리형 버전입니다. Anthos Service Mesh는 각 포드에 Envoy 사이드카 프록시를 배치하는 방식으로 작동합니다. Envoy 프록시는 애플리케이션 컨테이너에 대한 모든 인바운드 및 아웃바운드 트래픽을 가로챕니다. 즉, server
와 loadgen
은 각각 Envoy 사이드카 프록시를 가져오고 loadgen
에서 server
로 전송되는 모든 트래픽은 Envoy 프록시로 미디에이션됩니다. 이러한 Envoy 프록시 간의 연결은 서비스 메시를 형성합니다. 이 서비스 메시 아키텍처는 Kubernetes 위에 제어 레이어를 제공합니다.
Envoy 프록시는 자체 컨테이너에서 실행되므로 애플리케이션 코드를 크게 변경하지 않고 GKE 클러스터 위에 Anthos Service Mesh를 설치할 수 있습니다. 하지만 Anthos Service Mesh로 계측할 수 있도록 애플리케이션을 준비한 몇 가지 주요 방법은 다음과 같습니다.
- 모든 컨테이너의 서비스:
server
배포와loadgen
배포 모두 Kubernetes 서비스가 연결되어 있습니다. 인바운드 요청을 수신하지 않는loadgen
에도 서비스가 있습니다. - 서비스의 포트 이름을 지정해야 합니다. GKE에서는 이름이 지정되지 않은 서비스 포트를 정의할 수 있지만, Anthos Service Mesh에서는 포트 프로토콜과 일치하는 포트 이름을 제공해야 합니다.
server
가HTTP
통신 프로토콜을 사용하므로 YAML 파일에서server
의 포트의 이름은http
로 지정됩니다.service
가gRPC
를 사용한 경우 포트 이름을grpc
로 지정합니다. - 배포에는 라벨이 지정됩니다. 이렇게 하면 동일한 서비스의 버전 간 트래픽 분할과 같은 Anthos Service Mesh 트래픽 관리 기능을 사용할 수 있습니다.
Anthos Service Mesh 설치
Anthos Service Mesh 설치 가이드를 방문하여 안내에 따라 클러스터에 Anthos Service Mesh를 설치합니다.
삭제
이 가이드에서 사용된 리소스 비용이 Google Cloud 계정에 청구되지 않도록 하려면 리소스가 포함된 프로젝트를 삭제하거나 프로젝트를 유지하고 개별 리소스를 삭제하세요.
삭제하려면 GKE 클러스터를 삭제합니다. 클러스터를 삭제하면 컨테이너 클러스터를 구성하는 모든 리소스(예: 컴퓨팅 인스턴스, 디스크, 네트워크 리소스)가 삭제됩니다.
gcloud container clusters delete asm-ready
다음 단계
이 가이드에서 사용되는 기술에 대해 자세히 알아보세요.
도구에 대해 자세히 알아보기
Kubernetes 개념에 대해 자세히 알아보세요.