-
[Kubernetes] LoadBalancer 타입 Service 이해하기Kubernetes 2024. 6. 1. 09:27728x90반응형
- 목차
들어가며.
Kubernetes 에서 애플리케이션을 외부에 노출하는 방법 중 하나로 LoadBalancer 타입의 Service 가 있습니다.
이 글에서는 LoadBalancer 서비스의 개념과 동작 방식 그리고 사용 방법까지 다뤄보겠습니다.
특히 KinD 를 사용하여 로컬 환경에서 Kubernetes 를 실행하고, Nginx 를 LoadBalancer 로 활용하는 방법을 또한 설명드리겠습니다.
Service 와 LoadBalancer.
Kubernetes 에서 Service 는 클러스터 내부의 파드(Pod)들을 외부와 연결하는 중요한 역할을 합니다.
서비스 유형에는 ClusterIP, NodePort, LoadBalancer 가 있으며, 그중에서 LoadBalancer 는 외부 로드 밸런서를 생성하여 클러스터 외부에서 접근할 수 있는 엔드포인트를 제공합니다.
Service 종류 간의 포함 관계.
Kubernetes 의 Service 유형들은 서로 포함 관계를 갖고 있습니다.
이 포함 관계는 주로 ClusterIP > NodePort > LoadBalancer 순서로 표현되며,
각각의 서비스 유형은 이전 단계의 기능을 포함하면서 더 넓은 범위로 애플리케이션을 노출합니다.
먼저 NodePort 서비스와 ClusterIP 서비스의 포함 관계에 대해서 알아봅시다.
NodePort 타입의 Service 는 ClusterIP 타입의 기능을 내포하고 있습니다.
NodePort 는 클러스터 외부에서 특정 포트로 노출할 수 있는 기능을 제공하면서도,
클러스터 내부에서의 통신을 위해 ClusterIP 의 기능을 그대로 포함하고 있습니다.
즉, Kubernetes 내부의 통신을 수행하는 ClusterIP 기능 뿐만 아니라 Kubernetes 외부와도 통신할 수 있는 기능을 제공하죠.
그리고 LoadBalancer 타입의 Service 는 NodePort 타입의 기능을 내포하고 있습니다.
LoadBalancer 타입의 서비스는 Kubernetes 외부에 로드 밸런서를 생성하고,
외부 IP 주소와 Kubernetes 의 Node Port 를 연결합니다.
위의 이미지와 유사하게 LoadBalancer 는 쿠버네티스 내부로 네트워크 트래픽을 전송할 수 있습니다.
외부 클라이언트가 LoadBalancer 서비스의 외부 IP 주소에 요청을 보내면, 트래픽은 다음과 같은 단계로 전달됩니다.
- 외부 로드 밸런서 → 클러스터 Node (NodePort): 외부 로드 밸런서가 네트워크 트래픽을 클러스터 노드의 NodePort로 전달합니다.
- Node (NodePort) → 지정된 Pod (targetPort): Node는 내부 ClusterIP의 라우팅 규칙을 기반으로 지정된 파드의 targetPort로 트래픽을 전달합니다.
extraPortMappings 을 통해서 KinD Cluster 구성하기.
아래 링크의 내용을 통해서 기본적인 Kubernetes Cluster 를 Local 환경에 구축할 수 있습니다.
https://westlife0615.tistory.com/407
추가적으로 저희는 LoadBalancer 타입의 서비스를 구현해야하기 때문에
Node 가 외부 네트워크 트래픽을 수신할 수 있도록 KinD Cluster 를 구현해보도록 하겠습니다.
아래 스크립트는 Kubernetes 클러스터를 구성하기 위한 설정 파일로,
KinD Cluster 에 대한 설정 파일을 /tmp/kind_cluster.yaml 위치에 생성합니다.
세부적으로는 각 노드의 역할과 포트 매핑을 설정하며 총 3개의 Worker Node 들을 생성합니다.
cat <<EOF> /tmp/kind_cluster.yaml kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 nodes: - role: control-plane - role: worker extraPortMappings: - containerPort: 30007 hostPort: 30007 protocol: TCP - role: worker extraPortMappings: - containerPort: 30007 hostPort: 30008 protocol: TCP - role: worker extraPortMappings: - containerPort: 30007 hostPort: 30009 protocol: TCP EOF
아래의 스크립트는 kind CLI Command 입니다.
지정된 Cluster Config Yaml 파일을 기반으로 Kubernetes Cluster 를 실행합니다.
kind create cluster \ --name test-cluster \ --image kindest/node:v1.25.0 \ --config /tmp/kind_cluster.yaml
아래 이미지는 Docker Desktop 에서 확인할 수 있는 결과입니다.
모든 Worker Node 의 Docker Container 들이 지정된 Port 를 외부로 노출합니다.
NodePort 타입 Service 구현하기.
쿠버네티스 내부에서 NodePort 서비스를 생성하고 이를 외부 로드밸런서와 연결하는 과정에 대해서 설명해보도록 하겠습니다.
일반적으로 Load Balancer 유형의 서비스는 주로 클라우드 환경의 지원을 통해 구현됩니다.
그러나 로컬 환경에서는 구현이 어려울 수 있어 NodePort 서비스를 외부 Nginx 와 연결하는 방식으로 그 설명을 대체합니다.
먼저 아래의 스크립트를 통해서 Deployment 와 Service 를 생성합니다.
이 Deployment는 간단한 HTTP API 서버를 실행하며, Service는 NodePort 타입으로 생성됩니다.
cat <<EOF> /tmp/loadbalancer.yaml apiVersion: apps/v1 kind: Deployment metadata: name: http-api-server labels: app: http-api spec: replicas: 3 selector: matchLabels: app: http-api template: metadata: labels: app: http-api spec: containers: - name: http-api image: hashicorp/http-echo:1.0 args: - "-text=Hello, Kubernetes!" ports: - containerPort: 5678 --- apiVersion: v1 kind: Service metadata: name: http-api-service spec: type: NodePort selector: app: http-api ports: - port: 5678 targetPort: 5678 nodePort: 30007 EOF
kubectl apply -f /tmp/loadbalancer.yaml
위 스크립트들을 실행하게 되면, Service 와 Deployment 가 생성됩니다.
그리고 생성된 Service 와 Deployment 는 kubectl 명령어를 통해서 확인할 수 있습니다.
kubectl get services NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE http-api-service NodePort 10.96.79.12 <none> 5678:30007/TCP 96m kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 97m kubectl get deployments NAME READY UP-TO-DATE AVAILABLE AGE http-api-server 3/3 3 3 96m
위와 같은 설정을 마치면, 이제 NodePort로 설정된 30007 포트를 통해 HTTP API 서버 Pod와 원활하게 통신하실 수 있습니다.
curl http://localhost:30007
Hello, Kubernetes!
Load Balancer 로 활용할 Nginx 를 실행.
아래 스크립트는 Docker 에서 Nginx 를 실행하여 로컬 환경에서 Load Balancer를 구성하는 과정을 자동화한 것입니다.
cat <<'EOF'> /tmp/nginx.conf events { worker_connections 1024; } http { upstream backend { server host.docker.internal:30007; server host.docker.internal:30008; server host.docker.internal:30009; } server { listen 8080; location / { proxy_pass http://backend; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } } } EOF
upstream backend 블록을 통해서 로드 밸런싱 대상 서버 목록을 정의합니다.
부하를 분산할 서버 목록은 각각 Kubernetes Worker Node 들을 지칭합니다.
host.docker.internal은 Docker 컨테이너가 호스트 머신을 참조하도록 설정하며
여기서 포트 30007, 30008, 30009 로 트래픽을 분산합니다.
docker run -d --name nginx-load-balancer \ -p 8080:8080 \ -v /tmp/nginx.conf:/etc/nginx/nginx.conf:ro \ nginx:latest
이로써 Nginx 로 구현한 로드밸런서에 HTTP Curl 요청을 전송하게 되면,
Kubernetes 내부의 Pod 까지 네트워크 트래픽이 전송되게 됩니다.curl http://localhost:8080
Hello, Kubernetes!
웹 브라우저를 통해서 로드밸런서 서비스의 테스트가 가능합니다.
반응형'Kubernetes' 카테고리의 다른 글
[Kubernetes] PodDisruptionBudget 과 Out of Memory ( OOM ) 관계 알아보기 (0) 2024.06.08 [Kubernetes] last-applied-configuration annotation 알아보기 (0) 2024.04.20 [Kubernetes] HPA 알아보기 ( Horizontal Pod Autoscaler ) (0) 2024.02.16 [Kubernetes] QoS 알아보기 (Quality of Service) (0) 2024.02.04 [KinD] KinD Cluster 로 Docker Image 업로드하기 (kind load docker-image) (0) 2024.02.03