nayoungs
항상 끈기있게
nayoungs
  • 분류 전체보기 (274)
    • Cloud (21)
      • AWS (15)
      • Azure (3)
      • NCP (2)
      • GCP (1)
    • DevOps (68)
      • Docker (16)
      • Kubernetes (50)
      • CICD (2)
    • IaC (25)
      • Ansible (17)
      • Terraform (8)
    • Certification (4)
    • 금융 IT (5)
    • AI (3)
    • Linux (47)
    • 미들웨어 (5)
    • Programming (7)
      • GoLang (3)
      • Spring (4)
    • CS (25)
      • 네트워크 (17)
      • 운영체제 (5)
      • Web (1)
      • 개발 상식 (2)
      • 데이터베이스 (0)
    • Algorithm (59)
      • 프로그래머스 (36)
      • 백준 (18)
      • 알고리즘 정리 (5)
    • ETC (5)

블로그 메뉴

  • 홈
  • 방명록

공지사항

인기 글

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
nayoungs

항상 끈기있게

DevOps/Kubernetes

[Kubernetes] Service : Load Balancer

2022. 5. 22. 05:45
728x90

✔️ Service : LoadBalaner 타입

LoadBalancer 타입은 Nodeport 타입의 확장판이라고 할 수 있으며, 서비스를 외부에 노출 시킬 수 있다.

LoadBalaner 타입을 사용하는 경우, ClusteIP와 NodePort기반의 구성이 되는데

즉, LoadBalancer = ClusterIP + NodePort + LoadBalancer 라고 할 수 있다.

 

 

https://kim-dragon.tistory.com/52

 

NodePort타입 앞단에 Loadbalancer가 붙어서 살아있는 노드를 체크하여 트래픽을 전달 할 수 있는 장점이 있다.



💻실습 

 

myweb-svc-lb.yaml

apiVersion: v1
kind: Service
metadata:
  name: myweb-svc-lb
spec:
  type: LoadBalancer
  selector:
    app: web
  ports:
    - port: 80
      targetPort: 8080    
      nodePort: 31313

myweb-rs.yaml

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: myweb-rs
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
      env: dev
  template:
    metadata:
      labels:
        app: web
        env: dev
    spec:
      containers:
        - name: myweb
          image: ghcr.io/c1t1d0s7/go-myweb
          ports:
            - containerPort: 8080
              protocol: TCP
$ kubectl create -f .

Type이 LB인 것과, 포트 31313이 할당된 것, EXTERNAL-IP가 pending 상태인 것을 확인할 수 있다.

$ kubectl get svc    
NAME           TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubernetes     ClusterIP      10.233.0.1      <none>        443/TCP        38h
myweb-svc-lb   LoadBalancer   10.233.19.105   <pending>     80:31313/TCP   22s

여기서 EXTERNAL_IP는 클러스터 외부의 것으로, 쿠버네티스 자체에서 설정 할 수 없다.

클라우드를 연동하여 실제 외부에 로드 밸런서를 만들거나, 다른 방법을 이용하여 로드밸러서 기능을 구성해야한다.

 

METALB - Addon

 

본 실습에서는 클라우드 로드밸런서 대신, METALB 오픈소스를 사용해보자.

METALB는 베타버전이지만 실제로 프로덕션 환경에 많이 사용되며,

국내에서도 많이 사용되는 오픈소스이다.

bare metal 시스템 k8s 클러스터에서 로드밸런서를 구현해주는 것으로,

로드밸런서 기능을 하는 파드를 띄운다.

 

설치형을 사용하는 경우 직접 홈페이지 설명에 따라 METALAB을 설치할 수 있지만,

Kubespray에서 기능을 제공하므로, Kubespray를 이용해보자.

 

먼저 다음을 보고 kubespray 파일에서 몇가지를 수정한다.

kubespray/inventory/mycluster/group_vars/k8s_cluster/addons.yml

...
138 # MetalLB deployment
139 metallb_enabled: true #true로 수정
140 metallb_speaker_enabled: true
141 metallb_ip_range:     #주석 해제
142   - "192.168.100.240-192.168.100.249" #범위 수정
...
168 metallb_protocol: "layer2" #주석 해제
...

~/kubespray/inventory/mycluster/group_vars/k8s-cluster/k8s-cluster.yml

# configure arp_ignore and arp_announce to avoid answering ARP queries from kube-ipvs0 interface
# must be set to true for MetalLB to work
kube_proxy_strict_arp: true

파일을 수정 후, 다시 플레이북을 다시 실행하면 된다.

$ cd kubespray
$ ansible-playbook -i inventory/mycluster/inventory.ini cluster.yml -b

 

☁️참고

MetalLB는 2가지 모드 layer2와 BGP모드가 있고, default는 layer2이다.

  • layer2
    • 먼저 데몬셋 형태로 모든 노드에 speaker라고하는 파드가 생성된다.
    • 이때, speaker와 함께 하나의 controller 파드가 설치된다.
    • NodePort가 speaker 파드로 연결되고, speaker 파드들은 controller로 연결된다.
    • controller파드가 로드밸런서 역할을 하게되는데, 앞서 설정했던 addons.yml의 IP 범위 192.168.100.240-192.168.100.249 중 하나를 로드밸런서가 사용하게된다.
    • 외부에서 이 로드밸런서의 IP로 접속하게되면, 어느 노드든 상관없이 speaker를 통해 controller로 연결되고, controller는 다시 NodePort(여기서는 31313)로 분배해준다.
    • 그리고 NodePort가 내부의 실제 서비스로 다시 연결해준다.
    • 최종적으로 이 서비스가 다시 파드로 연결시켜준다.

