Podman 컨테이너 환경을 운영할 때, 기본적으로 Host, Bridge 두 가지를 사용한다.
Host 모드는 10.65 대역(외부망)을 사용하고, Bridge 모드는 10.88.0.0/16 대역(NAT)을 사용한다.
- Podman VS KVM
- Podman 의 네트워크는 Port 를 기반으로 통신한다.
- KVM 의 네트워크는 IP 를 기반으로 통신한다.
Podman 을 설치할 경우 기본적으로 생성되는 네트워크이다.
컨테이너 이미지를 실행할 때 기본적으로 선택되는 네트워크이며, NAT 로 동작하기 때문에 실행된 컨테이너 내부에 IP가 할당된다.
[root@jh-container-rocky86 ~]# podman network ls
NETWORK ID NAME DRIVER
2f259bab93aa podman bridge
[root@jh-container-rocky86 ~]# podman network ls --filter name=podman --format json
[
{
"name": "podman",
"id": "2f259bab93aaaaa2542ba43ef33eb990d0999ee1b9924b557b7be53c0b7a1bb9",
"driver": "bridge",
"network_interface": "cni-podman0",
"created": "2024-02-16T11:40:06.43855213+09:00",
"subnets": [
{
"subnet": "10.88.0.0/16",
"gateway": "10.88.0.1"
}
],
"ipv6_enabled": false,
"internal": false,
"dns_enabled": false,
"ipam_options": {
"driver": "host-local"
}
}
]
[root@jh-container-rocky86 ~]# ip addr show dev cni-podman0
3: cni-podman0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
link/ether 3e:2d:92:12:e5:3f brd ff:ff:ff:ff:ff:ff
inet 10.88.0.1/16 brd 10.88.255.255 scope global cni-podman0
valid_lft forever preferred_lft forever
inet6 fe80::3c2d:92ff:fe12:e53f/64 scope link
valid_lft forever preferred_lft forever
KVM 환경에서도 기본 네트워크가 생성되는데, 이 또한 NAT 를 사용한다.
[root@is1 ~]# virsh net-list | grep default
default active yes yes
[root@is1 ~]# virsh net-info default
Name: default
UUID: dd1b83fe-7489-4041-8851-a63d7d24476a
Active: yes
Persistent: yes
Autostart: yes
Bridge: virbr0
[root@is1 ~]# virsh net-dumpxml default
<network>
<name>default</name>
<uuid>dd1b83fe-7489-4041-8851-a63d7d24476a</uuid>
<forward mode='nat'>
<nat>
<port start='1024' end='65535'/>
</nat>
</forward>
<bridge name='virbr0' stp='on' delay='0'/>
<mac address='52:54:00:9f:0a:3b'/>
<ip address='192.168.122.1' netmask='255.255.255.0'>
<dhcp>
<range start='192.168.122.2' end='192.168.122.254'/>
</dhcp>
</ip>
</network>
[root@is1 ~]# ip addr show dev virbr0
30: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
link/ether 52:54:00:9f:0a:3b brd ff:ff:ff:ff:ff:ff
inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
valid_lft forever preferred_lft forever
Podman/KVM 기본 NAT 네트워크의 공통점은 Host 서버를 경유하여 외부와 통신이 가능하다는 점이다.
아래 예시는 외부에서 MariaDB에 어떻게 접근이 가능한 것인지 확인할 수 있다.
[root@jh-container-rocky86 ~]# podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f7f874049900 docker.io/library/mariadb:latest mariadbd About a minute ago Up About a minute ago 0.0.0.0:13306->3306/tcp jh-mariadb01
[root@jh-container-rocky86 ~]# netstat -antp | grep 3306
tcp 0 0 0.0.0.0:13306 0.0.0.0:* LISTEN 59714/conmon
# netstat
명령어가 없으므로 # ss
명령어로 확인한다.[root@jh-container-rocky86 ~]# podman exec -it jh-mariadb01 bash
root@f7f874049900:/# ss -4ltpn
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 80 0.0.0.0:3306 0.0.0.0:*
[root@jh-up-test-rhel84 ~]# mysql -uroot -p -h 10.65.121.86 -P 13306
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 4
Server version: 11.2.2-MariaDB-1:11.2.2+maria~ubu2204 mariadb.org binary distribution
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]>
root@f7f874049900:/# ss -4tpn
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
ESTAB 0 0 10.88.0.27:3306 10.65.121.84:42300
[root@jh-container-rocky86 ~]# netstat -antp
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 885/sshd
tcp 0 0 0.0.0.0:13306 0.0.0.0:* LISTEN 59714/conmon
tcp 0 36 10.65.121.86:22 10.0.9.6:51376 ESTABLISHED 56765/sshd: root [p
tcp6 0 0 :::22 :::* LISTEN 885/sshd
Internal 네트워크는 내부 네트워크를 얘기하며, KVM으로 비교했을 때 Isolated 네트워크와 동일하다.
내부 네트워크이므로 외부에서 접근이 불가능한 네트워크이다.
[root@jh-container-rocky86 ~]# podman network create --driver bridge --internal --subnet 200.200.200.0/24 --gateway 200.200.200.1 internal-network
internal-network
[root@jh-container-rocky86 ~]# podman network ls
NETWORK ID NAME DRIVER
a941d590a508 internal-network bridge
2f259bab93aa podman bridge
[root@jh-container-rocky86 ~]# podman network inspect --format json internal-network
[
{
"name": "internal-network",
"id": "a941d590a508e7dbc94ce1b2486ca17ed206e324827c304ffaf4620f299c1f6e",
"driver": "bridge",
"network_interface": "cni-podman1",
"created": "2024-02-19T09:31:43.821875969+09:00",
"subnets": [
{
"subnet": "200.200.200.0/24",
"gateway": "200.200.200.1"
}
],
"ipv6_enabled": false,
"internal": true,
"dns_enabled": false,
"ipam_options": {
"driver": "host-local"
}
}
]
[root@jh-container-rocky86 ~]# podman run -itd --network internal-network -p 23306:3306 -e MYSQL_ROOT_PASSWORD=1234 --restart always --name jh-mariadb02 mariadb:latest
b0f903cb9947aa57f5c23404796e37b0985e91edad574fdd45152883c154a870
[root@jh-container-rocky86 ~]# podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f7f874049900 docker.io/library/mariadb:latest mariadbd 2 days ago Up 2 days ago 0.0.0.0:13306->3306/tcp jh-mariadb01
b0f903cb9947 docker.io/library/mariadb:latest mariadbd 19 seconds ago Up 19 seconds ago 0.0.0.0:23306->3306/tcp jh-mariadb02
[root@jh-up-test-rhel84 ~]# mysql -uroot -p -h 10.65.121.86 -P 23306
Enter password:
ERROR 2002 (HY000): Can't connect to MySQL server on '10.65.121.86' (115)
[root@jh-container-rocky86 ~]# podman run -itd --network internal-network -p 33306:3306 -e MYSQL_ROOT_PASSWORD=1234 --restart always --name jh-rk86-mariadb03 jh/rk86-mariadb:240208
72a489ec69815f8309d48a9e0f302c9d36669d0035acab3b94ad79a981da9d40
[root@jh-container-rocky86 ~]# podman run -itd --network internal-network -p 43306:3306 -e MYSQL_ROOT_PASSWORD=1234 --restart always --name jh-rk86-mariadb04 jh/rk86-mariadb:240208
e4803261008676358f0284f94b8c2457880ddf572b4456956ab67cd797018fe4
[root@jh-container-rocky86 ~]# podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f7f874049900 docker.io/library/mariadb:latest mariadbd 2 days ago Up 2 days ago 0.0.0.0:13306->3306/tcp jh-mariadb01
b0f903cb9947 docker.io/library/mariadb:latest mariadbd 9 minutes ago Up 9 minutes ago 0.0.0.0:23306->3306/tcp jh-mariadb02
72a489ec6981 localhost/jh/rk86-mariadb:240208 /sbin/init About a minute ago Up About a minute ago 0.0.0.0:33306->3306/tcp jh-rk86-mariadb03
e48032610086 localhost/jh/rk86-mariadb:240208 /sbin/init About a minute ago Up About a minute ago 0.0.0.0:43306->3306/tcp jh-rk86-mariadb04
[root@jh-container-rocky86 ~]# podman inspect jh-rk86-mariadb03 | grep IPAddress
"IPAddress": "",
"IPAddress": "200.200.200.3",
[root@jh-container-rocky86 ~]# podman inspect jh-rk86-mariadb04 | grep IPAddress
"IPAddress": "",
"IPAddress": "200.200.200.4",
[root@jh-container-rocky86 ~]# podman exec -it jh-rk86-mariadb03 ping 200.200.200.4
PING 200.200.200.4 (200.200.200.4) 56(84) bytes of data.
64 bytes from 200.200.200.4: icmp_seq=1 ttl=64 time=16.5 ms
64 bytes from 200.200.200.4: icmp_seq=2 ttl=64 time=0.057 ms
64 bytes from 200.200.200.4: icmp_seq=3 ttl=64 time=0.054 ms
64 bytes from 200.200.200.4: icmp_seq=4 ttl=64 time=0.056 ms
^C
--- 200.200.200.4 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3074ms
rtt min/avg/max/mdev = 0.054/4.154/16.451/7.099 ms
[root@jh-container-rocky86 ~]# podman exec -it jh-rk86-mariadb04 ping 200.200.200.3
PING 200.200.200.3 (200.200.200.3) 56(84) bytes of data.
64 bytes from 200.200.200.3: icmp_seq=1 ttl=64 time=0.086 ms
64 bytes from 200.200.200.3: icmp_seq=2 ttl=64 time=0.054 ms
64 bytes from 200.200.200.3: icmp_seq=3 ttl=64 time=0.055 ms
64 bytes from 200.200.200.3: icmp_seq=4 ttl=64 time=0.057 ms
^C
--- 200.200.200.3 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3068ms
rtt min/avg/max/mdev = 0.054/0.063/0.086/0.013 ms
KVM 환경의 Bridge 대역처럼 Podman 에서도 Bridge 대역을 사용할 수 있다.
cni-podman0 인터페이스처럼 NAT를 거치지 않고 외부로 이어지는 방식이다.
Layer 한개를 축소할 수 있어 성능상 이점이 있다.
# podman network
에서는 확인이 안되는데, 커널에 내장된 기본 네트워크라고 생각하면 된다.
[root@jh-container-rocky86 ~]# podman network ls
NETWORK ID NAME DRIVER
a941d590a508 internal-network bridge
2f259bab93aa podman bridge
[root@jh-container-rocky86 ~]# podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f7f874049900 docker.io/library/mariadb:latest mariadbd 3 days ago Up 3 days ago 0.0.0.0:13306->3306/tcp jh-mariadb01
b0f903cb9947 docker.io/library/mariadb:latest mariadbd 24 hours ago Up 24 hours ago 0.0.0.0:23306->3306/tcp jh-mariadb02
72a489ec6981 localhost/jh/rk86-mariadb:240208 /sbin/init 24 hours ago Up 24 hours ago 0.0.0.0:33306->3306/tcp jh-rk86-mariadb03
e48032610086 localhost/jh/rk86-mariadb:240208 /sbin/init 24 hours ago Up 24 hours ago 0.0.0.0:43306->3306/tcp jh-rk86-mariadb04
[root@jh-container-rocky86 ~]# podman rm -af
b0f903cb9947aa57f5c23404796e37b0985e91edad574fdd45152883c154a870
e4803261008676358f0284f94b8c2457880ddf572b4456956ab67cd797018fe4
f7f874049900e0b238d8f446dda44d980d2f086344869c3d1b0f57712a449418
72a489ec69815f8309d48a9e0f302c9d36669d0035acab3b94ad79a981da9d40
- -p 옵션을 사용해도 Host 네트워크의 포트를 직접 사용하므로 무시된다.
- -p 옵션을 제외해도 포트 넘버가 동일하면 충돌이 일어나 접근이 불가능하다.
ex) SSH 22번 포트로 접속을 시도하면 컨테이너가 아닌 Host OS로 접속됨.- 컨테이너 내부에서 포트를 변경해도 접근이 불가능하다.
ex) -p 옵션을 사용하지 않고 컨테이너를 생성한 후, SSH 포트를 변경해도 접근이 불가능하다.결론: Host 네트워크를 사용하면 Host OS의 포트를 직접적으로 바인딩하기 때문에 포트 번호가 겹칠 경우 접속이 불가능하다.
이와 같은 상황을 방지하기 위해 이미지 자체에서 --port
옵션을 사용할 수 있는데,
이 옵션은 Host OS의 포트와 컨테이너의 포트를 연결해주는 포트포워딩과 다르게
컨테이너에 직접 특정 포트를 할당하는 옵션이다.
[root@jh-container-rocky86 ~]# podman run -itd --network host -e MYSQL_ROOT_PASSWORD=1234 --restart always --name jh-mariadb01 mariadb:latest --port 13306
aab0be1586283c32894698c0d4c914929f460ebd86b1e5f3cafceb11392e26cb
[root@jh-container-rocky86 ~]# podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
aab0be158628 docker.io/library/mariadb:latest --port 13306 2 seconds ago Up 2 seconds ago jh-mariadb01
[root@jh-container-rocky86 ~]# netstat -antp | grep 3306
tcp 0 0 0.0.0.0:13306 0.0.0.0:* LISTEN 67109/mariadbd
tcp6 0 0 :::13306 :::* LISTEN 67109/mariadbd
[root@jh-up-test-rhel84 ~]# mysql -uroot -p -h 10.65.121.86 -P 13306
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 3
Server version: 11.2.2-MariaDB-1:11.2.2+maria~ubu2204 mariadb.org binary distribution
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]>
[root@jh-container-rocky86 ~]# ss -4tpn
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
ESTAB 0 36 10.65.121.86:22 10.0.9.6:59499 users:(("sshd",pid=62560,fd=5),("sshd",pid=62546,fd=5))
ESTAB 0 0 10.65.121.86:13306 10.65.121.84:42306 users:(("mariadbd",pid=67109,fd=43))