Welcome! ๐Ÿ™‹โ€โ™‚๏ธ View more

Engineering ๐Ÿ’ป/MLOps

๋ณต์žกํ•œ ๋„คํŠธ์›Œํฌ๋ฅผ ๊ฐ„๋‹จํ•˜๊ฒŒ! Kubernetes Service๋ฅผ ์•Œ์•„๋ณด์ž (ClusterIP, NodePort, LoadBalancer)

DeepFlame 2025. 1. 13. 22:00

๊ฐœ์ธ์ ์œผ๋กœ Kubernetes ๋„คํŠธ์›Œํฌ๊ฐ€ ๋ณต์žกํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.
๊ทธ๋„ ์–ด์ฉ” ์ˆ˜ ์—†๋Š” ๊ฒŒ ํด๋Ÿฌ์Šคํ„ฐ ๋‚ด๋ถ€์— ์ˆ˜ ๋งŽ์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๋“ค์„ ์—ฐ๊ฒฐ์‹œํ‚ค๊ธฐ ์œ„ํ•ด์„œ๋Š” ๊ทธ๋Ÿด ์ˆ˜ ๋ฐ–์— ์—†์—ˆ์„ ๊ฒƒ์ด๋ผ~ ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.
๊ทธ๋ž˜๋„ ๋‚˜๋ฆ„ ๊ฐ„๋‹จํ•˜๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•œ ๋…ธ๋ ฅ๋„ ๋ณด์ด๋‹ˆ ์šฐ๋ฆฌ ํ•จ๊ป˜ ์ตœ๋Œ€ํ•œ ์ดํ•ดํ•ด๋ด…์‹œ๋‹ค!

 

Kubernetes Service ์™œ ํ•„์š”ํ•ด? ๐Ÿค”

๋จผ์ € ์šฐ๋ฆฌ๊ฐ€ ์ƒ๊ฐํ•ด๋ด์•ผํ•  ๊ฒŒ ์žˆ์Šต๋‹ˆ๋‹ค.
์™œ ์ด๊ฒŒ ํ•„์š”ํ• ๊นŒ์š”? 

Pod์˜ ์„ฑ์งˆ

