Podmanのmacvlanをやってみる
外部ネットワークからコンテナに接続する場合、macvlanプラグインを使用することでホストと同じネットワークに接続することができます。
ただし、ルートレスモードではmacvlanを利用することはできません。なぜなら、ルートレスモードはユーザの権限で実行されているため、ネットワークスタックに対して十分な権限を有していないからです。
注記
この手順は、ルートフルコンテナーにのみ適用されます。ルートレスコンテナーは、
12.4. macvlan プラグイン Red Hat Enterprise Linux 8 | Red Hat Customer Portalmacvlan
およびdhcp
プラグインを使用することができません。
ルートレスモードのコンテナは、内部ブリッジのみ利用することができ、ホストのネットワークインターフェースとは完全に分離されています。
そこで今回は、ルートフルモードで起動されたPodmanのコンテナを、ホストサーバ上のネットワークインターフェースを介して外部ネットワークと通信させるmacvlanプラグインの利用方法について解説します。
なお、Podmanの基本的な使い方は、こちらで解説しています。
Podmanのmacvlanをやってみる
Podmanは、ホストサーバ上のネットワークインターフェースを介してコンテナを外部ネットワークと通信できるようにする仕組みがあります。
ホストサーバのNIC上に仮想NICを作成し、そこに固有のMACアドレスを割り当てることで、ホストサーバと異なるIPアドレスをコンテナに割り当てることができます。このプラグインのことを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のシステム運用管理に関するお悩みごとについて、なんでもお気兼ねなくご相談ください。
現役システムエンジニアのスタッフが、ボランティアでご相談にご対応させていただきます。