갬미의 성장일기

Day 46 - 쿠버네티스 서비스, 로드밸런서 본문

Cloud/Cloud 공부일기

Day 46 - 쿠버네티스 서비스, 로드밸런서

갬미 2022. 3. 16. 18:02

오늘 배운 내용

- 쿠버네티스 서비스

- gke, eks 로드밸런서

 

쿠버네티스 서비스

쿠버네티스 서비스 타입에는 3가지가 존재한다

1. ClusterIP : Default Type, 클러스터 안에서만 통신 가능

2. NodePort : node ip를 통해 외부 접속이 가능하다, Clusterip의 기능도 포함 된다

3. LoadBalancer : 서비스에 외부 접속이 가능한 대표 ip를 제공, 클라우드 서비스 프로바이더 (csp)를 사용하는경우 가능한 기능이다

공식 문서 설명

 

Service

An abstract way to expose an application running on a set of Pods as a network service. With Kubernetes you don't need to modify your application to use an unfamiliar service discovery mechanism. Kubernetes gives Pods their own IP addresses and a single DN

kubernetes.io

 

2. NodePort

Node의 ip를 통해 서비스에 접속되기 때문에 node를 만들어야 한다 

나는 클러스터를 만들으면서 3개가 만들어졌기 때문에 그걸 활용할 예정

 

Service.yml을 다음과 같이 생성한다

apiVersion: v1
kind: Service
metadata:
  name: java-svc
spec:
  selector:
    app: java
  ports:
  - port: 80
    targetPort: 80
  type: NodePort

서비스에 활용할 pod를 만든다

apiVersion: v1
kind: Pod
metadata:
  name: sysinfo
  labels:
    app: java
spec:
  containers:
  - name: java
    image: gymin97/msa:sysinfo_v1
    ports:
      - containerPort: 80

apply 하면 다음과 같이 서비스가 생기며, 접속할 수 있는 포트가 주어진다

NodeIP:31976 -> 접속이 됨

 

pod를 rs를 통해 만들지 않았기때문에 1개만 만들어졌고, 이 pod는 3개의 노드중 하나에 배치되었다

 

pod가 있는 node와 pod가 없는 노드에 각각 접속해도 pod가 작동한다 (node ip를 통해 서비스 pod에 접속하는것이기 때문) 

이 두가지 경우에 무슨 차이가 있을까?

해당 노드에 있는 pod가 응답한 경우
해당 노드에 없는 pod가 응답 한 경우

접속한 pod의 remote addr은 게이트웨이의 ip

다른 노드로 들어간경우 - node의 ip 가 출력된다

 

이유는 다른 노드로 들어갔을경우에 다시 pod가 있는 곳으로 옮겨가는 과정이 필요하기 때문이다 

ip가 바뀌는 이유는 node에서 통신할때 proxy통신을 하기 때문인데, 이는 아래에서 설명하겠다 

 

서비스에 접속할때 다른 node에 접속했다가 pod를 찾아가는 과정을 거친다면 바로 pod가 있는 node에 들어가는것 보다 레이턴시가 발생할 수 있다

 

이런 지연을 방지하기 위해서 Service.yml을 만들때 ExternalTrafficPolicy 라는 옵션을 사용할 수 있다

apiVersion: v1
kind: Service
metadata:
  name: java-svc
spec:
  selector:
    app: java
  ports:
  - port: 80
    targetPort: 80
    nodePort: 30100
  type: NodePort
  externalTrafficPolicy: Local

아니면 

kubectl edit svc java-svc 해서 다음을 변경한다

파드가 없는 노드는 접속이 안된다

이때 ip는 클라이언트의 ip가 보존되어 보여진다

ExternalTrafficPolicy는 접속한 노드에 있는 pod만 보여주겠다는 말이다 

그렇기때문에 pod가 없는 node에는 접속되지 않고, pod가 있는 node에서는 pod에 바로 연결된다

 

2-1. NodePort에 LB붙이기 (클라우드 플랫폼 이용)

Node의 IP를 하나하나 기억해서 port를 붙이고 접속하고,, 서비스 배포에는 너무 번거로운 작업이다

이런일을 막고자 로드밸런서가 필요하다

Service를 만들때 yml파일에서 type에 로드밸런서를 줘도 되지만 csp를 사용하지 않는 경우

- nodeport들로 서비스를 만든다음에 이를 묶는 LB를 수동으로 만든다

- 예를 들어 nginx를 하나 만들어 여기에 node를 proxy한다 

- L4 장비를 이용한다

LB 만들어 보기

GCP의 경우에

1. instance group 만들어야 한다 (백엔드가 될 node를 묶어줘야 함)

로드밸런서 ip로 잘 접속이 된다

 

ip가 정말 제각각이다 그 이유는

통신 방법의 차이

통신 모드에는 Proxy mode와 None proxy mode가 있다 

Proxy mode - 클라이언트가 서버에 접속할때 일단 프록시에 접속 이때 session이 생김

proxy에서 서버로 가는 session이 또 생김 (A-B | B-C)

None proxy mode - 같은 node가 아닌경우 그 node로 간다 (경로를 따라서) 

라우팅은 패킷의 S/D가 안바뀌지만

프록시 모드는 패킷의 S/D가 바뀐다 

 

remoteaddr이(client 정보) 나의 ip가 아닌경우에는 proxy를 거쳤다고 생각하면 된다 

 

나는 node만 거쳤는데 왜 ip가 바뀌냐고요~

node에도 proxy가 있어서 다른 ip가 보인다

위의 사진을 다시 보면 

node proxy를 안거쳤을때
node proxy를 거쳤을때
로드밸런서 proxy를 거쳤을때 
아무 proxy를 안거쳤을때

 

LoadBalancer

방금은 수동으로 GCP - Network Service - LoadBalancer를 붙여주었지만

service yaml에서 type : LoadBalancer를 주면 자동으로 LB가 생긴다

apiVersion: v1
kind: Service
metadata:
  name: sysinfo-svc
spec:
  selector:
    app: java
  ports:
  - port: 80
    targetPort: 80
    nodePort: 30200
  type : LoadBalancer

결국에는 수동 nodeport + LB랑 같은 것임!

 

두가지를 비교해보면

 

 

LB 전달하는 알고리즘 

Proxy vs None-proxy 상황 보기

가정: client(a) ------- LB(b) ------- SVC(c) ------ pod(d)

패킷의 최종 source를 보면

LB ∖ SVC Proxy None-proxy 
Proxy C B
None-proxy  C A

client ip를 알기위해서는 모두가 none-proxy 여야 할 수 있다 

 

gke의 LB는 proxy 전달 알고리즘이다 (application)

eks의 LB는 none-proxy 알고리즘이다 (NLB) 

 

클라우드 서비스별로 LB 전달 알고리즘이 다르다

 

어떤 방식이 더 옳다고는 할 수 없다!

 

오늘의 회고

  • 오늘은 어제보다 더 어려웠다 ,,,,, 내가 아직 node pod service 이런 개념이 확 박혀있지 않아서 그런 것 같은데 오늘 정리를하면서 조금 더 확실하게 알게되었다!
  • 아까 node부분이 너무 이해가 안되어서 엄청 고민했는데 다시 한번 보면서 정리가 되었다 
  • 어렵지만 재미있다~ 다행이다 
Comments