らずぱい３で、ネットワークブート(SDなし) 


## 概要
- [Pi 3 booting part II: Ethernet](https://www.raspberrypi.org/blog/pi-3-booting-part-ii-ethernet-all-the-awesome/)


> Yesterday, we introduced the first of two new boot modes which have now been added to the Raspberry Pi 3. Today, we introduce an even more exciting addition: network booting a Raspberry Pi with no SD card.
> 昨日、私たちはラズベリーパイ3に追加された2つの新しいブートモードの一つ目を紹介しました。今日、我々は、さらにエキサイティングな追加機能：SDカードなしラズベリーパイをネットワークブート　を紹介します。

だそうです

- [Network Boot Your Raspberry Pi](https://www.raspberrypi.org/documentation/hardware/raspberrypi/bootmodes/net_tutorial.md) - 手順はこちら。

<br>

- マジで、起動した...


## 環境
- クライアント: Raspberry Pi 3
- サーバ: Raspberry Pi 2
- microSD 4GB 1枚
- `2016-05-27-raspbian-jessie-lite.img`




## 手順

- まずは通常通りに、microSDに、Raspbian liteを書き込む.

### クライアント Raspberry Pi 3で作業
- 焼いたmicroSDで起動

```
# レポジトリDB更新, ファームウェアのアップデート, config.txtの設定, 再起動
sudo apt-get update ; sudo apt-get install rpi-update -y ; sudo BRANCH=next rpi-update ; echo program_usb_boot_mode=1 | sudo tee -a /boot/config.txt ; sudo reboot
#
# 再起動後、 otpの値を確認
vcgencmd otp_dump | grep 17:
# > 17:3020000a となっていればOK
#
# MACアドレスをメモっておくといいかも? (確認のため)
cat /sys/class/net/eth0/address 
#
# 電源OFF
sudo poweroff 
```

### サーバ Raspberry Pi 2で作業
- ↑で使ったmicroSDを挿す。

```bash
#> クライアントPiが起動するのに、ルートファイルシステムが必要になりますが、
#> 私たちはサーバー上で何かを行う前に、
#> 私たちはそのファイルシステムの完全なコピーを作成し、/nfs/client1 と呼ばれるディレクトリにそれを置くつもりです。
#とのことです.
sudo mkdir -p /nfs/client1
sudo apt-get install rsync
time sudo rsync -xa --progress --exclude /nfs / /nfs/client1
#
# timeで計測
#<<< sdカードその１(まぁまぁ)
#real	6m52.395s
#user	0m21.890s
#sys	0m23.320s
#<<< sdカードその２(遅い)
#real	12m55.891s
#user	0m42.560s
#sys	0m44.310s
#
#
# クライアントのファイルシステムのsshホストキーを再生成
cd /nfs/client1
sudo mount --bind /dev dev
sudo mount --bind /sys sys
sudo mount --bind /proc proc
sudo chroot .
rm /etc/ssh/ssh_host_*
dpkg-reconfigure openssh-server
exit
sudo umount dev
sudo umount sys
sudo umount proc
#
# ネットワーク周りの現在の設定取得
# 'gateway' 
ip route | grep default | awk '{print $3}'
# 'brd'(broadcast)
ip -4 addr show dev eth0 | grep inet
cat /etc/resolv.conf
```

```shell-session:実行例
pi@raspberrypi:/nfs/client1 $ ip route | grep default | awk '{print $3}'
10.10.0.1
pi@raspberrypi:/nfs/client1 $ ip -4 addr show dev eth0 | grep inet
    inet 10.10.1.96/21 brd 10.10.7.255 scope global eth0
pi@raspberrypi:/nfs/client1 $ cat /etc/resolv.conf
# Generated by resolvconf
nameserver 10.10.0.21
pi@raspberrypi:/nfs/client1 $ 
```

#### 固定IPにします
- `sudo vi /etc/network/interfaces`

    ```txt:/etc/network/interfaces
...
#iface eth0 inet manual
auto eth0
iface eth0 inet static 
            address 10.10.1.96
            netmask 255.255.248.0
            gateway 10.10.0.1
...
```

- DHCPクライアントデーモン(dhcpcd)から、Debian標準のもの(networking)に変更

    ```bash
# DHCPクライアントデーモン(dhcpcd)から、Debian標準のもの(networking)に変更
sudo systemctl disable dhcpcd
sudo systemctl enable networking
#
# 再起動で、設定反映.
sudo reboot
```


### DNSまわりの設定
- この時点でDNSが動いてないので、さっきメモった鯖のアドレスを `/etc/resolv.conf`に入れて、イミュータブル(immutableあとで書き換えできないよう)にするよ。(`dnsmasq`が、ちょっかいだしてくるんだよ)

```bash
echo "nameserver 10.10.0.21" | sudo tee -a /etc/resolv.conf
sudo chattr +i /etc/resolv.conf

### 
# 必要なソフトを入れて、
# sudo apt-get update
sudo apt-get install dnsmasq tcpdump
# dnsmasq が、ごにょごにょしないように、する
sudo rm /etc/resolvconf/update.d/dnsmasq
# sudo mv /etc/resolvconf/update.d/dnsmasq ~
#
# 再起動
sudo reboot
```

### tcpdumpで、クライアントらずぱいからのDHCPパケットをみてみよう

- `sudo tcpdump -i eth0 port bootpc`<br>とか
- `sudo tcpdump -i eth0 port bootpc | grep b8:27:eb:6c:0f:31`<br>いっぱいパケットが飛んでたら、MACアドレスでフィルタしてみる、とか.
- avahiサービスを切ってみるのもいいかも。

```shell-session:実行例--RPi3の電源入れて10～25秒後ぐらいで応答キタ
pi@raspberrypi:~$ sudo tcpdump -i eth0 port bootpc | grep b8:27:eb:6c:0f:31
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
22:46:47.656127 IP 0.0.0.0.bootpc > 255.255.255.255.bootps: BOOTP/DHCP, Request from b8:27:eb:6c:0f:31 (oui Unknown), length 320
```

### dnsmasqの設定
- DHCPの応答できるように設定変更

    ```bash
sudo echo | sudo tee /etc/dnsmasq.conf
sudo vi /etc/dnsmasq.conf
```
- dhcp-range=には、メモったbrd(broadcast)アドレスを入れる

    ```txt:/etc/dnsmasq.conf
port=0
dhcp-range=10.10.7.255,proxy
log-dhcp
enable-tftp
tftp-root=/tftpboot
pxe-service=0,"Raspberry Pi Boot"
```

- `/tftpboot`作成

    ```bash
sudo mkdir /tftpboot
sudo chmod 777 /tftpboot
sudo systemctl enable dnsmasq.service
sudo systemctl restart dnsmasq.service
```


#### `/var/log/daemon.log`を観察。

```bash
tail -f /var/log/daemon.log
# メッセージがおおいとき..
#tail -f /var/log/daemon.log | grep dnsmasq-tftp
#
```
- クライアントらずぱいの電源いれる

```shell-session:実行例-こんなメッセージが出てくる
pi@raspberrypi:~$ tail -f /var/log/daemon.log | grep dnsmasq-tftp
Aug  5 22:58:32 raspberrypi dnsmasq-tftp[692]: file /tftpboot/bootcode.bin not found
```

#### `bootcode.bin`と`start.elf`を `/tftpboot`にコピー
- CTRL-Zで止めて、以下実行

```bash
# bootcode.binとstart.elf などを `/tftpboot`にコピー
cp -r /boot/* /tftpboot`<br>
#
# dnsmasqサービス再起動
sudo systemctl restart dnsmasq
```

### NFS ROOTの設定

```bash
sudo apt-get install nfs-kernel-server -y
echo "/nfs/client1 *(rw,sync,no_subtree_check,no_root_squash)" | sudo tee -a /etc/exports
sudo systemctl enable rpcbind
sudo systemctl restart rpcbind
sudo systemctl enable nfs-kernel-server
sudo systemctl restart nfs-kernel-server
```

- `sudo vi /tftpboot/cmdline.txt`<br>`/tftpboot/cmdline.txt`の編集
    - `nfsroot=`<サーバらずぱいのIP>`:/nfs/client`... みたいにする

    ```txt:/tftpboot/cmdline.txt
dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=/dev/nfs nfsroot=10.10.1.96:/nfs/client1 rw ip=dhcp rootwait elevator=deadline
#
#元の設定
#dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait
```

- `sudo vi /nfs/client1/etc/fstab`<br>`/nfs/client1/etc/fstab`の編集
    - `/dev/mmcblk0p`のとこをコメントアウト \#

    ```txt:/nfs/client1/etc/fstab
proc            /proc           proc    defaults          0       0
#/dev/mmcblk0p1  /boot           vfat    defaults          0       2
#/dev/mmcblk0p2  /               ext4    defaults,noatime  0       1
# a swapfile is not a swap partition, no line here
#   use  dphys-swapfile swap[on|off]  for that
```



### クライアントらずぱいの電源を入れて、待つ...

- root `/` が、nfs
 
```shell-session
pi@raspberrypi:~ $ ssh pi@10.10.1.62
pi@10.10.1.62's password: 

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Fri Aug  5 23:08:41 2016 from 10.10.1.96
pi@raspberrypi:~ $ mount | grep nfs
10.10.1.96:/nfs/client1 on / type nfs (rw,relatime,vers=2,rsize=4096,wsize=4096,namlen=255,hard,nolock,proto=udp,timeo=11,retrans=3,sec=sys,mountaddr=10.10.1.96,mountvers=1,mountproto=udp,local_lock=all,addr=10.10.1.96)
pi@raspberrypi:~ $ 
```



## その他
- 複数のクライアントって、できるの？(らずぱい３は1台しかもってないので、試せていない)
- おそい。。(apt-get install ... とか)<br>I/Oのやり取りが少なく、CPUをよく使うプログラム、、、だとよいのかな？