서비스 기본 개념 및 YAML 구조
파드는 동적으로 생성되고 삭제되므로 IP 주소가 계속 바뀐다. 서비스(Service)는 이렇게 동적으로 변하는 파드 그룹에 대한 고정된 단일 접근 지점(Single Point of Contact)을 제공하는 쿠버네티스 오브젝트다. 서비스를 통해 파드의 IP 주소가 변경되더라도 클라이언트는 서비스를 통해 안정적으로 파드에 접근할 수 있다.
서비스는 주로 L4(TCP/UDP) 레벨에서 동작하며, 레이블 셀렉터(Label Selector)를 사용하여 어떤 파드 그룹에 트래픽을 전달할지 결정한다.
기본 서비스 YAML 예시 (ClusterIP)
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: MyApp # 이 레이블을 가진 파드들을 대상으로 함
ports:
- protocol: TCP
port: 80 # 서비스 자체의 포트
targetPort: 9376 # 서비스가 트래픽을 전달할 파드의 컨테이너 포트
YAML 주요 필드 설명
apiVersion
: 오브젝트 API 버전으로, 서비스는v1
을 사용한다.kind
: 오브젝트 종류로,Service
이다.metadata
: 서비스의 이름 등 메타데이터를 정의한다.spec
: 서비스의 상세 스펙을 정의한다.selector
: 어떤 레이블을 가진 파드들을 이 서비스에 연결할지 지정한다. 이 필드가 없으면 서비스는 자동으로Endpoints
오브젝트를 생성하지 않는다.ports
: 서비스가 노출할 포트 정보를 정의하는 배열이다.port
: 서비스가 클러스터 내부에서 노출될 포트 번호다.targetPort
:selector
로 선택된 파드들이 실제로 요청을 수신할 컨테이너 포트 번호다.protocol
: 포트에서 사용할 프로토콜을 지정한다 (기본값:TCP
).
type
: 서비스의 타입을 지정한다. 생략 시 기본값은ClusterIP
이다.
서비스 타입 (Service Types)
쿠버네티스는 다양한 사용 사례에 맞춰 여러 종류의 서비스를 제공한다.
ClusterIP
- 설명: 기본 서비스 타입. 클러스터 내부에서만 접근 가능한 가상 IP를 할당받는다. 클러스터 내 다른 파드들이 이 IP를 통해 서비스에 접근할 수 있다. 외부 노출이 필요 없는 내부 컴포넌트 간 통신에 주로 사용된다.
- YAML 예시: 위의 기본 예시와 동일하다.
type: ClusterIP
를 명시하거나type
필드를 생략하면 된다.
NodePort
- 설명:
ClusterIP
의 모든 기능을 포함하며, 추가적으로 모든 워커 노드(Worker Node)의 특정 포트를 통해 외부에서 서비스에 접근할 수 있게 한다. 각 노드는 지정된 포트(nodePort
)로 들어오는 트래픽을 해당 서비스로 전달한다. - YAML 예시:
apiVersion: v1 kind: Service metadata: name: my-nodeport-service spec: type: NodePort selector: app: MyApp ports: - port: 80 targetPort: 80 # nodePort: 30007 # 생략 시 30000-32767 범위에서 자동 할당됨
CKA Tip: NodePort
서비스를 생성하면 <NodeIP>:<nodePort>
주소로 클러스터 외부에서도 파드에 접근할 수 있다.
LoadBalancer
- 설명:
NodePort
의 모든 기능을 포함하며, 클라우드 플랫폼(AWS, GCP, Azure 등)에서 제공하는 외부 로드 밸런서를 프로비저닝하고 서비스에 연결한다. 클라우드 로드 밸런서는 고유한 외부 IP를 가지며, 이 IP로 들어오는 트래픽을 모든 노드의NodePort
로 분산시킨다. - YAML 예시:
apiVersion: v1 kind: Service metadata: name: my-loadbalancer-service spec: type: LoadBalancer selector: app: MyApp ports: - port: 80 targetPort: 80
CKA Tip: kubectl get svc my-loadbalancer-service
명령을 실행했을 때 EXTERNAL-IP
가 <pending>
에서 실제 IP로 바뀌면 로드 밸런서 프로비저닝이 완료된 것이다.
ExternalName
- 설명: 서비스를 외부 서비스의 DNS 이름에 대한 별칭(CNAME 레코드)처럼 매핑한다. 클러스터 내부의 파드들이
my-service
와 같은 내부 서비스 이름을 사용하여 외부 서비스에 접근할 수 있게 해준다.selector
가 필요 없으며, 프록시나 포트 포워딩이 일어나지 않는다.** - YAML 예시:
apiVersion: v1 kind: Service metadata: name: external-service-alias spec: type: ExternalName externalName: my.database.example.com
참고 자료: 쿠버네티스 공식 문서 - 서비스
헤드리스 서비스 (Headless Service)
- 설명:
.spec.clusterIP
필드 값을None
으로 설정하여 생성하는 특별한 종류의 서비스다. 쿠버네티스는 헤드리스 서비스에 대해 클러스터 IP를 할당하지 않으며, 로드 밸런싱도 수행하지 않는다. 대신, 서비스의 DNS 이름으로 조회하면 서비스에 연결된 모든 파드의 IP 주소 목록(A
레코드)을 직접 반환한다. StatefulSet과 함께 사용되어 각 파드에 고유한 네트워크 식별자를 제공하는 데 주로 쓰인다. - YAML 예시:
apiVersion: v1 kind: Service metadata: name: nginx-headless-svc spec: clusterIP: None selector: app: MyApp ports: - port: 80 targetPort: 80
CKA Tip: nslookup <headless-service-name>
명령을 실행하면 서비스에 속한 파드들의 IP 목록을 직접 확인할 수 있다.
kube-proxy와 서비스 동작 원리
kube-proxy
는 각 노드에서 실행되는 네트워크 프록시로, 쿠버네티스 서비스의 핵심적인 네트워킹 규칙을 구현한다. kube-proxy
는 API 서버를 통해 서비스와 엔드포인트(서비스에 연결된 파드들)의 변경 사항을 감시하고, 각 노드의 네트워크 규칙(예: iptables
, IPVS
)을 업데이트하여 서비스의 가상 IP로 향하는 트래픽을 올바른 백엔드 파드로 전달한다.
- userspace 모드 (레거시): 모든 트래픽이
kube-proxy
를 거쳐 파드로 전달되어 성능 병목이 있었다. 현재는 거의 사용되지 않는다. - iptables 모드 (기본값):
kube-proxy
가 커널의iptables
규칙을 관리한다. 트래픽이iptables
규칙에 따라 커널 레벨에서 파드로 직접 전달되므로 성능이 좋다. 단, 연결 실패 시 자동 재시도를 하지 않는다. - IPVS 모드:
iptables
보다 더 빠르고 효율적인 로드 밸런싱을 위해 설계된 리눅스 커널 기능인 IPVS(IP Virtual Server)를 사용한다. 대규모 클러스터에서 더 나은 성능과 확장성을 제공한다.
참고 자료: 쿠버네티스 공식 문서 - 서비스 프록시
CKA 시험 핵심 전략 및 kubectl
명령어
- 서비스 생성:
kubectl expose
명령어를 사용하면 디플로이먼트나 파드를 기반으로 빠르게 서비스를 생성할 수 있다.- 예시:
kubectl expose deployment my-deployment --port=80 --target-port=8080 --type=NodePort
- 예시:
- 정보 조회:
kubectl get service
또는kubectl get svc
: 모든 서비스 목록을 확인한다.kubectl describe service <service-name>
: 서비스의 상세 정보(레이블 셀렉터, IP, 포트, 엔드포인트 등)를 확인하는 가장 중요한 명령어다.
- 엔드포인트 확인:
kubectl get endpoints <service-name>
명령으로 서비스가 현재 어떤 파드 IP들을 가리키고 있는지 확인할 수 있다. 서비스가 제대로 동작하지 않을 때 파드가 올바르게 연결되었는지 진단하는 데 유용하다. - 연결 테스트:
kubectl run tmp-pod --rm -it --image=busybox -- /bin/sh
로 임시 파드를 실행한 후,wget -O- <service-name>:<port>
와 같은 명령으로 서비스에 대한 연결을 테스트할 수 있다.