본문 바로가기

리눅스

[draft] 쿠버네티스 서비스 유형

728x90

쿠버네티스 서비스 유형(Kubernetes Service Types)

Kubernetes에서 서비스 유형은 클러스터 내의 애플리케이션을 외부 또는 다른 파드와 연결하는 방법을 정의합니다. 서비스는 파드의 IP 주소가 동적으로 변경될 수 있기 때문에 안정적인 네트워크 접점을 제공하는 역할을 합니다.

Service 유형 비교

유형 접근 범위 비고
Cluster IP 클러스터 내부 NodePort 또는 LoadBalancer를 사용하여 외부에서 접근할 수 있도록 추가 설정이 필요합니다.
NodePort 클러스터 내부 및 외부 각 노드의 특정 포트를 사용하여 서비스에 접근합니다. NodePort 범위는 일반적으로 30000~32767입니다.
LoadBalancer 클러스터 외부 클라우드 제공업체에서 제공하는 LoadBalancer를 사용하여 서비스에 접근합니다.
Ingress 클러스터 외부 경로 기반 라우팅, 호스트 헤더 기반 라우팅, HTTPS 지원 등 고급 기능을 제공합니다.
Port Forwarding 로컬 시스템 kubectl port-forward 명령을 사용하여 로컬 시스템에서 Pod 포트로 포트 포워딩을 설정할 수 있습니다.
ExternalName DNS 이름 기반 LoadBalancer 또는 Ingress와 함께 사용해야 클러스터 외부에서 접근 가능합니다.
External IP 외부 노드에 직접 할당된 외부 IP 주소입니다.

kubectl create service 명령어 구문

kubectl create service [flags] [options]
$ kubectl create service -h
Create a service using a specified subcommand.

Aliases:
service, svc

Available Commands:
  clusterip      Create a ClusterIP service
  externalname   Create an ExternalName service
  loadbalancer   Create a LoadBalancer service
  nodeport       Create a NodePort service

Usage:
  kubectl create service [flags] [options]

Use "kubectl create service <command> --help" for more information about a given command.
Use "kubectl options" for a list of global command-line options (applies to all commands).

node-app 배포

kubectl create deployment node-app --image=anti1346/node-app:latest --replicas=1 --port=3000
kubectl get pod,svc -l app=node-app

1. ClusterIP

내부 서비스 간 통신

  • 클러스터 내부에서만 접근 가능한 내부 IP를 제공합니다. 클러스터 외부에서는 직접 접근할 수 없습니다.
  • 클러스터 내의 다른 파드가 특정 파드에 접근할 때 사용합니다.
kubectl get pod,svc -l app=node-app
kubectl create svc clusterip node-app --tcp=8080:3000
kubectl get services -l app=node-app
kubectl exec -it $(kubectl get pods -l app=node-app -o jsonpath='{.items[0].metadata.name}') -- /bin/bash
curl localhost:3000
curl 10.97.152.249:8080
kubectl delete service node-app

2. NodePort

외부에서 액세스할 수 있는 서비스

  • 클러스터 내의 모든 노드에서 특정 포트를 열어 외부 트래픽을 노드의 IP 주소와 포트를 통해 서비스에 전달합니다. 이 포트는 노드의 IP 주소와 함께 외부에서 접근할 수 있습니다.
  • 간단한 테스트 환경이나 클러스터 외부에서 클러스터 내부의 애플리케이션에 접근할 때 사용합니다.
  • NodePort 서비스를 생성하면 해당 서비스에는 자동으로 Cluster IP가 할당됩니다.
kubectl get pod,svc -l app=node-app
kubectl create svc nodeport node-app --tcp=8080:3000
kubectl get services -l app=node-app
kubectl exec -it $(kubectl get pod -l app=node-app -o jsonpath='{.items[0].metadata.name}') -- /bin/bash
curl localhost:3000
curl 10.106.94.94:8080
curl http://$(minikube ip):32554
kubectl delete service node-app

3. LoadBalancer

외부 트래픽 분산

  • 클라우드 제공자(GCP, AWS, Azure 등)에서 외부 로드 밸런서를 생성하여 외부 트래픽을 클러스터의 서비스로 전달합니다. 외부에 공인 IP 주소를 제공합니다.
  • 클라우드 환경에서 외부 트래픽을 클러스터의 서비스로 라우팅할 때 사용합니다

4. Ingress

다중 서비스 라우팅

  • 여러 서비스에 대한 단일 진입점을 제공하고, 경로 또는 호스트 기반 라우팅을 수행할 때 사용됩니다.

Ingress Controller 배포(Nginx 사용)

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/cloud/deploy.yaml

Ingress 리소스 생성

vim node-app-ingress.yaml
# node-app-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: node-app-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
  - http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: node-app
            port:
              number: 3000

deployment와 서비스 리소스 생성

