๐ŸŒ ํŒŒ๋“œ๊ฐ€ ์ฃฝ์–ด๋„ ์ฃผ์†Œ๋Š” ๋ฐ”๋€Œ์ง€ ์•Š๋Š”๋‹ค – Kubernetes Service ์™„๋ฒฝ ์ดํ•ด

์ฟ ๋ฒ„๋„คํ‹ฐ์Šค์—์„œ ํŒŒ๋“œ๋Š” ์ƒ๊ฒผ๋‹ค ์ฃฝ์—ˆ๋‹ค๋ฅผ ๋ฐ˜๋ณตํ•˜๊ณ , ์ฃฝ์„ ๋•Œ๋งˆ๋‹ค IP๊ฐ€ ๋ฐ”๋€๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์–ด๋–ป๊ฒŒ ํŒŒ๋“œ๋ฅผ ์ฐพ์•„์•ผ ํ• ๊นŒ์š”? IP๋ฅผ ํ•˜๋“œ์ฝ”๋”ฉํ•ด๋‘๋ฉด ์ฃฝ์„ ๋•Œ๋งˆ๋‹ค ์„ค์ •์„ ๋ฐ”๊ฟ”์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๊ฒŒ Service์ž…๋‹ˆ๋‹ค. ํŒŒ๋“œ๋“ค ์•ž์— ๊ณ ์ •๋œ ์ง„์ž…์ (VIP, Virtual IP)์„ ๋งŒ๋“ค์–ด์„œ, ํด๋ผ์ด์–ธํŠธ๋Š” ํ•ญ์ƒ ๊ฐ™์€ ์ฃผ์†Œ๋กœ ์ ‘๊ทผํ•˜๊ณ  Service๊ฐ€ ๋’ค์—์„œ ์‚ด์•„์žˆ๋Š” ํŒŒ๋“œ๋กœ ์—ฐ๊ฒฐํ•ด์ค๋‹ˆ๋‹ค.


๐Ÿ“‹ Service์˜ ์ข…๋ฅ˜ โ€” ์ƒํ™ฉ์— ๋งž๊ฒŒ ๊ณจ๋ผ ์“ฐ๊ธฐ

ํƒ€์ž…์ ‘๊ทผ ๋ฒ”์œ„์‚ฌ์šฉ ์ผ€์ด์Šค
ClusterIPํด๋Ÿฌ์Šคํ„ฐ ๋‚ด๋ถ€์—์„œ๋งŒ๋‚ด๋ถ€ ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค ๊ฐ„ ํ†ต์‹ 
NodePort๋ชจ๋“  ๋…ธ๋“œ์˜ ํŠน์ • ํฌํŠธ ๊ฐœ๋ฐฉ๊ฐœ๋ฐœ/ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ, ์™ธ๋ถ€ ์ ‘๊ทผ
LoadBalancerํด๋ผ์šฐ๋“œ ๋กœ๋“œ๋ฐธ๋Ÿฐ์„œ ์‚ฌ์šฉํ”„๋กœ๋•์…˜ ์™ธ๋ถ€ ๋…ธ์ถœ

๐Ÿ”ง ClusterIP โ€” ๋‚ด๋ถ€ ํ†ต์‹ ์˜ ๊ธฐ๋ณธ

# nginx-clusterip.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-clusterip
spec:
  type: ClusterIP        # ๊ธฐ๋ณธ๊ฐ’
  selector:
    app: nginx           # ์ด ๋ผ๋ฒจ์„ ๊ฐ€์ง„ ํŒŒ๋“œ๋ฅผ ๋ฌถ์Œ
  ports:
  - port: 80
    targetPort: 80
kubectl apply -f nginx-clusterip.yaml
kubectl get svc

ClusterIP๋Š” ์™ธ๋ถ€์—์„œ ์ ‘๊ทผ์ด ์•ˆ ๋ฉ๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธํ•˜๋ ค๋ฉด ์ž„์‹œ ํŒŒ๋“œ๋ฅผ ํด๋Ÿฌ์Šคํ„ฐ ๋‚ด๋ถ€์— ๋„์›Œ์„œ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

# ์ž„์‹œ ํŒŒ๋“œ๋กœ ๋‚ด๋ถ€ ํ†ต์‹  ํ…Œ์ŠคํŠธ
kubectl run test --image=busybox --rm -it -- \
  wget -qO- http://nginx-clusterip

# Nginx ๊ธฐ๋ณธ HTML์ด ์ถœ๋ ฅ๋˜๋ฉด ์„ฑ๊ณต!

๐Ÿ”ง NodePort โ€” ์™ธ๋ถ€์—์„œ ์ ‘๊ทผํ•˜๊ธฐ

# nginx-nodeport.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-nodeport
spec:
  type: NodePort
  selector:
    app: nginx
  ports:
  - port: 80
    targetPort: 80
    nodePort: 30080      # 30000-32767 ๋ฒ”์œ„์—์„œ ์ง€์ •
kubectl apply -f nginx-nodeport.yaml

# Master ๋…ธ๋“œ์—์„œ curl ํ…Œ์ŠคํŠธ
curl http://192.168.56.10:30080

# ํ˜ธ์ŠคํŠธ PC ๋ธŒ๋ผ์šฐ์ €์—์„œ๋„ http://192.168.56.10:30080 ์œผ๋กœ ์ ‘์† ๊ฐ€๋Šฅ

