🦁

KindによるKubernetesクラスタ構築(MacOS)

2024/12/01に公開

こんにちは、Zoeyです!初めて書いたブログで、ぜひコメントとアドバイスいただければと思います!
この度は自宅でもKubernetesの各機能を試していける環境が欲しいため、自分のMacでkubernetesイメージでマルチノードクラスタ構築をしてみました。そして本記事ではMacOS M1環境で、Kindを使ってKubernetesクラスタ構築する際の流れを記録します。ご参考になれば幸いです!

必要ツールのインストール

kindをインストールする

kindの公式ドキュメントではバイナリリリース、ソースリリースとパッケージが提供されていて、適切な方法でインストールできます。

自分は下記コマンドでバイナリをインストールしています。インストール時にはバージョンを修正して使った方がいいと思います。「kind version」で結果が返してきた場合はインストール成功になります。

$ [ $(uname -m) = arm64 ] && curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.25.0/kind-darwin-arm64
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    98  100    98    0     0    133      0 --:--:-- --:--:-- --:--:--   133
  0     0    0     0    0     0      0      0 --:--:--  0:00:01 --:--:--     0
100 9470k  100 9470k    0     0  1506k      0  0:00:06  0:00:06 --:--:-- 1946k

% chmod +x ./kind

% sudo mv kind /usr/local/bin/kind

% kind version
kind v0.25.0 go1.22.9 darwin/arm64

Dockerをインストールする

KindはDockerコンテナをノードとして使用し、Kubernetesクラスタを実行するツールであるため、Dockerのインストールも必要になります。

Dockerインストールする際に、Linux環境だとDocker Engine(Docker CE)も使えますが、MacOSとWindowsの場合はDocker Desktopを使います。

Dockerの公式ドキュメントからインストールの前提条件手順を確認できます。

上記リンクにアクセスして、パッケージをダウンロードします。ダウンロードできましたらダブルクリックして、指示に従って操作するとインストールできます。「docker run hello-world」で結果が返してきた場合はインストール成功になります。

% docker run hello-world     
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
478afc919002: Pull complete 
Digest: sha256:305243c734571da2d100c8c8b3c3167a098cab6049c9a5b066b6021a60fcb966
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.
    (arm64v8)
 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/

Pullしたイメージ、またこの後ビルドしたクラスタ内にあるDockerコンテナとして動いているノードの情報もDocker Desktopから確認できます。

kubectlをインストールする

Kubernetesのクラスタが構築し終わると、kubectlというクラスタを制御するコマンドが必要になりますので、kubectlもインストールする必要があります。

インストール手順はkubernetesの公式ドキュメントから参照できます。「kubectl version --client」で結果が返してきた場合はインストール成功になります。

% curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/darwin/arm64/kubectl"

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   138  100   138    0     0    347      0 --:--:-- --:--:-- --:--:--   351
100 53.9M  100 53.9M    0     0  3840k      0  0:00:14  0:00:14 --:--:-- 3943k

% chmod +x ./kubectl

% sudo mv ./kubectl /usr/local/bin/kubectl

% sudo chown root: /usr/local/bin/kubectl

% kubectl version --client
Client Version: v1.31.3
Kustomize Version: v5.4.2

(必要に応じて)Golangをインストールする

この後はKubernetesのイメージをビルドしていきたいので、前準備としてGolangのインストールが必要になります。同じくGolangの公式ドキュメントにアクセスして、自分が使っているOSを選んたら、インストール方法を確認できます。

MacOSの場合は「Download」をクリックして、パッケージをダウンロードします。ダウンロードできましたらダブルクリックして、指示に従って操作します。その後は下記作業フォルダの作成とパスの設定も必要になります。

#作業フォルダを作成する
% mkdir -p go/pkg
% mkdir -p go/src/k8s.io

# パッケージは`/usr/local/go/bin`内にインストールされるので、コマンドが使えるためにPATHに設定する
% export PATH=${PATH}:/usr/local/go/bin
% echo $PATH
・・・:/usr/local/go/bin:・・・

# よく使うフォルダを設定(ここの${HOME}は自分の作業フォルダに引き換えできる)
% export GOPATH=${HOME}/go
% export GOPATH_K8S=${HOME}/go/src/k8s.io/kubernetes
% go env GOPATH
<workdir-path>/go                                 

「go version」で結果が返してきた場合はインストール成功になります。

% go version
go version go1.23.3 darwin/arm64

クラスタの作成

クラスタ作成時にはkind create clusterを使います。必要に応じてはオプションを指定して作成することも可能で、詳細はkindの公式ドキュメントから参照できます。

