K8s 基礎 #2 ローカル環境 — minikube / kind / Docker Desktop k8s

読了 10分

#1 Kubernetes とは で control plane と worker に分かれたクラスタの全体像を見ました。この記事ではローカルで K8s クラスタを立てる 3 つの方法 — minikubekindDocker Desktop 内蔵の K8s — を比較し、kubectl をインストールして kind で初めてのクラスタを立て、ノードとシステム pod を確認する流れを扱います。

このシリーズは K8s 基礎 7 編です。

この記事の終わりには ローカルクラスタ 1 台 + そのクラスタを覗き見られる kubectl までが揃います。それが #3 からの出発点です。

ローカル K8s の 3 つの道 #

3 つのツールはいずれも「ローカルに K8s クラスタを 1 台立てる」という同じ仕事をしますが、動作の仕方と長所短所が少しずつ違います。

ツール動作の仕方マルチノード起動時間向いている人
Docker Desktop k8sDocker Desktop 内部の VM 上で単一ノード K8s を実行× (単一ノード)macOS / Windows で既に Docker Desktop を使っているユーザ
minikubeVM またはコンテナドライバから選んでクラスタを実行○ (オプション)アドオン (ingress、dashboard など) を豊富に使いたいとき
kindDocker コンテナ 1 台 1 台を K8s ノードとして使用速い軽く、またはマルチノードを YAML で定義したいとき / CI

もう少し詳しく説明するとこうなります。

Docker Desktop k8s は macOS と Windows で一番手のかからない道です。Docker Desktop を既に使っているなら、設定メニューの Kubernetes タブでチェック 1 つでクラスタが立ち、kubectl のコンテキストも自動で docker-desktop に切り替わります。難点は macOS / Windows 限定 であること(Linux 用の Docker Desktop も同じオプションを提供しますが、環境によって事情が違います)、そしてどのみち Docker Desktop が立てた VM の中で動く K8s なので、メモリと CPU をかなり使うことです。

minikube はローカル K8s ツールの中でも古株です。環境に応じて docker / hyperkit / kvm / virtualbox などのドライバから 1 つが自動選択されるか、ユーザが選んで使えます。最大の長所は アドオン (addon) の豊富さです。ingress、metrics-server、dashboard、registry のようによく必要になる付加機能をコマンド 1 行でオンにできます。

kind は名前が動作の説明そのものです — Kubernetes IN Docker。Docker コンテナ 1 台を K8s ノードとして使うので、VM を別に立てる minikube / Docker Desktop より軽くて速いです。マルチノードクラスタを短い YAML で定義 できるので control plane と worker を分離した環境を再現しやすく、そのため K8s 自身の CI でも使われています。

どれを選ぶか #

既に macOS / Windows で Docker Desktop を使っているなら、最初は Docker Desktop k8s が一番楽です。チェック 1 つでクラスタが立ち、普段使っている Docker 環境と自然に繋がります。Linux ユーザだったり、マルチノード環境を再現してみたかったり、クラスタをよく作って消したいなら kind がよく合います。アドオンを 1 行でオンオフして色々試したいなら minikube も良い選択です。

このシリーズの本文では kind をメインの道にして進めます。軽くて速く、コマンド 1 〜 2 行でクラスタを作って消せるので学習向きだからです。ただし どれを選んでも #3 からの kubectl コマンドは同じです。 クラスタを立てる方法が違うだけで、その上で扱う K8s リソースは同じです。なので自分の環境に合うものを選んで付いてきてください。

kubectl のインストール #

クラスタをどこに立てても、そのクラスタと話すクライアントは共通で kubectl です。K8s コントロールプレーンの API サーバ (kube-apiserver) に HTTP でコマンドを送る CLI です。

macOS — Homebrew #

kubectl のインストール (macOS)
brew install kubectl

Windows — winget または Chocolatey #

kubectl のインストール (Windows)
winget install -e --id Kubernetes.kubectl
# または
choco install kubernetes-cli

Linux — 公式バイナリ #

kubectl のインストール (Linux)
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
chmod +x kubectl
sudo mv kubectl /usr/local/bin/

ディストリビューションによってはパッケージマネージャ (aptdnf など) でもインストールできますが、K8s はクライアントとサーバのバージョンの互換範囲を合わせておくほうが安全です。正確な手順が必要なら kubernetes.io のインストール案内 を参照してください。

インストールが終わったらクライアントのバージョンを確認します。

インストールの確認
kubectl version --client
出力例
Client Version: v1.30.x
Kustomize Version: v5.x.x

この時点ではまだクラスタが無いのでサーバのバージョンは出ません。クラスタを立てるとそのあとに付いてきます。

kind で最初のクラスタを立てる #

この記事のメインの道です。まず kind 自体をインストールします。

