스위치·라우팅·게이트웨이·IP 포워딩 → DNS(/etc/hosts, resolv.conf, CoreDNS) → 네트워크 네임스페이스 → Docker 네트워킹 → CNI → 쿠버네티스 노드 네트워크 점검 포인트
0. 왜 이걸 알아야 하나?
쿠버네티스 네트워킹은 결국 리눅스에서 이미 존재하는 기능(인터페이스, 라우팅 테이블, ARP, iptables, 네임스페이스, 브리지)을 조합한 것입니다.
- Pod = (리눅스 프로세스 + 네트워크 네임스페이스)
- Pod 네트워크 연결 = veth + 브리지 + 라우팅(+ 오버레이면 터널/VXLAN)
- 외부 통신/외부에서 접근 = NAT(마스커레이드) + 포트포워딩(DNAT)
- 여러 네트워크 솔루션을 표준화한 인터페이스 = CNI
아래는 “쿠버네티스를 이해하기 위한 리눅스 네트워킹 기초”부터 이어지는 내용을 한 편의 글로 엮은 정리입니다.
1. 리눅스 네트워킹 기초: 스위치·라우팅·게이트웨이·IP 포워딩
1.1 인터페이스 확인: ip link, ip addr
리눅스에서 네트워크 “포트”는 인터페이스로 나타납니다.
ip link
ip addr
lo: loopback. 자기 자신(127.0.0.1)로 돌려보내는 내부 인터페이스eth0: (물리/가상) NIC. 외부 네트워크(LAN/VPC 등)로 나가는 실제 통로
1.2 같은 네트워크 안의 통신: 스위치(= L2)
같은 IP 대역(예: 192.168.1.0/24)에 있는 두 호스트는 스위치를 통해 통신합니다.
- 같은 서브넷이면 “저 IP는 같은 네트워크 안이네?” → ARP로 MAC을 찾고 → L2로 전달
1.3 다른 네트워크로 가려면: 라우터 + 라우팅 테이블
다른 대역(예: 192.168.2.0/24)로 가려면 라우터(= 게이트웨이 역할) 가 필요합니다.
라우팅 테이블 확인:
ip route
# 또는
route -n
라우팅 테이블은 “이 목적지(대역/호스트)로 갈 땐 어느 게이트웨이/인터페이스로 보낼까?”를 결정합니다.
- 게이트웨이(door)는 “내 네트워크 밖으로 나가는 출입구”
- 라우터는 그 출입구 역할을 수행하는 장치/호스트입니다
→ 실무 표현으로 “라우터가 게이트웨이가 된다”가 대부분의 경우 맞습니다.
기본 게이트웨이(디폴트 라우트) 예시:
ip route add default via 192.168.1.1 dev eth0
1.4 리눅스 호스트를 라우터로 만들기: IP 포워딩
두 NIC(eth0, eth1)를 가진 호스트 B가 네트워크 A와 네트워크 C 사이를 중계하려면 “패킷 포워딩”이 필요합니다.
현재 포워딩 여부:
cat /proc/sys/net/ipv4/ip_forward
켜기(즉시 반영):
sudo sysctl -w net.ipv4.ip_forward=1
영구 반영(재부팅 후 유지):
sudo vi /etc/sysctl.conf
# net.ipv4.ip_forward=1
sudo sysctl -p
쿠버네티스 노드가 “Pod 네트워크 ↔ 노드 네트워크 ↔ 외부”를 중계하는 구조라면, 이 포워딩 개념이 계속 등장합니다.
2. Linux DNS 입문: /etc/hosts, resolv.conf, nsswitch.conf, 검색 도메인
2.1 /etc/hosts: 가장 로컬한 이름 해석
호스트 A에서 db라는 이름을 192.168.1.11로 해석하고 싶다면:
sudo vi /etc/hosts
# 192.168.1.11 db
/etc/hosts는 로컬 머신만의 “정적 이름 해석” 입니다.- 여기에 적힌 내용은 그 머신에서 “진실”로 취급됩니다(실제 호스트네임과 달라도 상관 없음).
2.2 /etc/resolv.conf: DNS 서버(네임서버) 지정 + search 도메인
DNS 서버를 쓰려면:
cat /etc/resolv.conf
예:
nameserver 192.168.1.100
search mycompany.com
nameserver: “이 DNS 서버에게 물어봐”search: “web만 치면 web.mycompany.com도 함께 시도해봐”
즉, 내부망에서 web 같은 짧은 이름을 쓸 수 있게 만드는 장치입니다.
2.3 nsswitch.conf: /etc/hosts vs DNS 우선순위
어느 순서로 이름을 찾을지 정의:
cat /etc/nsswitch.conf | grep hosts
# hosts: files dns
files=/etc/hostsdns= DNS 서버 질의
기본은 보통 files → dns 순서입니다.
2.4 DNS 진단 도구: nslookup, dig
nslookup,dig는 DNS 서버에 직접 질의하는 도구입니다./etc/hosts엔트리는 고려하지 않을 수 있습니다(실습에서 많이 헷갈리는 포인트).
nslookup web
dig web
3. (Prerequisite) CoreDNS로 DNS 서버 직접 띄워보기
쿠버네티스에서 CoreDNS는 클러스터 DNS의 핵심 구성요소입니다. 그 전에 “CoreDNS가 그냥 DNS 서버 프로그램”이라는 감각을 잡아두면 이후가 쉬워집니다.
3.1 CoreDNS 바이너리 설치/실행(전통적인 방식)
curl -LO https://github.com/coredns/coredns/releases/download/v1.12.4/coredns_1.12.4_linux_amd64.tgz
tar -zxf coredns_1.12.4_linux_amd64.tgz
./coredns
- 기본적으로 DNS 서버 포트 53에서 리슨합니다.
3.2 /etc/hosts를 CoreDNS가 읽게 만들기: Corefile
CoreDNS는 Corefile로 설정을 읽습니다. 아래 예시는:
- DNS 엔트리는 DNS 서버 자신의
/etc/hosts에 넣고 - CoreDNS가 그 파일을 읽어 질의에 응답하게 하는 설정입니다.
.:53 {
hosts /etc/hosts {
reload 1m
fallthrough
}
forward . /etc/resolv.conf {
max_concurrent 1000
}
cache 30
log
errors
}
hosts /etc/hosts: 호스트 파일 기반 응답reload 1m: hosts 파일 변경 감지fallthrough: hosts에서 못 찾으면 다음 플러그인으로 넘어감forward . /etc/resolv.conf: 나머지는 상위 DNS로 포워딩(인터넷 도메인 등)cache/log/errors: 캐시/로그/에러
쿠버네티스에서는 이 CoreDNS가 “kubernetes 플러그인”을 통해 Service/Pod 이름을 해석합니다. (이 글은 DNS 서버의 기본 구조 감각을 위한 파트)
4. Linux Network Namespace: 컨테이너 네트워크 격리의 핵심
컨테이너는 “프로세스 격리”를 네임스페이스로 합니다. 네트워크도 마찬가지로 네트워크 네임스페이스를 사용합니다.
4.1 네임스페이스 만들기/확인
ip netns add red
ip netns add blue
ip netns
네임스페이스 안에서 명령 실행:
ip netns exec red ip link
# 또는 축약
ip -n red link
처음엔 lo만 보입니다. 호스트의 eth0는 보이지 않습니다(격리 성공).
4.2 veth: 네임스페이스를 잇는 “가상 케이블”
두 네임스페이스를 직접 연결:
ip link add veth-red type veth peer name veth-blue
ip link set veth-red netns red
ip link set veth-blue netns blue
IP 부여(여기서 /24가 중요했던 이유):
ip -n red addr add 192.168.5.1/24 dev veth-red
ip -n blue addr add 192.168.5.2/24 dev veth-blue
ip -n red link set veth-red up
ip -n blue link set veth-blue up
왜 /32가 아니라 /24였나?
/24는 “같은 L2 네트워크(192.168.5.0/24)에 이웃이 있다”는 의미
→ 이웃 IP(192.168.5.2)에 대해 ARP를 수행하고 직접 통신 가능/32는 “내 IP 한 개만 존재(호스트 라우트)” 의미라
→ 같은 네트워크 개념이 약해지고, 보통은 게이트웨이/라우팅 기반 설계에서 사용됩니다.
4.3 ARP 테이블 vs 라우팅 테이블
- ARP 테이블: “이 IP는 어떤 MAC이지?” (L2 주소 해석)
- 라우팅 테이블: “이 목적지 IP(대역)는 어디로 보내지?” (L3 경로 결정)
확인:
ip neigh # ARP/neighbor table
ip route # routing table
veth로 연결하면 라우팅이 되는가?
- veth 자체는 “케이블”일 뿐이고, 실제로는
- 같은 서브넷 설정(/24 등) → ARP로 이웃 MAC을 알아내고
- L2로 프레임을 보내서 통신이 됩니다.
- 다른 네트워크로 가려면 라우팅 테이블/게이트웨이가 필요합니다.
4.4 bridge: 여러 네임스페이스를 한 네트워크에 묶기
브리지 생성:
ip link add vnet0 type bridge
ip link set vnet0 up
veth 한쪽을 브리지에 붙이기(질문에 있던 명령):
ip link set veth-blue-br master vnet0
이 의미는:
veth-blue-br인터페이스를 브리지 vnet0의 포트로 등록한다- 즉, L2 스위치에 랜선을 꽂는 것과 같습니다.
5. 네임스페이스/브리지에서 외부로: Routing + NAT + Port Forward
5.1 “왜 포워딩/NAT가 필요하지?” 핵심 논리
네임스페이스(예: 192.168.15.0/24)는 호스트 내부의 사설망이고, 외부 LAN(예: 192.168.1.0/24)은 그 사설망을 모릅니다.
- 네임스페이스 → 외부로 나갈 때:
외부는 192.168.15.x를 모름 → 응답이 돌아오지 않음
→ NAT(마스커레이드) 로 “호스트 IP로 나간 것처럼” 바꿔줘야 함
또한 호스트가 네임스페이스 트래픽을 중계하려면:
- IP 포워딩이 켜져 있어야 합니다.
5.2 NAT 마스커레이드 예시
sudo iptables -t nat -A POSTROUTING -s 192.168.15.0/24 -o eth0 -j MASQUERADE
POSTROUTING: 밖으로 나가기 직전-s 192.168.15.0/24: 소스가 내부 사설망이면-o eth0: eth0로 나갈 때MASQUERADE: 소스 IP를 호스트 IP로 바꿔서 나가게 함
5.3 외부 → 내부 서비스 접근: 포트포워딩(DNAT)
예: 외부에서 호스트 80으로 들어온 걸 네임스페이스(blue) 80으로 전달
sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.15.2:80
6. Docker 네트워킹: none / host / bridge, 그리고 docker0·iptables 포트포워딩
Docker는 위에서 우리가 손으로 만든 것과 거의 동일하게 동작합니다.
6.1 Docker 네트워크 옵션 3가지
- none
- 네트워크에 붙지 않음. 외부도 못 나가고 컨테이너끼리도 통신 어려움
- host
- 컨테이너가 호스트 네트워크를 그대로 사용
- 포트 매핑 없이도 호스트의 80이 곧 컨테이너 80
- 단점: 같은 포트를 여러 컨테이너가 동시에 못 씀(충돌)
- bridge (기본)
- 내부 사설 네트워크 생성(기본
docker0, 대역 보통172.17.0.0/16계열) - 컨테이너마다 별도 netns + veth로 docker0에 붙음
- 외부 접근은 포트 퍼블리싱(-p)으로 열어줘야 함
호스트에서 확인:
docker network ls
ip link show docker0
ip addr show docker0
6.2 “그냥 80으로 띄운 것” vs “8080:80으로 띄운 것” 차이
여기서 말하는 두 케이스:
- 케이스 A:
docker run nginx(포트 퍼블리싱 없음) - 케이스 B:
docker run -p 8080:80 nginx(호스트 8080 → 컨테이너 80)
케이스 A: 포트 퍼블리싱이 없으면 외부에서 컨테이너 80으로 못 들어온다
- 컨테이너는 자신의 netns 내부에서 80 리슨
- 호스트에는 “외부 트래픽을 그 컨테이너로 보내는 규칙”이 없음
- 따라서 외부에서
host:80으로 들어오면:- 호스트에 80 리슨 프로세스가 없으면 연결 실패
- 호스트에 다른 80 프로세스가 있으면 그 프로세스로 감
즉, 컨테이너가 80을 열었다 ≠ 호스트가 80을 외부에 제공한다
케이스 B: -p 8080:80은 호스트가 DNAT 룰을 만들어서 연결해준다
- 호스트 8080으로 들어오는 트래픽을
- iptables DNAT로 컨테이너 IP:80으로 바꿈
- 그래서 외부에서
host:8080으로 접근 가능
Docker는 내부적으로 아래와 유사한 룰을 만듭니다(개념):
iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 172.17.0.3:80
6.3 시퀀스 다이어그램으로 이해하기
A) 포트 퍼블리싱 없이(docker run nginx) 외부에서 접근 시도
[Client] ---TCP:80---> [Host eth0]
|
| (호스트에 80 리슨 프로세스 없음)
v
(Connection Refused / Timeout)
B) -p 8080:80으로 퍼블리싱한 경우
[Client] ---TCP:8080---> [Host eth0:8080]
|
| iptables DNAT (8080 -> 172.17.0.3:80)
v
[docker0/bridge]
|
| veth pair
v
[Container netns:80 nginx]
핵심: 외부에서 들어오는 트래픽을 컨테이너로 “맵핑(포워딩)”해주는 규칙이 있어야 한다 입니다.
7. CNI(Container Network Interface): 네트워크 세팅을 표준화해서 플러그인으로 분리한다
7.1 CNI가 해결하는 문제
여러 런타임/오케스트레이터가 “컨테이너를 네트워크에 붙이는 로직”을 매번 구현하지 않도록:
- 런타임이 플러그인을 어떻게 호출할지
- 플러그인이 어떤 입력/출력을 가져야 할지
를 표준화한 것이 CNI입니다.
7.2 런타임 vs 플러그인 책임
- 런타임: netns 생성, ADD/DEL 호출
- 플러그인: veth/브리지 연결, IP 할당(IPAM), 라우팅 설정 등 수행
CNI 플러그인 예:
- bridge, vlan, macvlan
- IPAM: host-local, dhcp
- 서드파티: flannel, calico, cilium, weave 등
7.3 “Docker는 CNM인데 CNI가 어떻게 동작하나?”
핵심은 이겁니다.
- CNI는 “도커 네트워크(CNM)를 확장하는 기능”이 아니라
- 리눅스 netns에 네트워크를 세팅하는 방식입니다.
쿠버네티스가 Docker를 런타임으로 쓰던 시절(역사적 흐름)에는:
- Docker로 컨테이너(netns)를 만들고(네트워크는 최소/없음)
- 그 netns에 대해 kubelet이 CNI 플러그인을 호출해
- veth/브리지/IP/라우팅을 구성
즉, Docker가 CNM을 쓰느냐와 별개로, Kubernetes는 CNI로 “netns를 직접 세팅”할 수 있었습니다.
8. 쿠버네티스 노드 네트워크 점검 포인트(필수 포트 포함)
쿠버네티스 클러스터는 컨트롤플레인/워커 모두 “노드로서의 네트워크”가 정상이어야 합니다.
8.1 노드 기본 조건
- 각 노드는 최소 1개 인터페이스 + IP 필요
- hostname 유니크
- MAC 유니크(특히 VM 클론 시 주의)
확인:
ip link
ip addr
hostname
8.2 자주 언급되는 포트(대표)
- API Server: 6443
- kubelet: 10250
- scheduler: 10259
- controller-manager: 10257
- NodePort range: 30000-32767
- etcd: 2379 (client), 2380 (peer)
포트 리슨 확인(둘 중 하나):
sudo ss -lntp
sudo netstat -lntp
netstat -anp | grep etcd에서 옵션 의미:
-a: 전체 소켓(리스닝+연결)-n: 숫자(IP/포트) 그대로-p: PID/프로세스 표시(보통 sudo 필요)
9. 라우팅 테이블 읽는 법: ip route 실전 예시 해석
예시:
ip route
default via 169.254.1.1 dev eth0
169.254.1.1 dev eth0 scope link
172.17.0.0/24 dev cni0 proto kernel scope link src 172.17.0.1
172.17.1.0/24 via 172.17.1.0 dev flannel.1 onlink
dev= device(인터페이스)
→ 이 경로로 나가는 패킷이 “어느 인터페이스로 나가야 하는지”를 뜻함
라인별 의미:
default via ... dev eth0- 기본 경로(모르는 목적지는 전부) → eth0로 게이트웨이에 전달
169.254.1.1 dev eth0 scope link- 게이트웨이 IP 자체는 eth0 링크에서 직접 도달 가능
172.17.0.0/24 dev cni0 ... src 172.17.0.1- 이 노드의 로컬 Pod 네트워크(또는 브리지 대역)가 cni0에 직접 연결
- cni0의 주소가 172.17.0.1인 형태
172.17.1.0/24 ... dev flannel.1 onlink- 다른 노드(다른 Pod CIDR)로 가는 트래픽을 flannel 오버레이 인터페이스로 보냄
onlink는 “직접 연결처럼 취급하고 보내라”는 강제 플래그로 이해하면 됨
10. 덤: /32 IP가 보이는 이유(쿠버네티스/컨테이너에서 흔함)
컨테이너/파드 내부에서 ip addr를 보면 이런 형태가 자주 보입니다.
inet 192.168.227.158/32 scope global eth0
/32는 “내 IP 한 개만”을 의미하는 호스트 라우트 스타일- 이런 경우 통신은 보통:
- 기본 게이트웨이로 보내면
- 노드가 라우팅/오버레이로 목적지까지 전달하는 구조입니다.
- 반대로 우리가 netns 실습에서
/24를 준 이유는 “같은 L2에서 ARP로 이웃을 찾아 직접 통신”시키려는 목적이었습니다.
마무리: 쿠버네티스 네트워킹을 보는 프레임
여기까지를 한 줄로 정리하면:
- 리눅스: 인터페이스/라우팅/ARP/iptables(포워딩·NAT·DNAT)
- 컨테이너: netns + veth + bridge
- Docker: docker0 + iptables로 포트 퍼블리싱
- Kubernetes: Pod 네트워크를 “CNI 플러그인”으로 표준화해서 구성
- 문제 해결 순서: 노드 네트워크(포트/방화벽/라우트) → CNI/브리지/오버레이 → 서비스/포트포워딩
'CKA' 카테고리의 다른 글
| Network - IPAM(IP Address Management) (0) | 2026.01.05 |
|---|---|
| Network - Pod Networking & CNI (1) | 2026.01.05 |
| Network - CNI(Container Network Interface) (0) | 2026.01.05 |
| Network - Docker Network (0) | 2026.01.05 |
| Network - 네트워크 기초(veth, bridge, routing, NAT, port-forward) (1) | 2026.01.05 |