[k8s] ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค Service (Headless / EndPoint / ExternalName)

์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ํด๋Ÿฌ์Šคํ„ฐ ์•ˆ์—๋Š” DNS Server๊ฐ€ ๋ณ„๋„๋กœ ์กด์žฌํ•œ๋‹ค. DNS Server์—๋Š” Service์˜ ๋„๋ฉ”์ธ ์ด๋ฆ„๊ณผ IP๊ฐ€ ์ €์žฅ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— Pod๊ฐ€ Service1์˜ ๋„๋ฉ”์ธ์„ ์งˆ์˜ํ•˜๋ฉด ip๋ฅผ ์•Œ๋ ค์ค€๋‹ค.

 

 

๋งŒ์•ฝ Pod๊ฐ€ User1์„ ์งˆ์˜ํ•˜๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ?? 

 

๋‚ด๋ถ€๋ง์—๋„ DNS์„œ๋ฒ„ ๊ตฌ์ถ•๋˜์–ด ์žˆ์„ ๊ฒƒ์ด๊ณ  ๋‚ด๋ถ€ ์„œ๋ฒ„๋“ค์ด ์ƒ๊ฒผ์„ ๋•Œ ํ•ด๋‹น ์ด๋ฆ„๋“ค์ด DNS์— ๋“ฑ๋ก๋œ๋‹ค. Pod๊ฐ€ User1์„ ์ฐพ์•˜์„ ๋•Œ ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค๋Š” ์ž์‹ ์˜ DNS Server์— User1์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— ์ƒ์œ„ DNS Server์—์„œ ์ด๋ฆ„์„ ์ฐพ๊ฒŒ ๋˜๊ณ  ip๋ฅผ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

 

๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์™ธ๋ถ€ ๋„คํŠธ์›Œํฌ๋„ ๊ฐ™์€ ๋ฉ”์ปค๋‹ˆ์ฆ˜์œผ๋กœ ๋™์ž‘ํ•œ๋‹ค. 

 

 

 

Headless

์•„๋ž˜ ๊ทธ๋ฆผ๊ณผ ๊ฐ™์ด Pod๊ฐ€ Pod1์— ์ ‘๊ทผํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•  ์ˆ˜ ์žˆ์„๊นŒ?

 

headless๋ฅผ ์ด์šฉํ•˜๋ฉด DNS Server์—” pod๋“ค์˜ DNS์™€ IP๋“ค์ด ๋“ฑ๋ก๋˜๊ณ  ์งˆ์˜๋ฅผ ํ†ตํ•ด Pod์˜ IP๋ฅผ ์•Œ์•„๋‚ด ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

์ด DNS Server๋Š” Pod๋“  Service๋“  ์ƒ์„ฑ๋˜๋ฉด ์ž๋™์œผ๋กœ ๋„๋ฉ”์ธ๊ณผ IP๊ฐ€ ์ €์žฅ๋œ๋‹ค. 

 

์ง€์ •๋˜๋Š” ๊ทœ์น™์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค. 

# {service์˜ ์ด๋ฆ„}.{namespace}.{svc}.cluster.local
service1.default.svc.cluster.local

# {Pod์˜ IP}.{namespace}.{pod}.cluster.local
20-109-5-11.default.pod.cluster.local

 

์ด๋Ÿฌํ•œ ๊ทœ์น™์„ ๊ฐ€์ง€๊ณ  ๋งŒ๋“ค์–ด์ง„ Domain Name์„ FQDN(Fully Qualified Domain Name)์ด๋ผ๊ณ  ํ•œ๋‹ค. 

 

 

Headless Service๋Š” 2๊ฐ€์ง€ ์„ค์ •์œผ๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค. 

1. ClusterIP ์†์„ฑ์— None์ด๋ผ๊ณ  ์ง€์ •. ํ•ด๋‹น ์„œ๋น„์Šค์˜ IP๋ฅผ ์ƒ์„ฑํ•˜์ง€ ์•Š๊ฒ ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธ

2. Pod์˜ ์†์„ฑ์— hostname ์ง€์ •. domain name์„ ๋„ฃ๊ณ  subdomain์— service์˜ ์ด๋ฆ„์„ ๋„ฃ์–ด์คŒ.

 

 

์ด๋ ‡๊ฒŒ headless service๋ฅผ ์ƒ์„ฑ ๋ฐ ์—ฐ๊ฒฐํ•˜๊ฒŒ ๋  ๊ฒฝ์šฐ, DNS Server์— Service์˜ IP๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— Service์˜ ์ด๋ฆ„์„ ํ˜ธ์ถœํ•˜๊ฒŒ ๋˜๋ฉด ์—ฐ๊ฒฐ๋œ ๋ชจ๋“  Pod์˜ IP๋ฅผ ๋ฐ˜ํ™˜ํ•ด์ค€๋‹ค. 