kind のインストール (macOS)
brew install kind
kind のインストール (Windows)
winget install -e --id Kubernetes.kind
# または
choco install kind
kind のインストール (Linux)
curl -Lo ./kind https://kind.sigs.k8s.io/dl/latest/kind-linux-amd64
chmod +x kind
sudo mv kind /usr/local/bin/

kind は Docker デーモンを使います。Docker Desktop または Docker Engine が先に動いている必要があります。

それではクラスタを 1 台作ります。単一ノードならコマンド 1 行で終わります。

クラスタの作成
kind create cluster
出力例
Creating cluster "kind" ...
 - Ensuring node image (kindest/node:v1.30.x) - 
 - Preparing nodes - 
 - Writing configuration - 
 - Starting control-plane - 
 - Installing CNI - 
 - Installing StorageClass - 
Set kubectl context to "kind-kind"
You can now use your cluster with:

kubectl cluster-info --context kind-kind

最後の行が肝心です。kubectl のコンテキストが自動で kind-kind に切り替わります。 これ以降の kubectl コマンドはこのクラスタに向かいます。

kind はどう動いているのか #

kind は Docker コンテナ 1 台を K8s ノードとして使う、と言いました。本当にそうなのか Docker 側で確認できます。

kind が立てたコンテナを見る
docker ps
出力例
CONTAINER ID   IMAGE                  COMMAND                  PORTS                       NAMES
abc123def456   kindest/node:v1.30.x   "/usr/local/bin/entr…"   127.0.0.1:xxxxx->6443/tcp   kind-control-plane

kindest/node イメージから作られたコンテナが 1 台立っていて、その中で control plane と worker が一緒に動いています。ホストの任意のポートがコンテナの 6443 (K8s API サーバの既定ポート) にマッピングされていて、kubectl はこのポート経由でコマンドを送ります。

最初のコマンド — ノードとシステム pod を眺める #

クラスタが立ったので、#1 で名前だけ出ていたコンポーネントが実際に動いている様子を確認します。

ノード一覧
kubectl get nodes
出力例
NAME                 STATUS   ROLES           AGE   VERSION
kind-control-plane   Ready    control-plane   45s   v1.30.x

単一ノードクラスタなので 1 行だけ出ます。このノード 1 台が control plane の役割もし、同時にワークロードも受け取る形 (ローカル環境でよくある構成) です。

次に すべての namespace の pod を見ます。K8s コンポーネントはクラスタ上に pod の形で立っていることが多いからです。

すべての namespace の pod
kubectl get pods -A
出力例
NAMESPACE            NAME                                         READY   STATUS    RESTARTS   AGE
kube-system          coredns-xxxxxxxxxx-aaaaa                     1/1     Running   0          1m
kube-system          coredns-xxxxxxxxxx-bbbbb                     1/1     Running   0          1m
kube-system          etcd-kind-control-plane                      1/1     Running   0          1m
kube-system          kindnet-xxxxx                                1/1     Running   0          1m
kube-system          kube-apiserver-kind-control-plane            1/1     Running   0          1m
kube-system          kube-controller-manager-kind-control-plane   1/1     Running   0          1m
kube-system          kube-proxy-xxxxx                             1/1     Running   0          1m
kube-system          kube-scheduler-kind-control-plane            1/1     Running   0          1m
local-path-storage   local-path-provisioner-xxxxxxxxxx-yyyyy      1/1     Running   0          1m

#1 で名前だけ出ていたコンポーネントがそのまま見えます — kube-apiserveretcdkube-schedulerkube-controller-managerkube-proxy、そしてクラスタ DNS の coredns。それに kind 特有のネットワークプラグイン kindnet、ローカル環境で PersistentVolume を再現する local-path-provisioner まで。

