Kubeflow에 Istio가 왜 필요할까?

Kubeflow에 Istio가 왜 필요할까?

Istio가 Kubeflow에서 어떤 역할을 하는지 알아보자

Istio?

Istio addresses the challenges developers and operators face with a distributed or microservices architecture. Whether you’re building from scratch or migrating existing applications to cloud native, Istio can help.

Istio는 개발자와 운영자가 분산 또는 마이크로서비스 아키텍처에서 직면하는 문제를 해결합니다. 처음부터 구축하든 기존 애플리케이션을 클라우드 네이티브로 마이그레이션하든 Istio가 도움이 될 수 있습니다.

위에 글은 Istio(이스티오라고 읽는다고 합니다) 공식 홈페이지에서 제공하는 Istio에 대한 설명입니다. 이어서 설명을 하자면, Istio는 기존 분산 애플리케이션에 투명하게 계층화되는 오픈 소스 서비스 매쉬이며, Istio는 서비스를 보호, 연결 및 모니터링하는 균일하고 효율적인 방법을 제공하고, 서비스 코드 변경 거의 없이 로드 밸런싱, 서비스 간 인증 및 모니터링을 위한 path를 컨트롤하는 역할을 맡고 있습니다. 읽어봤지만 아직까지는 어떤 역할을 하는지 제대로 이해하기 어렵습니다. 왜냐하면 Istio는 서비스 매쉬의 개념인데, 이 개념을 잘 모르고 있기 때문입니다. 뭔가를 연결하고 중개하고 있는 것 같은데, 무엇을 연결하는지 또 이 연결에서 어떤 일을 하는지 잘 이해가 가지 않습니다. 서비스 매쉬에 대해서 살펴 본 다음 Istio로 다시 돌아와 보도록 하겠습니다.



Service Mesh

서비스 매쉬에 대해서 얘기 하기 전에 또 가정해야할 것이 있습니다. 서비스 매쉬는 모놀리식 서비스보다 Micro Service Architecture 구조에 더 잘 어울리는 아키텍쳐입니다. 마이크로 서비스는 기능을 서비스라는 단위로 잘게 나누다 보니 전체 시스템이 커질 수록 서비스가 많아지고, 그로 인해서 서비스 간의 연결이 복잡해지고 여러가지 문제가 발생하게 됩니다. 이러한 문제들을 해결하기 위해 서비스 매쉬가 등장하게 된 것이죠. 대표적으로 장애전파 현상 이 있고, 또 서비스가 커지면서 연결이 너무 복잡하다보니 기본적으로 전체 구조를 알기 어렵게 되어 장애가 나면 어디서 났는지 추적하기가 힘들어지게 됩니다.

소프트웨어적으로 해결하는 방법이 있겠지만, 이것을 인프라적으로 해결하기 위해 등장한 것이 서비스 매쉬라는 아키텍쳐 입니다. 서비스 A와 B가 있다고 해봅시다.

이 구조에서 서비스는 서로를 직접 호출해야 합니다. 이렇게 되면 너무 단순한 구조이기 때문에 트래픽을 조정한다던가 서비스로 들어오고 나가는 트래픽을 통제하기 어렵습니다. 만약 서비스 A에서 장애가 났다면 어떨까요? A에서 응답이 없는데도 조치를 취할 수 없기 때문에 장애는 B로까지 확산될 수 밖에 없습니다. 서킷 브레이커 같은 구조를 통해 트래픽을 끊어버리면 장애가 전파되지 않을 것입니다. 그래서 단순 서비스만 놓지 않고, 여기에 프록시를 붙여보겠습니다.

이렇게 서비스에 사이드카로 프록시를 붙이게 되면 프록시를 통해 구조적으로 서킷 브레이커를 사용할 수 있게 되며, 더 나아가 더 다양한 기능을 붙일 수 있게 됩니다.

이렇게 헤더를 통해서 Clinet를 구분해서 프록시를 타게 해서 더 최적화된 서비스를 구현할 수도 있습니다. 하지만 하나 더 생각해야 할 것은 우리는 MSA구조라는 가정 하에 시작을 했으니, 이런 서비스가 딱 하나 있는 것이 아니라 엄청나게 많이 존재한다는 것입니다. 위와 같은 서비스 구조가 100개 이상이 된다면 어떻게 될까요? 방금 살펴 본 프록시를 사용해서 여러 기능을 구성할 수는 있었지만 서비스 수에 따라 프록시 수도 Linear하게 증가하기 때문에, 이 프록시에 대한 설정이 까다로워 진다는 것입니다.

