Metonymical Deflection

ゆるく日々のコト・たまにITインフラ

CentOS7 kickstartによるインストール

kickstartによるインストールのサンプルファイルをいくつかピックアップしてみたいと思います。

サンプルとしては以下3つ。

  • CentOS7上のKVMにminimalでインストール
  • CentOS7上のKVMにServerGUIでインストール
  • DL360G8上にCentOS7をServerGUIでインストール

これ以外にも応用はいくらでもできると思います。

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-2.qcow2ファイルの作成
qemu-img create -f qcow2 /var/lib/libvirt/images/c7623.qcow2 20G
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-2.qcow2ファイルの作成
qemu-img create -f qcow2 /var/lib/libvirt/images/c7625.qcow2 20G
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ファイルの作成

作業用PCのテキストエディタなどで作成してください。*1

#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.イメージファイルのセット

f:id:metonymical:20190721010844p:plain
上図のうち、以下のようにイメージファイルをセットします。

ImageFile RemovalMedhia ks.img
ImageFile CD-ROM/DVD CentOS-7-x86_64-DVD-1810.iso
3-3.起動オプションの設定とインストールの実行

f:id:metonymical:20190721011159p:plain
筐体を起動後、上図が表示されたら
Install CentOS 7を選択し、Tabキーを入力してください。
次に起動オプションの入力を促されるので、以下の通り入力してください。

inst.ks=hd:sdb:/ks.cfg

以下のようにインストールが始まれば、あとは待つだけです。
f:id:metonymical:20190721011458p:plain

以上です。

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.全体構成

