쿠버네티스 서비스 세 가지 유형 중 로드밸런서 유형은 온프레미스에서의 NodePort 유형의 서비스의 역할을 클라우드 환경에서 대체한다.
다른 애플리케이션 두 개가 클러스터 리소스를 공유할 수 있도록 하기 위해서는 같은 클러스터 내에 별도 Deployment로 배포해야 하는데, 이때 로드밸런서 유형의 서비스는 로드밸런서를 프로비저닝 하기 때문에 클라우드 비용도 증가할 수 있다.
로드밸런서 간의 트래픽을 URL 기반으로 전달하기 위해서는,
- URL 기반 트래픽을 다른 서비스로 리다이렉션 할 수 있는 프록시 또는 로드밸런서가 필요하다.
- 새 쿠버네티스 서비스를 구성할 때마다 로드밸런서를 재구성해야 한다.
때문에 구성이 다양해진 상황에서는 애플리케이션 확장 시 관리가 어려울 수 있고, 각 서비스마다 새 클라우드 로드밸런서를 프로비저닝 하여 비용 문제가 발생할 수 있다.
Ingress
사용자가 외부에서 접근할 수 있는 단일 URL을 사용하여 애플리케이션에 접근할 수 있게 한다.
다른 쿠버네티스 개체와 유사하게 구성할 수 있는 로드밸런서와 같으며, URL 기반으로 클러스터 내의 다른 서비스를 라우팅 하도록 설정할 수 있다. TLS 인증 구성 또한 가능하다.
Ingress도 클러스터 외부에서 접근할 수 있도록 하기 위해 NodePort 서비스나 로드밸런서를 사용해야 하지만, 한 개만 사용하면 된다.
Ingress 개념이 없었다면, NGINX, HAProxy, Traefik 등의 솔루션을 쿠버네티스 클러스터에 배포하고 라우팅을 구성(URL 경로, SSL 인증서 등을 정의) 해야 했을 것이다. Ingress도 유사하게 구성되지만 쿠버네티스에 의해 구성되고 실행된다.
Ingress Controller
GCE(Googles Layer 7 HTTP Load Balancer), NGINX, Contour, HAPROXY, TRAFIK, Istio 등의 솔루션으로 쿠버네티스에서 제공하지는 않는다.
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-ingress-controller
spec:
replicas: 1
selector:
matchLabels:
name: nginx-ingress
template:
metadata:
labels:
name: nginx-ingress
spec:
containers:
- name: nginx-ingress-controller
image: quay.io/kubernetes-ingresscontroller/nginx-ingress-controller:0.21.0
args:
- /nginx-ingress-controller # 프로그램 위치
- --configmap=$(POD_NAMESPACE)/nginx-configuration #구성 옵션 집합을 위한 configMap
env: # 포드 내 구성 데이터를 읽기 위한 환경 변수
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
ports:
- name: http
containerPort: 80
- name: https
containerPort: 443
예시로 든 Deployment 정의 파일은 Ingress Controller로 nginx 솔루션을 배포하도록 작성한 것이다. nginx는 프로그램 실행 경로와 구성 옵션 집합을 위한 configMap 전달이 필요하다.
Service
외부에서 Ingress Controller에 접근할 수 있게 하는 서비스
apiVersion: v1
kind: Service
metadata:
name: nginx-ingress
spec:
type: NodePort
ports:
- port: 80
targetPort: 80
protocol: TCP
name: http
- port: 443
targetPort: 443
protocol: TCP
name: https
selector:
name: nginx-ingress
Labels와 Selector를 이용한 NodePort 서비스를 생성하여 Deployment와 서비스를 연결한다.
Service Account
권한도 적절하게 필요할 수 있다.
apiVersion : v1
kind: ServiceAccount
metadata:
name: nginx-ingress-serviceaccount
Ingress Resource
Ingress Controller에 적용되는 규칙 및 구성 집합
트래픽을 응용프로그램으로 전달하거나 URL을 기반으로 라우팅하는 규칙을 구성한다.
apiVersion : extensions/v1beta1
kind: Ingress
metadata:
name: ingress-wear
spec:
backend: # 트래픽 라우팅 위치
serviceName: wear-service
servicePort: 80
backend 항목은 트래픽을 라우팅할 위치를 정의하며, 단일 백엔드일 경우에는 규칙(rule)이 따로 없다.
create 명령으로 생성한 ingress resource는 get 명령으로 확인할 수 있다.
kubectl get ingress
조건에 따라 라우팅을 다르게 하고 싶다면 rule을 지정하여 ingress를 생성한다.
apiVersion : extensions/v1beta1
kind: Ingress
metadata:
name: ingress-wear-watch
spec:
rules:
- http:
paths:
- path: /wear # 배열
backend:
serviceName: wear-service
servicePort: 80
- path: /watch
backend:
serviceName: watch-service
servicePort: 80
각 호스트나 DNS에 대한 규칙이 최상위에 있다.
생성한 ingress는 describe 명령으로 상세 내용을 확인할 수 있다.
kubectl describe ingress <INGRESS_NAME>
출력 내용 중 default backend는 사용자가 정의되지 않은 URL에 접근하려고 할 때 라우팅 할 서비스를 정의한 것이다. default-http-backend라는 이름의 서비스가 사용되며, 별도로 배포해야 한다.
아래는 DNS 또는 hostname을 사용해 라우팅하는 ingresss 정의 파일이다.
apiVersion : extensions/v1beta1
kind: Ingress
metadata:
name: ingress-wear-watch
spec:
rules:
- host: wear.my-conline-store.com
http:
paths:
- backend:
serviceName: wear-service
servicePort: 80
- host: watch.my-conline-store.com
http:
paths:
- backend:
serviceName: wear-service
servicePort: 80
참고로,
URL로 트래픽을 분할하는 경우, 하나의 rule을 두 개의 path로 트래픽을 분리한다.
트래픽을 hostname으로 분할하는 경우, rule 각각에 하나의 path로 트래픽을 분리한다.