kube-system namespace は K8s が自分の運用のために使う pod が集まる区画 です。これから作るアプリは default namespace (または自分で作った namespace、#7) に行きます。

最後にクラスタ自体のメタ情報を確認します。

クラスタ情報
kubectl cluster-info
出力例
Kubernetes control plane is running at https://127.0.0.1:xxxxx
CoreDNS is running at https://127.0.0.1:xxxxx/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

この出力の 1 行目に書かれた IP・ポートが、上で見た docker ps のポートマッピングと同じところです。つまり kubectl はホストで Docker が公開してくれたポート経由で、ノードコンテナの中の kube-apiserver と話しているわけです。

kubeconfig — kubectl がどこにコマンドを送るのか #

kubectl がどのクラスタにコマンドを送るかは kubeconfig ファイル が決めます。既定のパスは次の通りです。

  • macOS / Linux — ~/.kube/config
  • Windows — %USERPROFILE%\.kube\config

このファイルには 3 つの情報が入っています。

項目意味
clustersどんなクラスタがあるか (API サーバアドレス、CA 証明書)
usersそのクラスタにどんな資格情報でアクセスするか (証明書、トークンなど)
contexts「このクラスタ + このユーザ + この namespace」のまとまり。kubectl は一度に 1 つの context を使う

kind がクラスタを作るときに kind-kind という context を自動で追加し、現在の context をそこに合わせます。確認してみます。

context を見る
kubectl config get-contexts
出力例
CURRENT   NAME             CLUSTER          AUTHINFO         NAMESPACE
*         kind-kind        kind-kind        kind-kind        
現在の context
kubectl config current-context
出力例
kind-kind

複数のクラスタを同時に扱うようになると (例: ローカル kind、会社の dev クラスタ、会社の prod クラスタ) kubectl config get-contexts に項目が複数並びます。そのうち 1 つを選んで現在の context に切り替えるコマンドが use-context です。

context の切り替え
kubectl config use-context kind-kind

会社のクラスタとローカルを行き来して作業するときは、コマンドを誤ったクラスタに送らないよう常に context を意識する習慣 が大切です。シェルプロンプトに現在の context を出してくれるツール (kube-ps1starship など) もよく使われます。

Docker Desktop k8s で立てる場合 #

Docker Desktop を既に使う環境なら、設定メニューで K8s をオンにするだけでクラスタが立ちます。正確なメニューパスは Docker Desktop のバージョンによって少し違いますが、おおよそ次の通りです。

  1. Docker Desktop を起動 → Settings (または Preferences)
  2. 左メニューの Kubernetes タブ
  3. Enable Kubernetes をチェック → Apply & Restart

最初の有効化時は K8s コンポーネントイメージの取得で数分かかります。終わると kubectl の context が自動で追加されます。

Docker Desktop k8s context への切り替え
kubectl config use-context docker-desktop
kubectl get nodes
出力例
NAME             STATUS   ROLES           AGE   VERSION
docker-desktop   Ready    control-plane   2m    v1.30.x

これ以降の kubectl コマンドは kind と完全に同じです。

minikube で立てる場合 #

minikube も似ています。先に minikube CLI をインストールしてから (公式案内: minikube.sigs.k8s.io)、クラスタを開始します。

minikube クラスタの開始
minikube start

ドライバを明示的に選びたいなら --driver オプションを使います。既定のドライバは環境に応じて docker / hyperkit / kvm などから自動で選ばれます。

ドライバを明示した開始
minikube start --driver=docker

minikube が立つと context が minikube に切り替わります。

確認
kubectl config use-context minikube
kubectl get nodes

minikube の魅力の 1 つであるアドオンは minikube addons コマンドで扱います。例えば ingress コントローラをオンにするにはこうします。

ingress アドオン
minikube addons enable ingress

片付け #

学習が終わったり、クラスタを新しく作り直したいときに、きれいに片付ける方法も知っておくと便利です。

kind

kind クラスタの削除
kind delete cluster

名前を別途付けていなければ既定の名前 (kind) のクラスタが消えます。複数のクラスタを同時に運用していた場合は --name で指定してください。

Docker Desktop k8s

設定の Kubernetes タブで Disable Kubernetes をチェックします。または同じ画面の Reset Kubernetes Cluster ボタンで初期化することもできます。

minikube

minikube の停止/削除
minikube stop      # 一時停止 (次に start で再開可能)
minikube delete    # 完全に削除

ローカルクラスタは いつでも消して作り直せる軽さ が大きな長所です。何か絡まったと感じたら、きれいに消して立て直すほうが早いことが多いです。

まとめ #

この記事で押さえた流れ:

  • ローカルで K8s を立てる道は 3 つ — Docker Desktop k8s (チェック 1 つ、macOS / Windows)、minikube (アドオンが豊富)、kind (軽くて速い、マルチノード対応)。
  • クラスタをどこに立てても、クライアントは共通で kubectl です。パッケージマネージャか公式バイナリでインストールした後、kubectl version --client で確認します。
  • kind は Docker コンテナ 1 台をノードとして使います。 kind create cluster 1 行で単一ノードクラスタが立ち、docker pskindest/node コンテナとして見えます。
  • kubectl get nodes / kubectl get pods -A / kubectl cluster-info でクラスタを眺めると、#1 で名前だけ出ていた kube-apiserveretcdcoredns などが実際に動いています。
  • kubeconfig (~/.kube/config) は clusters / users / contexts の 3 部で構成され、kubectl config use-context で複数クラスタを行き来します。
  • 使い終わったクラスタは kind delete cluster / minikube delete / Docker Desktop の Disable Kubernetes できれいに片付けます。

次 — kubectl で最初の Pod を立てる #

この記事ではローカルクラスタを立てる方法と kubectl を繋ぐ出発点を押さえました。次の記事ではこのクラスタに最初の Pod を立てる方法を扱います。

#3 kubectl と最初の Pod では K8s の最小実行単位である Pod を見ます。kubectl run で命令的に立てる道と YAML マニフェストで宣言的に立てる道の両方を見て、kubectl get / describe / logs / exec のような日常コマンドで Pod を覗き見る流れまで整理します。そこからが K8s の本当の始まりです。

X