クラスタにこだわりがない場合

なんの設定もせずにkind create clusterを使うと、デフォルトではkindest/nodeイメージでkindというシングルノードのクラスタが作成されます。

# クラスタを作成する
% kind create cluster
Creating cluster "kind" ...
 ✓ Ensuring node image (kindest/node:v1.31.2) 🖼 
 ✓ 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

Thanks for using kind! 😊

# kindというクラスタが新たに作成されている
% kind get clusters
kind

# kindクラスタにはkind-control-planeというノードが一つ存在している
% kubectl get node  
NAME                 STATUS   ROLES           AGE    VERSION
kind-control-plane   Ready    control-plane   4m8s   v1.31.2

# ノードはDockerコンテナという形で提供されている
% docker ps
CONTAINER ID   IMAGE                  COMMAND                  CREATED         STATUS         PORTS                       NAMES
a7ef9bbb9591   kindest/node:v1.31.2   "/usr/local/bin/entr…"   4 minutes ago   Up 4 minutes   127.0.0.1:52429->6443/tcp   kind-control-plane

具体的にオプションにどんなものがあるか、どう使うかはkind create cluster --helpで確認できます。

% kind create cluster --help
Creates a local Kubernetes cluster using Docker container 'nodes'

Usage:
  kind create cluster [flags]

Flags:
      --config string       path to a kind config file
  -h, --help                help for cluster
      --image string        node docker image to use for booting the cluster
      --kubeconfig string   sets kubeconfig path instead of $KUBECONFIG or $HOME/.kube/config
  -n, --name string         cluster name, overrides KIND_CLUSTER_NAME, config (default kind)
      --retain              retain nodes for debugging when cluster creation fails
      --wait duration       wait for control plane node to be ready (default 0s)

Global Flags:
      --loglevel string   DEPRECATED: see -v instead
  -q, --quiet             silence all stderr output
  -v, --verbosity int32   info log verbosity, higher value produces more output

自分でカスタマイズしたい場合

今回はcontroller-plane一つ、workerノード三つで、名前はkind-test-kubernetesで、kubernetesイメージを使ったマルチノードクラスタが欲しいため、--name--config--imageオプションを使っていきます。

今回はkubernetesイメージを使うため、kubernetesのイメージをまずビルドします。(kubernetesだけでなく、他のプロジェクトイメージも同じ方法で作れます。)

# KubernetesソースコードをForkして、ローカルにCloneする
% cd go/src/k8s.io
% git clone https://github.com/<github-username>/kubernetes          
Cloning into 'kubernetes'...
remote: Enumerating objects: 1454831, done.
remote: Counting objects: 100% (25/25), done.
remote: Compressing objects: 100% (20/20), done.
Receiving objects: 100% (1454831/1454831), 1004.46 MiB | 2.13 MiB/s, done.
remote: Total 1454831 (delta 9), reused 14 (delta 5), pack-reused 1454806 (from 1)
Resolving deltas: 100% (1064687/1064687), done.
Updating files: 100% (26242/26242), done.
% cd ${GOPATH_K8S} 
% git remote add upstream https://github.com/kubernetes/kubernetes
% git remote set-url --push upstream no_push
% git remote -v
origin  https://github.com/<github-username>/kubernetes (fetch)
origin  https://github.com/<github-username>/kubernetes (push)
upstream        https://github.com/kubernetes/kubernetes (fetch)
upstream        no_push (push)
% git fetch upstream
% git tag --list

# kindコマンドでkubernetesイメージをビルドする
% kind build node-image ~/Documents/programming/go/src/k8s.io/kubernetes --image kind-image:kubernetestest
Detected build type: "source"
Building using source: "/Users/ziyixie/Documents/programming/go/src/k8s.io/kubernetes"
Starting to build Kubernetes
+++ [1201 14:53:39] Verifying Prerequisites....
+++ [1201 14:53:40] Using docker on macOS
+++ [1201 14:53:40] Building Docker image kube-build:build-ed342eb186-5-v1.32.0-go1.23.3-bullseye.0
+++ [1201 14:55:16] Creating data container kube-build-data-ed342eb186-5-v1.32.0-go1.23.3-bullseye.0
+++ [1201 14:55:16] Syncing sources to container
+++ [1201 14:55:34] Running build command...
+++ [1201 14:55:40] Building go targets for linux/arm64
    k8s.io/kubernetes/cmd/kube-apiserver (static)
    k8s.io/kubernetes/cmd/kube-controller-manager (static)
    k8s.io/kubernetes/cmd/kube-proxy (static)
    k8s.io/kubernetes/cmd/kube-scheduler (static)
    k8s.io/kubernetes/cmd/kubeadm (static)
    k8s.io/kubernetes/cmd/kubectl (static)
    k8s.io/kubernetes/cmd/kubelet (non-static)
