본문 바로가기

AWS

[Istio] EKS 환경에서 Istio로 여러개의 ALB, NLB 모두 사용하기

반응형

1. 개요

현업에서 외부 트래픽 인입을 받아내기 위해 Istio를 사용중인데, default 설정을 사용하면 CLB가 설치된다.

 

EKS로 쿠버네티스를 운영중인 환경에서 Istio로 ALB, NLB를 각 환경에 맞게 사용하고 싶을 경우에 어떻게 해야 할까?

 

## 전제 조건 ##

 

- AWS Load Balancer Controller 설치

 

AWS Load Balancer Controller는 Kubernetes에서 YAML 파일을 배포하는 것 만으로 AWS Load Balancer Controller 파드가 이를 감지하여 AWS API를 사용하여 요청한 대로 Load Balancer를 설치 및 구성해주는 오픈소스이다.

 

해당 AWS Load Balancer Controller가 설치되어 있지 않다면 내장 설치된 Controller를 통해 LB를 설치해야 하는데 지원되는 부분도 많지 않고 ALB를 설치할 수 없다. 따라서 필수적으로 설치해주어야 한다.

 

2. 설정 방법

 

1. AWS Load Balancer Controller가 설치되어 있는지 확인

- 설치되어 있지 않다면 따로 설치해주어야 한다.

 

2. Istio 설치 준비

- Istio는 오픈소스이기 때문에 버전에 따라 굉장히 민감하게 동작될 수 있으므로 버전을 고정하여 구성하는 것을 권장한다.

 

- 필자가 설치할 버전은 1.12.1이다.

- Helm Charts 또한 버전을 동일하게 가져가기 위해 1.12.1을 지정해준다.

- istioctl 명령어 또한 버전을 동일하게 가져가기 위해 1.12.1 버전의 CLI를 다운로드 받아준다.

(istioctl 명령어는 용량이 많이 나가기 때문에 .gitignore에 추가해줘야 한다.)

 

./bin/istioctl version
client version: 1.12.1
control plane version: 1.12.1
data plane version: 1.12.1 (7 proxies)

 

3. Operator로 Istio 설치

bin : istioctl이 들어있는 폴더

ingress : ALB를 구성하기 위한 Ingress yaml 파일 폴더

manifests : Helm charts가 구성되어 있는 폴더

 

istio-operator.yaml

 

여기서 중요한 부분은 다음과 같다.

 

[1] label -> istio: ingressgateway / istio: ingressgateway-alb / istio: ingressgateway-ext-alb

 

Istio를 설치하고 가장 중요한 Traffic 인입을 정의할 때 Istio Gateway, Virtual Service에서 어떤 Istio pod로 인입되는 트래픽에 대해 트래픽을 처리할 것인지 설정하게 된다.

 

무슨 말인지 잘 이해가 안 될 수 있어 살짝 풀어서 정리해봄

AWS LB (ALB는 Ingress(규칙 명세서)에 의해 생성됨) -> Istio Service -> Istio Pod

여기서 Isito Pod의 Label에 따라서 어떤 Istio Gateway에 정의된 Rule / Setting 값을 따를 것인지 정하게 된다.

 

[참고용 : Istio Gateway 설정]

 

추후 Istio Gateway를 설정할 때 istio Label 설정하는 부분에 위의 istio 레이블을 각각 고려하여 선택해주면 된다.

[2] ALB를 위한 Istio pod & service를 구성하는 부분인데 사용되지 않는 NodePort를 하나 선택한 뒤 status-port와 healthcheck-port를 같은 값으로 지정해주면 된다.

 

[3] NLB를 생성하는 Annotation에서 aws-load-balancer-type을 "external"로 지정해주어야 내장 LB Controller가 이를 감지하는게 아니라 외부 Controller, 즉 AWS Load Balancer Controller가 이를 감지하여 NLB를 생성하게 된다.

 

apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
  namespace: istio-system
  name: istiocontrolplane
