backend/kubernetes in action

[kubernetes in action] 5.3. Exposing services to external clients

seul chan 2020. 6. 7. 16:33

5.3. Exposing services to external clients

지금까지는 클러스터 안의 pod들이 어떻게 service에 접근하는지를 다뤘다. 하지만 frontend webserver와 같이 외부에 노출이 필요한 서비스들이 존재한다. (사실 내가 다루는 대부분의 서비스...)

여러 가지 방법으로 외부에서 접근 가능한 서비스를 만들 수 있따.

  • service typeNodePort를 설정: 각 클러스터의 노드는 자신의 포트를 열어 traffic을 service로 리다이렉트
  • service typeLoadBalance로 설정 (extension of the NodePort type):
  • Ingress 리소스 생성(radically different mechanism for exposing multiple services through a single IP address)

Using a NodePort service

kubia-svc-nodeport.yaml

apiVersion: v1
kind: Service
metadata:
  name: kubia-nodeport
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 8080
    nodePort: 30123
  selector:
    app: kubia

다음 예시는 GKE를 기준으로 설명한 것. minikube의 경우 minikube service <serevice_name>로 그냥 띄울 수 있다.

$ kubectl create -f kubia-svc-nodeport.yaml
service/kubia-nodeport created

$ kubectl get svc kubia-nodeport
NAME             TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubia-nodeport   NodePort   172.20.22.132   <none>        80:30123/TCP   13s

node의 IP를 보는방법

$ kubectl get nodes -o jsonpath='{.items[*].status.addresses[?(@.type=="ExternalIP")].address}'
35.167.185.8 52.25.169.64

이제 30123 포트로 어떤 노드로든지 접근이 가능하다. 하지만 첫 번째 노드가 실패하면 클라이언트는 더 이상 service에 접근이 불가능하다. 그래서 node의 앞단에 load balancer를 배치하여 healthy node에만 request를 보내야 하는 이유

Exposing a servic through an external load balancer

대부분의 cloud infrastructure의 kubernetes는 automatic provision을 제공하기 때문에 NodePort 대신 LoadBalance를 사용하기만 하면 된다.

minikube는 LoadBalance를 제공하지 않는다. 아래 예시는 GKE 예시.

kubia-svc-load_balancer.yaml

apiVersion: v1
kind: Service
metadata:
  name: kubia-loadbalancer
spec:
  type: LoadBalancer                1
  ports:
  - port: 80
    targetPort: 8080
  selector:
    app: kubia
$ kubectl get svc kubia-loadbalancer
NAME                 CLUSTER-IP       EXTERNAL-IP      PORT(S)         AGE
kubia-loadbalancer   10.111.241.153   130.211.53.173   80:32143/TCP    1m

$ curl http://130.211.53.173
You've hit kubia-xueq1

Understading thee peculiarities of external connections

외부 클라이언트가 node port를 통해 service에 접속하면 랜덤으로 선택된 pod가 connection을 받는데 이는 같은 노드에 있을수도, 그렇지 않을수도 있다. 그렇지 않을 경우 additional network hop이 발생한다.

service의 설정에서 외부 트래픽의 connection을 받은 node가 해당 노드의 pod에만 redirect되게 가능하다.

spec:
  externalTrafficPolicy: Local
  ...

문제점도 있다.

  • 이 경우 local pod가 선택되는데 local pod가 없으면 커넥션이 global pod로 포워드되지 않고 hang됨
  • 커넥션이 균등하게 분배되지 않음 (노드 2개에 pod가 1개, 2개 있는 경우 각 포드는 50%, 25%, 25%로 나뉘게 될것)