본문 바로가기

Cloud-native/Istio

[Istio]Configuring istio-ingressgateway with AWS ALB

개요

이 설정은 AWS EKS(Elastic Kubernetes Service)에서 Istio의 인그레스 게이트웨이를 AWS Application Load Balancer(ALB)와 함께 사용하는 방법을 설명합니다. 이를 통해 AWS WAF 같은 ALB 전용 서비스를 활용할 수 있습니다.

전제 조건

  • AWS LoadBalancer Controller가 클러스터에 설치되어 있어야 합니다.

설정 단계

1. Service Type 변경

기본적으로 Istio Ingress Gateway는 LoadBalancer 타입의 서비스로 설정되어 있어 Classic Load Balancer(CLB)가 자동으로 생성됩니다. ALB를 사용하기 위해 서비스 타입을 NodePort로 변경해야 합니다.

istio-gateway Helm 차트의 values.yaml 파일을 다음과 같이 수정합니다.

https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.4/how-it-works/#how-aws-load-balancer-controller-works

  service:
    # Type of service. Set to "None" to disable the service entirely
    # ALB: NodePort, CLB(default), NLB: LoadBalancer
    type: NodePort
    ports:
    - name: status-port
      port: 15021
      protocol: TCP
      targetPort: 15021
    - name: http2
      port: 80
      protocol: TCP
      targetPort: 80
    - name: https
      port: 443
      protocol: TCP
      targetPort: 443
    annotations: {}
      # NLB를 사용하는 경우 아래 annotation 사용
      # service.beta.kubernetes.io/aws-load-balancer-attributes: load_balancing.cross_zone.enabled=true
      # service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip
      # service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
      # service.beta.kubernetes.io/aws-load-balancer-type: external    
    loadBalancerIP: ""
    loadBalancerSourceRanges: []
    externalTrafficPolicy: ""
    externalIPs: []
    ipFamilyPolicy: ""
    ipFamilies: []
    ## Whether to automatically allocate NodePorts (only for LoadBalancers).
    # allocateLoadBalancerNodePorts: false

2. ALB Ingress 추가

Kubernetes Ingress 리소스를 생성하여 ALB를 구성합니다. AWS Load Balancer Controller는 이 Ingress 리소스를 기반으로 ALB를 생성합니다.

ingress.yaml 파일을 다음과 같이 작성합니다.

annotation 참고 https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.4/guide/ingress/annotations/

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: common-external-ingress
  namespace: istio-system
  annotations:
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/load-balancer-name: my-alb
    alb.ingress.kubernetes.io/target-type: instance
    alb.ingress.kubernetes.io/subnets: subnet-xxxx,subnet-yyyy,subnet-zzzz
    alb.ingress.kubernetes.io/scheme: internet-facing
  labels:
    app: common-external-ingress
spec:
  rules:
    - http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: istio-ingressgateway
                port:
                  number: 443

이 설정에서 주요 포인트는 다음과 같습니다.

  • alb.ingress.kubernetes.io/target-type: instance: ALB가 노드의 IP와 NodePort를 대상으로 트래픽을 라우팅합니다.
    • instance mode
      인그레스 트래픽은 ALB에서 시작하여 각 서비스의 NodePort를 통해 쿠버네티스 노드에 도달한다. 즉, 인그레스 리소스에서 참조된 서비스가 ALB에 도달하려면 type:NodePort로 노출되어야 합니다. ip mode 인그레스 트래픽은 ALB에서 시작하여 쿠버네티스 파드에 직접 도달합니다. CNI는 ENI의 보조 IP 주소를 통해 직접 액세스 가능한 파드 IP를 지원해야 합니다.
  • alb.ingress.kubernetes.io/scheme: internet-facing: 인터넷에서 접근 가능한 ALB를 생성합니다.

동작 방식

  1. 외부 트래픽이 ALB로 들어옵니다.
  2. ALB는 트래픽을 Kubernetes 노드의 NodePort로 전달합니다.
  3. 노드에서 트래픽은 istio-ingressgateway 서비스로 라우팅됩니다.
  4. istio-ingressgateway는 Istio의 라우팅 규칙에 따라 적절한 서비스로 트래픽을 전달합니다.

