노드 포트란 애플리케이션을 외부로 노출하기 위한 kind : Service
로 type : NodePort
를 통해서 지정하게 된다.
노드 포트는 VM의 노드 포트(nodePort)를 통과해 서비스(port)에서 선택되는 파드의 내부 애플리케이션(targetPort)까지 트래픽을 전달하는 유형의 서비스다.
노드 포트를 통해 클러스터 내부로 들어온 트래픽을 내부의 특정 파드로 연결하기 위한 ClusterIP 역시 자동으로 생성된다.
nodePort
: 외부에서 노드포트로 노출된 애플리케이션에 접속하기 위해 가장 먼저 통과되는 포트 port
: nodePort
를 통해서 들어온 트래픽이 서비스로 들어오기 위한 포트 (서비스를 노출하는 포트)targetPort
: 파드에서 애플리케이션으로 들어가기 위한 포트<접속할 노드 IP>:<nodePort>
를 통해 해당 노드(VM)를 통과한다.🎈[TIP]
이 때<접속할 노드 IP>
를 사용자가 직접 지정해야 한다.
이를 직접 지정하지 않고, 자동으로 지정하는 방법이 바로 로드밸런서이다.
port
를 통해서 클러스터 내부의 서비스에 도착한다.<해당 파드의 IP>:<targetPort>
로 전달한다.노드 포트를 배포하기 위해서 다음과 같이 yaml
파일을 설정해 주도록 하자.
노드포트에서 관리하게 될 파드의 레이블을 NodePort쪽의 selector에 app : deploy-nginx
로 동일하게 작성해주면 해당 Deployment로 배포된 파드들은 NodePort를 통해서 외부에서 접근할 수 있게 된다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-nginx
labels:
app: deploy-nginx
spec:
replicas: 3
selector:
matchLabels:
app: deploy-nginx
template:
metadata:
labels:
app: deploy-nginx
spec:
containers:
- name: nginx
image: nginx
---
apiVersion: v1
kind: Service
metadata:
name: np-nginx
spec:
selector:
app: deploy-nginx
ports:
- name: http
port: 80
targetPort: 80
nodePort: 30000 #option
type: NodePort
이를 통해 모든 노드가 노드 포트 30000번으로 노출 되었으므로, 각 노드의 INTERNAL-IP : 30000
을 통해서 접속해보자.
여기서 주의할 점은, 노드 포트 서비스로 노출했다고 해서 노드 포트의 내부 아이피인 CLUSTER-IP
를 사용해서 접근하는 것이 아니다.
노드에 대해서 접속을 열어준 "노드 포트" 이므로 노드의 INTERNAL-IP
로 접근해야 한다.
노드 포트는 클러스터 내의 모든 노드에 대해서 지정된 포트 30000
번을 열어주게 되므로, 워커노드는 물론이고, 마스터 노드의 주소인 192.168.1.10:30000
을 사용해서 접속해도 접속이 가능하다.
로드 밸런서란 노드들의 앞에 하나의 스위치 역할을 하는 문을 추가하여 기존 사용자가 노드 포트에서 직접 어떤 노드IP로 접속할지를 지정했던 것을 대신 해준다.
기존 <접속할 노드 IP>:<nodePort>
에서 접속할 노드 IP를 로드밸런서를 통해서 자동으로 지정해주는 것이다.
로드 밸런서의 사용을 통해 서비스의 가용성을 높이고, 특정 노드에 과부하가 발생하는 것을 방지할 수 있다.
port
를 통해서 Service로 전달.<해당 파드의 IP>:<targetPort>
를 통해서 Pod의 애플리케이션으로 접속이번에는 2개의 로드밸런서를 만들어보도록 하자.
하나는 IP를 체크하는 용도, 하나는 nginx에 접속하는 용도로 사용된다.
이를 그림으로 확인해보면 다음과 같다.
총 6개의 파드가 구성되고, 2개의 로드밸런서가 각각의 파드들에 대해서 동작하는 것을 확인할 수 있다.
k get po -n metallb-system -o wide
다음과 같이 metallb-system
의 네임스페이스에 metallb를 통해서 로드밸런싱을 하기 위한 필수적인 파드들이 배포되어 있는 것을 확인할 수 있다.
컨트롤러(controller)
: 외부에서 들어오는 트래픽을 처리하고, 노드들을 관리스피커(Speaker)
: 로드 밸런서와 각 노드 간의 네트워크 라우팅을 담당. 로드 밸런서로 들어온 트래픽을 노드로 전달하는 것을 수행
배포를 완료한 뒤 확인해보자.
## 배포 코드는 생략
k get service -o wide
이제 접속하여 확인해보자.
http://192.168.1.11
인 lb-nginx 로드밸런서의 EXTERNAL-IP
로 접속했을 때 웹 페이지로 잘 접속되는 것을 확인할 수 있다.
lb-chk-ip 로드밸런서의 EXTERNAL-IP
로 접속했을 때, 도착한 목적지 IP를 확인할 수 있고, 이는 접속할 때마다 지속적으로 변경된다.
변경되는 이유는 바로 노드포트 서비스에서 kube-proxy의 iptables
또는 ebpf
기술에 의해서 접속되는 Endpoint
가 변경되어 접속되는 파드가 지속적으로 변경되는 것이다.
🧐 관련 질문
가장 먼저 서비스의 가용성을 높일 수 있다.
로드 밸런서를 사용하면, 배포된 (파드-애플리케이션)서비스 간에 네트워크 트래픽을 고르게 분산시킬 수 있다.
만약 NodePort를 계속해서 사용한다면, NodePort는 외부 접근을 위한 서비스로 사용할 때 제한되는 사항이 있다.
- NodePort는 특정 포트 범위 내에서만 사용할 수 있음.
- 노드의 IP 주소가 변경되면 이를 알고, 직접 또 다시 변경된 IP 주소로 접속해야함.
Ingress와 같은 로드 밸런서는 고급 라우팅 기능을 제공한다.
(ex.URL 기반 라우팅이나 SSL 종료와 같은 기능)
따라서, 클러스터 IP 서비스가 내부적으로 트래픽을 분산시키는 데 도움이 되지만, 로드 밸런서는 외부 접근, 고가용성, 확장성, 그리고 고급 라우팅 기능과 같은 추가적인 이점을 제공한다.