f:id:metonymical:20190622154959p:plain
構成図上に(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.全体の流れ ~概要~
  1. Bridge作成:(1)
  2. Bonding:(2)
  3. Dockerコンテナをovsbr0にアタッチ:(12)
  4. 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-2.事前準備2:Dockerのインストール
curl -sSL https://get.docker.com/ | sh

最新のDcokerをインストールしています。

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

f:id:metonymical:20190622152119p:plain
以下の画面で各ポートの情報が確認できます。
f:id:metonymical:20190622152217p:plain
多数のコンテナを起動した際は見やすいのかなと思います。

以上です。

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の用途の違いかなと思っているので、あまり深入りはしませんでした。

Dockerコンテナのネットワーク設定方法

DockerコンテナのトラフィックをBridgeで外部ネットワークに流して使用する場合の設定方法を記載したいと思います。
Dockerで作成するBridge*1は、ホストOSのiptablesでPATされてしまうため、コンテナと外部NW機器が同一のNWセグメントとして使用できるようにします。

以下の過去記事のDcoker版と考えてください。
LXC/LXDコンテナのネットワーク設定方法 - Metonymical Deflection

なお、設定方法が2種類あります。先に1を記載した後、2を記載したいと思います。

No 設定方法 ホストOSとの疎通性 brctlやipコマンドでの確認可否
1 LinuxBridgeを併用 可能
2 dockerコマンドのみ使用(macvlan) 不可

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     : Minimal Install

ベアメタル環境でも同様に設定可能です。

1-2.全体構成

f:id:metonymical:20190616175355p:plain
上図のうちdocker0はDefaultで作成されています。
また、docker0はNATして外部ネットワークに接続されています。私の用途としては、コンテナ上でyumなどを行いたい場合のInternet接続用マネジメントインターフェースとして使用しています。*2

しかし、KVMライクにDockerコンテナを使用したいので、今回行う設定は(1)~(9)となります。
(1)(2)(5)(6)(7):nmcliコマンド
(3)(4)(8)(9):dockerコマンド
となります。

1-2.全体の流れ ~概要~
  • LinuxBridge併用の場合:(1)~(9)
  • dockerコマンドのみの場合:(3)(4)(8)(9)

 ※
 流れというよりも、それぞれ別々の設定となります。

1-3.全体の流れ ~コマンドのみ~

以下のコマンドを投入していきます。
やりたいことが既に決まっている方は、構成図とコマンドの内容を見るだけでもよいと思います。

1.LinuxBridge併用の場合
(1)
nmcli connection add type bridge autoconnect yes con-name br0 ifname br0
nmcli connection modify br0 bridge.stp no
nmcli connection modify br0 ipv6.method ignore
nmcli connection modify br0 ipv4.method manual ipv4.addresses 192.168.30.202/24
nmcli connection up br0
nmcli con show
brctl show

(2)
nmcli connection add type ethernet autoconnect yes con-name ens34 ifname ens34
nmcli connection modify ens34 connection.master br0 connection.slave-type bridge
nmcli connection up ens34
nmcli con show
brctl show

(3)
docker network create -d bridge \
--subnet=192.168.30.0/24 \
--ip-range=192.168.30.0/25 \
--gateway=192.168.30.202 \
--opt com.docker.network.bridge.name=br0 \
br0

(コンテナ起動)
docker run -itd \
--privileged \
--network bridge \
--name dkc1 \
centos \
/sbin/init

(4)
docker network connect br0 dkc1 \
--ip=192.168.30.100

(5)
nmcli connection add type bridge autoconnect yes con-name br301 ifname br301
nmcli connection modify br301 bridge.stp no
nmcli connection modify br301 ipv6.method ignore
nmcli connection modify br301 ipv4.method manual ipv4.addresses 192.168.31.202/24
nmcli connection up br301
nmcli con show
brctl show

(6)
nmcli connection add type vlan autoconnect yes con-name ens34.301 ifname ens34.301 dev ens34 id 301
nmcli con show
brctl show

(7)
nmcli connection modify ens34.301 connection.master br301 connection.slave-type bridge
nmcli connection up ens34.301
nmcli con show
brctl show

(8)
docker network create -d bridge \
--subnet=192.168.31.0/24 \
--ip-range=192.168.31.0/25 \
--gateway=192.168.31.202 \
--opt com.docker.network.bridge.name=br301 \
br301

(コンテナ起動)
docker run -itd \
--privileged \
--network bridge \
--name dkc2 \
centos \
/sbin/init

(9)
docker network connect br301 dkc2 \
--ip=192.168.31.100

2.dockerコマンドのみの場合
(3)
docker network create -d macvlan \
--subnet=192.168.30.0/24 \
--ip-range=192.168.30.0/25 \
--gateway=192.168.30.254 \
-o parent=ens34 br0

(コンテナ起動)
docker run -itd \
--privileged \
--network bridge \
--name dkc1 \
centos \
/sbin/init

(4)
docker network connect br0 dkc1 \
--ip=192.168.30.100

(8)
docker network create -d macvlan \
--subnet=192.168.31.0/24 \
--ip-range=192.168.31.0/25 \
--gateway=192.168.31.254 \
-o parent=ens34.301 br301

(コンテナ起動)
docker run -itd \
--privileged \
--network bridge \
--name dkc2 \
centos \
/sbin/init

(9)
docker network connect br301 dkc2 \
--ip=192.168.31.100

<コンテナ起動コマンドについて補足>
「--network bridge」について、Default定義NWとユーザ定義NWを2つ同時にアタッチしようとすると、以下のようにエラーで弾かれます。このため、まずはDefault定義NWを設定しています。

[root@c76dk01 ~]# docker run -itd \
> --privileged \
> --network bridge \
> --network br0 \
> --name dkc3 \
> c76 \
> /sbin/init
docker: conflicting options: cannot attach both user-defined and non-user-defined network-modes.
See 'docker run --help'.
[root@c76dk01 ~]#

2.LinuxBridge併用の場合

2-1.通常のBridge

nmcliコマンドによりBridgeインターフェースを作成し、コンテナのNICをLinuxBridgeにアタッチします。
(1)(2)Bridgeインターフェースbr0の作成+ens34をbr0にアタッチ
(3)dockerコマンドにてbr0を作成*3
(4)br0にコンテナdkc1のeth1をアタッチ+IP設定

(1)(2)Bridgeインターフェースbr0の作成+ens34をbr0にアタッチ
(1)と(2)は過去記事などを参照してください。

投入コマンド
(1)
nmcli connection add type bridge autoconnect yes con-name br0 ifname br0
nmcli connection modify br0 bridge.stp no
nmcli connection modify br0 ipv6.method ignore
nmcli connection modify br0 ipv4.method manual ipv4.addresses 192.168.30.202/24
nmcli connection up br0
nmcli con show
brctl show
(2)
nmcli connection add type ethernet autoconnect yes con-name ens34 ifname ens34
nmcli connection modify ens34 connection.master br0 connection.slave-type bridge
nmcli connection up ens34
nmcli con show
brctl show

出力例
以下のように出力されていればOKです。
[root@c76dk01 ~]# nmcli con show
NAME       UUID                                  TYPE      DEVICE
br0        5c7da373-af73-4cda-a420-7949eeb6974e  bridge    br0
docker0    227bbb74-0c07-447a-99ec-5f84c6bf61c0  bridge    docker0
ens33      2f7e32c0-adfd-41b1-9698-dff6406af75d  ethernet  ens33
ens34      2849b0b6-1c27-4293-81b3-a07068feb36c  ethernet  ens34

br0が作成され、物理インターフェースens34にもアタッチされます。

(3)dockerコマンドにてbr0を作成

投入コマンド
(3)
docker network create -d bridge \
--subnet=192.168.30.0/24 \
--ip-range=192.168.30.0/25 \
--gateway=192.168.30.202 \
--opt com.docker.network.bridge.name=br0 \
br0

出力例
[root@c76dk01 ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
ebc2a0612742        br0                 bridge              local
a6ae25cd104e        bridge              bridge              local
f51b9d166f07        host                host                local
d1023dacb10b        none                null                local

[root@c76dk01 ~]# docker network inspect br0
[
    {
        "Name": "br0",
        "Id": "ebc2a0612742e6b2529fde112c5b2cb465abb6d27fe8623c20b92c7242d573bb",
        "Created": "2019-06-16T18:22:29.649525689+09:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.30.0/24",
                    "IPRange": "192.168.30.0/25",
                    "Gateway": "192.168.30.202"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {
            "com.docker.network.bridge.name": "br0"
        },
        "Labels": {}
    }
]
docker network create -d bridge \ NWドライバにbridgeを選択。必須
--subnet=192.168.30.0/24 \ サブネットを定義。必須
--ip-range=192.168.30.0/25 \ DHCPで配布されるレンジを定義。任意
--gateway=192.168.30.202 \ GWアドレスを定義。任意。但し、設定しないと192.168.30.1が強制的に設定されます。また、nmcliコマンドで作成したbr0のIPも192.168.30.1に上書きされます。
--opt com.docker.network.bridge.name=br0 \ nmcliコマンドで作成したbr0にアタッチ。必須
br0 Docker上のNWの名前。必須。ですが任意の名前でOK。管理上nmcliコマンドで作成したbr0と名前を一致せています。


(4)br0にコンテナdkc1のeth1をアタッチ+IP設定
続いてコンテナを起動し、コンテナNICのeth1をbr0にアタッチさせます。

投入コマンド
(コンテナ起動)
docker run -itd \
--privileged \
--network bridge \
--name dkc1 \
centos \
/sbin/init

(4)
docker network connect br0 dkc1 \
--ip=192.168.30.100

出力例
[root@c76dk01 ~]# brctl show
bridge name     bridge id               STP enabled     interfaces
br0             8000.000c29d40546       no              ens34
                                                        veth41095a7
docker0         8000.0242f2b40eff       no              veth24c4ace

[root@c76dk01 ~]# docker network inspect br0
[
    {
        "Name": "br0",
        "Id": "e14f9d9ab5f236adee0bfbe95760272e3bfa5d0371804b1bb880164eb7b85c3f",
        "Created": "2019-06-16T18:44:09.13402567+09:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.30.0/24",
                    "IPRange": "192.168.30.0/25",
                    "Gateway": "192.168.30.202"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "b4ec13912196828e074ed21ab4a349afb93a816cf6788f563f36c9e0708a00a5": {
                "Name": "dkc1",
                "EndpointID": "3ddb6c7fd885c94d75d3e7bfbf37facc37778bffb01e7eeee02d42f790bba718",
                "MacAddress": "02:42:c0:a8:1e:64",
                "IPv4Address": "192.168.30.100/24",
                "IPv6Address": ""
            }
        },
        "Options": {
            "com.docker.network.bridge.name": "br0"
        },
        "Labels": {}
    }
]
2-2.VlanTagを付ける場合のBridge

nmcliコマンドによりVlan+Bridgeインターフェースを作成し、コンテナのNICをLinuxBridgeにアタッチします。
トラフィックがVlanインターフェースens34.301を通過する際に以下の挙動となります。

コンテナから外部NWへのトラフィック VlanTagが付けられる
外部NWからコンテナへのトラフィック VlanTagが外されたる

(5)(6)(7)Vlanインターフェースens34.301+Bridgeインターフェースbr301の作成+ens34.301をbr301にアタッチ
(8)dockerコマンドにてbr301を作成
(9)br301にコンテナdkc2のeth1をアタッチ+IP設定

(5)(6)(7)Vlanインターフェースens34.301+Bridgeインターフェースbr301の作成+ens34.301をbr301にアタッチ
(1)(2)と同様に過去記事などを参照してください。

投入コマンド
(5)
nmcli connection add type bridge autoconnect yes con-name br301 ifname br301
nmcli connection modify br301 bridge.stp no
nmcli connection modify br301 ipv6.method ignore
nmcli connection modify br301 ipv4.method manual ipv4.addresses 192.168.31.202/24
nmcli connection up br301
nmcli con show
brctl show

(6)
nmcli connection add type vlan autoconnect yes con-name ens34.301 ifname ens34.301 dev ens34 id 301
nmcli con show
brctl show

(7)
nmcli connection modify ens34.301 connection.master br301 connection.slave-type bridge
nmcli connection up ens34.301
nmcli con show
brctl show

出力例
以下のように出力されていればOKです。
[root@c76dk01 ~]# nmcli con show
NAME       UUID                                  TYPE      DEVICE
br0        5c7da373-af73-4cda-a420-7949eeb6974e  bridge    br0
br301      07f444fd-18d5-47a8-a721-39696d4fb0c6  bridge    br301
docker0    d3c2e742-6653-4d56-8b75-10d7f178fc41  bridge    docker0
ens33      2f7e32c0-adfd-41b1-9698-dff6406af75d  ethernet  ens33
ens34      2849b0b6-1c27-4293-81b3-a07068feb36c  ethernet  ens34
ens34.301  9e5eb500-f432-41fb-b72a-2492567a98c4  vlan      ens34.301

br301が作成され、VLANインターフェースens34.301にもアタッチされます。

(8)dockerコマンドにてbr301を作成

投入コマンド
(8)
docker network create -d bridge \
--subnet=192.168.31.0/24 \
--ip-range=192.168.31.0/25 \
--gateway=192.168.31.202 \
--opt com.docker.network.bridge.name=br301 \
br301

出力例
[root@c76dk01 ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
e14f9d9ab5f2        br0                 bridge              local
ce879f2b276f        br301               bridge              local
a6ae25cd104e        bridge              bridge              local
f51b9d166f07        host                host                local
d1023dacb10b        none                null                local

[root@c76dk01 ~]# docker network inspect br301
[
    {
        "Name": "br301",
        "Id": "ce879f2b276f71ca45f6f09b993d561f42b3297b40d2964b1518ef64280dfd0f",
        "Created": "2019-06-16T19:08:44.613109443+09:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.31.0/24",
                    "IPRange": "192.168.31.0/25",
                    "Gateway": "192.168.31.202"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {
            "com.docker.network.bridge.name": "br301"
        },
        "Labels": {}
    }
]
docker network create -d bridge \ NWドライバにbridgeを選択。必須
--subnet=192.168.31.0/24 \ サブネットを定義。必須
--ip-range=192.168.31.0/25 \ DHCPで配布されるレンジを定義。任意
--gateway=192.168.31.202 \ GWアドレスを定義。任意。但し、設定しないと192.168.31.1が強制的に設定されます。また、nmcliコマンドで作成したbr0のIPも192.168.31.1に上書きされます。
--opt com.docker.network.bridge.name=br301 \ nmcliコマンドで作成したbr301にアタッチ。必須
br301 Docker上のNWの名前。必須。ですが任意の名前でOK。管理上nmcliコマンドで作成したbr301と名前を一致せています。


(9)br301にコンテナdkc2のeth1をアタッチ+IP設定
続いてコンテナを起動し、コンテナNICのeth1をbr301にアタッチさせます。

投入コマンド
(コンテナ起動)
docker run -itd \
--privileged \
--network bridge \
--name dkc2 \
centos \
/sbin/init

(4)
docker network connect br301 dkc2 \
--ip=192.168.31.100

出力例
[root@c76dk01 ~]# brctl show
bridge name     bridge id               STP enabled     interfaces
br0             8000.000c29d40546       no              ens34
                                                        veth41095a7
br301           8000.000c29d40546       no              ens34.301
                                                        veth2d8f44e
docker0         8000.0242f2b40eff       no              veth24c4ace
                                                        veth2cc58e3

[root@c76dk01 ~]# docker network inspect br301
[
    {
        "Name": "br301",
        "Id": "ce879f2b276f71ca45f6f09b993d561f42b3297b40d2964b1518ef64280dfd0f",
        "Created": "2019-06-16T19:08:44.613109443+09:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.31.0/24",
                    "IPRange": "192.168.31.0/25",
                    "Gateway": "192.168.31.202"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "2ae29b5d870975ad25f86c674113ea4ef6db077f88c9de13c35d3b9f4dc94ecc": {
                "Name": "dkc2",
                "EndpointID": "0d46e4d5f92e68613096c8103714cf90fafde1ff3145c156cc6a9b76b66dc8fa",
                "MacAddress": "02:42:c0:a8:1f:64",
                "IPv4Address": "192.168.31.100/24",
                "IPv6Address": ""
            }
        },
        "Options": {
            "com.docker.network.bridge.name": "br301"
        },
        "Labels": {}
    }
]

以上がLinuxBridge併用の場合となります。

3.dockerコマンドのみの場合

作業工程としては、LinuxBridgeを併用する場合よりもシンプルかつ工程が少ないのでわかりやすいかもしれません。
しかし、ホストOS上では、MACアドレステーブルやarpテーブルの確認が不可能っぽいです。*4
かつ、ホストOSとの疎通性はありません。*5
なお、本項を試す場合は、前項までに作成したコンテナやBridge など*6は全て削除しておいてください。

3-1.通常のBridge

dockerコマンドによりBridgeネットワークを作成し、ens34にアタッチします。
(3)dockerコマンドにてbr0を作成
(4)br0にコンテナdkc1のeth1をアタッチ+IP設定

(3)dockerコマンドにてbr0を作成

投入コマンド
(3)
docker network create -d macvlan \
--subnet=192.168.30.0/24 \
--ip-range=192.168.30.0/25 \
--gateway=192.168.30.254 \
-o parent=ens34 br0

出力例
以下のように出力されていればOKです。
[root@c76dk01 ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
92bc5bdf05b4        br0                 macvlan             local
a6ae25cd104e        bridge              bridge              local
f51b9d166f07        host                host                local
d1023dacb10b        none                null                local
docker network create -d macvlan \ NWドライバにmacvlanを指定。必須
--subnet=192.168.30.0/24 \ 2.LinuxBridge併用の場合と同様
--ip-range=192.168.30.0/25 \ 2.LinuxBridge併用の場合と同様
--gateway=192.168.30.254 \ 2.LinuxBridge併用の場合と同様
-o parent=ens34 br0 ens34にアタッチ。必須。名前は2.LinuxBridge併用の場合と同様に任意の名前でOKです。


(4)br0にコンテナdkc1のeth1をアタッチ+IP設定

投入コマンド
(コンテナ起動)
docker run -itd \
--privileged \
--network bridge \
--name dkc1 \
centos \
/sbin/init

(4)
docker network connect br0 dkc1 \
--ip=192.168.30.100

出力例
[root@c76dk01 ~]# docker network inspect br0
[
    {
        "Name": "br0",
        "Id": "92bc5bdf05b4371123b3562325260de03ad2133a63ee6f50a4380bd1bbeeb220",
        "Created": "2019-06-16T19:27:48.575931685+09:00",
        "Scope": "local",
        "Driver": "macvlan",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.30.0/24",
                    "IPRange": "192.168.30.0/25",
                    "Gateway": "192.168.30.254"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "a86cfcb7c7729c2f5aa0ad1c5cbae1a84229328a1342d5670a7e3eb6159c5f39": {
                "Name": "dkc1",
                "EndpointID": "cbfdff9a7d5fd97cabc408c2a2bbb5766c0192c989952997ab09996e6ba3696c",
                "MacAddress": "02:42:c0:a8:1e:64",
                "IPv4Address": "192.168.30.100/24",
                "IPv6Address": ""
            }
        },
        "Options": {
            "parent": "ens34"
        },
        "Labels": {}
    }
]
3-2.VlanTagを付ける場合のBridge

dockerコマンドによりBridgeネットワークとVlanインターフェースを作成し、ens34.301にアタッチします。
(8)dockerコマンドにてbr301とens34.301を作成
(9)br301にコンテナdkc2のeth1をアタッチ+IP設定

dockerコマンドにてbr301とens34.301を作成

投入コマンド
(8)
docker network create -d macvlan \
--subnet=192.168.31.0/24 \
--ip-range=192.168.31.0/25 \
--gateway=192.168.31.254 \
-o parent=ens34.301 br301

出力例
以下のように出力されていればOKです。
[root@c76dk01 ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
92bc5bdf05b4        br0                 macvlan             local
8dd7d4bfec8c        br301               macvlan             local
a6ae25cd104e        bridge              bridge              local
f51b9d166f07        host                host                local
d1023dacb10b        none                null                local
docker network create -d macvlan \ NWドライバにmacvlanを指定。必須
--subnet=192.168.31.0/24 \ 2.LinuxBridge併用の場合と同様
--ip-range=192.168.31.0/25 \ 2.LinuxBridge併用の場合と同様
--gateway=192.168.31.254 \ 2.LinuxBridge併用の場合と同様
-o parent=ens34.301 br301 ens34.301とbr301を作成。*7br301をens34.301にアタッチ。必須。名前は2.LinuxBridge併用の場合と同様に任意の名前でOKです。

(9)br301にコンテナdkc2のeth1をアタッチ+IP設定

投入コマンド
(コンテナ起動)
docker run -itd \
--privileged \
--network bridge \
--name dkc2 \
centos \
/sbin/init

(9)
docker network connect br301 dkc2 \
--ip=192.168.31.100

出力例
[root@c76dk01 ~]# docker network inspect br301
[
    {
        "Name": "br301",
        "Id": "8dd7d4bfec8c0717acec3b40bc7cdf3d49ced0e2a2ac0a737d094f1ada2eec8c",
        "Created": "2019-06-16T19:28:00.783746421+09:00",
        "Scope": "local",
        "Driver": "macvlan",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.31.0/24",
                    "IPRange": "192.168.31.0/25",
                    "Gateway": "192.168.31.254"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "9a193996a6928474d792f88b9b72f21fbe8f4b46cd973e8ad2ba39b97d4adcaa": {
                "Name": "dkc2",
                "EndpointID": "279d95c111a3b33a7f8872966d15bd5af5251a4e25d46e31a64772a6930cb1e5",
                "MacAddress": "02:42:c0:a8:1f:64",
                "IPv4Address": "192.168.31.100/24",
                "IPv6Address": ""
            }
        },
        "Options": {
            "parent": "ens34.301"
        },
        "Labels": {}
    }
]

以上です。

4.最後に

以下のサイトを参考にさせて頂きました。
Use macvlan networks | Docker Documentation
macvlan_ipvlan_driver_notes.md · GitHub
外部ネットワーク側からDockerコンテナに通信できる環境を作成する - Qiita

今回の設定方法以外にも「DOCKER_OPTS=」のオプションを設定することでできるようです。

当然ながらDockerは多くのDocに恵まれているため、さほど苦労することなく、やりたい事ができるようになりました。
ただ、今回ご紹介した2種類の方法が同時に記載されているサイトは少なかったことや、過去記事からの延長として、LinuxBridgeやLXC/LXDとの比較ができるという点で、まとめた方が良いなと感じたため記載しました。

私の本職はNWエンジニアなので、最下層レイヤから上位層レイヤに昇っていく過程で、必要になりそうなポイントをクローズアップしながら記載していければいいなと考えています。
また、この流れが出来てしまったので、当然ですが、SR-IOVやDPDK、OvSによるDockerネットワークの設定方法なども、まとめられたらいいなと思います。
さらに、k8sのネットワーク周りまで踏み込んだり、OpenStackNeutron+OVNにも広げていけたら面白うそうだと考えていますので、ご期待ください。

*1:docker network create -d bridgeコマンドで作るBridgeのことです

*2:Dockerの場合はLXCとは異なり、コンテナ起動後にあまりyumなどを実行することはないと思いますが。

*3:作成というよりも、LinuxBridgeにアタッチするとか関連付けをすると言った方が良いかもしれません。

*4:RESTを使えばGETできるかもしれません

*5:トラブった際が少し不安ですね。

*6:nmcliコマンドによるBridge やVLANインターフェース、dockerコマンドによるNW設定やコンテナ

*7:-o parent=ens34.301と指定しただけで、VLANインターフェースを作成してくれるため、かなり楽です。

freeDiameterのビルドとインストール

CentOS6によるfree Daimeterのビルドとインストール方法について記載しました。
PCEFとPCRFの双方を構築しGxインターフェースの動きを確認します。

1.構成

1-1.環境
HostOS                           : Windows10pro Ver:1809 Build:17763.503
VMWare              : VMware(R) Workstation 15 Pro 15.1.0 build-13591040  
GuestOS              : CentOS6.10
Installed Environment Groups     : minimal
Kernel              : 2.6.32-754

上記GuestOS上でPCEFとPCRFを稼働させます。*1

1-2.構成概要

f:id:metonymical:20190608140611p:plain

1-3.全体の流れ

事前準備
ビルド&インストール
CAの構築
PCEFの設定
PCRFの設定
動作確認

2.事前準備

必要となるアプリなどのインストール

yum -y install gcc gcc-c++ cmake make flex bison lksctp-tools-devel gnutls-devel libidn-devel openssl libgcrypt-devel wget git

3.ビルド&インストール

freeDiameterのインストールを行います。

mkdir tmp
cd /root/tmp
wget http://www.freediameter.net/hg/freeDiameter/archive/1.2.0.tar.gz
tar zxvf 1.2.0.tar.gz
cd /root/tmp/freeDiameter-1.2.0
mkdir build
cd /root/tmp/freeDiameter-1.2.0/build

任意のPathにfreedaimeterのソースをDL
解凍後、ビルド用ディレクトリを作成してcd

cmake -D CMAKE_INSTALL_PREFIX:PATH=/opt/freeDiameter ..
make && make install

makeファイル作成後、ビルド&インストール

多少時間は掛かりますが、最後の方は以下のように出力されれば正常にインストールが完了しています。

cmake後の出力例
-- Generating done
-- Build files have been written to: /root/tmp/freeDiameter-1.2.0/build

make install後の出力例
-- Installing: /opt/freeDiameter/lib/freeDiameter/dict_nasreq.fdx
-- Installing: /opt/freeDiameter/lib/freeDiameter/dict_eap.fdx
-- Installing: /opt/freeDiameter/lib/freeDiameter/dict_dcca.fdx
-- Installing: /opt/freeDiameter/lib/freeDiameter/dict_dcca_3gpp.fdx
-- Installing: /opt/freeDiameter/lib/freeDiameter/dict_dcca_starent.fdx
-- Installing: /opt/freeDiameter/lib/freeDiameter/dict_sip.fdx
-- Installing: /opt/freeDiameter/lib/freeDiameter/dict_mip6a.fdx
-- Installing: /opt/freeDiameter/lib/freeDiameter/dict_mip6i.fdx
-- Installing: /opt/freeDiameter/lib/freeDiameter/dict_nas_mipv6.fdx
-- Installing: /opt/freeDiameter/lib/freeDiameter/dict_rfc5777.fdx
-- Installing: /opt/freeDiameter/lib/freeDiameter/rt_default.fdx
-- Installing: /opt/freeDiameter/lib/freeDiameter/rt_redirect.fdx
-- Installing: /opt/freeDiameter/lib/freeDiameter/rt_busypeers.fdx
-- Installing: /opt/freeDiameter/lib/freeDiameter/rt_ignore_dh.fdx
-- Installing: /opt/freeDiameter/lib/freeDiameter/rt_load_balance.fdx
-- Installing: /opt/freeDiameter/lib/freeDiameter/acl_wl.fdx
-- Installing: /opt/freeDiameter/lib/freeDiameter/dbg_monitor.fdx
-- Installing: /opt/freeDiameter/lib/freeDiameter/dbg_msg_timings.fdx
-- Installing: /opt/freeDiameter/lib/freeDiameter/dbg_msg_dumps.fdx
-- Installing: /opt/freeDiameter/lib/freeDiameter/dbg_rt.fdx

4.CAの構築

freedaimeterは互いに証明書を使用して認証するためCAを構築します。

4-1.CAの構築前準備1
vi /etc/pki/tls/openssl.cnf

以下を修正
[ CA_default ]

#dir             = /etc/pki/CA           # Where everything is kept
dir             = .
4-2.CAの構築前準備2
mkdir -p /opt/CA
cd /opt/CA
mkdir certs private newcerts
echo '01' > serial
touch index.txt

ディレクトリ作成後にcd
各種ディレクトリ作成
シリアルファイル作成
indexファイル作成

4-3.CAの構築
openssl req -new -x509 -newkey rsa:512 -out cacert.pem -keyout private/cakey-pass.pem
openssl rsa < private/cakey-pass.pem > private/cakey.pem

CA証明書の作成
CA証明書の鍵からパスフレーズの除外

以下出力例

[root@c610diam01 CA]# openssl req -new -x509 -newkey rsa:512 -out cacert.pem -keyout private/cakey-pass.pem
Generating a 512 bit RSA private key
.++++++++++++
..++++++++++++
writing new private key to 'private/cakey-pass.pem'
Enter PEM pass phrase: 任意のパスワードを入力
Verifying - Enter PEM pass phrase: 任意のパスワードを入力
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:JP
State or Province Name (full name) :Tokyo
Locality Name (eg, city) [Default City]:Minato-ku
Organization Name (eg, company) [Default Company Ltd]:local.jp
Organizational Unit Name (eg, section) :  空Enter
Common Name (eg, your name or your server's hostname) : ca.local.jp
Email Address :  空Enter

[root@c610diam01 CA]# openssl rsa < private/cakey-pass.pem > private/cakey.pem
Enter pass phrase: 上記のパスワードを入力
writing RSA key

5.PCEFの設定

5-1.PCEF用の証明書発行
cd /opt/CA
openssl req -new -newkey rsa:512 -keyout private/c610diam01-pass.key -out private/c610diam01.csr
openssl rsa < private/c610diam01-pass.key > private/c610diam01.key
openssl ca -in private/c610diam01.csr -out newcerts/c610diam01.crt

PCEF用CSR&鍵の作成
鍵からパスフレーズの除外
PCEF用CSRに署名

以下、出力例

[root@c610diam01 CA]# openssl req -new -newkey rsa:512 -keyout private/c610diam01-pass.key -out private/c610diam01.csr
Generating a 512 bit RSA private key
.++++++++++++
...........++++++++++++
writing new private key to 'private/c610diam01-pass.key'
Enter PEM pass phrase: 任意のパスワードを入力
Verifying - Enter PEM pass phrase: 任意のパスワードを入力
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:JP
State or Province Name (full name) :Tokyo
Locality Name (eg, city) [Default City]:Minato-ku
Organization Name (eg, company) [Default Company Ltd]:local.jp
Organizational Unit Name (eg, section) :  空Enter
Common Name (eg, your name or your server's hostname) :c610diam01.local.jp
Email Address :  空Enter

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password :  空Enter
An optional company name :  空Enter

[root@c610diam01 CA]# openssl rsa < private/c610diam01-pass.key > private/c610diam01.key
Enter pass phrase: 上記のパスワードを入力
writing RSA key

[root@c610diam01 CA]# openssl ca -in private/c610diam01.csr -out newcerts/c610diam01.crt
Using configuration from /etc/pki/tls/openssl.cnf
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 1 (0x1)
        Validity
            Not Before: Jun  8 02:41:08 2019 GMT
            Not After : Jun  7 02:41:08 2020 GMT
        Subject:
            countryName               = JP
            stateOrProvinceName       = Tokyo
            organizationName          = local.jp
            commonName                = c610diam01.local.jp
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            Netscape Comment:
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier:
                60:37:2C:A4:B6:7F:49:1D:A6:4C:22:D3:BE:BC:7F:88:1D:D4:D6:0C
            X509v3 Authority Key Identifier:
                keyid:8F:0F:1D:B8:82:F6:9F:84:26:2B:95:56:C5:7C:16:EB:55:F6:4E:DF

Certificate is to be certified until Jun  7 02:41:08 2020 GMT (365 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
5-2.PCEF用拡張モジュールの追加
cd /root/tmp
git clone https://github.com/kamome-e/fd_extensions.git
cd /root/tmp/fd_extensions/bin/
tar zxvf pcef.tar.gz
cd /root/tmp/fd_extensions/bin/pcef/
cp -p app_pcef.fdx dict_gx.fdx /opt/freeDiameter/lib/freeDiameter/
cp pcef-ctl.sh /opt/freeDiameter/bin/

任意のディレクトリ作成
git clone後にcd
解凍後にcd
fdx(拡張モジュール)ファイルのコピー
shファイルのコピー

5-3.freeDaimeter.confの設定
mkdir /opt/freeDiameter/etc
cd /opt/freeDiameter/etc/
vi freeDiameter.conf

#freeDiameter.conf

Identity =              "c610diam01.local.jp";
Realm =                 "local.jp";
TcTimer =               30;
TwTimer =               30;
AppServThreads =        4;

Port =                  3868;
SecPort =               5868;
SCTP_streams =          30;
ListenOn =              "0.0.0.0";

TLS_Cred =              "/opt/CA/newcerts/c610diam01.crt", "/opt/CA/private/c610diam01.key";
TLS_CA =                "/opt/CA/cacert.pem";

LoadExtension =         "/opt/freeDiameter/lib/freeDiameter/dict_nasreq.fdx";
LoadExtension =         "/opt/freeDiameter/lib/freeDiameter/dict_gx.fdx";
LoadExtension =         "/opt/freeDiameter/lib/freeDiameter/app_pcef.fdx" : "/opt/freeDiameter/etc/app_pcef.conf";

ConnectPeer =           "c610diam02.local.jp"{NO_TLS; No_SCTP; };

<補足>
最終行の

No_SCTP;

について。
本当はSCTPでやり取りしている様をPcapしたかったもののライブラリへのリンクが上手くいってないようでエラーが出力されたため、泣く泣く設定を入れました。*2

5-4.pcef.confの設定

destination_realmのみ変更してください。

cd /root/tmp/fd_extensions/bin/pcef/
cp -p app_pcef.conf /opt/freeDiameter/etc/
vi /opt/freeDiameter/etc/app_pcef.conf

signal = 10;
work_dir = "/tmp/freeDiameter";
destination_realm = "local.jp";
imsi = "017635273633";
default_charging_rule_name = "default-policy";
5-5.PCEF起動確認
export LD_LIBRARY_PATH=/opt/freeDiameter/lib
/opt/freeDiameter/bin/freeDiameterd -c /opt/freeDiameter/etc/freeDiameter.conf

以下出力例です。

[root@c610diam01 pcef]# /opt/freeDiameter/bin/freeDiameterd -c /opt/freeDiameter/etc/freeDiameter.conf
06/08/19,11:52:45.172063  NOTI   libfdproto '1.2.0' initialized.
06/08/19,11:52:45.173929  NOTI   libgnutls '2.12.23' initialized.
06/08/19,11:52:45.174303  NOTI   libfdcore '1.2.0' initialized.
06/08/19,11:52:45.316111  NOTI   All extensions loaded.
06/08/19,11:52:45.316133  NOTI   freeDiameter configuration:
06/08/19,11:52:45.316136  NOTI     Default trace level .... : +3
06/08/19,11:52:45.316138  NOTI     Configuration file ..... : /opt/freeDiameter/etc/freeDiameter.conf
06/08/19,11:52:45.316140  NOTI     Diameter Identity ...... : c610diam01.local.jp (l:19)
06/08/19,11:52:45.316142  NOTI     Diameter Realm ......... : local.jp (l:8)
06/08/19,11:52:45.316144  NOTI     Tc Timer ............... : 30
06/08/19,11:52:45.316146  NOTI     Tw Timer ............... : 30
06/08/19,11:52:45.316148  NOTI     Local port ............. : 3868
06/08/19,11:52:45.316150  NOTI     Local secure port ...... : 5868
06/08/19,11:52:45.316152  NOTI     Number of SCTP streams . : 30
06/08/19,11:52:45.316154  NOTI     Number of clients thr .. : 5
06/08/19,11:52:45.316156  NOTI     Number of app threads .. : 4
06/08/19,11:52:45.316158  NOTI     Local endpoints ........ : Default (use all available)
06/08/19,11:52:45.316160  NOTI     Local applications ..... : App: 16777238,AuAc,Vnd:0
06/08/19,11:52:45.316162  NOTI     Flags : - IP ........... : Enabled
06/08/19,11:52:45.316164  NOTI             - IPv6 ......... : Enabled
06/08/19,11:52:45.316184  NOTI             - Relay app .... : Enabled
06/08/19,11:52:45.316187  NOTI             - TCP .......... : Enabled
06/08/19,11:52:45.316189  NOTI             - SCTP ......... : Enabled
06/08/19,11:52:45.316191  NOTI             - Pref. proto .. : SCTP
06/08/19,11:52:45.316193  NOTI             - TLS method ... : Separate port
06/08/19,11:52:45.316195  NOTI     TLS :   - Certificate .. : /opt/CA/newcerts/c610diam01.crt
06/08/19,11:52:45.316197  NOTI             - Private key .. : /opt/CA/private/c610diam01.key
06/08/19,11:52:45.316199  NOTI             - CA (trust) ... : /opt/CA/cacert.pem (1 certs)
06/08/19,11:52:45.316201  NOTI             - CRL .......... : (none)
06/08/19,11:52:45.316203  NOTI             - Priority ..... : (default: 'NORMAL')
06/08/19,11:52:45.316205  NOTI             - DH bits ...... : 1024
06/08/19,11:52:45.316207  NOTI     Origin-State-Id ........ : 1559962365
06/08/19,11:52:45.316211  NOTI   Loaded extensions: '/opt/freeDiameter/lib/freeDiameter/dict_nasreq.fdx'[(no config file)], loaded
06/08/19,11:52:45.316213  NOTI   Loaded extensions: '/opt/freeDiameter/lib/freeDiameter/dict_gx.fdx'[(no config file)], loaded
06/08/19,11:52:45.316215  NOTI   Loaded extensions: '/opt/freeDiameter/lib/freeDiameter/app_pcef.fdx'[/opt/freeDiameter/etc/app_pcef.conf], loaded
06/08/19,11:52:45.316219  NOTI   {signal:10}'app_pcef'->0x7f2921bcfa20
06/08/19,11:52:45.342450  NOTI   Local server address(es): 192.168.11.161{---L-}        192.168.30.161{---L-}
06/08/19,11:52:45.342506  NOTI   freeDiameterd daemon initialized.

6.PCRFの設定

6-1.PCRF用の証明書発行
cd /opt/CA
openssl req -new -newkey rsa:512 -keyout private/c610diam02-pass.key -out private/c610diam02.csr
openssl rsa < private/c610diam02-pass.key > private/c610diam02.key
openssl ca -in private/c610diam02.csr -out newcerts/c610diam02.crt

PCRF用CSR&鍵の作成
鍵からパスフレーズの除外
PCRF用CSRに署名

以下、出力例

[root@c610diam02 CA]# openssl req -new -newkey rsa:512 -keyout private/c610diam02-pass.key -out private/c610diam02.csr
Generating a 512 bit RSA private key
.....++++++++++++
...............................++++++++++++
writing new private key to 'private/c610diam02-pass.key'
Enter PEM pass phrase: 任意のパスワードを入力
Verifying - Enter PEM pass phrase: 任意のパスワードを入力
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:JP
State or Province Name (full name) :Tokyo
Locality Name (eg, city) [Default City]:Minato-ku
Organization Name (eg, company) [Default Company Ltd]:local.jp
Organizational Unit Name (eg, section) :  空Enter
Common Name (eg, your name or your server's hostname) :c610diam02.local.jp
Email Address :  空Enter

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password :  空Enter
An optional company name :  空Enter

[root@c610diam02 CA]# openssl rsa < private/c610diam02-pass.key > private/c610diam02.key
Enter pass phrase: 上記のパスワードを入力
writing RSA key

[root@c610diam02 CA]# openssl ca -in private/c610diam02.csr -out newcerts/c610diam02.crt
Using configuration from /etc/pki/tls/openssl.cnf
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 2 (0x2)
        Validity
            Not Before: Jun  8 02:58:22 2019 GMT
            Not After : Jun  7 02:58:22 2020 GMT
        Subject:
            countryName               = JP
            stateOrProvinceName       = Tokyo
            organizationName          = local.jp
            commonName                = c610diam02.local.jp
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            Netscape Comment:
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier:
                58:48:A9:29:C0:63:60:17:EA:79:49:ED:3C:62:71:69:3C:E1:9D:92
            X509v3 Authority Key Identifier:
                keyid:8F:0F:1D:B8:82:F6:9F:84:26:2B:95:56:C5:7C:16:EB:55:F6:4E:DF

Certificate is to be certified until Jun  7 02:58:22 2020 GMT (365 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
6-2.PCRF用拡張モジュールの追加
cd /root/tmp/fd_extensions/bin/
tar zxvf pcrf.tar.gz
cd /root/tmp/fd_extensions/bin/pcrf/
cp -p app_pcrf.fdx dict_gx.fdx /opt/freeDiameter/lib/freeDiameter/

cd後にpcrfのtarファイル解凍
cd後にコピー*3

6-3.freeDaimeter.confの設定
vi /opt/freeDiameter/etc/freeDiameter.conf

[root@c610diam02 ~]# vi /opt/freeDiameter/etc/freeDiameter.conf
#freeDiameter.conf

Identity =              "c610diam02.local.jp";
Realm =                 "local.jp";
TcTimer =               30;
TwTimer =               30;
AppServThreads =        4;

Port =                  3868;
SecPort =               5868;
SCTP_streams =          30;
ListenOn =              "0.0.0.0";

TLS_Cred =              "/opt/CA/newcerts/c610diam02.crt", "/opt/CA/private/c610diam02.key";
TLS_CA =                "/opt/CA/cacert.pem";

LoadExtension =         "/opt/freeDiameter/lib/freeDiameter/dict_nasreq.fdx";
LoadExtension =         "/opt/freeDiameter/lib/freeDiameter/dict_gx.fdx";
LoadExtension =         "/opt/freeDiameter/lib/freeDiameter/app_pcrf.fdx" : "/opt/freeDiameter/etc/app_pcrf.conf";

ConnectPeer =           "c610diam01.local.jp"{NO_TLS; No_SCTP; };
6-4.pcrf.confの設定

特に変更する箇所はありません。

cd /root/tmp/fd_extensions/bin/pcrf/
cp app_pcrf.conf /opt/freeDiameter/etc/
vi /opt/freeDiameter/etc/app_pcrf.conf

[root@c610diam02 pcrf]# vi /opt/freeDiameter/etc/app_pcrf.conf

monitoring_key = "test-monitoring-key";
initial_charging_rule_name = "high-speed-policy";
restricted_charging_rule_name = "low-speed-policy";
total_octets_threshold = 20;
input_octets_threshold = 10;
output_octets_threshold = 10;
6-5.PCRF起動確認
export LD_LIBRARY_PATH=/opt/freeDiameter/lib
/opt/freeDiameter/bin/freeDiameterd -c /opt/freeDiameter/etc/freeDiameter.conf

以下、出力例です。

[root@c610diam02 pcrf]# /opt/freeDiameter/bin/freeDiameterd -c /opt/freeDiameter/etc/freeDiameter.conf
06/08/19,12:04:05.801044  NOTI   libfdproto '1.2.0' initialized.
06/08/19,12:04:05.801570  NOTI   libgnutls '2.12.23' initialized.
06/08/19,12:04:05.801772  NOTI   libfdcore '1.2.0' initialized.
06/08/19,12:04:05.911066  NOTI   All extensions loaded.
06/08/19,12:04:05.911114  NOTI   freeDiameter configuration:
06/08/19,12:04:05.911120  NOTI     Default trace level .... : +3
06/08/19,12:04:05.911122  NOTI     Configuration file ..... : /opt/freeDiameter/etc/freeDiameter.conf
06/08/19,12:04:05.911124  NOTI     Diameter Identity ...... : c610diam02.local.jp (l:19)
06/08/19,12:04:05.911126  NOTI     Diameter Realm ......... : local.jp (l:8)
06/08/19,12:04:05.911128  NOTI     Tc Timer ............... : 30
06/08/19,12:04:05.911130  NOTI     Tw Timer ............... : 30
06/08/19,12:04:05.911132  NOTI     Local port ............. : 3868
06/08/19,12:04:05.911134  NOTI     Local secure port ...... : 5868
06/08/19,12:04:05.911136  NOTI     Number of SCTP streams . : 30
06/08/19,12:04:05.911138  NOTI     Number of clients thr .. : 5
06/08/19,12:04:05.911140  NOTI     Number of app threads .. : 4
06/08/19,12:04:05.911142  NOTI     Local endpoints ........ : Default (use all available)
06/08/19,12:04:05.911144  NOTI     Local applications ..... : App: 16777238,AuAc,Vnd:0
06/08/19,12:04:05.911147  NOTI     Flags : - IP ........... : Enabled
06/08/19,12:04:05.911149  NOTI             - IPv6 ......... : Enabled
06/08/19,12:04:05.911151  NOTI             - Relay app .... : Enabled
06/08/19,12:04:05.911153  NOTI             - TCP .......... : Enabled
06/08/19,12:04:05.911155  NOTI             - SCTP ......... : Enabled
06/08/19,12:04:05.911157  NOTI             - Pref. proto .. : SCTP
06/08/19,12:04:05.911159  NOTI             - TLS method ... : Separate port
06/08/19,12:04:05.911161  NOTI     TLS :   - Certificate .. : /opt/CA/newcerts/c610diam02.crt
06/08/19,12:04:05.911163  NOTI             - Private key .. : /opt/CA/private/c610diam02.key
06/08/19,12:04:05.911165  NOTI             - CA (trust) ... : /opt/CA/cacert.pem (1 certs)
06/08/19,12:04:05.911168  NOTI             - CRL .......... : (none)
06/08/19,12:04:05.911170  NOTI             - Priority ..... : (default: 'NORMAL')
06/08/19,12:04:05.911172  NOTI             - DH bits ...... : 1024
06/08/19,12:04:05.911174  NOTI     Origin-State-Id ........ : 1559963045
06/08/19,12:04:05.911178  NOTI   Loaded extensions: '/opt/freeDiameter/lib/freeDiameter/dict_nasreq.fdx'[(no config file)], loaded
06/08/19,12:04:05.911180  NOTI   Loaded extensions: '/opt/freeDiameter/lib/freeDiameter/dict_gx.fdx'[(no config file)], loaded
06/08/19,12:04:05.911182  NOTI   Loaded extensions: '/opt/freeDiameter/lib/freeDiameter/app_pcrf.fdx'[/opt/freeDiameter/etc/app_pcrf.conf], loaded
06/08/19,12:04:05.938652  NOTI   Local server address(es): 192.168.11.162{---L-}        192.168.30.162{---L-}
06/08/19,12:04:05.938693  NOTI   freeDiameterd daemon initialized.

既にPCEFが起動中であれば、接続が開始されると思いますが、上記の出力例はPCEFが起動していない状態での出力となります。

7.動作確認

7-1.PCRF起動
[root@c610diam02 ~]# /opt/freeDiameter/bin/freeDiameterd -c /opt/freeDiameter/etc/freeDiameter.conf
06/08/19,12:08:49.011248  NOTI   libfdproto '1.2.0' initialized.
06/08/19,12:08:49.011937  NOTI   libgnutls '2.12.23' initialized.
06/08/19,12:08:49.012197  NOTI   libfdcore '1.2.0' initialized.
06/08/19,12:08:49.114938  NOTI   All extensions loaded.
06/08/19,12:08:49.114959  NOTI   freeDiameter configuration:
06/08/19,12:08:49.114963  NOTI     Default trace level .... : +3
06/08/19,12:08:49.114965  NOTI     Configuration file ..... : /opt/freeDiameter/etc/freeDiameter.conf
06/08/19,12:08:49.114967  NOTI     Diameter Identity ...... : c610diam02.local.jp (l:19)
06/08/19,12:08:49.114969  NOTI     Diameter Realm ......... : local.jp (l:8)
06/08/19,12:08:49.114971  NOTI     Tc Timer ............... : 30
06/08/19,12:08:49.114973  NOTI     Tw Timer ............... : 30
06/08/19,12:08:49.114975  NOTI     Local port ............. : 3868
06/08/19,12:08:49.114977  NOTI     Local secure port ...... : 5868
06/08/19,12:08:49.114979  NOTI     Number of SCTP streams . : 30
06/08/19,12:08:49.114981  NOTI     Number of clients thr .. : 5
06/08/19,12:08:49.114983  NOTI     Number of app threads .. : 4
06/08/19,12:08:49.114985  NOTI     Local endpoints ........ : Default (use all available)
06/08/19,12:08:49.114987  NOTI     Local applications ..... : App: 16777238,AuAc,Vnd:0
06/08/19,12:08:49.114989  NOTI     Flags : - IP ........... : Enabled
06/08/19,12:08:49.114991  NOTI             - IPv6 ......... : Enabled
06/08/19,12:08:49.114993  NOTI             - Relay app .... : Enabled
06/08/19,12:08:49.114995  NOTI             - TCP .......... : Enabled
06/08/19,12:08:49.114997  NOTI             - SCTP ......... : Enabled
06/08/19,12:08:49.114999  NOTI             - Pref. proto .. : SCTP
06/08/19,12:08:49.115001  NOTI             - TLS method ... : Separate port
06/08/19,12:08:49.115003  NOTI     TLS :   - Certificate .. : /opt/CA/newcerts/c610diam02.crt
06/08/19,12:08:49.115005  NOTI             - Private key .. : /opt/CA/private/c610diam02.key
06/08/19,12:08:49.115007  NOTI             - CA (trust) ... : /opt/CA/cacert.pem (1 certs)
06/08/19,12:08:49.115010  NOTI             - CRL .......... : (none)
06/08/19,12:08:49.115011  NOTI             - Priority ..... : (default: 'NORMAL')
06/08/19,12:08:49.115014  NOTI             - DH bits ...... : 1024
06/08/19,12:08:49.115016  NOTI     Origin-State-Id ........ : 1559963329
06/08/19,12:08:49.115019  NOTI   Loaded extensions: '/opt/freeDiameter/lib/freeDiameter/dict_nasreq.fdx'[(no config file)], loaded
06/08/19,12:08:49.115021  NOTI   Loaded extensions: '/opt/freeDiameter/lib/freeDiameter/dict_gx.fdx'[(no config file)], loaded
06/08/19,12:08:49.115023  NOTI   Loaded extensions: '/opt/freeDiameter/lib/freeDiameter/app_pcrf.fdx'[/opt/freeDiameter/etc/app_pcrf.conf], loaded
06/08/19,12:08:49.115728  NOTI   Local server address(es): 192.168.11.162{---L-}        192.168.30.162{---L-}
06/08/19,12:08:49.115774  NOTI   freeDiameterd daemon initialized.

7-2.PCEF起動
[root@c610diam01 ~]# /opt/freeDiameter/bin/freeDiameterd -c /opt/freeDiameter/etc/freeDiameter.conf
06/08/19,12:09:04.765012  NOTI   libfdproto '1.2.0' initialized.
06/08/19,12:09:04.765733  NOTI   libgnutls '2.12.23' initialized.
06/08/19,12:09:04.766007  NOTI   libfdcore '1.2.0' initialized.
06/08/19,12:09:04.949999  NOTI   All extensions loaded.
06/08/19,12:09:04.950020  NOTI   freeDiameter configuration:
06/08/19,12:09:04.950023  NOTI     Default trace level .... : +3
06/08/19,12:09:04.950026  NOTI     Configuration file ..... : /opt/freeDiameter/etc/freeDiameter.conf
06/08/19,12:09:04.950028  NOTI     Diameter Identity ...... : c610diam01.local.jp (l:19)
06/08/19,12:09:04.950030  NOTI     Diameter Realm ......... : local.jp (l:8)
06/08/19,12:09:04.950032  NOTI     Tc Timer ............... : 30
06/08/19,12:09:04.950034  NOTI     Tw Timer ............... : 30
06/08/19,12:09:04.950036  NOTI     Local port ............. : 3868
06/08/19,12:09:04.950038  NOTI     Local secure port ...... : 5868
06/08/19,12:09:04.950040  NOTI     Number of SCTP streams . : 30
06/08/19,12:09:04.950042  NOTI     Number of clients thr .. : 5
06/08/19,12:09:04.950044  NOTI     Number of app threads .. : 4
06/08/19,12:09:04.950046  NOTI     Local endpoints ........ : Default (use all available)
06/08/19,12:09:04.950048  NOTI     Local applications ..... : App: 16777238,AuAc,Vnd:0
06/08/19,12:09:04.950050  NOTI     Flags : - IP ........... : Enabled
06/08/19,12:09:04.950052  NOTI             - IPv6 ......... : Enabled
06/08/19,12:09:04.950055  NOTI             - Relay app .... : Enabled
06/08/19,12:09:04.950057  NOTI             - TCP .......... : Enabled
06/08/19,12:09:04.950058  NOTI             - SCTP ......... : Enabled
06/08/19,12:09:04.950061  NOTI             - Pref. proto .. : SCTP
06/08/19,12:09:04.950062  NOTI             - TLS method ... : Separate port
06/08/19,12:09:04.950065  NOTI     TLS :   - Certificate .. : /opt/CA/newcerts/c610diam01.crt
06/08/19,12:09:04.950067  NOTI             - Private key .. : /opt/CA/private/c610diam01.key
06/08/19,12:09:04.950069  NOTI             - CA (trust) ... : /opt/CA/cacert.pem (1 certs)
06/08/19,12:09:04.950071  NOTI             - CRL .......... : (none)
06/08/19,12:09:04.950073  NOTI             - Priority ..... : (default: 'NORMAL')
06/08/19,12:09:04.950075  NOTI             - DH bits ...... : 1024
06/08/19,12:09:04.950077  NOTI     Origin-State-Id ........ : 1559963344
06/08/19,12:09:04.950080  NOTI   Loaded extensions: '/opt/freeDiameter/lib/freeDiameter/dict_nasreq.fdx'[(no config file)], loaded
06/08/19,12:09:04.950083  NOTI   Loaded extensions: '/opt/freeDiameter/lib/freeDiameter/dict_gx.fdx'[(no config file)], loaded
06/08/19,12:09:04.950085  NOTI   Loaded extensions: '/opt/freeDiameter/lib/freeDiameter/app_pcef.fdx'[/opt/freeDiameter/etc/app_pcef.conf], loaded
06/08/19,12:09:04.950089  NOTI   {signal:10}'app_pcef'->0x7f641a9f5a20
06/08/19,12:09:04.950797  NOTI   Local server address(es): 192.168.11.161{---L-}        192.168.30.161{---L-}
06/08/19,12:09:04.950838  NOTI   freeDiameterd daemon initialized.
以下はPCRFへの接続時に出力されます。
06/08/19,12:09:04.953215  NOTI   Connected to 'c610diam02.local.jp' (TCP,soc#16), remote capabilities:
06/08/19,12:09:04.953224  NOTI      'Capabilities-Exchange-Answer'
06/08/19,12:09:04.953245  NOTI        Version: 0x01
06/08/19,12:09:04.953247  NOTI        Length: 236
06/08/19,12:09:04.953249  NOTI        Flags: 0x00 (----)
06/08/19,12:09:04.953251  NOTI        Command Code: 257
06/08/19,12:09:04.953253  NOTI        ApplicationId: 0
06/08/19,12:09:04.953255  NOTI        Hop-by-Hop Identifier: 0x40404F68
06/08/19,12:09:04.953257  NOTI        End-to-End Identifier: 0x6D04E4B6
06/08/19,12:09:04.953259  NOTI         {internal data}: src:c610diam02.local.jp(19) rwb:(nil) rt:2 cb:(nil),(nil)(nil) qry:0x7f6420000ba0 asso:0 sess:(nil)
06/08/19,12:09:04.953262  NOTI         AVP: 'Result-Code'(268) l=12 f=-M val='DIAMETER_SUCCESS' (2001 (0x7d1))
06/08/19,12:09:04.953264  NOTI         AVP: 'Origin-Host'(264) l=27 f=-M val="c610diam02.local.jp"
06/08/19,12:09:04.953266  NOTI         AVP: 'Origin-Realm'(296) l=16 f=-M val="local.jp"
06/08/19,12:09:04.953268  NOTI         AVP: 'Origin-State-Id'(278) l=12 f=-M val=1559963329 (0x5cfb26c1)
06/08/19,12:09:04.953271  NOTI         AVP: 'Host-IP-Address'(257) l=14 f=-M val=192.168.11.162
06/08/19,12:09:04.953273  NOTI         AVP: 'Host-IP-Address'(257) l=14 f=-M val=192.168.30.162
06/08/19,12:09:04.953275  NOTI         AVP: 'Vendor-Id'(266) l=12 f=-M val=0 (0x0)
06/08/19,12:09:04.953277  NOTI         AVP: 'Product-Name'(269) l=20 f=-- val="freeDiameter"
06/08/19,12:09:04.953279  NOTI         AVP: 'Firmware-Revision'(267) l=12 f=-- val=10200 (0x27d8)
06/08/19,12:09:04.953281  NOTI         AVP: 'Auth-Application-Id'(258) l=12 f=-M val=16777238 (0x1000016)
06/08/19,12:09:04.953284  NOTI         AVP: 'Acct-Application-Id'(259) l=12 f=-M val=16777238 (0x1000016)
06/08/19,12:09:04.953286  NOTI         AVP: 'Auth-Application-Id'(258) l=12 f=-M val=4294967295 (0xffffffff)
06/08/19,12:09:04.953288  NOTI         AVP: 'Supported-Vendor-Id'(265) l=12 f=-M val=5535 (0x159f)
06/08/19,12:09:04.953290  NOTI         AVP: 'Supported-Vendor-Id'(265) l=12 f=-M val=10415 (0x28af)
06/08/19,12:09:04.953292  NOTI         AVP: 'Supported-Vendor-Id'(265) l=12 f=-M val=13019 (0x32db)
06/08/19,12:09:04.953299  NOTI   No TLS protection negotiated with peer 'c610diam02.local.jp'.
06/08/19,12:09:04.953396  NOTI   'STATE_WAITCEA'        -> 'STATE_OPEN' 'c610diam02.local.jp'

7-3.PCEF起動後のPCRF側の出力
06/08/19,12:09:05.045712  NOTI   Connected to 'c610diam01.local.jp' (TCP,soc#12), remote capabilities:
06/08/19,12:09:05.045726  NOTI      'Capabilities-Exchange-Request'
06/08/19,12:09:05.045729  NOTI        Version: 0x01
06/08/19,12:09:05.045731  NOTI        Length: 236
06/08/19,12:09:05.045733  NOTI        Flags: 0x80 (R---)
06/08/19,12:09:05.045735  NOTI        Command Code: 257
06/08/19,12:09:05.045737  NOTI        ApplicationId: 0
06/08/19,12:09:05.045739  NOTI        Hop-by-Hop Identifier: 0x40404F68
06/08/19,12:09:05.045741  NOTI        End-to-End Identifier: 0x6D04E4B6
06/08/19,12:09:05.045743  NOTI         {internal data}: src:(nil)(0) rwb:(nil) rt:0 cb:(nil),(nil)(nil) qry:(nil) asso:1 sess:(nil)
06/08/19,12:09:05.045746  NOTI         AVP: 'Origin-Host'(264) l=27 f=-M val="c610diam01.local.jp"
06/08/19,12:09:05.045748  NOTI         AVP: 'Origin-Realm'(296) l=16 f=-M val="local.jp"
06/08/19,12:09:05.045750  NOTI         AVP: 'Origin-State-Id'(278) l=12 f=-M val=1559963344 (0x5cfb26d0)
06/08/19,12:09:05.045752  NOTI         AVP: 'Host-IP-Address'(257) l=14 f=-M val=192.168.11.161
06/08/19,12:09:05.045754  NOTI         AVP: 'Host-IP-Address'(257) l=14 f=-M val=192.168.30.161
06/08/19,12:09:05.045756  NOTI         AVP: 'Vendor-Id'(266) l=12 f=-M val=0 (0x0)
06/08/19,12:09:05.045758  NOTI         AVP: 'Product-Name'(269) l=20 f=-- val="freeDiameter"
06/08/19,12:09:05.045761  NOTI         AVP: 'Firmware-Revision'(267) l=12 f=-- val=10200 (0x27d8)
06/08/19,12:09:05.045763  NOTI         AVP: 'Inband-Security-Id'(299) l=12 f=-M val='NO_INBAND_SECURITY' (0 (0x0))
06/08/19,12:09:05.045765  NOTI         AVP: 'Auth-Application-Id'(258) l=12 f=-M val=16777238 (0x1000016)
06/08/19,12:09:05.045767  NOTI         AVP: 'Acct-Application-Id'(259) l=12 f=-M val=16777238 (0x1000016)
06/08/19,12:09:05.045769  NOTI         AVP: 'Auth-Application-Id'(258) l=12 f=-M val=4294967295 (0xffffffff)
06/08/19,12:09:05.045771  NOTI         AVP: 'Supported-Vendor-Id'(265) l=12 f=-M val=5535 (0x159f)
06/08/19,12:09:05.045774  NOTI         AVP: 'Supported-Vendor-Id'(265) l=12 f=-M val=10415 (0x28af)
06/08/19,12:09:05.045776  NOTI         AVP: 'Supported-Vendor-Id'(265) l=12 f=-M val=13019 (0x32db)
06/08/19,12:09:05.045858  NOTI   No TLS protection negotiated with peer 'c610diam01.local.jp'.
06/08/19,12:09:05.046000  NOTI   'STATE_CLOSED' -> 'STATE_OPEN' 'c610diam01.local.jp'
7-4.PCEF側のテストコマンド

以下のコマンドは全てPCEF側で投入します。
Daimeterサービスはフォアグラウンドで起動するため、以下のコマンドを打つためには、PCEF側でもう一つターミナル画面を出してください。

/opt/freeDiameter/bin/pcef-ctl.sh dump
/opt/freeDiameter/bin/pcef-ctl.sh init
/opt/freeDiameter/bin/pcef-ctl.sh update-input
/opt/freeDiameter/bin/pcef-ctl.sh update-output
7-5.状態確認

コマンドを打つと、Daimeterサービスがフォアグラウンドで起動しているターミナル画面に以下の出力が出ます。
何もポリシーが当たっていない状態です。

/opt/freeDiameter/bin/pcef-ctl.sh dump


06/08/19,12:10:02.779425  NOTI   -------------- User session state dump --------------
06/08/19,12:10:02.779452  NOTI   IMSI:                      017635273633
06/08/19,12:10:02.779456  NOTI   Charging rule name:        default-policy
06/08/19,12:10:02.779458  NOTI   Used total octets:         0
06/08/19,12:10:02.779460  NOTI   Used input octets:         0
06/08/19,12:10:02.779480  NOTI   Used output octets:        0
06/08/19,12:10:02.779482  NOTI   =================== Dump complete ===================
7-6.初期化

以下のコマンドにて初期のポリシーを当てます。

/opt/freeDiameter/bin/pcef-ctl.sh init
06/08/19,12:11:22.635425  NOTI   Sending initial request...
06/08/19,12:11:22.636343  NOTI   Received initial answer.

/opt/freeDiameter/bin/pcef-ctl.sh dump
06/08/19,12:11:57.275226  NOTI   -------------- User session state dump --------------
06/08/19,12:11:57.275234  NOTI   IMSI:                      017635273633
06/08/19,12:11:57.275236  NOTI   Charging rule name:        default-policy
06/08/19,12:11:57.275239  NOTI   Charging rule name:        high-speed-policy
06/08/19,12:11:57.275241  NOTI   Monitoring key:            test-monitoring-key
06/08/19,12:11:57.275243  NOTI     Total octets threshold:  20
06/08/19,12:11:57.275245  NOTI     Input octets threshold:  10
06/08/19,12:11:57.275246  NOTI     Output octets threshold: 10
06/08/19,12:11:57.275248  NOTI   Used total octets:         0
06/08/19,12:11:57.275250  NOTI   Used input octets:         0
06/08/19,12:11:57.275252  NOTI   Used output octets:        0
06/08/19,12:11:57.275254  NOTI   =================== Dump complete ===================
7-7.アップデート

以下のコマンドにてアップデートしていきます。
例えるなら、PGWやDPI装置にパケットが流れることにより、データ量がカウントされているようなイメージです。*4

/opt/freeDiameter/bin/pcef-ctl.sh update-input

06/08/19,12:12:24.735514  NOTI   Updated used input octets. [0->1]

上記コマンドを繰り返し打つと以下のように閾値(Input octets threshold: 10)に近づいていきます。

06/08/19,12:12:24.735514  NOTI   Updated used input octets. [0->1]
06/08/19,12:12:48.084391  NOTI   Updated used input octets. [1->2]
06/08/19,12:12:48.668832  NOTI   Updated used input octets. [2->3]
06/08/19,12:12:49.141213  NOTI   Updated used input octets. [3->4]
06/08/19,12:12:49.624475  NOTI   Updated used input octets. [4->5]
06/08/19,12:12:50.142395  NOTI   Updated used input octets. [5->6]
06/08/19,12:12:50.669159  NOTI   Updated used input octets. [6->7]
06/08/19,12:12:51.189578  NOTI   Updated used input octets. [7->8]
06/08/19,12:12:51.743437  NOTI   Updated used input octets. [8->9]
06/08/19,12:12:52.278174  NOTI   Updated used input octets. [9->10]
06/08/19,12:12:52.278194  NOTI   Sending update request...
06/08/19,12:12:52.278843  NOTI   Received update answer.

閾値に到達した後、状態確認をすると、新しいルールが適用されています。

/opt/freeDiameter/bin/pcef-ctl.sh dump

06/08/19,12:13:18.653228  NOTI   -------------- User session state dump --------------
06/08/19,12:13:18.653236  NOTI   IMSI:                      017635273633
06/08/19,12:13:18.653239  NOTI   Charging rule name:        default-policy
06/08/19,12:13:18.653241  NOTI   Charging rule name:        low-speed-policy
06/08/19,12:13:18.653243  NOTI   Used total octets:         10
06/08/19,12:13:18.653245  NOTI   Used input octets:         10
06/08/19,12:13:18.653247  NOTI   Used output octets:        0
06/08/19,12:13:18.653249  NOTI   =================== Dump complete ===================

以上です。

8.最後に

以下の書籍を参考にさせて頂きました。
O'Reilly Japan - Diameterプロトコルガイド
以下のサイトを参考にさせて頂きました。
freeDiameterdのインストール記録 第1回:ITエンジニア兼きもの屋のフリーライフ:エンジニアライフ

上記の書籍は、Diameterプロトコルや機能拡張に関するアーキテクチャについて理解するという点では、大変よくまとまっているため本当にお勧めです。

また、最近出版された以下の書籍もちょっと気になっています。
Diameter: New Generation AAA Protocol - Design, Practice and Applications

つい先日(6/2)、freeDiameterの1.3.2がリリースされていましたので、ちょっとキャッチアップしていこうかなと考えています。

*1:CentOS7系で試したところSegmentation Faultが出てしまったので、CentOS6系になっています。。

*2:SCTP自体は、eNodeB-MME間やCiscoのBox-to-Box NATなどでも使用されているため、そこまでニッチなプロトコルではないかと思います。

*3:dict_gx.fdxの上書き確認メッセージが表示されたらyでOKです

*4:通常、通信量の管理はGyインターフェースにてOCSが行いますので、あくまでもイメージとして捉えてください。通常、通信ポリシーの管理(ルールの適用など)はGxインターフェースにてPCRFが行います。

Open Stack Neutron環境構築 その4:NW設定と確認方法

ルータ作成やネットワーク&サブネット作成、そしてインスタンスの起動などについて記載していきます。
また、構成の詳細や、その確認方法についても後述します。

  1. 構成概要
  2. ルータ作成
  3. 外部NW(GW_NET)設定
  4. 内部NW(SV_NET)設定
  5. インスタンス(srv1)作成
  6. Trunk用NW(TR_NET)設定
  7. インスタンス(srv2)作成
  8. 構成詳細

1.構成概要

以下のようなNWを構築していきます。
f:id:metonymical:20190529163243p:plain
しかし、この図だけでは内部的なことはわからないため、8.構成詳細にて詳しく記載します。

なお、ダッシュボードにログインし、プロジェクト>ネットワーク>ネットワークトポロジーと進み、上記の画面を開いておいてください。2.~7.の作業を行うたびに、ネットワークトポロジーが少しづつ変化していく過程を確認できると思います。

2.ルータ作成

対象:Controllerのみ

openstack router create \
--distributed \
DV_RT

3.外部NW(GW_NET)設定

対象:Controllerのみ

3-1.NW作成
openstack network create \
--external \
--provider-network-type vlan \
--provider-physical-network physnet1 \
--provider-segment 30 \
GW_NET
3-2.サブネット作成
openstack subnet create \
--subnet-range 10.30.0.0/24 \
--no-dhcp \
--network GW_NET \
--allocation-pool start=10.30.0.128,end=10.30.0.223 \
GW_SNET
3-3.NWをルータにアタッチ
openstack router set \
--external-gateway GW_NET \
DV_RT
3-4.ポートとMACアドレステーブルの確認
#各Bridgeのポート番号を確認
ovs-ofctl show br-ens35
ovs-ofctl show br-int

#各BridgeのMACアドレステーブルを確認
ovs-appctl fdb/show br-ens35
ovs-appctl fdb/show br-int

4.内部NW(SV_NET)設定

対象:Controllerのみ

4-1.NW作成
openstack network create \
SV_NET
4-2.サブネット作成
openstack subnet create \
--subnet-range 192.168.200.0/24 \
--network SV_NET \
--dns-nameserver 8.8.8.8 \
SV_SNET
4-3.NWをルータにアタッチ
openstack router add \
subnet DV_RT \
SV_SNET

5.インスタンス(srv1)作成

対象:Controllerのみ

5-1.Flavor作成

簡易的なFlavorを作成しておきます。

#Cirros用
openstack flavor create \
--ram 512 \
--disk 1 \
m1

#Ubuntu
openstack flavor create \
--ram 512 \
--disk 10 \
m2
5-2.インスタンス(srv1)作成

compute01上にsrv1を作成します。

openstack server create \
--flavor m1 \
--image cirros-0.4.0 \
--availability-zone nova:compute01 \
--nic net-id=SV_NET \
srv1

6.Trunk用NW(TR_NET)設定

対象:Controllerのみ

6-1.NW作成
openstack network create \
--provider-network-type vlan \
--provider-physical-network physnet1 \
--provider-segment 300 \
TR_NET
6-2.サブネット作成
openstack subnet create \
--subnet-range 192.168.30.0/24 \
--network TR_NET \
--gateway 192.168.30.254 \
--allocation-pool start=192.168.30.128,end=192.168.30.223 \
--dns-nameserver 8.8.8.8 \
TR_SNET
6-3.親ポートの作成
openstack port create \
--network SV_NET P01
6-4.サブポートの作成

任意ですがDHCPで取得するアドレスを固定にしています。

openstack port create \
--network TR_NET P01_C01 \
--fixed-ip ip-address=192.168.30.100
6-5.Trunkの作成

親ポートとサブポートを関連付けて、Trunkを作成します。

openstack network trunk create \
--parent-port P01 \
--subport port=P01_C01,segmentation-type=vlan,segmentation-id=300 \
TRK1
6-6.MACアドレスの確認

サブポートP01_C01のMACアドレスをメモっておきます。
以下の例の場合、

P01_C01 fa:16:3e:37:12:36

になります。

openstack port list

root@controller01:~# openstack port list
+--------------------------------------+---------+-------------------+-------------------------------------------------------------------------------+--------+
| ID                                   | Name    | MAC Address       | Fixed IP Addresses                                                            | Status |
+--------------------------------------+---------+-------------------+-------------------------------------------------------------------------------+--------+
| 01ae96f9-c8bd-4149-8f7f-c936d0d038b9 |         | fa:16:3e:33:c7:36 | ip_address='10.30.0.132', subnet_id='e8168d18-ed3c-43d0-a950-9c9a6b635377'    | ACTIVE |
| 2eeb7f80-786c-4ba2-bd53-734da88114fe |         | fa:16:3e:7e:02:41 | ip_address='10.30.0.141', subnet_id='e8168d18-ed3c-43d0-a950-9c9a6b635377'    | ACTIVE |
| 33af164d-654e-4923-8a09-1f41c26fee37 |         | fa:16:3e:55:11:84 | ip_address='192.168.200.1', subnet_id='72151365-841f-4e6c-8b2b-1d9ed2898e7b'  | ACTIVE |
| 40442390-2fe7-4844-95ee-4a43c0296a59 | P01_C01 | fa:16:3e:37:12:36 | ip_address='192.168.30.100', subnet_id='0b313de3-b203-471a-9c26-edfeb8e14880' | ACTIVE |
| 64457abd-f622-4a9a-a61e-ecd9a118731d |         | fa:16:3e:1a:39:83 | ip_address='10.30.0.129', subnet_id='e8168d18-ed3c-43d0-a950-9c9a6b635377'    | ACTIVE |
| 859c401f-0e2e-4d65-8fd2-5e9137d4a3a2 | P01     | fa:16:3e:db:91:fd | ip_address='192.168.200.7', subnet_id='72151365-841f-4e6c-8b2b-1d9ed2898e7b'  | ACTIVE |
| 9872b8b5-c44f-49d9-a547-982949ffd9be |         | fa:16:3e:b7:ac:a1 | ip_address='192.168.30.128', subnet_id='0b313de3-b203-471a-9c26-edfeb8e14880' | ACTIVE |
| bb5d66dc-241d-43ff-95bd-8bf5e9034b9e |         | fa:16:3e:cd:9a:f3 | ip_address='10.30.0.135', subnet_id='e8168d18-ed3c-43d0-a950-9c9a6b635377'    | ACTIVE |
| c5d7fa51-0de0-49bf-92b3-00d3e7b3c7d1 |         | fa:16:3e:08:b2:10 | ip_address='192.168.200.2', subnet_id='72151365-841f-4e6c-8b2b-1d9ed2898e7b'  | ACTIVE |
| d11c5401-13e9-46f2-9cd0-3e5c242fa995 |         | fa:16:3e:58:39:d7 | ip_address='192.168.200.3', subnet_id='72151365-841f-4e6c-8b2b-1d9ed2898e7b'  | ACTIVE |
| d55e11c2-abcf-4425-afb2-3199a90bf2dc |         | fa:16:3e:66:30:85 | ip_address='192.168.200.18', subnet_id='72151365-841f-4e6c-8b2b-1d9ed2898e7b' | ACTIVE |
+--------------------------------------+---------+-------------------+-------------------------------------------------------------------------------+--------+

7.インスタンス(srv2)作成

対象:Controllerのみ

7-1.パスワードファイル作成
vi /root/udata.txt

#cloud-config
password: ubuntu
chpasswd: { expire: False }
ssh_pwauth: True
7-2.インスタンス(srv2)作成

Compute02上にsrv2を作成します。
user-dataとして、udata.txtを読込みます。
親ポートP01に接続させます。

openstack server create \
--flavor m2 \
--image ubuntu-xenial-16.04 \
--availability-zone nova:compute02 \
--user-data udata.txt \
--nic port-id=P01 \
srv2
7-3.インスタンスの設定

対象:Compute02からsrv2コンソールログインして実施
インスタンスにログイン後、以下の設定を実施。
サブポートP01_C01にアサインされたMACアドレスfa:16:3e:37:12:36を設定してください。
最後にdhcpでアドレス取得要求を行うと、サブポートに設定した192.168.30.100が取得できます。

sudo su
ip link add link ens3 name ens3.300 type vlan id 300
ip link set dev ens3.300 address fa:16:3e:37:12:36
ip link set ens3.300 up
dhclient ens3.300

以下出力例です。

root@compute02:~# virsh list
 Id    Name                           State
----------------------------------------------------
 1     instance-00000002              running

root@compute02:~# virsh console instance-00000002
Connected to domain instance-00000002
Escape character is ^]

Ubuntu 16.04.6 LTS srv2 ttyS0

srv2 login: ubuntu
Password: ubuntu
Last login: Wed May 29 06:03:11 UTC 2019 on ttyS0
Welcome to Ubuntu 16.04.6 LTS (GNU/Linux 4.4.0-148-generic x86_64)

ubuntu@srv2:~$ sudo su
sudo: unable to resolve host srv2
root@srv2:/home/ubuntu# cd
root@srv2:~# ip link add link ens3 name ens3.300 type vlan id 300
root@srv2:~# ip link set dev ens3.300 address fa:16:3e:37:12:36
root@srv2:~# ip link set ens3.300 up
root@srv2:~# dhclient ens3.300
root@srv2:~# ip add show
1: lo:  mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: ens3:  mtu 1450 qdisc pfifo_fast state UP group default qlen 1000
    link/ether fa:16:3e:db:91:fd brd ff:ff:ff:ff:ff:ff
    inet 192.168.200.7/24 brd 192.168.200.255 scope global ens3
       valid_lft forever preferred_lft forever
    inet6 fe80::f816:3eff:fedb:91fd/64 scope link
       valid_lft forever preferred_lft forever
3: ens3.300@ens3:  mtu 1450 qdisc noqueue state UP group default qlen 1000
    link/ether fa:16:3e:37:12:36 brd ff:ff:ff:ff:ff:ff
    inet 192.168.30.100/24 brd 192.168.30.255 scope global ens3.300
       valid_lft forever preferred_lft forever
    inet6 fe80::f816:3eff:fe37:1236/64 scope link
       valid_lft forever preferred_lft forever

8.構成詳細

8-1.構成

以下の図は第1回目で記載しました。
f:id:metonymical:20190527141522p:plain
各Nodeのens35より内側(左側)の詳細構成が以下となります。
f:id:metonymical:20190529175507p:plain
<補足>
Brdigeには1重下線、Routerには2重下線を入れています。
br-intよりも左側がNamespaceで作成されたRouterです。
v1~3はNeutron内部で使用されるVLAN IDです。Flowテーブルにより以下に書き換えられています。

VLAN1 VLAN56 SV_NET *1
VLAN2 VLAN30 GW_NET
VLAN3 VLAN300 TR_NET


論理構成だけを記載したものが以下となります。
f:id:metonymical:20190529175834p:plain

8-2.確認方法:L2レベルの確認

ここでは例としてController01のbr-intで行ってみます。

ovs-vsctl show
ovs-ofctl show br-int
ovs-appctl fdb/show br-int
ovs-ofctl dump-flows br-int
ovs-appctl ofproto/trace br-int in_port=n

以下出力例です。
もっと多くの補足を入れたいのですが、膨大な量になるため割愛します。

br-intのポート名や内部VLAN番号の確認*2

ovs-vsctl show

root@controller01:~# ovs-vsctl show
01a7c9a9-3ae0-45dd-8eda-f46aa41c164c
    Manager "ptcp:6640:127.0.0.1"
        is_connected: true
    Bridge br-int
        Controller "tcp:127.0.0.1:6633"
            is_connected: true
        fail_mode: secure
        Port "sg-d11c5401-13"
            tag: 1
            Interface "sg-d11c5401-13"
                type: internal
        Port br-int
            Interface br-int
                type: internal
        Port "qr-33af164d-65"
            tag: 1
            Interface "qr-33af164d-65"
                type: internal
        Port "int-br-ens35"
            Interface "int-br-ens35"
                type: patch
                options: {peer="phy-br-ens35"}
        Port "tapc5d7fa51-0d"
            tag: 1
            Interface "tapc5d7fa51-0d"
                type: internal
        Port "tap9872b8b5-c4"
            tag: 3
            Interface "tap9872b8b5-c4"
                type: internal
        Port "qg-2eeb7f80-78"
            tag: 2
            Interface "qg-2eeb7f80-78"
                type: internal
        Port patch-tun
            Interface patch-tun
                type: patch
                options: {peer=patch-int}
        Port "fg-bb5d66dc-24"
            tag: 2
            Interface "fg-bb5d66dc-24"
                type: internal
    ovs_version: "2.8.4"

br-intのポート番号の確認

ovs-ofctl show br-int

root@controller01:~# ovs-ofctl show br-int
OFPT_FEATURES_REPLY (xid=0x2): dpid:0000e678379a3b46
n_tables:254, n_buffers:0
capabilities: FLOW_STATS TABLE_STATS PORT_STATS QUEUE_STATS ARP_MATCH_IP
actions: output enqueue set_vlan_vid set_vlan_pcp strip_vlan mod_dl_src mod_dl_dst mod_nw_src mod_nw_dst mod_nw_tos mod_tp_src mod_tp_dst
 1(int-br-ens35): addr:c2:7b:ab:ac:4b:1f
     config:     0
     state:      0
     speed: 0 Mbps now, 0 Mbps max
 2(patch-tun): addr:7a:5e:f6:c2:45:26
     config:     0
     state:      0
     speed: 0 Mbps now, 0 Mbps max
 3(qr-33af164d-65): addr:00:00:00:00:00:00
     config:     PORT_DOWN
     state:      LINK_DOWN
     speed: 0 Mbps now, 0 Mbps max
 4(sg-d11c5401-13): addr:00:00:00:00:00:00
     config:     PORT_DOWN
     state:      LINK_DOWN
     speed: 0 Mbps now, 0 Mbps max
 5(fg-bb5d66dc-24): addr:00:00:00:00:00:00
     config:     PORT_DOWN
     state:      LINK_DOWN
     speed: 0 Mbps now, 0 Mbps max
 6(tapc5d7fa51-0d): addr:00:00:00:00:00:00
     config:     PORT_DOWN
     state:      LINK_DOWN
     speed: 0 Mbps now, 0 Mbps max
 7(qg-2eeb7f80-78): addr:00:00:00:00:00:00
     config:     PORT_DOWN
     state:      LINK_DOWN
     speed: 0 Mbps now, 0 Mbps max
 13(tap9872b8b5-c4): addr:00:00:00:00:00:00
     config:     PORT_DOWN
     state:      LINK_DOWN
     speed: 0 Mbps now, 0 Mbps max
 LOCAL(br-int): addr:e6:78:37:9a:3b:46
     config:     PORT_DOWN
     state:      LINK_DOWN
     speed: 0 Mbps now, 0 Mbps max
OFPT_GET_CONFIG_REPLY (xid=0x4): frags=normal miss_send_len=0

br-intのMacアドレステーブルの確認

ovs-appctl fdb/show br-int

root@controller01:~# ovs-appctl fdb/show br-int
 port  VLAN  MAC                Age
    1     2  2c:53:4a:01:27:66   38
    1     3  2c:53:4a:01:27:66   38

br-intのフローテーブルの確認
赤文字はフローテーブルによりVLANIDが書き換えられている箇所です。

ovs-ofctl dump-flows br-int

root@controller01:~# ovs-ofctl dump-flows br-int
 cookie=0xab814f17f876c4e7, duration=18281.635s, table=0, n_packets=0, n_bytes=0, priority=4,in_port="int-br-ens35",dl_src=fa:16:3f:05:7d:26 actions=resubmit(,2)
 cookie=0xab814f17f876c4e7, duration=18281.634s, table=0, n_packets=0, n_bytes=0, priority=2,in_port="patch-tun",dl_src=fa:16:3f:05:7d:26 actions=resubmit(,1)
 cookie=0xab814f17f876c4e7, duration=18281.632s, table=0, n_packets=210, n_bytes=18620, priority=4,in_port="int-br-ens35",dl_src=fa:16:3f:53:4c:80 actions=resubmit(,2)
 cookie=0xab814f17f876c4e7, duration=18281.631s, table=0, n_packets=0, n_bytes=0, priority=2,in_port="patch-tun",dl_src=fa:16:3f:53:4c:80 actions=resubmit(,1)
 cookie=0xab814f17f876c4e7, duration=18207.228s, table=0, n_packets=35, n_bytes=3684, priority=3,in_port="int-br-ens35",dl_vlan=56 actions=mod_vlan_vid:1,resubmit(,60)
 cookie=0xab814f17f876c4e7, duration=18203.240s, table=0, n_packets=1773, n_bytes=754143, priority=3,in_port="int-br-ens35",dl_vlan=30 actions=mod_vlan_vid:2,resubmit(,60)
 cookie=0xab814f17f876c4e7, duration=16350.937s, table=0, n_packets=1235, n_bytes=226168, priority=3,in_port="int-br-ens35",dl_vlan=300 actions=mod_vlan_vid:3,resubmit(,60)
 cookie=0xab814f17f876c4e7, duration=18281.646s, table=0, n_packets=310, n_bytes=41445, priority=2,in_port="int-br-ens35" actions=drop
 cookie=0xab814f17f876c4e7, duration=18281.778s, table=0, n_packets=564, n_bytes=514595, priority=0 actions=resubmit(,60)
 cookie=0xab814f17f876c4e7, duration=18281.646s, table=1, n_packets=0, n_bytes=0, priority=1 actions=drop
 cookie=0xab814f17f876c4e7, duration=18205.312s, table=2, n_packets=203, n_bytes=17846, priority=4,dl_vlan=56,dl_dst=fa:16:3e:58:39:d7 actions=mod_dl_src:fa:16:3e:55:11:84,resubmit(,60)
 cookie=0xab814f17f876c4e7, duration=16262.886s, table=2, n_packets=0, n_bytes=0, priority=4,dl_vlan=56,dl_dst=fa:16:3e:08:b2:10 actions=mod_dl_src:fa:16:3e:55:11:84,resubmit(,60)
 cookie=0xab814f17f876c4e7, duration=18281.646s, table=2, n_packets=7, n_bytes=774, priority=1 actions=drop
 cookie=0xab814f17f876c4e7, duration=18281.647s, table=23, n_packets=0, n_bytes=0, priority=0 actions=drop
 cookie=0xab814f17f876c4e7, duration=18281.777s, table=24, n_packets=0, n_bytes=0, priority=0 actions=drop
 cookie=0xab814f17f876c4e7, duration=18205.312s, table=60, n_packets=203, n_bytes=17846, priority=4,dl_vlan=56,dl_dst=fa:16:3e:58:39:d7 actions=strip_vlan,output:"sg-d11c5401-13"
 cookie=0xab814f17f876c4e7, duration=16262.885s, table=60, n_packets=0, n_bytes=0, priority=4,dl_vlan=56,dl_dst=fa:16:3e:08:b2:10 actions=strip_vlan,output:"tapc5d7fa51-0d"
 cookie=0xab814f17f876c4e7, duration=18281.777s, table=60, n_packets=3607, n_bytes=1498590, priority=3 actions=NORMAL

br-intのフローのトレース

ovs-appctl ofproto/trace br-int in_port=n
#nは、ovs-ofctl show br-intの出力で得られたポート番号

root@controller01:~# ovs-appctl ofproto/trace br-int in_port=7
Flow: in_port=7,vlan_tci=0x0000,dl_src=00:00:00:00:00:00,dl_dst=00:00:00:00:00:00,dl_type=0x0000

bridge("br-int")
----------------
 0. priority 0, cookie 0xab814f17f876c4e7
    goto_table:60
60. priority 3, cookie 0xab814f17f876c4e7
    NORMAL
     -> no learned MAC for destination, flooding

    bridge("br-ens35")
    ------------------
         0. in_port=2, priority 2, cookie 0xc29c894d4abba2e2
            goto_table:1
         1. priority 0, cookie 0xc29c894d4abba2e2
            goto_table:2
         2. in_port=2,dl_vlan=2, priority 4, cookie 0xc29c894d4abba2e2
            set_field:4126->vlan_vid
            NORMAL
             -> no learned MAC for destination, flooding

bridge("br-tun")
----------------
 0. in_port=1, priority 1, cookie 0x151d0b9924ed6dbf
    goto_table:1
 1. priority 0, cookie 0x151d0b9924ed6dbf
    goto_table:2
 2. dl_dst=00:00:00:00:00:00/01:00:00:00:00:00, priority 0, cookie 0x151d0b9924ed6dbf
    goto_table:20
20. priority 0, cookie 0x151d0b9924ed6dbf
    goto_table:22
22. priority 0, cookie 0x151d0b9924ed6dbf
    drop

Final flow: unchanged
Megaflow: recirc_id=0,eth,in_port=7,vlan_tci=0x0000,dl_src=00:00:00:00:00:00,dl_dst=00:00:00:00:00:00,dl_type=0x0000
Datapath actions: push_vlan(vid=2,pcp=0),7,pop_vlan,push_vlan(vid=30,pcp=0),2,1,pop_vlan,6
8-3.確認方法:L3レベルの確認

ここでは例としてController01で確認していきます。

ip netns
ip netns exec `ip netns | awk 'NR==5'` ip add show
ip netns exec `ip netns | awk 'NR==5'` ip route show
ip netns exec `ip netns | awk 'NR==5'` ip rule show
ip netns exec `ip netns | awk 'NR==5'` ip route show table NUMEBER

以下がController01のNamespaceに作成されたRouterとなります。

ip netns

root@controller01:~# ip netns
qdhcp-8fd11879-9c07-4130-9cd5-e2f1034394dc
qdhcp-10364a89-8a6e-499d-bee3-03f4085b745e
fip-a53cf798-1c15-4597-aeca-8b8917aa81fd
snat-e83bd724-c0da-42d0-b43e-0d6a923e1c5b
qrouter-e83bd724-c0da-42d0-b43e-0d6a923e1c5b

各Routerのポートやアドレスを確認する場合、

ip netns exec qrouter-e83bd724-c0da-42d0-b43e-0d6a923e1c5b ip add show

とコマンド入力するのは大変です。

このため、awkを使って以下のようにします。
NR==5は、ip netnsの出力結果の5行目(qrouter~)に該当します。

ip netns exec `ip netns | awk 'NR==5'` ip add show

root@controller01:~# ip netns exec `ip netns | awk 'NR==5'` ip add show
1: lo:  mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: rfp-e83bd724-c:  mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 16:b3:ee:52:8f:c0 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 169.254.106.114/31 scope global rfp-e83bd724-c
       valid_lft forever preferred_lft forever
    inet6 fe80::14b3:eeff:fe52:8fc0/64 scope link
       valid_lft forever preferred_lft forever
14: qr-33af164d-65:  mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000
    link/ether fa:16:3e:55:11:84 brd ff:ff:ff:ff:ff:ff
    inet 192.168.200.1/24 brd 192.168.200.255 scope global qr-33af164d-65
       valid_lft forever preferred_lft forever
    inet6 fe80::f816:3eff:fe55:1184/64 scope link
       valid_lft forever preferred_lft forever

次にqrouterのRoutingTableを確認します。
Default Routeが無いため、これではInternetに出られませんので、Default Routeを確認します。

ip netns exec `ip netns | awk 'NR==5'` ip route show

root@controller01:~# ip netns exec `ip netns | awk 'NR==5'` ip route show
169.254.106.114/31 dev rfp-e83bd724-c  proto kernel  scope link  src 169.254.106.114
192.168.200.0/24 dev qr-33af164d-65  proto kernel  scope link  src 192.168.200.1

以下のコマンドでruleを表示させます。
最終行の番号をメモしておいてください。

ip netns exec `ip netns | awk 'NR==5'` ip rule show

root@controller01:~# ip netns exec `ip netns | awk 'NR==5'` ip rule show
0:      from all lookup local
32766:  from all lookup main
32767:  from all lookup default
3232286721:     from 192.168.200.1/24 lookup 3232286721

以下のコマンドで3232286721のRoutingTableを確認します。

ip netns exec `ip netns | awk 'NR==5'` ip route show table NUMBER

root@controller01:~# ip netns exec `ip netns | awk 'NR==5'` ip route show table 3232286721
default via 192.168.200.3 dev qr-33af164d-65

これらのコマンドを全Nodeの全Bridgeや全Namespaceに対して行っていくと、詳細構成が明らかになってきます。

8-4.トラフィックフロー:FlotingIP使用時

f:id:metonymical:20190529190803p:plain
FlotingIPを使用している場合は、ComputeNodeから外部NWへそのまま送信されます。

8-5.トラフィックフロー:SourceNAT使用時

f:id:metonymical:20190529190824p:plain
一方、NAT(PAT)を使用している場合は、一度ControllerNodeのsnatへ行った後、NATされて外部NWへ送信されます。

なお、特に触れませんが、Trunkした箇所*3については、論理構成に記載した通り、VLAN ID300が付与されRoutingされることなく、Compute02から、そのまま外部NWへ送信されます。

以上です。

9.最後に

以下のサイトを参考にさせて頂きました。
運用する際に理解しておきたい OpenStack Neutron DVR の Packet Flow - Qiita
OpenStack Docs: Keystone Installation Tutorial(Keystone)
OpenStack Docs: Installation(Glance)
OpenStack Docs: Compute service(Nova)
OpenStack Docs: Networking service(Neutron)
OpenStack Docs: Installation Guide(Horizon)

Open Stack Neutron環境構築は今回で最後ですが、まだモヤっとしている部分があると思っていますので、時間があればAppendixとして、もう一回くらい書きたいなと考えています。
MACアドレステーブル、ARPテーブル、Routingテーブルに加えて、Flowテーブルを読み解いていくことにより、詳細なトラフィックフローを完全に理解するというDeepDive的なことができればいいなと。

また、今回は基本的なところしか記載しませんでしたが、今後の発展として、これをベースにGREやVXLANを導入すると、さらに面白くなってきます。
また、OVNを導入してGeneveを使用してみるのも面白いかもしれません。
さらに、SR-IOVやDPDKを導入するのも面白いと思いますので、以下の過去記事などを参考にしてみてください。
Linux nmcliコマンドによるKVM&LXC/LXD with SR-IOVのInterface設定 - Metonymical Deflection
CentOS7 ovs(Open vSwitch)+DPDKのビルドとネットワーク設定方法 - Metonymical Deflection

*1:VLAN56は、前回記事で設定した32~63より自動でアサインされています。

*2:br-tunとbr-ens35も表示されますが削っています。

*3:srv2のens3.300

Open Stack Neutron環境構築 その3:Neutron+OvS+DVR のインストール

Neutron, OvS, DVRのインストールを実施します。*1
ここから徐々に複雑になりますので、ネットワーク、サブネット、ポート、インスタンスなどの作成は次回以降に記載します。

  1. Neutronのインストール
  2. Open vSwitch(L2agent)のインストール
  3. DVR(L3agent)のインストール
  4. その他設定

構成概要やOpen Stackのインストールは、前々回前回の記事を参照してください。

また、前回以上に今回は、Controllerで設定したり、Computeで設定したり、といったことが頻繁に発生するため、今何をやっているのか?が分からなくなってくると思います。
このため、以下の図を参考にしてみてください。ControllerとComputeの役割や機能の違いが少しづつ明確になってくると思います。
f:id:metonymical:20190530073758p:plain

1.Neutronのインストール

1-1.DBの設定・ユーザ登録・サービス登録・Endpoint作成・インストール

対象:Controllerのみ

#DBの設定
mysql

CREATE DATABASE neutron;
GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'localhost' IDENTIFIED BY 'neutron';
GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'%' IDENTIFIED BY 'neutron';
quit;

#ユーザ登録
openstack user create --domain Default --password=neutron neutron
openstack role add --project service --user neutron admin

#サービス登録
openstack service create --name neutron \
--description "OpenStack Networking" network

#Endpoint作成
openstack endpoint create --region RegionOne \
network public http://controller01:9696
openstack endpoint create --region RegionOne \
network internal http://controller01:9696
openstack endpoint create --region RegionOne \
network admin http://controller01:9696

#インストール(NeutronServer, DHCP Agent, Metadata Agent, ML2 Plugin, NeutronClient)
apt -y install neutron-server neutron-dhcp-agent \
neutron-metadata-agent neutron-plugin-ml2 \
python-neutronclient
1-2.neutron.confの設定

対象:Controllerのみ

vi /etc/neutron/neutron.conf

[DEFAULT]
auth_strategy = keystone
transport_url = rabbit://openstack:rabbit@controller01

[database]
#connection = sqlite:////var/lib/neutron/neutron.sqlite
connection = mysql+pymysql://neutron:neutron@controller01/neutron

[keystone_authtoken]
auth_uri = http://controller01:5000
auth_url = http://controller01:35357
memcached_servers = controller01:11211
auth_type = password
project_domain_name = default
user_domain_name = default
project_name = service
username = neutron
password = neutron

[nova]
auth_url = http://controller01:35357
auth_type = password
project_domain_name = default
user_domain_name = default
region_name = RegionOne
project_name = service
username = nova
password = nova
1-3.ML2 Pluginのインストール・neutron.confの設定

対象:Computeのみ

apt -y install neutron-plugin-ml2

vi /etc/neutron/neutron.conf

[DEFAULT]
auth_strategy = keystone
transport_url = rabbit://openstack:rabbit@controller01

[database]
#connection = sqlite:////var/lib/neutron/neutron.sqlite
connection = mysql+pymysql://neutron:neutron@controller01/neutron

[keystone_authtoken]
auth_uri = http://controller01:5000
auth_url = http://controller01:35357
memcached_servers = controller01:11211
auth_type = password
project_domain_name = default
user_domain_name = default
project_name = service
username = neutron
password = neutron
1-4.nova.confの設定

対象:全Node

vi /etc/nova/nova.conf

[neutron]
url= http://controller01:9696
auth_url = http://controller01:35357
auth_type = password
project_domain_name = default
user_domain_name = default
region_name = RegionOne
project_name = service
username = neutron
password = neutron
1-5.DB登録・設定読込み

対象:Controllerのみ

su -s /bin/sh -c "neutron-db-manage \
--config-file /etc/neutron/neutron.conf \
--config-file /etc/neutron/plugins/ml2/ml2_conf.ini \
upgrade head" neutron

systemctl restart nova-api nova-scheduler nova-conductor

以下出力例です。

root@controller01:~# su -s /bin/sh -c "neutron-db-manage \
> --config-file /etc/neutron/neutron.conf \
> --config-file /etc/neutron/plugins/ml2/ml2_conf.ini \
> upgrade head" neutron
INFO  [alembic.runtime.migration] Context impl MySQLImpl.
INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
  Running upgrade for neutron ...
INFO  [alembic.runtime.migration] Context impl MySQLImpl.
INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
INFO  [alembic.runtime.migration] Running upgrade  -> kilo, kilo_initial
INFO  [alembic.runtime.migration] Running upgrade kilo -> 354db87e3225, nsxv_vdr_metadata.py
INFO  [alembic.runtime.migration] Running upgrade 354db87e3225 -> 599c6a226151, neutrodb_ipam
INFO  [alembic.runtime.migration] Running upgrade 599c6a226151 -> 52c5312f6baf, Initial operations in support of address scopes
INFO  [alembic.runtime.migration] Running upgrade 52c5312f6baf -> 313373c0ffee, Flavor framework

~一部省略~

INFO  [alembic.runtime.migration] Running upgrade kilo -> 67c8e8d61d5, Initial Liberty no-op script.
INFO  [alembic.runtime.migration] Running upgrade 67c8e8d61d5 -> 458aa42b14b, fw_table_alter script to make  column case sensitive
INFO  [alembic.runtime.migration] Running upgrade 458aa42b14b -> f83a0b2964d0, rename tenant to project
INFO  [alembic.runtime.migration] Running upgrade f83a0b2964d0 -> fd38cd995cc0, change shared attribute for firewall resource
  OK
root@controller01:~#
1-6.設定読込み

対象:Computeのみ

systemctl restart nova-compute
1-7.DCHP Agentの設定・nova.conf追記・設定読込み

対象:Controllerのみ

#DCHP Agentの設定
vi /etc/neutron/dhcp_agent.ini

[DEFAULT]
enable_isolated_metadata = True

#設定読込み
systemctl restart neutron-server neutron-dhcp-agent


#nova.conf追記
vi /etc/nova/nova.conf

[neutron]
service_metadata_proxy = true
metadata_proxy_shared_secret = MetadataAgentPasswd123
1-8.MetadataAgentの設定

対象:Controllerのみ

#MetadataAgentの設定
vi /etc/neutron/metadata_agent.ini

[DEFAULT]
nova_metadata_host = controller01
metadata_proxy_shared_secret = MetadataAgentPasswd123

#設定読込み
systemctl restart nova-api neutron-metadata-agent
1-9.簡易動作確認

対象:Controllerのみ
以下のようになっていればOKです。

openstack network agent list

root@controller01:~# openstack network agent list
+--------------------------------------+----------------+--------------+-------------------+-------+-------+------------------------+
| ID                                   | Agent Type     | Host         | Availability Zone | Alive | State | Binary                 |
+--------------------------------------+----------------+--------------+-------------------+-------+-------+------------------------+
| 11fca003-8bb0-49b3-9e39-bc60b1a4cf17 | DHCP agent     | controller01 | nova              | :-)   | UP    | neutron-dhcp-agent     |
| b4cd6ed6-2321-4525-9ffa-b52dcbfe7293 | Metadata agent | controller01 | None              | :-)   | UP    | neutron-metadata-agent |
+--------------------------------------+----------------+--------------+-------------------+-------+-------+------------------------+

2.Open vSwitch(L2agent)のインストール

2-1.ML2の設定

対象:Controllerのみ

vi /etc/neutron/plugins/ml2/ml2_conf.ini

[ml2]
mechanism_drivers = l2population,openvswitch
type_drivers = local,flat,vlan,vxlan
tenant_network_types= vlan,vxlan

[ml2_type_vlan]
network_vlan_ranges = physnet1:32:63

[ml2_type_vxlan]
vni_ranges = 128:255

<補足1>
VlanやVxlanのレンジは任意に変更可能です。

[ml2_type_vlan]
network_vlan_ranges = physnet1:1024:2047

[ml2_type_vxlan]
vni_ranges = 512:4095

<補足2>
ens35以外にも外部NW用NICを複数増やしたい場合は以下のような設定も可能です。

[ml2_type_vlan]
network_vlan_ranges = physnet1:32:63,physnet2:64:95

<補足3>
今回は取り上げませんが、flatネットワークを使用する際は以下の設定を行います。

[ml2_type_flat]
flat_networks = physnet1
2-2.ドライバとOvSエージェントの設定

対象:全Node

apt install neutron-plugin-openvswitch-agent -y

vi /etc/neutron/plugins/ml2/openvswitch_agent.ini

[agent]
tunnel_types = vxlan
l2_population = true
vxlan_udp_port = 8472

[ovs]
bridge_mappings = physnet1:br-ens35
local_ip = 10.20.0.10x
##xは、Nodeごとに変更##

[securitygroup]
firewall_driver = noop

ovs-vsctl add-br br-ens35
ovs-vsctl add-port br-ens35 ens35
ovs-vsctl show

以下出力例です。

ovs-vsctl show

root@compute02:~# ovs-vsctl show
9a905c31-1f4a-48cd-aa3e-9d2fcb50bdf9
    Manager "ptcp:6640:127.0.0.1"
        is_connected: true
    Bridge "br-ens35"
        Port "br-ens35"
            Interface "br-ens35"
                type: internal
        Port "ens35"
            Interface "ens35"
    Bridge br-int
        Controller "tcp:127.0.0.1:6633"
            is_connected: true
        fail_mode: secure
        Port br-int
            Interface br-int
                type: internal
    ovs_version: "2.8.4"
2-3.DHCPエージェントの設定

対象:Controller

#dhcp_agent.iniの設定
vi /etc/neutron/dhcp_agent.ini

[DEFAULT]
interface_driver = openvswitch
dnsmasq_config_file = /etc/neutron/dnsmasq-neutron.conf


#dnsmasq-neutron.confの設定
vi /etc/neutron/dnsmasq-neutron.conf

dhcp-option-force=26,1450


#設定読込み
systemctl restart neutron-dhcp-agent
2-4.簡易動作確認

対象:Controller
以下のように出力されていればOKです。

openstack network agent list

root@controller01:~# openstack network agent list
+--------------------------------------+--------------------+--------------+-------------------+-------+-------+---------------------------+
| ID                                   | Agent Type         | Host         | Availability Zone | Alive | State | Binary                    |
+--------------------------------------+--------------------+--------------+-------------------+-------+-------+---------------------------+
| 11fca003-8bb0-49b3-9e39-bc60b1a4cf17 | DHCP agent         | controller01 | nova              | :-)   | UP    | neutron-dhcp-agent        |
| 16807ec4-c816-47cd-92eb-45e9e1410705 | Open vSwitch agent | controller01 | None              | :-)   | UP    | neutron-openvswitch-agent |
| 980aa42b-562f-47ae-97e1-015d5b600088 | Open vSwitch agent | compute02    | None              | :-)   | UP    | neutron-openvswitch-agent |
| b4cd6ed6-2321-4525-9ffa-b52dcbfe7293 | Metadata agent     | controller01 | None              | :-)   | UP    | neutron-metadata-agent    |
| ddc78656-71f5-40fc-a9e1-66b03d6de317 | Open vSwitch agent | compute01    | None              | :-)   | UP    | neutron-openvswitch-agent |
+--------------------------------------+--------------------+--------------+-------------------+-------+-------+---------------------------+

