Kubernetes Service란 뭔가요

작성자 김아름 수정일 2022-12-02 13:21

#kubernetes, #쿠버네티스, #서비스, #service, #clusterIP

들어가며

  • kubernetes의 서비스는 pod들을 통해 실행되고 있는 애플리케이션을 네트워크에 노출시키는 가상의 컴포넌트 입니다.

  • pod의 경우 지정되는 ip는 랜덤하고, 재시작 할 때마다 변하기 때문에, 고정된 endpoint로 호출하기 어려운 점이 있습니다.

  • 이때, pod간 로드밸런싱 지원을 해주는 것이 k8s의 service 입니다.

  • 그렇다면, k8s의 service의 종류와 그 특징에 대해 알아보겠습니다.



Service

동일한 서비스를 제공하는 pod 그룹의 단일 진입점을 제공합니다.

예를 들어, nginx 웹서버 3개를 실행했다고 가정해봅니다.

한 웹서버에게만 몰리지 않도록 3개의 ip를 관리하는 가상 ip를 만들고, 그 가상 ip가 load balance 역할을 합니다.


즉, load balance 역할을 하는 가상 ip가 3개의 웹서버에게 균등한 분배를 하게 됩니다.




Service Type

서비스는 크게 4가지로 구분할 수 있습니다.


  1. Cluster IP

    해당 타입은 service의 기본값입니다.
    여러 pod들의 endpoint를 묶어 단일 진입점(virtual IP)을 생성합니다.
    k8s cluster 내에서는 이 서비스에 접근이 가능하지만,
    cluster 외부에서는 외부 IP를 할당 받지 못했기 때문에, 접근이 불가능합니다.

    스파클링소다 4.0 기준으로 ClusterIP 타입의 서비스를 살펴보겠습니다.
    kubectl get svc
    NAME                                     TYPE        CLUSTER-IP    EXTERNAL-IP      PORT(S)                      AGE
    devainexus                               ClusterIP   6.5.35.82     <none>           80/TCP,5001/TCP              42d


    nexus repository의 서비스인 devainexus는 ClsuterIP로 설정되어 있습니다.
    cluster 내부에서 해당 ClusterIP인 6.5.35.82 를 호출하면 response를 확인할 수 있습니다.

    curl 6.5.35.82 --head
    HTTP/1.1 200 OK
    Date: Thu, 01 Dec 2022 06:10:06 GMT
    Server: Nexus/3.29.2-02 (OSS)
    X-Content-Type-Options: nosniff
    X-Frame-Options: DENY
    X-XSS-Protection: 1; mode=block
    Content-Type: text/html
    Last-Modified: Thu, 01 Dec 2022 06:10:06 GMT
    Pragma: no-cache
    Cache-Control: no-cache, no-store, max-age=0, must-revalidate, post-check=0, pre-check=0
    Expires: 0
    Content-Length: 8240


  2. NodePort

    Cluster IP로 연결되어 있는 pod들에 대해 외부 접속이 가능하도록 하는 서비스 타입입니다.
    이는 cluster IP로만 접근이 가능한 것이 아니라, 모든 노드의 ip와 port를 통해서도 접근이 가능하게 됩니다.

    스파클링소다 4.0 기준의 NodePort 타입의 서비스를 살펴보겠습니다.
    kubectl get svc -A | grep -i nodeport
    NAMESPACE     NAME                                             TYPE        CLUSTER-IP    EXTERNAL-IP      PORT(S)                        AGE
    monitoring    kube-prometheus-stack-kube-state-metrics         NodePort    6.5.164.190   <none>           8080:30995/TCP                 43d


    PORT 부분을 보면, 8080:30995/TCP 라고 설정되어 있습니다.

    이는 30995의 nodeport로 들어오면, 8080의 target port로 연결이 됩니다.
    kubectl describe svc -n monitoring kube-prometheus-stack-kube-state-metrics
    Name:                     kube-prometheus-stack-kube-state-metrics
    Namespace:                monitoring
    Labels:                   app.kubernetes.io/instance=kube-prometheus-stack
                              app.kubernetes.io/managed-by=Helm
                              app.kubernetes.io/name=kube-state-metrics
                              helm.sh/chart=kube-state-metrics-2.12.0
    Annotations:              prometheus.io/scrape: true
    Selector:                 app.kubernetes.io/instance=kube-prometheus-stack,app.kubernetes.io/name=kube-state-metrics
    Type:                     NodePort
    IP:                       6.5.164.190
    Port:                     http  8080/TCP
    TargetPort:               8080/TCP
    NodePort:                 http  30995/TCP
    Endpoints:                6.2.171.102:8080
    Session Affinity:         None
    External Traffic Policy:  Cluster
    Events:                   <none>


    그렇다면, 현재 클러스터의 노드 ip와 nodeport를 통해, 클러스터 외부에서 접속을 시도해 봅니다.

    현재 클러스터의 node는 아래와 같습니다.

    kubectl get node -owide
    NAME     STATUS   ROLES    AGE   VERSION    INTERNAL-IP      EXTERNAL-IP   OS-IMAGE                KERNEL-VERSION                CONTAINER-RUNTIME
    master   Ready    master   43d   v1.18.19   192.168.50.200   <none>        CentOS Linux 7 (Core)   3.10.0-957.el7.x86_64         docker://20.10.7
    worker   Ready    <none>   43d   v1.18.19   192.168.50.201   <none>        CentOS Linux 7 (Core)   3.10.0-1160.76.1.el7.x86_64   docker://20.10.7

    master 사설 IP는 192.168.50.200, worker 사설 IP는 192.168.50.201 입니다.


    명령 프롬프트창에서 30995 port를 붙여 호출해보면 정상적인 response를 확인할 수 있습니다.
    curl 192.168.50.200:30995
    <html>
                 <head><title>Kube Metrics Server</title></head>
                 <body>
                 <h1>Kube Metrics</h1>
                             <ul>
                 <li><a href='/metrics'>metrics</a></li>
                 <li><a href='/healthz'>healthz</a></li>
                             </ul>
                 </body>
                 </html>
    
    curl 192.168.50.201:30995
    <html>
                 <head><title>Kube Metrics Server</title></head>
                 <body>
                 <h1>Kube Metrics</h1>
                             <ul>
                 <li><a href='/metrics'>metrics</a></li>
                 <li><a href='/healthz'>healthz</a></li>
                             </ul>
                 </body>
                 </html>


  3. LoadBalancer

    NodePort의 기능과 load balance 기능을 합친 것이 loadbalancer 타입의 서비스 입니다.
    서비스를 자체 로드 밸런서로 노출시켜, 외부 로드 밸런서를 통해 들어온 트래픽이 서비스의 설정값에 따라 해당되는 pod들로 연결됩니다.

    LoadBalancer 타입의 서비스를 생성할 때는 아래와 같이 정의합니다.
    apiVersion: v1
    kind: Service
    metadata:
      name: <service name>
    spec:
      type: LoadBalancer



  4. ExternalName

    외부 서비스를 k8s cluster 내부에서 호출하고자 할 때 사용합니다.
    호출하고자 하는 외부 서비스의 DNS 주소를 입력하면, cluster 도메인이 이를 치환하게 됩니다.
    apiVersion: v1
    kind: Service
    metadata:
      name: <service name>
    spec:
      type: ExternalName
      externalName: google.com


    위와 같이 정의된 서비스를 호출할 때는 서비스 이름으로 호출할 수 있습니다.

    curl <service name>.<namespace>.svc.cluster.local

    해당 서비스로 들어오는 모든 요청을 externalName에 정의된 DNS로 포워딩하게 됩니다.




마무리

  • k8s의 service에 대해 알아보았습니다.

  • service의 종류와 주요 기능 및 테스트를 통해 service의 역할에 대해 알아보았습니다.

아티클이 유용했나요?

훌륭합니다!

피드백을 제공해 주셔서 감사합니다.

도움이 되지 못해 죄송합니다!

피드백을 제공해 주셔서 감사합니다.

아티클을 개선할 수 있는 방법을 알려주세요!

최소 하나의 이유를 선택하세요
CAPTCHA 확인이 필요합니다.

피드백 전송

소중한 의견을 수렴하여 아티클을 개선하도록 노력하겠습니다.

02-558-8300