저는 현재 Docker를 통해 Raspberry Pi 4에서 다양한 서비스를 호스팅하는 소규모 홈 프로젝트를 진행하고 있습니다. 이 프로젝트를 진행하는 동안 실제로 해결할 수 없는 DNS 문제에 직면하게 되었습니다. 컨테이너 내부에 pihole을 호스팅하고 라우터를 업스트림 DNS 서버로 사용하도록 구성합니다. 내 라우터에서 라즈베리 파이를 로컬 DNS 서버로 구성하고 다른 업스트림 DNS 서버를 추가했습니다. 내 이해에 따르면 모든 DNS 요청이 내 라즈베리 파이의 파이홀 컨테이너를 통해 라우팅된 다음 문제를 해결하기 위해 내 라우터로 다시 라우팅됩니다. 지금까지 이 설정은 Raspberry Pi 자체를 포함하여 로컬 네트워크의 모든 장치에서 작동합니다.
지금 내가 가진 유일한 문제는 동일한 라즈베리 파이의 다른 컨테이너가 파이홀과 동일하거나 다른 네트워크에 있다는 것입니다. 그들은 모두 DNS 쿼리를 구문 분석하는 데 문제가 있는 것 같습니다. 예: pihole 컨테이너와 동일한 도커 네트워크에 연결된 phpmyadmin 카운터가 있습니다. 이제 phpmyadmin 컨테이너에 ssh를 연결하고 "google.com을 ping"하거나 "apt-get update"하려고 하면 DNS 오류로 인해 해당 명령을 실행할 수 없습니다.
제가 확인한 내용:
- phpmyadmin 컨테이너의 /etc/resolv.conf를 확인했습니다 =>여기에는 127.0.0.11이 포함되어 있습니다. 제가 아는 한 이것이 정확합니다.
- 호스트의 /etc/resolv.conf =>를 확인했습니다.여기에는 내 Raspberry Pi의 실제 IP(127.0.0.1 아님)가 포함됩니다. 여기서 localhost 대신 실제 IP를 사용하는 이유를 이해할 수 없지만 어쨌든 작동합니다.
- 도커 데몬을 다시 시작했습니다
- docker-compose.yml에 포함된 네트워크를 다시 만들었습니다.
- phpmyadmin 컨테이너를 다시 만들었습니다.
지금까지 위의 단계 중 어느 것도 문제를 해결하지 못했습니다.
호기심에 나는 라우터의 IP를 호스트 시스템의 /etc/dhcpcd.conf에 있는 정적 이름 서버로 설정하고 dhcpcd 및 docker 데몬을 다시 로드했습니다. 이제 phpmyadmin 컨테이너에 SSH를 연결하면 DNS가 갑자기 작동합니다. 문제를 확인하기 위해 라우터 IP를 다시 제외했고 DNS가 즉시 작동을 멈췄습니다. 이로 인해 내 모든 도커 컨테이너(pihole 제외 - 이 컨테이너에 대해 DNS 127.0.0.1을 지정했기 때문에)가 내 호스트 IP 주소를 DNS로 사용하는 데 문제가 있는 것 같다는 결론에 도달했습니다.
내 현재 docker-compose.yml:
version: '3'
services:
portainer:
image: portainer/portainer-ce:linux-arm
container_name: portainer
restart: unless-stopped
environment:
TZ: Europe/Berlin
networks:
- frontend
volumes:
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock
- portainer_data:/data
labels:
- traefik.enable=true
- traefik.docker.network=compose_frontend
- traefik.http.routers.portainer.entrypoints=web_tcp
- traefik.http.routers.portainer.rule=Host(`portainer.mydomain`)
- traefik.http.services.portainer.loadbalancer.server.port=9000
traefik:
image: traefik:latest
container_name: traefik
restart: unless-stopped
environment:
TZ: Europe/Berlin
networks:
- frontend
ports:
- 80:80
volumes:
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- /home/farmadmin/config/traefik:/etc/traefik
labels:
- traefik.enable=true
- traefik.docker.network=compose_frontend
- traefik.http.routers.traefik.entrypoints=web_tcp
- traefik.http.routers.traefik.rule=Host(`traefik.mydomain`)
- traefik.http.services.traefik.loadbalancer.server.port=8080
pihole:
image: pihole/pihole:latest
container_name: pihole
restart: unless-stopped
environment:
TZ: Europe/Berlin
networks:
- frontend
dns:
- 127.0.0.1
ports:
- 53:53/tcp
- 53:53/udp
volumes:
- /etc/localtime:/etc/localtime:ro
- etc-pihole:/etc/pihole/
- etc-dnsmasq.d:/etc/dnsmasq.d/
labels:
- traefik.enable=true
- traefik.docker.network=compose_frontend
- traefik.http.routers.pihole.entrypoints=web_tcp
- traefik.http.routers.pihole.rule=Host(`pihole.mydomain`)
- traefik.http.routers.pihole.middlewares=dashboard_prefix
- traefik.http.middlewares.dashboard_prefix.addprefix.prefix=/admin
- traefik.http.services.pihole.loadbalancer.server.port=80
mariadb:
image: linuxserver/mariadb:latest
container_name: mariadb
restart: unless-stopped
environment:
- TZ=Europe/Berlin
- PUID=1000
- PGID=1000
networks:
- backend
volumes:
- mariadb_data:/config
phpmyadmin:
image: phpmyadmin:latest
container_name: phpmyadmin
restart: unless-stopped
environment:
- TZ=Europe/Berlin
- PMA_HOST=mariadb
- PMA_PORT=3306
networks:
- frontend
- backend
labels:
- traefik.enable=true
- traefik.docker.network=compose_frontend
- traefik.http.routers.phpmyadmin.entrypoints=web_tcp
- traefik.http.routers.phpmyadmin.rule=Host(`phpmyadmin.mydomain`)
- traefik.http.services.phpmyadmin.loadbalancer.server.port=80
networks:
frontend:
backend:
internal: true
volumes:
# Persistent Portainer Data
portainer_data:
# Persistent Pihole Data
etc-pihole:
etc-dnsmasq.d:
# Persistent MariaDB Data
mariadb_data:
그래서 내 질문은: 왜 호스트의 resolv.conf에 localhost 대신 전체 IP가 포함되어 있습니까? 내 호스트는 자체 IP를 사용하여 DNS 쿼리를 확인할 수 있는데 내 Docker 컨테이너는 그렇지 않은 이유는 무엇입니까? 호스트 이름 서버를 라우터에 설정하지 않고 이 문제를 어떻게 해결할 수 있습니까?
답변1
따라서 이 문제를 더 자세히 알아보기 위해(저는내 Pi 중 하나에서 동일한 문제가 발생했습니다.), 해당 서버에서 로컬 DNS 확인자를 실행 중이고 Docker의 DNS가 올바르게 작동하도록 하려면 Pi의 파일에 (언급한 대로) /etc/resolv.conf
이름 서버가 있는지 확인해야 한다는 것을 알았습니다.127.0.0.1
변경 사항을 적용하려면 파일을 편집 /etc/resolvconf.conf
하고 다음 줄의 주석 처리를 제거해야 합니다.
# If you run a local name server, you should uncomment the below line and
# configure your subscribers configuration files below.
name_servers=127.0.0.1
그런 다음 즉시 파일을 다시 시작하거나 재생성할 수 있습니다 sudo resolvconf -u
.
기본적으로 Pi의 IP 주소를 입력하는 이유는 resolvconf
- 이를 재정의하거나 사용자 정의하지 않는 한 일반적으로 라우터에서 제공하는 DNS 서버의 IP를 입력하며 이것이 Pi의 IP 주소가 될 것입니다! (규칙 22... 하지만 Docker 이외의 많은 것들이 이 설정에서 잘 작동하기 때문에 디버깅하기가 까다롭습니다!)/etc/resolv.conf
name_servers
/etc/network/interfaces
답변2
Pi-hole
+ wg-easy
내부 도커
RPi 4의 docker에서 (wireguard VPN) pi-hole
을 실행하려고 합니다. wg-easy
문제는 eth0
RPi의 IP 주소를 클라이언트의 DNS 서버로 설정하는 것이 wg-easy
작동하지 않는다는 것입니다. Chrome의 페이지가 "로드 중"에서 멈춥니다. 설정하면 1.1.1.1
제대로 작동했지만 (분명히) 로컬 localhostname에 대한 액세스 권한을 잃었습니다. OP가 설명한 것과 유사합니다.
에서 영감을 받다
- @geerlingguy 여기요
- https://stackoverflow.com/a/24326540/1310733
pihole.log
포함된 것처럼 보임query[HTTPS] google.com from 172.18.0.1
docker0
해당 IP 주소를 DNS 서버 IP로 사용해 보았습니다 . 효과가 있었어요!
내가 한 단계:
- 인터페이스에서 RPi의 IP 주소를 가져옵니다
docker0
(위에 링크된 SO 응답에서 가져온 출력).
$ sudo ip addr show docker0
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 56:84:7a:fe:97:99 brd ff:ff:ff:ff:ff:ff
inet 172.17.42.1/16 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::5484:7aff:fefe:9799/64 scope link
valid_lft forever preferred_lft forever
- IP 주소를
172.17.42.1
네임서버로 설정/etc/resolvconf.conf
# Configuration for resolvconf(8)
# See resolvconf.conf(5) for details
resolv_conf=/etc/resolv.conf
# If you run a local name server, you should uncomment the below line and
# configure your subscribers configuration files below.
# docker0 interface with running pi-hole
name_servers=172.17.42.1
- 고쳐 쓰다
resolvconf
sudo resolvconf -u
- 이것이 의
name_servers=172.17.42.1
유일한 항목인지 확인하십시오/etc/resolv.conf
. 그렇지 않은 경우 파일을 편집하십시오. (이 단계에 대해 잘 모르겠습니다. 만지작거리고 있는데 이제 작동하고 만지고 싶지 않습니다.