3.DVR(L3agent)のインストール

3-1.DVRのインストール&設定・OvS&Neutronの追加設定・Horizon設定

対象:Controllerのみ

#DVRのインストール&設定
apt install neutron-l3-agent -y

vi /etc/neutron/l3_agent.ini

[DEFAULT]
interface_driver = openvswitch
agent_mode = dvr_snat
handle_internal_only_routers = false

#OvSの追加設定
vi /etc/neutron/plugins/ml2/openvswitch_agent.ini

[agent]
enable_distributed_routing = True

#Neutronの追加設定
vi /etc/neutron/neutron.conf

[DEFAULT]
service_plugins = router,trunk

#Horizon設定
vi /etc/openstack-dashboard/local_settings.py

OPENSTACK_NEUTRON_NETWORK = {
    'enable_router': True,
    'enable_quotas': False,
    'enable_ipv6': False,
    'enable_distributed_router': True,
    'enable_ha_router': False,
    'enable_lb': False,
    'enable_firewall': False,
    'enable_vpn': False,
    'enable_fip_topology_check': False,
}

#設定読込み
systemctl restart neutron-l3-agent neutron-openvswitch-agent neutron-server apache2
3-2.DVRのインストール&設定・OvSの追加設定

対象:Computeのみ

#DVRのインストール&設定
apt install neutron-l3-agent -y

