Kubernetesローカル開発環境を作る - minikubeのインストールと使用

ローカル開発環境を作り、アプリケーションを動かす

今回はWebアプリケーションのコンテナをローカルKubernetesに立てることを目標にする。

参考までに、ここではmacOSを中心にインストールを進めた。環境が違えば方法も異なる可能性があるので参考にしてほしい。

Minikubeのインストールと使用

今回はMinikubeという、ローカル環境でKubernetesを簡単に実行できるツールを使用する。このツールを使うと単一ノードのKubernetesクラスタを作成できる。
Minikubeの使い方は公式ドキュメントを参考にするとよい。

インストール前の事前準備

Dockerインストール

minikubeのインストール前に、Dockerを必ずインストールして使用することをおすすめする。

kubectlインストール

kubectlはKubernetesのClusterと通信し、さまざまなObjectの状態確認やCRUD操作などに使用されるCLIツールである。
minikubeをインストールし、Kubernetes Clusterとの作業を行うために必要である。

ここではmacOSでHomebrewを使用してインストールする。

brew install kubectl

他のシステムでは公式ドキュメントを参考に進める。

MinikubeをmacOSにインストール

ここではHomebrewを使用してインストールを進める。

brew install minikube

実行するとHomebrewがminikubeと関連ファイルをインストールし、zsh completionsも設定される。

Minikubeを使用する

Minikube cluster開始

インストールが成功したか、次のKubernetesクラスタを開始するコマンドで確認できる。

次のようにKubernetesバージョンを指定して起動する方法がある。

minikube start --kubernetes-version [起動するバージョン]

次のように指定しなければ、新しいバージョンが起動される。

minikube start

起動時にはベースイメージをダウンロードし、Dockerコンテナを作成し、証明書とキーを生成してコントロールプレーンを起動する。環境によってはswap、Dockerバージョン、kubeletサービスなどに関する警告が表示される場合がある。

Minikube cluster開始後の確認

minikubeはDocker imageをダウンロードして実行し、Kubernetes Clusterを作成し、kubectlとの接続のために~/.kube/configファイル設定まで完了してくれる。 1つずつ見てみよう。

minikube起動時にdownloadされるDocker imageは次のように確認できる。

% docker images
REPOSITORY                    TAG       IMAGE ID       CREATED        SIZE
gcr.io/k8s-minikube/kicbase   v0.0.33   f7ba2bce4549   5 weeks ago    1.06GB

ダウンロードしたDocker imageでminikube containerを実行し、Kubernetes clusterが作成されたことを確認できる。

% docker ps
CONTAINER ID   IMAGE                                 COMMAND                  CREATED             STATUS             PORTS                                                                                                                        NAMES
d9391f64eba5   gcr.io/k8s-minikube/kicbase:v0.0.33   "/usr/local/bin/entr..."   About an hour ago   Up About an hour   0.0.0.0:49463->22/tcp, 0.0.0.0:49464->2376/tcp, 0.0.0.0:49466->5000/tcp, 0.0.0.0:49467->8443/tcp, 0.0.0.0:49465->32443/tcp   minikube

Kubernetes Clusterとkubectlの接続情報を含むconfigファイルが作成されている。

% cat ~/.kube/config
apiVersion: v1
clusters:
- cluster:
    certificate-authority: /Users/user/.minikube/ca.crt
    server: https://127.0.0.1:50472
  name: minikube
contexts:
- context:
    cluster: minikube
    user: minikube
  name: minikube
current-context: minikube
kind: Config
preferences: {}
users:
- name: minikube
  user:
    client-certificate: /Users/user/.minikube/profiles/minikube/client.crt
    client-key: /Users/user/.minikube/profiles/minikube/client.key

Minikube cluster状態確認

クラスタの状態を確認するコマンドは次のとおりである。

minikube status
% minikube status
minikube
type: Control Plane
host: Running
kubelet: Stopped
apiserver: Stopped
kubeconfig: Configured