๊ทธ๋ฆฌ๊ณ  ํ•˜๋‹จ์— Pod๋ฅผ ๋ณด๋ฉด pod์˜ hostname์ด ์•ž์— ๋ถ™์–ด์žˆ๊ณ  ๋’ค์—๋Š” subdomain์ด ๋“ค์–ด์žˆ๋‹ค. ๋”ฐ๋ผ์„œ pod4.headless1 (hostname.subdomain) ํ˜•์‹์œผ๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

 

Service ์ƒ์„ฑ ์‹œ ClusterIP์ผ๋•Œ์™€ Headless์ผ ๋•Œ์˜ ์ฐจ์ด๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

Headless์—์„  Service์˜ IP๊ฐ€ ์‚ฌ๋ผ์ง€๊ณ  Service๊ฐ€ ํฌํ•จํ•˜๊ณ ์žˆ๋Š” Pod๋“ค์˜ IP๋“ค์ด ์กฐํšŒ๋œ๋‹ค. 

 

 

pod์—์„œ ๋‹ค๋ฅธ pod๋กœ ์ ‘๊ทผํ•˜๋Š” ํ…Œ์ŠคํŠธ๋ฅผ ํ•ด๋ณด์•˜๋‹ค. 

 

1. Pod์—์„œ Service๋ฅผ ๊ฑฐ์ณ Pod๋กœ ์š”์ฒญ

apiVersion: v1
kind: Service
metadata:
  name: clusterip1
spec:
  selector:
    svc: clusterip
  ports:
  - port: 80
    targetPort: 8080
    
    
apiVersion: v1
kind: Pod
metadata:
  name: pod1
  labels:
    svc: clusterip
spec:
  containers:
  - name: container
    image: kubetm/app
    
    
apiVersion: v1
kind: Pod
metadata:
  name: request-pod
spec:
  containers:
  - name: container
    image: kubetm/init

 

request pod์—์„œ service๋กœ curl ์š”์ฒญ์„ ๋ณด๋‚ด๋ฉด Hostname์ด ์ž˜ ๋œจ๋Š” ๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

 

2. pod์—์„œ ๋‹ค๋ฅธ pod๋กœ service๋ฅผ ๊ฑฐ์น˜์ง€ ์•Š๊ณ  ์š”์ฒญ ๋ณด๋‚ด๊ธฐ

Service์™€ Pod2๊ฐœ๋ฅผ ์ƒ์„ฑํ•ด์ค€๋‹ค. 

apiVersion: v1
kind: Service
metadata:
  name: headless1
spec:
  selector:
    svc: headless
  ports:
    - port: 80
      targetPort: 8080    
  clusterIP: None
  -----------------------
apiVersion: v1
kind: Pod
metadata:
  name: pod4
  labels:
    svc: headless
spec:
  hostname: pod-a # hostname ์„ค์ •
  subdomain: headless1 # service ์ด๋ฆ„
  containers:
  - name: container
    image: kubetm/app
-----------------------
apiVersion: v1
kind: Pod
metadata:
  name: pod5
  labels:
    svc: headless
spec:
  hostname: pod-b # hostname ์„ค์ •
  subdomain: headless1 # service ์ด๋ฆ„
  containers:
  - name: container
    image: kubetm/app

 

nslookup headless1 ๋ช…๋ น์–ด๋กœ dns์— ์งˆ์˜๋ฅผ ํ•ด๋ณด๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ๋‚˜์˜จ๋‹ค.

 

DNS Server์—๋„ ๋“ฑ๋ก๋˜์–ด์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์•„๋ž˜์™€ ๊ฐ™์ด ์งˆ์˜๋ฅผ ํ•ด๋„ ํ•ด๋‹น Pod์˜ IP๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. 

nslookup headless1
nslookup pod-a.headless1
nslookup pod-b.headless1

 

 

๋”ฐ๋ผ์„œ ์•„๋ž˜์™€ ๊ฐ™์ด curl๋ช…๋ น์–ด๋ฅผ ๋‚ ๋ฆฌ๋ฉด ์ž˜ ์‘๋‹ต์ด ์˜จ๋‹ค.

curl pod-a.headless1:8080/hostname
curl pod-b.headless1:8080/hostname

 

 

 

 

 

 

 

Endpoint

์‚ฌ์šฉ์ž ์ž…์žฅ์—์„œ๋Š” Service์™€ Pod๊ฐ€ ๋‹ค์ด๋ ‰ํŠธ๋กœ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋Š” ๊ฒƒ ๊ฐ™์ง€๋งŒ, ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ๋‚ด๋ถ€์ ์œผ๋กœ๋Š” EndPoint๋ผ๋Š” ๊ฒƒ์ด ์ƒ์„ฑ๋˜์–ด ์—ฐ๊ฒฐ๋œ๋‹ค. 

 

