Amazon Linux 2 でBBRを試す

この記事はMicroAd Advent Calendar 2017の14日目の記事です。
#はじめに
https://aws.amazon.com/jp/amazon-linux-2/

Amazon Linux 2が発表されましたね。言わずもがなAWS向けのLinuxディストリビューションです。
そしてなんと今回からイメージも公開されているのでオンプレでも使えます！（と、前のやつも公開されていたらゴメンなさい）

#試す
環境： MacOS High Sierra 10.13.2


コンテナ、Hyper-v、KVM等の仮想イメージが公開されているので、早速Mac上のVirtualBoxで試してみました。
https://cdn.amazonlinux.com/os-images/2017.12.0.20171212.2/virtualbox/
ここからイメージをダウンロードして仮想ストレージにイメージを設定すればいいんですが、ユーザパスワードとか設定されていないのでそのまま起動してしまうとログインのできないナゾOSになってしまいます。
なのでcloud-initを準備してあげる必要があります。
https://cdn.amazonlinux.com/os-images/2017.12.0.20171212.2/README.cloud-init
これを参考に作成しますが、isoをビルドするコマンドgenisoimageがなかったのでhdiutilを使います。

適当な場所にconfigフォルダを作って下記２ファイルを作ります。
ローカルなので雑にパスワードでログインする設定。

```shell-session:config/meta-data 
local-hostname: amazonlinux
```


```shell-session:config/user-data
#cloud-config
# vim:syntax=yaml
users:
# A user by the name ec2-user is created in the image by default.
  - default
chpasswd:
  list: |
    ec2-user:hogehoge123
```

上記フォルダを指定してisoファイルを作成します。

```shell
$ hdiutil makehybrid -o seed.iso -hfs -joliet -iso -default-volume-name cidata config/
```

ここで出来上がったファイルを光学ドライブで指定してあげて起動すると上記で設定したパスワードでコンソールログインができます。
<img width="804" alt="スクリーンショット 2017-12-14 20.52.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/21170/0bbe7cc2-c6f8-857f-6c36-3e64e5671f3d.png">

いろいろ見てみる。

```shell-session
[ec2-user@amazonlinux ~]$ cat /etc/system-release
Amazon Linux release 2.0 (2017.12) LTS Release Candidate
```

systemctlになった。

```shell-session
[ec2-user@amazonlinux ~]$ sudo systemctl list-units --type=service
UNIT                               LOAD   ACTIVE SUB     DESCRIPTION
atd.service                        loaded active running Job spooling tools
auditd.service                     loaded active running Security Auditing Service
chronyd.service                    loaded active running NTP client/server
cloud-config.service               loaded active exited  Apply the settings specified in cloud-config
cloud-final.service                loaded active exited  Execute cloud user/final scripts
cloud-init-local.service           loaded active exited  Initial cloud-init job (pre-networking)
cloud-init.service                 loaded active exited  Initial cloud-init job (metadata service crawler)
crond.service                      loaded active running Command Scheduler
dbus.service                       loaded active running D-Bus System Message Bus
getty@tty1.service                 loaded active running Getty on tty1
gssproxy.service                   loaded active running GSSAPI Proxy Daemon
httpd.service                      loaded active running The Apache HTTP Server
kmod-static-nodes.service          loaded active exited  Create list of required static device nodes for the current kernel
libstoragemgmt.service             loaded active running libstoragemgmt plug-in server daemon
lvm2-lvmetad.service               loaded active running LVM2 metadata daemon
lvm2-monitor.service               loaded active exited  Monitoring of LVM2 mirrors, snapshots etc. using dmeventd or progress polling
network.service                    loaded active running LSB: Bring up/down networking
postfix.service                    loaded active running Postfix Mail Transport Agent
rhel-dmesg.service                 loaded active exited  Dump dmesg to /var/log/dmesg
rhel-loadmodules.service           loaded active exited  Load legacy module configuration
rhel-readonly.service              loaded active exited  Configure read-only root support
rngd.service                       loaded active running Hardware RNG Entropy Gatherer Daemon
sshd.service                       loaded active running OpenSSH server daemon
sysstat.service                    loaded active exited  Resets System Activity Logs
systemd-fsck-root.service          loaded active exited  File System Check on Root Device
systemd-journal-flush.service      loaded active exited  Flush Journal to Persistent Storage
systemd-journald.service           loaded active running Journal Service
systemd-logind.service             loaded active running Login Service
systemd-random-seed.service        loaded active exited  Load/Save Random Seed
systemd-remount-fs.service         loaded active exited  Remount Root and Kernel File Systems
systemd-sysctl.service             loaded active exited  Apply Kernel Variables
systemd-tmpfiles-setup-dev.service loaded active exited  Create Static Device Nodes in /dev
systemd-tmpfiles-setup.service     loaded active exited  Create Volatile Files and Directories
systemd-udev-settle.service        loaded active exited  udev Wait for Complete Device Initialization
systemd-udev-trigger.service       loaded active exited  udev Coldplug all Devices
systemd-udevd.service              loaded active running udev Kernel Device Manager
systemd-update-utmp.service        loaded active exited  Update UTMP about System Boot/Shutdown
systemd-user-sessions.service      loaded active exited  Permit User Sessions
systemd-vconsole-setup.service     loaded active exited  Setup Virtual Console
update-motd.service                loaded active exited  Dynamically Generate Message Of The Day

LOAD   = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB    = The low-level unit activation state, values depend on unit type.

40 loaded units listed. Pass --all to see loaded but inactive units, too.
To show all installed unit files use 'systemctl list-unit-files'.
```