Minikube cluster一時停止/再稼働

Kubernetes clusterを一時停止するコマンドは次のとおりである。

minikube pause

一時停止後は、kubectlを通じたClusterへのアクセスや追加コマンドがtimeoutになり、使用できない。
ただし、既にデプロイ済みのapplicationには影響しないため、動作し続ける。

一時停止状態から再びClusterを再稼働したい場合は、次のコマンドを使用する。

minikube unpause

Minikube cluster終了

minikube stop
% minikube stop
✋  Stopping node "minikube"  ...
🛑  Powering off "minikube" via SSH ...
🛑  1 node stopped.

Minikube cluster削除

minikube delete

すべての内容を削除する初期化コマンドは次のとおりである。

% minikube delete --all
🔥  docker 의 "minikube" 를 삭제하는 중 ...
🔥  /Users/user/.minikube/machines/minikube 제거 중 ...
💀  "minikube" 클러스터 관련 정보가 모두 삭제되었습니다
🔥  모든 프로필이 성공적으로 삭제되었습니다

KubernetesでWebサーバーを設定して起動する

minikubeをインストールしたので、Kubernetes環境を作り、コンテナを実行してみよう。

Webサーバーには、Minikubeに適した簡単な応答だけを返すecho-serverを使用する。

minikubeクラスタ作成

minikubeを起動してクラスタを作成する。既に起動している場合は再起動しなくてもよい。

minikube start

このときDockerコンテナの起動状態を確認する。

% docker ps
CONTAINER ID   IMAGE                                 COMMAND                  CREATED              STATUS              PORTS                                                                                                                        NAMES
39b6898f6256   gcr.io/k8s-minikube/kicbase:v0.0.33   "/usr/local/bin/entr..."   About a minute ago   Up About a minute   0.0.0.0:51435->22/tcp, 0.0.0.0:51436->2376/tcp, 0.0.0.0:51438->5000/tcp, 0.0.0.0:51439->8443/tcp, 0.0.0.0:51437->32443/tcp   minikube

minikubeのコンテナが動作していることを確認できる。

kubectlを使用してDeploymentを作成

次にkubectlでKubernetes Deploymentを作成する。このKubernetes Deploymentオブジェクトを作成することで、アプリケーションを実行できるようになる。これはYAMLファイルで作成できる。これ自体はサービスというより、Podを作るためのDeploymentアプリである。

% kubectl create deployment hello-minikube --image=k8s.gcr.io/echoserver:1.10
deployment.apps/hello-minikube created

もしM1 MacBookなら、echoserver:1.10ではなくechoserver-arm:1.8を使用する必要がある。

kubectl create deploy hello-minikube --image=k8s.gcr.io/echoserver-arm:1.8

作成されたhello-minikube Deploymentを使用し、サービスとして公開する。ここが実際のアプリとほぼ同等のものと思われる。

% kubectl expose deployment hello-minikube --type=NodePort --port=8080
service/hello-minikube exposed

Podにデプロイされたコンテナ確認

この時点でDockerコンテナの動作状態を確認してみる。

% docker ps
CONTAINER ID   IMAGE                                 COMMAND                  CREATED         STATUS         PORTS                                                                                                                        NAMES
24733d0fd443   gcr.io/k8s-minikube/kicbase:v0.0.33   "/usr/local/bin/entr..."   5 minutes ago   Up 5 minutes   0.0.0.0:54248->22/tcp, 0.0.0.0:54249->2376/tcp, 0.0.0.0:54251->5000/tcp, 0.0.0.0:54247->8443/tcp, 0.0.0.0:54250->32443/tcp   minikube

明らかにhello-minikubeというコンテナは別に動いておらず、minikubeのコンテナ上で動作しているようである。おそらくこのminikubeコンテナ自体にKubernetesの単一ノードとPod、Deploymentが作られたのだと思われる。

ではPodが作成されたか確認する。

% kubectl get pod
NAME                              READY   STATUS    RESTARTS   AGE
hello-minikube-5d44b6b577-l99jz   1/1     Running   0          4m59s

