Hyper-V上のVMでkubernetesを構築する

業務でkubernetesに触れることになりそうなので、一念発起して家のHyper-Vに環境を構築してみました。というのと、せっかくなのでChatGPT o3に手順を作ってみてもらいました。

環境など
VM | vCPU | RAM | OS | 役割 | IPアドレス |
---|---|---|---|---|---|
1台目 | 3 | 6GB | Rocky Linux 9.5 | コントロールプレーン | 10.244.0.101/16 |
2台目 | 3 | 6GB | Rocky Linux 9.5 | ワーカー① | 10.244.0.102/16 |
3台目 | 3 | 6GB | Rocky Linux 9.5 | ワーカー② | 10.244.0.103/16 |

構成
以下の構成にしました
- Kubernetes v1.32
- containerd
- Flannel
Flannelにしたのは、のちのちMetalLBを使ってみたいからです

ここからは基本的に、ChatGPT o3が出力した内容です。
変更・修正した場所は補足していますが、ほぼ修正無しでした!

0. 前提条件とノード共通準備
項目 | 推奨値 |
---|---|
OS | Rocky Linux 9.5 (x86‑64) |
CPU/RAM | 最低 2 vCPU / 2 GiB(実運用は 4 vCPU / 8 GiB 以上推奨) |
ネットワーク | ノード間で L3 到達可、ポート開放は後述 |
権限 |
sudo 可能ユーザー |
-
ホスト名・ホスト間名前解決(DNS か
/etc/hosts
)を事前に設定します。 -
SELinux を permissive に変更し永続化します。
sudo setenforce 0 sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
-
swap を無効化(一時+永続)。
sudo swapoff -a sudo sed -i '/swap/s/^/#/' /etc/fstab
-
カーネルモジュールと sysctl(全ノード共通)。
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
補足
ChatGPT o3はファイアウォール周りの設定をしませんでした。
以下のコマンドでファイアウォールを無効化しています。
sudo systemctl disable firewalld
sudo systemctl stop firewalld

1. containerd のインストールと設定
-
Docker CE リポジトリを追加(Rocky = RHEL 系)。
sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf makecache
-
containerd を導入。
sudo dnf install -y containerd.io
-
既定設定ファイルを生成し SystemdCgroup を有効化。
sudo mkdir -p /etc/containerd sudo containerd config default | sudo tee /etc/containerd/config.toml sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
-
サービス起動 & 自動起動化。
sudo systemctl enable --now containerd

※なぜかv1.30を入れようとしていたので、読み替えてv1.32にしています。
2. Kubernetes 1.32 — リポジトリ追加とパッケージ導入
-
公式 rpm リポジトリ (pkgs.k8s.io) を登録。
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo [kubernetes] name=Kubernetes baseurl=https://pkgs.k8s.io/core:/stable:/v1.32/rpm/ enabled=1 gpgcheck=1 gpgkey=https://pkgs.k8s.io/core:/stable:/v1.32/rpm/repodata/repomd.xml.key exclude=kubelet kubeadm kubectl EOF
-
パッケージをインストールしてバージョン固定。Kubernetes v1.30 は 2025‑04‑17 リリースの最新安定版
sudo dnf install -y kubelet-1.32.* kubeadm-1.32.* kubectl-1.32.* --disableexcludes=kubernetes sudo systemctl enable --now kubelet

3. Control‑Plane ノードの初期化
sudo kubeadm init \
--kubernetes-version 1.30.0 \
--pod-network-cidr=10.244.0.0/16 \
--cri-socket unix:///run/containerd/containerd.sock
Flannel の既定 CIDR に合わせ --pod-network-cidr=10.244.0.0/16
を必ず指定
初期化完了後に表示される kubeadm join ...
コマンドは後で使うので控えておきます。
一般ユーザーで kubectl を使うための設定:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

4. Flannel CNI の導入
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/v0.26.7/Documentation/kube-flannel.yml
数分後に kubectl get pods -n kube-system
で kube-flannel-ds-*
が Running になればネットワークが開通しています。
補足
kubectl get pods -n kube-systemを実行して確認しようとしていますが、実際は
# DaemonSet を確認
kubectl get ds -n kube-flannel
# Pod の状態を一覧
kubectl get pods -n kube-flannel -o wide
# すべてまとめて
kubectl get pods -A | grep flannel
を実行して確認しています。(DESIRED / CURRENT / READY がノード数と一致)

5. Worker ノードをクラスターへ参加
各 Worker で、Control‑Plane で控えた join コマンドを実行:
sudo kubeadm join <control-plane-IP>:6443 --token <token> --discovery-token-ca-cert-hash sha256:<hash>
参加後に Control‑Plane で kubectl get nodes
を実行し、全ノードが Ready になることを確認します。

6. firewalld ポート開放(必要に応じて)
※事前に無効化しているのでスキップしています。一応載せますが未確認。
Control‑Plane 用
sudo firewall-cmd --permanent --add-port=6443/tcp # API server
sudo firewall-cmd --permanent --add-port=2379-2380/tcp # etcd
sudo firewall-cmd --permanent --add-port=10250/tcp # kubelet
sudo firewall-cmd --permanent --add-port=10251/tcp # scheduler
sudo firewall-cmd --permanent --add-port=10252/tcp # controller-manager
sudo firewall-cmd --permanent --add-port=8285/udp # Flannel udp
sudo firewall-cmd --permanent --add-port=8472/udp # Flannel vxlan
sudo firewall-cmd --permanent --add-masquerade
sudo firewall-cmd --reload
Worker 用(例)
sudo firewall-cmd --permanent --add-port=10250/tcp
sudo firewall-cmd --permanent --add-port=8285/udp
sudo firewall-cmd --permanent --add-port=8472/udp
sudo firewall-cmd --permanent --add-port=30000-32767/tcp # NodePort
sudo firewall-cmd --permanent --add-masquerade
sudo firewall-cmd --reload

7. 動作確認の例
kubectl get nodes
kubectl get pods -A
kubectl run --rm -i --tty busybox --image=busybox -- sh
/ # ping -c3 <別ノードの Pod IP>
すべて正常に応答すれば Rocky Linux 9.5 + Kubernetes 1.302 + containerd + Flannel クラスターの完成です。

追加の確認
以下のようなnginx Podを作成して確認もしました。
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- image: nginx:latest
name: nginx
(1) Podの作成
$ kubectl apply -f nginx.yaml
pod/nginx created
(2) Podの確認
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 42s
(3) Curl実行
# PodのIPアドレスの確認
$ kubectl describe pod nginx | grep "IP"
IP: 10.244.1.2
IPs:
IP: 10.244.1.2
$ curl 10.244.2.2
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
(4) Pod削除
$ kubectl delete pod nginx
pod "nginx" deleted

Nodeの停止など