私は現在、Dockerを通じてRaspberry Pi 4でさまざまなサービスをホストする小規模なホームプロジェクトを進めています。このプロジェクトの進行中に実際に解決できないDNS問題に直面しました。コンテナ内でピホールをホストし、ルータをアップストリームDNSサーバーとして使用するように設定します。私のルーターでは、ラズベリーパイをローカルDNSサーバーとして設定し、別のアップストリームDNSサーバーを追加しました。私の理解によると、すべてのDNS要求は私のラズベリーパイのPyholeコンテナを介してルーティングされ、次の問題を解決するために私のルータに再ルーティングされます。これまで、この設定はRaspberry Pi自体を含むローカルネットワーク上のすべてのデバイスで機能します。
今私が持っている唯一の問題は、同じラズベリーパイの他のコンテナがPyholeと同じまたは異なるネットワークにあることです。彼らはすべてDNSクエリを解析するのに問題があるようです。例:piholeコンテナと同じDockerネットワークに接続されている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デーモンを再起動しました
- docker-compose.ymlに含まれるネットワークを再作成しました。
- phpmyadminコンテナを再作成しました。
これまで、上記の手順のいずれも問題を解決できませんでした。
興味のあるところ、私はルーターのIPをホストシステムの/etc/dhcpcd.confにある静的ネームサーバーに設定し、dhcpcdとdockerデーモンを再ロードしました。 phpmyadminコンテナにSSHを接続すると、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にlocalhostの代わりに完全なIPが含まれているのですか?私のホストは独自のIPを使用してDNSクエリを解決できますが、私のDockerコンテナはそうではないのですか?ホスト名サーバーをルーターに設定せずにこの問題を解決するにはどうすればよいですか?
答え1
したがって、この問題をさらに詳しく知るために(私は私のPiの1つで同じ問題が発生しました。)、そのサーバーでローカル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
。そうでない場合は、ファイルを編集します。 (この段階についてはよくわかりません。触れていますが、今は機能して触れたくありません。