Docker 容器 DNS 無法與 pihole 一起使用
我目前正在做一個小型家庭項目,我通過 docker 在樹莓派 4 上託管各種服務。在從事這個項目時,我現在遇到了一個我無法真正理解的 dns 問題。我在容器內託管 pihole 並將其配置為使用我的路由器作為上游 dns 伺服器。在我的路由器上,我已將樹莓派配置為本地 dns 伺服器,並添加了其他一些上游 dns 伺服器。據我了解,這將導致所有 dns 請求通過我的樹莓派上的 pihole 容器路由,然後返回到我的路由器以解決問題。到目前為止,此設置適用於我本地網路上的所有設備,包括樹莓派本身。
我現在遇到的唯一問題是同一個樹莓派上的其他容器在與 pihole 相同和/或不同的網路中。他們似乎都有解決 dns 查詢的問題。例如:我有一個 phpmyadmin 計數器連接到與 pihole 容器相同的 docker 網路。如果我現在 ssh 進入 phpmyadmin 容器並想要執行“ping google.com”或“apt-get update”,由於 dns 失敗,它將無法執行這些命令。
我已經檢查過的內容:
- 我查看了 phpmyadmin 容器的 /etc/resolv.conf =>它包括 127.0.0.11 - 我的知識是正確的
- 我查看了主機的 /etc/resolv.conf =>它包括我的樹莓派的實際 ip(不是 127.0.0.1)。我不明白為什麼它在這裡使用實際 ip 而不是 localhost 但它確實可以工作
- 我重新啟動了 docker 守護程序
- 我重新創建了 docker-compose.yml 中包含的網路
- 我重新創建了 phpmyadmin 容器
到目前為止,上述步驟都沒有解決問題。
出於好奇,我在主機上的 /etc/dhcpcd.conf 中將路由器的 ip 設置為靜態名稱伺服器,並重新載入了 dhcpcd 和 docker 守護程序。如果我現在 ssh 進入我的 phpmyadmin 容器 dns 突然起作用了。我再次排除了我的路由器 ip 以驗證我的問題,並且 dns 立即停止工作。這使我得出結論,我的所有 docker 容器(不包括 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 包含它自己的完整 ip 而不是 localhost?為什麼我的主機能夠使用自己的 ip 解析 dns 查詢,但我的 docker 容器卻不能?如果不將主機名稱伺服器設置為我的路由器,如何解決此問題?
因此,進一步深入研究這個問題(我在其中一個 Pis 上遇到了同樣的問題),我發現如果你在該伺服器上執行本地 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
。至於為什麼在預設情況下
resolvconf
將 Pi 的 IP 地址放入其中/etc/resolv.conf
- 我相信除非您覆蓋name_servers
或在 中自定義內容/etc/network/interfaces
,否則它通常會放入您的路由器提供的 DNS 伺服器的 IP 中 - 這將是你的 Pi 的 IP 地址!(Catch 22 ……但調試起來很棘手,因為除了 Docker 之外的許多東西都可以在該設置下正常工作!)。