⛴️

Vagrant + Virtualboxを使ってMacbookにK8sクラスタ構築

2025/01/21に公開

Vagrant + Virtualboxを使ってMacbookにKubeadmを使ってK8sクラスタを構築します。

UdemyのCKAコースの講義とレポジトリを参考にしています。

環境

  • Macbook Pro 2019 Intel
  • macOS Sonoma
$ vagrant version
Installed Version: 2.4.2
Latest Version: 2.4.3

Vagrantfile

https://github.com/kodekloudhub/certified-kubernetes-administrator-course/blob/master/kubeadm-clusters/virtualbox/Vagrantfile

ちょっとVagrantfileは自分のMacと合わなかったので修正。
おもにCPU、メモリ、ブリッジ周りを変更。

diff --git a/kubeadm-clusters/virtualbox/Vagrantfile b/kubeadm-clusters/virtualbox/Vagrantfile
index 9c521fe..5667b23 100644
--- a/kubeadm-clusters/virtualbox/Vagrantfile
+++ b/kubeadm-clusters/virtualbox/Vagrantfile
@@ -43,15 +43,10 @@ end
 
 # Determine host adpater for bridging in BRIDGE mode
 def get_bridge_adapter()
-  if OS.windows?
-    return %x{powershell -Command "Get-NetRoute -DestinationPrefix 0.0.0.0/0 | Get-NetAdapter | Select-Object -ExpandProperty InterfaceDescription"}.chomp
-  elsif OS.linux?
-    return %x{ip route | grep default | awk '{ print $5 }'}.chomp
-  elsif OS.mac?
-    return %x{mac/mac-bridge.sh}.chomp
-  end
+  adapter = %x{mac/mac-bridge.sh}.chomp
+  puts "Detected bridge adapter: #{adapter}"  # Print the detected adapter
+  return adapter
 end
-
 # Helper method to get the machine ID of a node.
 # This will only be present if the node has been
 # created in VirtualBox.
@@ -122,13 +117,13 @@ Vagrant.configure("2") do |config|
     # Name shown in the GUI
     node.vm.provider "virtualbox" do |vb|
       vb.name = "controlplane"
-      vb.memory = 2048
-      vb.cpus = 2
+      vb.memory = 6144
+      vb.cpus = 4
     end
     node.vm.hostname = "controlplane"
     if BUILD_MODE == "BRIDGE"
       adapter = ""
-      node.vm.network :public_network, bridge: get_bridge_adapter()
+      node.vm.network :public_network, ip: "192.168.56.11", bridge: get_bridge_adapter()
     else
       node.vm.network :private_network, ip: IP_NW + ".#{MASTER_IP_START}"
       node.vm.network "forwarded_port", guest: 22, host: "#{2710}"
@@ -144,12 +139,12 @@ Vagrant.configure("2") do |config|
     config.vm.define "node0#{i}" do |node|
       node.vm.provider "virtualbox" do |vb|
         vb.name = "node0#{i}"
-        vb.memory = 1024
-        vb.cpus = 1
+        vb.memory = 2048
+        vb.cpus = 2
       end
       node.vm.hostname = "node0#{i}"
       if BUILD_MODE == "BRIDGE"
-        node.vm.network :public_network, bridge: get_bridge_adapter()
+        node.vm.network :public_network, ip: IP_NW + ".#{NODE_IP_START + i}", bridge: get_bridge_adapter()
       else
         node.vm.network :private_network, ip: IP_NW + ".#{NODE_IP_START + i}"
         node.vm.network "forwarded_port", guest: 22, host: "#{2720 + i}"

事前準備

ここからはVMの中での作業です。
まずいろいろK8sクラスタの邪魔になる設定を外していく・追加していきます。

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

Kubeadm 1.32を入れる

Kubeadm 1.32を入れる。

https://kubernetes.io/ja/docs/setup/production-environment/tools/kubeadm/install-kubeadm/

一応IPアドレスとポートがつながるか確認する。

sudo nc 192.168.56.11 6443
sudo nc 127.0.0.1 6443

いろいろダウンロード・インストールする。

sudo apt-get update
# apt-transport-httpsはダミーパッケージの可能性があります。その場合、そのパッケージはスキップできます
sudo apt-get install -y apt-transport-https ca-certificates curl gpg

curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.32/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg

echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.32/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list

sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

containerd

containerdを使っていきます。そのままインストールできます:

sudo apt update && sudo apt install -y containerd

いろいろ設定をします。
Cgroup周りとpauseコンテナ(?)の設定を一応しておきます。

参考:

https://kubernetes.io/ja/docs/setup/production-environment/container-runtimes/#systemd-cgroupドライバーを構成する

sudo mkdir -p /etc/containerd

containerd config default | sed -e 's/SystemdCgroup = false/SystemdCgroup = true/' -e 's|registry.k8s.io/pause:3.8|registry.k8s.io/pause:3.10|' | sudo tee /etc/containerd/config.toml

sudo systemctl restart containerd

確認用:

