ALB Ingress Controller

ALB Ingress Controller는 Kubernetes Ingress를 Application LoadBalancer 상품에 연동하여 HTTP, HTTPS 트래픽을 클러스터의 Pod에 라우팅되도록 합니다.

동작 방식

  • Ingress가 생성되면 Ingress Controller는 Ingress에 설정된 값들을 활용하여 Application Load Balancer를 생성합니다.
  • Ingress Rule에 설정된 Service들의 NodePort로 Worker Node들에 대한 Target Group들을 생성하고 Load Balancer에 등록합니다.

시작하기

시작하기 전에 Ingress Controller를 설치 할 Kubernetes Service 클러스터와 kubectl 설치 및 kubeconfig 설정이 선행되어야합니다.

클러스터에 ALB Ingress Controller 설치하기

아래 명령을 사용하면 kube-system 네임스페이스에 alb-ingress-controller가 생성되며, 그에 필요한 ServiceAccount, ClusterRole, ClusterRoleBinding이 생성됩니다.

kubectl --kubeconfig=$KUBE_CONFIG apply -f https://gist.githubusercontent.com/NaverCloudPlatformDeveloper/cd2f801d1896bca90fd13b9a5c7acc89/raw/6bf88a3e00a8bcca1dd0771070270f4c60040388/nks-alb-ingress-controller_v0.0.1.yaml

사용법

  • kubernetes.io/ingress.class: alb
    • ALB Ingress Controller를 사용하려면 Ingress Resource에 kubernetes.io/ingress.class: alb Annotation을 추가해야합니다.
  • Service type: NodePort
    • Ingress를 통해 노출시킬 Service는 모두 NodePort type으로 생성하여야 합니다.
  • Default Rule
    • Default Rule은 매칭되는 rule이 한 개도 없을 때 적용되는 rule이며 spec.backend에 설정할 수 있습니다.
    • 별도의 rule 및 use-annotation 설정은 불가능하며, 설정하지 않았을 경우 80포트로 설정된 기본 Target Group이 생성됩니다.
  • Rule Priority
    • Ingress에 정의한 rule의 순서에 따라 우선순위가 결정됩니다. 가장 위에 있는 rule의 우선순위가 1로 설정됩니다.

Ingress Annotations

IngressService 오브젝트에 annotation을 사용하여 설정을 변경할 수 있습니다. alb ingress annotation은 모두 alb.ingress.kubernetes.io/로 시작합니다.