vi /etc/neutron/l3_agent.ini

[DEFAULT]
interface_driver = openvswitch
agent_mode = dvr
handle_internal_only_routers = false


#OvSの追加設定
vi /etc/neutron/plugins/ml2/openvswitch_agent.ini

[agent]
enable_distributed_routing = True

#設定読込み
systemctl restart neutron-l3-agent neutron-openvswitch-agent
3-3.簡易動作確認

対象:Controllerのみ
この時点で以下のように登録されていればOKです。

openstack network agent list

root@controller01:~# openstack network agent list
+--------------------------------------+--------------------+--------------+-------------------+-------+-------+---------------------------+
| ID                                   | Agent Type         | Host         | Availability Zone | Alive | State | Binary                    |
+--------------------------------------+--------------------+--------------+-------------------+-------+-------+---------------------------+
| 0fdbdf3d-978a-4698-87f5-1d9ec71ccdd7 | Metadata agent     | compute01    | None              | :-)   | UP    | neutron-metadata-agent    |
| 11fca003-8bb0-49b3-9e39-bc60b1a4cf17 | DHCP agent         | controller01 | nova              | :-)   | UP    | neutron-dhcp-agent        |
| 16807ec4-c816-47cd-92eb-45e9e1410705 | Open vSwitch agent | controller01 | None              | :-)   | UP    | neutron-openvswitch-agent |
| 514136b2-cfa0-42ca-8ee5-fe768c895c7c | L3 agent           | controller01 | nova              | :-)   | UP    | neutron-l3-agent          |
| 980aa42b-562f-47ae-97e1-015d5b600088 | Open vSwitch agent | compute02    | None              | :-)   | UP    | neutron-openvswitch-agent |
| b4cd6ed6-2321-4525-9ffa-b52dcbfe7293 | Metadata agent     | controller01 | None              | :-)   | UP    | neutron-metadata-agent    |
| bb83830a-dd80-4ab8-b030-ce1dc1999643 | Metadata agent     | compute02    | None              | :-)   | UP    | neutron-metadata-agent    |
| ddc78656-71f5-40fc-a9e1-66b03d6de317 | Open vSwitch agent | compute01    | None              | :-)   | UP    | neutron-openvswitch-agent |
| e31f5012-53c0-4e84-9c00-37b361a16a82 | L3 agent           | compute02    | nova              | :-)   | UP    | neutron-l3-agent          |
| fbae2b3d-5641-444f-a8eb-00ffc4f45a91 | L3 agent           | compute01    | nova              | :-)   | UP    | neutron-l3-agent          |
+--------------------------------------+--------------------+--------------+-------------------+-------+-------+---------------------------+

