티스토리 뷰

이제는 이 썸네일이 적절할지 잘 모르겠네요

 

현재 하고 있는게 간단한 샘플 코드로 EKS를 구축하는 과정이라 이스티오(Istio)에 대해 다루는게 맞는지 잘 모르겠다.

 

그래도 서비스 메시(Service Mesh) 개념 정리도 할 겸 짚고 넘어가보려고 한다.

 

서비스 메시(Service Mesh)란?

서비스 메시는 애플리케이션의 서비스 간 모든 통신을 처리하는 소프트웨어 계층입니다. 이 계층은 컨테이너화된 마이크로서비스로 구성됩니다. 애플리케이션이 확장되고 마이크로서비스의 수가 증가함에 따라 서비스의 성능을 모니터링하기가 점점 어려워지고 있습니다. 서비스 메시는 서비스 간 연결을 관리하기 위해 모니터링, 로깅, 추적, 트래픽 제어와 같은 새로운 기능을 제공합니다. 이러한 기능은 각 서비스의 코드와 독립적이므로 네트워크 경계를 넘어 여러 서비스 관리 시스템에서 작동할 수 있습니다.
https://aws.amazon.com/ko/what-is/service-mesh/

 

서비스 메시를 사용하면, 서비스에 별도의 프록시를 둬서 연결 간 모니터링 기능과 보안 기능 등을 제공할 수 있게 된다.

 

마이크로서비스의 규모가 커지면, 아래와 같은 그림으로 연결이 표현 가능해진다.

 

서비스 메시를 구축하는게 무조건 장점만 있지 않다.

 

일단 구조가 복잡해지고, 오버헤드를 발생시키는 경우도 있으며 운영 팀의 러닝 커브도 문제가 된다.

 

그래서 굳이 샘플코드엔 넣지 말까.... 라고 생각했지만, 아직 잘 모르는 부분이 있기도해서 정리해보고 넘어가려한다.

 

이스티오(Istio)란?

Istio는 기존 분산 애플리케이션에 투명하게 계층화되는 오픈 소스 서비스 메시입니다. Istio의 강력한 기능은 서비스를 보호하고, 연결하고, 모니터링하는 균일하고 효율적인 방법을 제공합니다. Istio는 서비스 코드 변경이 거의 또는 전혀 없이 로드 밸런싱, 서비스 간 인증 및 모니터링을 위한 경로입니다. 
https://istio.io/latest/about/service-mesh/#what-is-istio

 

요약하면, MSA의 분산 네트워크 환경(K8s)에서 어플리케이션들을 쉽게 연결/모니터링 할 수 있도록 지원하는 기술이다.

 

오픈소스임에도 트래픽 관리, 보안, 관찰가능성, 서비스회복력 등에서 많은 기능을 제공하고 있다.

 

작년 7월에 CNCF에서 졸업함

 

이스티오(Istio)의 구성 요소

 

이스티오의 구성요소는 크게 데이터 플레인과 컨트롤 플레인으로 나뉜다.

 

데이터 플레인 서비스 메시의 모든 서비스에 대한 모든 인바운드 및 아웃바운드 트래픽을 관장한다.

 

각 서비스 인스턴스에 사이드카 형태로 Envoy Proxy를 배포한다.

 

Envoy Proxy는 트래픽을 가로채고 제어하며, 보안 기능과 텔레메트리 데이터를 수집한다.

 

컨트롤 플레인은 데이터 플레인의 라우팅 규칙, 정책, 인증서 등을 배포하고 갱신한다.

 

컨트롤 플레인은 이스티오 1.5 버전부터 istiod로 통합 관리한다.

 

이전의 개별 컴포넌트(Pilot, Citadel, Galley)의 기능 관리했어서 설정이 복잡했는데, 이를 통합했다.

 

세부 기능들을 알아보면 다음과 같다.

 

- Pilot 기능: 트래픽 관리와 라우팅 정책을 설정하고, Envoy 프록시에 전달합니다.
- Citadel 기능: 서비스 간의 인증서 발급 및 관리, TLS 설정을 처리합니다.
- Galley 기능: 구성 검증 및 배포, 설정 관리를 수행합니다.

 

Terraform으로 Istio 구성하기

https://github.com/aws-ia/terraform-aws-eks-blueprints/blob/main/patterns/istio/main.tf

AWS Summit에서 blueprint를 기반으로 Terraform을 구성하는게 권장사항이라는 걸 알됐다.

 

앞으로는 이걸 적극적으로 활용할 예정이다.

 

그런데 현재는 내가 작업한대로 생성하고 추후에 수정하려고 한다.

 

1. 먼저 ALB 컨트롤러에  연결된 인그레스 매니페스트부터 수정해야 한다.

