Kubernetes Service (NodePort , LoadBalancer)
NodePort Type
Nodeport-service.yaml
apiVersion: v1
kind: Service
metadata:
name: nodeport-service
spec:
type: NodePort
clusterIP : 10.100.100.200
selector:
app: webui
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 30200
Manifest Deploy
위와 같이 작성 후 해당 파일을 배포해줍니다. nodeport를 지정하지 않으면 30000 ~ 32767 사이의 포트가 할당 됩니다.
정상적으로 생성 되었는지 확인해줍니다. PORT를 확인해보시면 Cluster-IP의 80번 포트와 node의 30200 포트가 매핑되어 있는 것을 확인할 수 있습니다.
kubectl apply -f NodePort-service.yaml
kubectl get svc nodeport-service
root@master:~/sample_test# kubectl get svc nodeport-service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nodeport-service NodePort 10.100.100.200 <none> 80:30200/TCP 2m36s
kubectl describe svc nodeport-service
root@master:~/sample_test# kubectl describe svc nodeport-service
Name: nodeport-service
Namespace: default
Labels: <none>
Annotations: <none>
Selector: app=webui
Type: NodePort
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.100.100.200
IPs: 10.100.100.200
Port: <unset> 80/TCP
TargetPort: 80/TCP
NodePort: <unset> 30200/TCP
Endpoints: 10.44.0.5:80,10.44.0.6:80,10.44.0.7:80
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
접속 및 부하분산 테스트
그렇다면 실제 노드의 해당 포트로 접속이 가능한지 테스트 해보도록 하겠습니다. 그러기 위해선 먼저 방화벽이 열려 있어야 합니다. 각 노드로 접속해 방화벽 규칙을 추가해줍니다.
# 우분투
ufw allow 30200/tcp
# CentOS
firewall-cmd --add-port=30200/tcp --permanent
firewall-cmd --reload
Deployment를 통해 배포된 파드가 어떤 노드에 할당되어 있는지 확인해보겠습니다.
kubectl get pods --selector=app=webui -o wide
root@master:~/sample_test# kubectl get pods --selector=app=webui -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
webui-bd76d5967-6kgzp 1/1 Running 0 69m 10.44.0.5 worker <none> <none>
webui-bd76d5967-btqfq 1/1 Running 0 69m 10.44.0.7 worker <none> <none>
webui-bd76d5967-zh9xz 1/1 Running 0 69m 10.44.0.6 worker <none> <none>
제 경우 마스터 노드 1대와 워커 노드 1대를 이용중이다 보니 하나의 워커 노드에 모든 파드가 올라가 있습니다.
해당 노드의 30200 포트로 접속해 파드에서 실행중인 nginx 웹 페이지를 불러오는지 확인해보겠습니다.
root@master:~/sample_test# for i in {1..100}; do curl -s -q 192.168.56.104:30200; done | sort | uniq -c | sort -nr
35 webui #2
34 webui #3
31 webui #1
Cluster-IP Type 과 마찬가지로 로드밸런싱이 가능한듯 합니다. ( 오늘 공부하면서 처음 알게 되었네요 ! )
실제로 해당 노드의 30200 포트로 파드에서 작동중인 nginx 웹서버를 불러올 수 있는것을 확인 했습니다.
clusterip 는 내부 통신용이라면, NodePort 는 외부에서 접근 할 수 있도록 도와주는 용도입니다.
LoadBalancer Type
로드밸런서 타입 서비스는 주로 Public Cloud ( AWS, Azure, GCP ) 등에서 제공해주는 로드밸런서와 함께 사용되고, 로드밸런서의 동적 프로비저닝이 가능하도록 합니다.
현재 VM환경에서 작업중이기 때문에 오픈소스로 제공되는 bare metal load-balancer ( MetalLB ) 를 이용해 실습 해보려고 합니다. MetalLB 설치 관련 글을 참고해주시기 바랍니다.
LoadBalancer-Service.yaml
apiVersion: v1
kind: Service
metadata:
name: loadbalancer-service
spec:
type: LoadBalancer
selector:
app: webui
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 32000
Manifest Deploy
작성한 manifest file을 배포해줍니다.
로드밸런서 타입의 서비스가 생성되고 MetalLB 으로부터 EXTERNAL-IP를 할당 받은 것을 확인할 수 있습니다.
로드밸런서 타입의 서비스를 배포했지만 노드포트가 매핑된 것을 확인할 수 있습니다.
kubectl apply -f LoadBalancer-Service.yaml
root@master:~/sample_test# kubectl get svc
loadbalancer-service LoadBalancer 10.100.67.168 192.168.56.240 80:32000/TCP 31s
부하분산 테스트
root@master:~/sample_test# for i in {1..100}; do curl -s -q 192.168.56.240; done | sort | uniq -c | sort -nr
36 webui #1
32 webui #3
32 webui #2
할당받은 EXTERNAL-IP 로 정상적으로 접근 가능 및 부하분산 되는 것을 확인할 수 있습니다.