<補足>
L3 agentが表示されるまでに多少時間が掛かる場合があります。
そのときは、各Nodeで以下のように確認してみてください。

cat /var/log/neutron/neutron-l3-agent.log

root@controller01:~# cat /var/log/neutron/neutron-l3-agent.log
2019-05-28 08:40:40.631 9773 INFO neutron.common.config [-] Logging enabled!
2019-05-28 08:40:40.631 9773 INFO neutron.common.config [-] /usr/bin/neutron-l3-agent version 11.0.6
2019-05-28 08:40:40.754 9773 ERROR neutron.agent.l3.agent [-] An interface driver must be specified
2019-05-28 08:41:53.553 9847 INFO neutron.common.config [-] Logging enabled!
2019-05-28 08:41:53.553 9847 INFO neutron.common.config [-] /usr/bin/neutron-l3-agent version 11.0.6
2019-05-28 08:42:53.709 9847 ERROR neutron.common.rpc [req-58acf3df-e1c2-47a0-b83f-2aafa1e53e56 - - - - -] Timeout in RPC method get_service_plugin_list. Waiting for 10 seconds before next attempt. If the server is not down, consider increasing the rpc_response_timeout option as Neutron server(s) may be overloaded and unable to respond quickly enough.: MessagingTimeout: Timed out waiting for a reply to message ID 69bdb30bcf314476942d06106fa0b5f2
2019-05-28 08:42:53.711 9847 WARNING neutron.common.rpc [req-58acf3df-e1c2-47a0-b83f-2aafa1e53e56 - - - - -] Increasing timeout for get_service_plugin_list calls to 120 seconds. Restart the agent to restore it to the default value.: MessagingTimeout: Timed out waiting for a reply to message ID 69bdb30bcf314476942d06106fa0b5f2
2019-05-28 08:43:03.252 9847 WARNING neutron.agent.l3.agent [req-58acf3df-e1c2-47a0-b83f-2aafa1e53e56 - - - - -] l3-agent cannot contact neutron server to retrieve service plugins enabled. Check connectivity to neutron server. Retrying... Detailed message: Timed out waiting for a reply to message ID 69bdb30bcf314476942d06106fa0b5f2.: MessagingTimeout: Timed out waiting for a reply to message ID 69bdb30bcf314476942d06106fa0b5f2
2019-05-28 08:43:03.269 9847 INFO neutron.agent.agent_extensions_manager [req-f6aa92b3-2ba4-4cb4-9273-8cb9f54c5f43 - - - - -] Loaded agent extensions: []
2019-05-28 08:43:03.282 9847 INFO eventlet.wsgi.server [-] (9847) wsgi starting up on http:/var/lib/neutron/keepalived-state-change
2019-05-28 08:43:03.347 9847 INFO neutron.agent.l3.agent [-] L3 agent started
3-4.L2構成確認