vagrant@controlplane:~$ sudo cat /etc/containerd/config.toml | grep pause
    pause_threshold = 0.02
    sandbox_image = "registry.k8s.io/pause:3.10"
vagrant@controlplane:~$ sudo cat /etc/containerd/config.toml | grep Systemd
            SystemdCgroup = true

kubeadm initでマスターノード初期化

Masterノードで以下を走らせます。結構ぽんぽんいろいろ進むはずです。

sudo kubeadm init --apiserver-advertise-address 192.168.56.11 --pod-network-cidr "10.244.0.0/16" --upload-certs

flannelを入れる

なぜか直接Applyできないので、まずダウンロードしてからApplyしました。

wget https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml

Applyする前にちょっと変更点。Vagrantのデフォルトインターフェースではなく、enp0s8を使うようにさせる。

129       containers:
130       - args:
131         - --ip-masq
132         - --kube-subnet-mgr
133 +       - --iface=enp0s8
kubectl apply -f kube-flannel.yml

これで確認できる。

vagrant@controlplane:~$ kubectl get po -n kube-flannel
NAME                    READY   STATUS    RESTARTS   AGE
kube-flannel-ds-7vtdx   1/1     Running   0          7s

vagrant@controlplane:~$ kubectl get po -n kube-system
NAME                                   READY   STATUS    RESTARTS        AGE
coredns-668d6bf9bc-dvqrj               1/1     Running   0               24m
coredns-668d6bf9bc-rldqq               1/1     Running   0               24m
etcd-controlplane                      1/1     Running   7 (11m ago)     21m
kube-apiserver-controlplane            1/1     Running   7 (10m ago)     24m
kube-controller-manager-controlplane   1/1     Running   8 (8m6s ago)    25m
kube-proxy-vclz8                       1/1     Running   8 (9m3s ago)    24m
kube-scheduler-controlplane            1/1     Running   7 (9m43s ago)   24m

vagrant@controlplane:~$ kubectl get nodes
NAME           STATUS   ROLES           AGE   VERSION
controlplane   Ready    control-plane   25m   v1.32.1

Workerノードにてjoin する

以下のコマンドでJoinできます(トークンは毎回変わるので注意)

sudo kubeadm join 192.168.56.11:6443 --token 2ut3v7.ari40jyvq6mq5xow \
        --discovery-token-ca-cert-hash sha256:cb365296de6ccd69134878921f5e478fb8fc9d7d125dc137bc9932b3d1425437
output
...
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.
vagrant@controlplane:~$ kubectl get nodes
NAME           STATUS   ROLES           AGE   VERSION
controlplane   Ready    control-plane   32m   v1.32.1
node01         Ready    <none>          63s   v1.32.1

SCPなりでcontrolplaneの /etc/kubernetes/admin.confをワーカーノードに移す

mkdir -p kubeconfig
export KUBECONFIG=/home/vagrant/kubeconfig/admin.conf

# 永続化しておくと楽
echo 'export KUBECONFIG=/home/vagrant/kubeconfig/admin.conf' >> ~/.bashrc
source ~/.bashrc
vagrant@node02:~$ kubectl get nodes
NAME           STATUS   ROLES           AGE     VERSION
controlplane   Ready    control-plane   57m     v1.32.1
node01         Ready    <none>          25m     v1.32.1
node02         Ready    <none>          8m34s   v1.32.1
vagrant@node02:~$ kubectl get po
No resources found in default namespace.

kubelet環境変数設定

sudo vi /etc/default/kubelet
KUBELET_EXTRA_ARGS=--node-ip=192.168.56.11
sudo systemctl restart kubelet
vagrant@node02:~$ kubectl get nodes -o wide
NAME           STATUS   ROLES           AGE   VERSION   INTERNAL-IP     EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION       CONTAINER-RUNTIME
controlplane   Ready    control-plane   44m   v1.32.1   192.168.56.11   <none>        Ubuntu 22.04.5 LTS   5.15.0-130-generic   containerd://1.7.12
node01         Ready    <none>          42m   v1.32.1   192.168.56.21   <none>        Ubuntu 22.04.5 LTS   5.15.0-130-generic   containerd://1.7.12
node02         Ready    <none>          42m   v1.32.1   192.168.56.22   <none>        Ubuntu 22.04.5 LTS   5.15.0-130-generic   containerd://1.7.12

flannel環境変数

flannelの環境設定ファイルも入れておく

Node01:

$ cat /run/flannel/subnet.env

FLANNEL_NETWORK=10.244.0.0/16
FLANNEL_SUBNET=10.244.1.1/24
FLANNEL_MTU=1450
FLANNEL_IPMASQ=true                                             

Node02:

cat /run/flannel/subnet.env

FLANNEL_NETWORK=10.244.0.0/16
FLANNEL_SUBNET=10.244.2.1/24
FLANNEL_MTU=1450
FLANNEL_IPMASQ=true

podを走らせる

どっちかのWorkerノードで以下を走らせる。

kubectl run web --image=nginx

ここまでくるの長かった。。。いろいろ暗黙の知識やらドキュメント読み落としがあってなかなか一筋縄ではいきません。

Discussion