自宅サーバーでHA構成のKubernetesクラスター構築してみた【Proxmox】
最近個人的にKubernetesを勉強する機運が高まったので、一から構築してみることとしました。
現在、家ではProxmoxクラスターを構築しています。ですのでそのProxmoxクラスター上にUbuntuサーバーを立て、さらにその上でKubernetesを構築してみたいと思います。せっかくUbuntu立て放題?なので、今回はきちんとHA構成で構築してみます。
構築する環境
今回はコントロールプレーン3台、ワーカーノード3台の構成でいこうと思います。
ステートフルなKubernetesのデータの保存場所であるetcd(エトセディーと読むらしい)は、外部ではなくコントロールプレーンノードと相乗りするパターン(積層コントロールプレーンノード)でいこうと思います。
また、本来であれば前段にロードバランサーが必要となってくるのですが、今回はNginxを利用したいと思います。
簡略化した図としてはこんな感じになりそうです。
Ubuntuサーバーの準備
あらかじめUbuntu 20.04のVMを6台構築します。VMよりLXCの方がメモリやCPUを節約できますが、あとで出てくるoverlayの利用がうまくいかないので避けました。ここらへんによるとホスト側のoverlayを使う方法もあるみたいですが、今回はシンプルにVMで作っちゃいたいと思います。(というかKubernetes構築でホスト側のことあんま考え始めたくない笑)
とりあえずKubernetes用Ubuntuのスペックは、
割り当て | |
---|---|
memory | 4GB |
CPU | 2Core |
Storage | 8GB |
でいこうと思います。公式ドキュメントの最低要件を参考にしました。
冗長性を担保しつつ最低限の台数にするため、Master3台、Worker3台の計6台構築しました。
実際に構築するUbuntuはこのようになっています。
あとNginx用のUbuntuもLXCで立てておきました。これのスペックは特に初期設定からいじってません。
Nginxサーバーの準備
まずあらかじめNginxを用意しておきます。これは先ほどのNginx用のLXCで実行します。
これはコントロールプレーンがHA構成でなければ(コントロールプレーンが一台であれば)必要なさそうです。
Ubuntuのセットアップをしたのちに、NginxをInstallします。
(Ubuntuのセットアップは省略します…IPアドレスだけしっかり静的に設定しておくようにすれば大丈夫なはず)
$ sudo apt update && sudo apt -y upgrade
$ sudo apt install nginx
次にコントロールプレーンに転送するように設定します。
$ sudo vi /etc/nginx/nginx.conf
以下を追記します。server部分のIPはコントロールプレーンの今後設定する(予定)のIPアドレスにします。
stream {
upstream kubernetes {
least_conn;
server 192.168.1.85:6443;
server 192.168.1.86:6443;
server 192.168.1.87:6443;
}
server {
listen 6443;
proxy_pass kubernetes;
proxy_timeout 10m;
proxy_connect_timeout 1s;
}
}
これでNginxの準備は完了です。
Kubernetesサーバーの準備
若干順番が前後しましたが、次にKubernetes用Ubuntu6台全てで作業していきます。最初はコントロールプレーンとワーカーノードで操作は一緒です。
まず以下を実行しておきます。
$ sudo apt update && sudo apt -y upgrade
containerdのInstall
現在KubernetesはDockerがコンテナランタイムとして非推奨なため、containerdをInstallします。公式を参考にしましたが、一応こちらにも手順を書いていこうと思います。
$ cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
$ sudo modprobe overlay
$ sudo modprobe br_netfilter
$ cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
$ sudo sysctl --system
以下のコマンドでモジュールが読み込まれていることを確認します。
$ lsmod | grep br_netfilter
$ lsmod | grep overlay
またnet.bridge.bridge-nf-call-iptables
、net.bridge.bridge-nf-call-ip6tables
、net.ipv4.ip_forward
カーネルパラメーターが1に設定されていることも確認します。
sysctl net.bridge.bridge-nf-call-iptables net.bridge.bridge-nf-call-ip6tables net.ipv4.ip_forward
やっとここでcontainerdをInstallします。config.tomlも忘れずに作成しておきます。
$ sudo apt install -y containerd
$ sudo mkdir -p /etc/containerd
$ containerd config default | sudo tee /etc/containerd/config.toml
続いてsystemdを使うようにします。cgroupfsを使わないとエラーが発生するみたいな話もあったのですが、自分の環境では大丈夫でした。
sudo vi /etc/containerd/config.toml
SystemdCgroupの部分をtrueに変更してください。
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
...
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
SystemdCgroup = true
kubeadm、kubelet、kubectlのインストール
こちらも公式ドキュメントに倣ってやっていきます。apt-keyの部分は少し変更しました。
また、cgroup-driverをsystemdにするのも忘れないようにします(ここ忘れててちょっと躓いた…)。
$ sudo apt-get install -y apt-transport-https ca-certificates curl
$ curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
$ cat <<EOF | sudo tee /etc/apt/sources.list.d/kubernetes.list
deb https://apt.kubernetes.io/ kubernetes-xenial main
EOF
$ sudo apt-get update
$ sudo apt-get install -y kubelet kubeadm kubectl
$ sudo apt-mark hold kubelet kubeadm kubectl
$ cat << EOF | sudo tee /etc/default/kubelet
KUBELET_EXTRA_ARGS=--cgroup-driver=systemd
EOF
$ sudo systemctl daemon-reload
$ sudo systemctl restart kubelet
Kubernetesクラスターの構築
コントロールプレーンのセットアップ
ここまではコントロールプレーンとワーカーノードで操作が同じでしたが、ここから操作が変わってきます。
まずは一つのコントロールプレーンで以下を実行します。
$ sudo kubeadm init --control-plane-endpoint "192.168.1.90:6443" --upload-certs
$ mkdir -p $HOME/.kube
$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config
kubeadm init
を実行したときのkubeadm join
二つは記録しておきます。
次にCNIのcalicoを作成します。こちらも公式ドキュメントを参考にしました。
$ curl https://raw.githubusercontent.com/projectcalico/calico/v3.25.0/manifests/calico.yaml -O
$ kubectl create -f calico.yaml
以下を実行してReadyになっていることを確認します(少し時間かかった)。
$ kubectl get pod -n kube-system -w
続いて他のコントロールプレーンで以下を実行します。kubeadm join
の部分はkubeadm init
の出力を参考にしてください。
$ sudo kubeadm join 192.168.1.90:6443 ほげほげ...
$ mkdir -p $HOME/.kube
$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config
ワーカーノードのセットアップ
最後にワーカーノードもセットアップします。こちらもkubeadm init
の出力を参考にしてください。
$ sudo kubeadm join 192.168.1.90:6443 ふがふが...
ワーカーノードとかを紐づけるのはめっちゃ簡単だった…
MacからkubectlでClusterを操作できるようにする
kubectlをMacBookにInstallして、MacBookからKubernetes Clusterにアクセスできるようにします。
以下をMacのTerminalで実行します。
$ curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/darwin/amd64/kubectl
$ chmod +x ./kubectl
$ sudo mv ./kubectl /usr/local/bin/kubectl
次にControl Planeで以下を実行し、
$ kubectl config view --raw
出力内容をMacBook上の以下のファイルに書きます。(scpコマンドでもいいんですが…)
$ sudo vi $HOME/.kube/config
これでMacbook上でもkubectlが使えるようになったと思います。
最後に
今回はProxmox上にHA構成のKubernetesを構築してみました。
まだまだわからないことが多いですが、今後はこのKubernetesに自分のプロダクト(MyTalk, MyNote)を移したりして、遊んできたいと思います。
Discussion