ALB Ingress Controller 활용 예제

Prev Next

Ncloud Kubernetes Service에서는 Service와 Ingress에 어노테이션을 추가하여 다양한 라우팅 전략을 구현할 수 있습니다. 이 가이드에서는 ALB Ingress Controller 설정을 바탕으로 사용할 수 있는 예제를 제공합니다.

예제용 Deployment 및 Service는 아래 명령어를 실행하여 설치할 수 있습니다. 명령어 실행시 'naver', 'cloud', 'platform' 이라는 이름의 Deployment 및 Service가 생성됩니다:

kubectl --kubeconfig=$KUBE_CONFIG apply -f https://raw.githubusercontent.com/NaverCloudPlatform/nks-alb-ingress-controller/main/docs/examples/fin/nks-alb-ingress-sample-services.yaml
Shell

이 예제는 지정된 경로에 따라 요청을 서로 다른 서비스로 라우팅하는 방법을 보여줍니다. /naver 경로로 들어오는 요청은 naver 서비스로 라우팅되며, /cloud 경로로 들어오는 요청은 cloud 서비스로 라우팅됩니다.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: path-ingress
spec:
  ingressClassName: alb
  rules:
  - http:
      paths:
      - path: /naver
        pathType: Prefix
        backend:
          service:
            name: naver 
            port:
              number: 80
      - path: /cloud
        pathType: Prefix
        backend:
          service:
            name: cloud
            port:
              number: 80
YAML

