概要
セットアップしたラズパイを利用してkubernetesクラスタを構築していく。
kubernetes公式
を参考に進める。
ubuntu 20.04.3 LTS(64bit版)
事前準備
セットアップしたラズパイ君にはDockerが入っていなかったりするので、クラスタを構築するための準備する。
(ラズパイのセットアップで一緒に書けばよかったなーと思うものもある。。)
TimeZoneの設定
1
| sudo timedatectl set-timezone Asia/Tokyo
|
Dockerセットアップ
インストール手順。Docker公式あたりを参考に。。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| $ sudo apt-get update
$ sudo apt-get install \
ca-certificates \
curl \
gnupg \
lsb-release
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
$ echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# パッケージデータベース更新
$ sudo apt update
$ sudo apt-get install docker-ce docker-ce-cli
$ apt-cache madison docker-ce
|
ログインしていないdockerグループにユーザーを追加する必要がある場合は、次を使用して明示的にそのユーザー名を宣言します。
ラズパイセットアップで作成したユーザをdockerグループに追加する。
1
2
3
4
5
6
7
8
9
10
11
| # 追加(ユーザがubuntuの場合)
$ sudo adduser ubuntu docker
# "docker"が追加されたことを確認
$ groups ubuntu
# groups ubuntu
# ubuntu : adm dialout cdrom floppy sudo audio dip video plugdev netdev lxd ubuntu docker
# dockerコマンドがそのまま利用できることを確認する
$ docker -v
# Docker version 20.10.7, build 20.10.7-0ubuntu5~20.04.2
|
Swapの無効化
kubeletを利用するために、Swapを無効化しておく必要がある。
以下、公式より
Swapがオフであること。kubeletが正常に動作するためにはswapは必ずオフでなければなりません。
1
2
3
4
5
6
7
8
9
10
11
| $ sudo swapoff -a
$ free -h
total used free shared buff/cache available
Mem: 3.7Gi 804Mi 186Mi 4.0Mi 2.7Gi 2.9Gi
Swap: 0B 0B 0B
$ sudo systemctl --type swap --all
UNIT LOAD ACTIVE SUB DESCRIPTION
0 loaded units listed.
To show all installed unit files use 'systemctl list-unit-files'.
|
/etc/fstab
ファイル修正しないとかしらと思ったが、swapの設定ないのでそのままにした。
rebootして再確認したが結果変わらずだったので問題なさそう。
iptablesの設定
bridgeのトラフィック設定追加
…の前に、br_netfilter
がロードされているか確認する。
コマンドの結果が下記のようであればOK(参考:OracleHP)。
ロードされていない時はmodprobe br_netfilter
コマンド実行してロードする。
1
2
3
| $ lsmod | grep br_netfilter
# br_netfilter 28672 0
# bridge 225280 1 br_netfilter
|
公式の手順をそのままコピペ。
1
2
3
4
5
6
7
|
# rootで実行
sudo cat <<EOF > /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --system
|
一応iptables見てみる(下記はコマンドの結果抜粋)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
$ sudo iptables -nvL --line-number
Chain FORWARD (policy DROP 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
4 0 0 DOCKER-USER all -- * * 0.0.0.0/0 0.0.0.0/0
5 0 0 DOCKER-ISOLATION-STAGE-1 all -- * * 0.0.0.0/0 0.0.0.0/0
6 0 0 ACCEPT all -- * docker0 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
7 0 0 DOCKER all -- * docker0 0.0.0.0/0 0.0.0.0/0
8 0 0 ACCEPT all -- docker0 !docker0 0.0.0.0/0 0.0.0.0/0
9 0 0 ACCEPT all -- docker0 docker0 0.0.0.0/0 0.0.0.0/0
Chain DOCKER-ISOLATION-STAGE-1 (1 references)
num pkts bytes target prot opt in out source destination
1 0 0 DOCKER-ISOLATION-STAGE-2 all -- docker0 !docker0 0.0.0.0/0 0.0.0.0/0
2 0 0 RETURN all -- * * 0.0.0.0/0 0.0.0.0/0
Chain DOCKER-ISOLATION-STAGE-2 (1 references)
num pkts bytes target prot opt in out source destination
1 0 0 DROP all -- * docker0 0.0.0.0/0 0.0.0.0/0
2 0 0 RETURN all -- * * 0.0.0.0/0 0.0.0.0/0
|
問題なさそう。
iptablesがnftablesバックエンドを使用しないようにする
wiki.nfttables
nftables is the modern Linux kernel packet classification framework. New code should use it instead of the legacy {ip,ip6,arp,eb}_tables (xtables) infrastructure. For existing codebases that have not yet converted, the legacy xtables infrastructure is still maintained as of 2021. Automated tools assist the xtables to nftables conversion process.
Linux kernel packet classificationはlegacy(iptablesなど)ではなくmodern(nfttables)を利用するようにしてねー。まだモダンに切り替えられていないものもあるからlegacyもメンテナンスしてるよ(2021年時点)ー。ということらしい。
ラズパイに入れたubuntu20.04はどちらがデフォルトなのかしらと思って調べてみたら、how-to-install-nftables-on-ubuntu-20-04-ltsという記事があった。
nftablesのサービスステータスとnftコマンドを試してみたところ、セットアップされてなさそう。
1
2
3
4
5
6
7
|
$ sudo systemctl status nftables.service
Unit nftables.service could not be found.
$ nft -h
Command 'nft' not found, but can be installed with:
sudo apt install nftables
|
iptables
コマンドはちゃんと使えた(legacyですよと教えてくれる)。
nfttables利用していないことが確認できたのでOK。
1
2
3
| $ iptables
iptables v1.8.4 (legacy): no command specified
Try `iptables -h' or 'iptables --help' for more information.
|
kubernetesクラスタセットアップ
kubelet, kubeadm, kubectlのインストール
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
$ sudo apt-get install -y apt-transport-https ca-certificates curl
$ sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg
$ echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
$ sudo apt-get update
# インストール
# インストール可能なバージョンを確認したい時は apt-cache policy kubelet から確認する
$ sudo apt-get install -y kubelet=1.22.2-00 kubeadm=1.22.2-00 kubectl=1.22.2-00
# 意図せずupdateしないように固定化する
$ sudo apt-mark hold kubelet kubeadm kubectl
# kubelet set on hold.
# kubeadm set on hold.
# kubectl set on hold.
|
Masterノードの構築
試しにやってみる。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
$ sudo kubeadm init --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=192.168.0.11
[init] Using Kubernetes version: v1.22.2
[preflight] Running pre-flight checks
[preflight] The system verification failed. Printing the output from the verification:
KERNEL_VERSION: 5.4.0-1044-raspi
CONFIG_NAMESPACES: enabled
CONFIG_NET_NS: enabled
CONFIG_PID_NS: enabled
CONFIG_IPC_NS: enabled
CONFIG_UTS_NS: enabled
CONFIG_CGROUPS: enabled
CONFIG_CGROUP_CPUACCT: enabled
CONFIG_CGROUP_DEVICE: enabled
CONFIG_CGROUP_FREEZER: enabled
CONFIG_CGROUP_PIDS: enabled
CONFIG_CGROUP_SCHED: enabled
CONFIG_CPUSETS: enabled
CONFIG_MEMCG: enabled
CONFIG_INET: enabled
CONFIG_EXT4_FS: enabled
CONFIG_PROC_FS: enabled
CONFIG_NETFILTER_XT_TARGET_REDIRECT: enabled (as module)
CONFIG_NETFILTER_XT_MATCH_COMMENT: enabled (as module)
CONFIG_FAIR_GROUP_SCHED: enabled
CONFIG_OVERLAY_FS: enabled (as module)
CONFIG_AUFS_FS: enabled (as module)
CONFIG_BLK_DEV_DM: enabled
CONFIG_CFS_BANDWIDTH: enabled
CONFIG_CGROUP_HUGETLB: not set - Required for hugetlb cgroup.
CONFIG_SECCOMP: enabled
CONFIG_SECCOMP_FILTER: enabled
DOCKER_VERSION: 20.10.7
DOCKER_GRAPH_DRIVER: overlay2
OS: Linux
CGROUPS_CPU: enabled
CGROUPS_CPUACCT: enabled
CGROUPS_CPUSET: enabled
CGROUPS_DEVICES: enabled
CGROUPS_FREEZER: enabled
CGROUPS_MEMORY: missing
CGROUPS_PIDS: enabled
CGROUPS_HUGETLB: missing
[WARNING SystemVerification]: missing optional cgroups: hugetlb
error execution phase preflight: [preflight] Some fatal errors occurred:
[ERROR SystemVerification]: missing required cgroups: memory
[preflight] If you know what you are doing, you can make a check non-fatal with `--ignore-preflight-errors=...`
To see the stack trace of this error execute with --v=5 or higher
|
エラー出た。
memoryの有効化
askubuntu.comに対応方法が書いてあるため、参考に対応する。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| # 一番右の値が"1"(有効)になればOK
$ cat /proc/cgroups | grep memory
memory 0 109 0
# 念の為バックアップとっておく
$ sudo cp -a /boot/firmware/cmdline.txt /tmp/
# ファイルの中身を書き換える
$ sudo vi /boot/firmware/cmdline.txt
# net.ifnames=0 dwc_otg.lpm_enable=0 console=serial0,115200 cgroup_enable=cpuset cgroup_enable=memory cgroup_memory=1 console=tty1 root=LABEL=writable rootfstype=ext4 elevator=deadline rootwait fixrtc
$ sudo shutdown -r now
# 再起動後、接続し直す
cat /proc/cgroups | grep memory
memory 9 99 1
|
設定後、再度試してみたがkubeletが正しく起動できていないようで、エラーが出た
kubelet の状態を見てみると起動に失敗してる。
1
2
3
4
5
6
7
8
9
| systemctl status kubelet
● kubelet.service - kubelet: The Kubernetes Node Agent
Loaded: loaded (/lib/systemd/system/kubelet.service; enabled; vendor preset: enabl>
Drop-In: /etc/systemd/system/kubelet.service.d
└─10-kubeadm.conf
Active: activating (auto-restart) (Result: exit-code) since Mon 2021-10-25 02:07:1>
Docs: https://kubernetes.io/docs/home/
Process: 7628 ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_A>
Main PID: 7628 (code=exited, status=1/FAILURE)
|
そういえばipv6を有効化にしたままだったので無効化する
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| # バックアップとっておく
sudo cp -p /etc/sysctl.conf /etc/sysctl.conf_`date +%Y%m%d`
# 末尾に追記する
$ sudo vi /etc/sysctl.conf
# Custom Configure
# Not Use ipv6
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.eth0.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
$ sudo sysctl -p
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.eth0.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
# inet6 の表示がされなくなることを確認
$ ip a
|
CRI-Oのセットアップ[containerdを利用する場合は不要]
(containerdを利用する場合は不要。気づかずセットアップしてしまったのでメモだけ残す)
1
2
3
4
5
6
7
8
9
10
11
| export OS=xUbuntu_20.04
export VERSION=1.22:/1.22.2
echo "deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/$OS/ /" > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
echo "deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable:/cri-o:/$VERSION/$OS/ /" > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable:cri-o:$VERSION.list
curl -L https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable:cri-o:$VERSION/$OS/Release.key | apt-key add -
curl -L https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/$OS/Release.key | apt-key add -
apt-get update
apt-get install cri-o cri-o-runc
|
公式の手順ではVERSIONの指定はVERSION=1.18:1.18.3
のようになっているが、自分のインストールしたいバージョンの場合VERSION=1.22:/1.22.2
のように指定しないとエラーでた。エラーでた時はURLから正しい指定方法を確認するのが良さそう。
また、一部keyがなくてエラーが出たのでimportした。
1
2
|
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 4D64390375060AA4
|
CRI-Oにcontainerdを利用するため不要だった。
自動起動したくないので止めておく。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| # 自動起動対象になっているか確認する(symlinkがあれば対象になってる)
$ sudo ls -l /etc/systemd/system/ | grep crio
lrwxrwxrwx 1 root root 32 Mar 13 03:02 cri-o.service -> /lib/systemd/system/crio.service
# 自動起動無効化する
$ sudo systemctl disable crio
Removed /etc/systemd/system/cri-o.service.
Removed /etc/systemd/system/multi-user.target.wants/crio.service.
# symlinkがremoveされてる
$ sudo ls -l /etc/systemd/system/ | grep crio
# 一応ソケットファイルもmoveしておく
$ sudo mv /var/run/crio/crio.sock /var/run/crio/crio.sock_`date +%Y%m%d`
|
Masterノードの構築(再)
念の為コントロールプレーンリセットしておく。
CRI-Oを稼働させたままの状態でkubeadm reset
実行したら、こんなエラーでた。
Found multiple CRI sockets, please use --cri-socket to select one: /var/run/dockershim.sock, /var/run/crio/crio.sock
複数のCRIソケットファイルがあるので選択しないとダメとのこと。
(恥ずかしながらこの時CRI-Oセットアップする必要なかったことに気がついた。。)
1
| kubeadm reset --cri-socket /var/run/dockershim.sock
|
dockershim.sock
は非推奨となっているのでcontainerd
使うことにした。
dockerをインストールするとcontainerdもインストールされるとのことで、確認する。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
$ ls /run/containerd/containerd.sock
$ systemctl status containerd
● containerd.service - containerd container runtime
Loaded: loaded (/lib/systemd/system/containerd.service; enabled; vendor preset: enabled)
Active: active (running) since Sun 2022-03-13 17:44:36 JST; 14min ago
Docs: https://containerd.io
Main PID: 763 (containerd)
Tasks: 14
Memory: 66.0M
CGroup: /system.slice/containerd.service
└─763 /usr/bin/containerd
|
よかった。。すでに動いてた。そのままCRIにcontainerdを設定してinitすれば良い。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
| sudo kubeadm init --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=192.168.0.11 --cri-socket /run/containerd/containerd.sock
.
.
.
[kubelet-finalize] Updating "/etc/kubernetes/kubelet.conf" to point to a rotatable kubelet client certificate and key
[addons] Applied essential addon: CoreDNS
[addons] Applied essential addon: kube-proxy
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Alternatively, if you are the root user, you can run:
export KUBECONFIG=/etc/kubernetes/admin.conf
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 192.168.0.11:6443 --token ebsz3c.ow8d4kqexul4dfnv \
--discovery-token-ca-cert-hash sha256:b839bb8a8d798785e9481d652e2bf8f791e490e43cd78797238ee21be600b763
|
ようやく初期化できたー!ほっ。
ローカルユーザでもクラスタ操作できるように設定しておく。
1
2
3
| $ mkdir -p $HOME/.kube
$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config
|
試しにnode一覧表示する。master nodeがcontainerdで、指定したバージョンで起動してる。よかったー。
1
2
3
| kubectl get node -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
k8s-master Ready control-plane,master 24m v1.22.2 192.168.0.11 <none> Ubuntu 20.04.3 LTS 5.4.0-1055-raspi containerd://1.5.5
|
worker Node追加
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
$ sudo kubeadm join 192.168.0.11:6443 --token ebsz3c.ow8d4kqexul4dfnv --discovery-token-ca-cert-hash sha256:b839bb8a8d798785e9481d652e2bf8f791e490e43cd78797238ee21be600b763
[preflight] Running pre-flight checks
[preflight] Reading configuration from the cluster...
[preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Starting the kubelet
[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...
This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.
Run 'kubectl get nodes' on the control-plane to see this node join the cluster.
|
追加してもNotReadyのまま。wokerの情報を取得できてないっぽい。
そういえば仮想ネットワークの設定がまだだったので設定する。
flannelのセットアップ
flannelを利用する。
1
2
3
4
5
6
7
8
9
10
11
12
13
| # download manifest
$ wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
# CIDRはデフォ値(`10.244.0.0/16`)のままでOK。特に修正するところなかった。
# 適用
$ kubectl apply -f kube-flannel.yml
#Warning: policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+
#podsecuritypolicy.policy/psp.flannel.unprivileged created
#clusterrole.rbac.authorization.k8s.io/flannel created
#clusterrolebinding.rbac.authorization.k8s.io/flannel created
#serviceaccount/flannel created
#configmap/kube-flannel-cfg created
#daemonset.apps/kube-flannel-ds created
|
nodeがNotReady -> Ready
になった
1
2
3
4
5
|
$ kubectl get node -w
NAME STATUS ROLES AGE VERSION
k8s-master Ready control-plane,master 6h28m v1.22.2
k8s-node1 Ready <none> 21m v1.22.2
|