Kubernetes Services & Ingress. 프로젝트 #1
Source: Dev.to
전제 조건 (한 번)
minikube start
kubectl get nodes
예상
minikube Ready
기본 앱 (모든 프로젝트에 사용)
하나의 앱. 동일한 파드. 네트워킹만 변경됩니다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-app
spec:
replicas: 3
selector:
matchLabels:
app: demo
template:
metadata:
labels:
app: demo
spec:
containers:
- name: app
image: hashicorp/http-echo:0.2.3
args:
- "-listen=:8080"
- "-text=HELLO FROM POD"
ports:
- containerPort: 8080
kubectl apply -f deployment.yaml
kubectl get pods
Source: …
프로젝트 1 — ClusterIP (내부 전용)


이것이 증명하는 바
- 서비스는 안정적인 내부 네트워킹을 제공합니다
- Pod IP는 변경되지만 — 서비스는 절대 변하지 않습니다
ClusterIP 생성
apiVersion: v1
kind: Service
metadata:
name: demo-clusterip
spec:
selector:
app: demo
ports:
- port: 80
targetPort: 8080
kubectl apply -f svc-clusterip.yaml
kubectl get svc
테스트 (올바른 방법)
kubectl run test --rm -it --image=busybox -- sh
wget -qO- demo-clusterip
운영 이슈 #1 — 엔드포인트 없음
kubectl get endpoints demo-clusterip
원인
- Selector ≠ Pod 라벨
해결 방법
kubectl get pods --show-labels
kubectl edit svc demo-clusterip
DevOps 시사점
ClusterIP는 Kubernetes의 핵심입니다. 이것이 실패하면 — 아무것도 작동하지 않습니다.
Project 2 — NodePort (왜 위험한가)
이 것이 증명하는 바
- ✅ NodePort는 포트를 엽니다
- ❌ 라우팅, HA, 또는 안정적인 IP를 제공하지 않음
NodePort 생성
apiVersion: v1
kind: Service
metadata:
name: demo-nodeport
spec:
type: NodePort
selector:
app: demo
ports:
- port: 80
targetPort: 8080
nodePort: 30080
kubectl apply -f svc-nodeport.yaml
kubectl get svc
접근
minikube ip
curl http://<minikube-ip>:30080
프로덕션 이슈 #1 — 임의의 실패
kubectl delete pod -l app=demo
여전히 작동합니까?
YES → kube-proxy가 재라우팅합니다.
클라우드에서 노드가 삭제된 상황을 상상해 보세요 → ❌ 죽음.
프로덕션 이슈 #2 — 포트 차단
- Minikube에서는: ✅ 작동
- 클라우드에서는: ❌ 보안 그룹에 포트가 없음
DevOps 결론
| 판단 | 학습 | 디버그 | 프로덕션 |
|---|---|---|---|
| ✅ | ✅ | ✅ | ❌ |
Project 3 — LoadBalancer (Minikube 스타일)

이것이 증명하는 바
- ✅ Kubernetes LoadBalancer를 요청함
- ✅ Minikube가 클라우드 LB를 시뮬레이션함
LoadBalancer 생성
apiVersion: v1
kind: Service
metadata:
name: demo-lb
spec:
type: LoadBalancer
selector:
app: demo
ports:
- port: 80
targetPort: 8080
kubectl apply -f svc-lb.yaml
kubectl get svc
매우 중요 (Minikube 전용)
minikube tunnel # 이 터미널을 열어 둡니다
이제:
kubectl get svc demo-lb
다음과 같은 결과가 나옵니다:
EXTERNAL-IP: 127.0.0.1
PROD ISSUE #1 — EXTERNAL‑IP 대기 중
원인
- 터널이 없음
해결 방법
minikube tunnel
PROD ISSUE #2 — LB는 존재하지만 트래픽이 없음
kubectl describe svc demo-lb
kubectl get endpoints demo-lb
원인
- Pods가 Ready 상태가 아님
DevOps 결론
- ✔ 간단한 외부 애플리케이션에 적합
- ❌ 실제 클라우드에서는 비용이 많이 듦
- ❌ 서비스당 하나의 LB 필요
Project 4 — Ingress (REAL PRODUCTION MODEL)


What This Proves
- ✔ Ingress is the brain for external traffic
- ✔ One IP → many apps
STEP 1 — Enable Ingress in Minikube
minikube addons enable ingress
kubectl get pods -n ingress-nginx
Wait until
ingress-nginx-controller Running
STEP 2 — ClusterIP for Ingress
apiVersion: v1
kind: Service
metadata:
name: demo-ingress-svc
spec:
selector:
app: demo
ports:
- port: 80
targetPort: 8080
STEP 3 — Ingress Rule
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: demo-ingress
spec:
rules:
- host: demo.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: demo-ingress-svc
port:
number: 80
STEP 4 — DNS (Local)
minikube ip
sudo nano /etc/hosts
Add the following line to /etc/hosts:
<minikube-ip> demo.local
Test
curl http://demo.local
PROD ISSUE #1 — 404 from Ingress
kubectl describe ingress demo-ingress
Cause
- Wrong service name
- Wrong port
PROD ISSUE #2 — Ingress OK, app broken
kubectl get endpoints demo-ingress-svc
kubectl get pods
Cause
- No Ready pods
PROD ISSUE #3 — Ingress controller down
kubectl get pods -n ingress-nginx
kubectl logs -n ingress-nginx <controller-pod>
최종 DevOps 정신 모델 (Minikube 또는 Prod)
Client
|
v
Ingress (routing rules)
|
v
Service (ClusterIP)
|
v
Pod
최종 요약 표
| 구성 요소 | 목적 | 제공 주체 |
|---|---|---|
| ClusterIP | 내부 네트워킹 | Kubernetes |
| NodePort | 포트 노출 | Kubernetes |
| LoadBalancer | 외부 IP | Cloud / Minikube |
| Ingress | 라우팅 + TLS | Kubernetes |
| Egress | 아웃바운드 트래픽 | Cloud / NAT |
