Aus verschiedenen Gründen habe ich neulich wieder Dokumentation gelesen - konkret ging es um die Erstellung von Packages - quasi den T-Shirt-Sizes - in Triton. Denn zwar gibt es schon länger den neuen bhyve Hypervisor auf der Plattform, aber "normale User" können ihn noch nicht verwenden, weil es noch keine Packages gibt, die ihn benutzen würden. Beim Lesen der Dokumentation fiel dann auf, dass um die neue Funktion "flexible diskspace" für bhyve-VMs benutzen zu können, ein relativ aktuelles Platform Image (PI) auf dem Headnode und den Compute Nodes (CN) gestartet sein muß. Da also alle Nodes einmal gebootet werden mußten, bot es sich an, gleichzeitig noch eine weitere Triton-Funktion zu aktivieren: virtuelle Netzwerke - in Triton "Fabrics" genannt.
Ich hatte im August 2015 das Konzept schonmal erläutert. Zur Einrichtung habe ich diesmal mit Unterstützung einer netten SE-Kollegin ein tagged VLAN zusätzlich zu dem dort schon vorhandenen native VLAN auf dem externen Interface der Nodes konfigurieren lassen. Dies fungiert als "underlay network" - alle Nodes, auf denen virtuelle Netzwerke verfügbar sein sollen, müssen ein Interface darin haben. Das Vorgehen ist in der Dokumentation unter Setup Fabric Networks beschrieben. Nach dem nächsten reboot hat jeder so konfigurierte Server dann eine enstprechende VNIC in dem gewünschten VLAN:
[root@hh24-gts2-de28 (de-gt-2) ~]# ifconfig sdc_underlay0
sdc_underlay0: flags=201000843<UP,BROADCAST,RUNNING,MULTICAST,IPv4,CoS> mtu 9000 index 3
inet 172.20.2.24 netmask ffffff00 broadcast 172.20.2.255
ether 90:b8:d0:6d:c0:83
[root@hh24-gts2-de28 (de-gt-2) ~]# dladm show-vnic
LINK OVER SPEED MACADDRESS MACADDRTYPE VID ZONE
sdc_underlay0 igb2 1000 90:b8:d0:6d:c0:83 fixed 1715 --
net0 igb0 0 90:b8:d0:46:93:19 fixed 0 81dcfe12-788f-4c97-bfae-1959e7e77e9e
net0 sdc_overlay5556037 0 90:b8:d0:96:f1:32 fixed 2 ab4203a9-75f9-4ef8-bb6f-942ba24bdd47
Vermutlich weil ich schonmal eine Fabric-Konfiguration in diesem Datacenter hatte, stehen den Usern damit sofort virtuelle Netzwerke zur Verfügung:
root@e3b75fc5-3621-cdd8-f9dd-c9acbf4a37e9:~# triton network ls
SHORTID NAME SUBNET GATEWAY FABRIC VLAN PUBLIC
2fa4d4ed My-Fabric-Network 192.168.128.0/22 192.168.128.1 true 2 false
aa3f924b extpool - - - - true
bc7d2db4 sdc_nat - - - - true
Und jetzt endlich zu NFS: Shared Storage ist in Triton - und generell in der Cloud - eigentlich ein Anti-Pattern. Das haben inzwischen auch andere bermerkt. Aber wie es halt so ist, geht es eben doch nicht ohne. Und deshalb hat Joyent schon vor einiger Zeit den RFD Network Shared Storage for Triton angelegt und dann umgesetzt. In einem der letzten Releases wurde dann volapiv2 verfügbar gemacht und da ist es natürlich sinnvoll, das Ganze mal zu testen. Voraussetzung für die Konfiguration von NFS shared volumes ist das Vorhandensein von Fabric networks - und die hatten wir ja oben schon eingerichtet:
[root@headnode (de-gt-2) ~]# sdcadm experimental nfs-volumes docker
Getting versions for image dependencies: cnapi, vmapi, volapi, workflow, docker
Checking dependencies are up to date
Checking platform version dependencies
Enabling docker has no platform dependency
Checking if experimental_docker_nfs_shared_volumes=true in SDC app...
Setting experimental_docker_nfs_shared_volumes to true in SDC app...
experimental_docker_nfs_shared_volumes set to true on SDC app
Enabled docker NFS volumes support
[root@headnode (de-gt-2) ~]# sdcadm experimental nfs-volumes cloudapi
Getting versions for image dependencies: cnapi, vmapi, volapi, workflow, cloudapi
Checking dependencies are up to date
Checking platform version dependencies
Enabling cloudapi has no platform dependency
Checking if experimental_cloudapi_nfs_shared_volumes=true in SDC app...
Setting experimental_cloudapi_nfs_shared_volumes to true in SDC app...
experimental_cloudapi_nfs_shared_volumes set to true on SDC app
Enabled cloudapi NFS volumes support
[root@headnode (de-gt-2) ~]# sdcadm experimental nfs-volumes cloudapi-automount
Feature cloudapi-automount has no image dependencies
Checking platform version dependencies
Getting servers list
Checking if experimental_cloudapi_automount_nfs_shared_volumes=true in SDC app...
Setting experimental_cloudapi_automount_nfs_shared_volumes to true in SDC app...
experimental_cloudapi_automount_nfs_shared_volumes set to true on SDC app
Enabled cloudapi-automount NFS volumes support
[root@headnode (de-gt-2) ~]# sdcadm experimental nfs-volumes docker-automount
Feature docker-automount has no image dependencies
Checking platform version dependencies
Getting servers list
Checking if experimental_docker_automount_nfs_shared_volumes=true in SDC app...
Setting experimental_docker_automount_nfs_shared_volumes to true in SDC app...
experimental_docker_automount_nfs_shared_volumes set to true on SDC app
Enabled docker-automount NFS volumes support
Und so sieht das dann für den User aus:
root@e3b75fc5-3621-cdd8-f9dd-c9acbf4a37e9:~# triton network list
SHORTID NAME SUBNET GATEWAY FABRIC VLAN PUBLIC
2fa4d4ed My-Fabric-Network 192.168.128.0/22 192.168.128.1 true 2 false
aa3f924b extpool - - - - true
bc7d2db4 sdc_nat - - - - true
root@e3b75fc5-3621-cdd8-f9dd-c9acbf4a37e9:~# triton volume create -n testvolume -s 10G -N 2fa4d4ed
Creating volume testvolume (e99b5d90-2678-6d43-9b59-dff0d316b5eb)
root@e3b75fc5-3621-cdd8-f9dd-c9acbf4a37e9:~# triton volume ls
SHORTID NAME SIZE TYPE STATE AGE
e99b5d90 testvolume 10240 tritonnfs creating 0s
root@e3b75fc5-3621-cdd8-f9dd-c9acbf4a37e9:~# triton volume ls
SHORTID NAME SIZE TYPE STATE AGE
e99b5d90 testvolume 10240 tritonnfs ready 0s
root@e3b75fc5-3621-cdd8-f9dd-c9acbf4a37e9:~# triton volume ls -l
ID NAME SIZE TYPE RESOURCE STATE CREATED
e99b5d90-2678-6d43-9b59-dff0d316b5eb testvolume 10240 tritonnfs 192.168.128.5:/zones/ab4203a9-75f9-4ef8-bb6f-942ba24bdd47/data ready -
Auf der Serverseite wird eine SmartOS-Zone als NFS-Server gestartet:
[root@hh24-gts2-de28 (de-gt-2) ~]# vmadm list
UUID TYPE RAM STATE ALIAS
ab4203a9-75f9-4ef8-bb6f-942ba24bdd47 OS 256 running nfs-shared-volume-e99b5d90-2678-6d43-9b59-dff0d316b5eb
81dcfe12-788f-4c97-bfae-1959e7e77e9e OS 8192 running moray1
[root@hh24-gts2-de28 (de-gt-2) ~]# zfs list -r zones/ab4203a9-75f9-4ef8-bb6f-942ba24bdd47
NAME USED AVAIL REFER MOUNTPOINT
zones/ab4203a9-75f9-4ef8-bb6f-942ba24bdd47 9,00G 1,00G 48,7M /zones/ab4203a9-75f9-4ef8-bb6f-942ba24bdd47
zones/ab4203a9-75f9-4ef8-bb6f-942ba24bdd47/data 8,99G 1,00G 8,99G /zones/ab4203a9-75f9-4ef8-bb6f-942ba24bdd47/data
Wenn man dann eine Instanz erzeugt, die ein Netzwerkinterface in diesem virtuellen Netz hat, kann sie sich das Volume mounten:
ubuntu@a1bb03ff-2ab9-4298-826b-927d768a1dea:~$ ifconfig net1
net1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 8500
inet 192.168.128.9 netmask 255.255.252.0 broadcast 192.168.131.255
inet6 fe80::92b8:d0ff:fe12:2735 prefixlen 64 scopeid 0x20<link>
ether 90:b8:d0:12:27:35 txqueuelen 1000 (Ethernet)
RX packets 9 bytes 732 (732.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 19 bytes 1510 (1.5 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
root@a1bb03ff-2ab9-4298-826b-927d768a1dea:~# mount -t nfs 192.168.128.5:/zones/ab4203a9-75f9-4ef8-bb6f-942ba24bdd47/data /nfs
root@a1bb03ff-2ab9-4298-826b-927d768a1dea:~#
Wichtig! Vorher das nfs-common
Paket installieren.
Der aufmerksame Leser wird sich jetzt ggfs. fragen "und was hat es mit dem automount auf sich". Das habe ich mich auch gefragt und bin dabei auf einen Bugview-Artikel gestossen. Offenbar gibt es einen bisher nicht dokumentierten Parameter -v
. Damit kann man einerseits automatisch NFS-Mounts erzeugen und diese gleich in der neuen Instanz mounten oder andererseits bereits existierende NFS-Mounts in einer neuen Instanz mounten:
root@e3b75fc5-3621-cdd8-f9dd-c9acbf4a37e9:~# triton volume ls -l
ID NAME SIZE TYPE RESOURCE STATE CREATED
e99b5d90-2678-6d43-9b59-dff0d316b5eb testvolume 10240 tritonnfs 192.168.128.5:/zones/ab4203a9-75f9-4ef8-bb6f-942ba24bdd47/data ready -
root@e3b75fc5-3621-cdd8-f9dd-c9acbf4a37e9:~# triton inst create --name mounttest -v testvolume:/nfsmount e75c9d82 dd683c97
Das erzeugt eine Instanz mit Namen mounttest
, in der das NFS-Volume unter /nfsmount
gemountet ist:
[root@mounttest ~]# mount |grep nfsmount
/nfsmount on 192.168.128.5:/zones/ab4203a9-75f9-4ef8-bb6f-942ba24bdd47/data remote/read/write/setuid/nodevices/xattr/zone=e18e4d55-9bfe-6a99-a406-8bb9a6f4de18/dev=9300003 on Fr. Apr. 17 21:34:07 2020
[root@mounttest ~]# ls /nfsmount/
catalog composer.json customer downloadable import LICENSE.txt theme_customization wysiwyg
Wie ich festgestellt habe, bieten weder Amazons EFS noch Googles Filestore diese Option (dabei liegt sie eigentlich auf der Hand - die wenigsten werden ein NFS-Volume erzeugen wollen, ohne es hinterher an irgendwelchen Compute-Instanzen zu mounten). Da soll noch jemand sagen, OpenSource Projekte wären nicht zur Innovation fähig.
Natürlich ist dann ein kleiner Benchmark fällig:
GENERIC: (g=0): rw=randrw, bs=(R) 1024KiB-1024KiB, (W) 1024KiB-1024KiB, (T) 1024KiB-1024KiB, ioengine=libaio, iodepth=16
fio-3.1
Starting 1 process
GENERIC: (groupid=0, jobs=1): err= 0: pid=3677: Fri Apr 3 15:13:31 2020
read: IOPS=48, BW=48.7MiB/s (51.1MB/s)(14.3GiB/300067msec)
slat (usec): min=55, max=30320, avg=441.36, stdev=924.88
clat (msec): min=9, max=202, avg=67.96, stdev=34.79
lat (msec): min=9, max=202, avg=68.41, stdev=34.84
clat percentiles (msec):
| 1.00th=[ 11], 5.00th=[ 13], 10.00th=[ 20], 20.00th=[ 35],
| 30.00th=[ 48], 40.00th=[ 59], 50.00th=[ 68], 60.00th=[ 78],
| 70.00th=[ 86], 80.00th=[ 97], 90.00th=[ 113], 95.00th=[ 129],
| 99.00th=[ 157], 99.50th=[ 167], 99.90th=[ 190], 99.95th=[ 192],
| 99.99th=[ 203]
bw ( KiB/s): min= 2043, max=124678, per=100.00%, avg=68742.94, stdev=36666.15, samples=435
iops : min= 1, max= 121, avg=66.83, stdev=35.85, samples=435
write: IOPS=20, BW=20.8MiB/s (21.8MB/s)(6243MiB/300067msec)
slat (usec): min=64, max=49789, avg=724.46, stdev=1690.57
clat (msec): min=41, max=3014, avg=606.36, stdev=604.04
lat (msec): min=41, max=3015, avg=607.10, stdev=604.11
clat percentiles (msec):
| 1.00th=[ 65], 5.00th=[ 91], 10.00th=[ 107], 20.00th=[ 130],
| 30.00th=[ 146], 40.00th=[ 167], 50.00th=[ 194], 60.00th=[ 659],
| 70.00th=[ 1062], 80.00th=[ 1217], 90.00th=[ 1401], 95.00th=[ 1687],
| 99.00th=[ 2500], 99.50th=[ 2668], 99.90th=[ 2869], 99.95th=[ 2937],
| 99.99th=[ 3004]
bw ( KiB/s): min= 2043, max=77824, per=100.00%, avg=35754.23, stdev=17567.43, samples=357
iops : min= 1, max= 76, avg=34.58, stdev=17.13, samples=357
lat (msec) : 10=0.14%, 20=7.08%, 50=15.28%, 100=37.45%, 250=27.57%
lat (msec) : 500=0.37%, 750=0.37%, 1000=1.79%, 2000=9.46%, >=2000=0.50%
cpu : usr=0.98%, sys=2.12%, ctx=118110, majf=0, minf=10
IO depths : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=99.9%, 32=0.0%, >=64=0.0%
submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.1%, 32=0.0%, 64=0.0%, >=64=0.0%
issued rwt: total=14621,6243,0, short=0,0,0, dropped=0,0,0
latency : target=0, window=0, percentile=100.00%, depth=16
Run status group 0 (all jobs):
READ: bw=48.7MiB/s (51.1MB/s), 48.7MiB/s-48.7MiB/s (51.1MB/s-51.1MB/s), io=14.3GiB (15.3GB), run=300067-300067msec
WRITE: bw=20.8MiB/s (21.8MB/s), 20.8MiB/s-20.8MiB/s (21.8MB/s-21.8MB/s), io=6243MiB (6546MB), run=300067-300067msec
Fio Parameter:
DEFAULT_NAME=GENERIC
DEFAULT_RUNTIME=300
DEFAULT_DIRECTORY=/nfs
DEFAULT_READWRITE=randrw
DEFAULT_RWMIXREAD=70
#DEFAULT_BLOCKSIZE=8k
DEFAULT_BLOCKSIZE=1024k
DEFAULT_SIZE=9G
#DEFAULT_IODEPTH=1
DEFAULT_IODEPTH=16
DEFAULT_SLEEP=300
fio --name=$FIO_NAME --time_based --runtime=$FIO_RUNTIME \
--directory=$FIO_DIRECTORY --direct=1 --readwrite=$FIO_READWRITE \
--rwmixread=$FIO_RWMIXREAD --blocksize=$FIO_BLOCKSIZE \
--refill_buffers --size=$FIO_SIZE --ioengine=libaio \
--iodepth=$FIO_IODEPTH --output=fio-output.txt
Die Parameter hatte ich aus diesem Isilon-Benchmark (Github) abgeguckt. Dabei geht der Traffic über die 1Gbit/s Netzwerkkarten in den Servern.
Links