Nginx & WSGI pod를 service로 노출하기
Last updated
Last updated
최초작성일 [2020.03.18]
아래와 같은 구조로 쿠버네티스의 service를 생성하려고 한다. (replicaset 또는 deployment를 미리 생성해야 한다.)
WSGI 프로세스는 아래의 configuration으로 작동한다. 포트번호 9090을 통해 트래픽을 받아 flask 애플리케이션으로 전달한다.
WSGI는 nginx를 통해 들어오는 트래픽만을 허용하므로 service 타입은 ClusterIP
로 선택한다. ClusterIP
타입은 pod를 클러스터 내부에 한정하여 노출하려고 할 때 사용한다.
위에서 작성한 템플릿 service-app.yml
을 클러스터에 적용한다.
metadata.name
의 값에 맞게 service-flask-wsgi
라는 서비스가 생성되었다. CLUSTER-IP
필드의 IP주소는 클러스터 내부에서 해당 서비스에 접근하는 용도로 쓰인다. 즉, 클러스터 외부에서는 CLUSTER-IP
필드의 주소로 접근할 수 없다.
kubernetes
라는 서비스가 이미 있는 것을 볼 수 있다. kubernetes
서비스는 pod 내부에서 쿠버네티스의 API에 접근하기 위한 용도로 쓰인다.
nginx.conf
는 아래와 같다. Nginx가 업스트리밍하는 서버의 주소가 위에서 생성한 서비스의 이름에 해당하 service-flask-wsgi
인 것을 알 수 있다. 쿠버네티스 애플리케이션에는 service나 pod와 같은 리소스를 쉽게 찾을 수 있도록 리소스의 이름을 레코드로 관리하는 내부 DNS가 있다. 그리고 pod들은 이 DNS에 주소를 질의하기 때문에 service의 이름을 주소로 사용할 수 있다.
Nginx pod를 클러스터 외부에 노출하기 위해 아래와 같은 템플릿을 작성한다. NodePort
타입은 모든 노드의 특정 포트를 개방하여 외부에서 서비스에 접근하도록 허용한다. 아래의 service는 모든 노드에 포트번호 80번을 개방한다.
위에서 작성한 템플릿 service-nginx.yml
을 클러스터에 생성한다.
service-my-nginx
라는 이름으로 service가 생성된 것을 확인할 수 있다. service 타입이 NodePort
였음에도 CLUSTER-IP
가 만들어진 것을 볼 수 있는데, NodePort
타입의 service가 ClusterIP
타입의 기능을 포함하기 때문이다. 따라서 NodePort
타입으로 생성한 서비스는
클러스터 내부에서 CLUSTER-IP
또는 service 이름을 통해 접근할 수 있고
클러스터 외부에서 노드의 IP를 통해 접근할 수 있다.
PORT(S)
의 값은 <클러스터 내부에서 접근할 때 쓰는 포트번호>:<클러스터 외부에서 접근할 때 쓰는 포트번호>
로 되어있다.
클러스터 내부에서 service-my-nginx
에 접근해보자. 클러스터 내부의 워커 노드 중 하나에 접속하여 curl
을 실행했다. IP주소는 CLUSTER-IP
에 해당하는 100.68.131.17
이고 포트번호 8080
으로 접근한다.
이번에는 클러스터 외부에서 service-my-nginx
에 접근한다. 워커 노드의 퍼블릭IP주소와 함께 포트번호는 31085
으로 접근한다. 내/외부 IP주소를 포함한 노드의 정보를 조회하고 싶다면 아래의 커맨드를 실행한다.
위 커맨드에서 조회한 노드의 퍼블릭 IP주소로 curl을 실행한다.
참고
attribute
usage
selector
외부로 노출시키려는 pod의 라벨을 식별한다. (label selector 참고.)
ports.port
서비스가 생성되면 서비스는 클러스터 내부에서만 사용할 수 있는 고유한 IP를 가지게 된다. 서비스의 IP에 접근할 때 ports.port
에 해당하는 값을 포트번호로 쓴다.
ports.targetPort
selector에 정의된 라벨에 해당하는 pod들이 사용하는 포트번호. replicaset 템플릿에서 지정한containerPort
의 값과 같아야 한다.