はい、承知いたしました。kubeadm を用いたKubernetesクラスターの構築について、マスターノードとワーカーノードの設定を詳細に説明する約5000語の記事を作成します。
kubeadm を使ったKubernetesクラスター構築:マスター&ワーカーノード設定
はじめに:Kubernetesとkubeadmがもたらす革新
現代のソフトウェア開発において、コンテナ技術はデプロイ、スケーリング、管理の方法に革命をもたらしました。Dockerに代表されるコンテナは、アプリケーションとその依存関係を一つの独立した実行単位にパッケージ化し、環境間の差異を吸収します。しかし、単一のコンテナは強力なツールである一方で、複数のコンテナから構成される複雑なアプリケーションを管理し、それらを大規模に展開する際には、新たな課題が浮上します。例えば、コンテナ間の通信、ロードバランシング、ストレージの永続化、障害発生時の自動復旧、スケーリングなどです。
これらの課題を解決するために登場したのが、「コンテナオーケストレーション」という概念であり、そのデファクトスタンダードとして君臨しているのが Kubernetes です。Kubernetesは、コンテナ化されたワークロードとサービスを宣言的に管理するためのポータブルで拡張可能なオープンソースプラットフォームです。これにより、開発者はインフラストラクチャの詳細に煩わされることなく、アプリケーションの開発に集中できるようになります。
Kubernetesクラスターを構築する方法はいくつかありますが、公式が推奨し、最も一般的に利用されているツールの一つが kubeadm です。kubeadm は、最小限の労力で堅牢なKubernetesクラスターをセットアップするためのコマンドラインツールです。手動で各コンポーネントを設定するよりもはるかに簡単かつ迅速に、ベストプラクティスに従ったクラスターを構築できます。本記事では、この kubeadm を利用して、マスターノード1台とワーカーノード複数台からなるKubernetesクラスターをゼロから構築する手順を、詳細な解説とともに提供します。
このガイドは、Kubernetesの基礎知識がある方を対象としていますが、各ステップの背景にある理由や注意点についても深く掘り下げて説明することで、単なる手順書に留まらない実践的な知識を提供することを目指します。
本ガイドで構築するクラスターの概要
本記事では、以下のようなシンプルな構成のKubernetesクラスターを構築します。
- マスターノード (Master Node): 1台
- Kubernetesのコントロールプレーン(APIサーバー、スケジューラー、コントローラーマネージャー、etcd)を実行します。クラスターの状態を管理し、ワーカーノード上のワークロードをオーケストレーションします。
- ワーカーノード (Worker Node): 複数台
- コンテナ化されたアプリケーション(Pod)が実際に動作するノードです。kubelet、kube-proxy、コンテナランタイムが動作します。
- コンテナランタイム (Container Runtime): containerd を使用します。
- ネットワークプラグイン (CNI Plugin): Calico を使用します。Pod間のネットワークを確立し、ネットワークポリシーを適用します。
前提条件:構築を始める前に確認すべきこと
Kubernetesクラスターを安定して動作させるためには、各ノードが特定の要件を満たしている必要があります。以下の項目を慎重に確認し、準備を整えてください。
1. ハードウェア要件
各ノード(マスター、ワーカー共通)について、以下の最小要件を満たすことを推奨します。
- CPU: 2コア以上 (マスターノードは特に重要。ワーカーノードも複数のPodを動かすなら2コア以上が望ましい)
- RAM: 2GB以上 (マスターノードは4GB以上を推奨。etcdとコントロールプレーンの負荷を考慮)
- ディスクスペース: 20GB以上 (OS、Kubernetesコンポーネント、コンテナイメージ、Podデータ用。本番環境ではより大容量が必須)
- ネットワーク: 安定したネットワーク接続。有線接続を強く推奨。
2. オペレーティングシステム (OS)
Ubuntu 22.04 LTS を使用することを強く推奨します。kubeadm は様々なLinuxディストリビューションをサポートしていますが、UbuntuはKubernetesコミュニティで最も広く利用されており、豊富なドキュメントとコミュニティサポートがあります。
- 推奨OS: Ubuntu 22.04 LTS (Jammy Jellyfish)
- 互換性のあるOS: CentOS/RHEL 8+, Debian 11+, Fedora 37+, openSUSE Leap 15.x, SLES 15.x など。
- 注意: SELinuxを使用するOSの場合、Kubernetesの動作に影響を与える可能性があるため、無効化またはPermissiveモードに設定する必要があります。本記事ではUbuntuを前提とするため、SELinuxに関する詳細な手順は割愛します。
3. ネットワーク要件
Kubernetesクラスター内の通信は非常に重要です。以下の点を確認してください。
- 固定IPアドレス: 各ノードには静的IPアドレスを設定してください。DHCPを使用すると、IPアドレスが変更される可能性があり、クラスターの安定性に影響します。
- ホスト名 (Hostname) の設定: 各ノードに一意で分かりやすいホスト名を設定してください。
- 例:
k8s-master-01,k8s-worker-01,k8s-worker-02
- 例:
- DNS解決: 各ノードが自身および他のノードのホスト名をIPアドレスに解決できることを確認してください。
/etc/hostsファイルにエントリを追加するか、適切なDNSサーバーを設定します。 - ファイアウォール設定: Kubernetesの動作に必要なポートが開放されていることを確認してください。詳細なポートリストは後述します。
- SSHアクセス: 各ノードにSSHでアクセスできること。以降のほとんどの作業はSSH経由で行います。
ネットワーク設計の例:
| ノードの種類 | ホスト名 | IPアドレス | 役割 |
|---|---|---|---|
| マスター | k8s-master-01 |
192.168.1.10 |
Kubernetesコントロールプレーン |
| ワーカー | k8s-worker-01 |
192.168.1.11 |
アプリケーションPodの実行 |
| ワーカー | k8s-worker-02 |
192.168.1.12 |
アプリケーションPodの実行 (追加の例) |
4. ユーザー権限
sudo権限を持つユーザーで作業を行います。
ステップ1:全ノード共通の初期設定 (マスター&ワーカー)
このセクションでは、マスターノードとすべてのワーカーノードの両方に適用される共通の初期設定を行います。SSHで各ノードにログインし、以下の手順を実行してください。
1. OSの更新と必須パッケージのインストール
最新のセキュリティパッチとソフトウェアアップデートを適用し、後続のインストールに必要なパッケージを準備します。
“`bash
パッケージリストを更新
sudo apt update -y
システムのパッケージをアップグレード
sudo apt upgrade -y
必要なパッケージのインストール (ca-certificates, curl, gnupg, lsb-release)
ca-certificates: SSL/TLS 証明書を検証するために必要
curl: URLからデータを転送するためのコマンドラインツール
gnupg: GPGキーの管理に必要 (ソフトウェアリポジトリの認証に使用)
lsb-release: ディストリビューションの情報を取得するために必要 (リポジトリ設定用)
sudo apt install -y ca-certificates curl gnupg lsb-release
“`
2. Swapの無効化
Kubernetesは、パフォーマンスと安定性の理由から、ノード上でSwapが有効になっていることを許容しません。Swapは予測不能なパフォーマンスの低下を引き起こし、クラスターの挙動に悪影響を与える可能性があるため、完全に無効化する必要があります。
“`bash
一時的にswapを無効化 (再起動すると元に戻る可能性がある)
sudo swapoff -a
/etc/fstab を編集して永続的にswapを無効化
sedコマンドで/etc/fstab内の’swap’という行をコメントアウトする
sudo sed -i ‘/ swap / s/^(.*)$/#\1/g’ /etc/fstab
swapが完全に無効化されたか確認
free -h
Swap行が0Bになっていることを確認
“`
3. ファイアウォール (UFW) の設定
UbuntuではデフォルトでUFW (Uncomplicated Firewall) が利用できます。Kubernetesコンポーネント間の通信に必要なポートを開放します。
マスターノードで開放する必要があるポート:
| プロトコル | ポート範囲 | 説明 | コンポーネント |
|---|---|---|---|
| TCP | 6443 | Kubernetes APIサーバー | kube-apiserver |
| TCP | 2379-2380 | etcdサーバークライアントAPI | etcd |
| TCP | 10250 | Kubelet API | kubelet |
| TCP | 10259 | kube-schedulerのHTTPポート | kube-scheduler |
| TCP | 10257 | kube-controller-managerのHTTPポート | kube-controller-manager |
ワーカーノードで開放する必要があるポート:
| プロトコル | ポート範囲 | 説明 | コンポーネント |
|---|---|---|---|
| TCP | 10250 | Kubelet API | kubelet |
| TCP | 30000-32767 | NodePort Services (アプリケーション用) | kube-proxy |
全ノード共通のポート:
- SSH: TCP 22 (SSHアクセス用)
- Pod間通信: CalicoなどのCNIプラグインが使用するポート。CalicoはデフォルトでIP-in-IP (IP protocol 4) とUDP 4789 (VXLAN) を使用します。
以下のコマンドを 各ノードで 実行します。
“`bash
SSHポートの許可
sudo ufw allow 22/tcp
Kubelet APIの許可
sudo ufw allow 10250/tcp
マスターノードにのみ追加するポート
(マスターノードで実行)
sudo ufw allow 6443/tcp
sudo ufw allow 2379:2380/tcp
sudo ufw allow 10259/tcp
sudo ufw allow 10257/tcp
ワーカーノードにのみ追加するポート
(ワーカーノードで実行)
sudo ufw allow 30000:32767/tcp
UFWを有効化
sudo ufw enable
状態を確認
sudo ufw status verbose
``sudo ufw allow 22/tcp
**注意:** UFWを有効にするとSSHセッションが切断される可能性があります。をsudo ufw enableの前に実行することを忘れないでください。kubeadm
また、CNIプラグイン(Calicoなど)が使用するプロトコル(IP-in-IP: プロトコル番号4、またはUDP 4789)もファイアウォールで許可する必要がありますが、通常はとCNIの設定によって適切に処理されるか、ufw`がこれらのプロトコルに対して自動的に許可しないため、OSレベルのファイアウォールよりも、クラウドプロバイダのセキュリティグループやネットワークACLで管理する方が一般的です。ここでは基本的なTCPポートに絞ります。
4. Bridgeネットワークのフィルタリング有効化
KubernetesのPodネットワークは、Linuxブリッジングとiptablesに依存しています。sysctlパラメータを設定して、ブリッジされたトラフィックがiptablesによって正しく処理されるようにします。これは、CNIプラグインがPod間のネットワークを確立するために不可欠です。
“`bash
net.bridge.bridge-nf-call-iptables を有効化 (IPv4)
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF
モジュールのロード
sudo modprobe br_netfilter
sysctl設定の反映
sudo sysctl –system
``br_netfilter
*モジュール: ブリッジされたネットワークトラフィックがiptablesを通過できるようにするために必要です。net.bridge.bridge-nf-call-iptables = 1
*: IPv4トラフィックがブリッジを通過する際にiptablesのルールが適用されるようにします。net.bridge.bridge-nf-call-ip6tables = 1
*: IPv6トラフィックの場合。net.ipv4.ip_forward = 1`: IPフォワーディングを有効にし、ノードがルーターとして機能できるようにします。これはPodが外部と通信するために必要です。
*
5. コンテナランタイムのインストール (Containerd)
Kubernetesはコンテナの実行にCRI (Container Runtime Interface) 準拠のランタイムを必要とします。Dockerも利用可能ですが、軽量でKubernetesとの統合がより最適化された containerd を使用します。
“`bash
Dockerの公式GPGキーを追加
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg –dearmor -o /etc/apt/keyrings/docker.gpg
Dockerのリポジトリを追加
echo \
“deb [arch=$(dpkg –print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable” | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
パッケージリストを更新
sudo apt update -y
containerdのインストール
sudo apt install -y containerd.io
containerdのデフォルト設定ファイルを生成
sudo containerd config default | sudo tee /etc/containerd/config.toml >/dev/null
systemd cgroup driver を使用するように設定を変更
Kubernetesとcontainerdは同じcgroup driverを使用する必要がある
config.toml内の “SystemdCgroup = false” を “SystemdCgroup = true” に変更
sudo sed -i ‘s/SystemdCgroup = false/SystemdCgroup = true/g’ /etc/containerd/config.toml
containerdサービスを再起動して設定を適用
sudo systemctl restart containerd
containerdサービスが有効になっていることを確認 (OS起動時に自動起動するように)
sudo systemctl enable containerd
``kubelet
**Cgroup Driverの重要性:**
Kubernetesのとコンテナランタイム(この場合はcontainerd)は、**同じcgroup driver** を使用するように設定されている必要があります。デフォルトでは、kubeadmはkubeletにsystemdcgroup driverを使用するように設定します。したがって、containerdもsystemdcgroup driverを使用するように設定する必要があります。もしこれが一致しない場合、kubeletがcontainerdと通信できず、ノードがNotReady`状態になるなど、クラスターの起動に失敗します。
6. kubeadm, kubelet, kubectl のインストール
Kubernetesのコアツールをインストールします。
- kubeadm: Kubernetesクラスターを初期化またはワーカーノードをクラスターに参加させるためのコマンド。
- kubelet: 各ノード上で動作するエージェントで、Podの実行、ノードの登録、リソース管理などを行います。
- kubectl: Kubernetesクラスターと対話するためのコマンドラインツール。
“`bash
Kubernetesの公式GPGキーを追加
curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo gpg –dearmor -o /etc/apt/keyrings/kubernetes-archive-keyring.gpg
Kubernetesのリポジトリを追加
echo “deb [signed-by=/etc/apt/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main” | sudo tee /etc/apt/sources.list.d/kubernetes.list
パッケージリストを更新
sudo apt update -y
kubelet, kubeadm, kubectl をインストール
特定のバージョンを指定することも可能だが、今回は最新安定版をインストール
sudo apt install -y kubelet kubeadm kubectl
インストールしたKubernetesコンポーネントが自動更新されないようにする
自動更新されると、クラスターの安定性が損なわれる可能性があるため、手動でバージョンアップを行うのが一般的
sudo apt-mark hold kubelet kubeadm kubectl
kubeletサービスが有効になっていることを確認 (ただしまだ起動はしない)
sudo systemctl enable –now kubelet
``apt-mark hold
**の重要性:**apt upgrade
Kubernetesクラスターでは、各コンポーネントのバージョン管理が非常に重要です。などのコマンドでkubelet,kubeadm,kubectlが意図せずアップグレードされると、クラスターが不安定になったり、互換性の問題が発生したりする可能性があります。そのため、apt-mark hold`でこれらのパッケージを固定し、アップグレードは手動で行うのがベストプラクティスです。
これで、すべてのノード共通の初期設定が完了しました。次は、マスターノードとワーカーノード固有の設定に進みます。
ステップ2:マスターノード固有の設定
ここでは、k8s-master-01 (192.168.1.10) にログインして作業を行います。
1. kubeadmによるクラスターの初期化
マスターノードで kubeadm init コマンドを実行し、Kubernetesコントロールプレーンをセットアップします。このコマンドは、APIサーバー、etcd、スケジューラー、コントローラーマネージャーなどの主要コンポーネネントをインストールし、設定します。
重要なオプション:
--apiserver-advertise-address: APIサーバーが他のノードと通信するために使用するマスターノードのIPアドレスを指定します。マスターノードの固定IPアドレス (192.168.1.10) を指定します。--pod-network-cidr: Podに割り当てるIPアドレス範囲を指定します。これはCNIプラグインがPodネットワークを構築するために使用します。使用するCNIプラグイン(ここではCalico)のデフォルトのCIDRに合わせて192.168.0.0/16を指定します。これはクラスター内部のPod専用のIP空間です。--control-plane-endpoint: 高可用性(HA)クラスターを構築する場合にロードバランサーのDNS名またはIPアドレスを指定しますが、今回は単一マスターのためマスターノードのIPアドレスを直接指定するか、省略しても構いません。推奨はDNS名ですが、簡単化のためIPアドレスを使用します。
“`bash
kubeadm init の実行
–upload-certs を追加することで、ワーカーノード参加時に証明書を自動でコピーできるようになる (HAクラスターで特に便利だが、単一マスターでも利用可能)
sudo kubeadm init \
–apiserver-advertise-address=192.168.1.10 \
–pod-network-cidr=192.168.0.0/16 \
–control-plane-endpoint=k8s-master-01 \
–upload-certs
コマンド実行後、成功すると以下のような出力が表示されるはずです。
This will likely take several minutes.
… (省略) …
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
You should now deploy a Pod network to the cluster.
Run “kubectl apply -f [podnetwork].yaml” with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
Then you can join any number of worker nodes by running the following on each as root:
sudo kubeadm join 192.168.1.10:6443 –token –discovery-token-ca-cert-hash sha256:
``kubeadm init`が成功すると、重要な3つの情報 が出力されます。
kubectlの設定方法: クラスターを操作するためのkubectlコマンドを使用するための設定手順。- Podネットワーク (CNI) のインストール指示: クラスターが正しく機能するために必要なPodネットワークの導入について。
- ワーカーノード参加 (join) コマンド: 新しいワーカーノードをこのクラスターに参加させるための正確なコマンド。これは必ず控えておいてください。トークンとハッシュはセキュリティ上重要であり、一度失うと再生成が必要になります。
2. kubectl の設定
kubeadm init の出力に従い、通常のユーザーでkubectlコマンドを使えるように設定します。
“`bash
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
設定が正しく行われたか確認
kubectl cluster-info
Kubernetes control plane is running at https://192.168.1.10:6443
CoreDNS is running at https://192.168.1.10:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use ‘kubectl cluster-info dump’.
kubectl get nodes
出力は以下のようになり、マスターノードが “NotReady” と表示されるはずです。
NAME STATUS ROLES AGE VERSION
k8s-master-01 NotReady control-plane 2m v1.28.0 # バージョンは異なる可能性があります
NotReadyであるのは、まだPodネットワークがデプロイされていないためです。
“`
3. Podネットワークプラグイン (Calico) のインストール
クラスターのPod間の通信を有効にするため、CNI (Container Network Interface) プラグインをインストールします。ここでは、広く利用され、ネットワークポリシー機能も充実しているCalicoを使用します。
CalicoのYAMLファイルをダウンロードし、適用します。--pod-network-cidrで指定したIPアドレス範囲とCalicoの設定が一致している必要があります。
“`bash
CalicoのYAMLマニフェストをダウンロード
バージョンは適宜最新の安定版を確認してください
curl https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/calico.yaml -O
ダウンロードしたYAMLファイルを適用
これにより、CalicoのPodがkube-systemネームスペースにデプロイされ、Podネットワークが構築されます。
kubectl apply -f calico.yaml
Calico Podの起動状況を確認
少し時間がかかる場合があります。STATUSが”Running”になるまで待ちます。
kubectl get pods –all-namespaces -w
出力例:
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system calico-kube-controllers-5f78c946f8-abcde 1/1 Running 0 30s
kube-system calico-node-xxxxx 1/1 Running 0 30s
kube-system coredns-5c98db65d4-abcde 1/1 Running 0 1m
kube-system coredns-5c98db65d4-vwxyz 1/1 Running 0 1m
…
``Running`状態になったら、マスターノードのステータスを確認します。
すべてのCalico PodとCoreDNS Podが
“`bash
kubectl get nodes
出力例:
NAME STATUS ROLES AGE VERSION
k8s-master-01 Ready control-plane 5m v1.28.0 # STATUSが”Ready”になっていることを確認
``Ready`状態になっていれば、コントロールプレーンは正常に機能しており、Podネットワークも設定されています。
マスターノードが
ステップ3:ワーカーノード固有の設定
ここでは、k8s-worker-01 (192.168.1.11) と k8s-worker-02 (192.168.1.12) にログインして作業を行います。
1. クラスターへの参加 (kubeadm join)
マスターノードのkubeadm initコマンドの出力に表示された kubeadm join コマンドを、各ワーカーノードで実行します。
重要な注意点:
* kubeadm joinコマンドは、root権限 で実行する必要があります。
* --token と --discovery-token-ca-cert-hash は、kubeadm initコマンドの出力からコピーしたものを正確に入力してください。これらの値はクラスターごとに一意で、セキュリティのために使用されます。トークンの有効期限はデフォルトで24時間です。期限切れの場合は、マスターノードで kubeadm token create --print-join-command を実行して新しいトークンを取得できます。
ワーカーノード (k8s-worker-01, k8s-worker-02 など) で以下のコマンドを実行:
“`bash
マスターノードのkubeadm init出力からコピーしたjoinコマンドを実行
sudo kubeadm join 192.168.1.10:6443 –token
成功すると以下のような出力が表示されます
This node has joined the cluster:
* Certificate signing request was sent successfully to API Server 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.
“`
kubeadm join が成功したら、マスターノードに戻り、クラスターにノードが正しく参加したことを確認します。
ステップ4:クラスターの確認とテスト
マスターノード (k8s-master-01) にログインし、kubectlコマンドを使用してクラスターの状態を確認します。
1. ノードの状態確認
すべてのノードがReady状態になっていることを確認します。
“`bash
kubectl get nodes
出力例:
NAME STATUS ROLES AGE VERSION
k8s-master-01 Ready control-plane 15m v1.28.0
k8s-worker-01 Ready 2m v1.28.0 # k8s-worker-01が参加
k8s-worker-02 Ready 2m v1.28.0 # k8s-worker-02が参加
``STATUSがReadyになっていることを確認してください。もしNotReadyであれば、ワーカーノードのkubeletログ(sudo journalctl -u kubelet -f)やマスターノードのkubectl describe node
2. Podの状態確認
すべてのシステムPodがRunning状態であることを確認します。
“`bash
kubectl get pods –all-namespaces
出力例:
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system calico-kube-controllers-5f78c946f8-abcde 1/1 Running 0 18m
kube-system calico-node-xxxxx 1/1 Running 0 18m
kube-system calico-node-yyyyy 1/1 Running 0 2m # worker-01のCalico
kube-system calico-node-zzzzz 1/1 Running 0 2m # worker-02のCalico
kube-system coredns-5c98db65d4-abcde 1/1 Running 0 18m
kube-system coredns-5c98db65d4-vwxyz 1/1 Running 0 18m
kube-system etcd-k8s-master-01 1/1 Running 0 18m
kube-system kube-apiserver-k8s-master-01 1/1 Running 0 18m
kube-system kube-controller-manager-k8s-master-01 1/1 Running 0 18m
kube-system kube-proxy-abcde 1/1 Running 0 18m
kube-system kube-proxy-fghij 1/1 Running 0 2m # worker-01のkube-proxy
kube-system kube-proxy-klmno 1/1 Running 0 2m # worker-02のkube-proxy
kube-system kube-scheduler-k8s-master-01 1/1 Running 0 18m
``Running
すべてのPodが(またはCompleted、Evictedなど、正常な状態) であることを確認してください。特にPendingやCrashLoopBackOff`のPodがないか注意深く確認します。
3. サンプルアプリケーションのデプロイ
Nginxのデプロイメントを作成し、クラスターがアプリケーションを正しくスケジューリングして実行できるか確認します。
“`bash
Nginxデプロイメントの作成
kubectl create deployment nginx –image=nginx
デプロイメントの状態を確認
kubectl get deployment nginx
READYの列が1/1になるまで待ちます。
Podの状態を確認
kubectl get pods -l app=nginx
STATUSがRunningになることを確認
NginxサービスをNodePortとして公開
NodePortは、ワーカーノードの特定のポートを通じて外部からアプリケーションにアクセスできるようにするサービスタイプです。
kubectl expose deployment nginx –type=NodePort –port=80
サービスの状態を確認
kubectl get service nginx
出力例:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx NodePort 10.96.xxx.yyy 80:3xxxx/TCP 10s
PORT(S)の3xxxxの部分がNodePortとして割り当てられたポート番号です。
Nginxへのアクセス確認
ブラウザまたはcurlコマンドで、ワーカーノードのいずれかのIPアドレスとNodePortでアクセスします。
例: curl http://192.168.1.11:3xxxx (ワーカーノードのIPアドレス)
Welcome to nginx! が表示されれば成功です。
“`
これで、基本的なKubernetesクラスターの構築と動作確認が完了しました。
トラブルシューティング:一般的な問題と解決策
Kubernetesクラスター構築中に発生しやすい一般的な問題とその解決策をまとめました。
1. ノードが NotReady 状態のまま
- 原因:
kubeletが起動していない、コンテナランタイムが正しく動作していない、CNIプラグインがデプロイされていない、またはPodネットワークに問題がある。 - 確認コマンド:
sudo journalctl -u kubelet -f(ノード上でKubeletのログを確認)sudo systemctl status kubelet(Kubeletサービスの稼働状況確認)sudo systemctl status containerd(Containerdサービスの稼働状況確認)kubectl describe node <node_name>(マスターノードからノードの詳細な状態を確認)kubectl get pods --all-namespaces -o wide(Podがどのノードで実行されているか確認。特にkube-systemの名前空間のPod)
- 解決策:
- Cgroup Driverの不一致:
kubeletとcontainerdのcgroup driver設定が一致しているか確認 (/etc/containerd/config.tomlのSystemdCgroupとkubeletの設定)。多くの場合、SystemdCgroup = trueにする必要があります。変更後はsudo systemctl restart containerdとsudo systemctl restart kubelet。 - CNIプラグイン未インストール/問題: マスターノードにCalicoなどのCNIプラグインが正しくデプロイされているか確認。Calico Podが
Runningか確認し、ログ(kubectl logs calico-node-xxxxx -n kube-system)を確認。 - ファイアウォール: 必要なポートが開放されているか確認。
- Swap: Swapが完全に無効化されているか再確認。
- Cgroup Driverの不一致:
2. Podが Pending 状態のまま
- 原因: Podをスケジューリングできるノードがない、リソース不足、Node Selector/Taints and Tolerations の問題、Podネットワークの問題。
- 確認コマンド:
kubectl describe pod <pod_name> -n <namespace>(Podの詳細なイベントとエラーメッセージを確認)kubectl get nodes(ノードの状態とリソースを確認)
- 解決策:
- リソース不足: ノードのリソース(CPU, Memory)が十分か確認。Podの要求リソースがノードのキャパシティを超えていないか確認。
- CNI問題: CNIプラグインが正しく動作しているか確認。特にCalico Podが正常に起動しているか。
- Taints/Tolerations: マスターノードにPodをデプロイしたい場合、デフォルトではTaintが設定されているため、
kubectl taint nodes --all node-role.kubernetes.io/control-plane-でTaintを解除するか、PodにTolerationを設定する必要があります。
3. Podが CrashLoopBackOff 状態のまま
- 原因: アプリケーションのエラー、設定ミス、イメージが見つからない、依存関係の問題。
- 確認コマンド:
kubectl logs <pod_name> -n <namespace>(Podのアプリケーションログを確認)kubectl describe pod <pod_name> -n <namespace>(Podの詳細イベント、イメージプルエラーなどを確認)
- 解決策:
- アプリケーションログの確認: 最も重要なステップ。アプリケーションのエラーメッセージから原因を特定。
- イメージ名の確認: イメージ名が正しいか、プライベートレジストリからのプルに認証が必要な場合は設定されているか確認。
- 設定ファイル (ConfigMap, Secret) の確認: アプリケーションが依存する設定が正しく提供されているか確認。
4. kubeadm join がうまくいかない
- 原因: トークンの有効期限切れ、ハッシュ値の間違い、マスターノードへのネットワーク接続問題。
- 確認コマンド:
- ワーカーノードからマスターノードのAPIサーバーへの疎通確認:
curl -k https://192.168.1.10:6443/version
- ワーカーノードからマスターノードのAPIサーバーへの疎通確認:
- 解決策:
- 新しいトークンの生成: マスターノードで
sudo kubeadm token create --print-join-commandを実行し、新しいjoinコマンドを取得して再試行。 - ファイアウォール: マスターノードの6443ポートが開放されているか確認。
- ホスト名/IPアドレスの解決: 各ノードから他のノードのホスト名やIPアドレスが正しく解決できるか確認。
- 新しいトークンの生成: マスターノードで
5. kubeadm reset で初期状態に戻す
クラスターを再構築したい場合や、特定ノードをクラスターから除外して初期状態に戻したい場合は、kubeadm resetコマンドを使用します。
“`bash
ノード上で実行
sudo kubeadm reset
もしストレージボリュームが残っている場合 (Dockerやcontainerdのボリュームなど)
それらもクリーンアップしたい場合は、以下のコマンドを参考に手動で削除
sudo rm -rf /etc/cni/net.d
sudo rm -rf ~/.kube/config
sudo systemctl stop kubelet containerd
sudo rm -rf /var/lib/kubelet
sudo rm -rf /var/lib/containerd
sudo rm -rf /etc/kubernetes/pki
sudo apt purge -y kubelet kubeadm kubectl containerd.io
sudo apt autoremove -y
``kubeadm reset` はKubernetes関連のファイルを削除しますが、コンテナランタイムやOSレベルの設定(Swap無効化など)は手動で元に戻すか、再度設定し直す必要があります。
追加設定と次のステップ
クラスター構築は第一歩に過ぎません。より実用的なクラスターにするために、いくつかの追加設定や学習を継続することを推奨します。
1. Kubernetes Dashboardのインストール
Kubernetes Dashboardは、Webベースのユーザーインターフェースで、クラスター内のリソース(デプロイメント、Pod、サービスなど)の管理や監視を視覚的に行うことができます。
“`bash
Dashboardのデプロイ
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml
Dashboardへのアクセス用のServiceAccountとClusterRoleBindingを作成
(認証方法により方法は異なりますが、ここでは簡単化のためにトークン認証用の設定例)
cat <<EOF | kubectl apply -f –
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kubernetes-dashboard
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
– kind: ServiceAccount
name: admin-user
namespace: kubernetes-dashboard
EOF
トークンを取得
kubectl -n kubernetes-dashboard create token admin-user
プロキシを起動
マスターノードで実行し、Webブラウザから http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/ にアクセス
kubectl proxy –address=’0.0.0.0′ –accept-hosts=’.*’
“`
ブラウザでアクセスし、トークン認証でログインします。
2. Ingress Controllerのインストール
NodePortサービスはポートが動的に割り当てられるため、本番環境には向きません。Ingress Controllerは、外部からのHTTP/HTTPSトラフィックをクラスター内のサービスにルーティングするための強力な方法です。Nginx Ingress Controllerが最も一般的です。
“`bash
Nginx Ingress Controllerのデプロイ (例: bare-metal環境向け)
公式ドキュメントを参照して、お使いの環境に合ったマニフェストを適用してください
https://kubernetes.github.io/ingress-nginx/deploy/#bare-metal
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.1/deploy/static/provider/cloud-generic.yaml
“`
3. 永続ストレージのプロビジョニング (Persistent Volume)
コンテナは通常、一時的なストレージを使用します。データベースや状態を持つアプリケーションのために、永続的なストレージが必要です。
- NFS: 共有ファイルシステムとして手軽に利用できます。NFSサーバーを別途用意し、NFS Provisionerをデプロイします。
- Longhorn: Kubernetesネイティブな分散ブロックストレージソリューションで、デプロイが比較的簡単です。
- クラウドプロバイダのCSI (Container Storage Interface): AWS EBS, Google Persistent Disk, Azure Diskなど。
4. 監視 (Monitoring) とログ収集 (Logging)
- Prometheus & Grafana: クラスターのメトリクスを収集・可視化するためのデファクトスタンダード。
- ELK Stack (Elasticsearch, Logstash, Kibana) / Grafana Loki: クラスター内のログを集約・分析するためのソリューション。
5. 高可用性 (High Availability) クラスター
本ガイドでは単一マスターノードのクラスターを構築しましたが、本番環境ではマスターノードの障害に備えて複数台のマスターノード(3台または5台)と外部/内部ロードバランサーを使用したHA構成が推奨されます。
6. セキュリティの強化
- RBAC (Role-Based Access Control) の適切な設定
- ネットワークポリシーによるPod間の通信制御 (Calicoで可能)
- コンテナイメージの脆弱性スキャン
- シークレット管理のベストプラクティス
まとめ
本記事では、kubeadm を使用してKubernetesクラスターをゼロから構築する詳細な手順を、マスターノードとワーカーノードそれぞれに分けて解説しました。Swapの無効化、ファイアウォール設定、sysctlパラメータの調整、containerdのインストールとcgroup driverの設定、kubeadm, kubelet, kubectlの導入、そしてkubeadm initとkubeadm joinによるクラスターのセットアップ、さらにCalicoによるPodネットワークの確立までを網羅しました。
これにより、アプリケーションをデプロイし、実行できる基本的なKubernetes環境が手に入ります。しかし、Kubernetesは広大なエコシステムを持ち、その可能性を最大限に引き出すためには、Dashboard、Ingress、永続ストレージ、監視、ログ収集、そして高可用性といった追加の概念とツールを学習していくことが不可欠です。
このガイドが、皆さんのKubernetesジャーニーの確かな第一歩となり、コンテナ化されたアプリケーションのデプロイと管理をより効率的かつ堅牢にする手助けとなれば幸いです。Kubernetesの学習は奥深く、継続的な探求が必要ですが、その投資は間違いなく、現代のクラウドネイティブな開発において大きなリターンをもたらすでしょう。
文字数概算: 約5000語に調整しました。各ステップの説明、背景、トラブルシューティング、次のステップに詳細を加えています。