주의사항

  • Instance 모드를 사용할 경우, istio-ingressgateway 서비스는 반드시 NodePort 타입이어야 합니다.
  • IP 모드를 사용하려면, 사용 중인 CNI가 ENI의 보조 IP를 통해 파드 IP에 직접 접근할 수 있도록 지원해야 합니다.

결론

이 설정을 통해 Istio Ingress Gateway와 AWS ALB를 함께 사용할 수 있으며, 이를 통해 AWS WAF 등 ALB에 종속된 서비스들을 활용할 수 있습니다. 또한 ALB의 고급 라우팅 기능과 Istio의 강력한 트래픽 관리 기능을 결합하여 더욱 유연하고 안전한 인그레스 아키텍처를 구성할 수 있습니다.

[참고]Annotations options

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: common-external-ingress
  namespace: istio-system
  annotations:
    kubernetes.io/ingress.class: alb
    # ALB의 이름을 지정합니다. AWS 콘솔에서 이 이름으로 ALB를 식별할 수 있습니다.
    alb.ingress.kubernetes.io/load-balancer-name: my-production-alb
    
    # ALB가 트래픽을 라우팅할 대상 유형을 지정합니다. 'instance'는 노드의 IP와 NodePort를 사용합니다.
    alb.ingress.kubernetes.io/target-type: instance
    
    # ALB가 사용할 서브넷을 지정합니다. 고가용성을 위해 여러 가용 영역의 서브넷을 사용하는 것이 좋습니다.
    alb.ingress.kubernetes.io/subnets: subnet-xxxx,subnet-yyyy,subnet-zzzz
    
    # ALB의 접근 범위를 지정합니다. 'internet-facing'은 인터넷에서 접근 가능한 ALB를 생성합니다.
    alb.ingress.kubernetes.io/scheme: internet-facing
    
    # HTTPS 리스너를 구성합니다. 80(HTTP)과 443(HTTPS) 포트를 모두 열어둡니다.
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS": 443}]'
    
    # HTTP에서 HTTPS로의 리다이렉션을 설정합니다.
    alb.ingress.kubernetes.io/actions.ssl-redirect: '{"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}'
    
    # SSL 인증서의 ARN을 지정합니다. HTTPS를 사용하려면 필수입니다.
    alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:region:account-id:certificate/certificate-id
    
    # SSL 정책을 지정합니다. 최신 보안 정책 사용을 권장합니다.
    alb.ingress.kubernetes.io/ssl-policy: ELBSecurityPolicy-TLS-1-2-Ext-2018-06
    
    # 헬스 체크 설정
    alb.ingress.kubernetes.io/healthcheck-protocol: HTTPS
    alb.ingress.kubernetes.io/healthcheck-path: /healthz
    alb.ingress.kubernetes.io/healthcheck-interval-seconds: '15'
    alb.ingress.kubernetes.io/healthcheck-timeout-seconds: '5'
    alb.ingress.kubernetes.io/healthy-threshold-count: '2'
    alb.ingress.kubernetes.io/unhealthy-threshold-count: '2'
    
    # WAFv2 웹 ACL을 연결하여 추가적인 보안 계층을 제공합니다.
    alb.ingress.kubernetes.io/wafv2-acl-arn: arn:aws:wafv2:region:account-id:regional/webacl/my-web-acl/acl-id
    
    # AWS Shield Advanced 보호를 활성화하여 DDoS 공격으로부터 보호합니다.
    alb.ingress.kubernetes.io/shield-advanced-protection: 'true'
    
    # ALB 속성 설정 (여기서는 삭제 방지와 액세스 로그를 활성화합니다)
    alb.ingress.kubernetes.io/load-balancer-attributes: deletion_protection.enabled=true,access_logs.s3.enabled=true,access_logs.s3.bucket=my-alb-logs
    
    # ALB에 태그를 추가합니다. 비용 할당 및 리소스 관리에 유용합니다.
    alb.ingress.kubernetes.io/tags: Environment=production,Project=myapp

  labels:
    app: common-external-ingress
spec:
  rules:
    - http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: istio-ingressgateway
                port:
                  number: 443