Cloud SA's This and That

[NCP] Kubernetes - ALB Ingress Controller를 통한 외부 클라이언트에 여러 서비스 노출하기(+ HTTPS Redirect Test) 본문

Naver-Cloud/Containers

[NCP] Kubernetes - ALB Ingress Controller를 통한 외부 클라이언트에 여러 서비스 노출하기(+ HTTPS Redirect Test)

뽀삐누냐 2023. 8. 9. 13:50
SMALL

쿠버네티스 클러스터 외부에서 서비스를 액세스하는 방법 중 단일 IP 주소로 여러 서비스를 노출하는 인그레스 리소스를 사용하는 방법을 통해 서비스를 노출하여 접속해보는 테스트를 진행해보았다.

 

우선 간단히 인그레스에 대해 설명하자면!

로드밸런서 서비스는 각 서비스마다 자신의 공인 IP 주소를 가진 로드밸런서가 필요하지만 인그레스는 하나의 IP 주소로 수십 개의 서비스에 접근 가능하도록 지원해준다. 클라이언트가 HTTP 요청을 보낼 때 요청한 호스트(host)와 경로(path)에 따라 요청을 전달한 서비스가 결정된다.

> 인그레스는 네트워크 스택의 어플리케이션 계층(HTTP)에서 작동한다.

(서비스가 할 수 없는 쿠키 기반의 세션 어피티니 등과 같은 기능 제공)

 

* 쿠버네티스 세션 어피니티에 대해 궁금하다면? : https://velog.io/@hl08217/Kubernetes-Session-Affinity를-통해-Sticky-Session-설정을-해보자 

 

[인그레스 동작 방식]

테스트 과정을 보기 전에 인그레스 동작 방식에 대해 간단히 알아보면 좋을 것 같다.

클라이언트가 DNS 조회 -> DNS 서버가 인그레스 컨트롤러의 주소 반환 -> 클라이언트는 HTTP 요청을 인그레스 컨트롤러로 전송, host 헤더에서 해당 DNS 지정 -> 컨트롤러는 해당 헤더에서 클라이언트가 액세스하려는 서비스 결정하고 서비스와 관련된 엔드포인트 오브젝트로 파드 IP를 조회 -> 클라이언트 요청을 파드에 전달

 

*인그레스 컨트롤러는 파드에 요청을 보내며 요청을 서비스로 전달하지 않고 파드를 선택하는데만 사용한다.

 

=============================================================================================

 

[TEST]

 

<사전 구성>

NCP에서 생성한 쿠버네티스 클러스터 및 Container Registry를 사용하여 테스트를 진행했다.