프록시에 대한 설정을 중앙 집중화해서 관리할 수 있다면 어떨까요? 설정 정보를 중앙 집중화된 컨트롤러가 통제한다면 프록시의 기능도 살리고 관리하기도 편해질 것 같습니다. 데이터 플레인과 컨트롤 플레인이 바로 중앙집중화된 컨트롤러에 해당합니다. 프록시를 관리하는 각 프록시들로 이루어져서 트래픽을 설정값에 따라 트래픽을 컨트롤 하는 부분을 데이터 플레인(Data Plane)이라고 하고, 데이타 플레인의 프록시 설정값들을 저장하고, 프록시들에 설정값을 전달하는 컨트롤러 역할을 하는 부분을 컨트롤 플레인(Control Plane) 이라고 합니다.

이것을 구현한 것이 서비스 매쉬(Service Mesh)인 것이고, 우리는 구현체 중 하나인 Istio를 살펴보고 있는 것입니다.

Istio가 적용된다면 그림은 다음과 같아질 것입니다.

After utilizing Istio



Envoy

사실 이 Istio는 Envoy Proxy를 활용해서 만들어진 것입니다. Data Plane의 메인 프록시로 Envoy proxy를 사용하기 때문입니다. Envoy는 Lyft사에서 만들어졌고 C++로 개발된 고성능 프록시 사이드카로 dynamic service discovery, load balancing, TLS termination, circuit breaker..등등의 기능을 포함합니다. Envoy가 만들어질 때 목표는 다음과 같았습니다.

“The network should be transparent to applications. When network and application problems do occur it should be easy to determine the source of the problem.”

네트워크는 애플리케이션에* 투명해야하며, 장애가 발생했을시 어디에서 문제가 발생했는지 쉽게 파악할 수 있어야 한다.

주요 기능은 다음과 같습니다.

  • HTTP, TCP, gRPC 프로토콜을 지원
  • TLS client certification 지원
  • HTTP L7 라우팅 지원을 통한 URL 기반 라우팅, 버퍼링, 서버간 부하 분산량 조절 등
  • HTTP2 지원Auto retry, circuit breaker, 부하량 제한등 다양한 로드밸런싱 기능 제공
  • 다양한 통계 추적 기능 제공 및 Zipkin 통합을 통한 MSA 서비스간의 분산 트렌젝션 성능 측정 제공함으로써 서비스에 대한 다양한 가시성 (visibility)을 제공
  • Dynamic configuration 지원을 통해서 중앙 레파지토리에 설정 정보를 동적으로 읽어와서 서버 재시작없이 라우팅 설정 변경이 가능함
  • MongoDB 및 AWS Dynamo 에 대한 L7 라우팅 기능 제공

이렇게 다양한 기능을 가진 Envoy는 배포 위치에 따라 지원하는 기능이 달라집니다. 요약하자면 다음 그림과 같습니다.

서비스 매쉬 관점에서 보자면 데이터 플레인은 이 Envoy를 서비스 옆에 사이드카로 배포해서 이를 통해 서비스로 들어오고 나가는 트래픽을 통제하는 것입니다.



Istio As a Service Mesh

Istio 1.5버전 이후로 Istiod로 컨트롤 플레인이 통합되었다

Istio로 구성된 Service Mesh를 살펴보면 다음과 같습니다. Proxy로 Envoy를 사용하고 있고 그 밑에 Istio로 구성된 다양한 컴포넌트들이 있습니다. 자세히 보니 Control Plane이라고 되어있네요. 앞 단에서 Envoy Proxy를 통해서 트래픽이 전달되면 뒤에서 Envoy로 구성된 데이터 플레인을 컨트롤해 줄 것이 필요해집니다. 이 역할을 해주는 것이 바로 Control Plane인데, Istio는 이 Control Plane에 해당하는 오픈 소스입니다. 그럼 이 Control Plane, Istio는 어떤 역할을 하는지, 어떤 기능이 있는지 알아보겠습니다.

Pilot

파일럿은 Envoy에 대한 설정을 관리해주는 역할을 합니다. 주요 기능으로는 서비스 디스커버리, 서비스들의 엔드포인트 주소를 얻을 수 있습니다. 트래픽의 경로를 컨트롤하고 싶다면 파일럿을 통해서 서비스에서 서비스로 호출하는 경로를 조정할 수 있습니다. 이외에도 재시도(retry), 장애 전파를 막기 위한 써킷 브레이커 (Circuit breaker), Timeout 등의 기능이 있습니다.

Mixer

