구글 클라우드 인사이트 istio 사용하기 구글 인사이트 by Miyeon. Jo 2024년 02월 07일 2024년 02월 07일 517 PS1팀 조웅기목차istio 사용하기이스티오(Istio)란?이스티오가 제공하는 기능들이스티오의 아키텍처istio 테스트테스트 환경 구성istio 모니터링 하기Prometheus (로그 메트릭 수집)Grafana (모니터링)Kiali (모니터링)istio 사용하기이스티오(Istio)란?서비스 메쉬 오픈소스기존의 응용프로그램 위에 레이어링되어 다양한 동작들을 수행GCP에서는 이를 완전 관리해주는 서비스를 Anthos라고 함서비스 메쉬 설명 전 마이크로서비스란?소프트웨어를 구축하기 위한 아키텍처이자 하나의 접근 방식으로, 애플리케이션을 상호 독립적인 최소 구성 요소로 분할하는 방식모든 요소를 하나의 애플리케이션에 구축하는 전통적인 접근 방식 대신 마이크로서비스에서는 모든 요소가 독립적이며 연동되어 테스크를 수행이러한 각각의 구성 요소 또는 프로세스가 마이크로 서비스그렇다면 서비스 메쉬란 무엇인가?마이크로 서비스를 위한 인프라 계층레거시 코드의 변경 없이 각 서비스에 대해 가시성, 트래픽 관리, 보안 기능 등을 추가복잡하고 방대한 규모의 마이크로서비스에 대한 관리 용이마이크로서비스를 적용한 시스템의 내부 통신이 Mesh 네트워크 형태를 띄는 것에 빗대어 서비스 메쉬라고 말하고 있음서비스 간의 통신을 추상화를 통해 복잡한 내부 구조를 제어, 추적, 내부 네트워크 관련 로직을 추가함으로써 안정성, 신뢰성, 탄력성, 표준화, 가시성, 보안성 등을 확보Service Mesh 는 URL 경로, 호스트 헤더, API 버전 또는 기타 응용 프로그램 수준 규칙을 기반으로 하는 계층 7 네트워크 LayerService Mesh 의 구현체인 경량화 Proxy를 통해 다양한 Routing Rules, Circuit breaker 등 공통기능을 설정할 수 있습니다.이는 서비스 간 통신에 연관된 기능 뿐만 아니라, 서비스의 배포 전략에도 도움을 줍니다.이스티오가 제공하는 기능들클러스터 내부에서 TLS 암호화를 이용한 서비스간 안전한 통신 제공HTTP, gRPC, WebSocket 및 TCP 트래픽에 대한 로드 밸런싱재시도, 다양한 라우팅 규칙, fault injection 등을 통해 세부 트래픽 동작을 제어클러스터 내의 모든 트래픽에 대한 메트릭 수집과 로그 추적이스티오의 아키텍처<Istio 활용 전 아키텍쳐)<Istio 활용 후 아키텍쳐)데이터 플레인데이터 플레인은 데이터 전송과 처리를 담당하는 부분각 서비스를 Envoy proxy와 함께 배포(사이드카 패턴 방식)각 서비스 앞단에 프록시 서버를 두어 서비스로 또는 서비스로부터 나가는 모든 네트워크 패킷을 변환, 전달 및 모니터링Envoy proxy란?클라우드 네이티브용으로 Lyft 사에서 C++로 개발해서 2016년 12월 14일 공개한 L7 프록시2017년 5월에 Google, Lyft, IBM에서 공동으로 개발해서 내놓은 Service Mesh 오픈소스인 Istio의 메인 프록시가 됨주요 기능OUT OF PROCESS ARCHITECTUREEnvoy proxy는 그 자체로 메모리사용량이 적은 고성능의 서버입니다.모든 프로그래밍 언어, 프레임워크와 함께 실행될 수 있습니다.이는 다양한 언어,프레임워크를 함께 사용하는 Architecture에 유용히 사용될 수 있습니다.HTTP/2(1) AND gRPC SUPPORTHTTP/1.1은 물론 HTTP/2도 지원합니다.이는 HTTP/1.1과 HTTP/2 클라이언트와 서버간 모든 조합을 연결할 수 있음을 의미합니다.권장하는 구조는 모든 Envoy간에 HTTP/2를 사용하는 것입니다.또한 gRPC를 지원하여 HTTP/2기능을 보완할 수 있습니다.L3/L4 Architecture : Envoy의 주요 기능은 L7이지만 핵심은 L3/L4 네트워크 프록시 입니다. TCP프록시, HTTP프록시, TLS인증과 같은 다양한 작업을 지원합니다.L7 Architecture : 버퍼링, 속도제한, 라우팅/전달 등과 같은 다양한 작업을 수행할 수 있게 합니다.ADVANCED LOAD BALANCING자동 재시도, circuit break, 외부 속도 제한 서비스를 통한 글로벌 속도제한, 이상치 탐지 등의 기능을 제공합니다.APIS FOR CONFIGURATION MANAGEMENTEnvoy는 구성을 동적으로 관리하기 위한 강력한 API를 제공합니다.OBSERVABILITYL7 트래픽의 심층 관찰 성, 분산 추적에 대한 기본 지원, MongoDB, DynamoDB 등의 와이어 수준 관찰성을 제공합니다.사이드카 패턴이란?사이드카 패턴은 원래 사용하려고 했던 기본 컨테이너의 기능을 확장하거나 보조하는 용도의 컨테이너를 추가하는 패턴즉, 기본 컨테이너와 독립적으로 동작하는 별도의 컨테이너를 붙이는 패턴이기 때문에 어플리케이션 컨테이너의 변경이나 수정 없이 독립적으로 동작하는 컨테이너를 붙였다 뗐다 할 수 있다.컨트롤 플레인컨트롤 플레인은 네트워크의 제어와 관리를 담당하는 부분회로 차단, 로드 밸런싱, 타임아웃 등의 기본 구성 정보를 저장기본 구성 정보에 맞게 각 서비스의 프록시를 동istio 테스트테스트 환경 구성1. 테스트용 이미지 생성$ dotnet --version # 닷넷 기반 테스트 이미지 생성을 위한 설치 확인 $ dotnet new mvc -o HelloWorldAspNetCore # 닷넷 기반 웹 응용 프로그램 생성 $ vim Dockerfile # 도커 파일 생성 # Use Microsoft's official build .NET image. # https://hub.docker.com/_/microsoft-dotnet-core-sdk/ FROM mcr.microsoft.com/dotnet/sdk:7.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:7.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"] # 아래 코드 실행하기 전 Artifact Registry 저장소 생성 $ docker build -t asia-northeast3-docker.pkg.dev/${GOOGLE_CLOUD_PROJECT}/<생성한 저장소 이름>/hello-dotnet:v1 . $ docker push asia-northeast3-docker.pkg.dev/${GOOGLE_CLOUD_PROJECT}/<생성한 저장소 이름>/hello-dotnet:v12. GKE 생성$ gcloud services enable container.googleapis.com # GKE API 설정 gcloud container clusters create istio-test \ --cluster-version=latest \ --machine-type=n1-standard-2 \ --num-nodes=1 \ --region asia-northeast33. Istio 클라이언트 다운$ curl -L https://istio.io/downloadIstio | sh - # cli 창에서 뜬 istio 버전의 디렉토리가 생성됨 (테스트 현재 기준 istio-1.20.0) $ cd istio-1.20.0 # istioctl을 사용하기 위해 환경 변수 지정 $ export PATH="$PATH:/home//istio-1.20.0/bin"4. Istio 클라이언트 상태 확인# 생성한 gke 연결 후 $ gcloud container clusters get-credentials istio-test --region asia-northeast3 --project iistio $ istioctl x precheck # 환경 확인 (정상이면 아래와 같이 나옴) No issues found when checking the cluster. Istio is safe to install or upgrade! $ istioctl install --set profile=demo # 테스트를 위한 demo 프로필 사용 후 설치 $ kubectl label namespace default istio-injection=enabled # 자동 사이드카 매칭 $ kubectl get namespace -L istio-injection # 사이드카 확인 # 정상 설치 확인 (아래 3개 존재 확인) $ kubectl get svc -n istio-system istio-egressgateway ClusterIP 10.104.3.223 <none> 80/TCP,443/TCP 102s istio-ingressgateway LoadBalancer 10.104.9.211 34.64.230.54 15021:32493/TCP,80:31798/TCP,443:32556/TCP,31400:30436/TCP,15443:30945/TCP 102s istiod ClusterIP 10.104.14.127 <none> 15010/TCP,15012/TCP,443/TCP,15014/TCP 103s $ kubectl get pods -n istio-system (아래 3개 존재 확인) istio-egressgateway-56c5f9b7cc-s2xbk 1/1 Running 0 6m25s istio-ingressgateway-678fd6f6b9-xv8js 1/1 Running 0 6m25s istiod-664dc95b55-dfpv4 1/1 Running 0 6m25s5. 애플리케이션 배포aspnetcore.yamlapiVersion: 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: asia-northeast3-docker.pkg.dev//hello-dotnet/hello-dotnet:v2 imagePullPolicy: IfNotPresent ports: - containerPort: 8080$ kubectl apply -f aspnetcore.yaml $ kubectl get pods6. 테스트용 게이트웨이 및 가상 서비스 배포aspnetcore-gateway.yamlapiVersion: 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.yamlapiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: aspnetcore-virtualservice spec: hosts: - "*" gateways: - aspnetcore-gateway http: - route: - destination: host: aspnetcore-service7. 정상 동작 테스트kubectl get svc istio-ingressgateway -n istio-system 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 -o /dev/null -s -w "%{http_code}\n" http://${GATEWAY_URL}/<서비스 접속 확인)8. 신규 버전 배포vim aspnetcore2.yamlapiVersion: apps/v1 kind: Deployment metadata: name: aspnetcore-v2 spec: replicas: 1 selector: matchLabels: app: aspnetcore version: v2 template: metadata: labels: app: aspnetcore version: v2 spec: containers: - name: aspnetcore image: asia-northeast3-docker.pkg.dev/iistio/hello-dotnet/hello-dotnet:v2 imagePullPolicy: IfNotPresent ports: - containerPort: 8080v1와 v2배포가 모두 동일한 Kubernetes 서비스( aspnetcore-service) 뒤에 노출되고 이전 실습( )에서 생성한 VirtualService가 aspnetcore-virtualservice해당 서비스를 호스트로 사용하여 새로 고침을 하였을 때 각각 다르게 나옵니다.9. 서비스 새 버전으로 고정DestinationRule은 해당 대상 호스트의 명명된 버전을 의미하는 주소 지정 가능한 하위 집합도 정의하며 특정 버전의 서비스로 트래픽을 보낼 때 VirtualService 경로 사양에 사용본 서버(v1) 업데이트 시에 임시 서버(v2)를 바라보게 셋팅 가능 추측aspnetcore-destinationrule.yamlapiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: aspnetcore-destinationrule spec: host: aspnetcore-service trafficPolicy: tls: mode: ISTIO_MUTUAL subsets: - name: v1 labels: version: v1 - name: v2 labels: version: v2 # VirtualService에서 사용할 수 있는 두 개의 하위 집합(v1 및 v2)이 생성$ kubectl apply -f aspnetcore-destinationrule.yamlaspnetcore-virtualservice.yaml 수정apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: aspnetcore-virtualservice spec: hosts: - "*" gateways: - aspnetcore-gateway http: - route: - destination: host: aspnetcore-service **subset: v2 # 이렇게 서브셋을 지정해줌**$ kubectl apply -f aspnetcore-virtualservice.yaml10. 버전 간 트래픽 분할테스트나 과부화를 위한 트래픽 분할 가능 : 예를 들어 트래픽의 75%를 v1로 보내고 트래픽의 25%를 v2 버전의 서비스로 보낼 수 있음카나리 배포로 사용aspnetcore-virtualservice.yaml 수정apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: aspnetcore-virtualservice spec: hosts: - "*" gateways: - aspnetcore-gateway http: - route: - destination: host: aspnetcore-service subset: v1 weight: 75 - destination: host: aspnetcore-service subset: v2 weight: 25$ kubectl apply -f aspnetcore-virtualservice-weights.yaml11. 지연 및 에러 코드 발생 시키기트래픽에 오류나 지연을 삽입하고 서비스가 이에 응답하여 어떻게 작동하는지 확인 가능aspnetcore-virtualservice-fault-abort.yamlapiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: aspnetcore-virtualservice spec: hosts: - "*" gateways: - aspnetcore-gateway http: - fault: ## fault를 추가하면 에러 코드를 반환시킬 수 있다. 400 코드를 50% 반환 abort: percentage: value: 50 httpStatus: 400 route: - destination: host: aspnetcore-service subset: v1 # 버전 1에 대해 에러 400 반환$ kubectl apply -f aspnetcore-virtualservice-fault-abort.yaml지연이 필요한 경우 아래와 같이 설정할 수 있습니다.aspnetcore-virtualservice-fault-delay.yamlapiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: aspnetcore-virtualservice spec: hosts: - "*" gateways: - aspnetcore-gateway http: - fault: delay: # 지연 fixedDelay: 5s # 5초 percentage: value: 100 # 100프로의 확률로 route: - destination: host: aspnetcore-service subset: v1 # v1에 대해$ kubectl apply -f aspnetcore-virtualservice-fault-delay.yamlIstio 모니터링 하기Prometheus (로그 메트릭 수집)# 설치 $ kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.8/samples/addons/prometheus.yaml # 설치 확인 $ kubectl get svc prometheus -n istio-system # 확인을 위한 포트 포워딩 $ kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=prometheus -o jsonpath='{.items[0].metadata.name}') 8080:9090Grafana (모니터링)# 설치 $ kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.8/samples/addons/grafana.yaml # 설치 확인 kubectl get svc grafana -n istio-system # 확인을 위한 포트 포워딩 kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=grafana -o jsonpath='{.items[0].metadata.name}') 8080:3000Kiali (모니터링)# 설치 $ kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.11/samples/addons/kiali.yaml # 설치 확인 kubectl get svc grafana -n istio-system # 확인을 위한 포트 포워딩 kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=kiali -o jsonpath='{.items[0].metadata.name}') 8080:20001 출처 https://istio.io/latest/docs/ops/deployment/architecture/