티스토리 뷰

728x90
반응형

이번 포스팅에서는 Kubernetes Service를 생성해 보도록 하겠습니다.

Kubernetes의 Service는 Pod의 논리적 집합과 액세스 정책을 정의하는 역할을 수행합니다.

Service object는 클러스터 내부에서 접근 가능한 port와 외부에서 접근 가능한 nodePort를 가집니다. 이 포트를 통해 요청이 왔을 경우, Service object에 설정된 selector를 이용하여 요청이 전달될 Pod을 찾는데, Service object의 selector 값에 해당하는 label을 가진 Pod 그룹을 찾고 load balancing (기본은 random) 설정에 따라 특정 Pod에 요청이 전달 됩니다.

같은 Cluster 내에서 Pod이 어떤 Node 내 생성되었는지와 상관 없이 Service는 selector/label 방식으로 Pod을 찾을 수 있습니다. 

Kubernetes의 Service Object는 서비스 디스커버리와  로드밸런싱 기능을 제공하기 때문에 마이크로서비스 아키텍처의 구성 요소 중 하나인 Spring Netflix Eureka를 대신할 수도 있습니다.

지난 Kubernetes 가이드는 아래를 참고하세요.

 

[Container Management] Kubernetes Master Node 설치

[Container Management] Kubernetes Dashboard Install & Setting

[Container Management] Kubernetes Woker Node Install & Setting

[Container Management] Kubernetes Pod 생성 가이드

Kubernetes Service 생성

1. service.yaml 파일 생성

먼저 service를 생성하기 위한 yaml 파일을 정의하고 적용해 보도록 하겠습니다.

apiVersion: v1
kind: Service
metadata:
  name: gs-spring-boot-docker-service
spec:
  ports:
    - name: "8080"
      port: 8081
      targetPort: 8080
  selector:
    app: gs-spring-boot-docker
  type: NodePort

주요 내용은 다음과 같습니다.

- 다음은 yaml 파일 작성 시 참고하는 주요 설정입니다.


kind : 현재 yaml이 어떤 object를 생성하기 위함인지 kind에 설정합니다. kind: Service 설정을 통해 현재 yaml로 Service object를 생성하게 됩니다. 
spec.ports : Service object 에 설정할 포트 정보 입니다. 
spec.ports.name : Service object 에 설정할 포트 중 특정 포트 정보에 대한 명칭 입니다. 
spec.ports.port : Cluster 내부에서 사용될 Service object의 포트 입니다. 
spec.ports.targetPort : Service object로 들어온 요청을 전달할 target이되는 Pod이 노출하고 있는 포트 입니다. Deployment의 spec.template.spec.containers.ports.containerPort에 전달 됩니다. 기본적으로 targetPort는 port 필드와 동일한 값으로 설정됩니다. 
spec.selector : Service object가 요청을 전달할 Pod을 찾기위한 검색어 입니다. Pod의 label이 app: gs-spring-boot-docker 인 Pod을 찾아 요청을 전달 하게 됩니다. 찾은 Pod이 여러개인 경우 load balancing 정책에 따라 하나의 Pod을 선택하게 됩니다. 
spec.type : Service object를 노출하기 위한 방식을 설정 합니다. 가능한 type으로는 ClusterIP, NodePort, LoadBalancer가 있습니다. 
- ClusterIP (Service object의 cluster-internal IP만 노출 하고, Cluster 내부에서만 접근 가능 합니다.) 
- NodePort (각 Node에서 static 포트를 노출합니다. 클러스터 외부에서 :의 형태로 request가 가능 합니다. 앱을 배포후 테스트할 때 선택하기 좋은 type입니다.) 
- LoadBalancer (특정 cloud provider(GCE/AWS)의 load balancer에게 Service object를 노출시키는 방법 입니다.)


2. Service 적용

서비스를 생성하는 방법 역시 CLI를 사용하는 방법과 Dashboard를 사용하는 방법이 있습니다.

