Ubuntu 26.04 で Kubernetes のコントロールプレーンを構築する手順を整理します。この記事では、kubeadm init を直接打つだけではなく、control-plane endpoint、node-ip、pod subnet、service subnet、cgroup driver、kube-proxy mode を明示した kubeadm config を使う前提で進めます。
ここで扱うのは、単一の初期 control-plane ノードを bootstrap する手順です。高可用性 control-plane、CNI の詳細、worker 参加、kubeconfig の統合は後続の記事で分けて扱います。
書籍
Kubernetes完全ガイド 第2版
Kubernetes の仕組み、リソース、ネットワーク、運用観点を体系的に確認したい場合の参考書籍です。価格や在庫はリンク先で確認してください。
Amazon で見るこのリンクは Amazon アソシエイトリンクです。
control-plane が担うもの
Kubernetes の control-plane は、クラスタ全体の状態を管理する中枢です。主に API Server、etcd、Controller Manager、Scheduler が動きます。worker node を参加させる前に、まず control-plane が安定して動く状態を作ります。
- API Server: Kubernetes API の入口
- etcd: クラスタ状態の保存先
- Controller Manager: desired state へ近づける制御ループ
- Scheduler: Pod をどの node に配置するか決める
- kubelet: control-plane node 上でも static pod を管理する
事前準備を確認する
control-plane 構築前に、前の記事で整理したノード前提を確認します。swap、kernel module、sysctl、containerd、CRI socket が整っていない状態で kubeadm init を実行すると、初期化中や Pod 起動時に詰まりやすくなります。
swapon --show
lsmod | grep -E 'overlay|br_netfilter'
sysctl net.bridge.bridge-nf-call-iptables net.bridge.bridge-nf-call-ip6tables net.ipv4.ip_forward
systemctl --no-pager --full status containerd.service
ls -l /run/containerd/containerd.sockKubernetes パッケージリポジトリを設定する
kubeadm と kubelet を導入するために、Kubernetes の apt repository を設定します。minor version を固定することで、control-plane と worker のバージョン管理をしやすくします。
K8S_MINOR="1.35"
sudo mkdir -p /etc/apt/keyrings
curl -fsSL "https://pkgs.k8s.io/core:/stable:/v${K8S_MINOR}/deb/Release.key" \
| sudo gpg --dearmor --yes -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:/v${K8S_MINOR}/deb/ /" \
| sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt update
sudo apt install -y kubelet kubeadm
sudo apt-mark hold kubelet kubeadm管理端末や control-plane 上で kubectl も使う場合は、別途 kubectl を導入します。クラスタ操作に使う client version は、クラスタの minor version と大きくずれないようにします。
kubeadm config を作成する
kubeadm init に長い引数を渡すより、config file として残す方が再現性があります。特に dual-stack、control-plane endpoint、node-ip、kube-proxy mode を明示する場合は、config file の方が意図を追いやすくなります。
mkdir -p "$HOME/work/kubernetes"
cat > "$HOME/work/kubernetes/kubeadm-config.yaml" <<'EOF'
apiVersion: kubeadm.k8s.io/v1beta4
kind: InitConfiguration
localAPIEndpoint:
advertiseAddress: "10.1.0.10"
bindPort: 6443
nodeRegistration:
kubeletExtraArgs:
- name: node-ip
value: "10.1.0.10,fd00::10"
---
apiVersion: kubeadm.k8s.io/v1beta4
kind: ClusterConfiguration
clusterName: "k8s-base-g01-cluster.example.com"
controlPlaneEndpoint: "10.1.0.1:6443"
networking:
podSubnet: "10.193.0.0/21,fd02::/64"
serviceSubnet: "10.201.0.0/21,fd03::/108"
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
cgroupDriver: "systemd"
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: "nftables"
EOFIP アドレス、clusterName、endpoint、podSubnet、serviceSubnet は環境に合わせます。dual-stack クラスタでは、node-ip、podSubnet、serviceSubnet に IPv4 と IPv6 の両方を入れる点が重要です。
kubeadm init を実行する
config file を使って control-plane を初期化します。--upload-certs は、後で control-plane を追加する可能性がある場合に証明書共有の準備として使います。
sudo kubeadm init \
--config "$HOME/work/kubernetes/kubeadm-config.yaml" \
--upload-certs成功すると /etc/kubernetes/admin.conf が作成されます。このファイルが control-plane 管理用 kubeconfig です。
kubeconfig を配置する
管理ユーザーから kubectl を使えるように、admin kubeconfig を ~/.kube/config へ配置します。
mkdir -p "$HOME/.kube"
sudo cp /etc/kubernetes/admin.conf "$HOME/.kube/config"
sudo chown "$USER:$USER" "$HOME/.kube/config"
chmod 0600 "$HOME/.kube/config"
kubectl cluster-info
kubectl get nodes -o widecontrol-plane static pods を確認する
kubeadm で構築した control-plane の主要コンポーネントは static pod として動きます。まず kube-system namespace の状態を確認します。
kubectl -n kube-system get pods -o wide
kubectl -n kube-system get pods \
-l tier=control-plane \
-o wide
sudo crictl ps 2>/dev/null || true
sudo ctr -n k8s.io containers list | headCNI を入れる前は、node が NotReady のままになることがあります。これは control-plane 自体の失敗とは限りません。CNI 導入前後で状態を分けて確認します。
CNI 導入前後を分けて見る
kubeadm init の直後は、Pod network を提供する CNI がまだ入っていません。Calico などの CNI を導入してから、node の Ready 状態や CoreDNS の状態を確認します。
kubectl get nodes -o wide
kubectl -n kube-system get pods -o wide
kubectl -n kube-system describe pod -l k8s-app=kube-dnsこの環境では Calico や BGP、dual-stack、kube-proxy nftables などの設計要素がありますが、CNI の詳細は別記事に分けます。control-plane 記事では、kubeadm init と admin kubeconfig、CNI 導入前後の切り分けまでを範囲にします。
再起動後に確認する
control-plane は再起動後に復旧できる必要があります。再起動後に kubelet、containerd、static pod、API Server の状態を確認します。
sudo rebootsystemctl --no-pager --full status containerd.service
systemctl --no-pager --full status kubelet.service
kubectl get nodes -o wide
kubectl -n kube-system get pods -o wide確認ポイント
- Kubernetes minor version を決めて repository を設定している
kubeletとkubeadmを hold している- controlPlaneEndpoint を明示している
- dual-stack の場合、node-ip / podSubnet / serviceSubnet に IPv4 / IPv6 の両方を指定している
- containerd と kubelet の cgroup driver が systemd で揃っている
- admin kubeconfig を管理ユーザーへ配置している
- CNI 導入前後の NotReady を分けて確認している
まとめ
Ubuntu 26.04 で Kubernetes control-plane を構築する場合、kubeadm init を単発コマンドとして扱うより、kubeadm config にクラスタ設計を明示する方が安全です。特に dual-stack、controlPlaneEndpoint、cgroup driver、kube-proxy mode は、後から曖昧にすると切り分けが難しくなります。
次は、この control-plane に worker node を参加させる手順へ進みます。
関連記事
- Ubuntu 26.04 Kubernetes ノードの事前準備 – swap / kernel module / sysctl / containerd
- Ubuntu 26.04 containerd の基本設定 – Kubernetes 用 CRI runtime を整える
- Ubuntu 26.04 Kubernetes ワーカーノード参加
- Ubuntu 26.04 kubeconfig の基本
- Ubuntu 26.04 MicroK8s の基本
- Ubuntu 26.04 サーバー管理ガイド




