systemd設定とLinux起動オプションでよく使うもの（個人メモ）

Linux kernelの起動オプションとsystemd設定で自分がよく使うものです。[CGroup V2](http://gihyo.jp/admin/serial/01/linux_containers/0037?page=2) （[解説スライド](https://speakerdeck.com/hiro_kamezawa/cgroup-v2togvisor)）使用前提です。

# CGroup 2 への対応状況
- [LXCは対応済み](https://qiita.com/kakinaguru_zo/items/8c82954a1bb0a1ef9a40)
- [snapdは最近対応された](https://bugzilla.redhat.com/show_bug.cgi?id=1438079)
- [dockerはまだ（２０１９年１１月）](https://medium.com/nttlabs/cgroup-v2-596d035be4d7)。しかし[docker互換のPodmanがCgroup V2対応なのでそちらを使えばよい](https://qiita.com/kakinaguru_zo/items/18622abc92a7c2568617#_reference-c0969201225922166288)

# Linux kernel 起動オプション
## 再設定方法
1. `/etc/default/grub` の `GRUB_CMDLINE_LINUX_DEFAULT` に指定したいカーネルオプションを追加する
2. `update-grub` を`root`で実行する

## CGroup V2 の使用
`systemd.unified_cgroup_hierarchy=1` を追加する。`cgroup_no_v1=all` を同時に指定してもよい

## IOMMU の使用
IOMMUが付属するハードウェアではIOMMUを使用したほうがCPUによるDMA転送を回避できるし、[ソフトウェアTLBバッファーの不足による入出力の失敗](https://qiita.com/kakinaguru_zo/items/16bf99fb9abbaafd203c)が起きないためよいと思われる

`iommu=force,merge,nopanic,nopt intel_iommu=on amd_iommu=on swiotlb=noforce ` を追加する

## CPUの脆弱性に対する防御をやめて高速化する（自己責任で）

- `mitigations=off`

## Panasonic Let's Note

`i8042.reset=1 psmouse.synaptics_intertouch=1`

# systemd の設定

## ログの保存
```config:/etc/systemd/journald.conf
[Journal]
Storage=persistent
```

と書かないとログが残らないので上記のように設定する。

## Accounting
`/etc/systemd/system.conf.d/myconf.conf` と `/etc/systemd/user.conf.d/myconf.conf` に下記内容を追加してサービスの実行情報を収集・記録する

```config
DefaultCPUAccounting=On
DefaultMemoryAccounting=On
DefaultTasksAccounting=On
DefaultIOAccounting=On
DefaultIPAccounting=On
```
## ネットワークスピードメーター (systemd-networkd利用時）
```config:/etc/systemd/networkd.conf
[Network]
SpeedMeter=yes
SpeedMeterIntervalSec=10sec
```
スピード確認は `networkctl status`

## ログアウトしたときにそのユーザーのプロセスを全部殺す
```config:/etc/systemd/logind.conf
[Login]
KillUserProcesses=yes
```
一般ユーザーがログアウト後も実行され続けるプロセスを立ち上げたいときには`loginctl enable-linger` をそのユーザーが呼び出してから、例えば `systemd-run --user --nice=19 --remain-after-exit --unit=好きな名前 /usr/bin/sleep 10000` などのように起動する。環境変数の内容はほとんど引き継がれないので、環境変数を引き継ぎたいときは `--scope` を付けるか、`-E` を使う。


## ユーザーごとの占有リソース制限(systemd 240以降)
```config:/etc/systemd/system/user-.slice.d/myuser.conf
[Slice]
MemoryHigh=90%
TasksMax=70%
```

で特定のユーザーがシステムの実メモリーやプロセスをすべて使い切ってシステムを使用不可能にすることを回避できる

## CGroup2コントローラーの一般ユーザーによる使用

```config:/etc/systemd/system/user@.service.d/myuser.conf
[Service]
AllowedCPUs=0-15 # systemd 244 以降。
# 15は/proc/cpuinfoの最大のCPU番号にする
Delegate=yes
```

で、`systemd-run --user` や `systemctl --user` で開始するサービスがCGroup2 のすべてのリソースコントローラーを使えるようになる。[LXCを一般ユーザーから開始](https://qiita.com/kakinaguru_zo/items/8c82954a1bb0a1ef9a40#unified-cgroup%E9%9A%8E%E5%B1%A4%E3%82%92%E6%8E%A1%E7%94%A8%E3%81%99%E3%82%8B%E3%83%9B%E3%82%B9%E3%83%88linux%E3%81%A7%E3%81%AElxc%E3%81%AE%E8%B5%B7%E5%8B%95)するときにはこれをやっておかないとコンテナが全部のCGroupコントローラーを使えない。

## ディスクスケジューラーの変更(Fedora 31だと不要)
udevの話ですがudevがsystemdに取り込まれているのでメモします

1. `/etc/initramfs-tools/modules` に `bfq` を追加し、`update-initramfs -u` する
2. `/etc/udev/rules.d/60-block-scheduler.rules` に `ACTION=="add|change", SUBSYSTEM=="block", KERNEL=="sd[a-z]", ATTR{queue/scheduler}="bfq", ATTR{queue/iosched/low_latency}="0"` と書く（`low_latency`のところは好みで）
3. 再起動

## rpcbind.socket の依存関係修正
[rpcbind.socketの立ち上がりが早すぎてコンテナ内の `systemd-sysusers.service` がハングアップすることがある](https://qiita.com/kakinaguru_zo/items/18258d4dd296a755badd)。これを阻止するには下記の設定ファイルを作る。

```config:/etc/systemd/system/rpcbind.socket.d/after.conf
[Unit]
After=systemd-sysusers.service
```

# 物理インターフェースの上にipvlanインターフェースを立ててそこで通信する

Avahi, Network Manager, netplan, isc-dhcp-client, ifupdown など他のネットワーク関連パッケージでやることを[systemd に一元化することも可能](https://qiita.com/kakinaguru_zo/items/a6f2004cbb6d1314f842#network-manager%E3%82%92%E7%94%A8%E3%81%84%E3%81%AA%E3%81%84%E7%84%A1%E7%B7%9A%E8%A8%AD%E5%AE%9A)。

`systemd-nspawn` でコンテナを立ててそのコンテナに独自のIPアドレスを与えてホストと同一のLANに接続するときにはmacvlanを使う必要がある（`systemd-nspawn --network-macvlan=物理インターフェース`）。しかし無線LANの上にmacvlanを立ててもプロミシャスモードが使えずまともに動作しないため、ipvlanを用いる必要がある。そのようば場合の設定ファイルは以下のようになる。物理無線インターフェースの名前は `wl` で始まるとする。

```config:/etc/systemd/network/wl.network
[Match]
Name=wl*

[Network]
IPVLAN=ipvlan0 # この行を名前を変えて繰り返せば複数のipvlanを作れる
```
```config:/etc/systemd/network/ipvlan0.netdev
# ipvlan を複数作るならNameの部分を変えて複数のファイルを作る
[NetDev]
Name=ipvlan0
Kind=ipvlan

[IPVLAN]
Mode=L2
Flags=bridge
```
```config:/etc/systemd/network/ipvlan0.network
[Match]
Name=ipvlan0*

[Network]
DHCP=no #ipvlan のMACアドレスはホストと同じなのでDHCPは
# うまく動作しないことが多い。動作させるには工夫が必要
Address=192.168.1.200/24 # 手動でIPアドレスを振る。
# このアドレスが他のマシンに振られないようにDHCPサーバーを設定する
Gateway=192.168.1.1
DNS=192.168.1.1
MulticastDNS=yes
NTP=ntp.nict.jp 
```