본문 바로가기
kubernetes

[kubernetes] ingress-nginx-controller (helm) 설치 및 ingress 리소스 설정

by Blue____ 2024. 1. 21.

이번 글에서는 VM 기반의 kubernetes 클러스터에서 ingress-nginx-controller를 설치해, external-ip를 설정하고 이를 기반으로 ingress 리소스를 설정해 외부에서의 접속을 진행해보겠습니다.


우선, ingress-nginx-controller를 설치하기 전에, kubernetes 클러스터에서 ingress를 설장하는 이유에 대해서 간단히 설명하고 넘어가겠습니다. 

 

kubernetes 클러스터에서 Pod은 MasterPlain의 Controller에 의해 관리가 됩니다. 따라서, Pod의 IP는 고정되어 관리되지 않고 Pod이 delete/create 시 마다 변경되어 관리됩니다. 즉, Pod의 IP address를 확인해보면 초기 설정한 대역폭에 따라 랜덤하게 할당/설정되며 kubernetes 클러스터 내부에서만 해당 IP를 통신 포인트로 사용합니다. 다시말해 Pod의 IP는 외부에서는 접근을 할 수 없는 kubernetes 클러스터 내부의 가상 IP이며, 내부 통신에 사용됩니다. 

 

따라서, kubernetes 클러스터 외부에서, 클러스터 내부의 서비스들에 접근하기 위해선 "Ingress"라는 리소스를 생성/설정해주어야 하는데 이를 위한 서비스가 오늘 설치를 진행할 ingress-nginx-controller 입니다. ingress-nginx-controller에 대해서 간단하게 설명하자면 ingress-nginx-controller는 External-IP를 설정해, 해당 IP를 통해 외부에서 접근이 가능하도록 만들어 줍니다. 당연히, External-IP는 가상의 IP가 아닌, 실제 서버(VM, 베어메탈, EC2 등)의 IP로 설정을 해야 합니다 (외부 접근을 위해)ingress-nginx-controller를 설치하게 되면 외부에서 접근할 수 있는 External-IP가 설정되고, 다른 어플리케이션들은 해당 ingress-nginx-controller를 기반으로 ingress 리소스를 생성해 외부에서 어플리케이션의 서비스에 접근하도록 할 수 있습니다. 

 

본격적으로 ingress-nginx-controller를 설치하기 전에, kubernetes의 서비스 타입들에 대해서 간단하게만 설정하고 진행을 하겠습니다. 우선 kubernetes의 서비스 타입은 크게 3가지가 아래와 같이 있습니다. 

 

ClusterIP

ClusterIP는 가장 기본 타입이며, 클러스터 내부의 노드에서만 접근이 가능하며, 외부에서는 접근이 불가합니다. 

$ kubectl get services

NAME       TYPE    CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none>    443/TCP 5d21h

 

위처럼, ClusterIP는 클러스터 내부에서만 사용하는 IP입니다. 모든 Pod에는 ClusterIP가 존재합니다.

 

NodePort

NodePort는 각 노드의 포트를 지정해 외부/내부 모두에서 접근이 가능하도록 하는 서비스입니다. 이번, Ingress 설정에서도 서비스 타입은 NodePort로 진행할 예정입니다. 즉, 클러스터 외부에서도 Port를 기반으로 접근을 할 수 있으며, 클러스터 내부 노드들의 특정 포트를 개방해 서비스에 접근하도록 하는 방식입니다. VM 노드들로 구성된 클러스터에는 NodePort를 서비스 타입으로 사용합니다.

 

LoadBalancer

LoadBalancer 타입의 서비스는 서비스를 생성함과 동시에 로드 밸런서를 새롭게 생성해 pod과 연결합니다. Nodeport는 각 노드의 IP를 알아야 pod에 접근할 수 있지만, LoadBalancer 타입의 서비스는 쿨라우드 플랫폼으로 부터 도메인 이름과 IP를 할당 받기 때문에 Nodeport보다 쉽게 pod에 접근할 수 있습니다.  단, Loadbalancer를 동적으로 생성하는 기능을 제공하는 환경(예, AWS, GCP 등)에서만 사용할 수 있습니다. 

 

 

ingress-nginx-controller 설치

그럼 이제, ingress-nginx-controller의 설치를 진행해 보겠습니다. 이번 설치에서는 helm을 통해 설치를 진행할 예정입니다. 

# helm repo 추가
$ helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx

# helm repo 업데이트
$ helm repo update

