Docker 容器 DNS 无法与 pihole 配合使用

Docker 容器 DNS 无法与 pihole 配合使用

我目前正在开发一个小型家庭项目,其中我通过 docker 在树莓派 4 上托管各种服务。在从事这个项目时,我现在遇到了一个 dns 问题,我无法真正解决这个问题。我在容器内托管 pihole 并将其配置为使用我的路由器作为上游 DNS 服务器。在我的路由器上,我已将树莓派配置为本地 dns 服务器,并添加了其他一些上游 dns 服务器。根据我的理解,这将导致所有 dns 请求通过我的树莓派上的 pihole 容器进行路由,然后返回到我的路由器以解决它。到目前为止,此设置适用于我本地网络上的所有设备,包括树莓派本身。

我现在遇到的唯一问题是同一个树莓派上的其他容器与 pihole 位于相同和/或不同的网络中。他们似乎都在解析 dns 查询时遇到问题。例如:我有一个 phpmyadmin countainer 连接到与 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 容器却不能?在不将主机名称服务器设置到路由器的情况下,如何解决此问题?

答案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

至于为什么默认resolvconf将 Pi 的 IP 地址放入- 我相信除非你覆盖或在 中进行了自定义,否则它通常会放入你的路由器提供的 DNS 服务器的 IP - 这将是你的 Pi 的 IP 地址! (第 22 条规则...但是调试起来很棘手,因为除了 Docker 之外的许多东西都可以在该设置下正常工作!)。/etc/resolv.confname_servers/etc/network/interfaces

答案2

Pi-hole+wg-easy内部泊坞窗

我试图在 RPi 4 上的 docker 下运行pi-holewg-easy(wireguard VPN)。问题是,将eth0RPi 的 IP 地址设置为客户端中的 DNS 服务器wg-easy不起作用 - Chrome 中的页面卡在“正在加载”。设置它1.1.1.1使其工作,但我失去了对本地本地主机名的访问(显然)。类似OP描述的那样。

灵感来自

我尝试使用该docker0IP地址作为DNS服务器IP。它成功了!

我所做的步骤:

  1. 获取接口上 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
  1. 将 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
  1. 更新resolvconf
sudo resolvconf -u
  1. 检查 是否name_servers=172.17.42.1是 中的唯一条目/etc/resolv.conf。如果没有,请编辑该文件(我不确定这一步,我正在摆弄它,现在它可以工作了,我不想碰它

相关内容