CentOS8 小ネタ集その3:Nested KVMの設定
CentOS8におけるNested KVMの設定です。
1.Nestedの設定
sed -i -e "s/#options kvm_intel nested=1/options kvm_intel nested=1/g" /etc/modprobe.d/kvm.conf
上記はIntelCPUの場合の設定です。
AMDの場合は、/etc/modprobe.d/kvm.confを直接開けば設定可能です。
2.仮想マシン側の設定
virsh edit vm-name <cpu mode='custom' match='exact'> を <cpu mode='host-passthrough'> に変更して保存。
以上です。
3.最後に
大した内容ではありませんが、CentOS7からほんの少しだけ変更されていたため、知っておくと何かと便利なので記載しました。
小ネタ集その1~3以外にも、SELinuxやchrony、HugePage、run-level変更など小ネタはあるのですが、CentOS7からの変更はないので、あえて記載するほどでもないかなと思っています。
ちなみに、CentOS8ではnmcliコマンドに変更はないため、NW系コマンドはnmcliに統一してしまった方が効率的だと思います。
CentOS8 小ネタ集その2:Cockpit machineのインストール
Cockpit上で仮想マシンを管理できるようになります。
Defaultではcockpit-machinesがインストールされていないようなので、インストールした後にCockpitのサービス起動設定を実施するだけです。
1.インストール&自動起動設定
dnf -y install cockpit-machines && \ systemctl enable --now cockpit.socket && \ systemctl start --now cockpit.socket
2.Cockpitへのログイン
ブラウザを起動した後、CentOS8上のCockpitにアクセスします。
https://CentOS8のIP:9090/
ブラウザに以下の画面が表示されますので、ssh接続時と同様のCredential(Username/Passwd)でログインしてください。
3.最後に
Virt-Managerほど柔軟に設定できないようなので、VNC serverなどと併用するのがよいかと思います。
しかし、起動中の仮想マシンのステータスが見たいときなどは重宝すると思います。
CentOS8 小ネタ集その1:VNC serverの設定
CentOS8におけるtigervnc-serverの設定方法を記載します。
2021/04/14追記
CentOS8.3における設定方法を追記しました。6.5.CentOS8.3の設定方法を参照してください。
小ネタ集ってほどでもないですが、サクサクっと記載します。
1.インストールと設定ファイルコピー
dnf -y install tigervnc-server && \ cp -a /usr/lib/systemd/user/vncserver@.service /etc/systemd/system/vncserver@:1.service
2.設定ファイルの編集
青=追記、緑=コメントアウト
vi /etc/systemd/system/vncserver@:1.service [Service] Type=forking PIDFile=/root/.vnc/%H%i.pid ExecStartPre=/bin/sh -c '/usr/bin/vncserver -kill %i > /dev/null 2>&1 || :' #ExecStart=/usr/bin/vncserver %i ExecStart=/usr/sbin/runuser -l root -c "/usr/bin/vncserver %i" ExecStop=/usr/bin/vncserver -kill %i
sedでサクッと設定したい場合は以下の通り。
sed -i -e '/^Type/a PIDFile=/root/.vnc/%H%i.pid' /etc/systemd/system/vncserver@:1.service sed -i -e 's/ExecStart=/#ExecStart=/g' /etc/systemd/system/vncserver@:1.service sed -i -e '/^#ExecStart=/a ExecStart=/usr/sbin/runuser -l root -c "/usr/bin/vncserver %i"' /etc/systemd/system/vncserver@:1.service
3.Passwd設定と一時起動&停止
vncpasswd vncserver :1 vncserver -kill :1
4.ロックファイルの削除
rm /tmp/.X11-unix/X ⇒Tabで/Xのあとを補完すると、以下のような数字が表示される rm /tmp/.X11-unix/X1024 上記のようにXのあとが1024であれば、合わせて以下のファイルも削除しておく。 rm /tmp/.X1024-lock
5.Service自動起動&起動
systemctl daemon-reload systemctl enable vncserver@:1.service systemctl start vncserver@:1.service
6.解像度変更
vi /usr/bin/vncserver #$geometry = "1024x768"; $geometry = "1600x1200";
sedでサクッと設定したい場合は以下の通り。
sed -i -e '/$geometry/s/1024x768/1600x1200/g' /usr/bin/vncserver
6.5.CentOS8.3の設定方法
CentOS8.3におけるVNC Serverの設定方法が少し変わっています。*1
dnf -y install tigervnc-server && \ echo "session=gnome" >> /etc/tigervnc/vncserver-config-defaults && \ echo ":1=root" >> /etc/tigervnc/vncserver.users && \ mkdir /root/.vnc && \ echo "geometry=1600x1200" >> /root/.vnc/config && \ cp -p /usr/lib/systemd/system/vncserver@.service /etc/systemd/system/vncserver@:1.service && \ vncpasswd
上記コマンドにてパスワード入力後、以下のようにサービスの自動起動設定を行ってください。
systemctl daemon-reload systemctl enable vncserver@:1.service systemctl start vncserver@:1.service
以上です。
CentOS8 kickstartによるインストール
kickstartによるインストールのサンプルファイルをいくつかピックアップしてみたいと思います。
サンプルとしては以下の通り。*1
- KVM(CentOS7.6)上にCentOS8をServerGUIでインストール
- DL360G8上にCentOS8をServerGUIでインストール
- KVM(CentOS7.6)上にCentOS8をminimalでインストール
2019/10/14追記*2
これ以外にも応用はいくらでもできると思います。
1.KVM(CentOS7.6)上にCentOS8をServerGUIでインストール
1-1.kickstartファイルの作成
vi c80gui.ks # Network information network --bootproto=static --device=eth0 --onboot=on --ip=192.168.0.100 --gateway=192.168.0.1 --netmask=255.255.255.0 --nameserver=192.168.0.1 --noipv6 network --bootproto=dhcp --device=eth1 --onboot=off --noipv6 network --hostname=c80mas.md.jp # Root password rootpw --plaintext TESTPASSWD user --groups=wheel --name=rsadmin --password=TESTPASSWD --plaintext # System services services --disabled="bolt,colord,cups,fwupd,ModemManager,packagekit,smartd,sssd-kcm,sssd,wpa_supplicant" --enabled="chronyd" # Firewall configuration firewall --disabled # SELinux configuration selinux --disabled # Disk partitioning information part /boot --fstype="ext4" --ondisk=vda --size=1024 part pv.1 --fstype="lvmpv" --ondisk=vda --size=1024 --grow volgroup cl --pesize=4096 pv.1 logvol swap --fstype="swap" --recommended --name=swap --vgname=cl logvol / --fstype="xfs" --grow --size=1024 --name=root --vgname=cl cmdline install eula --agreed # Use CDROM installation media cdrom # Run the Setup Agent on first boot firstboot --enable # Keyboard layouts keyboard --vckeymap=us --xlayouts='us' # System language lang en_US.UTF-8 # System timezone timezone Asia/Tokyo --isUtc --nontp # X Window System configuration information xconfig --startxonboot zerombr bootloader --location=mbr --boot-drive=vda --append="crashkernel=auto biosdevname=0 net.ifnames=0 console=tty0 console=ttyS0,115200n8" clearpart --none --initlabel # repo repo --name="AppStream" --baseurl=file:///run/install/repo/AppStream ignoredisk --only-use=vda %packages @^graphical-server-environment @container-management @development @virtualization-client @virtualization-hypervisor @virtualization-tools kexec-tools %end %post dnf -y install cockpit-machines systemctl enable --now cockpit.socket systemctl start --now cockpit.socket dnf -y install epel-release rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org dnf -y install https://www.elrepo.org/elrepo-release-8.0-2.el8.elrepo.noarch.rpm sed -i -e "s/#options kvm_intel nested=1/options kvm_intel nested=1/g" /etc/modprobe.d/kvm.conf sed -i -e '/^pool/a server 192.168.0.1 iburst' /etc/chrony.conf sed -i -e 's/^pool/#pool/g' /etc/chrony.conf dnf -y install tigervnc-server cp -a /usr/lib/systemd/user/vncserver@.service /etc/systemd/system/vncserver@:1.service sed -i -e '/^Type/a PIDFile=/root/.vnc/%H%i.pid' /etc/systemd/system/vncserver@:1.service sed -i -e 's/ExecStart=/#ExecStart=/g' /etc/systemd/system/vncserver@:1.service sed -i -e '/^#ExecStart=/a ExecStart=/usr/sbin/runuser -l root -c "/usr/bin/vncserver %i"' /etc/systemd/system/vncserver@:1.service sed -i -e '/$geometry/s/1024x768/1600x1200/g' /usr/bin/vncserver systemctl set-default multi-user.target #dnf update -y %end reboot --eject
<補足1>
- NW, Credential, Service, Diskなど環境によって変更する頻度が多いパラメータを上位に記載しています。
- Serviceのうちdisabledは、私が不要ものを記載しているため、素の状態で使用したい場合はコメントアウトしてください。
- eulaが効かず、OSインストール&Reboot後に手動でContinueしないとダメな場合があります。
- %packagesのうち、"@^graphical-server-environment"以下は、私が必要なものを記載しているため、素の状態で使用したい場合はコメントアウトしてください。
- %postには、私が必要なものを記載しているため、素の状態で使用したい場合はコメントアウトしてください。
1-3.virt-installの実行
virt-install --connect=qemu:///system \ --name=c80mas \ --disk /var/lib/libvirt/images/c80mas.qcow2,format=qcow2,bus=virtio \ --network bridge=br0,model=virtio \ --network bridge=br0,model=virtio \ --initrd-inject=./c80gui.ks \ --extra-args='ks=file:/c80gui.ks biosdevname=0 net.ifnames=0 console=tty0 console=ttyS0,115200n8' \ --vcpus=2 \ --ram=2048 \ --accelerate \ --hvm \ --location='/var/lib/libvirt/images/CentOS-8-x86_64-1905-dvd1.iso' \ --nographics \ --os-type=linux \ --os-variant=centos7.0 \ --arch=x86_64
<補足2>
"--network"にPortGroupを使用したい場合は、過去記事を参照してください。
2.DL360G8上にCentOS8をServerGUIでインストール
2-1.kickstartファイルの作成
# Network information network --bootproto=static --device=eno1 --ip=192.168.0.240 --netmask=255.255.255.0 --gateway=192.168.0.1 --nameserver=192.168.0.1 --noipv6 --activate network --hostname=c80mas.md.jp #network --bootproto=dhcp --device=eno2 --onboot=off --ipv6=auto #network --bootproto=dhcp --device=eno3 --onboot=off --ipv6=auto #network --bootproto=dhcp --device=eno4 --onboot=off --ipv6=auto #network --bootproto=dhcp --device=ens1f0 --onboot=off --ipv6=auto #network --bootproto=dhcp --device=ens1f1 --onboot=off --ipv6=auto # Root password rootpw --plaintext TESTPASSWD user --groups=wheel --name=rsadmin --password=TESTPASSWD # System services services --disabled="bolt,colord,cups,fwupd,ModemManager,packagekit,smartd,sssd-kcm,sssd,wpa_supplicant" --enabled="chronyd" # Firewall configuration firewall --disabled # SELinux configuration selinux --disabled # System bootloader configuration bootloader --append=" crashkernel=auto" --location=mbr --boot-drive=sda # Partition clearing information clearpart --all --initlabel --drives=sda # Disk partitioning information part /boot --fstype="xfs" --ondisk=sda --size=1024 part pv.1 --fstype="lvmpv" --ondisk=sda --size=1 --grow volgroup cl --pesize=4096 pv.1 logvol / --fstype="xfs" --name=root --vgname=cl --size=1 --grow logvol swap --fstype="swap" --name=swap --vgname=cl --recommended # X Window System configuration information xconfig --startxonboot # License agreement eula --agreed # Use CDROM installation media cdrom # Use graphical install #graphical text # Run the Setup Agent on first boot firstboot --enable # Keyboard layouts keyboard --vckeymap=us --xlayouts='us' # System language lang en_US.UTF-8 # System timezone timezone Asia/Tokyo --isUtc --nontp # repo repo --name="AppStream" --baseurl=file:///run/install/repo/AppStream ignoredisk --only-use=sda %packages @^graphical-server-environment @container-management @development @virtualization-client @virtualization-hypervisor @virtualization-tools kexec-tools %end %addon com_redhat_kdump --enable --reserve-mb=auto %end %anaconda pwpolicy root --minlen=6 --minquality=1 --notstrict --nochanges --notempty pwpolicy user --minlen=6 --minquality=1 --notstrict --nochanges --emptyok pwpolicy luks --minlen=6 --minquality=1 --notstrict --nochanges --notempty %end # Reboot after installation reboot --eject
<補足3>
- 基本的には補足2に記載した内容と同様です。
- "reboot --eject"のうち、ejectオプションが効かないときがあるようなので、手動でejectしてください。
あとの操作方法は過去記事と同様です。
<補足4>
以下の起動オプションを入力する際、DL360G8pとDL360G8eで挙動が少し異なりました。
inst.ks=hd:sdb:/ks.cfg
DL360G8pの場合
inst.ks=hd:sdb:/ks.cfg
DL360G8eの場合
inst.ks=hd:sda:/ks.cfg
上記に伴いDL360G8eの場合にはkickstartファイルにおいても、"sda"を"sdb"に置換してください。
3.KVM(CentOS7.6)上にCentOS8をminimalでインストール
3-1.kickstartファイルの作成
さほど検証していないため、参考程度として記載します。
vi c80cui.ks cmdline install eula --agreed # Use CDROM installation media cdrom # Run the Setup Agent on first boot firstboot --enable # Keyboard layouts keyboard --vckeymap=us --xlayouts='us' # System language lang en_US.UTF-8 # Network information network --bootproto=static --device=eth0 --onboot=on --ip=192.168.0.100 --gateway=192.168.0.1 --netmask=255.255.255.0 --nameserver=192.168.0.1 --noipv6 network --bootproto=dhcp --device=eth1 --onboot=off --noipv6 network --hostname=c80mas.md.jp # System services #services --enabled=chronyd # Firewall configuration firewall --disabled # SELinux configuration selinux --disabled # repo repo --name="AppStream" --baseurl=file:///run/install/repo/AppStream ignoredisk --only-use=vda zerombr bootloader --location=mbr --boot-drive=vda --append="crashkernel=auto biosdevname=0 net.ifnames=0 console=tty0 console=ttyS0,115200n8" clearpart --none --initlabel # Disk partitioning information part /boot --fstype="ext4" --ondisk=vda --size=1024 part pv.1 --fstype="lvmpv" --ondisk=vda --size=1024 --grow volgroup cl --pesize=4096 pv.1 logvol swap --fstype="swap" --recommended --name=swap --vgname=cl logvol / --fstype="xfs" --grow --size=1024 --name=root --vgname=cl # Root password rootpw --plaintext TESTPASSWD # System timezone timezone Asia/Tokyo --isUtc --nontp user --groups=wheel --name=rsadmin --password=TESTPASSWD --plaintext # X Window System configuration information xconfig --startxonboot %packages @^minimal-environment kexec-tools %end %post %end reboot --eject
3-3.virt-installの実行
virt-install --connect=qemu:///system \ --name=c80mas \ --disk /var/lib/libvirt/images/c80mas.qcow2,format=qcow2,bus=virtio \ --network bridge=br0,model=virtio \ --network bridge=br0,model=virtio \ --initrd-inject=./c80cui.ks \ --extra-args='ks=file:/c80cui.ks biosdevname=0 net.ifnames=0 console=tty0 console=ttyS0,115200n8' \ --vcpus=2 \ --ram=2048 \ --accelerate \ --hvm \ --location='/var/lib/libvirt/images/CentOS-8-x86_64-1905-dvd1.iso' \ --nographics \ --os-type=linux \ --os-variant=centos7.0 \ --arch=x86_64
以下、2019/10/14に追記しました。
NWインターフェース名を変更していますが、それに伴い「--append」や「--extra-args」の設定も変更しています。
4.KVM(CentOS8.0)上にCentOS8をServerGUIでインストール
4-1.kickstartファイルの作成
vi c80gui.ks # Network information network --bootproto=static --device=enp1s0 --onboot=on --ip=192.168.0.100 --gateway=192.168.0.1 --netmask=255.255.255.0 --nameserver=192.168.0.1 --noipv6 network --bootproto=dhcp --device=enp2s0 --onboot=off --noipv6 network --hostname=c80mas.md.jp # Root password rootpw --plaintext TESTPASSWD user --groups=wheel --name=rsadmin --password=TESTPASSWD --plaintext # System services services --disabled="bolt,colord,cups,fwupd,ModemManager,packagekit,smartd,sssd-kcm,sssd,wpa_supplicant" --enabled="chronyd" # Firewall configuration firewall --disabled # SELinux configuration selinux --disabled # Disk partitioning information part /boot --fstype="ext4" --ondisk=vda --size=1024 part pv.1 --fstype="lvmpv" --ondisk=vda --size=1024 --grow volgroup cl --pesize=4096 pv.1 logvol swap --fstype="swap" --recommended --name=swap --vgname=cl logvol / --fstype="xfs" --grow --size=1024 --name=root --vgname=cl cmdline install eula --agreed # Use CDROM installation media cdrom # Run the Setup Agent on first boot firstboot --enable # Keyboard layouts keyboard --vckeymap=us --xlayouts='us' # System language lang en_US.UTF-8 # System timezone timezone Asia/Tokyo --isUtc --nontp # X Window System configuration information xconfig --startxonboot zerombr bootloader --location=mbr --boot-drive=vda --append="crashkernel=auto console=tty0 console=ttyS0,115200n8" clearpart --none --initlabel # repo repo --name="AppStream" --baseurl=file:///run/install/repo/AppStream ignoredisk --only-use=vda %packages @^graphical-server-environment @container-management @development @virtualization-client @virtualization-hypervisor @virtualization-tools kexec-tools %end %post dnf -y install cockpit-machines systemctl enable --now cockpit.socket systemctl start --now cockpit.socket dnf -y install epel-release rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org dnf -y install https://www.elrepo.org/elrepo-release-8.0-2.el8.elrepo.noarch.rpm sed -i -e "s/#options kvm_intel nested=1/options kvm_intel nested=1/g" /etc/modprobe.d/kvm.conf sed -i -e '/^pool/a server 192.168.0.1 iburst' /etc/chrony.conf sed -i -e 's/^pool/#pool/g' /etc/chrony.conf dnf -y install tigervnc-server cp -a /usr/lib/systemd/user/vncserver@.service /etc/systemd/system/vncserver@:1.service sed -i -e '/^Type/a PIDFile=/root/.vnc/%H%i.pid' /etc/systemd/system/vncserver@:1.service sed -i -e 's/ExecStart=/#ExecStart=/g' /etc/systemd/system/vncserver@:1.service sed -i -e '/^#ExecStart=/a ExecStart=/usr/sbin/runuser -l root -c "/usr/bin/vncserver %i"' /etc/systemd/system/vncserver@:1.service sed -i -e '/$geometry/s/1024x768/1600x1200/g' /usr/bin/vncserver systemctl set-default multi-user.target #dnf update -y %end reboot --eject
4-3.virt-installの実行
virt-install --connect=qemu:///system \ --name=c80mas \ --disk /var/lib/libvirt/images/c80mas.qcow2,format=qcow2,bus=virtio \ --network bridge=br0,model=virtio \ --network bridge=br0,model=virtio \ --initrd-inject=./c80gui.ks \ --extra-args='ks=file:/c80gui.ks console=tty0 console=ttyS0,115200n8' \ --vcpus=2 \ --ram=2048 \ --accelerate \ --hvm \ --location='/var/lib/libvirt/images/CentOS-8-x86_64-1905-dvd1.iso' \ --nographics \ --os-type=linux \ --os-variant=rhel8.0 \ --arch=x86_64
5.KVM(CentOS8.0)上にCentOS8をminimalでインストール
5-1.kickstartファイルの作成
vi c80cui.ks # Network information network --bootproto=static --device=enp1s0 --onboot=on --ip=192.168.0.100 --gateway=192.168.0.1 --netmask=255.255.255.0 --nameserver=192.168.0.1 --noipv6 network --bootproto=dhcp --device=enp2s0 --onboot=off --noipv6 network --hostname=c80mas.md.jp # Root password rootpw --plaintext TESTPASSWD user --groups=wheel --name=rsadmin --password=TESTPASSWD --plaintext # Firewall configuration firewall --disabled # SELinux configuration selinux --disabled # Disk partitioning information part /boot --fstype="ext4" --ondisk=vda --size=1024 part pv.1 --fstype="lvmpv" --ondisk=vda --size=1024 --grow volgroup cl --pesize=4096 pv.1 logvol swap --fstype="swap" --recommended --name=swap --vgname=cl logvol / --fstype="xfs" --grow --size=1024 --name=root --vgname=cl cmdline install eula --agreed # Use CDROM installation media cdrom # Run the Setup Agent on first boot firstboot --enable # Keyboard layouts keyboard --vckeymap=us --xlayouts='us' # System language lang en_US.UTF-8 # System timezone timezone Asia/Tokyo --isUtc --nontp # X Window System configuration information xconfig --startxonboot zerombr bootloader --location=mbr --boot-drive=vda --append="crashkernel=auto console=tty0 console=ttyS0,115200n8" clearpart --none --initlabel # repo repo --name="AppStream" --baseurl=file:///run/install/repo/AppStream ignoredisk --only-use=vda %packages @^minimal-environment kexec-tools %end %post %end reboot --eject
5-3.virt-installの実行
virt-install --connect=qemu:///system \ --name=c80mas \ --disk /var/lib/libvirt/images/c80mas.qcow2,format=qcow2,bus=virtio \ --network bridge=br0,model=virtio \ --network bridge=br0,model=virtio \ --initrd-inject=./c80cui.ks \ --extra-args='ks=file:/c80cui.ks console=tty0 console=ttyS0,115200n8' \ --vcpus=2 \ --ram=2048 \ --accelerate \ --hvm \ --location='/var/lib/libvirt/images/CentOS-8-x86_64-1905-dvd1.iso' \ --nographics \ --os-type=linux \ --os-variant=rhel8.0 \ --arch=x86_64
以上です。
10.最後に
以下のサイトを参考にさせて頂きました。
virt-install で KVM に CentOS8 を無人インストール - Qiita
/root/anaconda-ks.cfgを参考にすれば色々試せると思いますので、自分なりにやってみることをおススメします。
CentOS7 ovs(Open vSwitch)+ovnのネットワーク設定方法
ovs+ovnのoverlayネットワークを構築し、KVMの仮想マシンとDockerコンテナのトラフィックをBridgeで外部ネットワークに流して使用する場合の設定方法を記載したいと思います。
これにより、仮想マシンとコンテナと外部ネットワーク機器が同一VLANで通信可能になります。
ただ、実用性の観点で冗長化できないため、あまり使えないかもしれませんが、ovnの仕組みを理解する上では活用できるかと思います。
1.環境
1-1.VMWare
筐体 : 自作PC(Win10pro) CPU : Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz VMWare : VMware(R) Workstation 15 Pro 15.1.0 build-13591040 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&ovn : 2.11.1
ベアメタル環境でも同様に設定可能です。
1-2.全体構成その1:Underlay
1-3.全体構成その2:Overlay
補足
「'」が付いている箇所は、主に「'」が付いていない箇所を設定すると自動設定されます。*1
1-4 .全体の流れ ~概要~
- ovs+ovnのビルドとインストール
- ovs+ovnの設定
- docker+consulのクラスタ設定
- (1)~(7)の設定
1-5 .全体の流れ ~コマンドのみ~
以下のコマンドを投入していきます。
やりたいことが既に決まっている方は、構成図とコマンドの内容を見るだけでもよいと思います。
しかし、ovs+ovnやdocker+consulの設定もそこそこボリュームがあるため、(1)~(7)の辿り着くまでが少々しんどいかもしれません。。
(1) docker network create -d openvswitch --subnet=192.168.31.0/24 ovs (2) vi /etc/sysconfig/network-scripts/ifcfg-br-ext DEVICE=br-ext DEVICETYPE=ovs TYPE=OVSBridge BOOTPROTO=static NM_CONTROLLED=no ONBOOT=yes HOTPLUG=no vi /etc/sysconfig/network-scripts/ifcfg-ens36 DEVICE=ens36 ONBOOT=yes DEVICETYPE=ovs TYPE=OVSPort OVS_BRIDGE=br-ext BOOTPROTO=none NM_CONTROLLED=no OVS_OPTIONS="vlan_mode=trunk trunks=300-301" HOTPLUG=no (3) ovn-sbctl --db=tcp:192.168.30.101:6642 show ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet301:br-ext export SW_NAME=$(ovn-nbctl --db=tcp:192.168.30.101:6641 ls-list | awk '{print $2}' | sed s/\(//g | sed s/\)//g) ovn-nbctl --db=tcp:192.168.30.101:6641 lsp-add $SW_NAME l2gwport "" 301 ovn-nbctl --db=tcp:192.168.30.101:6641 lsp-set-addresses l2gwport unknown ovn-nbctl --db=tcp:192.168.30.101:6641 lsp-set-type l2gwport l2gateway ovn-nbctl --db=tcp:192.168.30.101:6641 lsp-set-options l2gwport network_name=physnet301 l2gateway-chassis=28928b40-900b-4f48-b4ed-8d9d2f1082fd (4) export SW_NAME=$(ovn-nbctl --db=tcp:192.168.30.101:6641 ls-list | awk '{print $2}' | sed s/\(//g | sed s/\)//g) export IFACE_ID=$(ovs-vsctl get interface vnet1 external_ids:iface-id | sed s/\"//g) export MAC_ADDR=$(ovs-vsctl get interface vnet1 external_ids:attached-mac | sed s/\"//g) ovn-nbctl --db=tcp:192.168.30.101:6641 lsp-add $SW_NAME $IFACE_ID ovn-nbctl --db=tcp:192.168.30.101:6641 lsp-set-addresses $IFACE_ID $MAC_ADDR ovn-nbctl --db=tcp:192.168.30.101:6641 show (5) export SW_NAME=$(ovn-nbctl --db=tcp:192.168.30.101:6641 ls-list | awk '{print $2}' | sed s/\(//g | sed s/\)//g) export IFACE_ID=$(ovs-vsctl get interface vnet1 external_ids:iface-id | sed s/\"//g) export MAC_ADDR=$(ovs-vsctl get interface vnet1 external_ids:attached-mac | sed s/\"//g) ovn-nbctl --db=tcp:192.168.30.101:6641 lsp-add $SW_NAME $IFACE_ID ovn-nbctl --db=tcp:192.168.30.101:6641 lsp-set-addresses $IFACE_ID $MAC_ADDR ovn-nbctl --db=tcp:192.168.30.101:6641 show (6) docker run -itd \ --privileged \ --network ovs \ --name c2 \ c76 \ /sbin/init (7) docker run -itd \ --privileged \ --network ovs \ --name c3 \ c76 \ /sbin/init
2.ovs+ovnのビルドとインストール
ControllerNode(c76ovn01)にてビルドとインストールを実施します。またDockerもインストールしてしまいます。
2-1.ControllerNode
yum -y install @'Development Tools' rpm-build yum-utils wget libpcap-devel numactl-devel mkdir -p /root/rpmbuild/SOURCES cd /root/rpmbuild/SOURCES wget https://www.openvswitch.org/releases/openvswitch-2.11.1.tar.gz tar zxvf openvswitch-2.11.1.tar.gz sed -e 's/@VERSION@/0.0.1/' openvswitch-2.11.1/rhel/openvswitch-fedora.spec.in > ovs.spec yum-builddep -y ovs.spec && \ cd openvswitch-2.11.1 && \ ./boot.sh && \ ./configure && \ make rpm-fedora RPMBUILD_OPT="--without check" && \ make rpm-fedora-ovn RPMBUILD_OPT="--without check" cd /root/rpmbuild/SOURCES/openvswitch-2.11.1/rpm/rpmbuild/RPMS/noarch yum -y localinstall python-openvswitch-2.11.1-1.el7.noarch.rpm cd /root/rpmbuild/SOURCES/openvswitch-2.11.1/rpm/rpmbuild/RPMS/x86_64 yum -y localinstall \ openvswitch-2.11.1-1.el7.x86_64.rpm \ ovn-2.11.1-1.el7.x86_64.rpm \ ovn-common-2.11.1-1.el7.x86_64.rpm \ ovn-central-2.11.1-1.el7.x86_64.rpm \ ovn-host-2.11.1-1.el7.x86_64.rpm \ ovn-docker-2.11.1-1.el7.x86_64.rpm curl -sSL https://get.docker.com/ | sh systemctl start openvswitch systemctl enable openvswitch systemctl start ovn-northd systemctl enable ovn-northd systemctl start docker systemctl enable docker
2-2.ComputeNode
ComputeNode(c76ovn02&c76ovn03)にてビルドとインストールを実施します。違いは、ovn-central-2.11.1-1.el7.x86_64.rpmが無いだけです。
yum -y install @'Development Tools' rpm-build yum-utils wget libpcap-devel numactl-devel mkdir -p /root/rpmbuild/SOURCES cd /root/rpmbuild/SOURCES wget https://www.openvswitch.org/releases/openvswitch-2.11.1.tar.gz tar zxvf openvswitch-2.11.1.tar.gz sed -e 's/@VERSION@/0.0.1/' openvswitch-2.11.1/rhel/openvswitch-fedora.spec.in > ovs.spec yum-builddep -y ovs.spec && \ cd openvswitch-2.11.1 && \ ./boot.sh && \ ./configure && \ make rpm-fedora RPMBUILD_OPT="--without check" && \ make rpm-fedora-ovn RPMBUILD_OPT="--without check" cd /root/rpmbuild/SOURCES/openvswitch-2.11.1/rpm/rpmbuild/RPMS/noarch yum -y localinstall python-openvswitch-2.11.1-1.el7.noarch.rpm cd /root/rpmbuild/SOURCES/openvswitch-2.11.1/rpm/rpmbuild/RPMS/x86_64 yum -y localinstall \ openvswitch-2.11.1-1.el7.x86_64.rpm \ ovn-2.11.1-1.el7.x86_64.rpm \ ovn-common-2.11.1-1.el7.x86_64.rpm \ ovn-host-2.11.1-1.el7.x86_64.rpm \ ovn-docker-2.11.1-1.el7.x86_64.rpm curl -sSL https://get.docker.com/ | sh systemctl start openvswitch systemctl enable openvswitch systemctl start ovn-controller systemctl enable ovn-controller systemctl start docker systemctl enable docker
3.ovs+ovnの設定
3-1.Overlay用のInteface設定
c76ovn01 nmcli con add type ethernet autoconnect yes con-name ens37 ifname ens37 nmcli con mod ens37 ipv4.method manual ipv4.addresses 192.168.30.101/24 nmcli con up ens37 c76ovn02 nmcli con add type ethernet autoconnect yes con-name ens37 ifname ens37 nmcli con mod ens37 ipv4.method manual ipv4.addresses 192.168.30.102/24 nmcli con up ens37 c76ovn03 nmcli con add type ethernet autoconnect yes con-name ens37 ifname ens37 nmcli con mod ens37 ipv4.method manual ipv4.addresses 192.168.30.103/24 nmcli con up ens37
3-2.ovnの設定
c76ovn01 ovn-nbctl set-connection ptcp:6641 ovn-sbctl set-connection ptcp:6642 ovs-appctl -t ovsdb-server ovsdb-server/add-remote ptcp:6640
3-3.ovsの設定
c76ovn02 export CENTRAL_IP=192.168.30.101 export ENCAP_TYPE=geneve export LOCAL_IP=192.168.30.102 ovs-vsctl set Open_vSwitch . external_ids:ovn-remote="tcp:${CENTRAL_IP}:6642" ovs-vsctl set Open_vSwitch . external_ids:ovn-nb="tcp:${CENTRAL_IP}:6641" ovs-vsctl set Open_vSwitch . external_ids:ovn-encap-ip=${LOCAL_IP} ovs-vsctl set Open_vSwitch . external_ids:ovn-encap-type="${ENCAP_TYPE}" systemctl restart ovn-controller c76ovn03 export CENTRAL_IP=192.168.30.101 export ENCAP_TYPE=geneve export LOCAL_IP=192.168.30.103 ovs-vsctl set Open_vSwitch . external_ids:ovn-remote="tcp:${CENTRAL_IP}:6642" ovs-vsctl set Open_vSwitch . external_ids:ovn-nb="tcp:${CENTRAL_IP}:6641" ovs-vsctl set Open_vSwitch . external_ids:ovn-encap-ip=${LOCAL_IP} ovs-vsctl set Open_vSwitch . external_ids:ovn-encap-type="${ENCAP_TYPE}" systemctl restart ovn-controller
3-4.設定確認
102と103が101とESTABとなっていればOKです。
c76ovn01 ss -ant |grep 6642 出力例 [root@c76ovn01 ~]# ss -ant |grep 6642 LISTEN 0 10 *:6642 *:* ESTAB 0 0 192.168.30.101:6642 192.168.30.102:44102 ESTAB 0 0 192.168.30.101:6642 192.168.30.103:34252
上記がOKな場合、br-intが自動生成され、GeneveによるOverlayのトンネル設定も自動で実施されます。また、ovs上では以下のようなステータスとなっていればOKです。
c76ovn02&03 ovs-vsctl show 出力例 [root@c76ovn02 ~]# ovs-vsctl show e2d97138-977a-4579-bc6a-dfb43d8769cb Bridge br-int fail_mode: secure Port br-int Interface br-int type: internal Port "ovn-925250-0" Interface "ovn-925250-0" type: geneve options: {csum="true", key=flow, remote_ip="192.168.30.103"} ovs_version: "2.11.0"
3-5.virshによるovsの設定
c76ovn02&03にてovsのPortGroup設定を実施しておきます。*2
c76ovn02&03 vi /tmp/ovsnw.xml <network> <name>ovsnw</name> <forward mode='bridge'/> <bridge name='br-int'/> <virtualport type='openvswitch'/> <portgroup name='untag' default='yes'> </portgroup> <portgroup name='vlan300'> <vlan> <tag id='300'/> </vlan> </portgroup> <portgroup name='vlan301'> <vlan> <tag id='301'/> </vlan> </portgroup> </network> virsh net-list virsh net-define /tmp/ovsnw.xml virsh net-start ovsnw virsh net-autostart ovsnw virsh net-list
4.docker+consulのクラスタ設定
4-1.Dockerの設定その1
Option設定を読込みできるようにします。
c76ovn01&02&03 vi /usr/lib/systemd/system/docker.service EnvironmentFile=-/etc/sysconfig/docker EnvironmentFile=-/etc/sysconfig/docker-storage EnvironmentFile=-/etc/sysconfig/docker-network ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock \ $OPTIONS \ $DOCKER_STORAGE_OPTIONS \ $DOCKER_NETWORK_OPTIONS \ $ADD_REGISTRY \ $BLOCK_REGISTRY \ $INSECURE_REGISTRY 出力例 青文字はコメントアウトしてください。 [Service] Type=notify # the default is not to use systemd for cgroups because the delegate issues still # exists and systemd currently does not support the cgroup feature set required # for containers run by docker #ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock EnvironmentFile=-/etc/sysconfig/docker EnvironmentFile=-/etc/sysconfig/docker-storage EnvironmentFile=-/etc/sysconfig/docker-network ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock \ $OPTIONS \ $DOCKER_STORAGE_OPTIONS \ $DOCKER_NETWORK_OPTIONS \ $ADD_REGISTRY \ $BLOCK_REGISTRY \ $INSECURE_REGISTRY ExecReload=/bin/kill -s HUP $MAINPID TimeoutSec=0 RestartSec=2 Restart=always
4-2.Dockerの設定その2
c76ovn01 vi /etc/sysconfig/docker OPTIONS="--cluster-store=consul://127.0.0.1:8500 --cluster-advertise=192.168.30.101:0" systemctl daemon-reload systemctl restart docker c76ovn02 vi /etc/sysconfig/docker OPTIONS="--cluster-store=consul://127.0.0.1:8500 --cluster-advertise=192.168.30.102:0" systemctl daemon-reload systemctl restart docker c76ovn03 vi /etc/sysconfig/docker OPTIONS="--cluster-store=consul://127.0.0.1:8500 --cluster-advertise=192.168.30.103:0" systemctl daemon-reload systemctl restart docker
4-3.consulのインストール
consulでクラスタを構成します。
一度設定をミスると色々やっかいだった*3ので、VMWareなどで各Nodeを動作させている方は、この手順を進める前にスナップショットなりクローンを作成しておいた方が良いと思います。
c76ovn01&ovn02&ovn03 yum -y install epel-release && \ yum -y install python-pip && \ pip install pip --upgrade && \ pip install flask wget https://releases.hashicorp.com/consul/1.5.2/consul_1.5.2_linux_amd64.zip unzip consul_1.5.2_linux_amd64.zip mv consul /usr/local/bin
4-4.consulの設定
最初に暗号キーを生成しておきます。生成した暗号キーは全Nodeで共通にしますので、任意の1台で生成すればOKです。ここでは例としてc76ovn01にて生成します。
c76ovn01 consul keygen 出力例 [root@c76ovn01 ~]# consul keygen az3EW5ykRod6hBS1FiSFAA==
各Nodeごとに設定ファイルを作成します。赤文字の箇所のみ異なっています。
c76ovn01 sudo mkdir -p /etc/consul.d/scripts sudo mkdir /var/consul vi /etc/consul.d/config.json { "bootstrap_expect": 3, "client_addr": "0.0.0.0", "datacenter": "dc1", "data_dir": "/var/consul", "domain": "consul", "enable_script_checks": true, "dns_config": { "enable_truncate": true, "only_passing": true }, "enable_syslog": true, "encrypt": "az3EW5ykRod6hBS1FiSFAA==", "leave_on_terminate": true, "log_level": "INFO", "rejoin_after_leave": true, "bind_addr": "192.168.30.101", "server": true, "start_join": [ "192.168.30.101", "192.168.30.102", "192.168.30.103" ], "ui": false } c76ovn02 sudo mkdir -p /etc/consul.d/scripts sudo mkdir /var/consul vi /etc/consul.d/config.json { "bootstrap_expect": 3, "client_addr": "0.0.0.0", "datacenter": "dc1", "data_dir": "/var/consul", "domain": "consul", "enable_script_checks": true, "dns_config": { "enable_truncate": true, "only_passing": true }, "enable_syslog": true, "encrypt": "az3EW5ykRod6hBS1FiSFAA==", "leave_on_terminate": true, "log_level": "INFO", "rejoin_after_leave": true, "bind_addr": "192.168.30.102", "server": true, "start_join": [ "192.168.30.101", "192.168.30.102", "192.168.30.103" ], "ui": false } c76ovn03 sudo mkdir -p /etc/consul.d/scripts sudo mkdir /var/consul vi /etc/consul.d/config.json { "bootstrap_expect": 3, "client_addr": "0.0.0.0", "datacenter": "dc1", "data_dir": "/var/consul", "domain": "consul", "enable_script_checks": true, "dns_config": { "enable_truncate": true, "only_passing": true }, "enable_syslog": true, "encrypt": "az3EW5ykRod6hBS1FiSFAA==", "leave_on_terminate": true, "log_level": "INFO", "rejoin_after_leave": true, "bind_addr": "192.168.30.103", "server": true, "start_join": [ "192.168.30.101", "192.168.30.102", "192.168.30.103" ], "ui": false }
4-5.consulのサービス化設定
consulをサービス化し、自動起動するように設定します。
c76ovn01&02&03 vi /etc/systemd/system/consul.service [Unit] Description=Consul Startup process After=network.target [Service] Type=simple ExecStart=/bin/bash -c '/usr/local/bin/consul agent -config-dir /etc/consul.d/' TimeoutStartSec=0 [Install] WantedBy=default.target systemctl daemon-reload systemctl start consul systemctl enable consul consul members 出力例 全Nodeで同様の出力となります。 [root@c76ovn03 ~]# consul members Node Address Status Type Build Protocol DC Segment c76ovn01.md.jp 192.168.30.101:8301 alive server 1.5.2 2 dc1c76ovn02.md.jp 192.168.30.102:8301 alive server 1.5.2 2 dc1 c76ovn03.md.jp 192.168.30.103:8301 alive server 1.5.2 2 dc1 [root@c76ovn03 ~]# systemctl status consul ● consul.service - Consul Startup process Loaded: loaded (/etc/systemd/system/consul.service; enabled; vendor preset: disabled) Active: active (running) since Sun 2019-07-21 16:27:32 JST; 1s ago Main PID: 28182 (consul) Tasks: 14 Memory: 18.2M CGroup: /system.slice/consul.service mq28182 /usr/local/bin/consul agent -config-dir /etc/consul.d/ Jul 21 16:27:32 c76ovn03.md.jp consul[28182]: consul: Adding LAN server c76ovn01.md.jp (Addr: tcp/192.168.30.101:8300) (DC: dc1) Jul 21 16:27:32 c76ovn03.md.jp consul[28182]: consul: Adding LAN server c76ovn02.md.jp (Addr: tcp/192.168.30.102:8300) (DC: dc1) Jul 21 16:27:32 c76ovn03.md.jp consul[28182]: serf: EventMemberJoin: c76ovn02.md.jp.dc1 192.168.30.102 Jul 21 16:27:32 c76ovn03.md.jp consul[28182]: serf: Re-joined to previously known node: c76ovn01.md.jp.dc1: 192.168.30.101:8302 Jul 21 16:27:32 c76ovn03.md.jp consul[28182]: agent: Started HTTP server on [::]:8500 (tcp) Jul 21 16:27:32 c76ovn03.md.jp consul[28182]: consul: Handled member-join event for server "c76ovn01.md.jp.dc1" in area "wan" Jul 21 16:27:32 c76ovn03.md.jp consul[28182]: consul: Handled member-join event for server "c76ovn02.md.jp.dc1" in area "wan" Jul 21 16:27:32 c76ovn03.md.jp consul[28182]: agent: (LAN) joining: [192.168.30.101 192.168.30.102 192.168.30.103] Jul 21 16:27:32 c76ovn03.md.jp consul[28182]: agent: (LAN) joined: 3 Jul 21 16:27:32 c76ovn03.md.jp consul[28182]: agent: started state syncer
ここまで完了したら、一度全Nodeを再起動しておいてください。
再起動完了後、以下のコマンドでDockerとconsulが正常に起動していることを確認してください。
systemctl status docker systemctl status consul
5.(1)~(7)の設定
5-1.事前準備
ovnのdocker-overlayドライバを各ComputeNodeで起動しておきます。
c76ovn02&03 ovn-docker-overlay-driver --detach
5-2.(1)の設定:DockerOverlaySwitchの作成
(1’)は自動生成されていますが、Overlay上では認識されていません。
以下のコマンドにより、ovnのNorthboundDBにDockerOverlaySwitchが生成されます。それと同時にDocker上のNWとしても認識されます。
c76ovn02もしくはc76ovn03のどちらか一方で設定すればOKです。
c76ovn02 or 03 docker network create -d openvswitch --subnet=192.168.31.0/24 ovs 出力例 [root@c76ovn02 ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 7a78f73ce06d bridge bridge local 368be43f05a1 host host local efee695f0f0c none null local b5fb702e9489 ovs openvswitch global [root@c76ovn02 ~]# ovn-nbctl --db=tcp:192.168.30.101:6641 show switch b70b9243-80b3-4ad6-8940-55bff06251fc (b5fb702e948902881b1b933191b9ee83f8dad4eb434a9d27d408d7a2d5fe2aa2)
5-3.(2)の設定:br-extの作成
br-intに無理やりインターフェースをアタッチしても外部とのBridge接続による疎通はできません。この辺りはNeutronのアーキテクチャに近い感じです。br-intとbr-extをPatch接続させて、外部ネットワークとブリッジ接続します。
c76ovn02 3-5に合わせて300-301をTrunkしていますが、今回の構成であれば301のみでOKです。 vi /etc/sysconfig/network-scripts/ifcfg-br-ext DEVICE=br-ext DEVICETYPE=ovs TYPE=OVSBridge BOOTPROTO=static NM_CONTROLLED=no ONBOOT=yes HOTPLUG=no vi /etc/sysconfig/network-scripts/ifcfg-ens36 DEVICE=ens36 ONBOOT=yes DEVICETYPE=ovs TYPE=OVSPort OVS_BRIDGE=br-ext BOOTPROTO=none NM_CONTROLLED=no OVS_OPTIONS="vlan_mode=trunk trunks=300-301" HOTPLUG=no systemctl restart network
5-4.(3)の設定:br-intとbr-extのPatch接続
先にovn-sbctlコマンドでシャーシIDを取得した後に設定を入れます。
c76ovn02
(3)
ovn-sbctl --db=tcp:192.168.30.101:6642 show
ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet301:br-ext
export SW_NAME=$(ovn-nbctl --db=tcp:192.168.30.101:6641 ls-list | awk '{print $2}' | sed s/\(//g | sed s/\)//g)
ovn-nbctl --db=tcp:192.168.30.101:6641 lsp-add $SW_NAME l2gwport "" 301
ovn-nbctl --db=tcp:192.168.30.101:6641 lsp-set-addresses l2gwport unknown
ovn-nbctl --db=tcp:192.168.30.101:6641 lsp-set-type l2gwport l2gateway
ovn-nbctl --db=tcp:192.168.30.101:6641 lsp-set-options l2gwport network_name=physnet301 l2gateway-chassis=28928b40-900b-4f48-b4ed-8d9d2f1082fd
補足その1
ovn-sbctl --db=tcp:192.168.30.101:6642 showの出力例を以下に記載します。
赤文字の箇所をl2gateway-chassis=の後に加えます。
出力例
[root@c76ovn02 ~]# ovn-sbctl --db=tcp:192.168.30.101:6642 show
Chassis "1fdd4703-9c73-4afd-adf3-e0e90b7afb63"
hostname: "c76ovn03.md.jp"
Encap geneve
ip: "192.168.30.103"
options: {csum="true"}
Port_Binding "35d89c2d-0505-41aa-b0c6-6aff6f483899"
Port_Binding "b7131d7ecd548dcc4b6eb38bef0179b1bc75645e5683b69e6131da69d0aed1be"
Chassis "28928b40-900b-4f48-b4ed-8d9d2f1082fd"
hostname: "c76ovn02.md.jp"
Encap geneve
ip: "192.168.30.102"
options: {csum="true"}
Port_Binding "16b258df72cb52ddb2527be69578c1f953c9275e154d4107743b0ee3ac13f095"
Port_Binding "2c5a0afd-b12a-419e-b6f5-718c5d0e6446"
Port_Binding "l2gwport"
[root@c76ovn02 ~]#
補足その2 設定後、以下のようになっていればOKです。 出力例 [root@c76ovn02 ~]# ovn-nbctl --db=tcp:192.168.30.101:6641 show switch b70b9243-80b3-4ad6-8940-55bff06251fc (b5fb702e948902881b1b933191b9ee83f8dad4eb434a9d27d408d7a2d5fe2aa2) port l2gwport type: l2gateway parent: tag: 301 addresses: ["unknown"] [root@c76ovn02 ~]# [root@c76ovn02 ~]# ovs-vsctl show 090be24a-f730-4d28-a4a0-dcf6d97fe618 Bridge br-int fail_mode: secure Port "patch-br-int-to-l2gwport" Interface "patch-br-int-to-l2gwport" type: patch options: {peer="patch-l2gwport-to-br-int"} Port "ovn-1fdd47-0" Interface "ovn-1fdd47-0" type: geneve options: {csum="true", key=flow, remote_ip="192.168.30.103"} Port br-int Interface br-int type: internal Bridge br-ext Port "patch-l2gwport-to-br-int" Interface "patch-l2gwport-to-br-int" type: patch options: {peer="patch-br-int-to-l2gwport"} Port br-ext Interface br-ext type: internal Port "ens36" trunks: [300, 301] Interface "ens36" ovs_version: "2.11.1" [root@c76ovn02 ~]#
ここまででアップリンクに相当する部分が構築できました。
あとは、仮想マシンやコンテナをアタッチしていきます。
コンテナは以下のコマンドで作成したDockerネットワークのovsにアタッチさせるだけで自動設定してくれます。
docker network create -d openvswitch --subnet=192.168.31.0/24 ovs
一方、KVMの仮想マシンについては、もう一工夫必要になります。
5-5.(4)と(5)の設定:KVM仮想マシンのアタッチ
先にvirt-installコマンドなどで仮想マシンを起動しておいてください。
その際、仮想マシンに使用するインターフェースは3-5で設定したPortGroupのうちvlan301を使用するようにしてください。
virt-installはこんな感じです。ポイントは赤文字の箇所です。
virt-install --connect=qemu:///system \
--name=c7623 \
--disk /var/lib/libvirt/images/c7623.qcow2,format=qcow2,bus=virtio \
--network bridge=virbr0,model=virtio \
--network network=ovsnw,portgroup=vlan301,model=virtio \
--initrd-inject=./c76min.ks \
--extra-args='ks=file:/c76min.ks biosdevname=0 net.ifnames=0 console=tty0 console=ttyS0,115200n8' \
--vcpus=1 \
--ram=1024 \
--accelerate \
--hvm \
--location='/var/lib/libvirt/images/CentOS-7-x86_64-DVD-1810.iso' \
--nographics \
--os-type=linux \
--os-variant=centos7.0 \
--arch=x86_64
これにより、以下のような設定になります。ポイントはvnet1とovsnw, vlan301がBridgeしている点です。
vnet0 | virbr0 | eth0 | libvirtでDefault定義 |
vnet1 | ovsnw, vlan301 | eth1 | 3-5で定義 |
仮想マシンが起動したら以下のコマンドにて、ovn上に登録していきます。
SW_NAME、IFACE_ID、MAC_ADDRを取得し、それをNorthboundDBに登録する形となります。*4
c76ovn02
(4)
export SW_NAME=$(ovn-nbctl --db=tcp:192.168.30.101:6641 ls-list | awk '{print $2}' | sed s/\(//g | sed s/\)//g)
export IFACE_ID=$(ovs-vsctl get interface vnet1 external_ids:iface-id | sed s/\"//g)
export MAC_ADDR=$(ovs-vsctl get interface vnet1 external_ids:attached-mac | sed s/\"//g)
ovn-nbctl --db=tcp:192.168.30.101:6641 lsp-add $SW_NAME $IFACE_ID
ovn-nbctl --db=tcp:192.168.30.101:6641 lsp-set-addresses $IFACE_ID $MAC_ADDR
ovn-nbctl --db=tcp:192.168.30.101:6641 show
c76ovn03
(5)
export SW_NAME=$(ovn-nbctl --db=tcp:192.168.30.101:6641 ls-list | awk '{print $2}' | sed s/\(//g | sed s/\)//g)
export IFACE_ID=$(ovs-vsctl get interface vnet1 external_ids:iface-id | sed s/\"//g)
export MAC_ADDR=$(ovs-vsctl get interface vnet1 external_ids:attached-mac | sed s/\"//g)
ovn-nbctl --db=tcp:192.168.30.101:6641 lsp-add $SW_NAME $IFACE_ID
ovn-nbctl --db=tcp:192.168.30.101:6641 lsp-set-addresses $IFACE_ID $MAC_ADDR
ovn-nbctl --db=tcp:192.168.30.101:6641 show
出力例
[root@c76ovn02 ~]# ovn-nbctl --db=tcp:192.168.30.101:6641 show
switch b70b9243-80b3-4ad6-8940-55bff06251fc (b5fb702e948902881b1b933191b9ee83f8dad4eb434a9d27d408d7a2d5fe2aa2)
port l2gwport
type: l2gateway
parent:
tag: 301
addresses: ["unknown"]
port 35d89c2d-0505-41aa-b0c6-6aff6f483899
addresses: ["52:54:00:f6:45:c2"]
port 2c5a0afd-b12a-419e-b6f5-718c5d0e6446
addresses: ["52:54:00:d7:a6:96"]
[root@c76ovn02 ~]#
5-6.(6)と(7)の設定:Dockerコンテナのアタッチ
DockerコンテナのアタッチはPlug-Inで自動的にovs&ovnに登録されるため、「--network ovs」だけ忘れずに設定すれば問題ありません。
c76ovn02
(6)
docker run -itd \
--privileged \
--network ovs \
--name c2 \
centos \
/sbin/init
c76ovn03
(7)
docker run -itd \
--privileged \
--network ovs \
--name c3 \
centos \
/sbin/init
構成を確認してみます。
確認コマンド docker network ls ovn-nbctl --db=tcp:192.168.30.101:6641 show ovn-sbctl --db=tcp:192.168.30.101:6642 show ovs-vsctl show 出力例 ここでは例としてc76ovn03にて実施します。 ovs-vsctl showだけは02&03の両方で出力させます。 [root@c76ovn03 ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 116424d7f10a bridge bridge local db62b02926e4 docker_gwbridge bridge local dcdbfcc3e390 host host local da1e0883a8ed none null local b5fb702e9489 ovs openvswitch global [root@c76ovn03 ~]# ovn-nbctl --db=tcp:192.168.30.101:6641 show switch b70b9243-80b3-4ad6-8940-55bff06251fc (b5fb702e948902881b1b933191b9ee83f8dad4eb434a9d27d408d7a2d5fe2aa2) port b7131d7ecd548dcc4b6eb38bef0179b1bc75645e5683b69e6131da69d0aed1be addresses: ["02:dc:06:e4:de:3c 192.168.31.2"] port 16b258df72cb52ddb2527be69578c1f953c9275e154d4107743b0ee3ac13f095 addresses: ["02:26:b3:e1:ab:5c 192.168.31.3"] port l2gwport type: l2gateway parent: tag: 301 addresses: ["unknown"] port 35d89c2d-0505-41aa-b0c6-6aff6f483899 addresses: ["52:54:00:f6:45:c2"] port 2c5a0afd-b12a-419e-b6f5-718c5d0e6446 addresses: ["52:54:00:d7:a6:96"] [root@c76ovn03 ~]# ovn-sbctl --db=tcp:192.168.30.101:6642 show Chassis "1fdd4703-9c73-4afd-adf3-e0e90b7afb63" hostname: "c76ovn03.md.jp" Encap geneve ip: "192.168.30.103" options: {csum="true"} Port_Binding "35d89c2d-0505-41aa-b0c6-6aff6f483899" Port_Binding "b7131d7ecd548dcc4b6eb38bef0179b1bc75645e5683b69e6131da69d0aed1be" Chassis "28928b40-900b-4f48-b4ed-8d9d2f1082fd" hostname: "c76ovn02.md.jp" Encap geneve ip: "192.168.30.102" options: {csum="true"} Port_Binding "16b258df72cb52ddb2527be69578c1f953c9275e154d4107743b0ee3ac13f095" Port_Binding "2c5a0afd-b12a-419e-b6f5-718c5d0e6446" Port_Binding "l2gwport" [root@c76ovn02 ~]# ovs-vsctl show 090be24a-f730-4d28-a4a0-dcf6d97fe618 Bridge br-int fail_mode: secure Port "16b258df72cb52d" Interface "16b258df72cb52d" Port "vnet1" tag: 301 Interface "vnet1" Port "patch-br-int-to-l2gwport" Interface "patch-br-int-to-l2gwport" type: patch options: {peer="patch-l2gwport-to-br-int"} Port "ovn-1fdd47-0" Interface "ovn-1fdd47-0" type: geneve options: {csum="true", key=flow, remote_ip="192.168.30.103"} Port br-int Interface br-int type: internal Bridge br-ext Port "patch-l2gwport-to-br-int" Interface "patch-l2gwport-to-br-int" type: patch options: {peer="patch-br-int-to-l2gwport"} Port br-ext Interface br-ext type: internal Port "ens36" trunks: [30, 300, 301] Interface "ens36" ovs_version: "2.11.1" [root@c76ovn03 ~]# ovs-vsctl show 2cbade66-e4e8-48e1-83e7-2ff460c1d665 Bridge br-ext Port "ens36" trunks: [300, 301] Interface "ens36" Port br-ext Interface br-ext type: internal Bridge br-int fail_mode: secure Port "ovn-28928b-0" Interface "ovn-28928b-0" type: geneve options: {csum="true", key=flow, remote_ip="192.168.30.102"} Port br-int Interface br-int type: internal Port "b7131d7ecd548dc" Interface "b7131d7ecd548dc" Port "vnet1" tag: 301 Interface "vnet1" ovs_version: "2.11.1" [root@c76ovn03 ~]# docker container exec c3 ping 192.168.31.2 PING 192.168.31.2 (192.168.31.2) 56(84) bytes of data. 64 bytes from 192.168.31.2: icmp_seq=1 ttl=64 time=0.029 ms 64 bytes from 192.168.31.2: icmp_seq=2 ttl=64 time=0.070 ms ^C [root@c76ovn03 ~]# docker container exec c3 ping 192.168.31.203 PING 192.168.31.203 (192.168.31.203) 56(84) bytes of data. 64 bytes from 192.168.31.203: icmp_seq=1 ttl=64 time=0.946 ms 64 bytes from 192.168.31.203: icmp_seq=2 ttl=64 time=0.697 ms ^C [root@c76ovn03 ~]# docker container exec c3 ping 192.168.31.2 PING 192.168.31.2 (192.168.31.2) 56(84) bytes of data. 64 bytes from 192.168.31.2: icmp_seq=1 ttl=64 time=0.028 ms 64 bytes from 192.168.31.2: icmp_seq=2 ttl=64 time=0.073 ms 64 bytes from 192.168.31.2: icmp_seq=3 ttl=64 time=0.027 ms ^C [root@c76ovn03 ~]# docker container exec c3 ping 192.168.31.202 PING 192.168.31.202 (192.168.31.202) 56(84) bytes of data. 64 bytes from 192.168.31.202: icmp_seq=1 ttl=64 time=2.34 ms 64 bytes from 192.168.31.202: icmp_seq=2 ttl=64 time=2.28 ms 64 bytes from 192.168.31.202: icmp_seq=3 ttl=64 time=2.98 ms ^C [root@c76ovn03 ~]# docker container exec c3 ping 192.168.31.203 PING 192.168.31.203 (192.168.31.203) 56(84) bytes of data. 64 bytes from 192.168.31.203: icmp_seq=1 ttl=64 time=0.256 ms 64 bytes from 192.168.31.203: icmp_seq=2 ttl=64 time=0.984 ms 64 bytes from 192.168.31.203: icmp_seq=3 ttl=64 time=0.262 ms ^C [root@c76ovn03 ~]# docker container exec c3 ping 192.168.31.254 PING 192.168.31.254 (192.168.31.254) 56(84) bytes of data. 64 bytes from 192.168.31.254: icmp_seq=1 ttl=64 time=9.48 ms 64 bytes from 192.168.31.254: icmp_seq=2 ttl=64 time=3.94 ms 64 bytes from 192.168.31.254: icmp_seq=3 ttl=64 time=3.91 ms
NorthboundDBとSouthboundDBの状態を確認する以下のコマンドですが
ovn-nbctl --db=tcp:192.168.30.101:6641 show ovn-sbctl --db=tcp:192.168.30.101:6642 show
図に起こすとこんな感じになります。
最初に載せた2つの図と合わせて観ると、より明確になってくるかと思います。
6.補足
ComputeNodeを再起動やShutdownしたいときは、以下のようなコマンドで必ずコンテナを終了させた後に、再起動やShutdownしてください。
docker container stop c2
というのも、Dockerコンテナのアタッチ時はほぼほぼ自動で設定してくれていましたが、デタッチ時は上記コマンドのように正常にコンテナを終了させないと、NorthboundDB上にゴミが残ります。場合によっては消せなくなるので、何度も繰り返し試したい方は必ずコンテナを終了させるようにしましょう。
以上です。
7.最後に
以下のサイトを参考にさせて頂きました。
OVN 設定サンプル | OVN config example 2015/12/27
Using OVN with KVM and Libvirt - Scott's Weblog - The weblog of an IT pro focusing on cloud computing, Kubernetes, Linux, containers, and networking
OVN - L2 Breakout Options | Blog @ Weiti.ORG
Dustin Spinhirne: The OVN Gateway Router
ovnは正直取っつきにくいかもしれません。
しかし、openstack stein以降では、ovnが実装されるようなので、今のうちから、しっかり理解しておくことは大切かなと思います。
また、今回はKVMとDockerでしたが、LXC/LXDでも試してみました。
しかし、FakeBridgeを使用する点が障壁となり疎通できませんでした。
さらに、アップリンク側にDPDKも動作させてみたのですが、設定方法は解ったものの、これまた疎通できずで断念しました。
Bridgeではなく、PAT+Routingだったら上手くいくような気がしていますが、取り急ぎ、一旦まとめてみようと思い今回の記事を書いた次第です。
なお、今回はl2gatewayという方法でBridgeさせましたが、localnetという方法もあります。こちらは、全ComputeNodeにてbr-extを作成した後、以下のコマンドでNorthboundDBに登録すれば設定可能です。
export SW_NAME=$(ovn-nbctl --db=tcp:192.168.30.101:6641 ls-list | awk '{print $2}' | sed s/\(//g | sed s/\)//g) ovn-nbctl --db=tcp:192.168.30.101:6641 lsp-add $SW_NAME lcntport "" 301 ovn-nbctl --db=tcp:192.168.30.101:6641 lsp-set-addresses lcntport unknown ovn-nbctl --db=tcp:192.168.30.101:6641 lsp-set-type lcntport localnet ovn-nbctl --db=tcp:192.168.30.101:6641 lsp-set-options lcntport network_name=physnet301
localnetの場合、冗長化できそうな雰囲気はありますが、L2ループの懸念があるため、あまり推奨されていないようです。
ただ、いずれにせよ、ovn単体で使うのはあまり現実的ではないと感じたので、やはりopenstackやovirtなどと一緒に使用するのが良いと思います。
*1:例外はあります。例えば、(1')は自動で設定されますが、その後(1)を手動設定した際に初めて利用可能となる、といったケースがあります。また、(2)を手動設定した後、(3)を設定しないと、(2’)や(3’)がNorthboundDB上で認識されない、など。
*2:ここではUntagやvlan300も作成されていますが、vlan301のみでOKです。他は削除して構いません。
*3:私の環境では、正しい設定に直してもエラーが解消されなかったりしました。本編とあまり関係の無いところで時間を取られるのは、しんどいのでスナップショットやクローン化をおススメします。
*4:上記(4)と(5)のコマンドは同じですが、それぞれのComputeNodeにて実行するため取得するIDが異なります。
CentOS7 kickstartによるインストール
kickstartによるインストールのサンプルファイルをいくつかピックアップしてみたいと思います。
サンプルとしては以下3つ。
これ以外にも応用はいくらでもできると思います。
1.CentOS7上のKVMにminimalでインストール
1-1.kickstartファイルの作成
vi c76min.ks cmdline install # Keyboard layouts keyboard --vckeymap=us --xlayouts='us' # System language lang en_US.UTF-8 # Network information network --bootproto=dhcp --device=eth0 --onboot=on --noipv6 --activate #network --bootproto=static --device=eth0 --ip=192.168.0.100 --netmask=255.255.255.0 --gateway=192.168.0.1 --nameserver=192.168.0.1 --noipv6 --activate network --bootproto=static --device=eth1 --ip=192.168.1.100 --netmask=255.255.255.0 --noipv6 network --hostname=c7623.local.com zerombr bootloader --location=mbr --boot-drive=vda --append="crashkernel=auto biosdevname=0 net.ifnames=0 console=tty0 console=ttyS0,115200n8" clearpart --none --initlabel # Disk partitioning information part /boot --ondisk=vda --size=1024 --fstype="xfs" part pv.1 --ondisk=vda --size=1024 --grow volgroup centos --pesize=4096 pv.1 logvol swap --fstype="swap" --name=swap --vgname=centos --recommended logvol / --fstype="xfs" --name=root --vgname=centos --size=1024 --grow # Root password rootpw --plaintext TESTPASSWORD # System timezone timezone Asia/Tokyo --isUtc --nontp user --groups=wheel --name=user1 --password=TESTPASSWORD --plaintext # X Window System configuration information xconfig --startxonboot %packages @^minimal @core kexec-tools chrony %end reboot --eject
1-3.virt-installの実行
virt-install --connect=qemu:///system \ --name=c7623 \ --disk /var/lib/libvirt/images/c7623.qcow2,format=qcow2,bus=virtio \ --network bridge=virbr0,model=virtio \ --network network=ovsnw,portgroup=vlan301,model=virtio \ --initrd-inject=./c76min.ks \ --extra-args='ks=file:/c76min.ks biosdevname=0 net.ifnames=0 console=tty0 console=ttyS0,115200n8' \ --vcpus=1 \ --ram=1024 \ --accelerate \ --hvm \ --location='/var/lib/libvirt/images/CentOS-7-x86_64-DVD-1810.iso' \ --nographics \ --os-type=linux \ --os-variant=centos7.0 \ --arch=x86_64
1-4.補足
上記1-3のvirt-installコマンドのうち、
--network network=ovsnw,portgroup=vlan301,model=virtio \
の部分は
以下のようにovsにてスイッチを作成し、net-defineによって定義した場合の設定となります。
vi /tmp/ovsnw.xml <network> <name>ovsnw <forward mode='bridge'/> <bridge name='ovsbr0'/> <virtualport type='openvswitch'/> <portgroup name='untag' default='yes'> </portgroup> <portgroup name='vlan11'> <vlan> <tag id='11'/> </vlan> </portgroup> <portgroup name='vlan300'> <vlan> <tag id='300'/> </vlan> </portgroup> <portgroup name='vlan301'> <vlan> <tag id='301'/> </vlan> </portgroup> <portgroup name='vlan302'> <vlan> <tag id='302'/> </vlan> </portgroup> </network> virsh net-define /tmp/ovsnw.xml virsh net-start ovsnw virsh net-autostart ovsnw virsh net-list
2.CentOS7上のKVMにServerGUIでインストール
2-1.kickstartファイルの作成
vi c76gui.ks cmdline install # Keyboard layouts keyboard --vckeymap=us --xlayouts='us' # System language lang en_US.UTF-8 # Network information network --bootproto=dhcp --device=eth0 --onboot=on --noipv6 --activate #network --bootproto=static --device=eth0 --ip=192.168.0.100 --netmask=255.255.255.0 --gateway=192.168.0.1 --nameserver=192.168.0.1 --noipv6 --activate network --bootproto=static --device=eth1 --ip=192.168.1.100 --netmask=255.255.255.0 --noipv6 network --hostname=c7625.local.com zerombr bootloader --location=mbr --boot-drive=vda --append="crashkernel=auto biosdevname=0 net.ifnames=0 console=tty0 console=ttyS0,115200n8" clearpart --none --initlabel # Disk partitioning information part /boot --ondisk=vda --size=1024 --fstype="xfs" part pv.1 --ondisk=vda --size=1024 --grow volgroup centos --pesize=4096 pv.1 logvol swap --fstype="swap" --name=swap --vgname=centos --recommended logvol / --fstype="xfs" --name=root --vgname=centos --size=1024 --grow # Root password rootpw --plaintext TESTPASSWORD # System timezone timezone Asia/Tokyo --isUtc --nontp user --groups=wheel --name=user1 --password=TESTPASSWORD --plaintext # X Window System configuration information xconfig --startxonboot %packages @^graphical-server-environment @base @core @desktop-debugging @development @fonts @gnome-desktop @guest-agents @guest-desktop-agents @hardware-monitoring @input-methods @internet-browser @virtualization-client @virtualization-hypervisor @virtualization-tools @x11 %end reboot --eject
2-3.virt-installの実行
virt-install --connect=qemu:///system \ --name=c7625 \ --disk /var/lib/libvirt/images/c7625.qcow2,format=qcow2,bus=virtio \ --network bridge=virbr0,model=virtio \ --network network=ovsnw,portgroup=vlan301,model=virtio \ --initrd-inject=./c76gui.ks \ --extra-args='ks=file:/c76gui.ks biosdevname=0 net.ifnames=0 console=tty0 console=ttyS0,115200n8' \ --vcpus=1 \ --ram=1024 \ --accelerate \ --hvm \ --location='/var/lib/libvirt/images/CentOS-7-x86_64-DVD-1810.iso' \ --nographics \ --os-type=linux \ --os-variant=centos7.0 \ --arch=x86_64
3.DL360G8上にCentOS7をServerGUIでインストール
3-1.kickstartファイルの作成
#version=DEVEL # X Window System configuration information xconfig --startxonboot # License agreement eula --agreed # Use CDROM installation media cdrom # Use graphical install graphical # Run the Setup Agent on first boot firstboot --enable # Keyboard layouts keyboard --vckeymap=us --xlayouts='us' # System language lang en_US.UTF-8 ignoredisk --only-use=sda # Network information network --bootproto=static --device=eno1 --ip=192.168.0.100 --netmask=255.255.255.0 --gateway=192.168.0.1 --nameserver=192.168.0.1 --noipv6 --activate network --hostname=c765.local.com #network --bootproto=dhcp --device=eno2 --onboot=off --ipv6=auto #network --bootproto=dhcp --device=eno3 --onboot=off --ipv6=auto #network --bootproto=dhcp --device=eno4 --onboot=off --ipv6=auto #network --bootproto=dhcp --device=ens1f0 --onboot=off --ipv6=auto #network --bootproto=dhcp --device=ens1f1 --onboot=off --ipv6=auto # Reboot after installation reboot --eject # Root password rootpw --plaintext TESTPASSWORD # System timezone timezone Asia/Tokyo --isUtc --nontp user --groups=wheel --name=user1 --password=TESTPASSWORD # System bootloader configuration bootloader --append=" crashkernel=auto" --location=mbr --boot-drive=sda # Partition clearing information clearpart --all --initlabel --drives=sda # Disk partitioning information part pv.105 --fstype="lvmpv" --ondisk=sda --size=1 --grow part /boot --fstype="xfs" --ondisk=sda --size=1024 volgroup centos --pesize=4096 pv.105 logvol / --fstype="xfs" --name=root --vgname=centos --size=1 --grow logvol swap --fstype="swap" --name=swap --vgname=centos --size=4096 %packages @^graphical-server-environment @base @core @desktop-debugging @development @dial-up @fonts @gnome-desktop @guest-agents @guest-desktop-agents @hardware-monitoring @input-methods @internet-browser @multimedia @print-client @virtualization-client @virtualization-hypervisor @virtualization-tools @x11 kexec-tools %end %addon com_redhat_kdump --enable --reserve-mb=auto %end %anaconda pwpolicy root --minlen=6 --minquality=1 --notstrict --nochanges --notempty pwpolicy user --minlen=6 --minquality=1 --notstrict --nochanges --emptyok pwpolicy luks --minlen=6 --minquality=1 --notstrict --nochanges --notempty %end
ファイル名をks.cfgとして、isoやimgファイルなどにイメージ化してください。
ここではイメージ化後のファイル名をks.imgとします。
3-2.イメージファイルのセット
上図のうち、以下のようにイメージファイルをセットします。
ImageFile RemovalMedhia | ks.img |
ImageFile CD-ROM/DVD | CentOS-7-x86_64-DVD-1810.iso |
3-3.起動オプションの設定とインストールの実行
筐体を起動後、上図が表示されたら
Install CentOS 7を選択し、Tabキーを入力してください。
次に起動オプションの入力を促されるので、以下の通り入力してください。
inst.ks=hd:sdb:/ks.cfg
以下のようにインストールが始まれば、あとは待つだけです。
以上です。
10.最後に
以下のサイトを参考にさせて頂きました。
KickStartその2(ks.cfg設定ファイルの説明) - のぴぴのメモ
/root/anaconda-ks.cfgを参考にすれば色々試せると思いますので、自分なりにやってみることをおススメします。
*1:graphicalではなく、textの方がインストールは早いのですが、私の環境ではなぜか?インストール中に何度も失敗したためgraphicalにしています。
Dockerコンテナのネットワーク設定方法 OvSとSR-IOV編
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の用途の違いかなと思っているので、あまり深入りはしませんでした。