DockerコンテナでOvSやSR-IOVを使用する場合の設定方法を記載します。
通常のLinuxBridgeやdockerコマンド(macvlan)を使用したネットワーク設定方法については前回記事
Dockerコンテナのネットワーク設定方法 - Metonymical Deflection
を参照してください。
また、OvSについては以下の過去記事のDocker版となります。
CentOS7 ovs(Open vSwitch)のネットワーク設定方法 - Metonymical Deflection
加えて、SR-IOVについては以下の過去記事のDocker版となります。
Linux nmcliコマンドによるKVM&LXC/LXD with SR-IOVのInterface設定 - Metonymical Deflection
なお、LXC/LXDと異なる点として、Docker側Interfaceの永続化設定までは記載していません。*1
1.構成
1-1.環境
筐体 : ProLiant DL360p Gen8 System ROM : P71 01/22/2018 NIC : Intel X520-SR2 ens2f0 NIC : HP(Emulex) NC552SFP ens1f0-1 OS : CentOS7.6(1810) Kernel : 3.10.0-957.el7.x86_64 Installed Environment Groups : Server with GUI Add-Ons for Selected Environment : Virtualization Client, Virtualization Hypervisor, Virtualization Tools ovs : 2.11.0
1-2.全体構成
構成図上に(1)~(13)までの番号を割り振りました。
このうち、(3)~(11)までは、過去記事↓
CentOS7 ovs(Open vSwitch)のネットワーク設定方法 - Metonymical Deflection
と同様になるため割愛します。
スイッチ側の設定は以下となります。
interface Port-channel1 switchport trunk encapsulation dot1q switchport trunk allowed vlan 11,300-302 switchport mode trunk spanning-tree portfast trunk ! interface TenGigabitEthernet0/25 switchport trunk encapsulation dot1q switchport trunk allowed vlan 300-304 switchport mode trunk spanning-tree portfast trunk channel-group 1 mode active ! interface TenGigabitEthernet0/26 switchport trunk encapsulation dot1q switchport trunk allowed vlan 300-304 switchport mode trunk spanning-tree portfast trunk channel-group 1 mode active ! interface TenGigabitEthernet0/27 switchport trunk encapsulation dot1q switchport trunk allowed vlan 300-304 switchport mode trunk spanning-tree portfast trunk ! interface Vlan300 ip address 192.168.30.254 255.255.255.0 !
1-3.全体の流れ ~概要~
- Bridge作成:(1)
- Bonding:(2)
- Dockerコンテナをovsbr0にアタッチ:(12)
- DockerコンテナをSR-IOVのVFにアタッチ:(13)
1-4.全体の流れ ~コマンドのみ~
以下のコマンドを投入していきます。
やりたいことが既に決まっている方は、構成図とコマンドの内容を見るだけでもよいと思います。
事前準備1:OvSのインストール yum install -y https://repos.fedorapeople.org/repos/openstack/openstack-stein/rdo-release-stein-2.noarch.rpm && \ yum install -y openvswitch 事前準備2:Dockerのインストール curl -sSL https://get.docker.com/ | sh 事前準備3:pipeworkのインストール curl -sL https://raw.githubusercontent.com/jpetazzo/pipework/master/pipework > /usr/local/bin/pipework chmod +x /usr/local/bin/pipework 1.Bridge作成 (1) ovs-vsctl add-br ovsbr0 2.Bonding (2) ovs-vsctl add-bond ovsbr0 bond0 ens1f0 ens1f1 1&2の永続化設定 vi /etc/sysconfig/network-scripts/ifcfg-ovsbr0 DEVICE=ovsbr0 DEVICETYPE=ovs TYPE=OVSBridge BOOTPROTO=static NM_CONTROLLED=no ONBOOT=yes HOTPLUG=no vi /etc/sysconfig/network-scripts/ifcfg-ens1f0 DEVICE=ens1f0 NETBOOT=yes IPV6INIT=no BOOTPROTO=none NM_CONTROLLED=no ONBOOT=yes HOTPLUG=no vi /etc/sysconfig/network-scripts/ifcfg-ens1f1 DEVICE=ens1f1 NETBOOT=yes IPV6INIT=no BOOTPROTO=none NM_CONTROLLED=no ONBOOT=yes HOTPLUG=no [LACPの場合] vi /etc/sysconfig/network-scripts/ifcfg-bond0 DEVICE=bond0 ONBOOT=yes DEVICETYPE=ovs TYPE=OVSBond OVS_BRIDGE=ovsbr0 BOOTPROTO=none NM_CONTROLLED=no BOND_IFACES="ens1f0 ens1f1" OVS_OPTIONS="bond_mode=balance-tcp lacp=active other_config:lacp-time=fast vlan_mode=trunk trunks=300-304" HOTPLUG=no [固定LAGの場合] vi /etc/sysconfig/network-scripts/ifcfg-bond0 DEVICE=bond0 ONBOOT=yes DEVICETYPE=ovs TYPE=OVSBond OVS_BRIDGE=ovsbr0 BOOTPROTO=none NM_CONTROLLED=no BOND_IFACES="ens1f0 ens1f1" OVS_OPTIONS="bond_mode=balance-slb lacp=off vlan_mode=trunk trunks=300-304" HOTPLUG=no 3.Dockerコンテナをovsbr0にアタッチ (コンテナ起動) docker run -itd \ --privileged \ --network bridge \ --name dkc1 \ centos \ /sbin/init (12) pipework \ ovsbr0 \ -i eth1 \ dkc1 \ 192.168.30.103/24 \ @300 4.DockerコンテナをSR-IOVのVFにアタッチ (コンテナ起動) docker run -itd \ --privileged \ --network bridge \ --name dkc2 \ centos \ /sbin/init (13) pipework \ --direct-phys enp7s16 \ -i eth1 \ dkc2 \ 192.168.30.104/24 \ @300
2.事前準備
2-1.事前準備1:OvSのインストール
yum install -y https://repos.fedorapeople.org/repos/openstack/openstack-stein/rdo-release-stein-2.noarch.rpm && \ yum install -y openvswitch
RDOのSteinのリポジトリをインストールした後、最新のOvSをインストールしています。
2-3.事前準備3:pipeworkのインストール
curl -sL https://raw.githubusercontent.com/jpetazzo/pipework/master/pipework > /usr/local/bin/pipework chmod +x /usr/local/bin/pipework
pieworkをインストールしています。
OvSとSR-IOVの両方とも同じコマンド体系で設定できるため、pieworkにしました。
ovs-dockerによる方法は最後に記載します。
3.Bridge作成
説明無しでザックリ書きます。
詳細な説明は過去記事を参照してください。
(1)Bridgeの作成
出力結果 [root@c761 ~]# ovs-vsctl add-br ovsbr0 [root@c761 ~]# ovs-vsctl show b1d3d75a-2c4c-49e7-bc33-06e44a70dfe2 Bridge "ovsbr0" Port "ovsbr0" Interface "ovsbr0" type: internal ovs_version: "2.11.0"
4.Bonding
Bondを作成し、物理インターフェースをBondにアタッチします。
(2)Bond作成+物理アタッチ
出力結果 [root@c761 ~]# ovs-vsctl add-bond ovsbr0 bond0 ens1f0 ens1f1 [root@c761 ~]# ovs-vsctl show b1d3d75a-2c4c-49e7-bc33-06e44a70dfe2 Bridge "ovsbr0" Port "ovsbr0" Interface "ovsbr0" type: internal Port "bond0" Interface "ens1f1" Interface "ens1f0" ovs_version: "2.11.0"
5.永続化設定
コマンドを打っただけだと、ホストOSをRebootすると消えてしまうので永続化設定を行います。
vi /etc/sysconfig/network-scripts/ifcfg-ovsbr0 DEVICE=ovsbr0 DEVICETYPE=ovs TYPE=OVSBridge BOOTPROTO=static NM_CONTROLLED=no ONBOOT=yes HOTPLUG=no vi /etc/sysconfig/network-scripts/ifcfg-ens1f0 DEVICE=ens1f0 NETBOOT=yes IPV6INIT=no BOOTPROTO=none NM_CONTROLLED=no ONBOOT=yes HOTPLUG=no vi /etc/sysconfig/network-scripts/ifcfg-ens1f1 DEVICE=ens1f1 NETBOOT=yes IPV6INIT=no BOOTPROTO=none NM_CONTROLLED=no ONBOOT=yes HOTPLUG=no [LACPの場合] vi /etc/sysconfig/network-scripts/ifcfg-bond0 DEVICE=bond0 ONBOOT=yes DEVICETYPE=ovs TYPE=OVSBond OVS_BRIDGE=ovsbr0 BOOTPROTO=none NM_CONTROLLED=no BOND_IFACES="ens1f0 ens1f1" OVS_OPTIONS="bond_mode=balance-tcp lacp=active other_config:lacp-time=fast vlan_mode=trunk trunks=300-304" HOTPLUG=no [固定LAGの場合] vi /etc/sysconfig/network-scripts/ifcfg-bond0 DEVICE=bond0 ONBOOT=yes DEVICETYPE=ovs TYPE=OVSBond OVS_BRIDGE=ovsbr0 BOOTPROTO=none NM_CONTROLLED=no BOND_IFACES="ens1f0 ens1f1" OVS_OPTIONS="bond_mode=balance-slb lacp=off vlan_mode=trunk trunks=300-304" HOTPLUG=no 設定後はnetworkサービスをリスタート systemctl restart network
networkサービスのリスタートを行っても正常に動作しない場合、少々ダサいですがホストOSごと再起動してみてください。
6.Dockerコンテナをovsbr0にアタッチ
(コンテナ起動)
docker run -itd \
--privileged \
--network bridge \
--name dkc1 \
centos \
/sbin/init
(12)
pipework \
ovsbr0 \
-i eth1 \
dkc1 \
192.168.30.103/24 \
@300
以下のようにvethが追加されていればOKです。
[root@c763 ~]# ovs-vsctl show
23cda0ca-2d97-4c3f-bd00-d143a1f3a151
Manager "ptcp:6640"
is_connected: true
Bridge "ovsbr0"
Port "ovsbr0"
Interface "ovsbr0"
type: internal
Port "bond0"
trunks: [300, 301, 302, 303, 304]
Interface "ens1f0"
Interface "ens1f1"
Port "veth1pl25675"
tag: 300
Interface "veth1pl25675"
ovs_version: "2.11.0"
以下にpipeworkのSyntax出力を記載します。
[root@c763 ~]# pipework Syntax: pipework[-i containerinterface] [-l localinterfacename] [-a addressfamily] / [@default_gateway] [macaddr][@vlan] pipework [-i containerinterface] [-l localinterfacename] dhcp [macaddr][@vlan] pipework route pipework rule pipework tc pipework --wait [-i containerinterface]
上記Syntaxより、例えば以下のようにGWとMACを指定した設定も可能になります。
また「@300」を消せばUntagとなります。
(12')
pipework \
ovsbr0 \
-i eth1 \
dkc1 \
192.168.30.103/24@192.168.30.254 \
00:11:22:33:44:55@300
7.DockerコンテナをSR-IOVのVFにアタッチ
(コンテナ起動)
docker run -itd \
--privileged \
--network bridge \
--name dkc2 \
centos \
/sbin/init
(13)
pipework \
--direct-phys enp7s16 \
-i eth1 \
dkc2 \
192.168.30.104/24 \
@300
以下のようにコンテナとVFのMACアドレスが一致していればOKです。
[root@c763 ~]# ip link show enp7s16 12: enp7s16:mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000 link/ether 1a:6a:a5:b0:49:59 brd ff:ff:ff:ff:ff:ff [root@c763 ~]# [root@c763 ~]# docker container exec -it dkc2 ip link show eth1 36: eth1@if12: mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000 link/ether 1a:6a:a5:b0:49:59 brd ff:ff:ff:ff:ff:ff link-netnsid 0
ポイントはオプション「--direct-phys enp7s16」にてVFを掴ませている点が、OvSとは異なります。
8.補足1:ovs-dockerによるOvSへのアタッチ
ovs-dockerのwget&実行権限付与 wget -O /usr/local/bin/ovs-docker \ https://raw.githubusercontent.com/openvswitch/ovs/master/utilities/ovs-docker chmod 755 /usr/local/bin/ovs-docker (コンテナ起動) docker run -itd \ --privileged \ --network bridge \ --name dkc3 \ centos \ /sbin/init (12)-1:OvSへのアタッチとIP設定 ovs-docker add-port ovsbr0 eth1 dkc3 \ --ipaddress="192.168.30.105/24" (12)-2:Vlanの設定 ovs-docker set-vlan ovsbr0 eth1 dkc3 300
以下のように出力されていればOKです。
[root@c763 ~]# ovs-vsctl show
23cda0ca-2d97-4c3f-bd00-d143a1f3a151
Manager "ptcp:6640"
Bridge "ovsbr0"
Port "ovsbr0"
Interface "ovsbr0"
type: internal
Port "15d5c9395dab4_l"
tag: 300
Interface "15d5c9395dab4_l"
Port "bond0"
trunks: [300, 301, 302, 303, 304]
Interface "ens1f0"
Interface "ens1f1"
ovs_version: "2.11.0"
一手間増えますが、SR-IOVのVFへのアタッチができないことやovs-dockerもpipeworkもdocker inspectに載ってこないことを考えると、pipeworkで良いのかなと思いました。
9.補足2:Open_vMonitor
補足というか、おまけでOpen_vMonitorをご紹介させてください。
ovs-vsctl set-manager ptcp:6640 docker run -d -p 3000:3000 --name ovsgui01 -h ovsgui01 plvisiondevs/open_vmonitor
ホストOSのIP(192.168.11.213)にアクセス
http://192.168.11.213:3000/enter username:admin password:admin Enter OVSDB IP:192.168.11.213
以下の画面で各ポートの情報が確認できます。
多数のコンテナを起動した際は見やすいのかなと思います。
以上です。
10.最後に
以下のサイトを参考にさせて頂きました。
第35回 Open vSwitchで作るDockerのネットワーク(OVSで構築する編) (1/6) - ITmedia エンタープライズ
SR-IOV in Docker containers - Anirban Mukherjee - Medium
永続化設定という課題はありますが、LXC/LXDとはそもそもの用途が異なるため、まぁ、こんなもんかなという感じです。
以下のサイトにLXC/LXDとDockerの比較表があるので参考までに。
Dockerもいいけど、LXCも使おうぜ - Qiita
次のステップとして、DPDKを実装したいと考えていますが、ovnやconsulを使用した構成となるため、CentOS8になってからにしようかなと思っています。
とはいえ、ovnを使い始めるとなると、OpenStackやokdの方がいいかなと少し悩んでいます。
*1:作りこめばできそうですが、LXC/LXDとDockerの用途の違いかなと思っているので、あまり深入りはしませんでした。