(참고: https://jyyoon94.tistory.com/2)

 

사전 생성 : ReplicationController, Pod, Service(NodePort)

 

> Pod 생성 시 사용할 이미지 (default, test1, test2)

 

> 3개의 RC를 생성하여 rctest, rctest2, rctest3 파드가 각 2개씩 유지되도록 설정함

   (이때 각 파드의 컨테이너 이미지는 rctest -> default , rctest2 -> test1 , rctest3 -> test2)

 

> 3개의 노드포트 서비스를 생성하여 nodeport-default 서비스의 파드셀렉터는 rctest 파드의 레이블과 일치하도록, nodeport-test1 서비스의 파드셀렉터는 rctest2 파드의 레이블과 일치하도록, nodeport-test2 서비스의 파드셀렉터는 rctest3 파드의 레이블과 일치하도록 설정함

 

> 이런식으로 파드가 서비스의 엔드포인트로 포함되는 것을 확인할 수 있다.

 

 

<ALB Ingress Controller 설치>

 

인그레스 리소스를 작동시키기 위해서는 클러스터에 인그레스 컨트롤러를 실행해야 하며 NCP의 ALB Ingress Controller를 설치하도록 한다. (ALB Ingress Controller를 통해 Kubernetes Ingress Load Balancer와 연동하여 트래픽을 라우팅 할 수 있다)

$ kubectl --kubeconfig=$KUBE_CONFIG apply -f https://raw.githubusercontent.com/NaverCloudPlatform/nks-alb-ingress-controller/main/docs/install/pub/install.yaml

> ALB Ingress Controller 설치 후 kube-system 네임스페이스에서 실행 중인 파드 확인

 

 

<인그레스 리소스 생성>

 

ALB Ingress Controller 기본 설정

 - service type : NodePort ( ingress를 통해 노출시킬 service는 모두 "NodePort" type으로 생성해야 함 )

 - default rule :  매칭되는 rule이 없을 때 적용되는 rule이며 [spec.defaultBackend]에 설정 가능 ( 설정하지 않았을 경우 80 포트로 설정된 기본 타깃 그룹이 생성됨 )

 - rule prioriy : ingress에서 정의한 rule의 순서에 따라 우선순위가 결정됨 ( 가장 위에 있는 rule의 우선 순위가 1 )

 

ALB Ingress Controller 어노테이션

 - Kubernetes Ingress와 Service 오브젝트에 어노테이션을 사용하여 설정 변경 가능함 ( ALB Ingress Controller 어노테이션은 "alb.ingress.kubernetes.io/"로 시작함 )

 

어노테이션 참고 : : https://guide.ncloud-docs.com/docs/k8s-k8suse-albingress

 

 

1. 동일한 호스트의 다른 경로로 여러 서비스 매핑

> jyyoon.shop/test1 로의 요청은 nodeport-test1 서비스로 라우팅되며

   jyyoon.shop/test2 로의 요청은 nodeport-test2 서비스로 라우팅된다.

   디폴트일 경우 nodeport-default 서비스로 라우팅된다.

 

> 생성된 인그레스(ingress-test) 확인 

 

> URL 경로에 따라 두 개의 다른 서비스로 규칙 설정이 되어있는 것 확인

 

> curl을 통해 ingress로 서비스에 액세스 -> 각 서비스로 라우팅되는 것을 확인할 수 있다.

 

 

2. 서로 다른 호스트로 서로 다른 서비스 매핑

> test1.jyyoon.shop으로의 요청은 서비스 nodeport-test1로 라우팅되며

   test2.jyyoon.shop으로의 요청은 서비스 nodeport-test2로 라우팅된다.

   디폴트의 경우 서비스 nodeport-default로 라우팅된다.

 

> 생성된 인그레스(ingress-test2) 확인

 

> 호스트에 따라 다른 서비스로 규칙 설정이 되어있는 것 확인

> 컨트롤러가 수신한 요청은 요청의 호스트 헤더(웹 서버에서 가상 호스트가 처리되는 방식)에 따라 서비스 nodeport-default, nodeport-test1, nodeport-test2로 전달된다. 이때 DNS는 jyyoon.shop& test1.jyyoon.shop & test2.jyyoon.shop 도메인 이름을 모두 인그레스 컨트롤러의 주소로 지정해야 한다.

 

> curl을 통해 ingress로 서비스에 액세스 -> 각 서비스로 라우팅되는 것을 확인할 수 있다.

 

==========================================================================================

+ 추가로 HTTP -> HTTPS 리다이렉트 테스트도 진행해보았다.

 

NCP 어노테이션을 활용하여 HTTP 들어오는 트래픽을 HTTPS 리다이렉트할  있다. (어노테이션 참고 : https://guide.ncloud-docs.com/docs/k8s-k8suse-albingress)

 

<사전 구성>

-도메인 (jyyoon.shop)

-NCP Certificate Manager 등록된 도메인의 인증서 (yjy-ssl)

 

[Certificate Manager]

 

[ssl-ingress.yaml]

alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80},{"HTTPS":443}]'

 리스너 포트에 80, 443 포트를 등록해준다.

 

alb.ingress.kubernetes.io/ssl-certificate-no: "<certificateNo>"

 >  HTTPS 리스너에 등록할 인증서 번호를 넣어준다(이때 인증서 번호는 NCP Resource Manager에서 확인이 가능하다)

 

[Resource Manager] - (nrn:PUB:CertificateManager::000:Certificate/External/${certificateNo})

 

alb.ingress.kubernetes.io/actions.ssl-redirect: |
  {"type":"redirection","redirection":{"port": "443","protocol":"HTTPS","statusCode":301}}

 >  443 포트로 리다이렉트하는 action 등록해준다.

 

- path: /*
  pathType: Prefix
  backend:
    service:
      name: ssl-redirect
      port:
        name: use-annotation
- path: /test1
  pathType: Prefix
  backend:
    service:
      name: nodeport-test1
      port:
        number: 80
- path: /test2
  pathType: Prefix
  backend:
    service:
      name: nodeport-test2
      port:
        number: 80

 > /* 경로에 트래픽이 들어오면 annotation 등록한 ssl-redirect.action 설정에 따라 443 포트로 리다이렉트한다.

 > 443 포트로 들어온 트래픽은 path(/test1, /test2) 따라 nodeport-test1 nodeport-test2 전달된다. 

 

 

[Load Balancer]

 > NCP 로드밸런서에서 ALB 생성된 것을 확인할  있다.

 

[Global DNS]

  > NCP의 Global DNS 서비스를 통해 도메인을 생성된 ALB Ingress의 주소로 지정해준다.

 

 

[Redirect Test]

 > 80 포트로 접속 -> 443 포트로 리다이렉트 확인

 

 

 > 80 포트로 접속 -> 443 포트로 리다이렉트 확인

 

 

 > 80 포트로 접속 -> 443 포트로 리다이렉트 확인

 

* 클라이언트와 인그레스 컨트롤러 간의 통신은 암호화(443 포트)되지만 컨트롤러와 백엔드 파드 간의 통신은 암호화 X(80 포트)

=> ALB Ingress Controller가 파드에서 실행되는 애플리케이션을 대신하여 SSL 암호화 통신 협상을 완료함으로써 SSL Offload를 실시할 수 있다.

(SSL Offload : 서버 대신 SSL HandShake를 수행하여 서버에 SSL 통신관련 부하를 제거하고 클라이언트와 서버 간의 SSL 암호화 통신을 제공하는 기능 )

 

LIST