Annotation 기본값 적용 Resource 설명
alb.ingress.kubernetes.io/listen-ports [{"HTTP":80}] (인증서 번호가 설정되었다면 [{"HTTPS":443}]) Ingress Listener의 프로토콜 및 포트 설정 리스트.
- 사용 가능한 프로토콜: HTTP,HTTPS
alb.ingress.kubernetes.io/description N/A Ingress 로드밸런서 메모
alb.ingress.kubernetes.io/ssl-certificate-no N/A Ingress 프로토콜이 HTTPS인 리스너에 적용할 Certificate Manager의 인증서 번호
- 인증서 번호는 Resource Manager의 nrn에서 확인할 수 있습니다. (예: nrn:PUB:CertificateManager::000:Certificate/External/${certificateNo})
alb.ingress.kubernetes.io/load-balancer-size small Ingress 로드밸런서의 부하처리 성능 설정
- 설정 가능한 값: small, medium, large
alb.ingress.kubernetes.io/network-type public Ingress 로드밸런서의 네트워크 유형 설정
- 사설: private, 공인: public
alb.ingress.kubernetes.io/subnet-id kube-system configmap(ncloud-config)lbSubnetNo Ingress 로드밸런서 생성을 위한 로드밸런서 전용 서브넷의 ID 값이며 생성할 때만 사용됩니다.
alb.ingress.kubernetes.io/actions.${actionName} N/A Ingress Listener Rule의 기능들을 사용하기 위한 설정(하단 설명 참고)
alb.ingress.kubernetes.io/conditions.${conditionName} N/A Ingress Ingress Rule의 Host, Path 조건에 추가 조건을 적용하기 위한 설정(하단 설명 참고)
alb.ingress.kubernetes.io/algorithm-type round-robin Ingress, Service Target Group의 로드밸런싱 알고리즘 설정
- 설정 가능한 값: round-robin, least-connection, source-ip-hash
alb.ingress.kubernetes.io/unhealthy-threshold-count 2 Ingress, Service Health Check 실패 임계값
alb.ingress.kubernetes.io/healthy-threshold-count 2 Ingress, Service Health Check 성공 임계값
alb.ingress.kubernetes.io/healthcheck-port TargetGroup 포트 Ingress, Service Health Check 포트
alb.ingress.kubernetes.io/healthcheck-path / Ingress, Service Health Check URL 경로
alb.ingress.kubernetes.io/healthcheck-interval-seconds 30 Ingress, Service Health Check 주기(초)
alb.ingress.kubernetes.io/healthcheck-protocol HTTP Ingress, Service Health Check 프로토콜
- HTTP, HTTPS
alb.ingress.kubernetes.io/backend-protocol HTTP Ingress, Service Target Group의 프로토콜
- HTTP, HTTPS
alb.ingress.kubernetes.io/enable-sticky-session false Ingress, Service Target Group의 Sticky Session 설정
  • alb.ingress.kubernetes.io/actions.${actionName}: actions 모델에 맞게 json 형태의 string으로 작성하여 Listener Rule의 추가적인 기능들을 설정할 수 있습니다. Ingress에 설정된 Rule의 serviceName을 사용하고자 하는 ${actionName}으로 설정하고, servicePortuse-annotation으로 설정하면 Annotation이 적용됩니다.
Property Type 설명
type string action의 type을 정의합니다.
- 설정 가능한 값 targetGroup, redirection
targetGroup object action의 type을 targetGroup으로 설정한 경우 사용됩니다.
targetGroup.targetGroups array 트래픽을 전달할 service의 목록입니다.
targetGroup.targetGroups[n].serviceName string service name
targetGroup.targetGroups[n].servicePort number service port
targetGroup.enableStickySession boolean sticky session 활성화 여부
- 기본값: false
redirection object action의 type을 redirection으로 설정한 경우 사용됩니다.
redirection.host string - 기본값: #{host}
redirection.path string - 기본값: /#{path}
redirection.query string - 기본값: #{query}
redirection.port string redirection 포트
- 기본값: #{port}
redirection.protocol string - 설정 가능한 프로토콜: HTTP, HTTPS
- 기본값: #{protocol}
redirection.statusCode number - 설정 가능한 코드: 301, 302
  • 예시
    • 경로 /exampleactionNametargets인 Annotation을 설정하여 두 개의 Service(a, b)로 가중치 기반 라우팅이 되도록 설정
      apiVersion: extensions/v1beta1
      kind: Ingress
      metadata:
      name: example-alb-ingress
      annotations:
        kubernetes.io/ingress.class: alb
        alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}]'
        alb.ingress.kubernetes.io/actions.targets: >
          {"type":"targetGroup","targetGroup":{"targetGroups":[{"serviceName":"a","servicePort":80,"weight":40},{"serviceName":"b","servicePort":80,"weight":60}],"enableStickySession":false}}
      labels:
        app: example-alb-ingress
      spec:
      rules:
        - http:
            paths:
              - path: /example
                backend:
                  serviceName: targets
                  servicePort: use-annotation
      
  • alb.ingress.kubernetes.io/conditions.${conditionName}: conditions 모델에 맞게 json 형태의 string으로 작성하여 Ingress에 정의된 Host, Path 조건 외에 추가 조건들을 설정할 수 있습니다. Ingress Rule에서 ${conditionName}과 일치하는 serviceName을 가진 Service에 대해 조건을 적용합니다.