対象:全Node
どのNodeでも構いませんので、以下のコマンドを打ってみてください。

ovs-vsctl show

root@compute02:~# ovs-vsctl show
c560fe9b-ea3c-4be6-8e94-109299e797aa
    Manager "ptcp:6640:127.0.0.1"
        is_connected: true
    Bridge "br-ens35"
        Controller "tcp:127.0.0.1:6633"
            is_connected: true
        fail_mode: secure
        Port "br-ens35"
            Interface "br-ens35"
                type: internal
        Port "phy-br-ens35"
            Interface "phy-br-ens35"
                type: patch
                options: {peer="int-br-ens35"}
        Port "ens35"
            Interface "ens35"
    Bridge br-tun
        Controller "tcp:127.0.0.1:6633"
            is_connected: true
        fail_mode: secure
        Port br-tun
            Interface br-tun
                type: internal
        Port patch-int
            Interface patch-int
                type: patch
                options: {peer=patch-tun}
    Bridge br-int
        Controller "tcp:127.0.0.1:6633"
            is_connected: true
        fail_mode: secure
        Port br-int
            Interface br-int
                type: internal
        Port patch-tun
            Interface patch-tun
                type: patch
                options: {peer=patch-int}
        Port "int-br-ens35"
            Interface "int-br-ens35"
                type: patch
                options: {peer="phy-br-ens35"}
    ovs_version: "2.8.4"

