Data science/MLOps

[쿠버네티스] 서비스(Service) 이용하기, 클러스터IP에 접속이 안될 때,

연금(Pension)술사 2022. 12. 10. 02:30

 

요약


쿠버네티스를 이용하면,파드를 통해 클라이언트들이 어플리케이션을 호출할 수 있다. 그러나, 클라이언트 입장에서는 각각 파드의 주소가 존재하는하고, 클라이언트는 어느 파드로 갈지 명시하지 않았는데도, 쿠버네티스가 알아서 각각의 파드가 처리하게 만들어준다. 즉, 네트워킹이 쿠버네티스에 의해서, 알아서 처리되는데, 이 네트워크 서비스를 제공할 수 있는 자원이 "서비스(Service)"이다. 즉, 파드로 실행중인 앱을 네트워크서비스로 노출하게 해주는 자원이다.

 

 

서비스를 이용하기위해 각 파드, 노드가 만족해야할 사항[1]


  • 각 파드는 노드상의 모든 파드와 통신할 수 있어야함
  • 노드상의 에이전트(데몬, kubelet)은 해당 노드의 모든 파드와 통신할 수 있어야함.

 

 

어플리케이션을 네트워크 서비스로 외부에 노출하기


아래와 같이, 디플로이먼트(deployment)와 서비스(Service)를 명시한 yaml파일을 각각 만든다. 

// nginx-svc.yaml

apiVersion: v1
kind: Service
metadata:
  name: my-nginx
  labels:
    run: my-nginx
spec:
  ports:
  - port: 80
    protocol: TCP
  selector:
    run: my-nginx
# run-my-nginx.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-nginx
spec:
  selector:
    matchLabels:
      run: my-nginx
  replicas: 2
  template:
    metadata:
      labels:
        run: my-nginx
    spec:
      containers:
      - name: my-nginx
        image: nginx
        ports:
        - containerPort: 80

 

그리고, 아래와 같이 클러스터 내부에서는  서비스가 가능하고, 각 클러스터의 IP을 확인할 수 있다.

$ kubectl get services
NAME              TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes        ClusterIP   10.96.0.1        <none>        443/TCP        28h
my-nginx          ClusterIP   10.108.171.235   <none>        80/TCP         26h

해당 클러스터의 내부

 

 

Trouble shooting: Cluster IP에 접속이 안될 때 -> Node Port로 외부 클라이언트가 접속할 수 있도록 변경 [2]


서비스하는 클러스터의 IP는 가상의 IP이기 때문에, 클러스터 내부에서 내부로만 서비스할 수 있다. 즉 위의 예시에서처럼 클러스터 IP가 10.108.171.235면, 이 클러스터로 들어가야만 "10.108.171.235:80"의 서비스를 요청하고 받을 수 있는 것이다. 이것을 해결하기, "Cluster IP"을 "Node Port"로 변경해주어야 한다.

Node Port은 외부 클라이언트가 노드로 접속하기 위한 포트를 의미한다. 이 노드 포트을 변경하려면 아래와 같이 kubectl expose을 이용한다.

$ kubectl expose deployment hello-world --type=LoadBalancer --name=example-service

 

expose을 하면 TYPE이 NodePort인 서비스가 하나 생성이된다.  example-serivce라는 이름을 가진 서비스의 TYPE이 NodePort인 것을 잘보자. 이 클러스터의 가상 IP은 10.101.151.252이다. 이것은 여전히 가상IP이기 때문에 서비스를 요청할 수 없다. 다만, 이 노드의 원래주소(localhost, 또는 privateIP, publicIP)로 들어갈때, 30384포트로 요청을하면 알아서 80번으로 바꿔준다. 즉 포트포워딩으로 30384을 80으로 바꿔서 10.101.151.252로 요청해볼 수 있다.

$ kubectl get services
NAME              TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
example-service   NodePort    10.101.151.252   <none>        80:30384/TCP   26h
kubernetes        ClusterIP   10.96.0.1        <none>        443/TCP        28h

$ curl localhost:30384
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

 

 

[1] https://kubernetes.io/ko/docs/concepts/services-networking/

 

서비스, 로드밸런싱, 네트워킹

쿠버네티스의 네트워킹에 대한 개념과 리소스에 대해 설명한다.

kubernetes.io

[2] https://stackoverflow.com/questions/49297226/kubernetes-cluster-ip-service-not-working-as-expected

반응형