G-gen の佐々木です。当記事ではコンテナ オーケストレーション ツールである Kubenretes の学習用のため、Minikube を使って Compute Engine(Google Compute Engine、GCE)仮想マシン上にローカル Kubernetes クラスタを構築していきます。
はじめに
当記事の目的
当記事では Minikube という OSS(オープンソースソフトウェア)を使用して、Compute Engine の仮想マシン(インスタンス)上に学習用の Kubernetes クラスタを構築する方法を紹介します。
Kubernetes はコンテナ オーケストレーション ツールのデファクトスタンダードであり、マネージドな Kubernetes クラスタを提供する Google Kubernetes Engine(GKE)は Google Cloud における代表的なサービスの一つです。
Kubernetes はコンテナの運用管理のための非常に強力なツールである反面、独自の用語や設定ファイル、高頻度のバージョンアップなど、学習コストが高いことで知られています。当記事の内容は、Kubernetes に入門するための簡易的な学習環境を、低コストで用意することを目的としています。
学習環境として Compute Engine を用いるメリットとして、使用しないときはインスタンスを停止して料金を節約できる点や、マシンイメージ等を使用してバックアップを取得し、必要に応じて手軽にリストアすることができる点があります。
なお、GKE では請求先アカウントにつき月額 $74.40 の無料枠が提供されています。実際の GKE クラスタを使用して学習を行いたい場合は、Autopilot クラスタでこの無料枠を利用してみるのもよいでしょう。
- 参考 : クラスタ管理手数料と無料枠
ただし、GKE は膨大な量のログを Cloud Logging に出力するため、Cloud Logging の料金にも注意を払う必要があります。
また、以下の記事では Terraform を使用して Autopilot モードの GKE クラスタを作成する方法を紹介していますので、参考にしてください。
Minikube とは
Minikube はローカル環境で Kubernetes を実行するためのツールです。Minikube を使うと、仮想マシン上にシングルノードの Kubernetes クラスタを構築することができます。Minikube では Kubernetes の全ての機能を使用できるわけではありませんが、基本的な動作の確認や開発環境として利用することができます。
当記事では、以下の公式チュートリアルを元に Minikube をインストールし、クラスタの構築を行います。
Compute Engine インスタンスの作成
作業の概要
Google Cloud プロジェクトに Compute Engine インスタンスを作成します。
インスタンスは VPC 内のサブネットに作成する必要があるため、それらのリソースを先に作成し、その中にインスタンスを作成します。
そして、インスタンス内で作業する際に VPC の外部から接続できるように、接続を許可するファイアウォールルールを設定しておきます。
当記事では gcloud コマンドを用いてリソースの作成を行っていきます。gcloud コマンドのインストールについては以下のドキュメントを参照してください。
- 参考 : gcloud CLI をインストールする
また、Google Cloud コンソールから利用できる Cloud Shell(ブラウザベースのターミナル環境)には gcloud コマンドがプリインストールされているため、以降の作業をそのまま実施することができます。
- 参考 : Cloud Shell を使用する
シェル変数の設定
コマンドで何度か使用する値をシェル変数に格納しておきます。当記事では SUFFIX
の値を minikube として進めていきます。PROJECT
にはリソースを作成するプロジェクトの ID を、REGION
には asia-northeast1 などのリージョンを指定します。
SUFFIX={適当な値} # 当記事では minikube PROJECT={プロジェクトID} REGION={リソースを作成するリージョン}
VPC・サブネットの作成
VPC の作成
以下のコマンドで VPC を作成します。サブネットを手動で作成するため、--subnet-mode
フラグで custom
を指定します。
# VPC を作成する $ gcloud compute networks create vpc-${SUFFIX} \ --subnet-mode=custom \ --project=${PROJECT}
サブネットの作成
作成した VPC を指定し、その中にサブネットを作成します。--range
フラグではサブネットに割り当てるプライベート IP アドレスの範囲を CIDR で指定します。当記事では 192.168.144.0/28
を割り当てています。
# サブネットを作成する $ gcloud compute networks subnets create subnet-${SUFFIX} \ --network=vpc-${SUFFIX} \ --region=${REGION} \ --range=192.168.144.0/28 \ --project=${PROJECT}
インスタンスの作成
Minikube の要件について
公式チュートリアルによると、Minikube のリソース要件は以下のようになっています。
- 2つ以上の CPU
- 2 GB 以上のメモリ容量
- 20 GB 以上のディスク領域
たとえばメモリが不足している場合、Minikube を実行しようとしても、以下のようにエラーが出て終了してしまいます。
# メモリ不足の場合、Minikube を実行できない $ minikube start --driver=docker 😄 minikube v1.34.0 on Debian 12.7 (amd64) ✨ Using the docker driver based on user configuration ⛔ Exiting due to RSRC_INSUFFICIENT_CONTAINER_MEMORY: docker only has 969MiB available, less than the required 1800MiB for Kubernetes
当記事ではメモリ容量にある程度余裕があるマシンタイプでインスタンスを作成します。
マシンタイプは簡単に変更することができるため、まずは小さめのマシンタイプで試してみて、足りなければリソースを増やしてもよいでしょう。
インスタンスの作成
前の手順で作成した VPC とサブネットを指定し、Compute Engine インスタンスを作成します。
当記事では以下の設定値でインスタンスを作成します。
項目 | gcloud コマンドのフラグ | 値 | 備考 |
---|---|---|---|
インスタンス名 | vm-${SUFFIX} | ||
VPC | --network |
vpc-${SUFFIX} | |
サブネット | --subnet |
subnet-${SUFFIX} | |
OS イメージ | --image-family --image-project |
debian-12 debian-cloud |
以降の手順はここで指定した OS を前提とする点に注意 |
マシンタイプ | --machine-type |
e2-medium | 2 vCPU、メモリ4GB 必要に応じて変更可(参考) |
ディスクサイズ | --boot-disk-size | 20GB | Minikube のリソース要件に準拠 |
ネットワークタグ | --tags |
ssh | 後で作成するファイアウォールルールをインスタンスに紐付ける際に使用 |
# Compute Engine インスタンスを作成する $ gcloud compute instances create vm-${SUFFIX} \ --network=vpc-${SUFFIX} \ --subnet=subnet-${SUFFIX} \ --zone=${REGION}-a \ --image-family=debian-12 \ --image-project=debian-cloud \ --machine-type=e2-medium \ --boot-disk-size=20GB \ --tags=ssh \ --project=${PROJECT}
ファイアウォールルールの設定
作成したインスタンスに SSH でアクセスできるように、VPC に内向きのファイアウォールルールを作成します。--target-tags
フラグでインスタンスに設定したものと同じタグを指定することで、このルールをインスタンスに紐付けることができます。
なお、当記事では便宜上 --source-ranges
フラグ、つまりアクセス元の IP アドレス範囲を 0.0.0.0/0(任意の IP アドレス)に設定していますが、セキュリティを考慮して自身の PC の IP アドレス等を設定することもできます。
# SSH を許可するファイアウォールルールを作成する $ gcloud compute firewall-rules create vpc-${SUFFIX}-allow-ssh \ --direction=INGRESS \ --source-ranges=0.0.0.0/0 \ --allow=tcp:22 \ --target-tags=ssh \ --network=vpc-${SUFFIX} \ --project=${PROJECT}
インスタンスに SSH 接続
コンソールからインスタンスに接続(GUI の場合)
Minikube をインストールするため、作成したインスタンスに SSH 接続します。
Google Cloud コンソールからインスタンスに SSH 接続する場合、インスタンス一覧画面で「SSH」を選択します。
gcloud コマンドで SSH 接続(CLI の場合)
gcloud では、以下のコマンドを使用してインスタンスに SSH 接続できます。
# インスタンスに SSH 接続する $ gcloud compute ssh vm-${SUFFIX} \ --zone=${REGION}-a \ --project=${PROJECT}
Docker のインストール
Minikube の driver について
Minikube では動作環境(driver)として Docker や VirtualBox など、いくつかの選択肢が提供されています。
- 参考 : Drivers
当記事では推奨 driver の1つである Docker を使用して構築を進めていきます。
以下の Docker 公式ドキュメントの手順に沿って、Docker をインストールしていきます。
パッケージリストの更新
以降の手順については、SSH 接続した Compute Engine VM 上でコマンドを実行してください。
まずは、APT のパッケージを最新化しておきます。
# パッケージリストを最新の状態にする $ sudo apt update # パッケージの最新化(時間がかかる可能性あり) $ sudo apt upgrade -y
インストール
APT リポジトリのセットアップ
まず、Docker パッケージの検証に必要な GPG Key を用意します。
# Docker のダウンロードに必要なパッケージをインストールする $ sudo apt install ca-certificates curl # keyrings ディレクトリのパーミッションを設定する $ sudo install -m 0755 -d /etc/apt/keyrings # Docker 公式の GPG Key をダウンロードして keyrings ディレクトリに格納する $ sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc # GPG Key のパーミッションを変更する $ sudo chmod a+r /etc/apt/keyrings/docker.asc
apt コマンドのパッケージ取得元のリポジトリとして Docker 関連のリポジトリを追加します。
# Docker のリポジトリを追加する $ echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \ $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
Docker のインストール
Docker の実行に必要なパッケージをインストールします。
# パッケージリストを更新する $ sudo apt update # Docker の実行に必要なパッケージをインストールする $ sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Docker の動作確認
Docker で適当なコンテナを実行してみます。ここでは Docker 公式コンテナイメージの hello-world を使用します。
# hello-world コンテナの起動 $ sudo docker run --name hello hello-world -------------------- 出力例 -------------------- Unable to find image 'hello-world:latest' locally latest: Pulling from library/hello-world c1ec31eb5944: Pull complete Digest: sha256:d211f485f2dd1dee407a80973c8f129f00d54604d2c90732e8e320e5038a0348 Status: Downloaded newer image for hello-world:latest Hello from Docker! This message shows that your installation appears to be working correctly. To generate this message, Docker took the following steps: 1. The Docker client contacted the Docker daemon. 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. (amd64) 3. The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading. 4. The Docker daemon streamed that output to the Docker client, which sent it to your terminal. To try something more ambitious, you can run an Ubuntu container with: $ docker run -it ubuntu bash Share images, automate workflows, and more with a free Docker ID: https://hub.docker.com/ For more examples and ideas, visit: https://docs.docker.com/get-started/
クリーンアップ
動作確認用の hello-world コンテナと、そのコンテナイメージを削除していきます。
hello-world コンテナは停止した状態で残っています。
# コンテナ一覧を確認する $ sudo docker container ls -a -------------------- 出力例 -------------------- CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 0f6492b1ab35 hello-world "/hello" 48 seconds ago Exited (0) 47 seconds ago hello
また、コンテナ実行に使用されたコンテナイメージもローカルにダウンロードされているため、これを削除していきます。
# コンテナイメージの一覧を確認する $ sudo docker image ls -------------------- 出力例 -------------------- REPOSITORY TAG IMAGE ID CREATED SIZE hello-world latest d2c94e258dcb 18 months ago 13.3kB
以下のコマンドで、停止したコンテナとコンテナイメージを削除します。
# コンテナを削除する $ sudo docker container rm hello # hello-world コンテナイメージを削除する $ sudo docker image rm hello-world:latest
Minikube のインストール
APT リポジトリのセットアップ
まず、Kubernetes のリポジトリを APT のパッケージ取得元として登録します。
# Kubernetes のリポジトリを登録 $ echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.28/deb/ /" | sudo tee /etc/apt/sources.list.d/kubernetes.list
パッケージの検証に使用する GPG Key をダウンロードします。
# GPG Key のダウンロード curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.28/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
改めてパッケージリストを更新します。
# パッケージリストを更新する
$ sudo apt update
インストール
Minikube のパッケージをダウンロードし、dpkg
コマンドでインストールを実行します。
# Minikube のパッケージをダウンロードする $ curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube_latest_amd64.deb # Minikube をインストールする $ sudo dpkg -i minikube_latest_amd64.deb -------------------- 出力例 -------------------- Selecting previously unselected package minikube. (Reading database ... 73229 files and directories currently installed.) Preparing to unpack minikube_latest_amd64.deb ... Unpacking minikube (1.34.0-0) ... Setting up minikube (1.34.0-0) ...
Minikube の実行
Minikube 実行ユーザーを docker グループに追加
Minikube を実行するユーザーを docker グループに所属させます。
この手順をスキップすると、Minikube 実行時に以下のような権限エラーが発生してしまいます。
$ minikube start --driver=docker 😄 minikube v1.34.0 on Debian 12.7 (amd64) ✨ Using the docker driver based on user configuration 💣 Exiting due to PROVIDER_DOCKER_NEWGRP: "docker version --format <no value>-<no value>:<no value>" exit status 1: permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.47/version": dial unix /var/run/docker.sock: connect: permission denied 💡 Suggestion: Add your user to the 'docker' group: 'sudo usermod -aG docker $USER && newgrp docker' 📘 Documentation: https://docs.docker.com/engine/install/linux-postinstall/
Suggestion:
の項目に記載されているコマンドを実行し、現在仮想マシンのログインに使用しているユーザーを docker グループに追加します。
# 現在のユーザーを docker グループに追加する $ sudo usermod -aG docker $USER && newgrp docker
Minikube の実行
minikube start
コマンドで Minikube を実行します。--driver
フラグで Docker をドライバとして設定しています。
$ minikube start --driver=docker -------------------- 出力例 -------------------- 😄 minikube v1.34.0 on Debian 12.8 (amd64) ✨ Using the docker driver based on user configuration 📌 Using Docker driver with root privileges 👍 Starting "minikube" primary control-plane node in "minikube" cluster 🚜 Pulling base image v0.0.45 ... 💾 Downloading Kubernetes v1.31.0 preload ... > preloaded-images-k8s-v18-v1...: 326.69 MiB / 326.69 MiB 100.00% 37.80 M > gcr.io/k8s-minikube/kicbase...: 487.90 MiB / 487.90 MiB 100.00% 46.45 M 🔥 Creating docker container (CPUs=2, Memory=2200MB) ... 🐳 Preparing Kubernetes v1.31.0 on Docker 27.2.0 ... ▪ Generating certificates and keys ... ▪ Booting up control plane ... ▪ Configuring RBAC rules ... 🔗 Configuring bridge CNI (Container Networking Interface) ... 🔎 Verifying Kubernetes components... ▪ Using image gcr.io/k8s-minikube/storage-provisioner:v5 🌟 Enabled addons: storage-provisioner, default-storageclass 💡 kubectl not found. If you need it, try: 'minikube kubectl -- get pods -A' 🏄 Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default
Minikube の状態は minikube status
コマンドで確認できます。
# Minikube の状態を確認する $ minikube status -------------------- 出力例 -------------------- minikube type: Control Plane host: Running kubelet: Running apiserver: Running kubeconfig: Configured
一般に Kubernetes の管理操作には kubectl
コマンドを使用しますが、Minikube では minikube kubectl
を使用します。
# Minikube のノードを確認する $ minikube kubectl -- get nodes -------------------- 出力例 -------------------- NAME STATUS ROLES AGE VERSION minikube Ready control-plane 11m v1.31.0
毎回 minikube の部分からコマンドを入力するのは手間なので、エイリアスを設定して kubectl だけでコマンドを実行できるようにします。エイリアスは .bashrc
ファイルに設定しておきます。
# エイリアスを設定する(.bashrc に追記) $ echo "alias kubectl='minikube kubectl --'" >> .bashrc # .bashrc の追記内容を反映する $ source .bashrc # エイリアスで実行できることを確認する $ kubectl get nodes -------------------- 出力例 -------------------- NAME STATUS ROLES AGE VERSION minikube Ready control-plane 13m v1.31.0
Pod の作成
Minikube のクラスタを実行できたので、Kubernetes で管理できる最小単位のコンピューティング リソースである Pod を作成してみます。
vim 等のエディタを使用して、sample-pod.yaml
として以下のマニフェストファイルを作成します。この Pod は、Web サーバである nginx のコンテナを実行します。
# sample-pod.yaml apiVersion: v1 kind: Pod metadata: name: nginx labels: app: sample spec: containers: - name: nginx image: nginx:1.27 ports: - containerPort: 80
kubectl apply
コマンドでマニフェストファイルをクラスタに適用します。これにより、YAML ファイルに記載した設定内容の Pod が Minikube クラスタ上で実行されます。
# マニフェストファイルをクラスタに適用して Pod を作成する $ kubectl apply -f sample-pod.yaml
kubectl get pods
で Pod の一覧を取得します。先程マニフェストファイルを適用した Pod が実行されています。
# Pod の一覧を取得する $ kubectl get pods -------------------- 出力例 -------------------- NAME READY STATUS RESTARTS AGE nginx 1/1 Running 0 2m15s
Pod の公開
Service リソースとして NodePort を作成して、先程作成した Pod の nginx コンテナに Minikube クラスタの外部から接続できるようにします。
Pod 同様、Service もマニフェストファイルから作成できますが、ここでは簡易的に kubectl expose
コマンドで作成します。
# NodePort を作成して Pod を公開する $ kubectl expose pod/nginx --type=NodePort --port=80
kubectl get services
コマンドで Service リソースの一覧を確認します。NodePort タイプの Service が作成されています(2行目)。
# Service の一覧を取得する $ kubectl get services -------------------- 出力例 -------------------- NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 49m nginx NodePort 10.110.131.236 <none> 80:30134/TCP 116s
minikube service nginx --url
で NodePort にアクセスするための URL を取得できるため、この URL にアクセスしてみます。ここまで手順通りにリソースを作成していれば、Pod 内の nginx コンテナからレスポンスが返ってきます。
$ curl $(minikube service nginx --url) -------------------- 出力例 -------------------- <!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>
クリーンアップ
動作確認用に作成した各リソースを削除します。
Service リソースを kubectl delete
コマンドで削除します。
# Service を削除する
$ kubectl delete services nginx
Pod はマニフェストファイルから作成したので、kubectl delete
コマンドで -f
フラグを使用し、リソース作成時に使用したマニフェストファイルを指定します。
# Pod を削除する $ kubectl delete -f sample-pod.yaml
バックアップの取得
Minikube を構築したインスタンスのバックアップを取得しておくと、学習中に環境を壊してしまった場合などに容易に復元することができます。
以下の記事で Compute Engine のマシンイメージの取得方法、およびマシンイメージからのインスタンスの復元方法を解説しているので、こちらの手順を参考にバックアップを取得しておくとよいでしょう。
佐々木 駿太 (記事一覧)
G-gen最北端、北海道在住のクラウドソリューション部エンジニア
2022年6月にG-genにジョイン。Google Cloud Partner Top Engineer 2025 Fellowに選出。好きなGoogle CloudプロダクトはCloud Run。
趣味はコーヒー、小説(SF、ミステリ)、カラオケなど。
Follow @sasashun0805