STATUSがRunningになっており、起動していることを確認できる。また1/1からPod数は1つであることも分かる。

サービス動作確認

サービスURLは次のコマンドで確認できる。

% minikube service hello-minikube --url
http://127.0.0.1:54612

ブラウザで確認すると、アプリケーションが実行中であることを確認できる。

echoserver

削除

次は削除手順である。

サービス削除は次のコマンドで行う。

% kubectl delete services hello-minikube
service "hello-minikube" deleted

hello-minikube Deployment削除は次のコマンドで行う。

% kubectl delete deployment hello-minikube
deployment.apps "hello-minikube" deleted

付録: コンテナの中を覗いてみる

公式ドキュメントにあったローカル開発環境を作るチュートリアルはこの程度で終わりだが、コンテナの中を覗いてみる。

次のコマンドでminikubeに入る。

% docker exec -itu 0 minikube /bin/bash
root@minikube:/#

コンテナに入ったらルートディレクトリに移動し、何があるかllコマンドで確認してみよう。

root@minikube:/# ll
total 80
drwxr-xr-x   1 root root 4096 Sep  7 06:33 ./
drwxr-xr-x   1 root root 4096 Sep  7 06:33 ../
-rwxr-xr-x   1 root root    0 Sep  7 06:33 .dockerenv*
... 以下省略 ...
root@minikube:/#

topコマンドでプロセスも確認してみる。

root@minikube:/# top
top - 07:23:51 up 18:40,  0 users,  load average: 0.69, 0.44, 0.37
Tasks:  38 total,   1 running,  37 sleeping,   0 stopped,   0 zombie

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
   1855 root      20   0 1998680 100428  64300 S   7.6   1.2   3:17.60 kubelet
   1675 root      20   0 1171496 360280  72324 S   7.3   4.5   5:20.97 kube-apiserver
    588 root      20   0 2028192  91008  44340 S   5.3   1.1   1:24.24 dockerd

   ... 以下省略 ...

コンソール内容を見ると、上位にkubeletkube-apiserverのプロセスが実行されている。

kube-apiserverは開発者からの操作を受け付けるAPIを提供し、kubeletはエージェントとして各ノード、今回は単一ノードに存在し、Pod実行を保証する。
containerd*として作成された多数のプロセスがあり、複数のコンテナが上がっていることが分かる。

さらにdocker psコマンドで実行中のDockerコンテナ一覧を取得してみる。

root@minikube:/# docker ps
CONTAINER ID   IMAGE                  COMMAND                  CREATED          STATUS          PORTS     NAMES
20094df9033f   ba04bb24b957           "/storage-provisioner"   59 minutes ago   Up 59 minutes             k8s_storage-provisioner_storage-provisioner_kube-system_514497a4-deaf-4755-a600-73f796f6be9e_1
a9368295b1f7   7a75aeb869dc           "/usr/local/bin/kube..."   59 minutes ago   Up 59 minutes             k8s_kube-proxy_kube-proxy-52hmm_kube-system_d0ed4ddc-0ccc-4f06-aeb9-cc18d5184e77_0
9b1f9ed7a6c1   k8s.gcr.io/pause:3.6   "/pause"                 59 minutes ago   Up 59 minutes             k8s_POD_kube-proxy-52hmm_kube-system_d0ed4ddc-0ccc-4f06-aeb9-cc18d5184e77_0
... 以下省略 ...
root@minikube:/#

コンテナ内でコンテナの稼働を初めて確認したが、これによりechoserverのイメージを使ったコンテナが動いていることが分かった。

仮説だが、NAMESを見るとPODという文字が書かれているコンテナがあり、Podをコンテナで表現しているように思える。
kube-proxyのコンテナもあるようで、これがServiceのプロキシとして動いているようだ。

今回はここまでだが、次回はもう少しKubernetesのアーキテクチャと設定を変えながら、どのように動作するか見ていく。

参考