이번 포스트에서는 쿠버네티스 인그레스(Ingress)에 대한 개념과 설치, 실습까지 알아보도록 하자.
쿠버네티스에 존재하는 Ingress 리소스 오브젝트는 외부에서 들어오는 네트워크 트래픽을 어떻게 처리할지 정의한다. 쉽게 말하자면 클러스터 내부의 서비스를 외부로 노출시키는 일종의 Gateway와 같은 역할을 담당한다.

Ingress는 Service와 함께 사용되기 때문에 Ingress가 마치 Gateway처럼 앞단에서 요청을 받는 특징도 가지고 있다. 또한 L7(애플리케이션 계층) 레벨에서의 요청을 처리하기때문에 아래와 같은 기능을 수행할 수 있다.
트래픽 로드밸런싱
TSL/SSL 인증서 처리
Virtual hosting 지정
쿠버네티스 클러스터는 기본적으로 Ingress API를 다루는 별도의 컨트롤러를 제공하지 않고 Ingress API 리소스에 대한 스펙만 제공한다. 그렇기 때문에 해당 스펙을 처리하기 위해서는 사용자가 별도의 Ingress 컨트롤러를 설치해야만 한다.
대표적인 Ingress 컨트롤러는 여러가지가 존재하지만 이번 실습 시간에는 Nginx Ingress Controller를 사용해보도록 하겠다.
Envoy Ingress Controller
Traffic Ingress Controller
HAProxy Ingress Controller
NGINX Ingress Controller
Kong Ingress Controller
AWS Load Balancer Controller
Google Load Balancer Controller

그림과 같이 worker 노드에서 동작중인 웹 서비스를 하나 만들었다고 가정해보자. (메인 파드, 로그인 파드 등)
우선 각 파드를 Cluter IP 서비스로 묶어주면 해당 파드에 대한 진입점이 생겨난다. 그러나 Cluster IP로 묶인 서비스는 외부에서 접근이 불가능한 상태이다.
이때 외부에서 사용자가 해당 웹 서비스에 접근할 수 있는 단일 진입점을 만들어주는게 Ingress 컨트롤러라고 보면된다.
쿠버네티스 공식 문서에서 제공하는 가이드를 참고하여 베어메탈 버전 Nginx Ingress Controller를 설치할 수 있다.
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.12.0-beta.0/deploy/static/provider/baremetal/deploy.yaml
wget 명령어를 통해 해당 yaml 파일을 다운로드 받는다면 port 수정과 같은 커스텀 작업을 할 수 있다. 그리고 Ingress 컨트롤러를 설치해보자.
$ kubectl create -f deploy.yaml
$ kubectl get all -n ingress-nginx
NAME READY STATUS RESTARTS AGE
pod/ingress-nginx-admission-create-jk2nt 0/1 Completed 0 92s
pod/ingress-nginx-admission-patch-j7kbs 0/1 Completed 0 92s
pod/ingress-nginx-controller-846949fc46-7glcj 0/1 ContainerCreating 0 92s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/ingress-nginx-controller NodePort 10.96.243.65 <none> 80:30100/TCP,443:30200/TCP 93s
service/ingress-nginx-controller-admission ClusterIP 10.96.171.83 <none> 443/TCP 13s
NAME DESIRED CURRENT READY AGE
replicaset.apps/ingress-nginx-controller-846949fc46 1 1 0 93s
NAME STATUS COMPLETIONS DURATION AGE
job.batch/ingress-nginx-admission-create Complete 1/1 50s 93s
job.batch/ingress-nginx-admission-patch Complete 1/1 50s 93s
Ingress Controller를 설치하면 ingress-nginx라는 namespace가 생성되어 해당 context에서 동작하게 되는데 실습을 좀 더 편하게 하기위해 default 네임스페이스를 ingress-nginx로 변경해주는 작업을 할 것이다.
$ kubectl config set-context ingress-admin@kubernetes --cluster=kubernetes --user=ingress-admin --namespace=ingress-nginx
Context "ingress-admin@kubernetes" created.
$ kubectl config use-context ingress-admin@kubernetes
Switched to context "ingress-admin@kubernetes".
$ kubectl config current-context
ingress-admin@kubernetes
해당 방법을 거쳐 default 네임스페이스를 변경해주면 리소스를 조회할때 별도의 옵션을 넣지 않아도 ingress-nginx와 관련된 리소스들이 확인된다.
Ingress 컨트롤러의 라우팅을 확인하기 위해 각각 메인 페이지와 결제를 위한 Pay 페이지를 가진 서비스를 생성해주도록 하자.
$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/ingress-nginx-admission-create-jk2nt 0/1 Completed 0 92s
pod/ingress-nginx-admission-patch-j7kbs 0/1 Completed 0 92s
pod/ingress-nginx-controller-846949fc46-7glcj 0/1 ContainerCreating 0 92s
pod/marvel-7b77bf5cfc-xj2tc 1/1 Running 0 15s
pod/pay-rc-9w4l6 1/1 Running 0 15s
pod/pay-rc-dbvv8 1/1 Running 0 15s
pod/pay-rc-wtksq 1/1 Running 0 15s
NAME DESIRED CURRENT READY AGE
replicationcontroller/pay-rc 3 3 3 15s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/ingress-nginx-controller NodePort 10.96.243.65 <none> 80:30100/TCP,443:30200/TCP 93s
service/ingress-nginx-controller-admission ClusterIP 10.96.237.134 <none> 443/TCP 93s
service/marvel-service ClusterIP 10.96.160.150 <none> 80/TCP 15s
service/pay-service ClusterIP 10.96.18.237 <none> 80/TCP 15s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/ingress-nginx-controller 0/1 1 0 93s
deployment.apps/marvel 1/1 1 1 15s
NAME DESIRED CURRENT READY AGE
replicaset.apps/ingress-nginx-controller-846949fc46 1 1 0 93s
replicaset.apps/marvel-7b77bf5cfc 1 1 1 15s
NAME STATUS COMPLETIONS DURATION AGE
job.batch/ingress-nginx-admission-create Complete 1/1 50s 93s
job.batch/ingress-nginx-admission-patch Complete 1/1 50s 93s
웹 서비스가 다음과 같이 동작되는 것을 확인했다.
이제 Ingress를 main(marvel) 파드와 pay 파드를 각각 묶어놓은 service와 매핑해주는 yaml 파일을 작성하여 생성해보도록 하자.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: marvel-heroes-ingress
spec:
rules:
- http:
paths:
- path: /
backend:
serviceName: marvel-service
servicePort: 80
- http:
paths:
- path: /pay
backend:
serviceName: pay-service
servicePort: 80
$ kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
marvel-ingress <none> * 80 13s
$ kubectl describe ingress marvel-ingress
Name: marvel-ingress
Labels: <none>
Namespace: ingress-nginx
Address:
Ingress Class: <none>
Default backend: <default>
Rules:
Host Path Backends
---- ---- --------
*
/ marvel-service:80 (10.244.3.5:80)
*
/pay pay-service:80 (10.244.1.4:8080,10.244.2.4:8080,10.244.3.6:8080)
Annotations: <none>
Events: <none>
생성한 Ingress를 상세히 조회해보면 메인(marvel) 서비스와 pay 서비스와 관련한 Rules가 추가된 것을 확인할 수 있다.
https://kubernetes.github.io/ingress-nginx/deploy/#bare-metal-clusters