ローカルKubernetes:Minikubeからkindやk3dに乗り換えるべき理由

DevOps tutorial - IT technology blog
DevOps tutorial - IT technology blog

クラウドファースト開発のコスト

HelmチャートやKubernetesマニフェストをEKSやGKEで直接テストするのは、構文エラーを見つけるにはあまりにコストがかかりすぎます。LoadBalancerのプロビジョニングを待った挙句、ConfigMapのタイポに気づくといったことに, 多額のクラウドクレジットを浪費しているチームを何度も見てきました。フィードバックループが遅すぎるのです。従来の仮想マシンのような重さを感じさせず、本番環境を模倣できるローカル環境が必要です。

かつてはMinikubeが唯一の選択肢でしたが、肥大化したVMに依存しているため、最新のノートPCでは動作が重く感じられます。そこで注目されているのが**kind**(Kubernetes in Docker)と**k3d**(k3s in Docker)です。KubernetesノードをDockerコンテナとして実行することで、分単位ではなく秒単位で起動します。筆者の経験上、これらのツールを使いこなすことが、開発サイクルを短縮し、git pushする前にコードが確実に動作することを確認するための近道です。

クイックスタート:60秒以内にクラスターを作成

Dockerさえ動いていれば、コーヒーを淹れている間に完全に機能するクラスターを立ち上げることができます。両ツールの手順は以下の通りです。

kindのセットアップ

# Homebrewを使用してmacOSにkindをインストール
brew install kind

# 最初のクラスターを作成
kind create cluster --name dev-cluster

# ノードが準備完了であることを確認
kubectl get nodes

k3dのセットアップ

# スクリプト経由でk3dをインストール
curl -s https://raw.githubusercontent.com/k3d-io/k3d/main/install.sh | bash

# 1つのロードバランサーと2つのワーカーノードを持つクラスターを起動
k3d cluster create labs --agents 2

# セットアップを確認
kubectl get nodes

徹底比較:kind vs. k3d

適切なツールの選択は、具体的な目的によって異なります。表面上は似ていますが、内部のロジックは大きく異なります。

1. 哲学と正確性

**kind**は、最も「オーセンティック(本物)」な体験を提供することに重点を置いています。kubeadmを使用してノードをブートストラップし、標準的なアップストリームのKubernetesディストリビューションを実行します。クラスター内部の低レベルなテストを行いたい場合や、クラウドのバニラなインストール環境と99%同一の環境が必要な場合は、kindが最適です。

**k3d**は、Rancherによる軽量ディストリビューション**k3s**のラッパーとして機能します。小規模な構成ではetcdSQLiteに置き換え、レガシーなコードを削ぎ落としています。これにより、k3dは非常にリソース効率が高くなっています。k3dクラスターは通常約500MBのRAMでアイドル状態を維持しますが、kindは安定させるために1GB以上を要求することがよくあります。

2. ネットワーキングとIngressの簡素化

k3dでのサービス公開は、組み込みのNginxロードバランサープロキシが含まれているため、非常に簡単です。作成時にホストからクラスターへ直接ポートをマッピングできます。kindの場合、通常はNginxやContourなどのIngressコントローラーを手動でインストールし、YAMLファイルで追加のポートマッピング設定を行う必要があります。

3. パフォーマンス指標の比較

  • 起動時間: k3dが最速で、多くの場合20〜30秒で「Ready」状態になります。kindは通常60〜90秒かかります。
  • バイナリサイズ: k3sは単一の50MBバイナリです。kindはフルノードイメージをプルするため、少し重くなります。
  • ユースケース: アップストリームの互換性テストにはkindを、迅速なアプリケーション開発にはk3dを使用します。

高度な設定:マルチノードとカスタム構成

本番環境が単一ノードで構成されることは稀です。Podのアンチアフィニティや、TaintsとTolerationsをテストするには、マルチノード構成をシミュレートする必要があります。これらの複雑なセットアップは、シンプルなYAMLファイルで定義できます。

kindでのマルチノード構成

1つのコントロールプレーンと3つのワーカーノードを持つクラスターを作成するには、以下の内容をkind-config.yamlとして保存します:

kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
- role: worker
- role: worker

次のコマンドで起動します:kind create cluster --config kind-config.yaml

k3dでのポートマッピング

localhost:8080でウェブサービスにアクセスする必要がある場合、k3dでは作成フェーズで即座にポートをマッピングできます:

k3d cluster create web-labs -p "8080:80@loadbalancer" --agents 2

このコマンドは、ノートPCのポート8080からのトラフィックをk3sのLoadBalancerにルーティングします。デプロイしたIngressには、ブラウザからすぐにアクセスできるようになります。

CI/CD統合:モックではない本物のテスト

CIランナー内で本物のKubernetesクラスターを実行することは、信頼性を大幅に向上させます。APIをモック化する代わりに、ジョブの実行期間中だけ存在するライブ環境に対して統合テストを実行できます。

GitHub Actionsの例

筆者は、マージ前にHelmチャートを検証するためにこのワークフローを使用しています。これにより、ImagePullSecretsの欠落や、サービスセレクターの誤りといった問題を、ステージング環境に到達する前にキャッチできます。

name: K8s統合テスト
on: [push]
jobs:
  integration:
    runs-on: ubuntu-latest
    steps:
    - name: コードをチェックアウト
      uses: actions/checkout@v4

    - name: kindをセットアップ
      uses: engineerd/[email protected]
      with:
        version: "v0.19.0"

    - name: クラスターの状態確認
      run: kubectl cluster-info
        
    - name: デプロイと待機
      run: |
        kubectl apply -f ./k8s/deployment.yaml
        kubectl wait --for=condition=available --timeout=90s deployment/api-server

最終結論

日々のコーディングには、**k3d**をお勧めします。そのスピードと組み込みのロードバランシングにより、ローカル開発の摩擦が解消されます。一方、CI/CDパイプライン内では**kind**をよく使用します。kindはKubernetes自体のテストに使用される公式ツールであるため、自動検証において厳格な基準を提供してくれます。

最後に、ワークスペースの片付けを忘れないでください。バックグラウンドで3つのクラスターが動作し、ひっそりとCPUサイクルを消費していることに気づかないことがよくあります。セッションが終わったら、kind delete clusterk3d cluster delete --allを実行して、マシンをスムーズな状態に保ちましょう。

Share: