Podmanのmacvlanをやってみる

外部ネットワークからコンテナに接続する場合、macvlanプラグインを使用することでホストと同じネットワークに接続することができます。

ただし、ルートレスモードではmacvlanを利用することはできません。なぜなら、ルートレスモードはユーザの権限で実行されているため、ネットワークスタックに対して十分な権限を有していないからです。

注記

この手順は、ルートフルコンテナーにのみ適用されます。ルートレスコンテナーは、macvlan および dhcp プラグインを使用することができません。

12.4. macvlan プラグイン Red Hat Enterprise Linux 8 | Red Hat Customer Portal

ルートレスモードのコンテナは、内部ブリッジのみ利用することができ、ホストのネットワークインターフェースとは完全に分離されています。

そこで今回は、ルートフルモードで起動されたPodmanのコンテナを、ホストサーバ上のネットワークインターフェースを介して外部ネットワークと通信させるmacvlanプラグインの利用方法について解説します。

なお、Podmanの基本的な使い方は、こちらで解説しています。

Podmanのmacvlanをやってみる

Podmanは、ホストサーバ上のネットワークインターフェースを介してコンテナを外部ネットワークと通信できるようにする仕組みがあります。

ホストサーバのNIC上に仮想NICを作成し、そこに固有のMACアドレスを割り当てることで、ホストサーバと異なるIPアドレスをコンテナに割り当てることができます。このプラグインのことをmacvlanと呼びます。

macvlanのイメージ図

上図では、ホストが属しているサブネットに4つのAlmaLinuxコンテナが接続されています。それぞれのコンテナは、割り当てられたIPアドレスで外部ネットワークと通信することが可能です。

macvlanを作成する

macvlanプラグインは、ルートフルモードのみ利用可能です。よって、以下の作業はホストサーバにrootでログインして作業する必要があります。

今回の検証で利用するPodman(2023年5月時点)とOSのバージョンは、以下の通りです。

$ podman -v
podman version 4.4.1

$ cat /etc/redhat-release
Red Hat Enterprise Linux release 8.5 (Ootpa)

macvlanを作成は、podman network createコマンドを使います。

$ podman network create --driver macvlan --subnet=192.168.11.0/24 --gateway=192.168.11.254 -o parent=enp0s25 test_macvlan01
test_macvlan01

$ podman network ls
NETWORK ID    NAME            DRIVER
2f259bab93aa  podman          bridge
8c833f42187c  test_macvlan01  macvlan

–driverオプションでmacvlanを指定します。ホストサーバのサブネットをCIDR形式で指定し、–gatewayオプションでデフォルトゲートウェイを指定します。-o parentオプションでホストサーバのインタフェース名を指定します。

作成したmacvlanの内容を確認します。

$ podman network inspect test_macvlan01
[
     {
          "name": "test_macvlan01",
          "id": "8c833f42187ccefc217d22e79731ac4924d664f8b43fac3a3228ebbd08ddbe08",
          "driver": "macvlan",
          "network_interface": "enp0s25",
          "created": "2023-05-21T05:50:00.868540812Z",
          "subnets": [
               {
                    "subnet": "192.168.11.0/24",
                    "gateway": "192.168.11.254"
               }
          ],
          "ipv6_enabled": false,
          "internal": false,
          "dns_enabled": false,
          "ipam_options": {
               "driver": "host-local"
          }
     }
]

macvlanにコンテナを接続する

作成したmacvlanにAlmaLinuxコンテナを接続します。今回は、外部ネットワークからAlmaLinuxコンテナにSSH接続できるように設定します。

まず、Containerfileを使用してAlmaLinuxのOSイメージにrootのパスワード(任意)とユーザアカウント(testuser)を新規に追加します。

次に、opensshをインストールして、SSHのポートをデフォルトの「22」から「2222」に変更します。また、rsyslogもインストールして、/var/logの下にsecureやmessagesなどのログを出力させます。

Containerfileは、以下のように記述します。

$ vi Containerfile

FROM docker.io/library/almalinux:latest

USER root

RUN echo root:roottest | chpasswd
RUN groupadd -g "1000" "test"
RUN useradd -u "1000" -g "test" -s /bin/bash testuser
RUN echo testuser:test0000 | chpasswd
RUN dnf -y install openssh-server; dnf -y install openssh-clients; dnf -y install rsyslog; dnf clean all
RUN echo "Port 2222" >> /etc/ssh/sshd_config
RUN systemctl enable rsyslog

Containerfileを作成したら、almaLinuxのOSコンテナイメージを「alma_test:1.0.0」というタグでbuildしていきます。

$ podman build -t alma_test:1.0.0 -f Containerfile .

・・<途中省略>・・
Complete!
28 files removed
--> bf42fe1b84b
STEP 8/9: RUN echo "Port 2222" >> /etc/ssh/sshd_config
--> 688a67636e2
STEP 9/9: RUN systemctl enable rsyslog
COMMIT alma_test:1.0.0
--> acaf7d8e50a
Successfully tagged localhost/alma_test:1.0.0
acaf7d8e50a58184ca6a6e98fb9daccab207ab91bbf8eac6db8a87082cdb4f60

$ podman images
REPOSITORY                   TAG         IMAGE ID      CREATED         SIZE
localhost/alma_test          1.0.0       acaf7d8e50a5  35 seconds ago  210 MB
docker.io/library/almalinux  latest      7ba003a70874  8 days ago      190 MB

作成されたOSコンテナイメージをコンテナ起動します。その際、先ほど作成したmacvlanネットワークに接続するようにします。

podman runコマンドを実行する際に、–netオプションを追加して接続するネットワーク名(またはネットワークID)を指定します。–ipオプションでコンテナに割り当てるIPアドレスを指定します。

$ podman run -d -it --rm --net test_macvlan01 --ip=192.168.11.1 --name test_almalinux01 alma_test:1.0.0 /sbin/init
fff6b9a066d4daa8d21889e45e7f5e8126a75dbf95fc6f93ef63e7056a69546f

$ ppodman ps
CONTAINER ID  IMAGE                      COMMAND     CREATED         STATUS         PORTS       NAMES
fff6b9a066d4  localhost/alma_test:1.0.0  /sbin/init  42 seconds ago  Up 42 seconds              test_almalinux01

macvlanに接続されたAlmaLinuxコンテナが立ち上がりました。コンテナに入ってネットワーク設定など確認します。

$ podman exec -it test_almalinux01 /bin/bash

[root@fff6b9a066d4 /]# hostname -i
192.168.11.1
[root@fff6b9a066d4 /]# systemctl status sshd
● sshd.service - OpenSSH server daemon
     Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; preset: enabled)
     Active: active (running) since Sun 2023-05-21 07:52:31 UTC; 1min 18s ago
       Docs: man:sshd(8)
             man:sshd_config(5)
   Main PID: 50 (sshd)
     CGroup: /machine.slice/libpod-fff6b9a066d4daa8d21889e45e7f5e8126a75dbf95fc6f93ef63e7056a69546f.scope/system.slice/sshd>
             mq50 "sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups"

May 21 07:52:31 fff6b9a066d4 systemd[1]: Starting OpenSSH server daemon...
May 21 07:52:31 fff6b9a066d4 sshd[50]: main: sshd: ssh-rsa algorithm is disabled
May 21 07:52:31 fff6b9a066d4 sshd[50]: Server listening on 0.0.0.0 port 2222.
May 21 07:52:31 fff6b9a066d4 sshd[50]: Server listening on :: port 2222.
May 21 07:52:31 fff6b9a066d4 systemd[1]: Started OpenSSH server daemon.

[root@fff6b9a066d4 /]# systemctl status rsyslog
× rsyslog.service - System Logging Service
     Loaded: loaded (/usr/lib/systemd/system/rsyslog.service; enabled; preset: enabled)
     Active: failed (Result: exit-code) since Sun 2023-05-21 07:52:30 UTC; 1min 56s ago
       Docs: man:rsyslogd(8)
             https://www.rsyslog.com/doc/
    Process: 46 ExecStart=/usr/sbin/rsyslogd -n $SYSLOGD_OPTIONS (code=exited, status=255/EXCEPTION)
   Main PID: 46 (code=exited, status=255/EXCEPTION)

May 21 07:52:30 fff6b9a066d4 systemd[1]: rsyslog.service: Main process exited, code=exited, status=255/EXCEPTION
May 21 07:52:30 fff6b9a066d4 systemd[1]: rsyslog.service: Failed with result 'exit-code'.
May 21 07:52:30 fff6b9a066d4 systemd[1]: Failed to start System Logging Service.
May 21 07:52:30 fff6b9a066d4 systemd[1]: rsyslog.service: Scheduled restart job, restart counter is at 5.
May 21 07:52:30 fff6b9a066d4 systemd[1]: Stopped System Logging Service.
May 21 07:52:30 fff6b9a066d4 systemd[1]: rsyslog.service: Start request repeated too quickly.
May 21 07:52:30 fff6b9a066d4 systemd[1]: rsyslog.service: Failed with result 'exit-code'.
May 21 07:52:30 fff6b9a066d4 systemd[1]: Failed to start System Logging Service.

コンテナ起動したAlmaLinuxが、192.168.11.1のIPアドレスでネットワークに接続され、sshdが「2222」ポートをリスニングしていることが確認できましたが、rsyslogはサービスの起動に失敗しています。

外部ネットワークからSSH接続する

今度は外部ネットワークからコンテナにアクセスしてみます。

PCのWindows PowerShellから、ホストサーバ上のAlmaLinuxコンテナに対してpingを打ってみます。

PS C:\Users\testuser> ping 192.168.11.1

192.168.11.1 に ping を送信しています 32 バイトのデータ:
192.168.11.1 からの応答: バイト数 =32 時間 =1ms TTL=64
192.168.11.1 からの応答: バイト数 =32 時間 =2ms TTL=64
192.168.11.1 からの応答: バイト数 =32 時間 =2ms TTL=64
192.168.11.1 からの応答: バイト数 =32 時間 =2ms TTL=64

192.168.11.1 の ping 統計:
    パケット数: 送信 = 4、受信 = 4、損失 = 0 (0% の損失)、
ラウンド トリップの概算時間 (ミリ秒):
    最小 = 1ms、最大 = 2ms、平均 = 1ms

pingの応答が返ってきましたので、ネットワークは接続できていることが確認できました。

次に、teratermを使ってAlmaLinuxのコンテナにSSH接続してみます。今回の検証で使用しているホストサーバはRHEL 8.5なので、firewall-cmdを使って「2222」のTCPポートを開放しておきます。

$ firewall-cmd --add-port=2222/tcp --zone=public --permanent
success

$ firewall-cmd --reload
success

$ firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: enp0s25
  sources:
  services: cockpit dhcpv6-client ssh
  ports: 2222/tcp
  protocols:
  forward: no
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

teratermを起動して、ホストに「192.168.11.1」を入力します。TCPポートは「22」から「2222」に変更してOKボタンを押します。

ユーザ名は、podman build実行時にContainerfileに指定した「testuser」を入力します。パスフレーズも同様で、今回は「test0000」を入力しOKボタンを押します。

teratermが消えてしまいました。SSH接続の成否をAlmaLinuxコンテナから確認します。システムログインは、lastコマンドで確認することができます。

[root@fff6b9a066d4 /]# last
testuser pts/2        192.168.11.185   Sun May 21 07:58 - 07:58  (00:00)
reboot   system boot  4.18.0-348.el8.x Sun May 21 07:52   still running

「testuser」という名前で接続されたことが記録されています。どうやらSSH接続には問題はなさそうです。

次に、新しいAlmaLinuxのコンテナ(test_almalinux02)を–privilegedオプションを付与して起動します。

$ podman run --privileged -d -it --rm --net test_macvlan01 --ip=192.168.11.2 --name test_almalinux02
 alma_test:1.0.0 /sbin/init
9ceac70ef03b44c9695585c93e5561873c55918c4bbe8952f39094ea8f4b10c6

$ podman ps
CONTAINER ID  IMAGE                      COMMAND     CREATED         STATUS         PORTS       NAMES
fff6b9a066d4  localhost/alma_test:1.0.0  /sbin/init  16 minutes ago  Up 16 minutes              test_almalinux01
9ceac70ef03b  localhost/alma_test:1.0.0  /sbin/init  30 seconds ago  Up 29 seconds              test_almalinux02

test_almalinux02(IPアドレス=192.168.11.2)にteratermからSSH接続してみます。

ユーザ名とパスワードは、先ほどと同じ「testuser」と「test0000」を入力しOKボタンを押します。

今度はteratermが閉じてしまう事象は発生せず、正常に接続できました。test_almalinux01(IPアドレス=192.168.11.1)で起動が失敗していたrsyslogも正常に起動できています。

–privilegedオプションを指定した場合、コンテナをホストから分離するセキュリティー機能が無効化されるとのことです。セキュリティ機能を無効化している点では少々気になるところですが、現時点では、–privilegedオプションを使うしかなさそうです。

ここまで、macvlanネットワークを利用することで、ホストサーバのNIC上に作成された仮想NICを経由して、コンテナが外部ネットワークと通信できることを検証しました。

macvlanネットワークで接続されたコンテナ間は通信可能ですが、コンテナとホスト間は通信できないことに注意してください。

まとめ

いかがでしたでしょうか。

今回は、Podmanのルートフルモード下でmacvlanネットワークとコンテナを接続して、外部ネットワークと通信させる方法について解説しました。

macvlanを利用することで、外部ネットワークと通信可能な論理ネットワークを簡単に作成することができます。

今回のように、SSHを起動させたAlmaLinuxのコンテナにmacvlanネットワークに接続することで、外部ネットワークからLinuxサーバとして普通に利用できるため、開発、研究や教育の現場において、コンピュータ資源を効率的に活用することができます。

現時点(2023年5月時点)では、macvlanをルートレスモードで利用することができません。ルートレスモードで利用できるネットワークは内部ブリッジのみに限られていますので、OSイメージコンテナが外部ネットワークと通信する必要がなければルートレスモードの利用を、必要があればルートフルモードの利用を検討することになりそうです。

また、コンテナをホストから分離するセキュリティー機能を無効化する–privilegedオプションの利用については、詳細がわからない部分も多いため、その使い方については気を付けるべきなのかもしれません。

参考になれば幸いです。

システムのお悩みについてご相談ください

本サイトの掲載内容に関するお問い合わせは、こちらから承ります。
SOHOのシステム運用管理に関するお悩みごとについて、なんでもお気兼ねなくご相談ください。
現役システムエンジニアのスタッフが、ボランティアでご相談にご対応させていただきます。
Podman

前の記事

Podman Networkをやってみる
IT関連

次の記事

GlassFishを構築してみる