CentOS7でJuniper vMXのセットアップを実施したため、その手順を記載しておきます。
vMXはCiscoやA10と異なり、qcow2ファイルをVirt-InstallやVirt-Managerでデプロイするのではなく、インストール用のvmx.shを使います。
これが中々くせ者で、少しでも環境が違うと、エラーを吐いてインストールが停止してしまうため、環境構築や事前準備をしっかりやっておかないといけません。
なので、基本的には公式Docに沿って記載しつつも、その辺りのポイントをなるべく細かく書きたいと思います。
https://www.juniper.net/documentation/en_US/vmx17.2/information-products/pathway-pages/getting-started/getting-started.pdf
また、VFPの足回りとして、virtioとSR-IOVの2パターンで構成可能ですが、それぞれ特有の箇所には注釈を入れていきますので、特に注釈の無い箇所は2パターンとも共通項目だと考えてください。
1.環境
筐体 : ProLiant DL360e Gen8, DL360p Gen8 System ROM : P73 01/22/2018, P71 01/22/2018 NIC : Intel X540-AT2, X520-SR2(82599ES) OS : CentOS7.2(1511) Kernel : kernel-3.10.0-327.22.2.el7.x86_64 Installed Environment Groups : Server with GUI Add-Ons for Selected Environment : Virtualization Client, Virtualization Hypervisor, Virtualization Tools
2.環境構築
2-1.各種アップデート
yum -y groupinstall "virtualization-host-environment" yum -y install "http://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm" yum -y install centos-release-scl yum -y install python27-python-pip python27-python-devel numactl-libs libpciaccess-devel parted-devel yajl-devel libxml2-devel glib2-devel libnl-devel libxslt-devel libyaml-devel numactl-devel redhat-lsb kmod-ixgbe libvirt-daemon-kvm numactl telnet net-tools yum -y install gcc yum -y install "ftp://ftp.riken.jp/Linux/cern/centos/7/updates/x86_64/Packages/kernel-3.10.0-327.22.2.el7.x86_64.rpm" yum -y install "ftp://ftp.riken.jp/Linux/cern/centos/7/updates/x86_64/Packages/kernel-devel-3.10.0-327.22.2.el7.x86_64.rpm"
解かる方には説明不要かと思いますが、上から5行目までが公式Docに記載の通り、下の2行はSystem Requirementに合わせるべくKernelのVersionを指定しています。
yum -y install kernel kernel-develとかやってしまうと最新版をDLしてしまうので。
また2行目は公式Docだとelrepo-release-7.0-2.el7.elrepo.noarch.rpmですが、既に存在しないファイルなため、上記の通りにしています。
kernel-develを入れている時点で気付かれている方がいると思いますが、vmx.shを動作させた(vMXのインストールの)際にixgbeやi40eドライバのコンパイルが走ります。
rpm -qa | grep kernel* ls -Fal /usr/src/kernels/ ls -Fal /lib/modules/3.10.0-327.22.2.el7.x86_64/build/
一通り完了したら上記コマンドで確認しておきましょう。
2-2.SR-IOV周りの事前設定
vi /etc/default/grub
で開いて、
GRUB_CMDLINE_LINUX=の行末に以下を追記。
intel_iommu=on iommu=pt pci=realloc
[root@ ~]# vi /etc/default/grub "/etc/default/grub" 7L, 279CGRUB_TIMEOUT=5 GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)" GRUB_DEFAULT=saved GRUB_DISABLE_SUBMENU=true GRUB_TERMINAL_OUTPUT="console" GRUB_CMDLINE_LINUX="crashkernel=auto rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhgb quiet intel_iommu=on iommu=pt pci=realloc" GRUB_DISABLE_RECOVERY="true"
その後、以下を実施。
grub2-mkconfig -o /etc/grub2.cfg grubby --update-kernel=ALL grub2-editenv list shutdown -r now
grub2の設定反映
kernel-3.10.0-327.22.2での起動設定
kernel-3.10.0-327.22.2での起動確認
一旦、reboot
3.事前準備
vmx.shがインストール時にPyYAML libraryを使うための準備となります。
公式Docだと3行くらいしか記載されてないですが、pipでyamlをインストールする際にしくじったため、RedHatのサイトを見ながら肉付けをしています。わからない人はこの順番でコマンド投入してください。
以下は公式Doc通り。この後すぐにpip install netifaces pyyamlするとしくじるので、
PATH=/opt/rh/python27/root/usr/bin:$PATH export PATH
以下のコマンドを実行。
scl enable python27 bash source scl_source enable python27
新規ファイルを作成し、再起動後も有効化させる。
[root@ ~]# vi /etc/profile.d/enablepython27.sh #!/bin/bash source scl_source enable python27
正しい環境変数を設定し、
export LD_LIBRARY_PATH=/opt/rh/python27/root/usr/lib64 env | grep -i LD_LIBRARY_PATH
pipをアップグレード後、netifacesとpyyamlをインストール。
pip install --upgrade pip pip install netifaces pyyaml
以下は公式Doc通りです。
ln -s /usr/libexec/qemu-kvm /usr/bin/qemu-system-x86_64 chattr +i /etc/resolv.conf ls -Fal /etc/libvirt/qemu.conf
リンクを張る
NetworkMangerを無効化したくない場合の対処
qemu.confのオーナー&グループがrootであることの確認
4.各種ファイル準備と注意点
tgzファイルを以下のパスに格納して作業します。
/var/lib/libvirt/images
cd /var/lib/libvirt/images/ tar zxvf vmx-bundle-17.2R1.13.tgz cd vmx
作業パスへ移動
tgzファイルの展開
展開したディレクトリへ移動
この後、全部で2箇所いじった後、confファイルを作成していきます。
さらに、confファイル作成後の注意点を4-5以降に記載していますが、個人的にはここが一番大事かなと思っています。
4-1.envファイルの修正
以下の修正は、vmx.shの実行中にWarringを出さないようにするための対処。
vi env/centos_sriov.env
で開いて、以下の行を
PARAMS_grub_file='/boot/grub/grub.cfg'
以下のように修正。
PARAMS_grub_file='/boot/grub2/grub.cfg'
[root@vmx]# vi env/centos_sriov.env "env/centos_sriov.env" 37L, 843C#!/bin/sh # # Set environment as detected # CHECK_ENV=1 # # Centos checks to be enabled # CHECK_GRUB=1 CHECK_pkg=1 CHECK_kernel_ver=1 CHECK_qemu_ver=1 CHECK_libvirt_ver=1 CHECK_virsh=1 CHECK_ixgbe=1 CHECK_i40e=1 # # Define values for Centos # PARAMS_pkg_list='qemu-kvm libvirt-client bridge-utils python libyaml-devel numactl numactl-devel parted-devel libpciaaccess-devel yajl-devel libxml2-devel glib2-devel libnl-devel' PARAMS_pkg_cmd='yum list installed' PARAMS_grub_file='/boot/grub2/grub.cfg' PARAMS_grub_user_file='/etc/default/grub' PARAMS_kernel_ver='3.10.0-327' # or greater PARAMS_kernel_delimiter='-generic' PARAMS_qemu_ver='1.5.3' # or greater PARAMS_qemu_bin='qemu-system-x86_64' PARAMS_libvirt_ver='1.2.17' # or greater PARAMS_libvirt_bin='libvirtd' PARAMS_libvirt_service='libvirtd' PARAMS_num_hugepages_per_numa_node=8192
4-2.ヘッダファイルの修正(SR-IOVのみ)
以下の修正は、vmx.shの実行中、i40eドライバのコンパイルを停止させないための対処。
vi drivers/i40e-1.3.46/src/i40e/kcompat.h
で開いて、以下の行を検索
#define NDO_DFLT_BRIDGE_GETLINK_HAS_BRFLAGS
上記の行の直下に以下を追記。
#define NDO_BRIDGE_GETLINK_HAS_FILTER_MASK_PARAM
[root@vmx]# vi drivers/i40e-1.3.46/src/i40e/kcompat.h ~・~中略~・~ /* RHEL 7.2 backported napi_alloc_skb and friends */ static inline struct sk_buff *__kc_napi_alloc_skb(struct napi_struct *napi, unsigned int length) {return netdev_alloc_skb_ip_align(napi->dev, length); } #define napi_alloc_skb(napi,len) __kc_napi_alloc_skb(napi,len) #define __napi_alloc_skb(napi,len,mask) __kc_napi_alloc_skb(napi,len) #endif /* SKB_ALLOC_NAPI */ #define HAVE_CONFIG_PM_RUNTIME #if (RHEL_RELEASE_CODE && (RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(6,7)) && \(RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,0))) #define HAVE_RXFH_HASHFUNC #endif /* 6.7 < RHEL < 7.0 */ #if RHEL_RELEASE_CODE && (RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(7,1)) #define HAVE_RXFH_HASHFUNC #define NDO_DFLT_BRIDGE_GETLINK_HAS_BRFLAGS #define NDO_BRIDGE_GETLINK_HAS_FILTER_MASK_PARAM #endif /* RHEL > 7.1 */ #ifndef napi_schedule_irqoff #define napi_schedule_irqoff napi_schedule #endif #ifndef READ_ONCE #define READ_ONCE(_x) ACCESS_ONCE(_x) #endif #if RHEL_RELEASE_CODE && (RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(7,2)) #define HAVE_NDO_FDB_ADD_VID #endif
!注意!
上記の方法は、vmx.shを最後まで走らせるため(i40eドライバのコンパイルを完了させるためだけ)の措置なので、商用でX710使うぜッ!っていう方は、必ずJTACに確認しましょう。
4-3.confファイル作成:SR-IOVの場合
以下にサンプルconfファイルを記載しておきます。
ポイントは、#vPFE VM parametersの項で、device-type : sriov と記載している点です。
[root@vmx]# vi config/vmx01.conf ############################################################## # # vmx.conf # Config file for vmx on the hypervisor. # Uses YAML syntax. # Leave a space after ":" to specify the parameter value. # ############################################################## #Configuration on the host side - management interface, VM images etc. HOST: identifier : vmx01 # Maximum 6 characters host-management-interface : eno1 routing-engine-image : "/var/lib/libvirt/images/vmx/images/junos-vmx-x86-64-17.2R1.13.qcow2" routing-engine-hdd : "/var/lib/libvirt/images/vmx/images/vmxhdd.img" forwarding-engine-image : "/var/lib/libvirt/images/vmx/images/vFPC-20170523.img" #External bridge configuration BRIDGES: - type : external name : br-ext # Max 10 characters #vRE VM parameters CONTROL_PLANE: vcpus : 1 memory-mb : 4096 console_port: 8603 interfaces : - type : static ipaddr : 192.168.11.217 macaddr : "0A:00:DD:C0:DE:03" #vPFE VM parameters FORWARDING_PLANE: vcpus : 3 memory-mb : 12288 console_port: 8604 device-type : sriov interfaces : - type : static ipaddr : 192.168.11.218 macaddr : "0A:00:DD:C0:DE:13" #Interfaces JUNOS_DEVICES: - interface : ge-0/0/0 port-speed-mbps : 10000 nic : ens1f0 mtu : 9198 virtual-function : 0 mac-address : "02:06:0A:0E:FF:E3" description : "ge-0/0/0 con to ens1f0vf0" - interface : ge-0/0/1 port-speed-mbps : 10000 nic : ens1f1 mtu : 9198 virtual-function : 0 mac-address : "02:06:0A:0E:FF:F3" description : "ge-0/0/1 con to ens1f0vf1"
4-4.confファイル作成:virtioの場合
以下にサンプルconfファイルを記載しておきます。
ポイントは、#vPFE VM parametersの項で、device-type : virtio と記載している点です。
また、ge-0/0/0やge-0/0/1におけるホストOS側インターフェースとのバインドは、後から変更できるため、インストール時はこのままでOKです。
[root@vmx]# vi config/vmx02.conf ############################################################## # # vmx.conf # Config file for vmx on the hypervisor. # Uses YAML syntax. # Leave a space after ":" to specify the parameter value. # ############################################################## #Configuration on the host side - management interface, VM images etc. HOST: identifier : vmx02 # Maximum 6 characters host-management-interface : eno1 routing-engine-image : "/var/lib/libvirt/images/vmx/images/junos-vmx-x86-64-17.2R1.13.qcow2" routing-engine-hdd : "/var/lib/libvirt/images/vmx/images/vmxhdd.img" forwarding-engine-image : "/var/lib/libvirt/images/vmx/images/vFPC-20170523.img" #External bridge configuration BRIDGES: - type : external name : br-ext # Max 10 characters #vRE VM parameters CONTROL_PLANE: vcpus : 1 memory-mb : 1024 console_port: 8601 interfaces : - type : static ipaddr : 192.168.11.215 macaddr : "0A:00:DD:C0:DE:01" #vPFE VM parameters FORWARDING_PLANE: memory-mb : 4096 vcpus : 3 console_port: 8602 device-type : virtio interfaces : - type : static ipaddr : 192.168.11.216 macaddr : "0A:00:DD:C0:DE:11" #Interfaces JUNOS_DEVICES: - interface : ge-0/0/0 mac-address : "02:06:0A:0E:FF:E1" description : "ge-0/0/0 interface" - interface : ge-0/0/1 mac-address : "02:06:0A:0E:FF:F1" description : "ge-0/0/1 interface"
4-5.注意点その1
virtioおよびSR-IOVに共通することで、host-management-interface : eno1と記載している点についてです。
私のホストOS環境上では、以下のようなインターフェース設定となっています。(RXやTXの行は不要なので削除しています)
[root@ vmx]# ifconfig eno1: flags=4163mtu 1500 inet 192.168.11.161 netmask 255.255.255.0 broadcast 192.168.11.255 inet6 fe80::ae16:2dff:febb:9ec0 prefixlen 64 scopeid 0x20 ether ac:16:2d:bb:9e:c0 txqueuelen 1000 (Ethernet) eno2: flags=4163 mtu 1500 inet 192.168.12.130 netmask 255.255.255.0 broadcast 192.168.12.255 inet6 fe80::ae16:2dff:febb:9ec1 prefixlen 64 scopeid 0x20 ether ac:16:2d:bb:9e:c1 txqueuelen 1000 (Ethernet) ens1f0: flags=4163 mtu 1500 ether a0:36:9f:3e:6d:68 txqueuelen 1000 (Ethernet) ens1f1: flags=4163 mtu 1500 ether a0:36:9f:3e:6d:6a txqueuelen 1000 (Ethernet)
上記の設定理由として、host-management-interface : eno1の項に書くインターフェースの要件を記載します。
(ここでは例として、eno1とします)
- eno1はDefaultGatewayが設定されていること。
- eno1は物理インターフェースであること。
- eno1以外のインターフェースにeno1と同一SubnetのIPを設定していないこと。
上記要件を満たさないと、いずれもvmx.shが途中で止まります。
検証した結果、
- ダミーのDefaultGatewayIPでもOKですが、DefaultGatewayIPが2つ以上設定されてるとNG
- eno1の代わりにbrインターフェースを指定したらvmx.shが途中で停止(bondは未検証ですが、イケるっぽい?です)
- eno2にeno1と同一SubnetのIPを設定してもvmx.shが途中で停止
vmx.shが停止するたびに、sshセッションが切れてしまい、IPMI(iLO)経由でホストOSのIP設定をやり直すことになります。
(IPMI無し環境であれば、D-Sub9ピン or KVM(キーボード・ビデオ・マウス)経由で頑張る?)
また、vMXは起動するたびにvmx.shを実行するのですが、毎回以下のようなインターフェース設定へと変更してくれます。
[root@ vmx]# ifconfig br-ext: flags=4163mtu 1500 inet 192.168.11.161 netmask 255.255.255.0 broadcast 192.168.11.255 ether 52:54:00:9f:a0:77 txqueuelen 0 (Ethernet) br-int-vmx01: flags=4163 mtu 1500 ether 52:54:00:27:d7:53 txqueuelen 0 (Ethernet) eno1: flags=4163 mtu 1500 inet6 fe80::ae16:2dff:febb:9ec0 prefixlen 64 scopeid 0x20 ether ac:16:2d:bb:9e:c0 txqueuelen 1000 (Ethernet) eno2: flags=4163 mtu 1500 inet 192.168.12.130 netmask 255.255.255.0 broadcast 192.168.12.255 inet6 fe80::ae16:2dff:febb:9ec1 prefixlen 64 scopeid 0x20 ether ac:16:2d:bb:9e:c1 txqueuelen 1000 (Ethernet) ens1f0: flags=4163 mtu 1500 ether a0:36:9f:3e:6d:68 txqueuelen 1000 (Ethernet) ens1f1: flags=4163 mtu 1500 ether a0:36:9f:3e:6d:6a txqueuelen 1000 (Ethernet) vcp-ext-vmx01: flags=4163 mtu 1500 inet6 fe80::fc00:ddff:fec0:de01 prefixlen 64 scopeid 0x20 ether fe:00:dd:c0:de:01 txqueuelen 500 (Ethernet) vcp-int-vmx01: flags=4163 mtu 1500 inet6 fe80::fc54:ff:fe2e:402b prefixlen 64 scopeid 0x20 ether fe:54:00:2e:40:2b txqueuelen 500 (Ethernet) vfp-ext-vmx01: flags=4163 mtu 1500 inet6 fe80::fc00:ddff:fec0:de11 prefixlen 64 scopeid 0x20 ether fe:00:dd:c0:de:11 txqueuelen 500 (Ethernet) vfp-int-vmx01: flags=4163 mtu 1500 inet6 fe80::fc54:ff:fe28:65a2 prefixlen 64 scopeid 0x20 ether fe:54:00:28:65:a2 txqueuelen 500 (Ethernet)
ここで怖いなと思ったことは、
- eno1がbr-extにバインド
- eno1のIPがbr-extに再アサイン
という動作がvmx.sh上で行われることです。
また、vMXを停止させると、br-extらが削除され元の状態に戻ります。
なので、私は先に記載したようなインターフェース設定で、vmx.shを走らせています。
ちなみに、eno1とeno2は同一VLANとし、sshクライアントPC側では192.168.12.0/24のIPをセカンダリとして設定しています。
4-6.注意点その2
SR-IOVの場合、#Interfacesの項で1PF1VFとしている点です。
本来のsriovであれば1つのPFに複数のVFが作成可能なため、
#Interfaces JUNOS_DEVICES: - interface : ge-0/0/0 port-speed-mbps : 10000 nic : ens1f0 mtu : 9198 virtual-function : 0 mac-address : "02:06:0A:0E:FF:E3" description : "ge-0/0/0 con to ens1f0vf0" - interface : ge-0/0/1 port-speed-mbps : 10000 nic : ens1f0 mtu : 9198 virtual-function : 1 mac-address : "02:06:0A:0E:FF:F3" description : "ge-0/0/1 con to ens1f0vf1"
としてもいいはずですが、vmx.shがエラーを吐いて止まります。
vMXのVer17系は1筐体に複数VMをサポートしていないためと思われます。
Ver18以降では1筐体に複数VMをサポートしていないとの記載が削除されているため、たぶん大丈夫なのでは?と考えています。
5.インストール
以下のコマンドでインストールします。
./vmx.sh -lvf --install --cfg config/vmx01.conf
virtioの場合は、confファイル名(vmx02.conf)を変えればOKです。
-lvfはDebug用なので一発でインストールできるようになったら外して構いませんが、最初はどこでvmx.shが停止するのかわからないので付けていて損はないと思います。
出力例は長いので以下のリンクにtxtファイルを貼り付けました。
SR-IOVの場合
virtioの場合
vmx.shが正常に終了すると、virshからでも確認できるようになります。
[root@c72x642 vmx]# virhsh list
Id Name State
----------------------------------------------------
1 vcp-vmx01 running
2 vfp-vmx01 running
3 vcp-vmx02 running
4 vfp-vmx02 running
vcpやvfpへの接続は、以下のようにvmx.shで実施可能です。
[root@ vmx]# .vmx./vmx.sh --console vfp vmx02 Login Console Port For vfp-vmx02 - 8602 Press Ctrl-] to exit anytime Trying ::1... telnet: connect to address ::1: Connection refused Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. Wind River Linux 6.0.0.13 vfp-vmx02 console vfp-vmx02 login: telnet> close Connection closed.
6.インターフェースのバインド設定:virtioの場合
SR-IOVの場合はインストール時にホストOSのインターフェースとバインドさせますが、
virtioの場合はインストール後、vMX起動中のままでも変更可能です。
そこで、まずはホストOS上にbrインターフェースを準備します。
ここでは例として、ens1f0にbr300とbr301を作成します。
nmcli connection add type bridge autoconnect yes con-name br300 ifname br300 nmcli connection modify br300 bridge.stp no nmcli connection modify br300 ipv4.method manual ipv4.address 192.168.30.130/24 nmcli connection up br300 nmcli connection add type vlan autoconnect yes con-name ens1f0.300 ifname ens1f0.300 dev ens1f0 id 300 nmcli connection modify ens1f0.300 connection.master br300 connection.slave-type bridge nmcli connection up ens1f0.300 nmcli connection add type bridge autoconnect yes con-name br301 ifname br301 nmcli connection modify br301 bridge.stp no nmcli connection modify br301 ipv4.method manual ipv4.address 192.168.31.130/24 nmcli connection up br301 nmcli connection add type vlan autoconnect yes con-name ens1f0.301 ifname ens1f0.301 dev ens1f0 id 301 nmcli connection modify ens1f0.301 connection.master br301 connection.slave-type bridge nmcli connection up ens1f0.301
次にbindファイルを作成します。
[root@ vmx]# vi config/bind01.conf ############################################################## # vmx-junos-dev.conf # - Config file for junos device bindings. # - Uses YAML syntax. # - Leave a space after ":" to specify the parameter value. # - For physical NIC, set the 'type' as 'host_dev' # - For junos devices, set the 'type' as 'junos_dev' and # set the mandatory parameter 'vm-name' to the name of # the vPFE where the device exists # - For bridge devices, set the 'type' as 'bridge_dev' ############################################################## interfaces : - link_name : vmx_link1 mtu : 1500 endpoint_1 : - type : junos_dev vm_name : vmx02 dev_name : ge-0/0/0 endpoint_2 : - type : bridge_dev dev_name : br300 - link_name : vmx_link2 mtu : 1500 endpoint_1 : - type : junos_dev vm_name : vmx02 dev_name : ge-0/0/1 endpoint_2 : - type : bridge_dev dev_name : br301
endpoint_1がvMX側のインターフェースで、endpoint_2がホストOS側のインターフェースとなります。
endpoint_2のtypeには、 host_dev, junos_devなども付けられます。
作成が終わったら、以下のコマンドでバインドさせます。
[root@ vmx]# ./vmx.sh --bind-dev --cfg config/bind01.conf Checking package ethtool..........................[OK] Bind Bridge port br300(ge-0.0.0-vmx02)............[OK] Bind Bridge port br301(ge-0.0.1-vmx02)............[OK]
今回はens1f0(X540やX520)にbr&vlanインターフェースを作成しましたが、これだとvMX側でVLANインターフェースを作りたい場合に困るので、ens1f0にVFを複数作成し、typeにhost_devを指定してバインドさせるのもアリだなと考えています。
7.最後に
vMXのインストールには本当に手こずりました。オンプレのこういう面が敬遠されがちなのでしょうか。。。
ただ、その一方でクラウドとの接続にはオンプレ環境が必要となる場面も出てくるため、バイモーダルITを念頭に、どっちも良いとこ取りができるようにしていこうと思っています。
また、仮想マシンのインストールにshを使い、しかもその中でドライバのコンパイルまで走らせるとは・・・という感じです。
大変よく作り込まれているなと思う反面、ドライバのヘッダファイル修正をしないとコンパイルが通らないという点については、もう少し作り込んで欲しいとも思います。
さらに、ルータを仮想化した旨みが失われないよう、他社の仮想マシンと共存させた場合のことも、考慮しないとダメな感じがしています。
というのも、Red Hat Virtualization 4.1からは、SR-IOVのVFにアタッチされた仮想マシンのライブマイグレーションが正式サポートされたので、可用性やメンテナンス性も加味した柔軟なネットワーク設計が重要になってくると考えているからです。