더보기
vim node-app-deployment.yaml
# node-app-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: node-app  # Deployment의 이름
spec:
  replicas: 1  # Replica 수
  selector:
    matchLabels:
      app: node-app  # Pod를 식별하기 위한 라벨
  template:
    metadata:
      labels:
        app: node-app  # Pod에 부여되는 라벨
      name: node-app  # Pod의 이름
    spec:
      containers:
      - name: node-app
        image: anti1346/node-app:latest  # 사용할 이미지
        ports:
        - containerPort: 3000  # 컨테이너에서 노출할 포트

---
apiVersion: v1
kind: Service
metadata:
  name: node-app  # Service의 이름
spec:
  selector:
    app: node-app  # 해당 Service가 라우팅할 Pod를 선택하는 라벨
  ports:
  - protocol: TCP
    port: 3000  # Service가 사용하는 포트
    targetPort: 3000  # Pod의 포트
kubectl apply -f node-app-deployment.yaml

Ingress 리소스 적용

kubectl apply -f node-app-ingress.yaml
kubectl get svc -n ingress-nginx
$ kubectl get svc -n ingress-nginx
NAME                                 TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx-controller             LoadBalancer   10.100.201.144   <pending>     80:32293/TCP,443:30103/TCP   5d17h
ingress-nginx-controller-admission   ClusterIP      10.100.87.56     <none>        443/TCP                      5d17h
node-app                             ClusterIP      10.107.176.19    <none>        3000/TCP                     8m59s

웹 페이지 확인

curl $(minikube ip):32293
$ curl $(minikube ip):32293
Hostname: node-app-5776f68947-8km29
Internal IP: 10.244.0.96
External IP: 111.111.111.111
Current Time: 2024. 2. 13. 오전 10:59:08

5. Port Forwarding

로컬 디버깅

  • 개발자가 로컬 머신에서 개별 Pod에 직접 액세스하여 디버깅 또는 테스트를 수행할 때 사용됩니다.

단일 포트 포워딩

  • 특정 포트를 로컬 시스템으로 포트 포워딩합니다.
kubectl port-forward <pod-name> <local-port>:<remote-port>

여러 포트 포워딩

  • 여러 포트를 동시에 로컬 시스템으로 포트 포워딩합니다.
kubectl port-forward <pod-name> <local-port1>:<remote-port1> <local-port2>:<remote-port2> ...
  • 포드 이름이 my-pod이고 포드 내부의 포트 8080을 로컬 시스템의 포트 8888로 포트 포워딩
kubectl port-forward my-pod 8888:8080
  • 포드 이름이 my-pod이고 포드 내부의 포트 8080과 9090을 각각 로컬 시스템의 포트 8888과 9999로 포트 포워딩
kubectl port-forward my-pod 8888:8080 9999:9090
728x90

6. ExternalName

외부 서비스 연결

  • 클러스터 내부에서 클러스터 외부의 서비스나 DNS 이름에 액세스할 때 사용됩니다.

ExternalName 서비스 정의

  • 외부 서비스에 대한 DNS 이름을 내부 클러스터 DNS로 매핑하는 ExternalName 서비스를 정의합니다.
vim your-service-definition.yaml
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  type: ExternalName
  externalName: example.com

서비스 적용

  • 정의한 ExternalName 서비스를 클러스터에 적용합니다.
kubectl apply -f your-service-definition.yaml

7. External IP

특정 서비스에 직접 액세스

  • 노드에 직접 할당된 외부 IP 주소를 사용하여 특정 서비스에 직접 액세스할 때 사용됩니다.

NodePort 서비스

  • 모든 노드의 지정된 포트에서 서비스를 노출합니다. 이를 통해 외부에서 클러스터에 접근할 수 있습니다.
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 8080
    nodePort: 30000  # 외부에서 접근할 포트
  selector:
    app: my-app

LoadBalancer 서비스

  • 클라우드 제공 업체의 로드 밸런서를 사용하여 외부 IP를 서비스에 할당합니다.
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  type: LoadBalancer
  ports:
  - port: 80
    targetPort: 8080
  selector:
    app: my-app

External IP를 가진 Node에 직접 접근

  • 클러스터 내의 특정 노드에 외부 IP를 할당하고 해당 노드에 포드를 스케줄링합니다.

Ingress 리소스

  • Ingress 리소스를 사용하여 외부 IP를 서비스에 매핑할 수 있습니다.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
spec:
  rules:
  - host: example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: my-service
            port:
              number: 80

 

참고URL

- The Baeldung : ClusterIP, NodePort, and LoadBalancer: Kubernetes Service Types

- Undefined - Blog by Eunsu Kim : 쿠버네티스 서비스(Service) 개념 정리

- Kubernetes Documentation : 서비스, 로드밸런싱, 네트워킹

- Kubernetes Documentation : 서비스와 애플리케이션 연결하기

- Kubernetes Documentation : 외부 로드 밸런서 생성하기

- Sysdig : Kubernetes Services: ClusterIP, Nodeport and LoadBalancer

 

728x90