[k8s] Ingress
대세는 쿠버네티스 [초급~중급] 강의를 보고 정리한 글입니다.
[중급 편] 컨트롤러 Ingress
Ingress use case
Service LoadBalancing
www.mall.com -> Ingress -> Service1 -> Shopping Pod
www.mall.com/customer -> Ingress -> Service2 -> Customer Center Pod
www.mall.com/order -> Ingress -> Service3 -> Order Service Pod
Canary Upgrade
www.app.com -> Ingress -> Service1(90%) -> pod1(app v1), pod2(app v1)
www.app.com -> Ingress -> Service2(10%) -> pod3(app v2)
Ingress 설정 예시
Ingress1
Host: www.app1.com (도메인 이름)
Path: /svc1 ==> ServiceName: Service1
Path: /svc2 ==> ServiceName: Service2
Path: /svc3 ==> ServiceName: Service3
이렇게 Ingress Rule을 만들어도 k8s가 구현체를 만들기 전까지는 아무것도 할 수 없다.
별도의 plugin을 설치해야하며 대표적으로 NGINX, Kong 이 있다.
설치 과정
- Ingress Controller의 하나인 NGINX를 설치한다.
- nginx의 Namespace가 생성되고 그 위에 Deployment, ReplicaSet이 만들어진다.
- ReplicaSet에 의해 실제 Ingress 구현체인 Pod가 만들어진다.
- 이 Pod에 Ingress Rule이 있는지 확인한다.
- Rule이 있다면 Rule에 맞게 각 Service에 연결한다.
- 외부에서 들어오는 트래픽을 Rule에 맞게 각 서비스에 전달되도록 하기 위해서는 외부 트래픽은 Ingress Pod를 거쳐야 한다. 이를 위해 외부에서 접근할 수 있는 Service 하나를 만들고 Ingress Pod에 연결한다.
- 직접 k8s 설치한 경우는 NodePort, 클라우드를 이용한 경우는 LoadBalancer 를 만들어서 외부 Service에 연결한다.
이제 www.app1.com/svc1 으로 들어오는 트래픽은 외부 Service -> Ingress Pod -> Ingress1 -> Service1 -> Pod1 로 전달된다.
이 상태에서 새로운 Ingress 룰을 만든다면?
Ingress2
Host: www.app2.com (도메인 이름)
==> ServiceName: Service4
Ingress 구현체가 이미 있기 때문에 Ingress Pod에 Ingress2 룰이 추가되고 www.app2.com 으로 들어오는 트래픽이 Service4로 연결된다.
Ingress의 세가지 기능
Service Loadbalancing
Ingress
Path: / ==> ServiceName: svc-shopping
Path: /customer ==> ServiceName: svc-customer
Path: /order ==> ServiceName: svc-order
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: service-loadbalancing
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
Canary Upgrade
Ingress
Host: www.app.com
ServiceName: svc-v1
Ingress(canary)
Host: www.app.com
ServiceName: svc-v2 (app v2 pod로 연결되는 서비스)
Ingress(canary)에 어노테이션을 달면 Ingress Controller의 다양한 기능을 사용할 수 있다.
Ingress - @weight: 10% : 트래픽의 10% 가도록
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: canary-v2
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "10"
spec:
rules:
- host: www.app.com
http:
paths:
- backend:
serviceName: svc-v2
servicePort: 8080
Ingress - @header : 특정 나라별로 테스트하고 싶을 때. user의 언어가 kr일 때 100% svc-v2로 연결된다.
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
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"
spec:
rules:
- host: www.app.com
http:
paths:
- backend:
serviceName: svc-v2
servicePort: 8080
Https
pod 자체에서 인증서 기능 제공하기 힘들 때 사용하면 좋다.
Ingress
rules
host: www.https.com
serviceName: svc-https
tls
secretName: secret-https (secret 객체의 이름을 지정한다)
Secret 안에는 data 값으로 인증서 정보를 가지고 있다. 이렇게 구성하면 사용자는 https 로만 접근 가능하다.
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: https
spec:
tls:
- hosts:
- www.https.com
secretName: secret-https
rules:
- host: www.https.com
http:
paths:
- backend:
serviceName: svc-https
servicePort: 8080