kubernetes CKA study (6) - Services

이동명·2023년 12월 18일
0

kubernetes CKA study

목록 보기
6/37
post-thumbnail

Services

Kubernetes Services는 내부의 컴포넌트끼리, 그리고 애플리케이션 외부와 통신할 수 있게 해줍니다. Kubernetes Services는 애플리케이션을 다른 애플리케이션이나 사용자와 연결하는 데 도움을 줍니다.

예를 들어, 우리의 애플리케이션은 다양한 섹션을 실행하는 파드의 그룹들이 있습니다. 프론트엔드를 유저에게 서빙하는 그룹, 백엔드 프로세스를 실행하는 그룹, 외부 데이터 소스에 연결하는 그룹들이 있을 것입니다. 이러한 파드 그룹 간 연결을 가능하게 하는 것이 Service입니다. Service를 통해 프론트엔드 애플리케이션을 엔드 유저가 사용할 수 있게 하고, 백엔드와 프론트엔드 파드 간 통신을 돕고, 외부 데이터 소스 연결 설정에 도움을 줍니다. 즉, 서비스는 애프리케이션의 마이크로서비스 간에 loose coupling을 가능하게 합니다.

External Communication

서비스의 한 가지 사용 사례를 살펴보겠습니다. 웹 애플리케이션이 실행되고 있는 파드를 배포했습니다. 어떻게 외부 사용자가 웹페이지에 접속할 수 있을까요?

먼저 기존 설정을 살펴보겠습니다. Kubernetes 노드에는 IP 주소가 있습니다. 지금 이 주소는 192.168.1.2입니다. 내 노트북도 같은 네트워크에 있고, IP 주소는 192.168.1.10입니다. 그리고 내부 파드 네트워크 범위는 10.244.0.0 입니다. 지금 파드의 IP는 10.244.0.2입니다.

지금 저는 파드와 다른 네트워크에 있으므로 파드에 ping하거나 접속할 수 없습니다. 어떻게 웹페이지를 볼 수 있을까요? 먼저, Kubernetes 노드에 SSH로 연결하면 curl을 수행하여 파드의 웹페이지에 접속할 수 있습니다. 또는, 노드에 GUI가 있다면 브라우저를 열어서 http://10.244.0.2 를 입력하여 웹페이지를 볼 수 있습니다.

그러나 이것은 Kubernetes 노드 내부에서 접근하는 방법입니다. 우리가 정말로 원하는 것은 SSH연결 없이 내 노트북에서 웹 서버에 접속하는 것을 원합니다.

우리는 노트북에서 SSH연결 없이 Kubernetes 노드의 IP에 접근하고, 웹 서버에 접속하고 싶습니다. 따라서 노트북에서 노드로, 노드에서 파드로 중간에 리퀘스트를 매핑할 무언가가 필요합니다. 이 역할을 하는 것이 Kubernetes Service입니다. 파드, replicaset, deployment과 마찬가지로 Kubernetes Service는 오브젝트입니다.

Service Types

쿠버네티스에는 3가지 타입의 Service가 있습니다.

1. NodePort

노드와 노드 내 파드에서 내부 파드에 접근 가능하도록 만드는 서비스 입니다.

서비스를 자세히 보겠습니다. 3개의 포트가 있습니다.

1) 실제 웹서버가 있는 파드의 포트는 80이며, Service가 리퀘스트를 전달할 곳이기 때문에 TargetPort라고 부릅니다.

2) 두 번째 포트는 서비스 자체의 포트입니다. 그냥 Port로 부릅니다. 사실 서비스는 노드 내의 가상 서버와 같습니다. 클러스터 내부에는 자체 IP주소가 있는데, IP주소를 서비스의 ClusterIP라고 부릅니다. (여기서는 10.106.1.12)

3) 마지막으로 노드 자체에 포트가 있습니다. 외부에서 웹 서버에 액세스하는 사용할 노드 포트이며, 지금은 30008로 설정되어 있습니다. 노드 포트는 30000에서 32767 사이의 범위에서 값을 가질 수 있습니다.