Property Type 설명
field string 추가할 조건을 정의합니다.
- 설정 가능한 값 hostHeader, pathPattern
hostHeader object condition의 field를 hostHeader으로 설정한 경우 사용됩니다.
hostHeader.values array host 목록입니다.
hostHeader.values[n] string host
pathPattern object condition의 field를 pathPattern으로 설정한 경우 사용됩니다.
pathPattern.values array path 목록입니다.
pathPattern.values[n] string path
  • 예시
    • 기존 rule에 설정된 경로 /example에 host 조건 example.com과 path 조건 /example2를 추가
      apiVersion: extensions/v1beta1
      kind: Ingress
      metadata:
      name: example-alb-ingress
      annotations:
        kubernetes.io/ingress.class: alb
        alb.ingress.kubernetes.io/conditions.example: >
          [{"field":"hostHeader","hostHeader":{"values":["example.com"]}},{"field":"pathPattern","pathPattern":{"values":["/example2"]}}]
      labels:
        app: example-alb-ingress
      spec:
      rules:
        - http:
            paths:
              - path: /example
                backend:
                  serviceName: example
                  servicePort: 80
      

Example

라우팅 예제

서로 다른 3개의 Service에 대해 다양한 방법으로 라우팅하는 예제입니다.

아래 명령을 실행하면 3개의 Sample용 Deployment 및 Service가 생성됩니다. 각 서비스의 이름은 naver, cloud, platform입니다.

kubectl --kubeconfig=$KUBE_CONFIG apply -f https://gist.githubusercontent.com/NaverCloudPlatformDeveloper/0e6262b996f74229719807cb5ae007fc/raw/3ce72e7961bc2407bfb87e153c94672e6ee6a1cf/nks-alb-ingress-sample-services.yaml

생성한 서비스들에 대해 아래와 같이 동작하도록 Ingress를 생성해보겠습니다.

  • 경로별 동작
    • /platform: Service platform으로 라우팅합니다.
    • /navercloud: 50 대 50의 가중치로 naver, cloud 두 Service로 라우팅합니다.
    • 그 외의 모든 경로: Service naver로 라우팅합니다.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: sample-alb-ingress
  annotations:
    kubernetes.io/ingress.class: alb
    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}]}}
  labels:
    app: sample-alb-ingress
spec:
  backend:
    serviceName: naver
    servicePort: 80
  rules:
    - http:
        paths:
          - path: /platform
            backend:
              serviceName: platform
              servicePort: 80
          - path: /navercloud
            backend:
              serviceName: navercloud
              servicePort: use-annotation

위 내용으로 ingress.yaml 파일을 생성 후 아래의 명령으로 클러스터에 Ingress를 생성합니다.

kubectl --kubeconfig=$KUBE_CONFIG apply -f ./ingress.yaml

Ingress가 생성되면 Application Load Balancer를 생성하고, 생성이 완료되면 Ingress의 ADDRESS에 Load Balancer 접속정보가 업데이트 되는 것을 확인할 수 있습니다.

kubectl --kubeconfig=$KUBE_CONFIG get ingress
NAME                 HOSTS   ADDRESS   PORTS   AGE
sample-alb-ingress   *       ing-default-samplealbing-e5bde-1494091-0687c0712561.kr.lb.naverncp.com   80      21s