์ด๋Š” Pod์˜ ์„ฑ์งˆ์— ๊ด€๋ จ์ด ์žˆ์Šต๋‹ˆ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด Deployment๋ฅผ ํ†ตํ•ด์„œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฐฐํฌ๋ฅผ ๊ด€๋ฆฌํ•˜๊ณ  ์žˆ๋Š”๋ฐ, Pod๊ฐ€ ๋ชจ์ข…์˜ ์ด์œ ๋กœ ์ฃฝ๊ฒŒ๋˜๊ณ  ๋‹ค์‹œ ์‚ด์•„๋‚ฌ๋‹ค๋ฉด 
์ด ์ „ Pod๊ฐ€ ์‚ฌ์šฉํ–ˆ๋˜ IP์™€ ์ƒˆ๋กœ ์ƒ์„ฑ๋œ Pod์˜ IP๋Š” ๋‹ค๋ฅด๊ฒŒ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ Pod IP๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ์œ„ํ—˜ํ•œ ๋ฐฉ๋ฒ•์ด๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ Deployment์™€ Pod์— ๋ผ๋ฒจ๋ง์„ ํ•˜๊ฒŒ ๋˜๊ณ , ์„œ๋น„์Šค๋Š” ์ด ๋ผ๋ฒจ๋ง์„ ์ฐพ์•„์„œ ํŠธ๋ž˜ํ”ฝ์„ ์ „๋‹ฌํ•ด์ฃผ๋Š” ์—ญํ• ์„ ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ  ์ด๋ฅผ ์„œ๋น„์Šค ๋””์Šค์ปค๋ฒ„๋ฆฌ๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ์•„๋ž˜์— ์„œ๋น„์Šค์— ์ ‘๊ทผํ•˜๋Š” ํŠธ๋ž˜ํ”ฝ์€ app.kubernetes.io/name: proxy์ธ Pod๋“ค์— ๋งคํ•‘๋˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
์„œ๋น„์Šค ์ ‘๊ทผ์€ ๋ณดํ†ต http://{service name}.{namespace} ๋กœ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
(์•„๋ž˜ ์„œ๋น„์Šค ์ ‘๊ทผ ์˜ˆ์‹œ http://nginx-service.system)

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
  namspace: system
spec:
  selector:  # label์ด 'app.kubernetes.io/name: proxy'๋ฅผ ๊ฐ€์ง„ Pod๋ฅผ ๋Œ€์ƒ์œผ๋กœํ•จ
    app.kubernetes.io/name: proxy
  ports:
  - name: name-of-service-port
    protocol: TCP
    port: 80
    targetPort: 8080

Kubernetes์˜ ๋ณต์žก์„ฑ

์œ„์— ์–ธ๊ธ‰ํ•œ ๋Œ€๋กœ Kubernetes์˜ ๋„คํŠธ์›Œํฌ๋Š” ๋ณต์žกํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ํŠธ๋ž˜ํ”ฝ์ด ์›ํ•˜๋Š” ๋Œ€๋กœ ์ „๋‹ฌ๋˜๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•œ ๊ณผ์ •์ด ๋ณต์žกํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ์™ธ๋ถ€ IP ํ˜ธ์ถœ์„ ํ†ตํ•ด์„œ ๋‚ด๊ฐ€ ์›ํ•˜๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊นŒ์ง€ ํŠธ๋ž˜ํ”ฝ์ด ์ „๋‹ฌ๋˜๊ณ  ์‹ถ๋‹ค๊ณ  ํ•ฉ์‹œ๋‹ค.
1. ๊ทธ๋ ‡๋‹ค๋ฉด ๋จผ์ € etcd์— ์ €์žฅ์„ ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ์›ํ•˜๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์–ด๋А ๋…ธ๋“œ์— ์žˆ๋Š”์ง€ ์•Œ์•„์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.
2. kube-proxy๋Š” ๊ฐ ๋…ธ๋“œ์˜ ๋„คํŠธ์›Œํฌ๋ฅผ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์—ฌ๊ธฐ์— ๋“ฑ๋ก์ด ๋˜์–ด์•ผ ํ•˜๋ฉฐ, ์ •ํ™•ํžˆ๋Š” iptable ๋˜๋Š” IP Virtual Service์— ๋“ฑ๋ก๋˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
3. ๋˜ํ•œ ์„œ๋น„์Šค ์ด๋ฆ„์œผ๋กœ ํด๋Ÿฌ์Šคํ„ฐ ๋‚ด๋ถ€ DNS๋ฅผ ๋“ฑ๋ก์„ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— Coredns์™€ ๊ฐ™์€ DNS ์‹œ์Šคํ…œ์— ๋“ฑ๋กํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ๋„คํŠธ์›Œํฌ ์„ค์ •๋“ค์„ ์„œ๋น„์Šค ๋“ฑ๋ก์„ ํ†ตํ•ด์„œ ๋น„๊ต์  ๊ฐ„๋‹จํžˆ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์–ด๋•Œ์š”? ์•Œ๊ณ ๋ณด๋‹ˆ ์„ ๋…€๊ฐ™์ฃ ? ๐Ÿ˜‚

 

 

Kubernetes Service ์ข…๋ฅ˜

Kubernetes์—์„œ๋Š” ํฌ๊ฒŒ 3๊ฐ€์ง€์˜ type์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

ClusterIP

๊ฐ€์žฅ ๊ธฐ๋ณธ ํƒ€์ž…์ด๋ฉฐ, ํด๋Ÿฌ์Šคํ„ฐ ๋‚ด๋ถ€ ํ†ต์‹ ์— ์ฃผ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
ํŠธ๋ž˜ํ”ฝ์„ ๋กœ๋“œ๋ฐธ๋Ÿฐ์‹ฑํ•ด์ฃผ๋ฉฐ, ์ด๋ฅผ ํ†ตํ•ด ํŠธ๋ž˜ํ”ฝ ๋ถ„์‚ฐ์„ ์ด๋ฃฐ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์•„๋ž˜ ๊ทธ๋ฆผ์„ ๋ณด๋ฉด Proxy๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋Š”๋ฐ์š”.
์œ„์— ์–ธ๊ธ‰ํ–ˆ๋‹ค์‹œํ”ผ ๊ฐ ๋…ธ๋“œ์˜ ๋„คํŠธ์›Œํฌ๋ฅผ ๊ด€์žฅํ•˜๋Š” Kube-Proxy์— ์„œ๋น„์Šค์˜ ์ •๋ณด๊ฐ€ ์ €์žฅ๋˜๊ธฐ ๋•Œ๋ฌธ์—,
ํŠธ๋ž˜ํ”ฝ์ด ์™”์„ ๋•Œ ์ ์ ˆํ•œ ์„œ๋น„์Šค๋กœ ๋งคํ•‘๋˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:  # label์ด 'app.kubernetes.io/name: proxy'๋ฅผ ๊ฐ€์ง„ Pod๋ฅผ ๋Œ€์ƒ์œผ๋กœํ•จ
    app.kubernetes.io/name: proxy
  ports:
  - name: name-of-service-port
    protocol: TCP
    port: 80  # ์™ธ๋ถ€์—์„œ Service์— ์ ‘๊ทผํ•  ๋•Œ ์‚ฌ์šฉ๋˜๋Š” ํฌํŠธ ๋ฒˆํ˜ธ
    targetPort: 8080  # Pod ๋‚ด๋ถ€์˜ ํฌํŠธ

 

NodePort

ClsuterIP์˜ ๊ธฐ๋Šฅ์— ๋”ํ•ด, ๋ชจ๋“  ๋…ธ๋“œ์˜ ํŠน์ • ํฌํŠธ๋ฅผ ๊ฐœ๋ฐฉํ•ฉ๋‹ˆ๋‹ค.
์ด๋Š” ํด๋Ÿฌ์Šคํ„ฐ ์™ธ๋ถ€์—์„œ ๋…ธ๋“œ์˜ IP์™€ ํ• ๋‹น๋œ ํฌํŠธ๋ฅผ ํ†ตํ•ด์„œ ํด๋Ÿฌ์Šคํ„ฐ ๋‚ด๋ถ€๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์•„๋ž˜ ๊ทธ๋ฆผ์„ ๋ณด๋ฉด VM(Virtual Machine = Node)์˜ ํฌํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋…ธ๋“œ ํฌํŠธ๋“ค์€ ์ด๋ฏธ ์™ธ๋ถ€์— ์˜คํ”ˆ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๊ฐ„๋‹จํ•˜๊ฒŒ ์™ธ๋ถ€ ํ˜ธ์ถœ์„ ๋ฐ›๋Š” ๋ฐฉ์‹์ด์—์š”.

๋…ธ๋“œ ํฌํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋…ธ๋“œ IP๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด ์ด์— ์˜ํ–ฅ์„ ๋ฐ›๋Š”๋‹ค๋Š” ์ ๊ณผ ๋…ธํŠธ ํฌํŠธ๊ฐ€ ํ•œ์ •์  (30000-32767) ์ด๋ผ๋Š” ์ ์ด ๋‹จ์ ์ž…๋‹ˆ๋‹ค.
๊ทธ๋ž˜์„œ ๋ณดํ†ต ์šด์˜ํ•  ๋•Œ๋Š” ์ด๋ ‡๊ฒŒ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ๊ฑฐ์˜ ์—†์ฃ .

piVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  type: NodePort
  selector:
    app.kubernetes.io/name: MyApp
  ports:
    - port: 80  # ์„œ๋น„์Šค ๋…ธ์ถœ ํฌ๋“œ
      targetPort: 80  # Pod์—์„œ ๋…ธ์ถœํ•˜๋Š” ํฌํŠธ
      # ์„ ํƒ์  ํ•„๋“œ (๋ช…์‹œํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ํฌํŠธ๋ฅผ ์ž๋™์œผ๋กœ ํ• ๋‹น)
      # ๊ธฐ๋ณธ์ ์œผ๋กœ ๊ทธ๋ฆฌ๊ณ  ํŽธ์˜์ƒ ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ์ปจํŠธ๋กค ํ”Œ๋ ˆ์ธ์€ ํฌํŠธ ๋ฒ”์œ„์—์„œ ํ• ๋‹นํ•œ๋‹ค(๊ธฐ๋ณธ๊ฐ’: 30000-32767)
      nodePort: 30007  # ๋งŒ์•ฝ 30007 ํฌํŠธ๊ฐ€ ์‚ฌ์šฉ ์ค‘์ด๋ผ๋ฉด ์‹คํŒจ

 

LoadBalancer

NodePort์˜ ๊ธฐ๋Šฅ์„ ํฌํ•จํ•˜๋ฉฐ, ์ถ”๊ฐ€๋กœ ํด๋ผ์šฐ๋“œ ์ œ๊ณต์ž์˜ ๋กœ๋“œ ๋ฐธ๋Ÿฐ์„œ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. 
๋ณดํ†ต ๋กœ๋“œ๋ฐธ๋Ÿฐ์„œ๋Š” ํด๋Ÿฌ์Šคํ„ฐ ์™ธ๋ถ€์— ์กด์žฌํ•˜๋ฉฐ, AWS, GCP ๋“ฑ์˜ ํด๋ผ์šฐ๋“œ ์„œ๋น„์Šค๊ฐ€ ์ œ๊ณตํ•˜๋Š” ํ”„๋กœ๋น„์ €๋‹๋œ ๋กœ๋“œ ๋ฐธ๋Ÿฐ์„œ์™€ ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ์—ฐ๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ  ์™ธ๋ถ€์—์„œ๋Š” ๋กœ๋“œ ๋ฐธ๋Ÿฐ์„œ์˜ IP๋ฅผ ํ†ตํ•ด์„œ ํด๋Ÿฌ์Šคํ„ฐ ๋‚ด๋ถ€์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•˜๋‚˜์˜ IP๋ฅผ ํ†ตํ•ด์„œ ์„œ๋น„์Šค๋ฅผ ๋…ธ์ถœ์‹œํ‚ค๊ธฐ ๋•Œ๋ฌธ์— ๊ด€๋ฆฌ์  ์ธก๋ฉด์—์„œ๋„ ํŽธํ•ด์ง€๋ฉฐ, ์šด์˜ ์ค‘์ธ ์„œ๋น„์Šค์—์„œ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค.
๋‹จ์ ์€ ์™ธ๋ถ€ Load Balancer๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋น„์šฉ์ด ๋ฐœ์ƒํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

apiVersion: v1
kind: Service
metadata:
  name: myapp-service
spec:
  type: LoadBalancer
  ports:
    - protocol: TCP
      port: 80  # ์„œ๋น„์Šค๋ฅผ ๋…ธ์ถœํ•˜๋Š” ํฌํŠธ
      targetPort: 80  # ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜(ํŒŒ๋“œ)๋ฅผ ๋…ธ์ถœํ•˜๋Š” ํฌํŠธ
  clusterIP: 10.0.171.239  # ํด๋Ÿฌ์Šคํ„ฐ IP
  selector:
    app: myapp
    type: frontend
status:
  loadBalancer:  # ํ”„๋กœ๋น„์ €๋‹๋œ ๋กœ๋“œ ๋ฐธ๋Ÿฐ์„œ ์ •๋ณด
    ingress:
    - ip: 192.0.2.127

 

์ •๋ฆฌ

์ฟ ๋ฒ„๋„คํ‹ฐ์Šค๋Š” ๋™์  IP๋ฅผ ๊ฐ€์ง€๋Š” Pod ํ™˜๊ฒฝ์—์„œ ์•ˆ์ •์ ์ธ ๋„คํŠธ์›Œํฌ๋ฅผ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•œ ์•„์ฃผ์•„์ฃผ ํ•ต์‹ฌ ์š”์†Œ์ž…๋‹ˆ๋‹ค.

๋ฌผ๋ก  ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค์—์„œ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋ณธ ๊ธฐ๋Šฅ์ด ์šฐ๋ฆฌ๊ฐ€ ์›ํ•˜๋Š” ์‚ฌํ•ญ์„ ์ถฉ์กฑ์‹œํ‚ค์ง€ ๋ชป ํ•ด์„œ Istio์™€ ๊ฐ™์€ ์™ธ๋ถ€ ํ”„๋กœ์ ํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค.
์ด๋Š” ๋‚˜์ค‘์— ๋˜ ์•Œ์•„๋ณด๋Š” ๊ฑธ๋กœ ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค ~~ 

 

์ฐธ๊ณ 

๋ชจ๋“  ๊ทธ๋ฆผ์€ ์•„๋ž˜ ์‚ฌ์ดํŠธ์—์„œ ๊ฐ€์ ธ์™”์Šต๋‹ˆ๋‹ค. 
https://medium.com/google-cloud/kubernetes-nodeport-vs-loadbalancer-vs-ingress-when-should-i-use-what-922f010849e0

์ž์„ธํ•œ ๋‚ด์šฉ์ด ์•Œ๊ณ  ์‹ถ๋‹ค๋ฉด Kubernetes ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”!

https://kubernetes.io/ko/docs/concepts/services-networking/service/