DHCP & TFTP Server を k8s で動かす
PXE Server を k8s で動かす検証をしています。
まずは、DHCP と TFTP を k8s で動かせるか試します。
成果物は全て以下のリポジトリに格納しています。
https://github.com/takutakahashi/k8s-pxe
DHCP と TFTP の役割は?
DHCP
TFTP Server address などの PXE Boot する際に必要な情報は
DHCP から降らせる必要があるみたいです。知らなかった。
PXE Boot する NIC は、まずブロードキャストパケットを投げて DHCP から情報を要求します。
その後 DHCP から IP や TFTP Server address を受け取った NIC は、
TFTP から Boot に必要なファイルをダウンロードして処理を進める、という流れになります。
TFTP
TFTP Server 自体は、簡素なアップロード/ダウンロードの機能を持ちます。
PXE Boot するためには、まずブートローダが必要となります。
Linux は、たいてい /boot
以下にブートローダがあって、それを読むのですが、
PXE Boot するサーバはローカルにブートローダを持ちません。
TFTP Server にブートローダを置いて、PXE Boot 時にダウンロードしてきてロードします。
設定
ネットワーク
DHCP Server には、ホームネットワークの DHCP を担当してもらいます。
なので、DHCP Server が直接ホームネットワークのアドレスに到達できる必要がありそうです。
具体的には、hostNetwork: true
を指定してノードの ns を共有する必要があります。
spec:
hostNetwork: true
containers
イメージには、andyshinn/dnsmasq
を利用します。
dhcpd + tftp-hpa で試行錯誤したのですがうまくいかず、
all in one で使える dnsmasq にしました。
dnsmasq.conf を configmap からマウントします。
追加で、tftp で利用するディレクトリをマウントします。
containers:
- image: andyshinn/dnsmasq
args:
- --log-facility=-
securityContext:
capabilities:
add: ["NET_ADMIN"]
imagePullPolicy: Always
name: dnsmasq
volumeMounts:
- mountPath: /tftpboot
name: tftpboot
- mountPath: /etc/dnsmasq.conf
name: dnsmasq-conf
subPath: dnsmasq.conf
configmap
dnsmasq.conf を configmap にセットします。
pxe-service
は、これを書くと良い理由が正直くわかってません。
apiVersion: v1
data:
dnsmasq.conf: |
port=0
dhcp-range=10.10.0.100,10.10.0.149,255.255.255.0,2h
dhcp-option = option:router, 10.10.0.1
dhcp-option = option:dns-server, 8.8.8.8
log-dhcp
enable-tftp
tftp-root=/tftpboot
pxe-service=0,"Raspberry Pi Boot"
kind: ConfigMap
metadata:
name: dnsmasq-conf
namespace: kube-pxe-system
起動
これで DHCP Server と TFTP Server ができました。起動してみます。
起動する前に router の DHCP を止めておかないと、ブロードキャストガチャになります。
dnsmasq-dhcp[1]: 2804706199 DHCPREQUEST(eno1) 10.10.0.145 xx:xx:xx:xx:xx:xx
dnsmasq-dhcp[1]: 2804706199 tags: eno1
dnsmasq-dhcp[1]: 2804706199 DHCPACK(eno1) 10.10.0.145 xx:xx:xx:xx:xx:xx OPPO-Reno-A
dnsmasq-dhcp[1]: 2804706199 requested options: 1:netmask, 3:router, 6:dns-server, 15:domain-name,
dnsmasq-dhcp[1]: 2804706199 requested options: 26:mtu, 28:broadcast, 51:lease-time, 58:T1,
dnsmasq-dhcp[1]: 2804706199 requested options: 59:T2, 43:vendor-encap
dnsmasq-dhcp[1]: 2804706199 next server: 10.10.0.11
dnsmasq-dhcp[1]: 2804706199 sent size: 1 option: 53 message-type 5
dnsmasq-dhcp[1]: 2804706199 sent size: 4 option: 54 server-identifier 10.10.0.11
dnsmasq-dhcp[1]: 2804706199 sent size: 4 option: 51 lease-time 2h
dnsmasq-dhcp[1]: 2804706199 sent size: 4 option: 58 T1 1h
dnsmasq-dhcp[1]: 2804706199 sent size: 4 option: 59 T2 1h45m
dnsmasq-dhcp[1]: 2804706199 sent size: 4 option: 1 netmask 255.255.255.0
dnsmasq-dhcp[1]: 2804706199 sent size: 4 option: 28 broadcast 10.10.0.255
dnsmasq-dhcp[1]: 2804706199 sent size: 4 option: 6 dns-server 8.8.8.8
dnsmasq-dhcp[1]: 2804706199 sent size: 4 option: 3 router 10.10.0.1
いい感じにリースできていそうです。
まとめ
hostNetwork というチートを使ってしまいましたが、
一応 DHCP と TFTP を k8s に立てることができました。
metallb の L2 Mode なら、Service を利用した DHCP できそうな気がするので、
近々やってみようと思います。
この DHCP + TFTP を利用して Raspberry Pi 4 を Network Boot できたので、
続きの記事を書こうと思います。