+++ [1201 14:58:30] Syncing out of container
+++ [1201 14:58:33] Building images: linux-arm64
+++ [1201 14:58:34] Starting docker build for image: kube-apiserver-arm64
+++ [1201 14:58:34] Starting docker build for image: kube-controller-manager-arm64
+++ [1201 14:58:34] Starting docker build for image: kube-scheduler-arm64
+++ [1201 14:58:34] Starting docker build for image: kube-proxy-arm64
+++ [1201 14:58:34] Starting docker build for image: kubectl-arm64
+++ [1201 14:58:41] Deleting docker image registry.k8s.io/kubectl-arm64:v1.33.0-alpha.0.7_810e9e212ec537
+++ [1201 14:58:41] Deleting docker image registry.k8s.io/kube-scheduler-arm64:v1.33.0-alpha.0.7_810e9e212ec537
+++ [1201 14:58:41] Deleting docker image registry.k8s.io/kube-controller-manager-arm64:v1.33.0-alpha.0.7_810e9e212ec537
+++ [1201 14:58:44] Deleting docker image registry.k8s.io/kube-proxy-arm64:v1.33.0-alpha.0.7_810e9e212ec537
+++ [1201 14:58:49] Deleting docker image registry.k8s.io/kube-apiserver-arm64:v1.33.0-alpha.0.7_810e9e212ec537
+++ [1201 14:58:49] Docker builds done
Finished building Kubernetes
Building node image ...
Building in container: kind-build-1733032750-1630903107
Image "kind-image:kubernetestest" build completed.

ビルド時には下記エラーが起こり、下記コマンドによって解決しています。

% kind build node-image ~/Documents/programming/go/src/k8s.io/kubernetes --image kind-image:kubernetestest
Detected build type: "source"
Building using source: "/Users/ziyixie/Documents/programming/go/src/k8s.io/kubernetes"
Starting to build Kubernetes
+++ [1201 14:52:20] Verifying Prerequisites....
  !!! Cannot find GNU tar. Build on Linux or install GNU tar
      on Mac OS X (brew install gnu-tar).
make: *** [quick-release-images] Error 1
Failed to build Kubernetes: failed to build images: command "make quick-release-images 'KUBE_EXTRA_WHAT=cmd/kubeadm cmd/kubectl cmd/kubelet' KUBE_VERBOSE=0 KUBE_BUILD_HYPERKUBE=n KUBE_BUILD_CONFORMANCE=n KUBE_BUILD_PLATFORMS=linux/arm64" failed with error: exit status 2
ERROR: error building node image: failed to build kubernetes: failed to build images: command "make quick-release-images 'KUBE_EXTRA_WHAT=cmd/kubeadm cmd/kubectl cmd/kubelet' KUBE_VERBOSE=0 KUBE_BUILD_HYPERKUBE=n KUBE_BUILD_CONFORMANCE=n KUBE_BUILD_PLATFORMS=linux/arm64" failed with error: exit status 2
Command Output: +++ [1201 14:52:20] Verifying Prerequisites....
  !!! Cannot find GNU tar. Build on Linux or install GNU tar
      on Mac OS X (brew install gnu-tar).
make: *** [quick-release-images] Error 1

% brew install bash
% kind build node-image ~/Documents/programming/go/src/k8s.io/kubernetes --image kind-image:kubernetestest 
Detected build type: "source"
Building using source: "/Users/ziyixie/Documents/programming/go/src/k8s.io/kubernetes"
Starting to build Kubernetes
ERROR: This script requires a minimum bash version of 4.2, but got version of 3.2
On macOS with homebrew 'brew install bash' is sufficient.
make: *** [quick-release-images] Error 1
Failed to build Kubernetes: failed to build images: command "make quick-release-images 'KUBE_EXTRA_WHAT=cmd/kubeadm cmd/kubectl cmd/kubelet' KUBE_VERBOSE=0 KUBE_BUILD_HYPERKUBE=n KUBE_BUILD_CONFORMANCE=n KUBE_BUILD_PLATFORMS=linux/arm64" failed with error: exit status 2
ERROR: error building node image: failed to build kubernetes: failed to build images: command "make quick-release-images 'KUBE_EXTRA_WHAT=cmd/kubeadm cmd/kubectl cmd/kubelet' KUBE_VERBOSE=0 KUBE_BUILD_HYPERKUBE=n KUBE_BUILD_CONFORMANCE=n KUBE_BUILD_PLATFORMS=linux/arm64" failed with error: exit status 2
Command Output: ERROR: This script requires a minimum bash version of 4.2, but got version of 3.2
On macOS with homebrew 'brew install bash' is sufficient.
make: *** [quick-release-images] Error 1

