3개의 디플로이먼트에서 애플리케이션이 각각 생성되어 있다고 가정해보자
디플로이먼트들을 외부로 노출하려면 앞서배웠던 NodePort나 LoadBalancer타입의 서비스 3개를 생성해야 한다.
하지만 이 방법은 서비스마다 세부적인 설정(SSL/TLS 보안 연결, 접근 도메인 및 클라이언트 상태에 기반한 라우팅 등)을 할 때 추가적인 복잡성이 발생하게 되어 좋은 방법은 아니다.
인그레스 오브젝트를 사용하면 URL 엔드포인트를 단 하나만 생성함으로써 이러한 번거로움을 해결할 수 있다. 즉 3개의 서비스에 대해 3개의 URL이 각각 존재하는 것이 아닌, 인그레스에 접근하기 위한 단 하나의 URL만 존재한다. 따라서 클라이언트는 인그레스의 URI로만 접근하게 되며, 해당 요청은 인그레스에서 정의한 규칙에 따라 처리된 뒤 적절한 디플로이먼트의 포드로 전달된다.
이 과정에서 중요한 점은 라우팅 정의나 보안 연결 등과 같은 세부 설정은 서비스와 디플로이먼트가 아닌 인그레스에 의해 수행된다는 것이다. 각 디플로이먼트에 대해 일일이 설정을 적용할 필요 없이 하나의 설정 지점에서 처리 규칙을 정의하기만 하면 된다.
인그레스 생성을 위한 YAML파일(ingress-example.yaml) 작성
인그레스 생성 및 확인
# kubectl apply -f ingress-example.yaml
kubectl get ingress
인그레스는 요청을 처리하는 규칙을 정의하는 선언적인 오브젝트일 뿐, 외부 요청을 받아들일 수 있는 실제 서버가 아니기 때문에 인그레스 컨트롤러(Ingress Controller)라고 하는 특수한 서버에 적용해야 이 규칙을 사용할 수 있다. 즉, 실제로 외부 요청을 받아들이는 것은 인그레스 컨트롤러 서버이며, 이 서버가 인그레스 규칙을 로드해 사용한다.
Nginx 웹 서버 인그레스 컨트롤러 설치
# kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.35.0/deploy/static/provider/aws/deploy.yaml
"ingress-nginx" 네임스페이스로 생성된 포드, 디플로이먼트 확인
ingress-nginx 네임스페이스의 디플로이먼트와 포드를 확인해보면 Nginx 웹 서버가 생성되어 있을 것이다
# kubectl get pods,deploy -n ingress-nginx
인그레스 컨트롤러에 접근하기 위한 LoadBalancer 타입의 서비스가 자동으로 생성되었고, DNS 이름을 할당하여 사용할 수 있다
클라우드 환경인 경우 인그레스 테스트를 하기 위해서 LoadBalancer를 통해 Nginx 인그레스 컨트롤러에 접근하면 되지만, 가상머신처럼 클라우드 환경이 아닌 경우 각 노드의 랜덤한 포트로 Nginx 인그레스 컨트롤러에 접근할 수 있도록 NodePort 타입의 서비스를 생성한다
NodePort 타입의 서비스 생성을 위한 YAML파일(ingress-nginx-svc-nodeport.yaml) 작성
NodePort 타입의 서비스 생성 및 확인
# kubectl apply -f ingress-nginx-svc-nodeport.yaml
# kubectl get svc -n ingress-nginx
이제 인그레스, Nginx 인그레스 컨트롤러 및 Nginx 포드에 접근하기 위한 서비스의 준비가 완료되었다. 하지만 아직 인그레스의 종착점이 될 테스트용 디플로이먼트와 서비스를 생성하지 않았으므로 이를 생성해 최종적으로 인그레스의 동작 여부를 확인해보자
테스트용 디플로이먼트 생성을 위한 YAML파일(hostname-deployment.yaml) 작성
테스트용 서비스 생성을 위한 YAML파일(hostname-service.yaml) 작성
테스트용 디플로이먼트와 서비스 생성 및 확인
Nginx 인그레스 컨트롤러로 들어오는 요청은 이 디플로이먼트의 포드들로 분산될 것이다
# kubectl apply -f hostname-deployment.yaml
# kubectl get pods,deploy,svc
Nginx 인그레스 컨트롤러의 /echo-hostname으로 요청 전송
# curl 10.108.111.116/echo-host
"404 Not Found"에러가 뜨는 이유는 앞서 인그레스(ingress-example.yaml)를 생성할 때 Nginx 인그레스 컨트롤러에 alicek106.example.com으로 접근했을 때만 응답을 처리하도록 설정했기 때문이다. 따라서 alicek106.example.com이 아닌 다른 도메인 이름으로 접근할 때는 Nginx 인그레스 컨트롤러가 해당 요청을 처리하지 않는다
curl 명령어의 --resolve 옵션을 통해 임시로 도메인명 설정
# curl --resolve alicek106.example.com:80:10.108.111.116 alicek106.example.com/echo-hostname
정상적으로 요청을 처리한 것을 확인할 수 있다
Nginx 인그레스 컨트롤러는 인증서를 통한 보안 연결 기능을 제공한다. 쿠버네티스 뒤쪽에 있는 디플로이먼트와 서비스가 아닌, 앞쪽에 있는 인그레스 컨트롤러에 인증서를 적용해두면 요청이 전달되는 애플리케이션에 대해 모두 인증서 처리를 할 수 있다
보안 연결에 사용할 인증서와 비밀키 생성
(호스트명 앞에 있는 문자는 대문자 O)
# openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout tls.key -out tls.crt -subj "/CN=<퍼블릭 DNS이름>/O=<호스트명>"
tls.key(비밀키)와 tls.crt(인증서)가 생성되었을 것이다. 이 파일들을 통해 tls타입의 시크릿을 생성해보자
TLS타입의 시크릿 생성
# kubectl create secret tls tls-secret --key tls.key --cert tls.crt
# kubectl describe secret tls-secret
인그레스 설정 추가
ingress-example.yaml(처음 인그레스 생성 때 사용했던) 파일을 열어서 spec.tls 내용을 추가하고 생성한다
# kubectl apply -f ingress-example.yaml
HTTPS로 접속
# curl https://jhb.example.com/echo-hostname -k
HTTPS로 접근했을 때에도 정상적으로 데이터를 반환하는 것을 확인할 수 있다
(인증서를 통해 보안 연결을 설정했을 때는 HTTP로 접근해도 자동으로 HTTPS로 리다이렉트된다)
'쿠버네티스' 카테고리의 다른 글
쿠버네티스 컨피그맵 설정값을 포드에 전달하기 + 파일로부터 컨피그맵 생성 (0) | 2021.05.07 |
---|---|
쿠버네티스 서비스(Service)를 이용해 포드를 외부에 노출 (0) | 2021.04.28 |
kops를 이용해 AWS에 쿠버네티스 설치 (0) | 2021.04.28 |
쿠버네티스 디플로이먼트(Delpoyment) 사용하기 (0) | 2021.04.27 |
구글 클라우드(GCP)에 쿠버네티스 연동하기 (0) | 2021.04.26 |