์ฟ ๋ฒ„๋„คํ‹ฐ์Šค๋Š” Service์˜ ์ด๋ฆ„๊ณผ ๋™์ผํ•œ ์ด๋ฆ„์œผ๋กœ EndPoint๋ฅผ ์„ค์ •ํ•˜๊ณ  ๋‚ด๋ถ€์—๋Š” pod์˜ ์ ‘์† ์ •๋ณด๋ฅผ ์ €์žฅํ•œ๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ์ด ๊ทœ์น™๋งŒ ์•Œ๊ณ  ์žˆ๋‹ค๋ฉด label/selector์„ ๋งŒ๋“ค์ง€ ์•Š๊ณ ๋„ Service์™€ Pod๋ฅผ ์ง์ ‘ ์—ฐ๊ฒฐ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค. 

 

 

์ด๋•Œ IP๋Š” ๋ณ€๊ฒฝ ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— DNS Server๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š”๋ฐ, ์ด๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด ExternalName์ด๋‹ค. 

 

 

 

EndPoint ์ž๋™ ์ƒ์„ฑ, ์ง์ ‘ ์ƒ์„ฑ์„ ๋น„๊ตํ•˜๊ธฐ ์œ„ํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ–ˆ๋‹ค. 

 

1. ์—”๋“œํฌ์ธํŠธ ์ž๋™ ์ƒ์„ฑ ํ™•์ธ

apiVersion: v1
kind: Service
metadata:
  name: endpoint1
spec:
  selector:
    svc: endpoint
  ports:
  - port: 8080
  
  
  apiVersion: v1
kind: Pod
metadata:
  name: pod7
  labels:
    svc: endpoint
spec:
  containers:
  - name: container
    image: kubetm/app

 

service์˜ ์ด๋ฆ„์ธ endpoint1์ด๋ผ๋Š” ์ด๋ฆ„์˜ endpoint object๊ฐ€ ์ƒ์„ฑ๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ฒฐ๊ตญ label/selector๋ฅผ ์ง€์ •ํ•˜๋ฉด ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค๊ฐ€ service์˜ ์ด๋ฆ„๊ณผ ๋™์ผํ•œ endpoint๋ฅผ ์•Œ์•„์„œ ๋งŒ๋“ ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

 

2. ์—”๋“œํฌ์ธํŠธ ์ง์ ‘ ์ง€์ •

apiVersion: v1
kind: Service
metadata:
  name: endpoint2
spec:
  ports:
  - port: 8080


apiVersion: v1
kind: Pod
metadata:
  name: pod9
spec:
  containers:
  - name: container
    image: kubetm/app
    
    
    
apiVersion: v1
kind: Endpoints
metadata:
  name: endpoint2
subsets:
 - addresses:
   - ip: 192.168.226.109 # ์œ„์—์„œ ๋งŒ๋“ค์–ด์ง„ pod์˜ ip.
   ports:
   - port: 8080

 

 

 

์ด์ œ request pod์— ์ ‘์†ํ•˜์—ฌ curl ๋ช…๋ น์„ ๋‚ ๋ฆฌ๋ฉด ์ •์ƒ์ ์œผ๋กœ pod๊ฐ€ ์—ฐ๊ฒฐ๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

curl endpoint2:8080/hostname

 

 

 

 

ExternalName

Service์— ExternalName์ด๋ผ๋Š” ์†์„ฑ์„ ๋„ฃ์–ด์„œ Domain ์ด๋ฆ„์„ ์ถ”๊ฐ€ํ•˜๋ฉด DNS cache๊ฐ€ ๋‚ด๋ถ€/์™ธ๋ถ€ DNS Server๋ฅผ ํ™•์ธํ•˜์—ฌ IP๋ฅผ ์•Œ์•„๋‚ธ๋‹ค. 

 

 

๋งŒ์•ฝ Pod์—์„œ ์ ‘๊ทผํ•˜๋Š” ์‚ฌ์ดํŠธ๊ฐ€ ๋ณ€๊ฒฝ๋˜๋”๋ผ๋„ Pod๋Š” Service๋งŒ ๊ฐ€๋ฅดํ‚ค๊ณ  ์žˆ๋‹ค๋ฉด ๋”ฐ๋กœ ์žฌ๋ฐฐํฌ ํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค.

 

 

 

 

์•„๋ž˜์™€ ๊ฐ™์ด Service๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ExternalName์„ ์„ค์ •ํ•ด์ค„ ์ˆ˜ ์žˆ๋‹ค.

apiVersion: v1
kind: Service
metadata:
 name: externalname1
spec:
 type: ExternalName
 externalName: github.github.io

 

 

 

์œ„์™€ ๊ฐ™์ด ExternalName์„ ์„ค์ •ํ–ˆ๋‹ค๋ฉด Service์ด๋ฆ„์œผ๋กœ curl์š”์ฒญ์„ ๋‚ ๋ ธ์„ ๋•Œ ์ž˜ ๋™์ž‘ํ•œ๋‹ค. 

curl -O externalname1/kubetm/kubetm.github.io/blob/master/sample/practice/intermediate/service-sample.md