[GCP]GKE 차근 차근 알아보기 7탄 — Istio 로 하는 Service Mesh

이정운 (Jungwoon Lee)
18 min readApr 6, 2019

--

안녕하세요 이정운 입니다.

지난 시간에는 GKE 관점에서 Cloud IAM 을 살펴보고 GKE 환경안의 Kubernetes 관점에서 RBAC 도 조금 살펴보는 시간을 가져 봤습니다. 또한, 짧게 Cloud IAM 과 RBAC 의 조합에 대해서도 살펴보는 시간을 가졌으며 이를 통해서 GKE 환경의 권한 관리라던가 접근제어에 대한 방안에 대해서 조금은 알 수 있는 시간이 되지 않았을까 기대해 봅니다.

지금까지 진행된 6개의 이야기를 통해서 기본적인 Kubernetes 와 GKE 에 대해서는 일차적으로 필요한 부분은 얼추 살펴본듯 하니 이번에는 GKE 환경에서 한발 더 나아가 요즘들어 사람들이 많이 이야기하는 Service Mesh 인 Istio 를 살펴보는 시간을 가져보는 것은 어떨까 합니다. Service Mesh 라는 용어는 요즘 여러 군데에서 사용되는데 여기서 다루고자 하는 것은 애플리케이션 또는 마이크로서비스 네트워크, 그리고 이러한 요소 간의 관계와 상호 작용의 연결을 이루는 네트워크를 의미하며 대규모로 분산되는 Microservices Architecture 에서 어떻게 효과적으로 서비스와 네트워크를 관리할 것인가에 대한 방안입니다.

그러면 조금 더 자세하게 왜 Servie Mesh 를 갑자기 이야기하며 이러한 Service Mesh 는 무엇에 필요한 것일까요?

이런 부분의 답변을 가장 잘 표현한 것이 제 생각에는 Redhat 에서 이야기하는 하단의 그림과 설명이 아닐까 하는데요.

http://www.itworld.co.kr/news/109449

“마이크로서비스의 가장 어려운 부분 : 서비스 호출”은 중요한 점을 지적한다. API를 호출할 때 개발자는 A-B 직접 통합(아래 그림 1)을 다룬다고 생각할 수 있다. 그러나 컴퓨터 네트워크는 직접 통신에 최적화되도록 설계되지 않았으며(그림 2), 특히 클라우드 환경을 고려 또는 사용 중인 경우 통제 범위를 벗어난 많은 실제 및 가상 네트워크 디바이스를 필연적으로 다루게 된다. 예를 들어 이런 디바이스 중 하나의 성능이 저하되는 경우 전체 애플리케이션 응답 시간이 영향을 받는다(그림 3)”

이러한 환경에서 클라우드에서 탄력적인 서비스를 제공하기 위해서는 애플리케이션이 환경의 이상 현상으로부터 스스로를 보호하기 위한 방안이 필요하며 이때 언급되는 것이 Service Mesh 입니다. 그리고 이러한 Service Mesh 를 구축하는 여러가지 방법이 있겠지만 요즘에 가장 유명하고 어느덧 대세로 자리잡고 있는 것이 바로 Istio 이며 그래서 이번 이야기에서는 Istio 를 통해서 Service Mesh 가 무엇인지 확인해보는 시간을 가져보고자 합니다. 또한, Istio 를 GKE 환경에 설치 및 간단하게 테스트를 수행해보면서 말이 아니라 직접 만져볼 수 있는 시간을 가져보도록 하겠습니다.

늘 그렇지만 본 이야기는 하단과 같이 좋은 이야기를 기반으로 참고해서 작성되었습니다.

Installing Istio on GKE
https://cloud.google.com/istio/docs/istio-on-gke/installing

Install Istio on the Google Kubernetes Engine
https://istio.io/docs/setup/kubernetes/install/platform/gke/

Bookinfo Application
https://istio.io/docs/examples/bookinfo/

Istio step-by-step Part 03 — Deploying an application with Istio in Kubernetes
https://medium.com/devopslinks/istio-step-by-step-part-03-deploying-an-application-with-istio-in-kubernetes-d2b1de64fb6b

Istio Service Mesh, the Step-by-Step Guide, Part 2: Tutorial
https://dzone.com/articles/istio-service-mesh-the-step-by-step-guide-part-2-t

Introduction to Service Management with Istio Service Mesh (Cloud Next ‘18)
https://www.youtube.com/watch?v=wCJrdKdD6UM

