ํฐ์คํ ๋ฆฌ ๋ทฐ
Kubernetes ๋คํธ์ํน ์์ ์ ๋ณต: DNS๋ถํฐ ์๋น์ค, ํฌ๋ก์ค ๋ ธ๋ ํต์ ๊น์ง
kimub 2026. 3. 29. 20:37๐ค AI Assisted Content
์ด ๊ธ์ AI(Claude, Anthropic)์ ๋์์ ๋ฐ์ ์์ฑ๋์์ต๋๋ค.
์์ฑ์๊ฐ ๋ด์ฉ์ ๊ฒํ ํ๊ณ ํธ์งํ์ผ๋, AI๊ฐ ์ด์ ์์ฑ ๋ฐ ๊ตฌ์ฑ์ ์ฐธ์ฌํ์์ ๋ฐํ๋๋ค.
์ ์ฟ ๋ฒ๋คํฐ์ค ๋คํธ์ํน์ ์ดํดํด์ผ ํ๋๊ฐ
์ฟ ๋ฒ๋คํฐ์ค๋ฅผ ํ์ตํ๋ค ๋ณด๋ฉด ํ๋๋ฅผ ๋ฐฐํฌํ๊ณ ๋ํ๋ก์ด๋จผํธ๋ฅผ ๋ง๋๋ ๊ฒ๊น์ง๋ ๋น๊ต์ ์์ํ๊ฒ ๋ฐ๋ผ๊ฐ๋ค. ํ์ง๋ง "์ด ํ๋์์ ์ ํ๋๋ก ์ด๋ป๊ฒ ํต์ ํ์ง?", "์ธ๋ถ์์ ์ด๋ป๊ฒ ์ ๊ทผํ์ง?" ๊ฐ์ ์ง๋ฌธ์ ๋ถ๋ชํ๋ ์๊ฐ ๋คํธ์ํน์ด๋ผ๋ ๋ฒฝ์ ๋ง๋๊ฒ ๋๋ค.
์ด ๊ธ์์๋ ์ฟ ๋ฒ๋คํฐ์ค ๋คํธ์ํน์ ํต์ฌ 3๊ฐ์ง๋ฅผ ์ ๋ฆฌํ๋ค:
- ํ๋ ๊ฐ ๋ด๋ถ ํต์ — DNS์ CoreDNS์ ์ญํ
- ์๋น์ค ์ ํ๋ณ ํธ๋ํฝ ํ๋ฆ — ClusterIP, LoadBalancer, NodePort, ExternalName
- ๋ค๋ฅธ ๋ ธ๋์ ์๋ ํ๋๋ผ๋ฆฌ์ ํต์ — CNI์ VXLAN Overlay
1. ํ๋ ๊ฐ ํต์ ์ ๊ทผ๋ณธ์ ์ธ ๋ฌธ์
ํ๋๊ฐ ๋ค๋ฅธ ํ๋์ ํต์ ํ๋ ค๋ฉด IP ์ฃผ์๊ฐ ํ์ํ๋ค. ๊ทธ๋ฐ๋ฐ ์ฌ๊ธฐ์ ๋ ๊ฐ์ง ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค.
์ฒซ์งธ, ํ๋๋ ์ผ์์ (ephemeral)์ด๋ค. ํ๋๊ฐ ์ฌ์์ฑ๋๋ฉด IP ์ฃผ์๊ฐ ๋ฐ๋๋ค. ๋์งธ, ๋ฐ๋ IP๋ฅผ ์ ๋ฐฉ๋ฒ์ด ๋ง๋ ์น ์๋ค. ์ IP๋ฅผ ํ์ ํ๋ ค๋ฉด Kubernetes API๋ฅผ ์ง์ ํธ์ถํด์ผ ํ๋ค.
์ธํฐ๋ท์์ ์ด ๋ฌธ์ ๋ฅผ ์ด๋ป๊ฒ ํด๊ฒฐํ๋์ง ๋ ์ฌ๋ ค ๋ณด๋ฉด, ๋ต์ ๊ฐ๋ค. ๋๋ฉ์ธ ๋ค์ ์์คํ (DNS)์ด๋ค. ์ฟ ๋ฒ๋คํฐ์ค๋ ํด๋ฌ์คํฐ ์ ์ฉ DNS ์๋ฒ๋ฅผ ๋๊ณ , ์๋น์ค ์ด๋ฆ๊ณผ IP ์ฃผ์๋ฅผ ๋งคํํ์ฌ ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ค.
์๋น์ค — ํ๋๋ฅผ ์ํ ์์ ์ ์ธ ์ง์ ์
์๋น์ค(Service)๋ ํ๋๋ค์ด ๊ณต์ ํ๋ ๊ฐ์ ์ฃผ์(Virtual IP)๋ค. ๋ํ๋ก์ด๋จผํธ๊ฐ ๋ ์ด๋ธ ์ ๋ ํฐ๋ก ํ๋๋ฅผ ๊ด๋ฆฌํ๋ฏ, ์๋น์ค๋ ๋ ์ด๋ธ ์ ๋ ํฐ๋ก ๋์ ํ๋์ ๋์จํ๊ฒ ์ฐ๊ฒฐ๋๋ค. ์ด๋ ์๋น์ค์ ํ๋ ์ฌ์ด์๋ Endpoints(๋๋ EndpointSlice) ๋ฆฌ์์ค๊ฐ ์ค๊ฐ ๋ค๋ฆฌ ์ญํ ์ ํ๋ค. ์ ๋ ํฐ์ ์ผ์นํ๋ ํ๋์ IP:Port ๋ชฉ๋ก์ด Endpoints์ ์๋ ๋ฑ๋ก๋๊ณ , kube-proxy๋ ์ด ๋ชฉ๋ก์ ์ฐธ์กฐํ์ฌ ํธ๋ํฝ์ ๋ผ์ฐํ ํ๋ค.
์๋น์ค๊ฐ ์๋ ํ๋๋ ๋๋ฉ์ธ ๋ค์์ผ๋ก ์ ๊ทผํ ์ ์๋ค. ์๋น์ค๋ฅผ ๋ง๋ค์ด์ผ DNS ๋ ์ฝ๋๊ฐ ์์ฑ๋๊ณ , ๋ค๋ฅธ ํ๋์์ ์ด๋ฆ์ผ๋ก ํต์ ํ ์ ์๊ฒ ๋๋ค.
2. CoreDNS — ์ฟ ๋ฒ๋คํฐ์ค์ ์ ์ฉ DNS ์๋ฒ
์ฟ ๋ฒ๋คํฐ์ค์ "์ ์ฉ DNS ์๋ฒ"๋ ๋ฐ๋ก CoreDNS ํ๋๋ค.
CoreDNS๋ Go ์ธ์ด๋ก ์์ฑ๋ ํ๋ฌ๊ทธ์ธ ๊ธฐ๋ฐ์ DNS ์๋ฒ๋ก, Kubernetes 1.11๋ถํฐ ๊ธฐ๋ณธ ํด๋ฌ์คํฐ DNS๋ก ์ฑํ๋์๋ค. ์ด์ ์ ์ฌ์ฉํ๋ kube-dns๋ dnsmasq + kube-dns + sidecar 3๊ฐ์ ์ปจํ ์ด๋๋ก ๊ตฌ์ฑ๋์์ง๋ง, CoreDNS๋ ๋จ์ผ ์ปจํ ์ด๋, ๋จ์ผ ํ๋ก์ธ์ค๋ก ๋์ํด ํจ์ฌ ๋จ์ํ๋ค.
CoreDNS ๋ฐฐํฌ ๊ตฌ์กฐ
| ๊ตฌ์ฑ ์์ | ์ด๋ฆ | ์ค๋ช |
|---|---|---|
| Deployment | coredns |
kube-system ๋ค์์คํ์ด์ค, ๊ธฐ๋ณธ 2 ๋ ํ๋ฆฌ์นด (๊ณ ๊ฐ์ฉ์ฑ) |
| Service | kube-dns |
kube-system ๋ค์์คํ์ด์ค. ์ด๋ฆ์ด "kube-dns"์ธ ์ด์ ๋ ํ์ ํธํ์ฑ |
| ConfigMap | coredns |
Corefile(์ค์ ํ์ผ)์ ๋ด๊ณ ์์ |
| ClusterRole | system:coredns |
Service, Endpoints, Pod, Namespace์ ๋ํ list/watch ๊ถํ |
# CoreDNS ํ๋ ํ์ธ
kubectl get pods -n kube-system -l k8s-app=kube-dns
# CoreDNS ์๋น์ค์ ClusterIP ํ์ธ
kubectl get svc -n kube-system kube-dns
# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
# kube-dns ClusterIP 192.168.194.138 <none> 53/UDP,53/TCP,9153/TCP 573d
Corefile — CoreDNS์ ํต์ฌ ์ค์
.:53 {
errors # ์๋ฌ๋ฅผ stdout์ผ๋ก ์ถ๋ ฅ
health { lameduck 5s } # ํฌ์ค์ฒดํฌ ์๋ํฌ์ธํธ
ready # readiness ํ๋ก๋ธ ์๋ํฌ์ธํธ
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure # ํ๋ A ๋ ์ฝ๋ ์์ฑ (kube-dns ํธํ)
fallthrough in-addr.arpa ip6.arpa
ttl 30 # DNS TTL 30์ด
}
prometheus :9153 # ๋ฉํธ๋ฆญ ๋
ธ์ถ
forward . /etc/resolv.conf # cluster.local ์ธ ์ฟผ๋ฆฌ๋ฅผ upstream DNS๋ก ์ ๋ฌ
cache 30 # 30์ด๊ฐ ์๋ต ์บ์
loop # ๋ฌดํ ๋ฃจํ ๊ฐ์ง ์ ์ข
๋ฃ
reload # Corefile ๋ณ๊ฒฝ ์ ์๋ ๋ฆฌ๋ก๋
loadbalance # A/AAAA ๋ ์ฝ๋ ๋ผ์ด๋๋ก๋น
}
๊ฐ์ฅ ์ค์ํ ๊ฒ์ kubernetes ํ๋ฌ๊ทธ์ธ์ด๋ค. CoreDNS๊ฐ ์์๋๋ฉด Kubernetes API ์๋ฒ์ ์ฐ๊ฒฐํ์ฌ Service, Endpoints, Pod ๋ฆฌ์์ค๋ฅผ watchํ๊ณ , ์์ ํ ์ ๋ณด๋ฅผ ์ธ๋ฉ๋ชจ๋ฆฌ์ ์บ์ํ๋ค. DNS ์ฟผ๋ฆฌ๊ฐ ๋ค์ด์ค๋ฉด API ์๋ฒ์ ๋งค๋ฒ ์ง์ํ์ง ์๊ณ ์บ์์์ ๋ฐ๋ก ์๋ตํ๋ค. ์๋น์ค๊ฐ ์์ฑ/์ญ์ ๋๋ฉด watch ์ด๋ฒคํธ๋ฅผ ํตํด ์ค์๊ฐ์ผ๋ก ์บ์๊ฐ๊ฐฑ์ ๋๋ค.
DNS ์กฐํ ์ ์ฒด ํ๋ฆ (7๋จ๊ณ)
ํ๋์์ ์๋น์ค๋ก ํธ๋ํฝ์ด ์ ๋ฌ๋๋ ์ ์ฒด ๊ณผ์ ์ ๋ค์๊ณผ ๊ฐ๋ค.
- ํ๋ ๋ด ์ ํ๋ฆฌ์ผ์ด์
์ด ์๋น์ค ์ด๋ฆ(์:
my-service)์ผ๋ก ์์ฒญ์ ๋ณด๋ธ๋ค. - ํ๋์
/etc/resolv.conf์ ์ง์ ๋ nameserver(CoreDNS์ ClusterIP)๋ก DNS ์ฟผ๋ฆฌ๊ฐ ์ ์ก๋๋ค. - resolv.conf์ search ๋๋ฉ์ธ์ ๋ฐ๋ผ
my-service.<namespace>.svc.cluster.local๋ก ํ์ฅ๋๋ค. - CoreDNS๊ฐ ์บ์์์ ํด๋น ์๋น์ค์ ClusterIP๋ฅผ ์ฐพ์ ๋ฐํํ๋ค.
- ํ๋๊ฐ ๋ฐํ๋ฐ์ ClusterIP๋ก ํจํท์ ์ ์กํ๋ค.
- kube-proxy๊ฐ ์ค์ ํ iptables/IPVS ๊ท์น์ ์ํด ClusterIP๊ฐ ์ค์ ํ๋ IP๋ก DNAT๋๋ค.
- ํจํท์ด CNI ํ๋ฌ๊ทธ์ธ์ด ๊ตฌ์ฑํ ๋คํธ์ํฌ๋ฅผ ํตํด ๋์ ํ๋์ ๋๋ฌํ๋ค.
# ํ๋ ๋ด๋ถ์ /etc/resolv.conf (kubelet์ด ์๋ ์ค์ )
nameserver 10.96.0.10
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5
๐ก ndots:5๋? ์ฟผ๋ฆฌ์ ์ (
.)์ด 5๊ฐ ๋ฏธ๋ง์ด๋ฉด FQDN์ด ์๋ ๊ฒ์ผ๋ก ๊ฐ์ฃผํ๊ณ , search ๋๋ฉ์ธ์ ์์์๋ถํฐ ํ๋์ฉ ๋ถ์ฌ์ ์กฐํํ๋ค.my-service๋ผ๊ณ ์ ๋ ฅํ๋ฉด ๋จผ์ my-service.default.svc.cluster.local์ ์๋ํ๋ ์ด์ ๋ค.
DNS ์ด๋ฆ ํด์ ๊ท์น
| ์ฟผ๋ฆฌ | ํด์ ๊ฒฐ๊ณผ | ์ค๋ช |
|---|---|---|
my-service |
my-service.default.svc.cluster.local |
๊ฐ์ ๋ค์์คํ์ด์ค |
my-service.prod |
my-service.prod.svc.cluster.local |
๋ค๋ฅธ ๋ค์์คํ์ด์ค |
my-service.prod.svc.cluster.local |
๊ทธ๋๋ก | FQDN ์ง์ ์กฐํ |
google.com |
upstream DNS๋ก forward | cluster.local์ ์๋ ์ธ๋ถ ๋๋ฉ์ธ |
CoreDNS๊ฐ ์์ฑํ๋ DNS ๋ ์ฝ๋
| ๋ ์ฝ๋ | ๋์ | FQDN ํ์ | ๋ฐํ๊ฐ |
|---|---|---|---|
| A/AAAA | ์ผ๋ฐ Service | <svc>.<ns>.svc.cluster.local |
ClusterIP |
| A/AAAA | Headless Service | <svc>.<ns>.svc.cluster.local |
ํ๋ IP ๋ชฉ๋ก |
| SRV | ์ด๋ฆ ์๋ ํฌํธ | _<port>._<proto>.<svc>.<ns>.svc.cluster.local |
ํฌํธ ๋ฒํธ + ๋๋ฉ์ธ |
| CNAME | ExternalName Service | <svc>.<ns>.svc.cluster.local |
์ธ๋ถ ๋๋ฉ์ธ๋ช |
๋ค์์คํ์ด์ค์ DNS
๋ชจ๋ ์ฟ ๋ฒ๋คํฐ์ค ๋ฆฌ์์ค๋ ๋ค์์คํ์ด์ค ์์ ์กด์ฌํ๋ค. ๊ฐ์ ๋ค์์คํ์ด์ค์์๋ ์๋น์ค ์ด๋ฆ๋ง์ผ๋ก ์ ๊ทผ ๊ฐ๋ฅํ๊ณ , ๋ค๋ฅธ ๋ค์์คํ์ด์ค์ ์๋น์ค๋ FQDN์ด ํ์ํ๋ค.
# ๊ฐ์ ๋ค์์คํ์ด์ค (default → default)
kubectl exec deploy/sleep-1 -- sh -c 'nslookup numbers-api'
# → numbers-api.default.svc.cluster.local → 192.168.194.228
# ๋ค๋ฅธ ๋ค์์คํ์ด์ค์ ์๋น์ค (default → kube-system)
kubectl exec deploy/sleep-1 -- sh -c 'nslookup kube-dns.kube-system.svc.cluster.local'
# → 192.168.194.138
3. ์๋น์ค ์ ํ๋ณ ํธ๋ํฝ ํ๋ฆ
ClusterIP — ํด๋ฌ์คํฐ ๋ด๋ถ ์ ์ฉ
๊ฐ์ฅ ๊ธฐ๋ณธ์ด ๋๋ ์๋น์ค ์ ํ์ด๋ค. ํด๋ฌ์คํฐ ์ ์ฒด์์ ์ ํจํ ๊ฐ์ IP๋ฅผ ์์ฑํ๋ฉฐ, ํ๋๊ฐ ์ด๋ ๋ ธ๋์ ์๋ ์ด IP๋ก ์ ๊ทผ ๊ฐ๋ฅํ๋ค. ๋จ, ํด๋ฌ์คํฐ ์ธ๋ถ์์๋ ์ ๊ทผ ๋ถ๊ฐํ๋ค.
kubectl apply -f sleep/sleep2-service.yaml
# service/sleep-2 created
kubectl get svc sleep-2
# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
# sleep-2 ClusterIP 192.168.194.221 <none> 80/TCP 7s
โ ๏ธ ClusterIP๋ก๋ ping์ด ์ ๋๋ค. ClusterIP๋ ๋คํธ์ํฌ ์ธํฐํ์ด์ค์ ๋ฐ์ธ๋ฉ๋ ์ค์ IP๊ฐ ์๋๋ผ, kube-proxy๊ฐ iptables ๊ท์น์ผ๋ก ํน์ ํ๋กํ ์ฝ:ํฌํธ ์กฐํฉ์ ๋ํด์๋ง DNAT์ ์ํํ๋ ๊ฐ์ IP๋ค. ํฌํธ ๊ฐ๋ ์ด ์๋ ICMP(ping) ํจํท์ ๋งค์นญ๋๋ ๊ท์น์ด ์์ด ๋๋กญ๋๋ค.
# ping์ ์คํจํ๋ค
kubectl exec deploy/sleep-1 -- ping -c 1 sleep-2
# PING sleep-2 (192.168.194.221): 56 data bytes
# (์๋ต ์์)
# TCP ๊ธฐ๋ฐ ํ์ธ์ ์ฑ๊ณตํ๋ค
kubectl exec deploy/sleep-1 -- wget -qO- http://sleep-2
kubectl exec deploy/sleep-1 -- nc -zv sleep-2 80
LoadBalancer — ์ธ๋ถ ํธ๋ํฝ์ ํ๋ก๋์ ์ง์ ์
์ธ๋ถ์์ ํด๋ฌ์คํฐ๋ก ํธ๋ํฝ์ ์ ๋ฌํ๋ ๊ฐ์ฅ ์ผ๋ฐ์ ์ธ ๋ฐฉ๋ฒ์ด๋ค. ํด๋ผ์ฐ๋ ํ๊ฒฝ์์๋ ์ค์ ๋ก๋๋ฐธ๋ฐ์๊ฐ ํ๋ก๋น์ ๋๋๋ค.
kubectl get svc numbers-web
# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
# numbers-web LoadBalancer 192.168.194.241 192.168.139.2 8080:30732/TCP 61s
์ฌ๊ธฐ์ ์ฃผ๋ชฉํ ์ ์ 8080:30732/TCP๋ผ๋ ์ถ๋ ฅ์ด๋ค. 8080์ ์๋น์ค ํฌํธ, 30732๋ ์๋ ์์ฑ๋ NodePort๋ค. ์ด๊ฒ์ด ์๋น์ค์ Superset ๊ตฌ์กฐ๋ฅผ ๋ณด์ฌ์ค๋ค:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ LoadBalancer Service โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ NodePort Service โ โ
โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ โ
โ โ โ ClusterIP Service โ โ โ
โ โ โ (๊ฐ์ IP: 10.96.x.x) โ โ โ
โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ โ
โ โ NodePort: 30000-32767 โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ External LB + External IP โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
LoadBalancer๋ฅผ ๋ง๋ค๋ฉด NodePort์ ClusterIP๊ฐ ์๋์ผ๋ก ํฌํจ๋๋ค. ์ฆ, LoadBalancer ์๋น์ค๋ ์ธ๋ถ IP + NodePort + ClusterIP ์ธ ๊ฐ์ง ์ ๊ทผ ๋ฐฉ์์ ๋ชจ๋ ๊ฐ์ง๋ค.
๐ก ๋ถ์ฐ ํ๊ฒฝ์ ๋ฐ๋ฅธ ์ฐจ์ด: ๊ฐ์ YAML ๋งค๋ํ์คํธ๋ผ๋ ํ๊ฒฝ์ ๋ฐ๋ผ ๊ฒฐ๊ณผ๊ฐ ๋ฌ๋ผ์ง๋ค. Docker Desktop์ localhost ์ฃผ์๋ฅผ ์ฌ์ฉํ๊ณ , K3s๋ ํธ์คํธ VM IP๋ฅผ ์ฌ์ฉํ๋ฉฐ, AKS/EKS ๊ฐ์ ํด๋ผ์ฐ๋์์๋ ๊ณต์ธ IP๊ฐ ํ ๋น๋๋ค. ์ฟ ๋ฒ๋คํฐ์ค๊ฐ ๋์ผํ๋๋ผ๋ ๋ก๋๋ฐธ๋ฐ์๋ฅผ ๊ตฌํํ๋ ๋ฐฉ์์ ์ฐจ์ด๊ฐ ์๊ธฐ ๋๋ฌธ์ด๋ค.
NodePort — ๊ฐ๋จํ์ง๋ง ์ ์ฝ์ด ์๋ ์ธ๋ถ ์ ๊ทผ
์ธ๋ถ ๋ก๋๋ฐธ๋ฐ์ ์์ด ๋ชจ๋ ๋ ธ๋์ ํน์ ํฌํธ(๊ธฐ๋ณธ 30000-32767)๋ฅผ ๊ฐ๋ฐฉํ์ฌ ํธ๋ํฝ์ ๋ฐ๋ ๋ฐฉ์์ด๋ค. ํธ๋ํฝ์ด ํน์ ๋ ธ๋๋ก ๋ค์ด์จ ํ์๋ kube-proxy๊ฐ ํด๋ฌ์คํฐ ์ ์ฒด์ ํ๋๋ก ๋ถ์ฐํ๋ค.
๋จ, NodePort๋ ๋ ธ๋ ์์ค์ ๋ก๋๋ฐธ๋ฐ์ฑ์ด ์๋ค๋ ๊ฒ์ด ํต์ฌ ๋จ์ ์ด๋ค. ์ธ๋ถ์์ ํน์ ๋ ธ๋ ํ๋๋ก๋ง ์์ฒญ์ด ์ง์ค๋ ์ ์์ผ๋ฉฐ, ๋ ธ๋๋ค ์ฌ์ด์์ ํธ๋ํฝ์ ๋ถ์ฐํ๋ ์ธ๋ถ ๋ก๋๋ฐธ๋ฐ์์ ์ญํ ์ด ๋น ์ ธ ์๋ค.
externalTrafficPolicy — ์์๋๋ฉด ์ข์ ์ค์
LoadBalancer์ NodePort ์๋น์ค์๋ externalTrafficPolicy๋ผ๋ ์ค์ํ ์ค์ ์ด ์๋ค:
| ๊ฐ | ๋์ | ์ฅ์ | ๋จ์ |
|---|---|---|---|
Cluster (๊ธฐ๋ณธ) |
ํด๋ฌ์คํฐ ์ ์ฒด ํ๋๋ก ๋ถ์ฐ | ๊ท ๋ฑ ๋ถ์ฐ | ๋ค๋ฅธ ๋ ธ๋๋ก ์ถ๊ฐ ํ ๋ฐ์, ํด๋ผ์ด์ธํธ IP๊ฐ SNAT๋จ |
Local |
์์ฒญ ๋ฐ์ ๋ ธ๋์ ํ๋๋ก๋ง ์ ๋ฌ | ํด๋ผ์ด์ธํธ ์๋ณธ IP ๋ณด์กด, ์ถ๊ฐ ํ ์์ | ํด๋น ๋ ธ๋์ ํ๋๊ฐ ์์ผ๋ฉด ํธ๋ํฝ ๋๋กญ |
4. ํด๋ฌ์คํฐ ์ธ๋ถ๋ก ํธ๋ํฝ ์ ๋ฌํ๊ธฐ
์ฟ ๋ฒ๋คํฐ์ค ํด๋ฌ์คํฐ ๋ด๋ถ ํ๋๊ฐ ์ธ๋ถ ์์คํ (๋งค๋์ง๋ DB, ์ธ๋ถ API ๋ฑ)๊ณผ ํต์ ํด์ผ ํ ๋๊ฐ ์๋ค. ์ด๋ ๋ก์ปฌ ๋๋ฉ์ธ ๋ค์์ ํ์ฉํ์ฌ ์ธ๋ถ๋ฅผ ๊ฐ๋ฆฌํค๋ ๋ ๊ฐ์ง ๋ฐฉ๋ฒ์ด ์๋ค.
ExternalName ์๋น์ค — DNS ์์ค์ ๋ฆฌ๋ค์ด๋ ํธ
ExternalName ์๋น์ค๋ ๋ก์ปฌ ์๋น์ค ์ด๋ฆ์ ์ธ๋ถ ๋๋ฉ์ธ์ CNAME์ผ๋ก ์นํํ๋ ๋ฐฉ์์ด๋ค. ํ๋๋ ํด๋ฌ์คํฐ ๋ด๋ถ ์ด๋ฆ๋ง ์๊ณ ์์ผ๋ฉด ๋๊ณ , ์ฟ ๋ฒ๋คํฐ์ค DNS๊ฐ ์ด๋ฅผ ์ธ๋ถ ๋๋ฉ์ธ์ผ๋ก ํด์ํด์ค๋ค.
apiVersion: v1
kind: Service
metadata:
name: numbers-api
spec:
type: ExternalName
externalName: raw.githubusercontent.com
kubectl exec deploy/sleep-1 -- sh -c 'nslookup numbers-api | tail -n 5'
# Name: raw.githubusercontent.com
# Address: 185.199.111.133
# Address: 185.199.108.133
โ ๏ธ HTTP Host ํค๋ ๋ฌธ์ : ExternalName์ ๊ฐ์ฅ ํฐ ์ ์ฝ์ด๋ค. HTTP ์์ฒญ ์ Host ํค๋์๋ ํ๋๊ฐ ์๊ณ ์๋ ๋ก์ปฌ ์ด๋ฆ(
numbers-api)์ด ๋ค์ด๊ฐ๋ค. ์ธ๋ถ ์๋ฒ(GitHub)๋Host: numbers-api๋ฅผ ์ธ์ํ์ง ๋ชปํ๋ฏ๋ก ์์ฒญ์ด ์คํจํ๋ค. ๋น์ ํ์๋ฉด, ํธ์ง๊ฐ ์ฌ๋ฐ๋ฅธ ๊ฑด๋ฌผ(GitHub ์๋ฒ)์ ๋์ฐฉํ์ง๋ง ํธ์ง ์์ "์์ : numbers-api ๊ทํ"๋ผ๊ณ ์ ํ ์์ด์ ๊ฑด๋ฌผ ๊ด๋ฆฌ์ธ์ด "๊ทธ๋ฐ ์ฌ๋ ์๋๋ฐ์?"๋ผ๊ณ ๊ฑฐ๋ถํ๋ ์ ์ด๋ค. HTTPS์ ๊ฒฝ์ฐ TLS SNI ๋ถ์ผ์น๋ก ์ธ์ฆ์ ๊ฒ์ฆ ์์ฒด๊ฐ ์คํจํ๋ฏ๋ก ๋ ์ฌ๊ฐํ๋ค.
TCP ํ๋กํ ์ฝ(DB ๋ฑ)์ Host ํค๋ ๊ฐ๋ ์ด ์์ผ๋ฏ๋ก ์ด ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ง ์๋๋ค. ๋ฐ๋ผ์ ExternalName์ TCP ๊ธฐ๋ฐ ์ธ๋ถ ์๋น์ค(DB ๋ฑ)์ ์ ํฉํ๋ค.
์ฃผ์ํ ์ ์ด ํ๋ ๋ ์๋ค. externalName ํ๋์ IP ์ฃผ์ ๋ฌธ์์ด(์: 1.2.3.4)์ ๋ฃ์ผ๋ฉด IP๊ฐ ์๋ DNS ์ด๋ฆ์ผ๋ก ์ทจ๊ธ๋์ด ์กฐํ๊ฐ ์คํจํ๋ค. IP ์ฃผ์๋ก ์ฐ๊ฒฐํ๋ ค๋ฉด ๋ค์ ๋ฐฉ์์ ์ฌ์ฉํด์ผ ํ๋ค.
์ ๋ ํฐ ์๋ ์๋น์ค + ์๋ Endpoints — IP ์์ค์ ํ๋ก์
ExternalName์ด DNS ์์ค์์ ๋์ํ๋ค๋ฉด, ์ด ๋ฐฉ์์ kube-proxy๋ฅผ ํตํ IP ์์ค ํ๋ก์๋ค. ClusterIP ์๋น์ค๋ฅผ ์ ๋ ํฐ ์์ด ๋ง๋ค๊ณ , Endpoints ๋ฆฌ์์ค์ ์ธ๋ถ IP๋ฅผ ์ง์ ์ง์ ํ๋ค.
apiVersion: v1
kind: Service
metadata:
name: numbers-api
spec:
type: ClusterIP
ports:
- port: 80
---
kind: Endpoints
apiVersion: v1
metadata:
name: numbers-api # ์๋น์ค์ ์ด๋ฆ์ด ๊ฐ์์ผ ํ๋ค
subsets:
- addresses:
- ip: 192.168.123.234
ports:
- port: 80
kubectl get svc numbers-api
# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
# numbers-api ClusterIP 192.168.194.228 <none> 80/TCP 4m27s
kubectl exec deploy/sleep-1 -- sh -c 'nslookup numbers-api | grep "^[^*]"'
# Name: numbers-api.default.svc.cluster.local
# Address: 192.168.194.228 ← Endpoints IP๊ฐ ์๋ ClusterIP๊ฐ ๋ฐํ๋จ
DNS ๊ฒฐ๊ณผ๊ฐ Endpoints IP(192.168.123.234)๊ฐ ์๋ ClusterIP(192.168.194.228)์ธ ์ด์ ๋, clusterIP: None์ด ์๋ ์ผ๋ฐ ClusterIP ์๋น์ค์ด๊ธฐ ๋๋ฌธ์ด๋ค. DNS๋ ClusterIP๋ฅผ ๋ฐํํ๊ณ , ์ค์ ์ธ๋ถ IP๋ก์ ๋ผ์ฐํ
์ kube-proxy๊ฐ DNAT์ผ๋ก ์ฒ๋ฆฌํ๋ค.
๐ก ๊ณต์ Headless Service์์ ์ฐจ์ด:
clusterIP: None์ผ๋ก ์ ์ํ ์๋น์ค๊ฐ ๊ณต์์ ์ธ Headless Service๋ค. Headless Service๋ ClusterIP ์์ด DNS๊ฐ ํ๋ IP๋ฅผ ์ง์ ๋ฐํํ๋ค. ์ ์์๋ ClusterIP๊ฐ ํ ๋น๋ ์๋น์ค์ด๋ฏ๋ก ์ ํํ๋ "์ ๋ ํฐ ์๋ ์๋น์ค(Service without selector)"์ ํด๋นํ๋ค.
์ด ํจํด์ ์ ์ง์ ๋ง์ด๊ทธ๋ ์ด์ ์ ํนํ ์ ์ฉํ๋ค. ์ธ๋ถ DB๋ฅผ ํด๋ฌ์คํฐ ๋ด๋ถ๋ก ์ด์ ํ ๋ Endpoints์ IP๋ง ๋ณ๊ฒฝํ๋ฉด ํด๋ผ์ด์ธํธ ํ๋๋ ์์ ํ ํ์๊ฐ ์๋ค.
๋ ๋ฐฉ์ ๋น๊ต
| ๊ตฌ๋ถ | ExternalName | ์ ๋ ํฐ ์๋ ์๋น์ค + Endpoints |
|---|---|---|
| ๋์ ์์ค | DNS (CNAME ์นํ) | IP (kube-proxy DNAT) |
| ClusterIP | ํ ๋น ์ ๋จ | ํ ๋น๋จ |
| ์ธ๋ถ ๋์ ์ง์ | ๋๋ฉ์ธ ๋ค์๋ง | IP ์ฃผ์๋ง |
| HTTP Host ํค๋ ๋ฌธ์ | ์์ | ์์ |
| HTTPS/TLS SNI ๋ฌธ์ | ์์ (๋ ์ฌ๊ฐ) | ์์ |
| TCP ์๋น์ค ํธํ | ์ข์ (DB์ ์ต์ ) | ์ข์ |
| ๋ง์ด๊ทธ๋ ์ด์ ํ์ฉ | ์ธ๋ถ→์ธ๋ถ ์ ํ | ์ธ๋ถ→๋ด๋ถ ์ ํ (Endpoints IP๋ง ๊ต์ฒด) |
5. ์๋น์ค์ ํด์ ๊ณผ์ ๊ณผ Endpoints ๋ผ์ดํ์ฌ์ดํด
์๋น์ค์ ๋ด๋ถ ๋์์ ์์ฝํ๋ฉด ์ด๋ ๋ค. ํ๋์ DNS ์กฐํ๋ CoreDNS๊ฐ ์๋ตํ๊ณ , ํ๋์์ ๋์จ ๋ชจ๋ ํต์ ์ ๊ฐ ๋ ธ๋์์ ๋์ํ๋ kube-proxy๊ฐ ๋ผ์ฐํ ์ ๋ด๋นํ๋ค. kube-proxy๋ Endpoints์ ์ต์ ์ ๋ณด๋ฅผ ์ ์งํ๋ฉด์, ์ด์์ฒด์ ์ ํจํท ํํฐ(iptables ๋๋ IPVS)๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ์ ClusterIP๋ฅผ ์ค์ ํ๋ IP๋ก ์ฐ๊ฒฐํ๋ค.
์๋น์ค ์ปจํธ๋กค๋ฌ์ Endpoints์ ๋ผ์ดํ์ฌ์ดํด์ ์ค์ต์ผ๋ก ํ์ธํ ์ ์๋ค:
# 1. ์๋น์ค๊ฐ ์์ ๋ — Endpoints์ ํ๋ IP๊ฐ ๋ฑ๋ก๋จ
kubectl get endpoints sleep-2
# NAME ENDPOINTS AGE
# sleep-2 192.168.194.38:80 3m28s
# 2. ํ๋๋ฅผ ์ญ์ ํ๋ฉด — ์ ํ๋๊ฐ ์์ฑ๋๊ณ Endpoints๊ฐ ์๋ ๊ฐฑ์ ๋จ
kubectl delete pods -l app=sleep-2
kubectl get endpoints sleep-2
# NAME ENDPOINTS AGE
# sleep-2 192.168.194.40:80 4m2s ← IP๊ฐ ๋ฐ๋์์ง๋ง ์๋ ๊ฐฑ์
# 3. ๋ํ๋ก์ด๋จผํธ๋ฅผ ์ญ์ ํ๋ฉด — ํ๋๊ฐ ์์ผ๋ฏ๋ก Endpoints๊ฐ ๋น์ด์ง
kubectl delete deploy sleep-2
kubectl get endpoints sleep-2
# NAME ENDPOINTS AGE
# sleep-2 <none> 4m20s ← ๋์ ํ๋ ์์
# 4. ์๋น์ค๋ฅผ ์ญ์ ํ๋ฉด — Endpoints๋ ํจ๊ป ์ญ์ ๋จ
kubectl delete svc sleep-2
kubectl get endpoints sleep-2
# Error from server (NotFound): endpoints "sleep-2" not found
์ด๊ฒ์ด ์๋น์ค์ ํต์ฌ ๊ฐ์น๋ค. ClusterIP๋ ์๋น์ค๊ฐ ์ญ์ ๋ ๋๊น์ง ๋ณํ์ง ์์ผ๋ฉฐ, ํ๋๊ฐ ๊ต์ฒด๋์ด๋ Endpoints๊ฐ ์๋์ผ๋ก ๊ฐฑ์ ๋์ด ํด๋ผ์ด์ธํธ๋ ํญ์ ์ต์ ์ํ์ ๋ฐฑ์๋์ ์ ๊ทผํ ์ ์๋ค.
6. ๋ค๋ฅธ ๋ ธ๋์ ์๋ ํ๋๋ผ๋ฆฌ๋ ์ด๋ป๊ฒ ํต์ ํ ๊น?
์ฟ ๋ฒ๋คํฐ์ค ๋คํธ์ํฌ ๋ชจ๋ธ์ ํต์ฌ ์๊ตฌ์ฌํญ์ "๋ชจ๋ ํ๋๋ NAT ์์ด ๋ค๋ฅธ ๋ชจ๋ ํ๋์ ์ง์ ํต์ ํ ์ ์์ด์ผ ํ๋ค"๋ ๊ฒ์ด๋ค. ๊ฐ์ ๋ ธ๋๋ , ๋ค๋ฅธ ๋ ธ๋๋ ์๊ด์๋ค. ์ด๊ฒ์ ์คํํ๋ ๊ฒ์ด CNI(Container Network Interface) ํ๋ฌ๊ทธ์ธ์ด๋ค.
๊ฐ์ ๋ ธ๋ ๋ด ํต์
๊ฐ์ ๋ ธ๋์ ์๋ ํ๋๋ผ๋ฆฌ๋ ๋จ์ํ๋ค. ๊ฐ ํ๋๋ veth pair(๊ฐ์ ์ด๋๋ท ์)๋ก ๋ ธ๋์ ๋ธ๋ฆฟ์ง(cni0 ๋๋ cbr0)์ ์ฐ๊ฒฐ๋์ด ์๋ค. veth pair์ ํ์ชฝ ๋์ ํ๋ ์์, ๋ค๋ฅธ ์ชฝ์ ๋ ธ๋์ ๋ธ๋ฆฟ์ง์ ์๋ค. ๋ธ๋ฆฟ์ง๊ฐ L2 ์ค์์น ์ญํ ์ ํ๋ฏ๋ก, ๊ฐ์ ๋ ธ๋์ ํ๋ ๊ฐ ํต์ ์ ๋ธ๋ฆฟ์ง ๋ด์์ MAC ์ฃผ์ ๊ธฐ๋ฐ์ผ๋ก ์ง์ ์ ๋ฌ๋๋ค.
๋ค๋ฅธ ๋ ธ๋ ๊ฐ ํต์ — VXLAN Overlay
๋ค๋ฅธ ๋ ธ๋์ ์๋ ํ๋๋ผ๋ฆฌ ํต์ ํ ๋๋ ํจํท์ด ๋ฌผ๋ฆฌ ๋คํธ์ํฌ๋ฅผ ๊ฑฐ์ณ์ผ ํ๋ค. ๊ฐ์ฅ ๋๋ฆฌ ์ฌ์ฉ๋๋ ๋ฐฉ์์ VXLAN Overlay๋ค. Flannel(๊ธฐ๋ณธ ๋ชจ๋), Calico(vxlan ๋ชจ๋), Cilium ๋ฑ์ด ์ด ๋ฐฉ์์ ์ง์ํ๋ค.
ํต์ฌ ์์ด๋์ด๋ ์บก์ํ(Encapsulation)๋ค. ์๋ณธ ํ๋ ํจํท์ UDP ํจํท์ผ๋ก ํ๋ฒ ๋ ๊ฐ์ธ์ ๋ ธ๋ ๊ฐ ๋ฌผ๋ฆฌ ๋คํธ์ํฌ๋ฅผ ํต๊ณผ์ํจ๋ค.
ํธ๋ํฝ ํ๋ฆ์ ๋จ๊ณ๋ณ๋ก ๋ณด๋ฉด
- Pod A (10.244.1.5, Node1)๊ฐ Pod C (10.244.2.10, Node2)๋ก ํจํท์ ๋ณด๋ธ๋ค.
- ํจํท์ด veth → cni0 ๋ธ๋ฆฟ์ง๋ก ์ ๋ฌ๋๋ค.
- Node1์ ๋ผ์ฐํ ํ ์ด๋ธ์์ 10.244.2.0/24๊ฐ VXLAN ํฐ๋(flannel.1) ์ธํฐํ์ด์ค๋ฅผ ํตํด ๋๋ฌ ๊ฐ๋ฅํจ์ ํ์ธํ๋ค.
- flannel.1 (VTEP)์ด ์๋ณธ ํจํท์ UDP:4789๋ก ์บก์ํํ๋ค. ์ธ๋ถ ํค๋์ ๋ชฉ์ ์ง๋ Node2์ IP๋ค.
- ๋ฌผ๋ฆฌ ๋คํธ์ํฌ๋ฅผ ํตํด Node2๋ก ์ ์ก๋๋ค. ๋ฌผ๋ฆฌ ๋คํธ์ํฌ ์ ์ฅ์์๋ ๊ทธ๋ฅ Node1→Node2์ ์ผ๋ฐ UDP ํธ๋ํฝ์ด๋ค.
- Node2์ flannel.1์ด ์ธ๋ถ UDP ํค๋๋ฅผ ๋ฒ๊ฒจ๋ด๊ณ ์๋ณธ ํ๋ ํจํท์ ๋ณต์ํ๋ค.
- ๋ณต์๋ ํจํท์ด cni0 → veth → Pod C์ ๋๋ฌํ๋ค.
CNI ๋ชจ๋ ๋น๊ต
| ๊ตฌ๋ถ | VXLAN (Overlay) | IP-in-IP | BGP (Direct Routing) |
|---|---|---|---|
| ์บก์ํ | UDP:4789 | IP ํ๋กํ ์ฝ 4 | ์์ |
| ์ค๋ฒํค๋ | 50๋ฐ์ดํธ | 20๋ฐ์ดํธ | 0๋ฐ์ดํธ |
| ๋คํธ์ํฌ ์๊ตฌ | L3 (์ด๋์๋ ๋์) | L3 (IP ํ๋กํ ์ฝ 4 ํ์ฉ) | L2 ๋๋ BGP ๋ผ์ฐํฐ |
| ์ฑ๋ฅ | ๋ณดํต | ์ข์ | ์ต๊ณ |
| ๋ํ CNI | Flannel, Calico, Cilium | Calico (๊ธฐ๋ณธ) | Calico BGP, Flannel host-gw |
| ํด๋ผ์ฐ๋ ํธํ | ๋ชจ๋ ํ๊ฒฝ | ๋๋ถ๋ถ | ๋ฒ ์ด๋ฉํ/์จํ๋ ๋ฏธ์ค์ ์ ํฉ |
๋ง๋ฌด๋ฆฌ
์ฟ ๋ฒ๋คํฐ์ค ๋คํธ์ํน์ ํ ๋ฌธ์ฅ์ผ๋ก ์์ฝํ๋ฉด ์ด๋ ๋ค: CoreDNS๊ฐ ์ด๋ฆ์ IP๋ก ๋ฐ๊ฟ์ฃผ๊ณ , kube-proxy๊ฐ ๊ฐ์ IP๋ฅผ ์ค์ ํ๋ IP๋ก ์ฐ๊ฒฐํด์ฃผ๋ฉฐ, CNI๊ฐ ๋ ธ๋ ๊ฐ ํจํท ์ ๋ฌ์ ์ฑ ์์ง๋ค.
ํ์ตํ๋ฉด์ ๋๋ ์ ์, ์ฟ ๋ฒ๋คํฐ์ค๊ฐ ํน๋ณํ ์๋ก์ด ๊ธฐ์ ์ ๋ฐ๋ช ํ ๊ฒ์ด ์๋๋ผ๋ ๊ฒ์ด๋ค. DNS, iptables, VXLAN, BGP — ๋ชจ๋ ์ด๋ฏธ ๊ฒ์ฆ๋ ๋คํธ์ํฌ ๊ธฐ์ ์ด๋ค. ์ฟ ๋ฒ๋คํฐ์ค๋ ์ด๊ฒ๋ค์ ์ปจํ ์ด๋ ์ค์ผ์คํธ๋ ์ด์ ์ ๋ง๊ฒ ์กฐํฉํ๊ณ ์๋ํํ ๊ฒ์ด๋ค. ๊ทธ๋์ ๊ธฐ์กด ๋คํธ์ํฌ ์ง์์ด ์๋ค๋ฉด ์ฟ ๋ฒ๋คํฐ์ค ๋คํธ์ํน์ ์ดํดํ๋ ๋ฐ ํฐ ๋์์ด ๋๋ค.
๋ค์์ผ๋ก ํ์ตํ ์ฃผ์ ๋ก๋ Ingress/Gateway API(HTTP ๊ฒฝ๋ก ๊ธฐ๋ฐ ๋ผ์ฐํ ), NetworkPolicy(ํ๋ ๊ฐ ๋ฐฉํ๋ฒฝ), ์๋น์ค ๋ฉ์(Istio/Linkerd)(mTLS, ํธ๋ํฝ ๊ด๋ฆฌ) ๋ฑ์ ์ถ์ฒํ๋ค.