resource "kubernetes_manifest" "alb_ingress" {
  manifest = yamldecode(<<-YAML
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: alb-ingress
      namespace: istio-system
      annotations:
        alb.ingress.kubernetes.io/load-balancer-name: ${local.alb_name}
        alb.ingress.kubernetes.io/scheme: internet-facing
        alb.ingress.kubernetes.io/target-type: ip
        alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'
        alb.ingress.kubernetes.io/certificate-arn: ${local.acm_arns}
        alb.ingress.kubernetes.io/ssl-policy: ELBSecurityPolicy-TLS13-1-2-2021-06
        alb.ingress.kubernetes.io/ssl-redirect: '443'
        alb.ingress.kubernetes.io/healthcheck-protocol: HTTP
        alb.ingress.kubernetes.io/healthcheck-port: '15021'
        alb.ingress.kubernetes.io/healthcheck-path: '/healthz/ready'
        alb.ingress.kubernetes.io/tags: Team=Metashare,Stage=test
    spec:
      ingressClassName: alb
      rules:
        - host: "*.[your domain]"
          http: &istio
            paths:
              - path: /
                pathType: Prefix
                backend:
                  service:
                    name: ${var.istio_chart.gateway_name}
                    port:
                      number: 80
        - host: "[your domain]"
          http: *istio
  YAML
  )

  field_manager {
    force_conflicts = true
  }

  depends_on = [helm_release.aws_load_balancer_controller, helm_release.istio-ingress]
}

어노테이션에 istio에서 사용하는 옵션들이 많이 나오고, 서비스에는 별도의 게이트웨이를 연결해준다.

 

2. 헬름차트 배포

istio-base와 istiod, istio gateway를 위한 ingress를 정의한다.

 

이 코드를 참고해도 좋아보인다. : https://github.com/msfidelis/eks-with-istio/blob/main/helm_istio.tf

 

value 파일들은 아래에서 참고해서 작성해야 한다. 같은 경로의 helm_values 디렉토리에 저장하고 사용했다.

https://github.com/istio/istio/blob/master/manifests/charts/istiod-remote/values.yaml

https://github.com/istio/istio/blob/master/manifests/charts/gateway/values.yaml

variable "istio_chart_version" {
  type        = string
  description = "Istio chart version"
  default     = "1.18.1"
}

variable "istio_chart" {
  type        = map(string)
  description = "Istio chart"
  default = {
    base_name  = "istio-base"
    base_chart = "base"

    istiod_name  = "istiod"
    istiod_chart = "istiod"

    gateway_name  = "istio-ingress"
    gateway_chart = "gateway"

    namespace  = "istio-system"
    repository = "https://istio-release.storage.googleapis.com/charts"
    version    = "1.18.1"
  }
}

resource "helm_release" "istio-base" {
  namespace        = var.istio_chart.namespace
  create_namespace = true
  repository       = var.istio_chart.repository
  name    = var.istio_chart.base_name
  chart   = var.istio_chart.base_chart
  version = var.istio_chart_version
  depends_on = [helm_release.aws_load_balancer_controller]
}

resource "helm_release" "istiod" {
  namespace  = var.istio_chart.namespace
  repository = var.istio_chart.repository
  name    = var.istio_chart.istiod_name
  chart   = var.istio_chart.istiod_chart
  version = var.istio_chart_version
  values = [
    file("${path.module}/helm_values/istiod.yml")
  ]
  depends_on = [helm_release.istio-base]
}

resource "helm_release" "istio-ingress" {
  namespace  = var.istio_chart.namespace
  repository = var.istio_chart.repository
  name    = var.istio_chart.gateway_name
  chart   = var.istio_chart.gateway_chart
  version = var.istio_chart_version
  values = [
    file("${path.module}/helm_values/istio_gateway.yml")
  ]
  depends_on = [helm_release.istiod]
}

locals {
  istio_gateway_name = "${var.istio_chart.namespace}/gateway"
}

 

3. Gateway 배포

이스티오를 제대로 쓰려면 서비스들을 이스티오 게이트웨이와 연결시켜야 한다.

 

이때 서비스들은 VirtualService로 만들어야한다. 이번 포스팅에서는 별도의 연결은 하지 않을 예정

resource "kubernetes_manifest" "istio_gateway" {
  manifest = yamldecode(<<-YAML
      apiVersion: networking.istio.io/v1alpha3
      kind: Gateway
      metadata:
        name: gateway
        namespace: 'istio-system'
        labels:
          Team: Metashare
      spec:
        selector:
          app: 'istio-ingress'
        servers:
          - port:
              number: 80
              name: http
              protocol: HTTP
            hosts:
              - '*.[도메인 이름]'
              - [도메인 이름]
    YAML
  )

  field_manager {
    force_conflicts = true
  }
}

여기까지 진행하면 필요한 요소들은 다 구성된다.

 

잘 배포됐나 확인

> kubectl get gateway -n istio-system
NAME      AGE
gateway   8d
> kubectl get all -n istio-system    
NAME                                 READY   STATUS    RESTARTS   AGE
pod/istio-ingress-6ff5d5b79d-8tknw   1/1     Running   0          88m
pod/istio-ingress-6ff5d5b79d-k8wnb   1/1     Running   0          87m
pod/istiod-dfd7f45c5-278lm           1/1     Running   0          88m
pod/istiod-dfd7f45c5-jkfhk           1/1     Running   0          87m

 

마치며

이런 용두사미가 될까봐 다루지 않으려던 내용

 

제대로 사용하려면 VirtualService로 파드를 수십개 연동하고, Grafana에서  Visualization까지 해줘야한다.

 

정말 여러가지 기능을 제공하지만, 현재 서비스에서는 100% 활용 못하고 있다.

 

더 자세히 알아보고 싶으면 삼성 SDS의 개발 블로그를 추천한다. 정말 잘 정리해주셨음

https://www.samsungsds.com/kr/insights/service_mesh.html

https://www.samsungsds.com/kr/insights/service_mesh_istio.html

 

100% 알고 작성한 포스팅이 아니라 꾸준히 업데이트 될 예정

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/07   »
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 31
글 보관함