[도커/쿠버네티스] 8장_인그레스
ingress 는 일반적으로 외부에서 내부로 향하는 것을 지칭한다.
쿠버네티스 인그레스는, 외부 요청을 어떻게 처리할 것인지 네트워크 7 계층 레벨에서 정의하는 오브젝트이다.
사용 이유
어플리케이션이 3 개의 디플로이먼트로 생성되어 있다고 하자.
디플로이먼트를 외부에 노출하려면 위 그림 처럼,
NodePort or LoadBalancer 타입의 서비스 3 개를 각각 디플로이먼트에 연결해주면 된다.
그런데, 이 방식은 서비스마다 세부적인 설정을 할 때 추가적인 복잡성이 발생한다.
예를 들면, 아래와 같은 내용을 구현하려면, 서비스와 디플로이먼트에 대해 일일이 설정해야한다.
- SSL / TLS 보안 연결
- 접근 도메인 및 클라이언트 상태에 기반한 라우팅
그래서 인그레스가 필요하다.
인그레스 오브젝트를 이용하면, URL 엔드포인트를 단 하나만 생성해서 이런 번거로움을 해결할 수 있다.
위 그림처럼, 3 개의 서비스에 대해 3 개 URL 이 각각 존재하는 것이 아니라
인그레스에 접근하기 위한 하나의 URL 만 존재한다.
핵심은, 라우팅 정의나 보안 연결 같은 세부 설정은 서비스와 디플로이먼트가 이니라 인그레스에 의해 수행
구조
ingress-example.yaml 파일을 작성하자.
1 | apiVersion: networking.k8s.io/v1beta1 |
그리고, 인그레스 오브젝트를 생성하자.
1 | kubuctl apply -f ingress-example.yaml |
하지만, 이것만으로 아무일도 일어나지 않는다.
인그레스는 요청 처리 규칙을 정의한 선언적인 오브젝트일 뿐, 외부 요청을 받는 서버가 아니기 때문이다.
그래서, 인그레스 컨트롤러라는 특수한 서버에 이 규칙을 적용해서 생성해야한다.
인그레스 컨트롤러의 종류로는 다음 것들이 있다.
- Kong API Gateway : https://konghq.com/kong
- GKE (Google Kubernetes Engine) : https://cloud.google.com/kubernetes-engine
- Nginx 웹서버 인그레스 컨트롤러 : https://github.com/kubernetes/ingress-nginx
아래와 같이,
쿠버네티스에서 공식적으로 개발되고 있는 Nginx 웹서버 인그레스 컨트롤러를 설치하자.
1 | kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.41.2/deploy/static/provider/aws/deploy.yaml |
설치하면,
- ingress-nginx 네임스페이스에 디플로이먼트와 포드를 확인하면, Nginx 웹 서버가 생성되어 있다.
- 그리고, 외부에서 Nginx 인그레스 컨트롤러에 접근하기 위한 서비스도 생성되어 있다.
이제, 인그레스의 종착점이 될 테스트용 디플로이먼트와 서비스를 아래와 같이 생성해보자.
Nginx 인그레스 컨트롤러로 들어오는 요청은 이 디플로이먼트의 포드들로 분산될 것이다.
1 | apiVersion: apps/v1 |
1 | apiVersion: v1 |
1 | kubuctl apply -f hostname-deployment.yaml |
이제, Nginx 인그레스 컨트롤러의 /echo-hostname 으로 요청을 전송해보자.
AWS 를 사용하고 있기 때문에, DNS 이름으로 요청한다.
1 | curl a20...3.elb.amazonaws.com/echo-hostname |
404 Not Found 에러가 반환될 것이다. 왜그럴까 ?
Nginx 인그레스 컨트롤러가 jko.example.com 으로 접근할 때만 응답을 처리하도록 설정해서이다.
위에서 작성한 ingress-example.yaml 파일을 수정해보자.
1 | kubectl edit ingress ingress-example |
다시 아래와같이 요청하면, Nginx 인그레스 컨트롤러가 해당 요청을 처리할 것이다.
1 | curl a20...3.elb.amazonaws.com/echo-hostname |
인그레스 컨트롤러 동작 원리
지금까지의 과정은 위와 같다. 정리하면,
- 공식 github 에서 제공하는 YAML file 로 Nginx 인그레스 컨트롤러 생성
- Nginx 인그레스 컨트롤러를 외부로 노출하기 위한 서비스 생성
- 요청 처리 규칙을 정의하는 인그레스 오브젝트 생성
- Nginx 인그레스 컨트롤러로 들어온 요청은 인그레스 규칙에 따라 적절한 서비스로 전달
인그레스 리소스의 상태
그런데 위의 3번에서 인그레스 오브젝트를 생성만 하면,
인그레스 컨트롤러는 자동으로 인그레스를 로드해서 Nginx 웹 서버에 적용한다.
어떻게 이게 가능할까 ?
Nginx 인그레스 컨트롤러는 항상 인그레스 리소스의 상태를 지켜보고 있기 때문이다.
bypass
특정 경로와 호스트 이름으로 유입된 요청은 인그레스에 의해 정의된 규칙에 따라 서비스로 전달된다.
위에서 정의한, ingress-example.yaml 파일을 다시 보면,
1 | ... |
/echo-hostname 으로 유입된 요청이 hostname-service 라는 서비스로 전달되도록 설정되어 있다.
하지만 실제로는, 요청이 실제로 hostname-service 로 전달되지 않고Nginx 인그레스 컨트롤러는 서비스에 의해 생성된 엔드 포인트로 요청을 직접 전달한다.
이러한 동작을 bypass 라고 한다.
시작하세요! 도커/쿠버네티스 <용찬호>