# values.yaml의 overwrite를 위해, values.yaml를 다른 이름으로 저장
PS C:\Users\1155476> helm show values ingress-nginx > my-ingress-nginx.yaml

 

아래는, ingress-nginx-controller의 values.yaml 파일 수정 내용입니다. 

 

controller:
 name: controller
 enableAnnotationValidations: false
 image:
 chroot: false
 registry: {registry 주소}  ## private 저장소를 사용하면 해당 주소를 입력해주면 됩니다.
 image: ingress-nginx/controller
configMapName: ""
configMapKey: ""

service:
enabled: true  ## 서비스 사용은 true로 변경해줍니다. 
appProtocol: true
through helm tpl engine.
annotations: {}
labels: {}

externalIPs: [10.xx.110.xxx] ## 외부 접근을 허용할 노드 IP를 정해, IP 주소를 입력해줍니다.

ipFamilies:
- IPv4
ports:
http: 80
https: 443
targetPorts:
http: http
https: https
type: NodePort ## 서비스 타입은 NodePort로 설정해주고, http, https 포트를 지정해줍니다. (지정을 안해줘도 랜덤하게 만들어지긴 합니다.)
nodePorts:
http: 32080
https: 32443
tcp: {}
udp: {}
external:  ## external 설정을 true로 변경해줍니다. 
enabled: true

 

Yaml 파일의 들여쓰기가 잘 안되어 있는데, 붙여넣기하게 되는 경우 기본 Template에서 value만 바꾸기를 권장합니다. 위의 values.yaml 파일에서 신경 써줘야 하는 포인트는 External-IP와 서비스 타입을 잘 설정해줘야 합니다. 

# 수정한, values.yaml 파일을 기반으로 helm install을 진행해줍니다.
$ helm install my-ingress-nginx -f .\my-ingress-nginx.yaml ingress-nginx/ingress-nginx

 

설치 후, ingress-nginx-controller를 확인해보면 아래와 같이 External-IP가 정상적으로 설정되어 있는 것을 확인할 수 있습니다. 

$ kubectl get services

NAME                                  TYPE     CLUSTER-IP   EXTERNAL-IP   PORT(S)          AGE
my-ingress-nginx-controller           NodePort 10.10.230.29 10.xx.110.xxx 80:32080/TCP,443:32443/TCP 5m30s
my-ingress-nginx-controller-admission ClusterIP 10.19.231.98 <none> 443/TCP 5m30s

 

Trino의 Ingress 설정 및 설치

그럼, 이번에는 Trino 어플리케이션을 설치하며 Ingress 설정도 함께, 진행해보도록 하겠습니다. 

# Trino helm 설치
$ helm show values trino/trino > my-trino-values.yaml

 

아래는 Trino의 values.yaml 파일 중, Ingress의 설정 내용입니다. 

ingress:
 enabled: true ##ingress 설정을 true로 변경
 className: nginx  ##classname은 ingress-nginx-controller의 기본 classname은 nginx로 입력해줍니다.
 annotations:
 k8s.io/ingress.class: nginx ##annotation 설정도 기본 설정인 nginx로 설정
 hosts:
 - host: my-trino.co.kr ## hostname은 본인이 원하는 주소 입력해줍니다. 
 paths:
 - path: / ## path는 / 기본 path로 우선 설정 (원하는 path로 설정해 주어도됩니다.)
 pathType: Prefix
 tls: []

 

위에서 ClassName은 Ingress서비스와 ingress-nginx-controller를 Mapping 해주는 역할을 포인트입니다. 

# trino helm install
$ helm install my-trino -f my-trino-values.yaml trino/trino

# 설치 후, ingress 확인
$ kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
my-trino-coordinator nginx my-trino.co.kr 10.xx.110.xxx 80 64m

 

트리노의 Ingress 서비스를 확인해보면, Host-name은 Trino 설치 과정에서 설정한 name으로 올라와있고, Address는 ingress-nginx-controller의 External-IP 기반으로 올라와 있는 것을 확인할 수 있습니다. 이제 서비스의 port-forwarding을 진행해주지 않아도 해당 Hostname과 IP를 기반으로 외부 접속이 가능한지 확인해보겠습니다. (hostname과 IP는 로컬 PC의 host 파일에 입력을 해주어야 합니다.)

 

http, https 모두, 설정한 hostname 기반으로 접속 가능

 

Trino-web UI

 

위처럼, 정상적으로 외부에서 접속이 가능한 것을 확인할 수 있습니다.