순서만 간략하게 나타내면 다음과 같다.

외부에서 접속 -> NodePort -> speaker 파드 -> controller 파드 -> NodePort -> 실제 서비스 -> 파드

정리하자면 로드밸런서를 외부에 두지 않고, 내부에 파드로 구현시킨 형태가 layer2라고 할 수 있다.

(그림 대충 그린점 양해부탁드립니다)

 

  • BGP
    • L3스위치(스위칭 기능을 가진 라우터)를 사용하며, 이 라우터가 로드밸런싱 기능을 가진다.
    • 외부에서 라우터의 IP로 접속하면 실제 서비스로 연결 시켜준 뒤, 서비스가 파드로 연결시켜준다.

https://cyuu.tistory.com/170

 

설치가 완료되면 metallb-system이라는 네임스페이스가 생성된 것을 확인할 수 있다.

$ kubectl get ns 
NAME              STATUS   AGE
...
metallb-system    Active   48m

speaker 파드와 controller 파드가 생성된 것을 확인할 수 있다.

$ kubectl get po -n metallb-system 
NAME                         READY   STATUS             RESTARTS   AGE
controller-77c44876d-dbcx5   1/1     Running            0          49m
speaker-7jgsg                0/1     ImagePullBackOff   0          49m
speaker-jkfcg                1/1     Running            0          49m
speaker-vzw82                0/1     ImagePullBackOff   0          49m

speaker 파드를 생성하는 데몬셋도 확인할 수 있다.

$ kubectl get ds -n metallb-system 
NAME      DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR            AGE
speaker   3         3         1       3            1           kubernetes.io/os=linux   50m

speaker 파드에는 호스트의 IP가 부여되고, controller가 실제 로드밸런서 역할을 한다.

$ kubectl get po -n metallb-system -o wide
NAME                         READY   STATUS             RESTARTS   AGE   IP                NODE    NOMINATED NODE   READINESS GATES
controller-77c44876d-dbcx5   1/1     Running            0          52m   10.233.92.248     node3   <none>           <none>
speaker-7jgsg                0/1     Running            0          52m   192.168.100.100   node1   <none>           <none>
speaker-jkfcg                1/1     Running            0          52m   192.168.100.102   node3   <none>           <none>
speaker-vzw82                0/1     Running            0          52m   192.168.100.101   node2   <none>           <none>

이제 myweb-svc-np 서비스에 EXTERNAL-IP가 부여된 것을 확인할 수 있다.

$ kubectl get svc                         
NAME              TYPE           CLUSTER-IP      EXTERNAL-IP       PORT(S)        AGE
myweb-svc-lb      LoadBalancer   10.233.19.105   192.168.100.240   80:31313/TCP   3h10m

접속 확인

$ curl 192.168.100.240
Hello World!
myweb-rs-h8jg5

외부에서도 접속 가능한 것을 확인할 수 있다.

 

로드밸런서는 NodePort기능과 ClusterIP기능도 포함하기 때문에

NodePort로도, ClusterIP로도 접속이 가능한 것을 확인할 수 있다.

$ curl 192.168.100.100:31313
Hello World!
myweb-rs-jwvbh
$ kubectl run nettool -it --image ghcr.io/c1t1d0s7/network-multitool --rm

If you don't see a command prompt, try pressing enter.
/ # curl myweb-svc-lb
Hello World!
myweb-rs-jwvbh

로드밸런서 확인

$ sudo ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  169.254.25.10:31313 rr
  -> 10.233.90.71:8080            Masq    1      0          0         
  -> 10.233.92.249:8080           Masq    1      0          0         
  -> 10.233.96.84:8080            Masq    1      0          0         
TCP  192.168.100.100:31313 rr
  -> 10.233.90.71:8080            Masq    1      0          0         
  -> 10.233.92.249:8080           Masq    1      0          0         
  -> 10.233.96.84:8080            Masq    1      0          0         
TCP  192.168.100.240:80 rr
  -> 10.233.90.71:8080            Masq    1      0          0         
  -> 10.233.92.249:8080           Masq    1      0          0         
  -> 10.233.96.84:8080            Masq    1      0          0         
...
TCP  10.233.19.105:80 rr
  -> 10.233.90.71:8080            Masq    1      0          0         
  -> 10.233.92.249:8080           Masq    1      0          0         
  -> 10.233.96.84:8080            Masq    1      0          0         
TCP  10.233.90.0:31313 rr
  -> 10.233.90.71:8080            Masq    1      0          0         
  -> 10.233.92.249:8080           Masq    1      0          0         
  -> 10.233.96.84:8080            Masq    1      0          0         
...





 

728x90
저작자표시 비영리 (새창열림)
    'DevOps/Kubernetes' 카테고리의 다른 글
    • [Kubernetes] k8s Ingress란? (feat. 도메인 없이 테스트하기)
    • [Kubernetes] Service : ExternalName
    • [Kubernetes] Service : NodePort
    • [kubernetes] Service Discovery란? (feat.nodelocal DNS)
    nayoungs
    nayoungs
    안되면 될 때까지

    티스토리툴바