上記出力より、br-ens35, br-tun, br-intの3つのBridgeが全Nodeで作成されています。
図にすると、こんな↓イメージです。
f:id:metonymical:20190528110237p:plain
これが素の状態で、全Nodeで同一のBridge 構成となっています。
ここから、Network, Subnet, Port, VMインスタンスを作ったり、VMインスタンスからTrunkしてみたりすると、少しづつ複雑になり始めます。

3-5.各種確認

対象:全Node
以下のコマンドでPortやMacアドレステーブル、フローテーブルが確認可能です。

#Port確認
ovs-ofctl show br-ens35
ovs-ofctl show br-int
ovs-ofctl show br-tun

root@controller01:~# ovs-ofctl show br-ens35
OFPT_FEATURES_REPLY (xid=0x2): dpid:0000000c294300d2
n_tables:254, n_buffers:0
capabilities: FLOW_STATS TABLE_STATS PORT_STATS QUEUE_STATS ARP_MATCH_IP
actions: output enqueue set_vlan_vid set_vlan_pcp strip_vlan mod_dl_src mod_dl_dst mod_nw_src mod_nw_dst mod_nw_tos mod_tp_src mod_tp_dst
 1(ens35): addr:00:0c:29:43:00:d2
     config:     0
     state:      0
     current:    1GB-FD COPPER AUTO_NEG
     advertised: 10MB-HD 10MB-FD 100MB-HD 100MB-FD 1GB-FD COPPER AUTO_NEG
     supported:  10MB-HD 10MB-FD 100MB-HD 100MB-FD 1GB-FD COPPER AUTO_NEG
     speed: 1000 Mbps now, 1000 Mbps max
 2(phy-br-ens35): addr:62:2f:61:76:05:b2
     config:     0
     state:      0
     speed: 0 Mbps now, 0 Mbps max
 LOCAL(br-ens35): addr:00:0c:29:43:00:d2
     config:     PORT_DOWN
     state:      LINK_DOWN
     speed: 0 Mbps now, 0 Mbps max
OFPT_GET_CONFIG_REPLY (xid=0x4): frags=normal miss_send_len=0


#Macアドレステーブル確認
ovs-appctl fdb/show br-ens35
ovs-appctl fdb/show br-int
ovs-appctl fdb/show br-tun

root@controller01:~# ovs-appctl fdb/show br-ens35
 port  VLAN  MAC                Age
    1    30  6c:50:4d:d5:07:da  141
    1     0  2c:53:4a:01:27:67   94
    1   300  6c:50:4d:d5:07:da   92
    1    30  2c:53:4a:01:27:66   65
    1   300  2c:53:4a:01:27:66   65


#フローテーブル確認
ovs-ofctl dump-flows br-ens35
ovs-ofctl dump-flows br-int
ovs-ofctl dump-flows br-tun

root@controller01:~# ovs-ofctl dump-flows br-ens35
 cookie=0xa3dbef6a19c99333, duration=5955.130s, table=0, n_packets=0, n_bytes=0, priority=2,in_port="phy-br-ens35" actions=resubmit(,1)
 cookie=0xa3dbef6a19c99333, duration=5955.218s, table=0, n_packets=0, n_bytes=0, priority=0 actions=NORMAL
 cookie=0xa3dbef6a19c99333, duration=5955.130s, table=0, n_packets=4058, n_bytes=366211, priority=1 actions=resubmit(,3)
 cookie=0xa3dbef6a19c99333, duration=5955.130s, table=1, n_packets=0, n_bytes=0, priority=0 actions=resubmit(,2)
 cookie=0xa3dbef6a19c99333, duration=5955.129s, table=2, n_packets=0, n_bytes=0, priority=2,in_port="phy-br-ens35" actions=drop
 cookie=0xa3dbef6a19c99333, duration=5576.007s, table=3, n_packets=0, n_bytes=0, priority=2,dl_src=fa:16:3f:05:7d:26 actions=output:"phy-br-ens35"
 cookie=0xa3dbef6a19c99333, duration=5529.828s, table=3, n_packets=0, n_bytes=0, priority=2,dl_src=fa:16:3f:53:4c:80 actions=output:"phy-br-ens35"
 cookie=0xa3dbef6a19c99333, duration=5955.129s, table=3, n_packets=4058, n_bytes=366211, priority=1 actions=NORMAL

4.その他設定

直接Neutronには関係ありませんが、インスタンス周りで困るときがあるため、以下の設定を行っておきます。

4-1.NovaDB登録

対象:Controllerのみ
インスタンスが作成できたけど起動しない場合の対処。

openstack compute service list
su -s /bin/sh -c "nova-manage cell_v2 discover_hosts --verbose" nova
systemctl restart nova-api nova-consoleauth nova-scheduler nova-conductor nova-novncproxy

以下出力例です。

root@controller01:~# openstack compute service list
+----+------------------+--------------+----------+---------+-------+----------------------------+
| ID | Binary           | Host         | Zone     | Status  | State | Updated At                 |
+----+------------------+--------------+----------+---------+-------+----------------------------+
|  1 | nova-scheduler   | controller01 | internal | enabled | up    | 2019-05-28T01:26:14.000000 |
|  2 | nova-consoleauth | controller01 | internal | enabled | up    | 2019-05-28T01:26:17.000000 |
|  3 | nova-conductor   | controller01 | internal | enabled | up    | 2019-05-28T01:26:17.000000 |
|  7 | nova-compute     | compute01    | nova     | enabled | up    | 2019-05-28T01:26:14.000000 |
|  8 | nova-compute     | compute02    | nova     | enabled | up    | 2019-05-28T01:26:17.000000 |
+----+------------------+--------------+----------+---------+-------+----------------------------+

#上記のようにcompute01&02が表示されている状態であることを確認の上、以下のようにNovaDBへ登録します。

root@controller01:~# su -s /bin/sh -c "nova-manage cell_v2 discover_hosts --verbose" nova
Found 2 cell mappings.
Skipping cell0 since it does not contain hosts.
Getting computes from cell 'cell1': e0e3f86a-8b85-4184-9287-7e4dcd53db81
Checking host mapping for compute host 'compute01': 521aeaf7-1d0e-4aa9-81b4-d7f39397c33c
Creating host mapping for compute host 'compute01': 521aeaf7-1d0e-4aa9-81b4-d7f39397c33c
Checking host mapping for compute host 'compute02': d32c9aee-af7b-4b90-a767-56dc9897de5f
Creating host mapping for compute host 'compute02': d32c9aee-af7b-4b90-a767-56dc9897de5f
Found 2 unmapped computes in cell: e0e3f86a-8b85-4184-9287-7e4dcd53db81
4-2.MetadataAgent設定

対象:Computeのみ
インスタンスが起動したけど、メタデータ(KeypairとかPasswd設定ファイルなど)が取得できないときの対処。

#MetadataAgent設定
vi /etc/neutron/metadata_agent.ini

[DEFAULT]
nova_metadata_host = controller01
metadata_proxy_shared_secret = MetadataAgentPasswd123

#設定読込み
systemctl restart neutron-metadata-agent

<補足>
インスタンスUbuntuなど(Cirros以外)を使用する場合、Defaultで鍵認証となっているため、Keypairを取得させるか、Passwd設定&許可ファイルを取得されるなどの方法で、インスタンスssh接続します。*2

以上です。

5.最後に

少しづつ出来てきた感が出ていれば良いなと思います。
3-4.や3-5.に記載した素の状態をよく確認し構成を理解しておくと良いと思います。

*1:進める前に現段階での仮想マシンのクローンやスナップショットは取得しておくことをお勧めします。

*2:vncやvirsh consoleでも、Passwd設定ファイルを取得させないとログインできない場合もあるため。

Open Stack Neutron環境構築 その2:OpenStack のインストール

Open Stack(pike)のインストールを実施します。*1
構成などは前回記事を確認してください。

  1. 各種サービスなどのインストール
  2. Keystone
  3. Glance
  4. Nova1:Controller
  5. Nova2:Compute
  6. Horizon

1.各種サービスなどのインストール

対象:Controllerのみ

1-1.OpenStackクライアント
apt -y install python-openstackclient
1-2.MySQL
apt -y install mariadb-server python-pymysql

vi /etc/mysql/mariadb.conf.d/99-openstack.cnf

[mysqld]
bind-address = 10.10.0.100
default-storage-engine = innodb
innodb_file_per_table = on
max_connections = 4096
collation-server = utf8_general_ci
character-set-server = utf8

systemctl restart mysql

mysql_secure_installation
#パスワードは全てopenstackとします。

以下出力例です。*2

root@controller01:~# mysql_secure_installation

NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB
      SERVERS IN PRODUCTION USE!  PLEASE READ EACH STEP CAREFULLY!

In order to log into MariaDB to secure it, we'll need the current
password for the root user.  If you've just installed MariaDB, and
you haven't set the root password yet, the password will be blank,
so you should just press enter here.

Enter current password for root (enter for none): Enter
OK, successfully used password, moving on...

Setting the root password ensures that nobody can log into the MariaDB
root user without the proper authorisation.

Set root password? [Y/n] Enter
New password: openstackと入力
Re-enter new password: openstackと入力
Password updated successfully!
Reloading privilege tables..
 ... Success!


By default, a MariaDB installation has an anonymous user, allowing anyone
to log into MariaDB without having to have a user account created for
them.  This is intended only for testing, and to make the installation
go a bit smoother.  You should remove them before moving into a
production environment.

Remove anonymous users? [Y/n] Enter
 ... Success!

Normally, root should only be allowed to connect from 'localhost'.  This
ensures that someone cannot guess at the root password from the network.

Disallow root login remotely? [Y/n] Enter
 ... Success!

By default, MariaDB comes with a database named 'test' that anyone can
access.  This is also intended only for testing, and should be removed
before moving into a production environment.

Remove test database and access to it? [Y/n] Enter
 - Dropping test database...
 ... Success!
 - Removing privileges on test database...
 ... Success!

Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.

Reload privilege tables now? [Y/n] Enter
 ... Success!

Cleaning up...

All done!  If you've completed all of the above steps, your MariaDB
installation should now be secure.

Thanks for using MariaDB!
1-3.RabbitMQ
apt -y install rabbitmq-server

rabbitmqctl add_user openstack rabbit
rabbitmqctl set_permissions openstack ".*" ".*" ".*"
1-4.Memcached
apt -y install memcached python-memcache

vi /etc/memcached.conf

#-l 127.0.0.1
-l 10.10.0.100

systemctl restart memcached

2.Keystone

対象:Controllerのみ

2-1.DBの設定
mysql

CREATE DATABASE keystone;
GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'localhost' IDENTIFIED BY 'keystone';
GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'%' IDENTIFIED BY 'keystone';
quit;

以下出力例です。

root@controller01:~# mysql
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 40
Server version: 10.0.38-MariaDB-0ubuntu0.16.04.1 Ubuntu 16.04

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> CREATE DATABASE keystone;
Query OK, 1 row affected (0.00 sec)

MariaDB [(none)]> GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'localhost' IDENTIFIED BY 'keystone';
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'%' IDENTIFIED BY 'keystone';
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> quit;
Bye
root@controller01:~#
2-2.インストールと設定
apt -y install keystone apache2 libapache2-mod-wsgi

vi /etc/keystone/keystone.conf

[database]
#connection = sqlite:////var/lib/keystone/keystone.db
connection = mysql+pymysql://keystone:keystone@controller01/keystone

[token]
provider = fernet
2-3.DB登録と初期化
su -s /bin/sh -c "keystone-manage db_sync" keystone

keystone-manage fernet_setup \
--keystone-user keystone --keystone-group keystone

keystone-manage credential_setup \
--keystone-user keystone --keystone-group keystone
2-4.Endpoint設定
keystone-manage bootstrap --bootstrap-password openstack \
--bootstrap-admin-url http://controller01:35357/v3/ \
--bootstrap-internal-url http://controller01:5000/v3/ \
--bootstrap-public-url http://controller01:5000/v3/ \
--bootstrap-region-id RegionOne
2-5.Webサービス設定&再起動
sed -i '1s/^/ServerName controller01\n&/' /etc/apache2/apache2.conf
systemctl restart apache2
2-6.環境変数ファイル生成
cat >> ~/adminrc <<EOF
export OS_PROJECT_DOMAIN_NAME=default
export OS_USER_DOMAIN_NAME=default
export OS_PROJECT_NAME=admin
export OS_USERNAME=admin
export OS_PASSWORD=openstack
export OS_AUTH_URL=http://controller01:35357/v3
export OS_IDENTITY_API_VERSION=3
EOF

cat >> ~/demorc <<EOF
export OS_PROJECT_DOMAIN_NAME=default
export OS_USER_DOMAIN_NAME=default
export OS_PROJECT_NAME=demo
export OS_USERNAME=demo
export OS_PASSWORD=demo
export OS_AUTH_URL=http://controller01:35357/v3
export OS_IDENTITY_API_VERSION=3
EOF

source adminrc

#これ以降、openstackコマンドを打つときは、
#sshログイン直後に上記adminrcを読み込んでください。
#読み込まずにopenstackコマンドを打つと以下のエラーが表示されます。
#demorcはほぼ使用しないと思いますが念のため。

root@controller01:~# openstack endpoint list
Missing value auth-url required for auth plugin password
2-7.動作確認
openstack endpoint list
openstack service list
2-8.ProjectやRoleの登録
openstack project create --description "Service Project" service
openstack project create --description "Demo Project" demo
openstack user create demo --password=demo
openstack role create user
openstack role add --project demo --user demo user

3.Glance

対象:Controllerのみ

3-1.DBの設定
mysql

CREATE DATABASE glance;
GRANT ALL PRIVILEGES ON glance.* TO 'glance'@'localhost' IDENTIFIED BY 'glance';
GRANT ALL PRIVILEGES ON glance.* TO 'glance'@'%' IDENTIFIED BY 'glance';
quit;

3-2.ユーザ登録・サービス登録・Endpoint作成・インストール
openstack user create glance --domain default --password=glance
openstack role add --project service --user glance admin

openstack service create --name glance \
--description "OpenStack Image" image

openstack endpoint create --region RegionOne \
image public http://controller01:9292

openstack endpoint create --region RegionOne \
image internal http://controller01:9292

openstack endpoint create --region RegionOne \
image admin http://controller01:9292

apt -y install glance
3-3.glance-api.comf設定
vi /etc/glance/glance-api.conf

[database]
connection = mysql+pymysql://glance:glance@controller01/glance

[keystone_authtoken]
auth_uri = http://controller01:5000
auth_url = http://controller01:35357
memcached_servers = controller01:11211
auth_type = password
user_domain_name = default
project_domain_name = default
project_name = service
username = glance
password = glance

[paste_deploy]
flavor = keystone

[glance_store]
stores = file,http
default_store = file
filesystem_store_datadir = /var/lib/glance/images
3-4.glance-registry.comf設定
vi /etc/glance/glance-registry.conf

[database]
connection = mysql+pymysql://glance:glance@controller01/glance

[keystone_authtoken]
auth_uri = http://controller01:5000
auth_url = http://controller01:35357
memcached_servers = controller01:11211
auth_type = password
user_domain_name = default
project_domain_name = default
project_name = service
username = glance
password = glance

[paste_deploy]
flavor = keystone
3-5.DB登録&設定ファイル読込み
su -s /bin/sh -c "glance-manage db_sync" glance

systemctl restart glance-registry glance-api
3-6.イメージ登録
mkdir /tmp/images

