만자의 개발일지

[Kubernetes] Endpoints란 본문

Kubernetes

[Kubernetes] Endpoints란

박만자 2022. 7. 20. 14:57

쿠버네티스에서 Service는 라벨 셀렉터를 사용해 라벨에 해당하는 Pod들을 서비스에 매칭시키는데, 만약 새로 추가된 Pod가 해당하는 라벨을 달고있다면 Service는 해당 Pod로 트래픽을 보내는 방법을 알게됩니다.

이게 가능한 이유는 Service가 실제로는 Endpoints라는 오브젝트에 해당 하는 Pod들을 매핑 시키는데, Service는 이 Endpoints에 매핑된 Pod들의 IP정보를 가지고 Pod에게 트래픽을 전달하게 됩니다. 위 예시처럼 새로 추가된 Pod가 서비스의 라벨을 달고있다면 실제로는 Endpoints에 해당 Pod의 IP가 추가됨으로써 이러한 동작이 가능한 것입니다.

 

Endpoints

Endpoints는 Service가 트래픽을 전달하고자 하는 Pod의 집합입니다.

Endpoints는 실제로 Endpoints Controller에 의해 관리되는데, 이 Endpoints Controller는 마스터 노드의 Controller Manager에 의해 관리됩니다.

Endpoints Controller는 API Server를 감시하고있다가 Service에 유효한 Pod가 추가되면 해당 Pod를 Endpoints 목록에 추가하고, Pod가 삭제되면 해당 Pod를 Endpoints 목록에서 삭제합니다.

 

확인해보자

먼저 다음과 같이 Service(NodePort)를 생성해주었습니다.

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  type: NodePort
  selector:
    app: myapp
  ports:
    - name: http
      nodePort: 30001 
      port: 80 
      targetPort: 80 
      protocol: TCP

 

다음 명령어로 Endpoints를 조회할 수 있습니다.

$ kubectl get endpoints
NAME         ENDPOINTS           AGE	
my-service   <none>              76m

분명 Service는 생성되었는데 Endpoints가 할당되지 않았습니다. Endpoints가 할당되지 않은 이유는 아직 Service의 라벨 셀렉터에 해당하는 Pod가 없기 때문입니다.

 

다음과 같이 Pod를 생성해주었습니다. 해당 Pod는 서비스와 동일한 라벨을 가지고있습니다.

apiVersion: v1
kind: Pod
metadata:
  name: web
  labels:
    app: myapp
spec:
  containers:
    - name: app
      image: nginx

Endpoints Controller는 해당 Pod의 생성을 감지하고 Endpoints 목록에 해당 Pod를 추가합니다.

 

다시 Endpoints를 확인해보니 Endpoints가 추가된 것을 보실 수 있습니다. 

$ kubectl get endpoints
NAME         ENDPOINTS           AGE	
my-service   10.1.0.66:80        83m

이 Endpoints의 IP주소는 Endpoints목록에 추가된 Pod의 IP주소입니다. 

 

실제로 다음 명령어를 통해 확인해보면 Pod의 IP와 Endpoints의 IP가 일치하는 것을 보실 수 있습니다.

$ kubectl describe endpoints my-service | grep Addresses && kubectl describe pod web | grep IP
  Addresses:          10.1.0.66
  NotReadyAddresses:  <none>
IP:           10.1.0.66
IPs:
  IP:  10.1.0.66

 

만약 Pod가 한개가 아니라 여러개인 경우에는 어떻게 될까요?

Pod를 두개 더 추가한 후 Endpoints를 확인해보았습니다.

$ kubectl get endpoints
NAME         ENDPOINTS                                AGE
my-service   10.1.0.66:80,10.1.0.68:80,10.1.0.69:80   90m

Endpoints Controller는 두 Pod의 추가를 감지하고 Endpoints 목록에 해당 Pod들의 IP를 추가합니다. 실제로 IP가 3개로 증가한 것을 보실 수 있습니다.

 

실제로 Service(NodePort)를 생성하게되면 내부적으로는 다음과 같이 동작합니다.

https://stackoverflow.com/questions/52857825/what-is-an-endpoint-in-kubernetes

 

Endpoints 수동 설정

Endpoints는 Endpoints Controller에 의해 자동으로 설정되지만 수동으로 설정해야 하는 경우도 있습니다.

Service에 라벨 셀렉터가 없는 경우에는 Pod를 할당할 수 없기 때문에 Endpoints가 생성되지 않는데, 이 경우에는 Endpoints를 수동으로 생성해야 합니다.

 

Endpoints를 수동으로 생성해야하는 경우(라벨 셀렉터가 없는 Service를 생성해야하는 경우) 예시

  • Service를 통해 클러스터 외부에 있는 서버로 트래픽을 보내야 하는 경우
  • 한 Service에서 다른 Namespace 또는 다른 클러스터의 Service를 지정하려고 하는 경우

 

다음과 같이 셀렉터가 없는 Service와 Endpoints를 생성해 주었습니다.

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  type: NodePort
  ports:
    - name: http
      nodePort: 30001
      port: 80
      targetPort: 80
      protocol: TCP

---
apiVersion: v1
kind: Endpoints
metadata:
  name: my-service
subsets:
  - addresses:
      - ip: 52.78.168.73 # 외부 웹 서버 IP 주소 
    ports:
      - name: http
        port: 80

생성시 주의할점은 Endpoints의 metadata.nameports.name이 Service와 일치해야 합니다.

 

Service의 nodePort로 접속 시 Endpoints의 추가된 외부 웹 서버의 IP 주소로 포워딩 되는 것을 보실 수 있습니다.

참고

Comments