믹서는 액세스 제어와 정책을 관리하며 각종 모니터링에 필요한 지표들을 수집합니다. 서비스의 총 처리량을 정책으로 지정하면 그 처리량 이상으로 요청을 못받게 하거나 특정 헤더값이 일치해야 요청을 받을 수 있게 할 수 있습니다.

Citadel

시타델은 “성(Castle)” 이라는 말로써, 단어 뜻에서 유추할 수 있듯, 보안과 관련이 되어 있습니다. 사용자 인증(Authentication)과 인가(Authorization)와 관련된 역할을 수행합니다. Istio의 모든 트래픽은 TLS를 통해서 암호화가 가능한데 이 암호화에 필요한 인증서를 관리합니다.

Istio 설정을 Validation, Ingestion, Processing, Distribution 하는 역할을 합니다. 즉, Istio의 구성 및 설정을 검증하고 배포 관리를 진행합니다.

1.5이전의 버전

Istio 1.4버전까지는 위에 4가지 요소로 나뉘어져 있었으나 그 이후에는 Istiod 라는 하나의 모듈로 통합되었습니다.

istiod는 Mixer 가 없어지고, Pilot 이 Mixer 의 기능까지도 함께 수행합니다.

Istiod

Istio 1.5 이상 버전에서 제공되며 서비스 디스커버리, 설정관리, 인증관리 등을 수행합니다.

  • 트래픽 동작을 제어하는 라우팅 규칙을 Envoy 전용 설정으로 변환하고 마이크로 서비스에 사이드카 방식으로 Envoy를 배포합니다.
  • Envoy 설정 변경을 통해 서비스 매쉬 트래픽을 제어합니다.
  • 내장된 Identity나 Credential Management(증명 관리)을 통해서 강력한 서비스 간 인증 및 사용자 인증 기능을 지원합니다.
  • 인증 기관의 역할을 수행하며, 데이터 플레인에서 안전한 mTLS 통신을 허용하는 인증서를 생성합니다.



Istio의 주요 기능

Istio의 주요 기능으로는 트래픽 통제와 서비스간 안정성 제공 (Resilience), 보안 그리고 모니터링입니다.

Istio는 트래픽 분할이 가능한데, 이를 통해 들어오는 트래픽의 양을 조절할 수 있습니다. 카날리 테스트 등 배포 테스트를 이를 통해 수행할 수 있게됩니다. 또한 위에서 잠깐 살펴봤듯이 컨텐츠 기반의 트래픽 분할이 가능해서, 예를 들어 헤더의 User-Agent값에 따라서 Android 유저면 안드로이드 쪽으로 라우팅하고, IOS유저면 Ios쪽으로 라우팅할 수 있습니다.

Istio의 파일럿을 통해서 헬스체크 및 서비스 디스커버리의 기능을 수행할 수 있습니다. 파일럿은 여러 대상 인스턴스에 대해서 로드밸런싱하고 이 서비스들에 대해 Health 상태를 주기적으로 점검하고 문제가 있다면 서비스에서 제거해버립니다.

Istio의 중요한 특징 중 하나는 기본적으로 envoy를 통해서 통신하는 모든 트래픽을 자동으로 TLS를 이용해서 암호화한다는 것입니다. 서비스 간 통신이 기본적으로 TLS로 암호화 되기 때문에 이후에 설명하겠지만, Kubeflow에 적용하기 위해서는 꼭 Https 설정을 해주어야 합니다.

Istio Security Architecture

위에서 인증서를 관리한다고 설명한 Citadel에서 인증서를 가져와서 이를 이용해 TLS통신을 하게 됩니다.

모니터링은 Mixer에서 담당하게 됩니다. 다음 그림에서와 같이 서비스에 Proxy가 있고 이것을 믹스로 보내게 됩니다.

서비스 A가 서비스 B를 호출할 때 호출 트래픽은 각각의 Proxy를 타게 됩니다. 호출을 하게되면 응답 시간과 서비스의 처리량과 같은 정보가 Mixer로 전달되고 전달된 각종 지표는 Mixer에 연결된 Logging Backend에 저장됩니다. 이렇게 저장된 로그들은 GCP의 Stackdriver, AWS, Prometheus, DataDog 등으로 플러그인을 통해 쉽게 전달이 가능합니다.



Kubeflow에서 Istio