NodePort์˜ ์›๋ฆฌ: ์–ด๋А ๋…ธ๋“œ(๋งˆ์Šคํ„ฐ๋“  ์›Œ์ปค๋“ )๋กœ ๋“ค์–ด์™€๋„ 30080 ํฌํŠธ๋กœ ์˜ค๋ฉด ๋ฐฑ์—”๋“œ ํŒŒ๋“œ๋กœ ์—ฐ๊ฒฐํ•ด์ค๋‹ˆ๋‹ค. kube-proxy๊ฐ€ ๊ฐ ๋…ธ๋“œ์—์„œ iptables ๊ทœ์น™์„ ๊ด€๋ฆฌํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.


๐Ÿ” ์„œ๋น„์Šค ๋””์Šค์ปค๋ฒ„๋ฆฌ์˜ ํ•ต์‹ฌ โ€” Label Selector

์„œ๋น„์Šค๊ฐ€ ๋ฐฑ์—”๋“œ ํŒŒ๋“œ๋ฅผ ์ฐพ๋Š” ๊ธฐ์ค€์€ IP๊ฐ€ ์•„๋‹ˆ๋ผ Label์ž…๋‹ˆ๋‹ค.

selector:
  app: nginx  # ์ด ๋ผ๋ฒจ์ด ๋ถ™์€ ํŒŒ๋“œ๋Š” ์ „๋ถ€ ์„œ๋น„์Šค์— ํฌํ•จ

ํŒŒ๋“œ๊ฐ€ ์ฃฝ๊ณ  ์ƒˆ๋กœ ์ƒ๊ฒจ์„œ IP๊ฐ€ ๋ฐ”๋€Œ์–ด๋„, ๋ผ๋ฒจ๋งŒ ๋™์ผํ•˜๋ฉด ์„œ๋น„์Šค๋Š” ์ž๋™์œผ๋กœ ์ƒˆ ํŒŒ๋“œ๋กœ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค. ํŒŒ๋“œ์˜ IP๋ฅผ ๋ชฐ๋ผ๋„ ๋˜๋Š” ์ด์œ ๊ฐ€ ๋ฐ”๋กœ ์ด๊ฒƒ์ž…๋‹ˆ๋‹ค.


๐Ÿ” ์›Œ์ปค ๋…ธ๋“œ ๋ ˆ๋ฒจ์—์„œ ์ง์ ‘ ํ™•์ธํ•˜๊ธฐ

์‹ค์Šต ์ค‘์— “Worker ๋…ธ๋“œ์—์„œ ์ž๊ธฐ๊ฐ€ ์‹คํ–‰ ์ค‘์ธ ํŒŒ๋“œ๋ฅผ ์–ด๋–ป๊ฒŒ ๋ณด๋‚˜?” ๊ถ๊ธˆํ•ด์ ธ์„œ ์ง์ ‘ ๋“ค์–ด๊ฐ€๋ดค์Šต๋‹ˆ๋‹ค.

# ์ปจํ…Œ์ด๋„ˆ ๋Ÿฐํƒ€์ž„(containerd) ๋ ˆ๋ฒจ์—์„œ ์ง์ ‘ ํ™•์ธ
sudo crictl ps

# Master์—์„œ ํŠน์ • ๋…ธ๋“œ์˜ ํŒŒ๋“œ๋งŒ ํ•„ํ„ฐ๋ง
kubectl get pods -o wide --field-selector spec.nodeName=k8s-worker1

crictl ps๋ฅผ ๋ณด๋ฉด ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ๋ ˆ์ด์–ด ๋ฐ‘์—์„œ containerd๊ฐ€ ์‹ค์ œ๋กœ ํ”„๋กœ์„ธ์Šค๋ฅผ ๋Œ๋ฆฌ๊ณ  ์žˆ๋‹ค๋Š” ๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ถ”์ƒํ™” ๋ ˆ์ด์–ด ์•„๋ž˜๊ฐ€ ๊ถ๊ธˆํ•  ๋•Œ ์œ ์šฉํ•œ ๋ช…๋ น์–ด์ž…๋‹ˆ๋‹ค.


๐Ÿ’ก ์ •๋ฆฌ

ClusterIP์™€ NodePort๋ฅผ ์“ฐ๋ฉด:

  • ClusterIP โ†’ ๋‚ด๋ถ€ ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค๊ฐ€ ์„œ๋กœ๋ฅผ ์ฐพ๋Š” ์•ˆ์ •์ ์ธ ๋ฐฉ๋ฒ•
  • NodePort โ†’ ์™ธ๋ถ€ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ์„œ๋น„์Šค์— ์ ‘๊ทผํ•˜๋Š” ๋ฐฉ๋ฒ•

๋‹จ, NodePort๋Š” IP:ํฌํŠธ ์กฐํ•ฉ์ด ๋Š˜์–ด๋‚ ์ˆ˜๋ก ๊ด€๋ฆฌ๊ฐ€ ๋ณต์žกํ•ด์ง‘๋‹ˆ๋‹ค. ์„œ๋น„์Šค๊ฐ€ 10๊ฐœ๋ฉด ํฌํŠธ๋„ 10๊ฐœ๋ฅผ ๊ด€๋ฆฌํ•ด์•ผ ํ•˜์ฃ .

๋‹ค์Œ ๊ธ€์—์„œ๋Š” ์—ฌ๋Ÿฌ ์„œ๋น„์Šค๋ฅผ ํ•˜๋‚˜์˜ ๋„๋ฉ”์ธ์œผ๋กœ ํ†ตํ•ฉ ๊ด€๋ฆฌํ•˜๋Š” Ingress Controller๋ฅผ ๋‹ค๋ฃน๋‹ˆ๋‹ค.