podman のコンテナ名で通信する


コンテナを複数立ち上げた場合、他のコンテナへアクセスする場合は

  • 10.88.0.60 のように、起動のたびに変わるIPを指定する
  • 10.88.0.1:8080 のように、ホストのIPを指定&ポートフォワーディング
  • pod を使ってコンテナをまとめる

の3パターンがあります。Docker だと IP ではなくコンテナ名でアクセスできたので、podman でもできないか試してみました。

更新: ホスト側の設定方法を追加しました

今回は rootful コンテナで試します(rootless まだ理解できていない・・・)。

プラグインのインストール

使用するのは dnsname プラグインです。

まずは dnf でインストールできるか確認します。

dnf list podman-plugins
利用可能な場合
Available Packages
podman-plugins.aarch64                        2.0.4-1.el8                        devel_kubic_libcontainers_stable

インストール済みの場合
Installed Packages
podman-plugins.x86_64                         2.0.4-1.el8                        @devel_kubic_libcontainers_stable

dnf 経由でインストールしたい場合はこちらの記事を参考にしてください。

未インストール&利用可能な場合はインストールします。

dnf install podman-plugins

make する場合

go 言語が必要なので、なければインストールしておきます。

dnf install golang

作業フォルダを作成し、 ファイルを落とします。

git clone https://github.com/containers/dnsname.git
cd dnsname

make します。

make
make install PREFIX=/usr

プラグインを設定に追加する

/etc/cni/net.d/87-podman-bridge.conflist ファイルに設定を追加します。このファイルはデフォルトネットワーク用です。podman network create した場合は、同じディレクトリにネットワークごとにファイルが生成されています。

設定ファイルに plugins 配列があるので、その中に「”type”: “dnsname”」を追加してください。

{
  "plugins": [
    {
      "type": "bridge",
      ....
    },
    {
      "type": "dnsname",
      "domainName": "example.com"
    }
  ]
}

動作確認

network に設定を反映する方法が不明なのですが、少なくともコンテナをすべて落としてから立ち上げ直す必要があると思います。(私は面倒なので reboot しました)

ping コンテナ名 や curl http://コンテナ名 などでアクセスできるようになっていると思います。pod の中のコンテナはコンテナ名ではなく http://ポッド名 になります。

ホスト側の設定

ここまでで、コンテナ同士での名前解決はできるようになったのですが、ホスト側からコンテナへの名前解決はできません。ホスト側に dnsmasq を設定する必要があります。

dnf install dnsmasq

Network Manager から dnsmasq を立ち上げるよう設定できるので、設定 /etc/NetworkManager/NetworkManager.conf を追加します。[main] セクション内に dns=dnsmasq を追加します。

[main]
#plugins=ifcfg-rh
dns=dnsmasq
systemctl restart NetworkManager

NetworkManager を再起動すると、 dnsmasq プロセスが立ち上がっているはずです。(podman の dnsmasq と NetworkManager の dnsmasq で2行表示されます)

$ ps ww -C dnsmasq
    PID TTY      STAT   TIME COMMAND
   1234 ?        S      0:00 /usr/sbin/dnsmasq -u root --conf-file=/run/containers/cni/dnsname/podman/dnsmasq.conf
   3456 ?        S      0:00 /usr/sbin/dnsmasq --no-resolv --keep-in-foreground --no-hosts --bind-interfaces --pid-file=/run/NetworkManager/dnsmasq.pid --listen-address=127.0.0.1 --cache-size=400 --clear-on-reload --conf-file=/dev/null --proxy-dnssec --enable-dbus=org.freedesktop.NetworkManager.dnsmasq --conf-dir=/etc/NetworkManager/dnsmasq.d

resolv.conf も書き変わっています。

$ cat /etc/resolv.conf
# Generated by NetworkManager
search example.com
nameserver 127.0.0.1

次に DNS サーバーの設定をします。 dnsname プラグインで指定した domainName の場合は、 dnsname プラグインの dnsmasq で名前解決するよう設定します。

$ vim /etc/NetworkManager/dnsmasq.d/my-dns.conf

# IPv6 でも動くようにする
listen-address=::1

# podman
server=/example.com/10.88.0.1

もう一度 NetworkManager を再起動すると反映されます。

systemctl restart NetworkManager

これで [container-name].example.com でつながるようになります。resolv.conf の search も example.com で統一されていれば、ドメイン部分は省略できます。

search を統一するには、 /etc/sysconfig/network-scripts/ 内にネットワークごとにファイルがあるので、そこに以下を追記し NetworkManager を再起動すれば反映されます。

DOMAIN=example.com

参考


コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください