Vagrant と kubeadm で Kubernetes クラスターをつくる
勉強用の Kubernetes クラスターを kubeadm でつくりました。ローカル PC 上に Vagrant で仮想マシンを起動して、ノードとして利用します。
単にコンテナーのデプロイを試したいだけであれば、Docker Desktop や Kind を利用するのが早いと思いますが、Kubernetes コンポーネントの設定もふくめて色々触りながら勉強したかったので、VM を用意してクラスターをつくることにしました。
環境
- macOS Monterey version 12.2.1
Vagrant で Ubuntu の VM を起動する
Vagrant は Homebrew を使ってインストールできます。
brew install vagrant
Vagrantfile
を記述していきます。
Ubuntu 20.04 の Box を利用して、まずは 2 ノード分の VM 定義を用意しました。
プロビジョニング用のシェル スクリプトを使って Swap を無効化しています。
Vagrant.configure("2") do |config|
config.vm.box = "generic/ubuntu2004"
config.vm.define "node01" do |server|
server.vm.hostname = "node01"
server.vm.network "private_network", ip: "192.168.56.10"
end
config.vm.define "node02" do |server|
server.vm.hostname = "node02"
server.vm.network "private_network", ip: "192.168.56.11"
end
config.vm.provision "shell", inline: <<-SHELL
# Disable swap
swapoff -a
sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
sed -i '/ swap / s/^\\(.*\\)$/#\\1/g' /etc/fstab
SHELL
end
あとは vagrant up
コマンドを実行するだけ。
vagrant ssh
で各 VM に SSH できる。
これで VM の用意は完了。
vagrant up
vagrant ssh node01
vagrant ssh node02
kubeadm のインストール
VM が用意できたら Kubernetes ドキュメントに従って kubeadm やクラスター コンポーネントのインストールをすすめていきます。 用意した各 VM に対してインストールします。
iptablesがブリッジを通過するトラフィックを処理できるようにする
sudo su -
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がnftablesバックエンドを使用しないようにする
# レガシーバイナリがインストールされていることを確認してください
sudo apt-get install -y iptables arptables ebtables
# レガシーバージョンに切り替えてください。
sudo update-alternatives --set iptables /usr/sbin/iptables-legacy
sudo update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
sudo update-alternatives --set arptables /usr/sbin/arptables-legacy
sudo update-alternatives --set ebtables /usr/sbin/ebtables-legacy
ランタイムのインストール
ここでは containerd を利用します。
必要な設定の追加
sudo su -
cat > /etc/modules-load.d/containerd.conf <<EOF
overlay
br_netfilter
EOF
modprobe overlay
modprobe br_netfilter
# 必要なカーネルパラメータの設定をします。これらの設定値は再起動後も永続化されます。
cat > /etc/sysctl.d/99-kubernetes-cri.conf <<EOF
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF
sysctl --system
containerdのインストール
sudo su -
# (containerdのインストール)
## リポジトリの設定
### HTTPS越しのリポジトリの使用をaptに許可するために、パッケージをインストール
apt-get update && apt-get install -y apt-transport-https ca-certificates curl software-properties-common
## Docker公式のGPG鍵を追加
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
## Dockerのaptリポジトリの追加
add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
## containerdのインストール
apt-get update && apt-get install -y containerd.io
# containerdの設定
mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
# containerdの再起動
systemctl restart containerd
kubeadm、kubelet、kubectlのインストール
sudo apt-get update && sudo apt-get install -y apt-transport-https 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
コントロールプレーンノードのkubeletによって使用されるcgroupドライバーの設定
ワーカーノードの IP アドレスの指定を KUBELET_EXTRA_ARGS
であわせて行います。
参考: Playing with kubeadm in Vagrant Machines, Part 2
cat << EOF | sudo tee /etc/default/kubelet
KUBELET_EXTRA_ARGS=--cgroup-driver=systemd --node-ip=<worker IP address (ex: 192.168.56.10)>
EOF
sudo systemctl daemon-reload
sudo systemctl restart kubelet
コントロール プレーン ノードのセットアップ
node01 VM をコントローラー ノードとして、シングル コントロール プレーンのクラスターをセットアップします。
コントロールプレーンノードの初期化
kubeadm init
コマンドを実行するだけで非常にかんたん。
sudo su -
kubeadm init \
--pod-network-cidr 10.244.0.0/16 \
--apiserver-advertise-address 192.168.56.10
初期化が完了したら kubeconfig ファイルをホーム ディレクトリ配下にコピーしておきます。
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
これで kubectl コマンドでクラスター操作ができるようになります。 この時点では、ネットワーク プラグインが未インストールのため、ノードは NotReady ステータスです。
% kubectl get nodes
NAME STATUS ROLES AGE VERSION
node01 NotReady control-plane,master 71s v1.23.3
% kubectl describe node node01
...
Conditions:
...
Ready False Mon, 07 Feb 2022 20:35:14 +0000 Mon, 07 Feb 2022 20:34:56 +0000 KubeletNotReady container runtime network not ready: NetworkReady=false reason:NetworkPluginNotReady message:Network plugin returns error: cni plugin not initialized
Podネットワークアドオンのインストール
ここでは flannel をインストールしました。 https://github.com/flannel-io/flannel#getting-started-on-kubernetes
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
flannel のマニフェストの apply 後、ノードが Ready ステータスに変わることを確認します。
% kubectl get pods -A
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-64897985d-4g6dm 1/1 Running 0 7m57s
kube-system coredns-64897985d-c579n 1/1 Running 0 7m57s
kube-system etcd-node01 1/1 Running 1 8m5s
kube-system kube-apiserver-node01 1/1 Running 1 8m5s
kube-system kube-controller-manager-node01 1/1 Running 1 8m5s
kube-system kube-flannel-ds-76tbb 1/1 Running 0 39s
kube-system kube-proxy-nfk6r 1/1 Running 0 7m57s
kube-system kube-scheduler-node01 1/1 Running 1 8m5s
% kubectl get nodes
NAME STATUS ROLES AGE VERSION
node01 Ready control-plane,master 8m16s v1.23.3
ノードの追加
2 ノード目以降では、kubeadm join
コマンドを実行してクラスターにノードが追加できる。
kubeadm init
の実行結果にトークンを含むコマンド例が表示されるので、そのコマンドをそのまま実行すればよい。
sudo su -
kubeadm join 192.168.56.10:6443 --token 1ubbqx.mad3qulm6jk77dvc \
--discovery-token-ca-cert-hash sha256:a347de9fa17bc6cda79ff3fdcf9804fb6862fe14ad8a711fdb53cf16c6be6373
node02
が追加された。
% kubectl get nodes
NAME STATUS ROLES AGE VERSION
node01 Ready control-plane,master 15m v1.23.3
node02 Ready <none> 49s v1.23.3
kubeadm init
の実行結果を控えておらず、kubeadm join
に渡すトークンがわからないときにはどうすればよいか?
--token
オプションに渡すトークンは、kubeadm token list
コマンドで確認ができる。
% kubeadm token list
TOKEN TTL EXPIRES USAGES DESCRIPTION EXTRA GROUPS
1ubbqx.mad3qulm6jk77dvc 23h 2022-02-08T20:35:01Z authentication,signing The default bootstrap token generated by 'kubeadm init'. system:bootstrappers:kubeadm:default-node-token
トークンの有効期限が切れていて利用できない場合には、kubeadm token create
コマンドで新しいトークンが作成できる。
% kubeadm token create
pl1f37.3rrw0sl7x5jk2kug
% kubeadm token list
TOKEN TTL EXPIRES USAGES DESCRIPTION EXTRA GROUPS
1ubbqx.mad3qulm6jk77dvc 23h 2022-02-08T20:35:01Z authentication,signing The default bootstrap token generated by 'kubeadm init'. system:bootstrappers:kubeadm:default-node-token
pl1f37.3rrw0sl7x5jk2kug 23h 2022-02-08T20:55:58Z authentication,signing <none> system:bootstrappers:kubeadm:default-node-token
--discovery-token-ca-cert-hash
オプションの値は、以下コマンドで確認できる。
% openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | \
openssl dgst -sha256 -hex | sed 's/^.* //'
a347de9fa17bc6cda79ff3fdcf9804fb6862fe14ad8a711fdb53cf16c6be6373
あとは kubeadm join
コマンドに対して、コントロール プレーンのエンドポイントと一緒にトークンを渡せば、ノードの追加ができる。
--discovery-token-ca-cert-hash
オプションの値には、先頭に sha256:
をつける。
% kubeadm join 192.168.56.10:6443 \
--token pl1f37.3rrw0sl7x5jk2kug \
--discovery-token-ca-cert-hash sha256:a347de9fa17bc6cda79ff3fdcf9804fb6862fe14ad8a711fdb53cf16c6be6373
Previous Post
Next Post