Docker CentOS8, Fedora에서 컨테이너 Host 사용 불가능한 문제 해결방법.

Updated on

이거 때문에, 못해도 토탈 24시간은 소모한거 같다.. nginx 설정 문제인줄 알고, 수정하고 수정하고.. 근데도 계속 안되서… 테스트용 하나 만들어놓고,, 세팅 하나 씩 해가면서, 다시 reinstall 하고.. 계속 반복하면서… 그래서 도달한 결론에 대해서 설명하고자 한다.

컨테이너에서 Host 간의 연결이 안되는 문제 발생.

CentOS8, Fedora에서 Docker를 설치하고나서, 아래와 같이 명령어를 쳐보면

docker run busybox nslookup google.com

nslookup: write to '108.61.10.10': No route to host
;; connection timed out; no servers could be reached

docker run yauritux/busybox-curl curl google.com

안된다.

컨테이너 간의 Host 문제(?) 아무튼, 이러한게 발생해서 라는데.
그래서 발견한게 아래의 링크다.

https://ahelpme.com/linux/centos-8/firewalld-and-podman-or-docker-no-internet-in-the-container-and-could-not-resolve-host/

그래서, 이것으로 해결했었다. 실제로 dnf install도 문제없이되고, nslookup도 문제없이 된다.

firewall-cmd --list-all

public (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens3
  sources:
  services: cockpit dhcpv6-client ssh
  ports:
  protocols:
  masquerade: yes
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

masquerade: yes 가 yes 처리되어있다.
그리고, 컨테이너간의 Host 역시 잘 된다… 하지만,,, 단,,, 단,, 단 !!!!!!!!!!!!!!!!

nginx, traefik x-real-ip 를 받아올 수 없는 문제 발생.

nginx.conf 로 x-real-ip 를 받아오게 해두거나,
traefik 를 사용하는 경우에 X-REAL-IP를 절대 받아올 수가 없다.

받아오더라도, 무조건 “172.19.0.1” 같이, docker network ip 를 가져온다.

첫번째 해결방법

“etc/firewalld/firewalld.conf” 을 수정하는 방법이다.
FirewallBackend=nftables 을
FirewallBackend=iptables 로 수정한다.

두번째 해결방법

firewall-cmd --permanent --zone=trusted --add-interface=docker0

firewall-cmd --reload

명령어로 적용한다.

이렇게 하면, docker build 할때 dnf install host 라든가, 기타 등등 모든 연결에 문제 없이 잘 된다. 하지만 !!

만약에, 나의 docker-compose service 에 network 가 frontend 나 backend 처럼 다른 네트워크를 생성해둔 상태라면, 꼭 추가한 네트워크도 trusted 존에 추가시켜줘야 한다.

그렇지않으면, traefik 사용하는 상태에서는 아래와 같은 에러가 발생한다.

'502 Bad Gateway' caused by: dial tcp 172.18.0.4:80: connect: no route to host
# ifconfig
br-d193b7e58cd8: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.18.0.1  netmask 255.255.0.0  broadcast 172.18.255.255
        inet6 fe80::42:17ff:fed7:dc73  prefixlen 64  scopeid 0x20<link>
        ether 02:42:17:d7:dc:73  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

br-e34899da24a1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.19.0.1  netmask 255.255.0.0  broadcast 172.19.255.255
        inet6 fe80::42:61ff:fe06:9f0c  prefixlen 64  scopeid 0x20<link>
        ether 02:42:61:06:9f:0c  txqueuelen 0  (Ethernet)
        RX packets 41  bytes 2757 (2.6 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 73  bytes 6079 (5.9 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        inet6 fe80::42:6dff:fe00:e5f1  prefixlen 64  scopeid 0x20<link>
        ether 02:42:6d:00:e5:f1  txqueuelen 0  (Ethernet)
        RX packets 12831  bytes 722769 (705.8 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 18098  bytes 98702867 (94.1 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
firewall-cmd --permanent --zone=trusted --add-interface=br-d193b7e58cd8
firewall-cmd --permanent --zone=trusted --add-interface=br-e34899da24a1

firewall-cmd --reload

그러니.. 위와 같이, 해당 interface도 추가해주면 된다.

firewall-cmd --list-all-zones

public (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens3
  sources:
  services: cockpit dhcpv6-client ssh
  ports:
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:


trusted (active)
  target: ACCEPT
  icmp-block-inversion: no
  interfaces: br-d193b7e58cd8 br-e34899da24a1 docker0
  sources:
  services:
  ports:
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

이렇게 해주면, 이제 X-REAL-IP를 정상적으로 받아올 수가 있다.

이 문제는 docker가 nftables를 지원하지 않아서 생기는거라고 이야기하는것 같은데..
어쨌든… 나중에 지원하고, 공식적으로 고쳐줬으면 하는 바램이다.
일단은… 이렇게 해결했으니 다행이다.

firewall-cmd –permanent –zone=public –add-masquerade
로 적용했을때

firewall-cmd --permanent --zone=trusted --add-interface=docker0
firewall-cmd --permanent --zone=trusted --add-interface=br-87014b87949d
firewall-cmd --permanent --zone=trusted --add-interface=br-fb2316a253cd

firewall-cmd --reload

로 적용하면 될듯 싶다.

https://github.com/docker/for-linux/issues/955