Best Practices from Google SRE: How You Can Use Them with GKE + Istio (Cloud Next ‘18)
https://www.youtube.com/watch?v=XPtoEjqJexs

#1) Istio 란?

Service Mesh 는 굉장히 큰 개념이기 때문에 이를 설명하기 보다는 서두에 말씀드린 것처럼 이를 제공하는 프레임워크인 Istio 를 살펴보고 하나씩 테스트해보는 것이 좋지 않을까 합니다.

https://istio

Istio 에 대해서 좀 더 들어가보면 Istio 는 Google, IBM, Redhat, Lyft, VMware 와 같이 다수의 대형업체들이 참여하여 Service Mesh 의 개념을 쉽게 구현할 수 있는 일종의 프레임워크(?) 형태로 제공하는 오픈소스입니다. 그리고 이를 통해서 대규모 마이크로서비스 환경이라고 하여도 서비스를 연결, 보안, 제어 및 관찰 할 수 있는 방안을 쉽게 제공할 수 있도록 지원하고 있습니다.

아주 쉽게 요약해서 설명한 내용이라 이해가 잘 안된다면 Google cloud 공식 페이지에 나와있는 내용을 가지고 조금더 보충 설명을 드리도록 하겠습니다.

https://cloud.google.com/istio/

Istio는 마이크로 서비스 간 통신의 인증, 승인, 암호화를 확장 가능한 방식으로 제공 및 관리할 수 있습니다. 특히, Istio 가 기본적으로 기반 보안 통신 채널을 제공하므로 이를통해 개발자는 애플리케이션 수준 보안에 집중할 수 있습니다. 다시말해 별도의 보안에 대한 고민 없이도 Istio 가 안전한 보안 커뮤니케이션을 지원할 수 있습니다.

Istio 는 기본적으로 추적, 모니터링, 로깅을 제공 가능하며 이를통해 Service Mesh 배포에 대한 심층적인 정보를 제공하여 서비스의 성능과 다른 프로세스에 미치는 성능의 영향을 확인하고 문제를 빠르고 효과적으로 감지 및 분류할 수 있도록 지원할 수 있습니다.

마지막으로 Istio 는 트래픽 관리 기능을 제공하여 이를 통해 서비스 간의 API 호출 및 트래픽 흐름을 제어하고 트래픽에 대한 가시성을 향상시켜 문제가 발생하기 전에 포착할 수 있으며 악조건 속에서도 호출을 보다 안정적으로 하고 네트워크를 강화할 수 있습니다.

이렇듯 Istio 를 활용하게 되면 대단위의 마이크로서비스 환경에서 꼭 필요한 서비스 연결, 보안, 제어 및 관찰 기능을 프레임워크 단에서 제공하므로 개발자는 좀더 비즈니스 로직에 집중할 수 있도록 지원할 수 있습니다.

#2) Istio 테스트 해보기

기본적인 개념은 이전 파트에서 간단하게 설명드렸고 하단과 같이 Istio 공식 사이트에서도 아주 정리가 잘되어 있으므로 참고하시기를 추천드립니다.

https://istio.io/docs/concepts/what-is-istio/

특히, 하단의 아키텍처를 보시면 Istio 의 가장 큰 차별점 or 장점이 드러나는데 관리에 필요한 Control plain 부분을 제외하고 실제 서비스를 보면 Sidecar 패턴 형태로 실제 서비스와 proxy(Envoy) 가 병렬로 공존하도록 되어있어서 실제 서비스 호출에서는 직접 서비스를 호출하는 것이 아니라 proxy 를 통해서 호출하도록 되어 있습니다. 이렇게 proxy 를 거쳐 가므로 개발자가 별도의 작업을 하지 않아도 전체적으로 대규모 시스템을 잘 운영하기 위해서 필요한 로깅, 모니터링 정보 뿐만 아니라 보안, 트래픽 제어와 같은 다양한 이점을 누릴 수 있습니다.

Kubernetes 환경에서는 pod 안의 각각의 container 형태로 배치하여 쉽게 sidecar 패턴 구현 및 Istio 를 활용할 수 있습니다. 그럼 이전에 말한 것처럼 설명만 하지않고 간단하게 샘플애플리케이션을 통해서 직접 테스트해보고 이를 살펴보는 시간을 가지도록 하겠습니다.

먼저 설치부터 해야하는데 GKE 의 가장 큰 특징중의 하나는 Istio 를 설치하기 위해 별도로 작업할 필요없이 하단과 같이 설정중에 Add-ons 로 바로 Istio 설치를 추가할 수 있습니다. 이미 설치된 GKE cluster 라고 해도 edit 를 클릭하여 설정을 변경(enable) 가능합니다.