#cirrosの登録
wget -P /tmp/images http://download.cirros-cloud.net/0.4.0/cirros-0.4.0-x86_64-disk.img

openstack image create "cirros-0.4.0" \
--file /tmp/images/cirros-0.4.0-x86_64-disk.img \
--disk-format qcow2 \
--container-format bare \
--public

#ubuntuの登録
wget -P /tmp/images http://cloud-images.ubuntu.com/xenial/current/xenial-server-cloudimg-amd64-disk1.img

openstack image create "ubuntu-xenial-16.04" \
--file /tmp/images/xenial-server-cloudimg-amd64-disk1.img \
--disk-format qcow2 \
--container-format bare \
--public

#登録イメージの確認
openstack image list

root@controller01:~# openstack image list
+--------------------------------------+---------------------+--------+
| ID                                   | Name                | Status |
+--------------------------------------+---------------------+--------+
| 749433d2-2f69-47bf-9de7-a0a9e3a72bb6 | cirros-0.4.0        | active |
| 6819234c-4757-41d8-867a-c3b44a9f5a47 | ubuntu-xenial-16.04 | active |
+--------------------------------------+---------------------+--------+
3-7.簡易動作確認

この時点で以下のように登録されていればOKです。

openstack endpoint list
openstack service list

root@controller01:~# openstack endpoint list
+----------------------------------+-----------+--------------+--------------+---------+-----------+-------------------------------+
| ID                               | Region    | Service Name | Service Type | Enabled | Interface | URL                           |
+----------------------------------+-----------+--------------+--------------+---------+-----------+-------------------------------+
| 266e4c678cda43ab9bec4a70ddccfb97 | RegionOne | glance       | image        | True    | internal  | http://controller01:9292      |
| 6256b9ec413d4a9ca8bc1feb90448260 | RegionOne | glance       | image        | True    | public    | http://controller01:9292      |
| 7ab5e26b0f524c60a9ba33870283940a | RegionOne | keystone     | identity     | True    | admin     | http://controller01:35357/v3/ |
| e414354758e04ac7802ba300a864258f | RegionOne | keystone     | identity     | True    | internal  | http://controller01:5000/v3/  |
| e8a1585c91754424a2c7432e2bb31116 | RegionOne | keystone     | identity     | True    | public    | http://controller01:5000/v3/  |
| f1fb03de6fb24d6e818b239ad0276083 | RegionOne | glance       | image        | True    | admin     | http://controller01:9292      |
+----------------------------------+-----------+--------------+--------------+---------+-----------+-------------------------------+
root@controller01:~# openstack service list
+----------------------------------+----------+----------+
| ID                               | Name     | Type     |
+----------------------------------+----------+----------+
| 42e7a20b30944518ae5c345aab323d3d | glance   | image    |
| f3d100b18b794f649ee80c651787eb22 | keystone | identity |
+----------------------------------+----------+----------+

4.Nova1:Controller

対象:Controllerのみ

4-1.DBの設定・ユーザ登録・サービス登録・Endpoint作成
#DB設定
mysql

CREATE DATABASE nova;
CREATE DATABASE nova_api;
CREATE DATABASE nova_cell0;
GRANT ALL PRIVILEGES ON nova.* TO 'nova'@'localhost' IDENTIFIED BY 'nova';
GRANT ALL PRIVILEGES ON nova.* TO 'nova'@'%' IDENTIFIED BY 'nova';
GRANT ALL PRIVILEGES ON nova_api.* TO 'nova'@'localhost' IDENTIFIED BY 'nova';
GRANT ALL PRIVILEGES ON nova_api.* TO 'nova'@'%' IDENTIFIED BY 'nova';
GRANT ALL PRIVILEGES ON nova_cell0.* TO 'nova'@'localhost' IDENTIFIED BY 'nova';
GRANT ALL PRIVILEGES ON nova_cell0.* TO 'nova'@'%' IDENTIFIED BY 'nova';
quit;

#ユーザ登録
openstack user create nova --domain default --password=nova
openstack user create placement \
--domain default --password=placement

openstack role add --project service --user nova admin
openstack role add --project service --user placement admin

#サービス登録
openstack service create --name nova \
--description "OpenStack Compute" compute
openstack service create --name placement \
--description "Placement API" placement

#Endpoint作成
openstack endpoint create --region RegionOne \
compute public http://controller01:8774/v2.1
openstack endpoint create --region RegionOne \
compute internal http://controller01:8774/v2.1
openstack endpoint create --region RegionOne \
compute admin http://controller01:8774/v2.1

openstack endpoint create --region RegionOne \
placement public http://controller01:8778
openstack endpoint create --region RegionOne \
placement internal http://controller01:8778
openstack endpoint create --region RegionOne \
placement admin http://controller01:8778
4-2.インストール・nova.conf設定
#インストール
apt -y install nova-api nova-conductor nova-consoleauth \
nova-novncproxy nova-scheduler nova-placement-api

#nova.conf設定
vi /etc/nova/nova.conf

[DEFAULT]
transport_url = rabbit://openstack:rabbit@controller01
my_ip = 10.10.0.100

[api_database]
#connection = sqlite:////var/lib/nova/nova_api.sqlite
connection = mysql+pymysql://nova:nova@controller01/nova_api

[database]
#connection = sqlite:////var/lib/nova/nova.sqlite
connection = mysql+pymysql://nova:nova@controller01/nova

[vnc]
enabled = true
vncserver_listen = 10.10.0.100
vncserver_proxyclient_address = 10.10.0.100

[api]
auth_strategy= keystone

[keystone_authtoken]
auth_uri = http://controller01:5000
auth_url = http://controller01:35357
memcached_servers = controller01:11211
auth_type = password
project_domain_name = Default
user_domain_name = Default
project_name = service
username = nova
password = nova

[glance]
api_servers = http://controller01:9292

[oslo_concurrency]
lock_path = /var/lib/nova/tmp

[placement]
#os_region_name = openstack
os_region_name = RegionOne
auth_url = http://controller01:35357/v3
auth_type = password
project_domain_name = Default
user_domain_name = Default
project_name = service
username = placement
password = placement
4-3.DB登録&設定ファイル読込み
su -s /bin/sh -c "nova-manage api_db sync" nova
su -s /bin/sh -c "nova-manage cell_v2 map_cell0" nova

su -s /bin/sh -c "nova-manage cell_v2 create_cell --name=cell1 --verbose" nova
su -s /bin/sh -c "nova-manage db sync" nova

systemctl restart nova-api nova-consoleauth nova-scheduler nova-conductor nova-novncproxy

以下出力例です。

root@controller01:~# su -s /bin/sh -c "nova-manage api_db sync" nova
root@controller01:~# su -s /bin/sh -c "nova-manage cell_v2 map_cell0" nova
root@controller01:~# su -s /bin/sh -c "nova-manage cell_v2 create_cell --name=cell1 --verbose" nova
e0e3f86a-8b85-4184-9287-7e4dcd53db81
root@controller01:~# su -s /bin/sh -c "nova-manage db sync" nova
/usr/lib/python2.7/dist-packages/pymysql/cursors.py:166: Warning: (1831, u'Duplicate index `block_device_mapping_instance_uuid_virtual_name_device_name_idx`. This is deprecated and will be disallowed in a future release.')
  result = self._query(query)
/usr/lib/python2.7/dist-packages/pymysql/cursors.py:166: Warning: (1831, u'Duplicate index `uniq_instances0uuid`. This is deprecated and will be disallowed in a future release.')
  result = self._query(query)
root@controller01:~# systemctl restart nova-api nova-consoleauth nova-scheduler nova-conductor nova-novncproxy
root@controller01:~#

This is deprecated and will be disallowed in a future release.と表示されますが、このまま先に進めてください。

<補足>
上記と似たようなコマンドで、以下の設定を実施する必要があります。
後ほど設定しますので現段階では不要です。

su -s /bin/sh -c "nova-manage cell_v2 discover_hosts --verbose" nova
4-4.簡易動作確認

この時点で以下のように登録されていればOKです。

openstack endpoint list
openstack service list

root@controller01:~# openstack endpoint list
+----------------------------------+-----------+--------------+--------------+---------+-----------+-------------------------------+
| ID                               | Region    | Service Name | Service Type | Enabled | Interface | URL                           |
+----------------------------------+-----------+--------------+--------------+---------+-----------+-------------------------------+
| 266e4c678cda43ab9bec4a70ddccfb97 | RegionOne | glance       | image        | True    | internal  | http://controller01:9292      |
| 4a8adf71ef9848b096819cf12e54c747 | RegionOne | placement    | placement    | True    | public    | http://controller01:8778      |
| 6256b9ec413d4a9ca8bc1feb90448260 | RegionOne | glance       | image        | True    | public    | http://controller01:9292      |
| 7ab5e26b0f524c60a9ba33870283940a | RegionOne | keystone     | identity     | True    | admin     | http://controller01:35357/v3/ |
| 8578d6dedb1742e2a190b261cddd831b | RegionOne | placement    | placement    | True    | admin     | http://controller01:8778      |
| 92a1b113381d4bd692879d335776928b | RegionOne | nova         | compute      | True    | admin     | http://controller01:8774/v2.1 |
| a8a9533b8b6345a1ba9fbedf840434d8 | RegionOne | nova         | compute      | True    | public    | http://controller01:8774/v2.1 |
| de3c9c2ca4484068b7e24a1dca3064a9 | RegionOne | placement    | placement    | True    | internal  | http://controller01:8778      |
| e414354758e04ac7802ba300a864258f | RegionOne | keystone     | identity     | True    | internal  | http://controller01:5000/v3/  |
| e8a1585c91754424a2c7432e2bb31116 | RegionOne | keystone     | identity     | True    | public    | http://controller01:5000/v3/  |
| f1fb03de6fb24d6e818b239ad0276083 | RegionOne | glance       | image        | True    | admin     | http://controller01:9292      |
| fe3a19d428c24042acb57218376f5fa6 | RegionOne | nova         | compute      | True    | internal  | http://controller01:8774/v2.1 |
+----------------------------------+-----------+--------------+--------------+---------+-----------+-------------------------------+

root@controller01:~# openstack service list
+----------------------------------+-----------+-----------+
| ID                               | Name      | Type      |
+----------------------------------+-----------+-----------+
| 35ae7499a8474de6b2650335cee9c38e | placement | placement |
| 42e7a20b30944518ae5c345aab323d3d | glance    | image     |
| bf8c25de6879401ea107f0462e8da1a4 | nova      | compute   |
| f3d100b18b794f649ee80c651787eb22 | keystone  | identity  |
+----------------------------------+-----------+-----------+

5.Nova2:Compute

対象:Computeのみ
x」となっている箇所は、Compute01と02でそれぞれ固有の値*3を入れる必要があります。

5-1.インストール・nova.conf設定・設定読込み
#インストール
apt -y install nova-compute

#nova.conf設定
vi /etc/nova/nova.conf

[DEFAULT]
transport_url = rabbit://openstack:rabbit@controller01
my_ip = 10.10.0.10x
##xについて##
#compute01=1, compute02=2となります。

[api]
auth_strategy= keystone

[keystone_authtoken]
auth_uri = http://controller01:5000
auth_url = http://controller01:35357
memcached_servers = controller01:11211
auth_type = password
project_domain_name = Default
user_domain_name = Default
project_name = service
username = nova
password = nova

[vnc]
vncserver_proxyclient_address = 10.10.0.10x
enabled = True
vncserver_listen = 0.0.0.0
novncproxy_base_url = http://controller01:6080/vnc_auto.html
##xについて、上記と同様です##

[glance]
api_servers = http://controller01:9292

[oslo_concurrency]
lock_path = /var/lib/nova/tmp

[placement]
#os_region_name = openstack
os_region_name = RegionOne
auth_url = http://controller01:35357/v3
auth_type = password
project_domain_name = Default
user_domain_name = Default
project_name = service
username = placement
password = placement

##VMWare上のu16.04の場合##
[libvirt]
hw_machine_type = x86_64=pc-i440fx-xenial

#設定読込み
systemctl restart nova-compute
5-2.簡易動作確認

この時点で以下のようにCompute01と02が登録されていればOKです。
Controller01で以下のコマンドにて確認してください。

openstack compute service list

root@controller01:~# openstack compute service list
+----+------------------+--------------+----------+---------+-------+----------------------------+
| ID | Binary           | Host         | Zone     | Status  | State | Updated At                 |
+----+------------------+--------------+----------+---------+-------+----------------------------+
|  1 | nova-scheduler   | controller01 | internal | enabled | up    | 2019-05-27T14:07:43.000000 |
|  2 | nova-consoleauth | controller01 | internal | enabled | up    | 2019-05-27T14:07:43.000000 |
|  3 | nova-conductor   | controller01 | internal | enabled | up    | 2019-05-27T14:07:44.000000 |
|  7 | nova-compute     | compute01    | nova     | enabled | up    | 2019-05-27T14:07:45.000000 |
|  8 | nova-compute     | compute02    | nova     | enabled | up    | 2019-05-27T14:07:41.000000 |
+----+------------------+--------------+----------+---------+-------+----------------------------+

6.Horizon

対象:Controllerのみ

6-1.インストール・nova.conf設定・設定読込み
#インストール
apt -y install openstack-dashboard

#nova.conf設定
vi /etc/openstack-dashboard/local_settings.py

#Defaultで以下の設定が入っていますが、全てコメントアウトしてください。
#OPENSTACK_HOST = "127.0.0.1"
#OPENSTACK_KEYSTONE_URL = "http://%s:5000/v2.0" % OPENSTACK_HOST
#OPENSTACK_KEYSTONE_DEFAULT_ROLE = "_member_"

#以下の設定を投入。
OPENSTACK_HOST = "controller01"
OPENSTACK_KEYSTONE_URL = "http://%s:5000/v3" % OPENSTACK_HOST
OPENSTACK_KEYSTONE_DEFAULT_ROLE = "user"
OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT = True
OPENSTACK_KEYSTONE_DEFAULT_DOMAIN = "Default"

#OPENSTACK_API_VERSIONSの設定は、Defaultでコメントアウトされているため、
#以下の設定をそのまま投入してください。
OPENSTACK_API_VERSIONS = {
    "identity": 3,
    "image": 2,
    "volume": 2,
}

#Defaultで以下の設定が入っていますが、全てコメントアウトしてください。
#かなり画面をスクロールしないと最後まで表示されないと思います。
#OPENSTACK_NEUTRON_NETWORK = {
#    'enable_router': True,
#    'enable_quotas': True,
#    'enable_ipv6': True,
#    'enable_distributed_router': False,
#    'enable_ha_router': False,
#    'enable_fip_topology_check': True,

    # Default dns servers you would like to use when a subnet is
    # created.  This is only a default, users can still choose a different
    # list of dns servers when creating a new subnet.
    # The entries below are examples only, and are not appropriate for
    # real deployments
    # 'default_dns_nameservers': ["8.8.8.8", "8.8.4.4", "208.67.222.222"],

    # Set which provider network types are supported. Only the network types
    # in this list will be available to choose from when creating a network.
    # Network types include local, flat, vlan, gre, vxlan and geneve.
    # 'supported_provider_types': ['*'],

    # You can configure available segmentation ID range per network type
    # in your deployment.
    # 'segmentation_id_range': {
    #     'vlan': [1024, 2048],
    #     'vxlan': [4094, 65536],
    # },

    # You can define additional provider network types here.
    # 'extra_provider_types': {
    #     'awesome_type': {
    #         'display_name': 'Awesome New Type',
    #         'require_physical_network': False,
    #         'require_segmentation_id': True,
    #     }
    # },

    # Set which VNIC types are supported for port binding. Only the VNIC
    # types in this list will be available to choose from when creating a
    # port.
    # VNIC types include 'normal', 'direct', 'direct-physical', 'macvtap',
    # 'baremetal' and 'virtio-forwarder'
    # Set to empty list or None to disable VNIC type selection.
#    'supported_vnic_types': ['*'],

    # Set list of available physical networks to be selected in the physical
    # network field on the admin create network modal. If it's set to an empty
    # list, the field will be a regular input field.
    # e.g. ['default', 'test']
#    'physical_networks': [],

#}

#以下の設定を投入。
#現段階では全てFalseでOKです。後でrouterとdistributed_routerをTrueにします。
OPENSTACK_NEUTRON_NETWORK = {
    'enable_router': False,
    'enable_quotas': False,
    'enable_ipv6': False,
    'enable_distributed_router': False,
    'enable_ha_router': False,
    'enable_lb': False,
    'enable_firewall': False,
    'enable_vpn': False,
    'enable_fip_topology_check': False,
}

#DEFAULT_THEME = 'ubuntu'
DEFAULT_THEME = 'default'

#設定読込み
systemctl reload apache2
6-2.簡易動作確認

以下のURLにアクセスし、ログインしてください。

http://controller01/horizon/
domain default
username admin
password openstack

ログイン画面は以下の通りです。
f:id:metonymical:20190527234147p:plain

ログイン後、いくつかのページが開ければOKです。
f:id:metonymical:20190527234201p:plain

以上です。

7.最後に

Neutron+OvS+DVR&Trunkをメインの内容にしたいと考えていたため、OpenStack のインストールまで書くのはどうかな?と正直悩みました。
RDO(PackStack)やDevStackを使えば、サクッとできると思うので。。。

しかし、物理筐体のNW周りからスタートしたこと*4により、

  • 物理NW周り
  • OpenStackの主要コンポーネント準備
  • Neutron:NWシステム(dhcp&metadata含む)
  • OvS:L2agent
  • DVR:L3agent
  • Trunk:L2トランク

という風に、段階的に構築していくことで、
より理解が深まりやすいのではないか?と考えました。

最初からDevStackなどで構築してしまうと、とりあえずDNSでLookupしてPing通るようになったけど、そこから自分がやりたい構成に変更する場合は、どこをいじったらいいのか?すぐにはピンと来ないかなと考えたからです。

というのも、
今回の構成を実際に構築して理解した上で
 L2agentであれば、LinuxBridge
 L3agentであれば、スタンドアローンRouterやHA Router(VRRP)
に変更することは容易いです。

また、Tungsten FabricやMidoNetに構成変更することも、今回の構成を理解していれば、それほど敷居は高くないかなと考えています。
なので、復習の意味も込めて、OpenStackのインストールも書くことにしました。

*1:進める前に現段階での仮想マシンのクローンやスナップショットは取得しておくことをお勧めします。

*2:以降、大事な箇所のみ出力例を記載します。

*3:compute01=1, compute02=2となります。今後もちょくちょく登場するので気を付けてください。

*4:今回はOpenStackのHostOSはVMWare上の仮想マシンですが…