Load Balancer의 주소를 호출하여 ingress에 설정한 경로들이 각각 다른 Service의 Pod로 연결되는지 Server name에서 확인할 수 있습니다.

  • /navercloud (여러번 호출 하여 naver, cloud로 라우팅 확인)

    $ curl http://ing-default-samplealbing-e5bde-1494091-0687c0712561.kr.lb.naverncp.com/navercloud
    Server address: 198.18.0.160:80
    Server name: cloud-868dcd94cb-7lpl6
    Date: 15/Oct/2020:12:31:25 +0000
    URI: /navercloud
    Request ID: 6eaff95fa4000943b9aea8903ba8e598
    
    $ curl http://ing-default-samplealbing-e5bde-1494091-0687c0712561.kr.lb.naverncp.com/navercloud
    Server address: 198.18.0.75:80
    Server name: naver-5b64c89ff8-gwqxx
    Date: 15/Oct/2020:12:35:59 +0000
    URI: /navercloud
    Request ID: 9aa7cc193798ce3bce89718570fb9cb9
    
  • /platform
    $ curl http://ing-default-samplealbing-e5bde-1494091-0687c0712561.kr.lb.naverncp.com/platform
    Server address: 198.18.0.35:80
    Server name: platform-85f9569d46-9zx6v
    Date: 15/Oct/2020:12:31:34 +0000
    URI: /platform
    Request ID: 2c9ef5533e8eb3421f129a095ab0b418
    
  • /navercloudplatform(설정에 없는 경로)
    $ curl http://ing-default-samplealbing-e5bde-1494091-0687c0712561.kr.lb.naverncp.com/navercloudplatform
    Server address: 198.18.0.75:80
    Server name: naver-5b64c89ff8-gwqxx
    Date: 15/Oct/2020:12:31:46 +0000
    URI: /navercloudplatform
    Request ID: aa95fbc807f305e6a8a07aa6a57884b2
    

HTTP를 HTTPS로 리다이렉트하기

action type이 redirection인 annotation을 활용하여 HTTP(80)로 들어오는 트래픽을 HTTPS(443)으로 redirect하는 예제입니다. 이 예제를 수행하기 위해서는 먼저 도메인이 필요하며, 해당 도메인에 대한 Certificate Manager 상품에 등록 된 인증서가 필요합니다.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80},{"HTTPS":443}]'
    alb.ingress.kubernetes.io/ssl-certificate-no: "1004"
    alb.ingress.kubernetes.io/actions.ssl-redirect: |
      {"type":"redirection","redirection":{"port": "443","protocol":"HTTPS","statusCode":301}}
  labels:
    app: sample-alb-ingress
  name: sample-alb-ingress
  namespace: sample
spec:
  backend:
    serviceName: my-service
    servicePort: 80
  rules:
  - http:
      paths:
      - path: /*
        backend:
          serviceName: ssl-redirect
          servicePort: use-annotation
      - path: /*
        backend:
          serviceName: my-service
          servicePort: 80
  • 80 포트를 443 포트로 redirection하기 위해 두개의 port를 등록합니다.

    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80},{"HTTPS":443}]'
    
  • HTTPS 리스너에 등록할 인증서 번호입니다. 인증서 번호는 Resource Manager의 nrn에서 확인할 수 있습니다. (예: nrn:PUB:CertificateManager::000:Certificate/External/${certificateNo})

    alb.ingress.kubernetes.io/ssl-certificate-no: "1004"
    
  • 443 포트로 redirect하는 action을 등록합니다.

    alb.ingress.kubernetes.io/actions.ssl-redirect: |
      {"type":"redirection","redirection":{"port": "443","protocol":"HTTPS","statusCode":301}}
    
  • /* 경로에 트래픽이 들어오면 ssl-redirect에 등록한 action 설정대로 443 포트로 redirect 합니다.(이 rule은 최상단에 위치해야 합니다.)

    
    - path: /*
      backend:
        serviceName: ssl-redirect
        servicePort: use-annotation
    
  • 443 포트로 들어온 트래픽이 my-service로 전달됩니다.

    - path: /*
      backend:
        serviceName: my-service
        servicePort: 80
    

기본적으로 alb-ingress-controller는 ingress에 등록된 rule들을 모든 listener에 동일하게 등록합니다. 하지만 redirect 설정의 경우 redirect loop가 발생할 수 있는 케이스에서는 해당하는 포트의 listener에는 redirect rule을 등록하지 않습니다. 따라서 위의 예제에서는 80포트의 리스너에만 redirect rule이 등록이 됩니다.

""에 대한 건이 검색되었습니다.

    ""에 대한 검색 결과가 없습니다.

    처리중...