본문 바로가기
DevOps 스터디 - 도커 & K8S

5주차. Service(ClusterIP, NodePort, LB, externalTrafficPolicy, ExternalName)

by yeongki0944 2025. 4. 13.

출처 : https://netpple.github.io/docs/deepdive-into-kubernetes/k8s-controller-manager

 

5편. kube-controller-manager

쿠버네티스의 심장 컨트롤러에 대해 다룹니다. 빌트인 컨트롤러들을 기동하고 관리하는 컨트롤러 매니저에 대해 알아보고 다양한 컨트롤러들을 소개하고 이들이 협력하여 일하는 방법에 대해

netpple.github.io

 

Service

  • 쿠버네티스 오브젝트
  • 파드에서 실행중인 어플리케이션을 네트워크 서비스로 노출하는 추상화 방법

 

Service 

kubectl apply -f https://raw.githubusercontent.com/alicek106/start-docker-kubernetes/refs/heads/master/chapter6/deployment-hostname.yaml
# 예제 6.9 chapter6/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

 

 

Cluster IP - 쿠버네티스 내부에서만 접근가능

kubectl apply -f https://raw.githubusercontent.com/alicek106/start-docker-kubernetes/refs/heads/master/chapter6/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

 

NodePort - 외부에 노출하기

kubectl apply -f https://raw.githubusercontent.com/alicek106/start-docker-kubernetes/refs/heads/master/chapter6/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

 

NodePort 의 단점

1. 80, 443으로 NodePort 설정하기 부적절함
2. SSL 적용하기 어려움
3. 라우팅 설정 어려움

-> Ingress가 NodePort의 단점을 커버할 수 있음

 

LoadBalancer - 클라우드 LB와 연동하기

[실습 환경]
AWS : kops를 통해 설치한 쿠버네티스 or 클라우드 프로바이더를 설정해 kubeadm으로 설치한 쿠버네티스
GCP : GKE 환경

 

kubectl apply -f https://raw.githubusercontent.com/alicek106/start-docker-kubernetes/refs/heads/master/chapter6/hostname-svc-lb.yaml
# chapter6/hostname-svc-lb.yaml
apiVersion: v1
kind: Service
metadata:
  name: hostname-svc-lb
spec:
  ports:
    - name: web-port
      port: 80
      targetPort: 80
  selector:
    app: webserver
  type: LoadBalancer

 

AWS로부터 자동 할당된 External-IP

 

 

kubectl apply -f https://raw.githubusercontent.com/alicek106/start-docker-kubernetes/refs/heads/master/chapter6/hostname-svc-nlb.yaml
#chapter6/hostname-svc-nlb.yaml
apiVersion: v1
kind: Service
metadata:
  name: hostname-svc-nlb
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
spec:
  ports:
    - name: web-port
      port: 80
      targetPort: 80
  selector:
    app: webserver
  type: LoadBalancer

 

 

externalTrafficPolicy

 

 

  1. externalTrafficPolicy: Cluster 설정
  2. NodePort/LoadBalancer 요청이 노드(A)로 인입 
  3. 트래픽은 아래 두가지중 하나로 전달
    1. 노드 A -> 포드 a
    2. 노드 A -> 노드 B -> 포드 b
  4. 만약, 3-2케이스의 경우, (노드 A -> 노드 B -> 포드 b) 노드 B를 한번더 거치는 네트워크 홉(hop)이 발생
  5. 또한, 이 과정에서 SNAT(Source Network Address Translation)가 발생 (실제 클라이언트의 IP 주소가 유실될 수 있음)

 

kubectl apply -f https://raw.githubusercontent.com/alicek106/start-docker-kubernetes/refs/heads/master/chapter6/hostname-svc-lb-local.yaml
#chapter6/hostname-svc-lb-local.yaml

apiVersion: v1
kind: Service
metadata:
  name: hostname-svc-lb-local
spec:
  externalTrafficPolicy: Local
  ports:
    - name: web-port
      port: 80
      targetPort: 80
  selector:
    app: webserver
  type: LoadBalancer

 

 

externalTrafficPolicy의 Cluster와 Local은 둘 다 장단점이 있기에, 상황에 맞게 적절히 사용을 하는게 좋음

 

ExternalName

 

kubectl apply -f https://raw.githubusercontent.com/alicek106/start-docker-kubernetes/refs/heads/master/chapter6/external-svc.yaml
#chapter6/external-svc.yaml

apiVersion: v1
kind: Service
metadata:
  name: externalname-svc
spec:
  type: ExternalName
  externalName: my.database.com