본문 바로가기

컨테이너/쿠버네티스 네트워크

[KANS] 쿠버네티스 네트워크 (3) 컨테이너 네트워크 & IPTABLES

대주제
  • RED ↔ BLUE 네트워크 네임스페이스 간 통신 
  • RED ← Bridge(br0) → BLUE 간 통신
  • RED/BLUE → 호스트 & 외부(인터넷) 통신

1. RED<->BLUE 네임스페이스간 통신

결론 : 네트워크 네임스페이스 생성 시 호스트 네트워크와 구별된다

# 터미널1~3 관리자
sudo su -
whoami


# veth (가상 이더넷 디바이스) 생성, man ip-link
ip link add veth0 type veth peer name veth1

# veth 생성 확인(상태 DOWN), ifconfig 에는 peer 정보 확인 안됨
# very pair 정보 확인 : ({iface}@if{pair#N})
ip -c link
ip -c addr  # 축약 ip -c a
ifconfig -a

# 네트워크 네임스페이스 생성 , man ip-netns
ip netns add RED
ip netns add BLUE

# 네트워크 네임스페이스 확인 
ip netns list

# veth0 을 RED 네트워크 네임스페이스로 옮김
ip link set veth0 netns RED
ip netns list
## 호스트의 ip a 목록에서 보이지 않음, veth1의 peer 정보가 변경됨
ip -c link
## RED 네임스페이스에서 ip a 확인됨(상태 DOWN), peer 정보 확인, link-netns RED, man ip-netns
ip netns exec RED ip -c a

# veth1 을 BLUE 네트워크 네임스페이스로 옮김
ip link set veth1 netns BLUE
ip -c link
ip netns exec BLUE ip -c a

# veth0, veth1 상태 활성화(state UP)
ip netns exec RED ip link set veth0 up
ip netns exec RED ip -c a
ip netns exec BLUE ip link set veth1 up
ip netns exec BLUE ip -c a

# veth0, veth1 에 IP 설정
ip netns exec RED ip addr add 11.11.11.2/24 dev veth0
ip netns exec RED ip -c a
ip netns exec BLUE ip addr add 11.11.11.3/24 dev veth1
ip netns exec BLUE ip -c a

# 터미널1 (RED 11.11.11.2)
## nsenter : 네임스페이스에 attach 하여 지정한 프로그램을 실행
tree /var/run/netns
nsenter --net=/var/run/netns/RED
ip -c a
## neighbour/arp tables management , man ip-neighbour
ip -c neigh
## 라우팅 정보, iptables 정보
ip -c route
iptables -t filter -S
iptables -t nat -S

# 터미널2 (호스트)
lsns -t net  # nsenter 실행 후 TYPE(net) CMD(-bash) 생성 확인
ip -c a
ip -c neigh
ip -c route
iptables -t filter -S
iptables -t nat -S

# 터미널3 (BLUE 11.11.11.3)
nsenter --net=/var/run/netns/BLUE
ip -c a
ip -c neigh
ip -c route
iptables -t filter -S
iptables -t nat -S

# ping 통신 확인
# 터미널3 (BLUE 11.11.11.3)
tcpdump -i veth1
ip -c neigh
exit

# 터미널1 (RED 11.11.11.2)
ping 11.11.11.3 -c 1
ip -c neigh
exit

# 삭제
ip netns delete RED
ip netns delete BLUE

2. RED - Br0 - BLUE 간 통신

결론 : arp table, route table, iptables 와 호스트의 bridge fdb 를 통하여 통신

# 네트워크 네임스페이스 및 veth 생성
ip netns add RED
ip link add reth0 type veth peer name reth1
ip link set reth0 netns RED
ip netns add BLUE
ip link add beth0 type veth peer name beth1
ip link set beth0 netns BLUE

# 확인
ip netns list
ip -c link
ip netns exec RED ip -c a
ip netns exec BLUE ip -c a

# 브리지 정보 확인
brctl show

# br0 브리지 생성
ip link add br0 type bridge

# br0 브리지 정보 확인
brctl show br0
brctl showmacs br0
brctl showstp br0

# reth1 beth1 을 br0 연결
ip link set reth1 master br0
ip link set beth1 master br0
brctl show br0
brctl showmacs br0
ip -br -c link

# reth0 beth0 에 IP 설정 및 활성화, br0 활성화
ip netns exec RED  ip addr add 11.11.11.2/24 dev reth0
ip netns exec BLUE ip addr add 11.11.11.3/24 dev beth0
ip netns exec RED  ip link set reth0 up; ip link set reth1 up
ip netns exec BLUE ip link set beth0 up; ip link set beth1 up
ip link set br0 up
ip -br -c addr


