
사용 목적으로는 대표적으로 Service LoadBalancing, Canary Upgrade가 있다.
외부에서 쿠버네티스 클러스터 내부로 들어오는 네트워크 요청을 어떻게 처리할 지 정의한다.
별도의 IP 로드밸런싱 장비 필요 없이 Ingress를 쓰면 된다.
예를 들어 쇼핑몰의 경우
Shopping page, Customer Center, Order Service 역할을 하는 각각 Pod를 만들어놓고, Pod마다 Service가 연결되어 있어 각각의 Pod의 상태는 다른 Pod에 영향을 주지 않는 상태이다.
사용자가 각각의 Service에 접근할 때는 도메인으로 접근할 수 있는데, (www.mail.com, www.mail.com/customer,...) 이 도메인들을 각각의 Service에 연결해주기 위해서는 별도의 IP 로드밸런싱 장비가 필요하다.
이 때 Ingress를 사용하면 각각의 도메인을 해당 Service에 연결해줄 수 있다.
V1에서 V2로 업그레이드를 하려고 한다면
V1 Pod와 V2 Pod를 각각 Service와 연결해놓고 Ingress를 사용하면
트래픽을 원하는 배분에 맞게 V1과 V2로 분산시킬 수 있다.
Ingress는 쿠버네티스를 설치하면 바로 만들 수 있다.
Ingress의 내용
Host: 도메인 이름
Path: 경로
serviceName: 해당 경로와 연결할 서비스
Ingress를 사용하려면 구현체가 필요한데, 이것을 Ingress Controller라고 하며 별도의 플러그인 설치가 필요하다. Ingress Controller는 대표적으로 Nginx, Kong 등이 있다.
만약 Nginx를 사용한다고 한다면
Nginx에 대한 Namespace가 생기고, 이 위에 Deployment, ReplicaSet이 만들어지면서 실제 Ingress 구현체인 Nginx Pod가 만들어진다. 그럼 이 Pod는 Ingress Rule이 있는지 확인하고 그 Rule에 맞게 해당 Service와 연결해준다.
외부에서 접속하려면 이 Nginx Pod를 거쳐야 하기 때문에 Nginx Pod가 외부에서 접속 가능하도록 Service와 연결해주어야 한다.
Nginx 설치
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.27.1/deploy/static/mandatory.yaml
NodePort Service 생성
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.27.1/deploy/static/provider/baremetal/service-nodeport.yaml
spec:
rules:
- http:
paths:
- path: /
backend:
serviceName: svc-shopping
servicePort: 8080
- path: /customer
backend:
serviceName: svc-customer
servicePort: 8080
- path: /order
backend:
serviceName: svc-order
servicePort: 8080
외부로부터 온 각각의 도메인 요청을 해당 Service에 연결해줄 수 있다.
마스터IP:NginxPod 포트번호+도메인
$ curl 192.168.0.30:30431/customer
Ingress를 두 개 만들어서 같은 호스트 도메인에 다른 서비스를 연결해준다. (v1, v2)
업그레이드할 버전 서비스가 연결된 Ingress에 어노테이션으로 @weight: 10% 를 준다면 트래픽의 10%만 업그레이드 버전 서비스로 분산될 것이다.
metadata:
name: canary-v2
annotations:
nginx.ingress.kubernetes.io/canary: "true" // canary 테스트를 할 것이다
nginx.ingress.kubernetes.io/canary-weight: "10"
@header 어노테이션을 사용하면 원하는 국가의 트래픽만 해당 서비스로 연결해줄 수 있다.
metadata:
name: canary-kr
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-by-header: "Accept-Language"
nginx.ingress.kubernetes.io/canary-by-header-value: "kr"
// kr을 Header로 연결 테스트하기
$ curl -H "Accept-Language: kr" www.app.com:30431/version
Ingress를 통해서 https로 연결하도록 인증서 관리가 가능하다. Pod 자체에서 인증서 기능을 제공하기 힘들 때 사용하면 좋다. 다음과 같이 연결하면 사용자는 https로만 해당 서비스에 접속할 수 있다.
Nginx Pod의 포트번호를 80이 아닌 443으로 설정해준다.
Ingress를 만들 때 호스트도메인과 서비스를 연결한다.
tls라는 옵션으로 secretName에 실제 Secret 오브젝트를 연결해준다.
spec:
tls:
- hosts:
- www.https.com
secretName: secret-https
rules:
- host: www.https.com
http:
paths:
- backend:
serviceName: scv-https
servicePort: 8080
Secret 안에는 데이터 값으로 인증서를 담고 있다.
// 인증서 생성
$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=www.https.com/0=www.https.com"
# Secret 생성
kubectl create secret tls secret-https --key tls.key -cert tls.crt