おうちKubernetesクラスタ構築チャレンジ with Alpine

経緯

  • おうちにk8sがあることの安心感
  • おうちにk8sがあることの優越感
  • おうちにk8sがあることの多幸感

を求めて...

目標

おうちに安くk8sクラスタを構築する!!!!!!!!!!!!!!!!!

参考文献

Day1: 材料調達

材料 個数
Raspberry Pi 4 Model B/4G 3
microSDカード/32G 3
type-C USBケーブル 3
microHDMI-HDMIケーブル 1
USB充電器 5ポート 1
USB(無線)キーボード・マウス 1
ケース/ヒートシンク 1
モニタ 1
無線LANルータ 1
クーラーの効いた涼しい部屋 1

モニタ以下は既に家にあったものを使用しました.ルータは普通のBuffaloのやつ. それ以外の総額は税込31474円. N*** Switchより安い! f:id:saku44127:20200827203712j:plain

構成

名前 k8sでの役割 OS local ipアドレス
khost Master Raspberry Pi OS 192.168.11.20
knode1 Worker Alpine Linux 192.168.11.21
knode2 Worker Alpine Linux 192.168.11.22

Day2: OSインストール

khost

Raspberry Pi OS 64bit - OSイメージをダウンロード - 今回は2020-08-20-raspios-buster-arm64.zipを選択 - microSDカードにOSイメージを書き込む.SDカードがマウントされている場所を調べ,アンマウントしてからディスク書き込みを行うという流れ. ↓ Mac Terminalでの書き込み手順(NAMEはSDカードの名前.初期状態ではNO NAMEとなっていた.)

  > diskutil list
  # 中略
  /dev/disk2 (internal, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     FDisk_partition_scheme                        *31.9 GB    disk2
   1:             Windows_FAT_32 RSPI-HOST               31.9 GB    disk2s1
  > diskutil unmountDisk /dev/disk2
  > dd if=rspiOSのイメージ名.img of=/dev/disk2 bs=16m
  > diskutil eject /dev/disk2
  • cgroupの設定(for kubeadm init)
    • cmdline.txtにcgroup_enable=cpuset cgroup_enable=memory cgroup_memory=1を追加

knode*

Alpine Linux - RASPBERRY PI aarch64をダウンロード - tar.gzを解凍してできたフォルダの中身すべてをmicroSDカードにコピぺ - cgroupの設定(for kubeadm init) - cmdline.txtにcgroup_enable=cpuset cgroup_enable=memory cgroup_memory=1を追加

Day3: raspiの起動・設定

khost

  • マウス,キーボード,microHDMIケーブルをraspiに取り付ける
  • type-C充電器(電源)と接続して起動
  • GUIから流れに従って初期設定
  • sshの有効化
    • 左上設定から,もしくはsudo raspi-configから
  • ipアドレスの固定化
    • ルータのdhcp手動設定を追加
    • もしくは/etc/dhcp/dhcpd.confを書き換えても良い.詳細は割愛
    • 今回は外部に接続しない.外部に接続するにはポート開放とルータのポート変換,固定グローバルIPアドレス(もしくはDDNS)が必要.
  • 作業user作成(hogeは好きな名前に変える)
> sudo adduser hoge
> passwd hoge 
> sudo gpasswd -a hoge sudo
> sudo dphys-swapfile swapoff
> sudo dphys-swapfile uninstall
> sudo systemctl disable dphys-swapfile
  • セキュリティ
> sudo passwd root
  • Dockerのセットアップ
> sudo apt install apt-transport-https ca-certificates curl software-properties-common
# GPGキーの追加
> curl -fsSL https://download.docker.com/linux/$(. /etc/os-release; echo "$ID")/gpg | sudo apt-key add -
# リポジトリの追加
> echo "deb [arch=armhf] https://download.docker.com/linux/$(. /etc/os-release; echo "$ID") \
$(lsb_release -cs) stable" | \
sudo tee /etc/apt/sources.list.d/docker.list
# Dockerのインストール
> sudo apt update
> sudo apt install docker-ce
# GPGキーの追加
> curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg|sudo apt-key add -
# リポジトリの追加
> echo "deb http://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kube.list
# Kubernetesのインストール
> sudo apt update
> sudo apt install kubelet kubeadm kubectl

knode*

  • キーボード,microHDMIケーブルをraspiに取り付ける
  • type-C充電器(電源)と接続して起動
  • CUIから流れに従って初期設定
  • 初期設定ではユーザ名: root,パスワードは無し
  # 初期設定の開始
  > setup-alpine

  # キーボードレイアウトの設定
  Select keyboad layout [none]: jp

  Select variant: jp

  # ホスト名の設定
  Enter system hostname [localhost]: knode1

  # ネットワークの設定
  Which one do you want to initialize? [eth0] ENTERキー押下

  Ip addres for eth0? [dhcp] ENTERキー押下

  Which one do you want to initialize? [wlan0] ENTERキー押下

  # 無線LANのSSID
  Type the wireless network name to connect to: xxxxxxxx

  # 無線LANのパスワード
  Type the "xxxxxxxx" network Pre-Shared Key: xxxxxxxx

  Ip address for wlan0? [dhcp] ENTERキー押下

  Do you want to do any manual network configuration? [no] ENTERキー押下

  # rootパスワードの設定
  New password: xxxxxxxx

  Retype password: xxxxxxxx

  # タイムゾーンの設定
  Which timezone are you in? [UTC] Japan

  # プロキシの設定
  HTTP/FTP proxy URL? [none] ENTERキー押下

  # NTPの設定
  Which NTP client to run? [chrony] ENTERキー押下

  # パッケージを取得するミラーサイトの設定
  # rはランダム、fはファステストまたは番号指定
  Enter mirror number (1-46) or URL to add (or r/f/e/done) [1]: ENTERキー押下

  # SSHの設定
  Which SSH server? [openssh] ENTERキー押下

  # データの保存先
  Enter where to store configs [mmcblk0p1]: ENTERキー押下

  Enter apk cache directory [/media/mmcblk0p1/cache]: ENTERキー押下
  # 設定の保存
  > lbu commit
  > apk update
  > apk upgrade
  > rc-update add wpa_supplicant boot
  > apk add avahi
  > apk add dbus
  > rc-update add dbus
  > rc-update add avahi-daemon
  > service avahi-daemon restart
  > lbu commit
  > reboot
  > apk add linux-firmware-brcm
  # errorの場合,apk update,apk upgrade,lbu commit,rebootして
  # もう一度上記コマンドを入力
  > lbu commit
  > apk add sudo
  > adduser hoge
  > addgroup hoge wheel
  > vi /etc/sudoers
  # ファイルの下の方の"# %wheel ALL=(ALL) ALL"を#だけxで消して(コメントを外して):wq!で保存
  > lbu add /home # /home をlbu管理下に置く
  > lbu commit
  > reboot

lbuについて https://wiki.alpinelinux.org/wiki/Alpine_local_backup Alpine Linuxディスクレスモードではそのまま電源を落とすと変更したファイルがすべて破棄される.そのため,その都度lbu commitまたはlbu ciを入力しデータを永続化する必要がある.lbu statusで次に永続化されるファイルが表示される.

  • ipアドレスの固定化
    • ルータのdhcp手動設定を追加
  • Dockerのセットアップ https://wiki.alpinelinux.org/wiki/Docker の手順に従う. 事前に/etc/apk/repositoriesの編集が必要.#http://dl-cdn.alpinelinux.org/alpine/edge/communityのコメント#を外す.
  • Kubernetesのセットアップ 事前に/etc/apk/repositoriesの編集が必要.#http://dl-cdn.alpinelinux.org/alpine/edge/testingのコメント#を外す.
  > sudo apk add kubelet kubeadm kubectl
  > sudo lbu commit

Day4: k8s/Dockerのテスト

local

~/.ssh/config

Host kh
     USER hoge
     HostName 192.168.11.20
     Port 22
     ServerAliveInterval 15
Host kn1
     USER hoge
     HostName 192.168.11.21
     Port 22
     ServerAliveInterval 15
Host kn2
     USER hoge
     HostName 192.168.11.22
     Port 22
     ServerAliveInterval 15

ssh接続には以下のように実行(パスワード認証)

> ssh kh

khost

> sudo kubeadm init --pod-network-cidr=10.244.0.0/16
> mkdir -p $HOME/.kube
> sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
> sudo chown $(id -u):$(id -g) $HOME/.kube/config
# ネットワークインターフェース追加
> kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

下記のknodeでの作業後,以下を実行

> kubectl get nodes

これでkhost,knode1,knode2が表示されたら成功!

  • Labeling
> kubectl label node knode1 node-role.kubernetes.io/worker=worker
> kubectl label node knode2 node-role.kubernetes.io/worker=worker

f:id:saku44127:20200827203725p:plain

knode*

khostでkubeadm initの際に最後に出てきたjoinコマンドを各knodeで入力

> sudo kubeadm join 192.168.11.20:6443 --token xxx --discovery-token-ca-cert-hash sha256:xxx

Reset

khost,knode1,knode2で以下を実行

> sudo kubeadm reset
> ifconfig flannel.1 down
> ip link delete flannel.1

ひとまず完成しました... 各raspiでの設定途中にAnsibleとかが欲しくなりました(3台くらいなら手動設定でなんとか行けるレベルではありました).

SDカード書き込み時にLANの設定とかすればヘッドレスでssh越しでの作業だけで事足りるのでモニタいらないかもしれません.

完成形を眺めてるだけでもうれしいものです.

これを使って何かするのは来年以降になりそうです.

Day5: To be continued...