[Service]
- Cluster IP 10.233.0.0/18
- SM : 10.233.0.0 - 10.233.63.255
- Service Pod: 10.233.64.00.00 - 10.233.255.255
서비스 유형
🔹 1. ClusterIP (기본값)
- 역할: 클러스터 내부에서만 접근 가능한 고정 IP 제공
- 외부 접근: ❌ (클러스터 내부에서만 사용 가능)
- 특징 : 동일 레이블 가지는 파드에 대한 단일 지점 가상 IP 주소 제공
- 서비스 유형 미지정 시 디폴트값 제공
- 주 용도: 파드 간 통신, 마이크로서비스 구조에서 내부 백엔드 연결
- 예시: 프론트엔드 → 백엔드, 백엔드 → DB
1-1 . 자동할당
vi cluster.yml
apiVersion: v1
kind: Service
metadata:
name: mycluster
spec:
selector:
app: webui
ports:
- protocol: TCP
port: 80
targetPort: 80
1-2. 고정 할당
> Deployment
vi mydeploy.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mydp
spec:
replicas: 3
*** selector:
matchLabels:
app: webui***
template:
metadata:
name: mypod
***labels:
app: webui***
spec:
containers:
- name: mycon
image: nginx:1.14
apiVersion: apps/v1
kind: Deployment
metadata:
name: mydp
spec:
replicas: 3
selector:
matchLabels:
app: webui
template:
metadata:
labels:
app: webui
spec:
containers:
- name: mycon
image: nginx:1.14
ports:
- containerPort: 80
1-2-1. 서비스 생성
vi clusterip.yml
apiVersion: v1
kind: Service
metadata:
name: myclusterip
spec:
type: ClusterIP
clusterIP: 10.233.10.10
***selector:
app: webui // 동일해야 서비스 연결 가능***
ports:
- protocol: TCP
port: 80
targetPort: 80
Deployment로 생성한 웹 파드 접속 시
해당 서비스 IP로 로드 밸런싱 가능
[포트 포워딩]
ClusterIP는 내부 클러스터에서만 접속 가능하지만 개발/테스트용으로 포트 포워딩 시
외부에서 내부로 접근 가능하다
'
🔹 2. NodePort
- 역할: 클러스터 외부에서 모든 노드의 IP 주소 + 고정 포트를 통해 서비스에 접근 가능
- 외부 접근: ⭕ (모든 노드의 IP에서 접근 가능)
- 주 용도: 간단한 외부 노출 테스트, 작은 규모 서비스
- 기본 포트 범위: 30000~32767
- 구성 흐름: ClusterIP → NodePort 설정 → 외부에서 접근 가능
http://<NodeIP>:<NodePort>
[NodePort 구성]
vi mynodeport.yml
apiVersion: v1
kind: Service
metadata:
name: my-nodeport
spec:
type: NodePort
selector:
app: webui
ports:
- port: 80 # 서비스 내부 포트
targetPort: 8080 # 파드 컨테이너가 사용하는 포트
nodePort: 30080 # 노드 외부에서 접근할 수 있는 고정 포트
[ 외부 사용자 ]
|
192.168.10.100:30080 (노드 IP + NodePort)
↓
[ NodePort 서비스 ]
↓
[ app=webui 라벨 가진 파드들 중 하나 ]
🔹 3. LoadBalancer
- 역할: 클라우드 제공업체의 로드밸런서를 사용하여 외부에 서비스 노출
- 외부 접근: ⭕ (공인 IP 제공)
- 주 용도: 실제 운영 서비스 외부 노출, 클라우드 환경에서 가장 많이 사용
- 특징:
- 내부적 ClusterIP + NodePort 동시 생성
- 퍼블릭 클라우드(GCP, AWS, Azure 등)에서만 동작 (on-prem에서는 MetalLB 등 필요)
3-1. Service 생성
vi loadbalacner.yml
apiVersion: v1
kind: Service
metadata:
name: myloadbalance
spec:
type: LoadBalancer
clusterIP: 10.233.10.100
selector:
app: webui
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 32000
3-2. HA Proxy
dnf -y install haproxy
vi /etc/hosts
vi /etc/haproxy/harpoxy.cfg
파일 수정
67 frontend main
68 bind *: 80 // 80으로 변경
# acl url_static path_beg -i /static /images /javascript /stylesheets
# acl url_static path_end -i .jpg .gif .png .css .js
# use_backend static if url_static // 주석 처리 3줄
85 backend app
86 balance roundrobin
87 server app1 191.168.10.100:32000 check
88 server app2 191.168.10.150:32000 check
89 server app3 191.168.10.200:32000 check
/// 각 노드로 수정
systemctl restart haproxy
🔹 4. Headless
- 역할 : 단일 진입점 없이 모든 파드 접근 가능
- 일반 서비스와 달리 ClusterIP를 생성하지 않고, 대신 DNS를 통해 각 파드의 IP를 직접 반환하는 서비스
- 파드 개별 접근이 가능하도록 로드밸런싱 없이 파드 목록을 직접 노출
🔸 역할
상황 설명
StatefulSet과 함께 사용 | DB나 캐시처럼 각 인스턴스가 고유해야 할 때 사용 (예: MongoDB, Cassandra, Kafka 등) |
파드 직접 접근 필요 | 로드밸런싱 없이 파드 하나하나에 직접 접근해서 다르게 동작시켜야 할 때 |
spec:
clusterIP: None
기본적으로 Kubernetes에서
파드는 직접 접근 대상이 아니다
- 파드는 생성/삭제/재시작 자동 수행 → IP 상시 변경
- **Service(서비스)**를 통해 접근 가능
- → "단일 진입점" (ex: ClusterIP)
✅ Headless Service는?
spec:
clusterIP: None # 단일 진입점이 없다!
→ 이건 서비스가 로드밸런싱을 안 해주고,
DNS 질의 결과로 파드의 "실제 IP들"을 모두 응답
my-headless-service.default.svc.cluster.local 로 접근하면
→ "서비스 IP" 하나가 아니라
→ pod-a, pod-b, pod-c 각각의 IP 확인 가능
🎯 정리하자면
항목 일반 Service Headless Service
DNS 응답 | ClusterIP 하나 | 각 파드의 IP 목록 |
접근 방식 | 로드밸런싱된 하나의 진입점 | 파드에 직접 접근 |
의미 | 서비스 이름으로 요청 시 어느 파드가 응답할지 모름 | 서비스 이름으로 요청하면 원하는 파드에 직접 연결 가능 |
💡 그럼 "누가 파드에 접근하냐"면?
- 다른 파드나 컨테이너가 접근하는 것.
- 예를 들어:
- 데이터베이스 클러스터 구성 시,
- cassandra-1이 cassandra-0에 직접 붙어야 한다면 → DNS로 직접 IP를 알아야 함.
- 상태 있는 앱에서 파드 간 통신 시 → “어느 노드에게 붙을지” 지정해야 함.
- 일반 서비스는 “콜센터 대표번호” , 누가 받을지 몰라.
- Headless는 “직통 번호” 같아서, 특정 파드 확인 가능
✅ 왜 Headless Service는 StatefulSet과 함께 쓰일까?
StatefulSet은 파드에 고유한 이름과 고정된 네트워크 ID를 부여
상태가 있는 애플리케이션(예: DB, Kafka 등)에 적합
일반 Service는 로드밸런싱해서 파드 중 아무나 연결
→ 이건 상태 있는 애플리케이션에 비적합
각 파드 직접 연결 가능Headless Service 필요
🔷 Cassandra 클러스터 배포
1. Headless Service 정의
apiVersion: v1
kind: Service
metadata:
***name: cassandra***
spec:
***clusterIP: None*** # ✅ 핵심!
selector:
app: cassandra
ports:
- port: 9042
2. StatefulSet 정의 (일부만)
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: cassandra
spec:
***serviceName: cassandra*** # ✅ Headless Service 이름과 같아야 함
replicas: 3
selector:
matchLabels:
app: cassandra
template:
metadata:
labels:
app: cassandra
spec:
containers:
- name: cassandra
image: cassandra:latest
📌 파드 DNS 이름 어떻게 될까?
StatefulSet은 파드명 순차적 생성
cassandra-0.cassandra.default.svc.cluster.local
cassandra-1.cassandra.default.svc.cluster.local
cassandra-2.cassandra.default.svc.cluster.local
파드이름.서비스이름.네임스페이스.svc.cluster.local
→ 이 DNS 이름을 통해 각 파드에 직접 연결 가능
🎯 정리
항목 설명
Headless Service | 파드 각각에 직접 연결할 수 있도록 도와주는 서비스 |
StatefulSet | 이름이 고정된 파드 생성 (예: pod-0, pod-1...) |
같이 쓰는 이유 | 파드마다 상태(데이터 등)를 유지하고, 고정된 네트워크 주소로 접근해야 하기 때문 |
- Headless Service는 "서비스 이름으로 요청하면 로드밸런서 거치지 않고 파드 IP를 직접 알려준다."
- 그래서 파드 하나하나에 "정확히" 붙을 수 있는 구조가
apiVersion: apps/v1
kind: Deployment
metadata:
name: mydp
spec:
replicas: 3
selector:
matchLabels:
app: webui
template:
metadata:
name: test
labels:
app: webui
spec:
containers:
- name: mycon
image: nginx:1.14
---
apiVersion: v1
kind: Service
metadata:
name: myhead
spec:
type: ClusterIP
clusterIP: None
selector:
app: webui
ports:
- protocol: TCP
port: 80
targetPort: 80
nslookup myhead.default.svc.cluster.local
dig myhead.default.svc.cluster.local
🔹 5. ExternalName
- 역할: 서비스 이름을 외부 DNS 이름으로 매핑
- 외부 접근: ❌ (내부에서 외부 서비스로 접근)
- 주 용도: 외부 데이터베이스나 외부 API 서버를 DNS 이름으로 접근
- 접근 가능한 FQDN를 CNAME으로 매핑
- 특징:
- 파드에서
- ex-name.namespace.svc.cluster.local 형태로 접근
- 자동으로 외부 도메인으로 리디렉션
apiVersion: v1
kind: Service
metadata:
name: external-db
spec:
type: ExternalName
externalName: db.external.com
kubectl run mypod -it --image ubuntu
apt-get update
apt-get -y install dnsutils
dlg myex.default.svc.cluster.local
apt-get -y install iputils-ping
ping myex.default.svc.cluster.local
- ExternalName 서비스는 클러스터 내부에서 myex.default.svc.cluster.local 을 사용하면, 내부적으로 CNAME DNS를 통해 외부 도메인(여기선 www.google.com)으로 리다이렉션.
- 실제로 포트 포워딩은 안 되고, 단지 DNS 이름을 외부 도메인으로 매핑하는 역할만 합니다.
- 즉, 이건 단순한 도메인 이름 연결 트릭이지, TCP 로드밸런싱 같은 건 해주지 않습니다.
🔹 6. KUBE-proxy
- ClusterIP , NodePort로 접근 가능
- userspace proxy mode
- iptables proxy mode
- IPVS(IP Virtual Server) proxy mode
userspace mode
> 클라이언트의 서비스 요청을 iptables 통해
kube proxy가 수신 후 연결 모드
iptables mode
> Default Kubernetes Network Mode
IPSV mode
> kubespray 설치 시 사용하는 모드
kubectl get ds -A
daemonset
get ds -A -o wide | head -1 ; kubectl get pod -A -o wide | grep kube-proxy
'IT 엔지니어 > CLOUD' 카테고리의 다른 글
Labels/ Annotations (1) | 2025.06.01 |
---|---|
K8S - ingress (0) | 2025.05.31 |
K8S - STATEFULSET (0) | 2025.05.29 |
k8S - REPLICASET (0) | 2025.05.28 |
K8S- daemonset (0) | 2025.05.27 |