To create the service

deployment, replicaset, pod을 만들었을 때와 같이 Definition file을 사용합니다.

파일의 구조는 이전과 마찬가지로 apiVersion, kind, metadata, spec으로 동일합니다.

  • apiVersion: v1

  • kind: Service

  • metadata:

    • name: my-app-service 가 들어가고, 이것이 서비스의 이름입니다.
    • labels: 레이블이 있을 수 있지만, 지금은 필요하지 않습니다.
  • spec: 늘 그렇듯이 spec이 가장 중요한 부분입니다. 서비스의 spec에는type과 ports가 있습니다.

    • type: 우리가 만들고 있는 서비스의 유형을 나타냅니다. 지금은 NodePort입니다.

    • ports: 위에서 말한 포트들을 array로 적어줄 곳입니다. 여기서 필수 필드는 port입니다. targetPort를 적지 않으면 port와 동일하다고 간주합니다. nodePort를 적지 않으면 30000에서 32767 사이에서 사용 가능한 포트가 자동으로 배정됩니다.

      • targetPort: 80
      • port: 80
      • nodePort: 30008
    • selector: labels와 selector를 사용해서 서비스를 파드에 연결해야 합니다. selector에 연결할 파드의 labels 정보를 입력하면 됩니다.

완성된 definition file 은 아래와 같습니다.

apiVersion: v1
kind: Service
metadata:
 name: myapp-service
spec:
 types: NodePort
 ports:
 - targetPort: 80
   port: 80
   nodePort: 30008
 selector:
   app: myapp
   type: front-end

A service with multiple pods

지금까지 단일 파드에 매핑된 서비스에 대해 이야기했습니다. 그런데 프로덕션 환경에서는 실행중인 웹 애플리케이션의 여러 인스턴스가 있을 것이고 파드도 여러 개 있을 것입니다. 다행히 파드들은 모두 같은 label을 가지고 있을 것이며, 서비스의 selector에서 해당 label을 가지고 있는 파드를 모두 선택하게 됩니다. 그 중 리퀘스트를 전달할 파드는 파드간 로드 균형을 조정하면서 랜덤 알고리즘으로 선택하게 됩니다. 따라서 서비스는 파드 간 부하를 분산하면서 기본적으로 로드 밸런서 역할을 하게 됩니다.

2. ClusterIP

Cluster IP 서비스는 서로 다른 서비스(ex. 프론트엔드 서버, 백엔드 서버) 간에 소통을 가능하게 하기 위해 클러스터 안에 Virtual IP 를 생성합니다.

3. LoadBalancer

세 번째 타입은 loadbalancer 입니다. 예를 들어 frontent tier 웹 서버에 걸쳐있는 부하를 분산시킬 수 있습니다.

ClusterIP

풀스택 웹 애플리케이션에는 일반적으로 다양한 종류의 파드가 있습니다. 프론트엔드 웹 서버를 실행하는 파드 세트, 백엔드 웹서버를 실행하는 파드 세트, Redis와 같은 key-value store를 실행하는 파드 세트, MYSQL과 같은 영구 데이터베이스를 실행중인 파드 세트들이 있을 수 있습니다. 웹 프론트엔드 서버는 백엔드서버와 통신해야하며, 백엔드서버는 데이터베이스, Redis서버 등과 통신해야 합니다.

To create a service of type ClusterIP

  1. Definition File 생성

ClusterIP 타입의 서비스를 만들기 위해서는 언제나처럼 먼저 Definition file을 만듭니다.

  • apiVersion: v1

  • kind: Service

  • metadata:

    • name: 이름은 back-end로 하겠습니다.
  • spec:

    • types: ClusterIP 입니다. ClsuetrIP는 디폴트 타입입니다. 즉 types를 지정하지 않으면 디폴트로 ClusterIP가 지정됩니다.

    • ports:

      • targetPort: 백엔드가 노출되는 포트입니다. 80으로 지정하겠습니다.

      • port: 서비스가 노출되는 포트입니다. 이 또한 80으로 지정하겠습니다.

  • selector: 서비스를 특정한 파드 그룹에 연결하기 위해 selector를 작성합니다. 여기에는 파드의 labels가 들어갑니다. 완성된 Definition file은 아래와 같습니다.

