ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 클라우드: 쿠버네티스 서비스(Service) ClusterIP와 NodePort 실습하기
    K8S 2021. 2. 18. 23:17

    이전의 경우에서는 kubectl describe 커맨드로 포드의 내부의 IP를 찾고, 마스터노드를 통해 포드에 직접 접근했다. 

     

     

    네트워크: 쿠버네티스 포드(Pod) 오브젝트 사용하기

    쿠버네티스는 대부분의 리소스를 오브젝트 형태로 관리한다. 쿠버네티스의 컨테이너의 집합(pods), 컨테이너의 집합을 관리하는 컨트롤러(replica set) 사용자(service account), 노드(node)등이 하나의 오

    seungjuitmemo.tistory.com

     

     

    하지만 이러한 방법은 쿠버네티스 클러스터 내부 또는 로컬을 통해서만 사용할 수 있다. 

     

    또한 포드의  IP는 계속 바뀔 수 있으므로, 하나의 어플리케이션으로 연동시킬려면 IP를 이용한 접근이 아닌 다른 방법이 

    필요하다. 

     

    이전에 포드를 생성할때 containerPort 항목에 포트를 지정해서 포드를 정의하였다.

     

    yaml파일에 포트를 지정했다고 해서 이 포드가 외부로 노출되는 것은 아니다.

     

    외부 사용자들이 이 포드에 접근하거나,

    내부 포드들이 이 포드에 접근하려면 서비스(Service)라는 오브젝트를 생성해야 한다.

     

     

    서비스의 주요 기능은 다음과 같다. 

     

    - 고유의 도메인 이름을 정해서 여러개 포드에 쉽게 접근할 수 있도록 한다.

    - 포드를 외부로 노출시킨다. 

    - 로드 밸런서로써 사용된다.

     

     

    서비스에 대해서 자세히 알아보기 위해 실습을 하나 해본다.

     

    우선 디플로이먼트 yaml파일을 만든다.

     

    < deployment-hostname.yaml >

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: hostname-deployment
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: webserver
      template:
        metadata:
          name: my-webserver
          labels:
            app: webserver
        spec:
          containers:
          - name: my-webserver
            image: alicek106/rr-test:echo-hostname
            ports:
            - containerPort: 80
    

     

     

    kubectl apply -f deployment-hostname.yaml

     

     

    디플로이먼트에 의해 만들어진 포드들의 IP를 확인한다. 

     

    kubectl get pods -o wide

     

     

     

    다음과 같이 ubuntu2 워커노드에서 각 포드에 접근할 수 있음은 자명하다. 

     

     

     

     

     

    이제부터 본격적으로 포드에 접근할 수 있는 규칙을 서비스를 통해서 새롭게 생성한다.

     

    서비스에는 여러가지 타입이 있는데 주로 사용하는 서비스 타입은 크게 3가지이다.

     

    - CluserIP: 클러스터 내부에서만 포드들에 접근할 때 사용한다. 

    - NodePort: 클러스터의 모든 노드들에게 포드에 접근할 수 있는 포트를 개방한다. 즉 외부에서 포드로 접근할 수 있게 된다.

    - LoadBalancer: 클라우드 플랫폼에서 제공하는 로드밸러서를 동적으로 프로비저닝하여 포드에 연결한다. 

     Nodeport와 마찬가지로 외부에서 접근할 수 있는 기능을 제공하며 AWS, GCP등과 같은 환경에서만 사용가능하다. 

     

    이번 실습에서는 로드밸랜서는 온프레미스환경에서는 사용하기 힘드므로 clusterip와 Nodeport만 실습해본다. 

     

     

     

     

    1. CluserIP 서비스를 이용한 실습

     

    클러스터 내부에서만 포드에 접근할 때 사용한다.

     

    다음과 같이 service yaml파일을 만든다. 

     

    < hostname-svc-clusterip.yaml >

    apiVersion: v1
    kind: Service
    metadata: 
      name: hostname-svc-clusterip
    spec: 
      ports:
      - name: web-port
        port: 8080
        targetPort: 80
      selector:
        app: webserver
      type: ClusterIP
    

     

    port는 서비스 자체의 포트

     

    targetPort는 selector에 의해 선택된 포드들이 내부적으로 사용중인 포트를 적는다.

     

    deployment-hostname에서 정의된 컨테이너의 포트가 80이므로 targetPort 또한 80

     

     

    서비스 생성 또한 이전과 같이 apply해준다.

     

    kubectl apply -f hostname-svc-clusterip.yaml

     

     

     

     

    위와 같이 서비스는 IP와 port를 갖고, 클러스터 내부에서 이 IP를 이용해서 서비스에 연결된 포드에 접근할 수 있다.

     

     

     

    이번에는 임시 포드를 생성해서 서비스에 요청을 보내본다.

     

    kubectl run -i --tty --rm debug --image=alicek106/ubuntu:curl --restart=Never -- bash

     

     

    위와 같이 요청을 보낼때마다 다른 포드들이 응답한다.

     

    이는 서비스에게 전해진 요청들이 자동으로 분산되는 것이다. 

     

    즉, 별도의 설정 없이도 서비스를 통해서 로드 밸런싱이 되고 있다는 것을 알 수 있다. 

     

     

     

    이렇게 selector를 통해서 서비스와 포드가 연결되면 쿠버네티스는 자동으로 엔드포인트(End Point)를 생성한다.

     

    이 엔드 포인트는 서비스와 같은 이름으로 생성되며 연결된 포드들을 나타낸다.

     

     

     

     

     

    2. NodePort 서비스를 이용한 실습

     

    ClusterIP 타입은 내부에서만 접근이 가능했지만 이번에 실습해볼 NodePort는 클러스터 외부에서도 접근이 가능하다. 

     

    NodePort는 모든 노드의 특정 포트를 열어 서비스에 접근하는 방식이다. 

     

     

    먼저 다음과 같이 NodePort 타입의 yaml파일을 생성해준다.

     

    < hostname-svc-nodeport.yaml >

    apiVersion: v1
    kind: Service
    metadata: 
      name: hostname-svc-nodeport
    spec:
      ports:
      - name: web-port
        port: 8080
        targetPort: 80
      selector:
        app: webserver
      type: NodePort
    

     

    hostname-svc-nodeport 서비스 생성

     

     

    nodeport 서비스를 생성하면서 clusterip 타입에는 없던 31420 포트가 추가되었다. 

     

    이 포트는 모든 노드에서 동일하게 접근할 수 있는 포트를 의미한다. 

     

     

     

    도중에 문제가 생겨서 minkube로 대체했기 때문에 적당한 예시는 되지 못하지만 

     

     

    각 노드의 내부 IP, 외부 IP를 통해 31420포트로 접근하면 서비스에 연결할 수 있다.

     

     

    내부 IP와 31420포트를 통해 요청이 다른 포드들에게 분산되고 있음을 알 수 있다.

     

     

     

    그리고 clusterip타입을 사용했을 때와 마찬가지로 임시 포드를 생성하였고

     

    kubectl run -i --ty --rm debug --image=alice106k/ubuntu:curl --restart=Never -- bash

     

    cluster 내부에서 로드밸런싱이 잘 일어나고 있음을 알 수 있다. 

     

     

     

     

     

     

    용찬호 개발자님의 "시작하세요! 도커/쿠버네티스"를 인용해서 작성했습니다.

    반응형

    댓글

Designed by Tistory.