Kubeflow를 설치해보고 조금이라도 사용해보면 알겠지만, 정말 다양한 ML을 위한 도구들이 모여져있습니다. 이런 도구와 프레임워크, 서비스의 모음은 각각 독립적으로 개발이 되어 있고 서로 조금씩 다른 부분들을 돕고 있습니다. 좀 더 완전하고 ML개발 환경을 만들고 싶다면 여러 서비스와 구성 요소들을 결합하는 것은 필수적입니다. Kubeflow는 이러한 구성요소들의 모음을 결합할 수 있는 기본 인프라를 제공하고 있고, Istio를 통해 마이크로서비스를 보호하고 연결하며, 모니터링합니다.

  • 강력한 ID 기반 인증 및 권한 부여를 사용하여 Kubeflow 배포에서 서비스 간 통신을 보호합니다.
  • 액세스 제어 및 할당량을 지원하기 위한 정책 레이어
  • 클러스터 ingress 및 egress를 포함하여 배포 내 트래픽에 대한 자동 메트릭, 로그 및 추적이 가능합니다.
Istio in Kubeflow

Kubeflow에서 Istio가 사용되는 모습은 위의 그림과 같습니다. 사용자가 각 컴포넌트에 접속하고 사용하기 위해 인증하고 역할을 제공하는데에 Istio가 사용되는 것이라고 보면 그림이 이해가 되실 것입니다. 이 방식은 다음과 같습니다.

  1. User Request는 IAM on Cloud Services Provider 또는 Active Directory/LDAP 온프레미스와 같은 SSO 서비스 공급자와 통신하는 식별 프록시에 의해 가로채어집니다.
  2. 사용자가 인증되면 User ID가 포함된 JWT 헤더 토큰을 포함하도록 요청이 Istio 게이트웨이에 의해 수정됩니다. 서비스 메쉬 전체의 모든 요청은 이 토큰을 전달합니다.
  3. Istio RBAC 정책은 서비스 및 요청된 네임스페이스에 대한 액세스를 검증하기 위해 수신 요청에 적용됩니다. 사용자가 둘 중 하나에 액세스할 수 없으면 오류 응답이 다시 전송됩니다.
  4. 요청이 확인되면 해당 컨트롤러(이 경우 Notebook 컨트롤러)로 전달됩니다.
  5. 노트북 컨트롤러는 Kubernetes RBAC로 권한 부여를 검증하고 사용자가 요청한 네임스페이스에 Notebook Pod를 생성합니다.

네임스페이스에서 Training 작업 또는 기타 리소스를 생성하기 위해 노트북을 사용하는 사용자의 추가 작업은 유사한 프로세스를 거칩니다. 프로필 컨트롤러는 프로필 생성을 관리하고 적절한 Istio 정책을 생성 및 적용합니다.

현재 Istio 없이 Kubeflow를 배포할 수 없습니다. Kubeflow는 게이트웨이에서 생성된 노트북에 액세스하기 위한 새 경로를 표현하기 위해 Istio용 사용자 지정 리소스 정의(CRD)가 필요합니다.



Https

Istio를 사용하기 때문에 기본적으로 Kubeflow를 https설정이 되어있지 않다면, 기능을 제대로 수행할 수 없습니다. 인증서 없이 http로 접근한다면, 각 컴포넌트를 이용하는데 에러가 뜨거나 제약이 발생합니다. 그래서 Kubernetes를 사용한다면 Ingress 설정시에 Https 설정을 위한 Annotation을 꼭 설정해주어야 하고 Kubeflow 도메인에 대한 인증서를 미리 발급해놓아야 합니다. 인증서에 대한 내용은 온프레미스나 클라우드 Provider에 따라 다르니 생략하고, AWS EKS 기준 Annotation에 대한 설정 정보를 남겨놓겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# Annotation Reference:
# https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.4/guide/ingress/annotations/
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-kubeflow-central-dashboard
namespace: istio-system # this ingress should be in the same namespace as 'istio-ingressgateway' service
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/load-balancer-name: kubeflow-central-dashboard-lab
alb.ingress.kubernetes.io/scheme: internal # internal load balancer
alb.ingress.kubernetes.io/target-type: ip # connect to pod directly
alb.ingress.kubernetes.io/subnets: {} # subnets of EKS
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80, "HTTPS": 443}]' # listener for alb
alb.ingress.kubernetes.io/ssl-redirect: '443' # enables SSLRedirect and specifies the SSL port that redirects to
alb.ingress.kubernetes.io/healthcheck-path: /healthz/ready # health check path of istio-ingressgateway
alb.ingress.kubernetes.io/healthcheck-port: '15021' # health check port of istio-ingressgateway
spec:
rules:
- host: kubeflow.hyubyworld.co.kr
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: istio-ingressgateway
port:
number: 80

Reference

Kubeflow에 Istio가 왜 필요할까?

http://tkdguq05.github.io/2022/10/02/kubeflow-istio/

Author

SangHyub Lee, Jose

Posted on

2022-10-02

Updated on

2024-02-02

Licensed under

Comments