5.3. Exposing services to external clients
지금까지는 클러스터 안의 pod들이 어떻게 service에 접근하는지를 다뤘다. 하지만 frontend webserver와 같이 외부에 노출이 필요한 서비스들이 존재한다. (사실 내가 다루는 대부분의 서비스...)
여러 가지 방법으로 외부에서 접근 가능한 서비스를 만들 수 있따.
service type
을NodePort
를 설정: 각 클러스터의 노드는 자신의 포트를 열어 traffic을 service로 리다이렉트service type
을LoadBalance
로 설정 (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%로 나뉘게 될것)