apiVersion: v1
kind: Service
metadata:
 name: back-end
spec:
 types: ClusterIP
 ports:
 - targetPort: 80
   port: 80
 selector:
   app: myapp
   type: back-end
  1. kubectl create로 service 생성
kubectl create -f service-definition.yaml
  1. 생성한 서비스 조회
kubectl get services

LoadBalancer

앞에서 우리는 Nodeport 서비스를 보았습니다. NodePort 서비스는 워커 노드 포트에서 외부 애플리케이션을 사용할 수 있도록 해줍니다.

이제 프론트엔드 애플리케이션으로 초점을 돌리겠습니다. 투표앱과 결과앱이 있습니다. 이제 우리는 이런 파드가 클러스터의 워크 노드에서 호스팅된다는 것을 알고 있습니다. 클러스터에 4개의 워커노드가 있다고 가정해보겠습니다. 그리고 Nodeport 타입의 서비스를 생성하여 외부 유저가 애플리케이션에 액세스할 수 있도록 합니다. Node port 타입 서비스는 노드로 들어오는 트래픽을 수신하고 각 노드에 트래픽을 라우팅하는데 도움을 줍니다.

그런데 애플리케이션에 액세스 할 때 유저에게 어떤 URL을 제공하시겠습니까? IP와 포트를 통해 두 애플리케이션 모두 어디든 액세스할 수 있습니다. 따라서 제공할 수 있는 조합은 투표앱에 4개 조합(IP 와 port 조합), 결과앱에 4개 조합(IP 와 port 조합)입니다.

만약 두 개의 노드에서만 파드가 호스팅 되는 경우에서도 여전히 클러스터에 있는 모든 노드의 IP에 여전히 액세스할 수 있습니다. 투표앱에 대한 파드가 ip가 70, 71로 끝나는 두 노드에만 배치가 되었다고 가정해봅시다. 그 파드들은 여전히 모든 노드에 접근 가능합니다. 이것이 서비스가 구성되는 방식입니다. 따라서 이 URL을 공유하고, 유저가 애플리케이션에 액세스할 수 있도록 합니다.

그러나 이것은 엔드 유저가 정말 원하는 것은 아닙니다. 엔드 유저가 원하는 것은 http://example-vote.com 이나 http://example-result.com과 같은 단일 URL로 프로그램에 액세스하는 것입니다. 이를 달성하는 한 가지 방법은 로드밸런서용 새 VM을 생성하고 로드밸런서를 설치하고 구성하는 것입니다. 적합한 로드 밸런서는 AJ/Proxy, ngingx 같은 것이 있습니다. 그 다음엔, 노드들에 트래픽을 라우팅하도록 로드밸런서를 구성합니다.

이제 외부 로드 밸런싱에 대한 설정을 모두 마쳤습니다. 이제 유지관리를 해야 합니다. 이 작업은 지루할 수 있습니다.

그러나 우리는 Google Cloud, AWS, Azure와 같은 클라우드 플랫폼에서 네이티브 로드 밸런서를 활용할 수 있습니다. Kubernetes는 클라우드 공급자의 네이티브 로드밸런서를 사용하는 것을 지원합니다. 우리가 할 것은 서비스 타입을 설정하기만 하면 됩니다.

GCP, AWS 및 Azure는 확실히 지원됩니다. VirtualBox나 다른 지원되지 않는 환경에서 서비스 타입을 LoadBalancer로 입력했을 경우에는 Node port로 설정한 것과 동일한 효과가 나타납니다.


테스트 통과 완료 !

profile
Web Developer

0개의 댓글