# 터미널1 (RED 11.11.11.2)
nsenter --net=/var/run/netns/RED
ip -c a;echo; ip -c route;echo; ip -c neigh
## 현재 네트워크 네임스페이스 정보 확인
ip netns identify $$
RED

# 터미널2 (호스트)
brctl showmacs br0
bridge fdb show
bridge fdb show dev br0

iptables -t filter -S
iptables -t filter -L -n -v

# 터미널3 (BLUE 11.11.11.3)
nsenter --net=/var/run/netns/BLUE
ip -c a;echo; ip -c route;echo; ip -c neigh
## 현재 네트워크 네임스페이스 정보 확인
ip netns identify $$
BLUE

==============================================================
# 터미널2 (호스트)
# ping 통신 전 사전 설정
## iptables 정보 확인
iptables -t filter -S | grep '\-P'
	-P INPUT ACCEPT
	-P FORWARD DROP
	-P OUTPUT ACCEPT
	
iptables -nvL -t filter

## Ubuntu 호스트에서 패킷 라우팅 설정 확인 : 커널의 IP Forwarding (routing) 기능 확인 - 0(off), 1(on)
## echo 1 > /proc/sys/net/ipv4/ip_forward
cat /proc/sys/net/ipv4/ip_forward
1

==============================================================
# ping 통신 테스트
# 터미널1 (RED 11.11.11.2) >> ping 왜 실패했을까요?
ping -c 1 11.11.11.3

# 터미널2 (호스트)
tcpdump -l -i br0
watch -d 'iptables -v --numeric --table filter --list FORWARD'
watch -d 'iptables -v --numeric --table filter --list FORWARD;echo;iptables -v --numeric --table filter --list DOCKER-USER;echo;iptables -v --numeric --table filter --list DOCKER-ISOLATION-STAGE-1'

# 터미널3 (BLUE 11.11.11.3)
tcpdump -l -i beth0

통신 테스트

# 터미널2 (호스트)
# iptables 설정 정보 확인
iptables -t filter -S
iptables -t nat -S  | grep '\-P'

# iptables 설정 추가 -t(table), -I(insert chain), -j(jump to - ACCEPT 허용)
iptables -t filter -I DOCKER-USER -j ACCEPT
iptables -nvL -t filter
iptables -t filter -S
iptables -t nat -S  | grep '\-P'
watch -d 'iptables -v --numeric --table filter --list FORWARD;echo;iptables -v --numeric --table filter --list DOCKER-USER;echo;iptables -v --numeric --table filter --list DOCKER-ISOLATION-STAGE-1'
tcpdump -l -i br0

==============================================================
# ping 통신 테스트
# 터미널1 (RED 11.11.11.2)
ping -c 1 11.11.11.3
ip -c neigh

# 터미널2 (호스트)
watch -d 'iptables -v --numeric --table filter --list FORWARD;echo;iptables -v --numeric --table filter --list DOCKER-USER;echo;iptables -v --numeric --table filter --list DOCKER-ISOLATION-STAGE-1'
tcpdump -l -i br0

## 정보 확인
ip -c neigh

# 터미널3 (BLUE 11.11.11.3)
tcpdump -l -i beth0
ip -c neigh

==============================================================
# (옵션) 추가 방안1 : 출발지 IP 11.2, 11.3 허용
## -t(table), -A(APPEND chain rule), -s(출발지), -j(jump to - ACCEPT 허용)
iptables -t filter -A FORWARD -s 11.11.11.2/32 -j ACCEPT
iptables -t filter -A FORWARD -s 11.11.11.3/32 -j ACCEPT
## 추가 정책 삭제 시
iptables -t filter -D FORWARD -s 11.11.11.2/32 -j ACCEPT
iptables -t filter -D FORWARD -s 11.11.11.3/32 -j ACCEPT

# (옵션) 추가 방안2 : 11.11.11.0/24 대역 출발지 허용
iptables -t filter -A FORWARD -s 11.11.11.0/24 -j ACCEPT
## 추가 정책 삭제 시 
iptables -t filter -D FORWARD -s 11.11.11.0/24 -j ACCEPT