spec:
  profile: default
  components:
    egressGateways:
      - name: istio-egressgateway
        enabled: false
    ingressGateways:
      # NLB
      - name: istio-ingressgateway
        enabled: true
        label:
          istio: ingressgateway
        k8s:
          resources:
            requests:
              cpu: 100m
              memory: 128Mi
            limits:
              cpu: 2000m
              memory: 1024Mi
          hpaSpec:
            minReplicas: 1
          service:
            externalTrafficPolicy: Cluster
            type: LoadBalancer
            ports:
              # Status Port
              - port: 15021
                targetPort: 15021
                name: status-port
                protocol: TCP
              # HTTP Port
              - port: 80
                targetPort: 8080
                name: http2
                protocol: TCP
              # HTTPS Port
              - port: 443
                targetPort: 8443
                name: https
                protocol: TCP
          serviceAnnotations:  # NLB
            service.beta.kubernetes.io/aws-load-balancer-name: istio-ingress-nlb
            service.beta.kubernetes.io/aws-load-balancer-type: "external"
            service.beta.kubernetes.io/aws-load-balancer-internal: "true"
            service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: "ip"
            service.beta.kubernetes.io/load-balancer-source-ranges: "XXXXXXX, XXXXXXXXX"
            service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "443"
            service.beta.kubernetes.io/aws-load-balancer-ssl-negotiation-policy: ELBSecurityPolicy-2016-08
            service.beta.kubernetes.io/aws-load-balancer-ssl-cert: XXXXXXXXXXXXXXXXXXXXXXXXXXXX
            service.beta.kubernetes.io/aws-load-balancer-healthcheck-path: /healthz/ready
            service.beta.kubernetes.io/aws-load-balancer-healthcheck-port: "15021"
            service.beta.kubernetes.io/aws-load-balancer-attributes: load_balancing.cross_zone.enabled=true


      # ALB
      - name: istio-ingressgateway-alb
        enabled: true
        label:
          istio: ingressgateway-alb
        k8s:
          resources:
            requests:
              cpu: 100m
              memory: 128Mi
            limits:
              cpu: 2000m
              memory: 1024Mi
          hpaSpec:
            minReplicas: 1
            maxReplicas: 2
          serviceAnnotations:  # Health check 관련 정보
            alb.ingress.kubernetes.io/healthcheck-path: /healthz/ready
            alb.ingress.kubernetes.io/healthcheck-port: "30621" # Status Port에서 지정한 nodePort 지정
          service:
            type: NodePort # ingress gateway 의 NodePort 사용
            ports:
              - name: status-port
                protocol: TCP
                port: 15021
                targetPort: 15021
                nodePort: 30621
              - name: http2
                protocol: TCP
                port: 80
                targetPort: 8080
              - name: https
                protocol: TCP
                port: 443
                targetPort: 8443

      # ALB
      - name: istio-ingressgateway-ext-alb
        enabled: true
        label:
          istio: ingressgateway-ext-alb
        k8s:
          resources:
            requests:
              cpu: 100m
              memory: 128Mi
            limits:
              cpu: 2000m
              memory: 1024Mi
          hpaSpec:
            minReplicas: 1
            maxReplicas: 2
          serviceAnnotations:  # Health check 관련 정보
            alb.ingress.kubernetes.io/healthcheck-path: /healthz/ready
            alb.ingress.kubernetes.io/healthcheck-port: "30622" # Status Port에서 지정한 nodePort 지정
          service:
            type: NodePort # ingress gateway 의 NodePort 사용
            ports:
              - name: status-port
                protocol: TCP
                port: 15021
                targetPort: 15021
                nodePort: 30622
              - name: http2
                protocol: TCP
                port: 80
                targetPort: 8080
              - name: https
                protocol: TCP
                port: 443
                targetPort: 8443

 

이후에 다음의 명령어로 설치를 수행하면 된다. dry-run 또한 옵션으로 가능하다.

./bin/istioctl install --manifests ./manifests -f istio-operator.yaml

 

4. Ingress로 ALB 설치

 

이제 Ingress 리소스를 배포하여 ALB를 생성해주면 된다.

 

주의할 점으로 service의 name에 위에 Operator로 생성한 Istio Service의 이름과 Port를 정확히 매핑해주어야 한다.

그래야 해당 ALB로 인입되는 트래픽이 ALB를 위해 생성된 Istio Pod로 트래픽이 라우팅이 될 것이다.

 

ALB는 Ingress 까지 생성해야 배포가 되고, NLB는 Istio Operator를 배포하면 생성이 된다.

 

NLB는 타겟 타입을 IP로 했기 때문에 정확히 Istio Pod의 IP로만 NLB 타겟 그룹의 트래픽이 라우팅된다. (AWS VPC CNI이기 때문)

 

ALB는 NodePort로 설정했기 때문에 모든 Node의 nodePort로 트래픽이 라우팅되어, 라우팅 된 이후 iptables에 의해 내부적으로 실제 Istio Pod로 라우팅이 된다.

 

[NLB]

 

[ALB]

 

 

 

반응형