이 문서에서는 분산 추적을 사용하여 마이크로서비스 지연 시간 관찰에 설명된 참조 아키텍처를 배포하는 방법을 보여줍니다. 이 문서에 설명된 배포는 OpenTelemetry 및 Cloud Trace를 사용하여 마이크로서비스 애플리케이션의 trace 정보를 캡처합니다.
이 배포의 샘플 애플리케이션은 Go로 작성된 마이크로서비스 두 개로 구성됩니다.
이 문서에서는 사용자가 다음에 익숙하다고 가정합니다.
- Go 프로그래밍 언어
- Google Kubernetes Engine(GKE)
목표
- GKE 클러스터를 만들고 샘플 애플리케이션을 배포합니다.
- OpenTelemetry 계측 코드를 검토합니다.
- 계측에서 생성된 trace 및 로그를 검토합니다.
아키텍처
다음 다이어그램은 배포할 아키텍처를 보여줍니다.
완전 관리형 지속적 통합, 전송, 배포 플랫폼인 Cloud Build를 사용하여 샘플 코드에서 컨테이너 이미지를 만들고 Artifact Registry에 저장합니다. GKE 클러스터는 배포 시 Artifact Registry에서 이미지를 가져옵니다.
프런트엔드 서비스는 /
URL에서 HTTP 요청을 수락하고 백엔드 서비스를 호출합니다. 백엔드 서비스의 주소는 환경 변수로 정의됩니다.
백엔드 서비스는 /
URL에서 HTTP 요청을 수락하고 환경 변수에 정의된 외부 URL로 아웃바운드 호출을 수행합니다. 외부 호출이 완료되면 백엔드 서비스가 호출자에게 HTTP 상태 호출(예: 200
)을 반환합니다.
비용
이 문서에서는 비용이 청구될 수 있는 다음과 같은 Google Cloud 구성요소를 사용합니다.
프로젝트 사용량을 기준으로 예상 비용을 산출하려면 가격 계산기를 사용하세요.
이 문서에 설명된 태스크를 완료했으면 만든 리소스를 삭제하여 청구가 계속되는 것을 방지할 수 있습니다. 자세한 내용은 삭제를 참조하세요.
시작하기 전에
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Enable the GKE, Cloud Trace, Cloud Build, Cloud Storage, and Artifact Registry APIs.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Enable the GKE, Cloud Trace, Cloud Build, Cloud Storage, and Artifact Registry APIs.
환경 설정하기
이 섹션에서는 배포 전반에서 사용하는 도구로 환경을 설정합니다. 이 배포의 모든 터미널 명령어는 Cloud Shell에서 실행해야 합니다.
-
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.
- 환경 변수를 Google Cloud 프로젝트의 ID로 설정합니다.
export PROJECT_ID=$(gcloud config list --format 'value(core.project)' 2>/dev/null)
- 연결된 Git 저장소를 클론하여 이 배포에 필요한 파일을 다운로드합니다.
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples.git cd kubernetes-engine-samples/observability/distributed-tracing WORKDIR=$(pwd)
저장소 폴더를 이 배포와 관련된 모든 태스크를 수행하는 작업 디렉터리(
$WORKDIR
)로 만듭니다. 이렇게 하면 리소스를 유지하지 않는 경우 배포를 완료했을 때 폴더를 삭제하면 됩니다.
도구 설치
Cloud Shell에서
kubectx
및kubens
를 설치합니다.git clone https://github.com/ahmetb/kubectx $WORKDIR/kubectx export PATH=$PATH:$WORKDIR/kubectx
이 두 도구를 사용하여 여러 Kubernetes 클러스터, 컨텍스트, 네임스페이스 관련 작업을 수행할 수 있습니다.
Cloud Shell에서 오픈소스 부하 생성 도구인 Apache Bench를 설치합니다.
sudo apt-get install apache2-utils
Docker 저장소 만들기
이 배포의 샘플 이미지를 저장할 Docker 저장소를 만듭니다.
콘솔
Google Cloud 콘솔에서 저장소 페이지를 엽니다.
저장소 만들기를 클릭합니다.
distributed-tracing-docker-repo
를 저장소 이름으로 지정합니다.형식은 Docker를 선택하고 모드는 표준을 선택합니다.
위치 유형에서 리전을 선택한 후
us-west1
위치를 선택합니다.만들기를 클릭합니다.
저장소가 저장소 목록에 추가됩니다.
gcloud
Cloud Shell에서
us-west1
위치에docker repository
이라는 설명과 함께distributed-tracing-docker-repo
라는 새 Docker 저장소를 만듭니다.gcloud artifacts repositories create distributed-tracing-docker-repo --repository-format=docker \ --location=us-west1 --description="Docker repository for distributed tracing deployment"
저장소가 만들어졌는지 확인합니다.
gcloud artifacts repositories list
GKE 클러스터 만들기
이 섹션에서는 샘플 애플리케이션을 배포하는 2개의 GKE 클러스터를 만듭니다. GKE 클러스터는 기본적으로 Cloud Trace API에 대해 쓰기 전용 액세스 권한으로 생성됩니다. 따라서 클러스터를 만들 때 액세스 권한을 정의할 필요가 없습니다.
Cloud Shell에서 클러스터를 만듭니다.
gcloud container clusters create backend-cluster \ --zone=us-west1-a \ --verbosity=none --async gcloud container clusters create frontend-cluster \ --zone=us-west1-a \ --verbosity=none
이 예시에서 클러스터는
us-west1-a
영역에 위치합니다. 자세한 내용은 위치 및 리전을 참조하세요.클러스터 사용자 인증 정보를 가져와 로컬에 저장합니다.
gcloud container clusters get-credentials backend-cluster --zone=us-west1-a gcloud container clusters get-credentials frontend-cluster --zone=us-west1-a
나중에 컨텍스트에서 쉽게 액세스할 수 있도록 클러스터 컨텍스트 이름을 바꿉니다.
kubectx backend=gke_${PROJECT_ID}_us-west1-a_backend-cluster kubectx frontend=gke_${PROJECT_ID}_us-west1-a_frontend-cluster
OpenTelemetry 계측 검토
다음 섹션에서는 샘플 애플리케이션의 main.go
파일에서 코드를 검토합니다. 이렇게 하면 컨텍스트 전파를 사용하여 여러 요청의 스팬을 단일 상위 trace에 추가하도록 허용하는 방법을 알아보는 데 도움이 됩니다.
애플리케이션 코드의 가져오기 검토
가져오기와 관련하여 다음 사항에 유의하세요.
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp
패키지에는 HTTP 서버 또는 HTTP 클라이언트를 계측할 수 있는otelhttp
플러그인이 포함됩니다. 서버 계측은 HTTP 요청에서 스팬 컨텍스트를 검색하고 서버의 요청 처리를 위한 스팬을 기록합니다. 클라이언트 계측은 스팬 컨텍스트를 발신 HTTP 요청에 삽입하고 응답을 대기하는 데 소요된 시간 스팬을 기록합니다.go.opentelemetry.io/contrib/propagators/autoprop
패키지는 전파를 처리하기 위해otelhttp
에서 사용하는 OpenTelemetryTextMapPropagator
인터페이스의 구현을 제공합니다. 전파는 HTTP와 같은 전송의 trace 컨텍스트를 저장하는 데 사용되는 형식과 키를 결정합니다. 특히otelhttp
는 HTTP 헤더를 전파에 전달합니다. 전파는 헤더에서 스팬 컨텍스트를 Go 컨텍스트로 추출하거나, Go 컨텍스트의 스팬 컨텍스트를 인코딩하여 헤더에 삽입합니다(클라이언트 또는 서버인지에 따라 다름). 기본적으로autoprop
패키지는 W3C trace 컨텍스트 전파 형식을 사용하여 스팬 컨텍스트를 삽입하고 추출합니다.github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace
가져오기는 trace를 Cloud Trace로 내보냅니다.github.com/gorilla/mux
가져오기는 샘플 애플리케이션에서 요청 처리에 사용하는 라이브러리입니다.go.opentelemetry.io/contrib/detectors/gcp
가져오기는 애플리케이션이 Google Cloud 내에서 실행되는 위치를 식별하는cloud.availability_zone
과 같은 스팬에 속성을 추가합니다.- OpenTelemetry를 설정하는 데 사용되는
go.opentelemetry.io/otel
,go.opentelemetry.io/otel/sdk/trace
,go.opentelemetry.io/otel/sdk/resource
가져오기
main
함수 검토
main
함수는 Cloud Trace로의 trace 내보내기를 설정하고 mux 라우터를 사용하여 /
URL에 대한 요청을 처리합니다.
이 코드에 대해서는 다음 사항에 유의하세요.
- Google Cloud에서 실행될 때 속성을 감지하고 Cloud Trace로 trace를 내보내는 OpenTelemetry TracerProvider를 구성합니다.
otel.SetTracerProvider
및otel.SetTextMapPropagators
함수를 사용하여 전역TracerProvider
및Propagator
설정을 지정합니다. 기본적으로otelhttp
와 같은 계측 라이브러리는 전역으로 등록된TracerProvider
를 사용하여 스팬 및Propagator
를 만들고 컨텍스트를 전파합니다.- HTTP 서버를
otelhttp.NewHandler
로 래핑하여 HTTP 서버를 계측합니다.
mainHandler
함수 검토
대상에 대한 아웃바운드 요청의 지연 시간을 캡처하려면 otelhttp
플러그인을 사용하여 HTTP 요청을 수행합니다. 또한 다음과 같이 r.Context
함수를 사용하여 수신 요청을 송신 요청에 연결합니다.
// Use otelhttp to record a span for the outgoing call, and propagate
// context to the destination.
resp, err := otelhttp.Get(r.Context(), destination)
애플리케이션 배포
이 섹션에서는 Cloud Build를 사용하여 백엔드 및 프런트엔드 서비스의 컨테이너 이미지를 빌드한 다음 이를 GKE 클러스터에 배포합니다.
Docker 컨테이너 빌드
Cloud Shell의 작업 디렉터리에서 빌드를 제출합니다.
cd $WORKDIR gcloud builds submit . --tag us-west1-docker.pkg.dev/$PROJECT_ID/distributed-tracing-docker-repo/backend:latest
컨테이너 이미지가 성공적으로 생성되었고 Artifact Registry에서 사용할 수 있는지 확인합니다.
gcloud artifacts docker images list us-west1-docker.pkg.dev/$PROJECT_ID/distributed-tracing-docker-repo
출력이 다음과 비슷하면 컨테이너 이미지가 성공적으로 생성된 것입니다. 여기서
PROJECT_ID
는 Google Cloud 프로젝트의 ID입니다.NAME us-west1-docker.pkg.dev/PROJECT_ID/distributed-tracing-docker-repo/backend
백엔드 서비스 배포
Cloud Shell에서
kubectx
컨텍스트를backend
클러스터로 설정합니다.kubectx backend
backend
배포를 위한 YAML 파일을 만듭니다.export PROJECT_ID=$(gcloud info --format='value(config.project)') envsubst < backend-deployment.yaml | kubectl apply -f -
포드가 실행 중인지 확인합니다.
kubectl get pods
출력에
Running
의Status
값이 표시됩니다.NAME READY STATUS RESTARTS AGE backend-645859d95b-7mx95 1/1 Running 0 52s backend-645859d95b-qfdnc 1/1 Running 0 52s backend-645859d95b-zsj5m 1/1 Running 0 52s
부하 분산기를 사용하여
backend
배포를 노출합니다.kubectl expose deployment backend --type=LoadBalancer
backend
서비스의 IP 주소를 가져옵니다.kubectl get services backend
출력은 다음과 비슷합니다.
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE backend LoadBalancer 10.11.247.58 34.83.88.143 8080:30714/TCP 70s
EXTERNAL-IP
필드 값이<pending>
인 경우 IP 주소 값이 나올 때까지 명령어를 반복합니다.이전 단계의 IP 주소를 변수로 캡처합니다.
export BACKEND_IP=$(kubectl get svc backend -ojson | jq -r '.status.loadBalancer.ingress[].ip')
프런트엔드 서비스 배포
Cloud Shell에서
kubectx
컨텍스트를 백엔드 클러스터로 설정합니다.kubectx frontend
frontend
배포를 위한 YAML 파일을 만듭니다.export PROJECT_ID=$(gcloud info --format='value(config.project)') envsubst < frontend-deployment.yaml | kubectl apply -f -
포드가 실행 중인지 확인합니다.
kubectl get pods
출력에
Running
의Status
값이 표시됩니다.NAME READY STATUS RESTARTS AGE frontend-747b445499-v7x2w 1/1 Running 0 57s frontend-747b445499-vwtmg 1/1 Running 0 57s frontend-747b445499-w47pf 1/1 Running 0 57s
부하 분산기를 사용하여
frontend
배포를 노출합니다.kubectl expose deployment frontend --type=LoadBalancer
frontend
서비스의 IP 주소를 가져옵니다.kubectl get services frontend
출력은 다음과 비슷합니다.
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE frontend LoadBalancer 10.27.241.93 34.83.111.232 8081:31382/TCP 70s
EXTERNAL-IP
필드 값이<pending>
인 경우 IP 주소 값이 나올 때까지 명령어를 반복합니다.이전 단계의 IP 주소를 변수로 캡처합니다.
export FRONTEND_IP=$(kubectl get svc frontend -ojson | jq -r '.status.loadBalancer.ingress[].ip')
애플리케이션 로드 및 trace 검토
이 섹션에서는 Apache Bench 유틸리티를 사용하여 애플리케이션에 대한 요청을 만듭니다. 그런 다음 Cloud Trace에서 결과 trace를 검토합니다.
Cloud Shell에서 Apache Bench를 사용하여 3개의 동시 스레드를 통해 1,000개의 요청을 생성합니다.
ab -c 3 -n 1000 http://${FRONTEND_IP}:8081/
Google Cloud Console에서 Trace 목록 페이지로 이동합니다.
타임라인을 검토하려면
server
라벨이 지정된 URI 중 하나를 클릭합니다.이 trace에는 다음 이름을 가진 4개의 스팬이 포함됩니다.
- 첫 번째
server
스팬은 프런트엔드 서버에서 HTTP 요청을 처리할 때의 엔드 투 엔드 지연 시간을 캡처합니다. - 첫 번째
HTTP GET
스팬은 프런트엔드 클라이언트가 백엔드로 요청한 GET 호출의 지연 시간을 캡처합니다. - 두 번째
server
스팬은 백엔드 서버에서 HTTP 요청을 처리할 때의 엔드 투 엔드 지연 시간을 캡처합니다. - 두 번째
HTTP GET
스팬은 백엔드 클라이언트가 google.com에 요청한 GET 호출의 지연 시간을 캡처합니다.
- 첫 번째
삭제
비용이 청구되지 않도록 하는 가장 쉬운 방법은 배포하면서 만든 Google Cloud 프로젝트를 삭제하는 것입니다. 또는 개별 리소스를 삭제할 수 있습니다.
프로젝트 삭제
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.
개별 리소스 삭제
전체 프로젝트를 삭제하는 대신 개별 리소스를 삭제하려면 Cloud Shell에서 다음 명령어를 실행합니다.
gcloud container clusters delete frontend-cluster --zone=us-west1-a
gcloud container clusters delete backend-cluster --zone=us-west1-a
gcloud artifacts repositories delete distributed-tracing-docker-repo --location us-west1
다음 단계
- OpenTelemetry에 대해 알아보세요.
- 그 밖의 참조 아키텍처, 다이어그램, 튜토리얼, 권장사항을 알아보려면 클라우드 아키텍처 센터를 확인하세요.