% brew install gnu-tar
% export PATH="/usr/local/opt/gnu-tar/libexec/gnubin:$PATH"
% tar --version
bsdtar 3.5.1 - libarchive 3.5.1 zlib/1.2.11 liblzma/5.0.5 bz2lib/1.0.8

configアフィルの書き方はkindの公式ドキュメントから参照できます。イメージやFeature Gateなどについていろいろと設定できます。今回は下記configファイルを使います。

kubernetes-cluster.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: kubernetes-test-cluster
nodes:
- role: control-plane
- role: worker
- role: worker
- role: worker

ここでいよいよクラスタ作成に入る条件が揃ったので、下記コマンドでクラスタを作成します。

% kind create cluster --name kind-kubernetes-test --image kind-image:kubernetestest --config kubernetes-cluster.yaml
Creating cluster "kind-kubernetes-test" ...
 ✓ Ensuring node image (kind-image:kubernetestest) 🖼
 ✓ Preparing nodes 📦 📦 📦 📦  
 ✓ Writing configuration 📜 
 ✓ Starting control-plane 🕹️ 
 ✓ Installing CNI 🔌 
 ✓ Installing StorageClass 💾 
 ✓ Joining worker nodes 🚜 
Set kubectl context to "kind-kind-kubernetes-test"
You can now use your cluster with:

kubectl cluster-info --context kind-kind-kubernetes-test

Not sure what to do next? 😅  Check out https://kind.sigs.k8s.io/docs/user/quick-start/

# kind-kubernetes-testというクラスタが新たに作成されている
% kind get clusters
kind
kind-kubernetes-test

# kind-kubernetes-testクラスタにはノード計四つ存在している
 % kubectl get node
NAME                                 STATUS   ROLES           AGE   VERSION
kind-kubernetes-test-control-plane   Ready    control-plane   41s   v1.33.0-alpha.0.7+810e9e212ec537
kind-kubernetes-test-worker          Ready    <none>          31s   v1.33.0-alpha.0.7+810e9e212ec537
kind-kubernetes-test-worker2         Ready    <none>          31s   v1.33.0-alpha.0.7+810e9e212ec537
kind-kubernetes-test-worker3         Ready    <none>          31s   v1.33.0-alpha.0.7+810e9e212ec537

# kindクラスタ内のノード一つと、新たに作成したkind-kubernetes-testクラスタ内のノード四つのコンテナが動いていることが確認できる
% docker ps
CONTAINER ID   IMAGE                       COMMAND                  CREATED              STATUS          PORTS                       NAMES
4e95c1601a7e   kind-image:kubernetestest   "/usr/local/bin/entr…"   About a minute ago   Up 56 seconds   127.0.0.1:55830->6443/tcp   kind-kubernetes-test-control-plane
5cba9419ccf4   kind-image:kubernetestest   "/usr/local/bin/entr…"   About a minute ago   Up 56 seconds                               kind-kubernetes-test-worker
e03697bb3896   kind-image:kubernetestest   "/usr/local/bin/entr…"   About a minute ago   Up 56 seconds                               kind-kubernetes-test-worker3
9943f8a1c902   kind-image:kubernetestest   "/usr/local/bin/entr…"   About a minute ago   Up 56 seconds                               kind-kubernetes-test-worker2
9ded63812f08   kindest/node:v1.31.2        "/usr/local/bin/entr…"   5 hours ago          Up 5 hours      127.0.0.1:52599->6443/tcp   kind-control-plane

今環境内には二つクラスタ存在していますが、今はどのクラスタを操作しているかというと、下記二つのコマンドで確認できます。

% kubectl config get-contexts
CURRENT   NAME                        CLUSTER                     AUTHINFO                    NAMESPACE
          kind-kind                   kind-kind                   kind-kind                   
*         kind-kind-kubernetes-test   kind-kind-kubernetes-test   kind-kind-kubernetes-test

% kubectl config current-context                      
kind-kind-kubernetes-test

そして今はkind-kind-kubernetes-testクラスタではなく、kind-kindクラスタ使いたい場合は、下記コマンドで、クラスタの指定ができます。

% kubectl config use-context kind-kind
Switched to context "kind-kind".
% kubectl config current-context
kind-kind

これでkindを使って、Kubernetesクラスタを自分のMacOSで構築できています!またクラスタでたくさん試していきたいと思いますので、またよろしくお願いします〜

Discussion