그럼 이미 만들어진 GKE cluster 가 있다고 가정하고 Edit 를 클릭하여 Add-on 에서 Istio 를 enable 하고 맨 하단의 Save 를 클릭합니다. 이때 Istio mTLS 는 각 서비스간의 연결을 무조건 mTLS 를 사용할 것인지 아닌지에 대한 설정이므로 우선은 Permissive 로 설정하시면 됩니다.

이렇게 설정만 변경하면 추가적인 작업 없이도 GKE cluster 에 istio 설치를 완료하실 수 있습니다. 설치가 잘 되었는지 확인하기 위해서 istio-system 이라는 namespace 에 정상적으로 Istio 서비스들이 설치되었는지 확인해 봅니다.

kubectl get service -n istio-system
kubectl get pods -n istio-system -o wide

상단에 보시는 것처럼 Istio 가 정상적으로 설치되었다면 이전에 봤던 아키텍처의 Istio 의 control plain 에 있던 Pilot, Mixer, Galley, Citadel, Gateway등의 컴포넌트가 pod 형태로 설치된 것을 확인할 수 있습니다. Istio 가 정상적으로 추가 되었으면 이제 간단하게 샘플 애플리케이션을 설치 및 구동해보도록 하겠습니다. 샘플은 Istio 공식 샘플인 Bookinfo 를 사용하도록 하겠습니다. Bookinfo 는 기본적으로 MSA 구조를 가지고 있으며 이에대한 아키텍처 구조 설명은 하단의 링크에 자세하게 나와있습니다.

https://istio.io/docs/examples/bookinfo/

그리고 Bookinfo 의 실제 소스는 하단의 github 에서 받을 수 있습니다.

https://github.com/istio/istio/tree/master/samples/bookinfo

그럼 먼저 이전에 작업해두었던 것과 이번 테스트 구분을 위해서 새로운 namespace 를 하나 만들고 istio-injection 설정을 추가 합니다. 해당 설정을 enabled 로 하면 별도의 추가 명령 없이도 해당 namespace 로 배포되는 모든 deployments 에는 자동으로 Istio 를 위한 proxy 컨테이너가 추가됩니다.

kubectl create namespace istio
kubectl label namespace istio istio-injection=enabled

그러면 github 에서 소스를 다운로드 받은 후에 실제 kubernetes 서비스를 배포합니다. 여기서 서비스를 배포한다는 의미는 deployment 와 service 를 의미합니다.

kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml -n istio

해당 bookinfo.yaml 파일을 일일이 설명드리기는 어렵지만 지금까지 여러 이야기에서 다루었던 일반적인 형태의 kubernetes 의 deployment 와 service 를 위한 yaml 파일 입니다. 일부 부분만 발췌해 보면, productpage 라는 deployment 를 생성하고 service 를 연결하는데 해당 서비스는 기본 ClusterIP 타입으로 생성해서 cluster 범위 에서만 접근가능하며 외부에서는 접근 불가하도록 설정되어있습니다.

--
apiVersion: v1
kind: Service
metadata:
name: productpage
labels:
app: productpage
service: productpage
spec:
ports:
- port: 9080
name: http
selector:
app: productpage
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: productpage-v1
labels:
app: productpage
version: v1
spec:
replicas: 1
template:
metadata:
labels:
app: productpage
version: v1
spec:
containers:
- name: productpage
image: istio/examples-bookinfo-productpage-v1:1.10.1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 9080

이렇게 이전과 동일하게 서비스를 배포했지만 Istio 설정이 추가되었기 때문에 실제 눈에 보이는 것과 다르게 내부 배포 결과는 좀 달라집니다. 이를 좀 더 자세히 말씀드리면 관리콘솔 > GKE > cluster 이름 > Workloads > pod 이름 > 관리되는 pod 이름 메뉴로 들어가 보면 배포된 deployment 모두에는 하단과 같이 pod 안에 isito-proxy 라는 컨테이너가 추가되어있는 것을 확인할 수 있습니다.

이 부분이 아까 말씀드린 sidecar 패턴의 proxy 공존이라는 의미이며 istio 의 경우에는 서비스의 호출시 proxy 를 통해서 이루어진다고 했는데 istio-proxy 가 그때 사용되는 proxy 의 실체입니다. (참고로, Istio 는 proxy 로 Envoy 를 사용)

