자격증 학원 › CKA › 서비스 · 네트워킹

강의 19 / 28 · 약 25분

서비스 — 파드 앞의 고정 주소

ClusterIP · NodePort · LoadBalancer · Headless, 셀렉터와 엔드포인트, port · targetPort · nodePort 의 관계.

이 강의를 마치면

  • 서비스 타입별 용도와 접근 경로를 설명할 수 있다
  • port · targetPort · nodePort 를 정확히 구분해 쓸 수 있다
  • 엔드포인트가 비어 있을 때 원인을 찾을 수 있다

왜 서비스가 필요한가

파드 IP 는 파드가 다시 만들어질 때마다 바뀝니다. 서비스는 레이블 셀렉터로 파드 묶음을 가리키는 고정된 가상 IP(ClusterIP)와 DNS 이름을 줍니다. 요청은 준비된(Ready) 파드들에 나뉘어 갑니다.

클라이언트 → web-svc(10.96.12.34:80) ─┬→ 10.244.1.5:8080 (app=web, Ready)
             (kube-proxy 규칙)         └→ 10.244.2.7:8080 (app=web, Ready)

타입

타입접근쓰임
ClusterIP(기본)클러스터 안에서만 서비스IP:port내부 통신
NodePort+ 모든 노드의 노드IP:nodePort간단한 외부 공개, 테스트
LoadBalancer+ 클라우드 로드밸런서의 외부 IP클라우드 외부 공개(온프레미스는 MetalLB 등이 필요, 없으면 EXTERNAL-IP <pending>)
ExternalNameDNS CNAME외부 도메인에 내부 이름 붙이기
Headless(clusterIP: None)가상 IP 없음, DNS 가 파드 IP 들을 반환StatefulSet

세 가지 포트

apiVersion: v1
kind: Service
metadata:
  name: web-svc
spec:
  type: NodePort
  selector:
    app: web             # ← 이 레이블을 가진 파드로
  ports:
  - name: http
    port: 80             # 서비스가 받는 포트(서비스IP:80)
    targetPort: 8080     # 파드가 듣는 포트 (이름도 가능: targetPort: http)
    nodePort: 30100      # 노드가 여는 포트(NodePort/LoadBalancer, 생략하면 자동)
    protocol: TCP

포트가 둘 이상이면 각 포트에 name 이 필수입니다.

명령형으로 만들기

kubectl expose deployment web --name=web-svc --port=80 --target-port=8080
kubectl expose deployment web --type=NodePort --port=80                 # nodePort 는 무작위
kubectl expose pod db --port=6379                                        # 파드 레이블을 셀렉터로
kubectl create service clusterip web --tcp=80:8080                       # ⚠ 셀렉터가 app=web 으로 고정
kubectl create service nodeport web --tcp=80:8080 --node-port=30100

expose 는 대상(디플로이먼트·파드)의 레이블을 자동으로 셀렉터로 씁니다. create service 는 셀렉터를 app=<이름> 으로 가정하니 레이블이 다르면 엔드포인트가 비어 있게 됩니다. nodePort 를 특정 값으로 정하려면 --dry-run=client -o yaml 로 뽑아 nodePort: 를 넣습니다.

엔드포인트 — 서비스가 실제로 가리키는 곳

kubectl get endpoints web-svc          # ENDPOINTS: 10.244.1.5:8080,10.244.2.7:8080
kubectl get endpointslices -l kubernetes.io/service-name=web-svc
kubectl describe svc web-svc           # Selector, TargetPort, Endpoints 를 한눈에

최근 버전은 엔드포인트를 EndpointSlice 로 관리하고, 옛 Endpoints API 는 폐지 예정 경고를 냅니다. 어느 쪽으로 보든 들어 있는 정보(파드 IP:포트)는 같습니다.

엔드포인트가 비어 있거나 접속이 안 될 때

  1. 셀렉터 ↔ 파드 레이블 — kubectl get pods --show-labels vs describe svc 의 Selector. 오타 한 글자면 비어 있습니다.
  2. 파드가 Ready 인가 — Ready 아닌 파드(readinessProbe 실패)는 엔드포인트에서 빠집니다.
  3. targetPort 가 컨테이너가 듣는 포트인가 — 엔드포인트는 있는데 connection refused 면 대개 이것.
  4. 네임스페이스 — 서비스와 파드는 같은 네임스페이스여야 셀렉터가 닿습니다.
  5. NetworkPolicy — 연결이 거부가 아니라 시간 초과로 끝나면 정책이 막고 있을 가능성.

접속 확인

노드 셸에서는 파드 네트워크에 직접 닿지 않을 수 있으니 클러스터 안의 임시 파드로 확인합니다.

kubectl run tmp --rm -it --image=busybox:1.37 --restart=Never -- wget -qO- -T2 web-svc
kubectl run tmp --rm -it --image=busybox:1.37 --restart=Never -- wget -qO- -T2 web-svc.shop.svc.cluster.local
kubectl run tmp --rm -it --image=busybox:1.37 --restart=Never -- nc -zv -w2 db-svc 6379
curl http://<노드IP>:30100            # NodePort 는 노드에서 바로

busybox 에는 curl 이 없고 wget 과 nc 가 있습니다. curl 이 필요하면 curlimages/curl 이미지를 씁니다.

⌨️ 직접 해 보기

브라우저 실습 터미널에서 풀고 자동 채점을 받습니다.

✅ 확인 문제

과정 목차