이 예제는 지정된 호스트에 따라 요청을 서로 다른 서비스로 라우팅하는 방법을 보여줍니다. svc.naver.com 호스트로 들어오는 모든 요청은 naver 서비스로 라우팅되며, svc.cloud.com 호스트로 들어오는 모든 요청은 cloud 서비스로 라우팅됩니다.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: host-ingress
spec:
  ingressClassName: alb
  rules:
  - host: svc.naver.com
    http:
      paths:
      - path: /*
        pathType: Prefix
        backend:
          service:
            name: naver
            port:
              number: 80
  - host: svc.cloud.com
    http:
      paths:
      - path: /*
        pathType: Prefix
        backend:
          service:
            name: cloud
            port:
              number: 80
YAML

이 예제는 HTTP 헤더 값을 기반으로 트래픽을 라우팅하는 방법을 보여줍니다. alb.ingress.kubernetes.io/conditions 어노테이션을 사용하여 HTTP 헤더 규칙을 정의합니다. 아래 경우, 'HeaderName'이라는 HTTP 헤더에 'HeaderValue1' 또는 'HeaderValue2' 값이 포함되어 있는 요청만 네이버 서비스로 라우팅됩니다.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: condition-ingress
  annotations:
    alb.ingress.kubernetes.io/conditions.naver: >
      [{"field":"httpHeader","httpHeader":{"key": "HeaderName", "values":["HeaderValue1", "HeaderValue2"]}}]
spec:
  ingressClassName: alb
  rules:
    - http:
        paths:
          - path: /*
            pathType: Prefix
            backend:
              service:
                name: naver
                port:
                  number: 80
YAML

Ingress 규칙에서 서비스의 포트 이름(port.name)을 사용하여 트래픽 라우팅 규칙을 정의할 수 있습니다. 이를 위해, 서비스 정의 시 port.name을 명시적으로 지정해야 합니다. 이 예제는 네이버 서비스의 포트에 http-web이라는 이름을 지정하고 Ingress 규칙에서 이를 참조합니다.

apiVersion: v1
kind: Service
metadata:
  name: naver
spec:
  ports:
  - name: http-web
    nodePort: 30080
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: naver
  type: NodePort
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: portname-ingress
spec:
  ingressClassName: alb
  rules:
  - http:
      paths:
      - path: /naver
        pathType: Prefix
        backend:
          service:
            name: naver
            port:
              name: http-web
YAML

이 예제는 ssl-redirect 어노테이션을 활용하여 HTTP로 들어오는 트래픽을 HTTPS로 리다이렉트하는 방법을 보여줍니다. 예제를 수행하기 위해서는 다음 요소가 필요합니다.

  • 도메인
  • Certificate Manager에 등록된 해당 도메인의 인증서

HTTP(80)로 들어오는 트래픽을 HTTPS(443)으로 리다이렉트하려면 아래 예제와 같이 Ingress를 생성해 주십시오.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80},{"HTTPS":443}]'
    alb.ingress.kubernetes.io/ssl-certificate-no: "1004"
    alb.ingress.kubernetes.io/ssl-redirect: "443"
  name: redirect-ingress
spec:
  ingressClassName: alb
  defaultBackend:
    service:
      name: cloud
      port:
        number: 80
YAML
  • 위 설정에서 80 포트를 443 포트로 리다이렉트하기 위해 두 개의 포트를 등록하는 부분은 아래와 같습니다.

    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80},{"HTTPS":443}]'
    
    YAML
  • 위 설정에서 HTTPS 리스너에 등록할 인증서 번호를 나타내는 부분은 아래와 같습니다.

    alb.ingress.kubernetes.io/ssl-certificate-no: "1004"
    
    YAML
    참고

    인증서 번호는 Resource Manager의 nrn에서 확인할 수 있습니다. (예: nrn:PUB:CertificateManager::000:Certificate/External/${certificateNo})

  • 위 설정에서 리다이렉트할 포트를 등록하는 부분은 아래와 같습니다.

    alb.ingress.kubernetes.io/ssl-redirect: "443"
    
    YAML

로드밸런서에 여러 인증서를 등록할 수 있습니다. 이 예제에서는 기본(default) 인증서와 추가 인증서를 설정하는 방법을 보여줍니다.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80},{"HTTPS":443}]'
    alb.ingress.kubernetes.io/ssl-certificate-no: "1234, 1004"
    alb.ingress.kubernetes.io/ssl-redirect: "443"
  name: multi-ssl-ingress
spec:
  ingressClassName: alb
  rules:
  - http:
      paths:
      - path: /*
        pathType: Prefix
        backend:
          service:
            name: naver 
            port:
              number: 80
YAML
  • 위 설정에서 인증서를 등록하는 부분은 아래와 같습니다. 첫 번째 인증서가 기본 인증서로 추가되며 나머지 인증서는 추가 인증서로 설정됩니다.

    alb.ingress.kubernetes.io/ssl-certificate-no: "1234, 1004"
    
    YAML

이 예제에서는 Ingress 규칙과 함께 어노테이션을 사용하여 특정 경로에 대한 트래픽 처리 방식을 정의합니다. /navercloud 경로에 대해서 어노테이션을 통해 트래픽이 naver와 cloud 서비스로 분산되도록 설정됩니다.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: action-ingress
  annotations:
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}]'
    alb.ingress.kubernetes.io/description: 'alb ingress controller'
    alb.ingress.kubernetes.io/actions.navercloud: >
      {"type":"targetGroup","targetGroup":{"targetGroups":[{"serviceName":"naver","servicePort":80,"weight":50},{"serviceName":"cloud","servicePort":80,"weight":50}]}}
spec:
  ingressClassName: alb
  defaultBackend:
    service:
      name: naver
      port:
        number: 80
  rules:
    - http:
        paths:
          - path: /platform
            pathType: Prefix
            backend:
              service:
                name: platform
                port:
                  number: 80
          - path: /navercloud
            pathType: Exact
            backend:
              service:
                name: navercloud
                port:
                  name: use-annotation
YAML
  • 위 설정에서 트래픽을 naver와 cloud 서비스로 분산하는 부분은 아래와 같습니다.
    alb.ingress.kubernetes.io/actions.navercloud: >
      {"type":"targetGroup","targetGroup":{"targetGroups":[{"serviceName":"naver","servicePort":80,"weight":50},{"serviceName":"cloud","servicePort":80,"weight":50}]}}
    
    YAML
  • 어노테이션을 적용하기 위해서는 Ingress 명세 내에 정의된 경로와 actions.${actionName} 의 actionName 이 일치해야 합니다.

이 예제에서는 Ingress 규칙과 함께 어노테이션을 사용하여 서로 다른 네임스페이스에 있는 서비스를 하나의 Ingress에서 관리합니다. /navercloud 경로로 접근할 때, navercloud 네임스페이스에 존재하는 naver 서비스로 라우팅됩니다.

apiVersion: v1
kind: Service
metadata:
  name: naver
  namespace: navercloud
spec:
  type: NodePort
  selector:
    app: naver
  ports:
    - port: 80
      targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: naver
  namespace: navercloud
spec:
  replicas: 1
  selector:
    matchLabels:
      app: naver
  template:
    metadata:
      labels:
        app: naver
    spec:
      containers:
        - name: naver
          image: nks.ncr.fin-ntruss.com/hello:plain-text
          ports:
            - containerPort: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: action-ingress
  annotations:
    alb.ingress.kubernetes.io/actions.navercloud: >
      {"type":"targetGroup","targetGroup":{"targetGroups":[{"serviceName":"navercloud/naver","servicePort":80,"weight":100}]}}
spec:
  ingressClassName: alb
  defaultBackend:
    service:
      name: cloud 
      port:
        number: 80
  rules:
    - http:
        paths:
          - path: /navercloud
            pathType: Exact
            backend:
              service:
                name: navercloud
                port:
                  name: use-annotation
YAML
  • 위 설정에서 다른 네임스페이스에 존재하는 서비스를 정의하는 부분은 아래와 같습니다. action 내부의 서비스는 namespace/service 형식으로 지정되어야 합니다.
    alb.ingress.kubernetes.io/actions.navercloud: >
      {"type":"targetGroup","targetGroup":{"targetGroups":[{"serviceName":"navercloud/naver","servicePort":80,"weight":100}]}}
    
    YAML
  • 어노테이션을 적용하기 위해서는 Ingress 명세 내에 정의된 경로와 actions.${actionName} 의 actionName 이 일치해야 합니다.
  • action 내부에 기재된 서비스는 NodePort 타입이어야 합니다.

이 예제에서는 Ingress 규칙과 함께 어노테이션을 사용하여 특정 경로에 대한 조건 추가 방식을 정의합니다. 명세 내부에 기재된 룰을 통해 /naver 경로에 대해 naver 서비스로 라우팅하며 어노테이션을 통해 조건을 추가합니다.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: condition-ingress
  annotations:
    alb.ingress.kubernetes.io/conditions.naver: >
      [{"field":"hostHeader","hostHeader":{"values":["svc.naver.com"]}},{"field":"pathPattern","pathPattern":{"values":["/cloud"]}}]
spec:
  ingressClassName: alb
  rules:
    - http:
        paths:
          - path: /naver
            pathType: Prefix
            backend:
              service:
                name: naver
                port:
                  number: 80
YAML
  • 위 설정에서 svc.naver.com 호스트 헤더 조건과 추가 경로를 적용하는 부분은 아래와 같습니다.
    alb.ingress.kubernetes.io/conditions.naver: >
      [{"field":"hostHeader","hostHeader":{"values":["svc.naver.com"]}},{"field":"pathPattern","pathPattern":{"values":["/cloud"]}}]
    
    YAML
  • 어노테이션을 적용하기 위해서는 Ingress 명세 내에 정의된 경로와 conditions.${conditionName} 의 conditionName이 일치해야 합니다.

어노테이션의 적용 대상이 Ingress, Service 인 경우, 해당 어노테이션은 두 리소스 유형에서 사용할 수 있습니다. 동일한 어노테이션이 Ingress, Service 에 존재하는 경우 Service에 적용된 어노테이션이 우선적으로 적용됩니다.

이 예제에서는 경로별로 등록된 서비스의 헬스체크를 각각 다르게 설정합니다. 각 서비스에 대한 특정 헬스체크 설정은 서비스의 어노테이션을 통해 구현됩니다.

# naver-service.yaml
apiVersion: v1
kind: Service
metadata:
  annotations:
    alb.ingress.kubernetes.io/healthcheck-path: /naver
  name: naver
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: naver
  type: NodePort
---
# cloud-service.yaml
apiVersion: v1
kind: Service
metadata:
  annotations:
    alb.ingress.kubernetes.io/healthcheck-path: /cloud
  name: cloud
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: cloud
  type: NodePort
---
# healthcheck-alb.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: healthcheck-alb
  annotations:
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}]'
    alb.ingress.kubernetes.io/healthcheck-path: "/"
spec:
  defaultBackend:
    service:
      name: platform 
      port:
        number: 80
  rules:
  - http:
      paths:
      - path: /naver
        pathType: Prefix
        backend:
          service:
            name: naver
            port:
              number: 80
      - path: /cloud
        pathType: Prefix
        backend:
          service:
            name: cloud
            port:
              number: 80
YAML
  • 위 설정에서 /naver 경로로 라우팅되는 타겟 그룹의 헬스체크 조건은 아래와 같습니다. 타겟 그룹 별로 특정 헬스체크 조건을 적용하고자 할 때, 이러한 설정들은 해당 서비스의 어노테이션을 통해 정의되어야 합니다.
    alb.ingress.kubernetes.io/healthcheck-path: /naver
    
    YAML

로드밸런서의 Sticky Session은 리스너의 룰에서 설정 가능한 Sticky Session 기능과 타겟 그룹에서 설정 가능한 Sticky Session 기능으로 제공됩니다.
이 예제에서는 생성되는 모든 타겟그룹의 Sticky Session을 설정하고, action을 통해 생성된 룰의 Sticky Session을 사용하도록 설정합니다.

참고
  • 네이버 클라우드 플랫폼의 Application Load Balancer는 타깃 그룹으로 서버를 지정하므로 Ncloud Kubernetes Service 상품에서 Sticky Session 기능이 정상적으로 동작하지 않을 수 있습니다.
  • Sticky Session 기능을 활용하려면 서비스의 externalTrafficPolicy를 Local로 설정하고, 한 노드에 한 개의 파드만 배포해야 합니다.
  • 이 기능은 추후 개선될 예정이며, 되도록 운영 어플리케이션의 세션 관리 기능을 이용해야 합니다.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: sticky-ingress 
  annotations:
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}]'
    alb.ingress.kubernetes.io/enable-sticky-session: 'true'
    alb.ingress.kubernetes.io/actions.targets: >
      {"type":"targetGroup","targetGroup":{"targetGroups":[{"serviceName":"naver","servicePort":80,"weight":50},{"serviceName":"cloud","servicePort":80,"weight":50}],"enableStickySession":true}}
spec:
  ingressClassName: alb
  rules:
  - http:
      paths:
      - path: /navercloud
        pathType: Prefix
        backend:
          service:
            name: targets 
            port:
              name: use-annotation 
      - path: /platform
        pathType: Prefix
        backend:
          service:
            name: platform 
            port:
              number: 80
YAML
  • 위 설정에서 타겟그룹의 Sticky Session을 사용하는 부분은 아래와 같습니다.
    alb.ingress.kubernetes.io/enable-sticky-session: 'true'
    
    YAML
  • 위 설정에서 /navercloud 경로로 들어오는 요청에 Sticky Session을 사용하는 부분은 아래와 같습니다.
    alb.ingress.kubernetes.io/actions.targets: >
      {"type":"targetGroup","targetGroup":{"targetGroups":[{"serviceName":"naver","servicePort":80,"weight":50},{"serviceName":"cloud","servicePort":80,"weight":50}],"enableStickySession":true}}
    
    YAML