kernelのバージョン

```shell-session
[ec2-user@amazonlinux ~]$ uname -a
Linux amazonlinux.microad.co.jp 4.9.62-10.57.amzn2.x86_64 #1 SMP Wed Dec 6 00:07:49 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
```
4.9.62なのでいろいろと新しい機能が使えそうです。
と、実は2017.03から4.9になってたみたいで、2017.09からはBBRも対応してましたね。
https://aws.amazon.com/jp/amazon-linux-ami/2017.09-release-notes/
もちろんAmazon Linux 2も対応しています。

#BBRとは
https://www.school.ctc-g.co.jp/columns/nakai2/nakai222.html
中井さんの説明がわかりやすいですが、Googleが開発したTCPの新しい輻輳制御アルゴリズムで、Bottleneck Bandwidth and Round-trip propagation timeの略。名前の通りネットワークの帯域とラウンドトリップタイムを評価してパケットの送信頻度を調整する仕組みです。

サーバ側からのパケット調整のはずなのでMac<->Amazon Linux2 (VirtualBox上)で試してみました。

### BBR設定
下記２ファイルを作成

```shell:/etc/sysconfig/modules/tcpcong.modules
#!/bin/bash
exec /sbin/modprobe tcp_bbr >/dev/null 2>&1
exec /sbin/modprobe sch_fq >/dev/null 2>&1
```

```shell:/etc/sysctl.d/00-tcpcong.conf
net.ipv4.tcp_congestion_control = bbr
net.core.default_qdisc = fq
```

実行権限を付与

```shell-session
chmod 755 /etc/sysconfig/modules/tcpcong.modules
```

再起動すれはBBRが有効になりす。

設定前

```shell-session
[ec2-user@amazonlinux ~]$ sudo tc qdisc
qdisc noqueue 0: dev lo root refcnt 2 
qdisc pfifo_fast 0: dev eth0 root refcnt 2 bands 3 priomap  1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
```
設定後

```shell-session
[ec2-user@amazonlinux ~]$ sudo tc qdisc
qdisc noqueue 0: dev lo root refcnt 2 
qdisc fq 0: dev eth0 root refcnt 2 limit 10000p flow_limit 100p buckets 1024 quantum 3028 initial_quantum 15140 
```
### apache設定

ブラウザでの読み込みがどのくらい時間がかかるか測ってみたいのでLinux側に適当にapacheをインストールして10MBのファイルを配置します。ちなみにapacheは2.4.6系でした。

```shell-session
$ sudo yum install -y httpd
$ sudo dd if=/dev/zero of=/var/www/html/hoge.png bs=1M count=10
$ sudo systemctl start httpd
```


### 接続テスト
Mac側からはパケットロスするような貧弱なネットワークを準備します。
https://qiita.com/kobadlve/items/4ebc971f3285bf875b7f
こちらを参考にNetwork Link Conditionerを入れて使います。

ちょっと時間がなかったので5パターンでの検証。それぞれ5回計測した平均値です。（defaultの10%パケットロスは時間短縮のため2回計測）
検証：10MBのpngファイルをchromeで表示されるまでの時間を計測
パターン１：特に制限なし
パターン2〜5：1Gbps上で1%〜10%のパケットロス、10msのdelay

|  | default | BBR |
|:-:|:-:|:-:|
|  パターン１：制限なし | 0.25s  |  0.24s |
|  パターン２：パケットロス 1% |  16.29s |  1.55s |
|  パターン３：パケットロス 3% | 35.18s  |  2.50s |
|  パターン4：パケットロス 5% | 49.55s  |  3.74s |
|  パターン5：パケットロス 10% | 104.00s  |  5.00s |

パケットロスが多くなるほどBBRの速さが実感できますね。というか標準が遅いです。。
モバイルからのアクセスが多かったり海外兼用のサイトとかだとかなり効果が上がるんじゃないでしょうか。安定しているかどうか検証が必要ですがそのうちデフォルトで設定されるんですかね。

こちらからは以上です。

・サンプル画像：default パケットロス 5%
<img width="759" alt="スクリーンショット 2017-12-14 18.37.53.png" src="https://qiita-image-store.s3.amazonaws.com/0/21170/a8839e92-bbea-3d7b-263c-5037518ab2d2.png">

・サンプル画像：BBR パケットロス 5%
<img width="755" alt="スクリーンショット 2017-12-14 18.40.24.png" src="https://qiita-image-store.s3.amazonaws.com/0/21170/ccdd0a31-7daa-f115-4576-372299cff492.png">