[root@guruson ~]# kubectl apply -f service.yaml 
service/gs-spring-boot-docker-service created
[root@guruson ~]# kubectl get services
NAME                            TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)          AGE
gs-spring-boot-docker-service   NodePort    10.99.52.49   <none>        8081:32189/TCP   6s
kubernetes                      ClusterIP   10.96.0.1     <none>        443/TCP          18h
[root@guruson ~]#

- 다음과 같이 정상 추가된 것을 볼 수 있습니다.

정상적으로 추가가 완료되면 왼쪽 메뉴 바에서 Services => 해당 서비스  => NodePort를 확인합니다.

NodePort 정보는 기동 시마다 변경되는 정보로 현재는 "32189"입니다.

NodePort는 Pod 내부 Internal Container Port인 8081로 요청을 라우팅하게 됩니다.

3. Service 호출

자 그럼 마지막으로 NodePort로 서비스를 직접 호출해 보도록 하겠습니다.
Pod에 배포된 Service인 gs-spring-boot-docker-service를 호출하는 URL은 다음과 같이 확인이 가능합니다.

[root@guruson ~]# kubectl get pods
NAME                                                READY     STATUS    RESTARTS   AGE
apache-docker-deployment-54876bbd86-rdkmn           1/1       Running   0          5h21m
apache2-docker-deployment-5bf4bfdb-qlcdx            1/1       Running   0          5h11m
gs-spring-boot-docker-deployment-7455d748bc-2rlgb   1/1       Running   0          99m
[root@guruson ~]# kubectl describe pod gs-spring-boot-docker-deployment-7455d748bc-2rlgb
Name:               gs-spring-boot-docker-deployment-7455d748bc-2rlgb
Namespace:          default
Priority:           0
PriorityClassName:  <none>
Node:               kubeworker/124.111.196.223
Start Time:         Sun, 04 Aug 2019 13:45:56 +0900
Labels:             app=gs-spring-boot-docker
                    pod-template-hash=7455d748bc
Annotations:        <none>
Status:             Running
IP:                 10.44.0.3
Controlled By:      ReplicaSet/gs-spring-boot-docker-deployment-7455d748bc
Containers:
  gs-spring-boot-docker:
    Container ID:   docker://a40304c7fc040f28b9aa645f03e78edf0f6352154237612bb73df928f1036332
    Image:          nara0617/gs-spring-boot-docker:1.0
    Image ID:       docker-pullable://nara0617/gs-spring-boot-docker@sha256:879e37e16545d45391f30e5559dface8d90636ab330b546fa53d3ae79dfed545
    Port:           8080/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Sun, 04 Aug 2019 13:46:13 +0900
    Ready:          True
    Restart Count:  0
    Limits:
      cpu:     500m
      memory:  1Gi
    Requests:
      cpu:        200m
      memory:     256Mi
    Environment:  <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-2nfnx (ro)
Conditions:
  Type              Status
  Initialized       True 
  Ready             True 
  ContainersReady   True 
  PodScheduled      True 
Volumes:
  default-token-2nfnx:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-2nfnx
    Optional:    false
QoS Class:       Burstable
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:          <none>
[root@guruson ~]#

위와 같이 Node 정보를 통해 호출할 서버 IP를 확인할 수 있습니다.
- 또한 kubectl get service로 NodePort 확인이 가능합니다.

[root@guruson ~]# kubectl get services
NAME                            TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)          AGE
gs-spring-boot-docker-service   NodePort    10.99.52.49   <none>        8081:32189/TCP   21m
kubernetes                      ClusterIP   10.96.0.1     <none>        443/TCP          19h
[root@guruson ~]#

즉 http://IP:NodePort/Context/PageName => http://222.234.124.110:32189/로 호출이 가능합니다.

이를 기반으로 서비스가 정상 호출되는 과정을 살펴보았습니다.

다음 포스팅에서는 Kubernetes의 애플리케이션 관리 방법에 대해 알아보도록 하겠습니다.

728x90
반응형