# (옵션) 추가 방안3 : FORWARD 기본 정책 허용으로 변경
iptables -t filter -P FORWARD ACCEPT
## 추가 정책 삭제 시 
iptables -t filter -P FORWARD DROP
유의할점
도커 설치가 없으면 iptables는 기본적으로 전부 ACCEPT 되어 있음
✅ 도커 설치가 될때 다음과 같이 기본 정책이 생성되며 기본 policy가 DROP으로 변경됨
-P INPUT ACCEPT
-P FORWARD DROP
-P OUTPUT ACCEPT

 iptables -t filter -I DOCKER-USER -j ACCEPT 
 해당 방안은 root 권한을 부여하는것 
추가 방안 1,2,3 은 비유하자면 32비트로 방화벽을 오픈할거냐 24비트로 오픈할거냐 아니면 0.0.0.0으로 오픈할거냐
-A : append, 해당 chain 끝 행에 룰 추가
-I [chain] [number] : insert, 해당 [chain] [number] 행에 룰 삽입
-D : delete, 행 번호 지정하여 룰 삭제
-R : replace, 행 번호 지정하여 룰 치환
-F : flush, 해당 체인의 모든 룰 삭제
-L : list, 룰 리스트 출력
-P : policy, 기본(default) 정책 설정. 체인의 모든 룰에 매칭되지 않으면 적용
-p : protocol,  예) tcp, udp, icmp, ...
-s : source ip, 지정 안할 경우 any 
-d : destination ip, 지정 안할 경우 any
-sport : source port
-dport : destination port
-i : input interface 예) eth0
-o : output interface 예 eth0
-S : List 출력
-n: IP 주소와 포트 번호를 숫자 형식으로 표시합니다. 기본적으로 iptables는 IP 주소를 호스트 이름으로, 
포트를 서비스 이름으로 해석하여 보여줍니다. 그러나 -n 옵션을 사용하면 이러한 해석 과정을 생략하고 
숫자 그대로 표시합니다. 이 옵션은 출력 속도를 높이는 데도 도움이 됩니다.
-v: 상세한(Verbose) 출력을 표시합니다. 기본 출력에 비해 패킷 수와 바이트 수 등의 추가 정보를 제공합니다.
-L: 현재 설정된 방화벽 규칙을 나열합니다. 기본적으로 INPUT, FORWARD, OUTPUT 체인의 규칙이 나열됩니다.

3. RED<->BLUE 네임스페이스간 통신

# 터미널1 (RED 11.11.11.2)
nsenter --net=/var/run/netns/RED
tcpdump -i any

# 터미널3 (호스트)
exit
tcpdump -i br0 -n

# 터미널2 (호스트) >> 호스트에서 RED 로 통신이 안되는 이유가 무엇일까요?
ping -c 1 11.11.11.2
ip -c route
ip -c addr

==============================================================
# 터미널2 (호스트) >> br0 에 IP 추가(라우팅 정보)
ip addr add 11.11.11.1/24 dev br0
ping -c 1 11.11.11.2
ping -c 1 11.11.11.3

# 터미널1 (RED 11.11.11.2) >> 192.168.50.10 와 통신이 안되는 이유는 무엇일까요?
ping -c 1 11.11.11.1
ping -c 1 192.168.50.10
ip -c route
ip -c addr

==============================================================
# 터미널3 (호스트)
tcpdump -i any icmp -n

# 터미널1 (RED 11.11.11.2)
ip route add default via 11.11.11.1
ping -c 1 192.168.50.10
ip -c route
ping -c 1 8.8.8.8 >> 외부 대역(인터넷)과 통신이 안되는 이유가 무엇일까요?

# 터미널2 (호스트)
iptables -S -t nat
iptables -nvL -t nat
## POSTROUTING : 라우팅 Outbound or 포워딩 트래픽에 의해 트리거되는 netfilter hook
## POSTROUTING 에서는 SNAT(Source NAT) 설정
iptables -t nat -A POSTROUTING -s 11.11.11.0/24 -j MASQUERADE
watch -d 'iptables -v --numeric --table nat --list POSTROUTING'
iptables -nvL -t nat
conntrack -L --src-nat

# 터미널1 (RED 11.11.11.2)
ping -c 1 8.8.8.8
exit

# 터미널3 (BLUE 11.11.11.3)
nsenter --net=/var/run/netns/BLUE # 주의, 꼭 실행 후 아래 진행 할 것
ip route add default via 11.11.11.1
ping -c 1 8.8.8.8
exit

# 삭제
ip netns delete RED
ip netns delete BLUE
ip link delete br0

iptables -t filter -D DOCKER-USER -j ACCEPT
iptables -t nat -D POSTROUTING -s 11.11.11.0/24 -j MASQUERADE