Kubernetes 를 위한 서비스를 모두 배포했으면 이제 실제 서비스를 수행하기 위해서 Istio 에서 필요한 Gateway 와 VirtualService 를 배포해야 합니다. 이에 대해서 조금 더 보충 설명을 하자면 Istio 는 보안을 위해서 기본적으로 인입 서비스는 Ingress gateway 를 통해서만 들어오는 구조로 구성되어 있다고 보시면 됩니다. 실제 서비스를 수행하기 위해서는 Ingress gateway -> VirtualService 라는 구조를 가지고 있어야 하며 VirtualService 는 실제로 kubernetes 의 service 를 목적지로 지정합니다. 따라서, 좀 더 실제적으로 그림을 그려보면 Ingress gateway -> VirtualService -> k8s Service 가 될 수 있을듯 합니다. 그리고 만약 반대로 kubernetes cluster 외부로 호출이 필요한 경우에는 선택적이긴 하지만 Egress gateway 를 선언하고 이를 통해 외부 서비스를 수행할 수 있습니다. 결국은 보시면 아시겠지만 전체 서비스의 흐름이 proxy 를 거치는 것으로 이해하시면 좋을듯 합니다. 하단의 첨부 그림을 참고하시면 이해에 도움이 될듯 합니다.

https://blog.aquasec.com/istio-service-mesh-traffic-control

그럼 다시 테스트로 돌아와서 하단과 같은 명령어를 통해서 만들어진 Istio 설정에 대한 배포를 수행합니다.

kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml -n istio
kubectl get gateway -n istio
kubectl get virtualservice -n istio

이해에 도움이 되기 위하여 bookinfo-gateway.yaml 를 조금 더 분석해보면 상단에는 Istio 서비스를 위하여 bookinfo-gateway 라는 gateway 를 생성하는데 istio 설치시에 기본적으로 설치되는 default controller 를 사용(istio-ingressgateway) 하여 생성하도록 되어있으며 기본 http 프로토콜로 80 포트를 사용하는 설정입니다. 그리고 하단에는 booinfo 라는 bookinfo-gateway 와 연결되어 있으며 ‘/productpage’ 라는 요청이 들어오면 productpage service 에게 9080 포트로 전달하는 VirtualService 를 생성하는 구문으로 구성되어 있습니다.

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: bookinfo-gateway
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: bookinfo
spec:
hosts:
- "*"
gateways:
- bookinfo-gateway
http:
- match:
- uri:
exact: /productpage
- uri:
exact: /login
- uri:
exact: /logout
- uri:
prefix: /api/v1/products
route:
- destination:
host: productpage
port:
number: 9080

이제 Kuberenetes 를 위한 서비스인 deployment, service 와 Istio 를 위한 gateway, virtualservice 에 대한 배포가 끝났으니 실제 테스트를 해보도록 하겠습니다. 서비스를 위해 생성된 gateway 가 ingressgateway 를 사용하도록 되어 있으니 하단과 같은 명령어로 이를 확인하여 서비스 가능 IP 를 확인합니다.

kubectl get svc istio-ingressgateway -n istio-system

IP 확인이 되었으면 이제 브라우저를 통해서 실제 서비스 호출을 수행하여 정상적으로 bookinfo 페이지가 나오는 것을 확인합니다. (현재는 기본설정으로 여러 버전의 review 를 번갈아가면서 호출하도록 되어있어 refresh 버튼을 클릭하면 해당 부분이 변경 되는 것을 확인 가능합니다.)

http://34.85.111.253/productpage

여기까지 잘 수행하셨다면 아주 기본적으로 Servce Mesh 를 지원하기 위한 Istio 를 GKE 에 설치해서 가장 기본적인 샘플 애플리케이션을 배포 및 수행하신 것 입니다. 비록 간단한 이야기이긴 하지만 이해하는데는 시간이 좀 걸리므로 이번 이야기는 여기서 마무리하고 다음에 좀 더 자세한 이야기를 추가로 다루도록 하겠습니다. 그럼 이만 휘리릭~~~~

* Disclaimer: 본 글의 작성자는 Google 직원이지만 Google cloud 를 공부하는 한 개인으로서 작성된 글입니다. 본 글의 내용, 입장은 Google 을 대변하지 않으며 Google 이 해당 콘텐츠를 보장하지 않습니다.

--

--

이정운 (Jungwoon Lee)

Technical engineer who dreams better future. (These thoughts are my own personal opinions, and do not reflect or represent Google’s opinions or plans.)