【Kubernetes】クバァ～...？という人のためのハンズオン【超初心者入門】

# ➊ はじめに
**Kubernetes**？クバァ～...？なんて読むんだ？読めない………😓
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405376/750863ae-b013-4a78-140b-e33303c6cb38.png">

呼び方分からないし、なんか内容も難しそうだし、見てみないフリをしていましたが、周りでは使っている人もチラホラ。分からないから逃げるではなく、ここは勇気を出して、一歩進んでみます！このハンズオンが終わることには、**Kubernetes**の呼び方も分かるようになっているでしょう😁

:::note info
それでは、「クバァ～...？という人のためのハンズオン」初めましょう！
:::

# ➋ クバァ～...？
クバァ～🤔❓の基本について、簡単に調査していきたいと思います。

## (1) Kubernetesとは
### ⬢ 呼び名
**Kubernetes**は、クバネティス、クバネテス、クーべネティスなど呼び方がいくつかあるようです。私は、「`クバネティス`」と呼ぶことにしました（どうでも良いですね）。Kubernetesは、ギリシャ語で**航海長**、または**水先案内人**を意味するようです。

### ⬢ 何をするもの？
Kubernetesの役割は、簡単に言うと**コンテナ化したアプリケーションのデプロイ、スケーリング等の管理を行うもの**です。ここまで分かると、きちんと意図したネーミングだということが分かります。ちなみに「`K8s`」と略されることもあります。

## (2) 今回やるもの
更に知識を高めるために、**Kubernetes**をハンズオンしながらお勉強していきたいと思います。まずは、ローカル環境で**Kubernetes**を動かすための「`Minikube`」というツールがあるので、それを使って**超初心者から初心者への階段を上りたい**と思います。

# ➌ お勉強
「`Minikube`」やる前に、覚える必要がある用語が色々あります。まずは、こちらを簡単に勉強していきましょう。以下の表は、かいつまんで記載しました。

### ⬢ 全体概要
|用語|概要|
|:--|:--|
|Kubernetes（K8s）|呼び方は、クバネティス。**コンテナ化したアプリケーションのデプロイ、スケーリング等の管理を行うもの**。Googleが作っています。|
|Kubernetes Cluster|Control PlaneとNodesの**集合体**。|
|Control Plane|Podの指定レプリカ数の制御（Podのレプリカ数3で実行中、レプリカの1つダウンしレプリカ数が2になった場合、Podを1つ起動しレプリカ数を3に保ちます）など、**クラスターイベントの検出および応答、スケジューリング**などを行います。|
|Node|基本的にノードは1つのVMまたは物理的なマシンです。Nodeは、**Pod**や、Podを制御するための**kubelet**、ネットワークプロキシを行う**kube-proxy**、 Docker等を動作させる**コンテナランタイム**なども含んでいます。|
|Pod|1つまたは複数の**コンテナ**のグループであり、**ストレージ**や**ネットワークの共有リソース**を持ち、コンテナの実行方法に関する仕様（レプリカ数などの規定）を持っています。|
|Deployment|Deploymentは、**Podの作成とレプリカ数の宣言**を提供します。|
|Service|Podをクラスター**内部および外部からアクセスできるように制御**するネットワークサービスです。|

### ⬢ 全体図
<img width="800" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405376/efa1f1a8-54ff-6bd0-a2df-5ccae0e1d8fb.png">

### ⬢ ノード図
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405376/ee17533f-5c82-d235-d0c1-7758c03e36a0.png">

> 引用：ノード図において、分かりやすかったので[Kubenetesドキュメント](https://kubernetes.io/ja/docs/tutorials/kubernetes-basics/explore/explore-intro/)の図を引用させて頂きました。

# ➍ Minikubeインストール
今回実施する環境は、win10、Docker Desktop、WSL2(Ubuntu)で実行します。
同じ様な環境で実施する場合は、こちらの[記事](https://qiita.com/PoodleMaster/items/75edc1744b0a4986c1c8#-%E6%BA%96%E5%82%99)をご参考にセットアップしてください。
## (1) dockerの準備
**Kubernetes**は、Dockerだけでなく複数のコンテナランタイムをサポートしていますが、今回はDockerで実施します。

### ⬢ dockerが使える状態か確認
```sh:
$ docker version
Client: Docker Engine - Community
 Cloud integration: v1.0.20
 Version:           20.10.10
 API version:       1.41
 Go version:        go1.16.9
 Git commit:        b485636
 Built:             Mon Oct 25 07:43:23 2021
 OS/Arch:           linux/amd64
 Context:           default
 Experimental:      true

Server: Docker Engine - Community
 Engine:
  Version:          20.10.10
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.16.9
  Git commit:       e2f740d
  Built:            Mon Oct 25 07:41:30 2021
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.4.11
  GitCommit:        5b46e404f6b9f661a205e28d59c982d3634148f8
 runc:
  Version:          1.0.2
  GitCommit:        v1.0.2-0-g52b36a2
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0
```

### ⬢ dockerグループ所属
dockerコマンドをsudoしなくて良いように、ユーザをdockerグループに所属させます。

```sh
# docker GRP作成
$ sudo groupadd docker

# docker GRPにユーザ追加 (popcornはユーザ名です)
$ sudo usermod -aG docker popcorn

# docker GRP反映
$ sudo newgrp docker
```

使用ユーザが、dockerグループに所属できているか、確認しておきましょう。

```sh
$ cat /etc/group | grep docker
docker:x:1001:root,popcorn
```
## (2) Minikubeインストール
詳細はこちら👉 https://minikube.sigs.k8s.io/docs/start/

### ⬢ Minikubeダウンロード
```sh
# ダウンロード
$ curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
```

### ⬢ Minikubeインストール

```sh
# インストール
$ sudo install minikube-linux-amd64 /usr/local/bin/minikube
```

### ⬢ Minikubeインストール確認
きちんとインストールできたか、確認してみましょう。
ClientとServerのバージョンが表示されれば、きちんとインストールできています。

```sh
# バージョン情報表示
$ kubectl version
Client Version: version.Info{Major:"1", Minor:"21", GitVersion:"v1.21.5", GitCommit:"aea7bbadd2fc0cd689de94a54e5b7b758869d691", GitTreeState:"clean", BuildDate:"2021-09-15T21:10:45Z", GoVersion:"go1.16.8", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"22", GitVersion:"v1.22.3", GitCommit:"c92036820499fedefec0f847e2054d824aea6cd1", GitTreeState:"clean", BuildDate:"2021-10-27T18:35:25Z", GoVersion:"go1.16.9", Compiler:"gc", Platform:"linux/amd64"}
```

## (3) Minikube起動確認
### ⬢ Minikube起動
初回起動時は、minikubeのDockerイメージを自動でダウンロードしにいきます。

```sh:1回目
# Minikube起動
$ minikube start --driver=docker
😄  minikube v1.24.0 on Ubuntu 20.04
✨  Using the docker driver based on user configuration
👍  Starting control plane node minikube in cluster minikube
🚜  Pulling base image ...
💾  Downloading Kubernetes v1.22.3 preload ...
    > preloaded-images-k8s-v13-v1...: 501.73 MiB / 501.73 MiB  100.00% 6.53 MiB
    > gcr.io/k8s-minikube/kicbase: 355.78 MiB / 355.78 MiB  100.00% 4.29 MiB
🔥  Creating docker container (CPUs=2, Memory=2200MB) ...
🐳  Preparing Kubernetes v1.22.3 on Docker 20.10.8 ...
    ▪ Generating certificates and keys ...
    ▪ Booting up control plane ...
    ▪ Configuring RBAC rules ...
🔎  Verifying Kubernetes components...
    ▪ Using image gcr.io/k8s-minikube/storage-provisioner:v5
🌟  Enabled addons: storage-provisioner, default-storageclass
🏄  Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default
```

2回目以降は、立ち上げるだけになります。

```sh:2回目以降
# Minikube起動
$ minikube start
😄  minikube v1.24.0 on Ubuntu 20.04
✨  Using the docker driver based on existing profile
👍  Starting control plane node minikube in cluster minikube
🚜  Pulling base image ...
🔄  Restarting existing docker container for "minikube" ...
🐳  Preparing Kubernetes v1.22.3 on Docker 20.10.8 ...
🔎  Verifying Kubernetes components...
    ▪ Using image gcr.io/k8s-minikube/storage-provisioner:v5
🌟  Enabled addons: storage-provisioner, default-storageclass
🏄  Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default
```

### ⬢ Minikubeステータス確認
Minikubeがきちんと起動できているか、ステータスを確認します。

```sh
# Minikubeステータス確認
$ minikube status
minikube
type: Control Plane
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured
```

# ➎ Podを動作させよう
今回起動させるPod(コンテナ)は、以下の「`mnister`」という自作Dockerイメージにします。
ポート5000番で待ち受けるwebアプリサーバです。

https://hub.docker.com/repository/docker/poodlemaster/img-mnister/general

このDockerイメージをDeploymentすることにより、Podを作成します。

> Kubernetesの **Deployment** はPodの状態を確認し、Podのコンテナが停止した場合には再起動します。DeploymentはPodの作成やスケールを管理するために推奨される方法です。
※引用：[Kubenetesドキュメント](https://kubernetes.io/ja/docs/tutorials/hello-minikube/)

## (1) Worker Node
### ⬢ Worker Nodeを追加
Podを動かすworkerノードを追加します。

```sh
$ minikube node add --worker

😄  Adding node m02 to cluster minikube
❗  Cluster was created without any CNI, adding a node to it might cause broken networking.
👍  Starting worker node minikube-m02 in cluster minikube
🚜  Pulling base image ...
🔥  Creating docker container (CPUs=2, Memory=2200MB) ...
🐳  Preparing Kubernetes v1.22.3 on Docker 20.10.8 ...

🔎  Verifying Kubernetes components...
🏄  Successfully added m02 to minikube!
```
### ⬢ 追加したNodeを確認
「`minikube-m02`」ノードが追加されていますね。

```sh
$ kubectl get nodes
NAME           STATUS   ROLES                  AGE   VERSION
minikube       Ready    control-plane,master   21d   v1.22.3
minikube-m02   Ready    <none>                 94m   v1.22.3
```

### ⬢ Nodeのラベルを確認
workerの方に「`kubernetes.io/hostname=minikube-m02`」というユニークなラベルがあることを確認しておきます。これは、次の手順で、どのNodeでPodを起動するか指定する際に使用します。

```sh
$ kubectl get nodes --show-labels
NAME           STATUS   ROLES                  AGE   VERSION   LABELS
minikube       Ready    control-plane,master   21d   v1.22.3   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=minikube,kubernetes.io/os=linux,minikube.k8s.io/commit=76b94fb3c4e8ac5062daf70d60cf03ddcc0a741b,minikube.k8s.io/name=minikube,minikube.k8s.io/updated_at=2021_11_16T11_07_01_0700,minikube.k8s.io/version=v1.24.0,node-role.kubernetes.io/control-plane=,node-role.kubernetes.io/master=,node.kubernetes.io/exclude-from-external-load-balancers=
minikube-m02   Ready    <none>                 93m   v1.22.3   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=minikube-m02,kubernetes.io/os=linux
```

## (2) レシピ（yaml）を作成
**Deployment**の設定ファイルであるレシピ（yaml）を作成します。
「`spec`」以降は、コンテナの設定を記載します。「`nodeSelector`」の箇所には、先程調べたラベルを指定します。これでworkerノードでPodが動作するようになります。

```yaml:mnister.yaml
# -------------------------------------------------------------------------------------------
# Deployment
# -------------------------------------------------------------------------------------------apiVersion: apps/v1
kind: Deployment                                # 種別はDeployment
metadata:
  name: mnister                                 # mnisterという名前のDeploymentが作成
spec:
  selector:
    matchLabels:
      app: mnister                              # Podテンプレートにて定義されたラベル(app: mnister)を選択
  replicas: 1                                   # 1つのレプリカPodを作成
  template:
    # ---- ここからPodTemplate ----
    metadata:
      labels:
        app: mnister                            # app: mnisterというラベルを付与
    spec:
      containers:
      - name: mnister                           # Podがmnisterという名前で
        image: poodlemaster/img-mnister:latesta # Docker Hubにあるimg-mnisterの最新バージョンのコンテナを動作させる
        ports:
        - containerPort: 5000                   # containerPortは5000番
      nodeSelector:
        kubernetes.io/hostname: minikube-m02    # minikube-m02というラベルがついたNodeで動作させる
    # ---- ここまでPodTemplate ----
```
## (3) Pod作成
**Deployment**を作成すると、その内容に従い**Pod**が起動されます。

### ⬢ Deploymentの作成
先程の設定ファイルから、**Deployment**を作成します。

```sh
$ kubectl apply -f mnister.yaml
deployment.apps/mnister created
```

**Deployment**が作成されたことを確認します。

```sh
$ kubectl get deploy
NAME      READY   UP-TO-DATE   AVAILABLE   AGE
mnister   0/1     1            0           58s
```
「`mnister`」が、立ち上がるまで待ちましょう。（AVAILABLE 0→1）

```sh
$ kubectl get deploy
NAME      READY   UP-TO-DATE   AVAILABLE   AGE
mnister   1/1     1            1           97s
```

### ⬢ Podの確認
**Deployment**を作成すると、その内容に従い**Pod**が起動されます。今回は、「`mnister-79597cf8c9-phdq6`」という名の**Pod**が、作成されたことを確認しておきましょう。

```sh
$ kubectl get pods
NAME                       READY   STATUS    RESTARTS   AGE
mnister-79597cf8c9-phdq6   1/1     Running   0          76m
```

PodがNode「`minikube-m02`」で実行されているのを確認します。

```sh
$ kubectl describe pods
Name:         mnister-79597cf8c9-phdq6
Namespace:    default
Priority:     0
Node:         minikube-m02/192.168.49.3
Start Time:   Tue, 07 Dec 2021 17:28:15 +0900
Labels:       app=mnister
              pod-template-hash=64ff478f7d
Annotations:  <none>
Status:       Running
IP:           172.17.0.2
IPs:
  IP:           172.17.0.2
Controlled By:  ReplicaSet/mnister-64ff478f7d
Containers:
  mnister:
    Container ID:   docker://2bf64e2cfefaccffd8c9844dd490eb5933ba9d18c61f8c4027f3d2480d67cf97
    Image:          poodlemaster/img-mnister:latest
    Image ID:       docker-pullable://poodlemaster/img-mnister@sha256:0f2c26e4910f2fb8e571106ddc1ed094625a3e867bfbe69cf7200d75757a83ec
    Port:           5000/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Tue, 07 Dec 2021 17:28:18 +0900
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-z8mgm (ro)
Conditions:
  Type              Status
  Initialized       True
  Ready             True
  ContainersReady   True
  PodScheduled      True
Volumes:
  kube-api-access-z8mgm:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              kubernetes.io/hostname=minikube-m02
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:                      <none>
```

### ⬢ レプリカ動作の確認
レプリカ（replicas: 1）が正しく動作するか確認してみます。
今は「`mnister-79597cf8c9-phdq6`」のPodが動いています。

```sh
$ kubectl get pods
NAME                       READY   STATUS    RESTARTS   AGE
mnister-79597cf8c9-phdq6   1/1     Running   0          2m10s
```
「`mnister-79597cf8c9-phdq6`」のPodを削除します。

```sh
$ kubectl delete pod mnister-79597cf8c9-phdq6
pod "mnister-79597cf8c9-phdq6" deleted
```
「`mnister-79597cf8c9-phdq6`」のPodを削除後、Podの状態を確認すると「`mnister-64ff478f7d-4v58k`」という新たなPodが、自動的に1つ起動され運転中になりました。これで、レプリカが正しく動作していることが分かりました。

```sh
$ kubectl get pods
NAME                       READY   STATUS              RESTARTS   AGE
mnister-64ff478f7d-4v58k   0/1     ContainerCreating   0          3s
$ kubectl get pods
NAME                       READY   STATUS    RESTARTS   AGE
mnister-64ff478f7d-4v58k   1/1     Running   0          2m48s
```

※Podを消してもレプリカ設定数に戻そうとするので、Podを起動させたくない場合は、Deploymentを削除する必要があります。

### ⬢ Serviceの作成
mnisterをport5000番で公開するように**Service**の作成を行います。

```sh
$ kubectl expose deploy/mnister --port=5000
```

**Service**にmnisterが、追加されたことを確認します。

```sh
$ kubectl get svc
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE
kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP    21d
mnister      ClusterIP   10.103.65.68   <none>        5000/TCP   99m
```

### ⬢ おまけ
**Deployment**と**Service**をまとめて記載することもできます。その場合レシピ（yaml）は、以下のようになります。

```yaml:mnister_deploy_svc.yaml
# -------------------------------------------------------------------------------------------
# Deployment
# -------------------------------------------------------------------------------------------
apiVersion: apps/v1
kind: Deployment                                # 種別はDeployment
metadata:
  name: mnister                                 # mnisterという名前のDeploymentが作成
spec:
  selector:
    matchLabels:
      app: mnister                              # Podテンプレートにて定義されたラベル(app: mnister)を選択
  replicas: 3                                   # 3つのレプリカPodを作成
  template:
    # ---- ここからPodTemplate ----
    metadata:
      labels:
        app: mnister                            # app: mnisterというラベルを付与
    spec:
      containers:
      - name: mnister                           # Podがmnisterという名前で
        image: poodlemaster/img-mnister:latest  # Docker Hubにあるmnisterの最新バージョンのコンテナを動作させる
        ports:
        - containerPort: 5000                   # containerPortは5000番
      nodeSelector:
        kubernetes.io/hostname: minikube-m02    # minikube-m02というラベルがついたNodeで動作させる
    # ---- ここまでPodTemplate ----
---
# -------------------------------------------------------------------------------------------
# Service
# -------------------------------------------------------------------------------------------
apiVersion: v1
kind: Service                                   # 種別はService
metadata:
  name: mnister                                 #  mnisterという名前のServiceが作成
spec:
  ports:
  - port: 5000                                  # Port5000を外部へ公開
  selector:
    app: mnister                                # ラベル(app: mnister)のあるPodへ転送
```
レシピ（yaml）の適応方法は以下の通りです。「`kubectl apply`」コマンドの応答メッセージは、新規作成の場合はcreated、設定変更した場合はconfigured、設定変更が無い場合はunchangedとなります。

```sh
$ kubectl apply -f mnister_deploy_svc.yaml
deployment.apps/mnister created
service/mnister created
```

## (3) port-forward開始
### ⬢ port-forward
「localhostの5050番」へ届いたパケットを「Podの5000番」へ転送するように設定します。「kubectl port-forward」のあとに、Pod名、Deployment名、Service名などを指定できます。

```sh
$ kubectl port-forward deployment.apps/mnister 5050:5000
Forwarding from 127.0.0.1:5050 -> 5000
Forwarding from [::1]:5050 -> 5000
```

## (4) ブラウザアクセス
### ⬢ ブラウザアクセス
この状態で、ブラウザから以下のURLへアクセスします。

URL👉 http://localhost:5050/

### ⬢ アクセス結果
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405376/49540265-b7d3-eb2a-1d46-314988d5380a.png">

# ➏ ダッシュボード
Minikubeは、dashboard機能も持っています。

### ⬢ ダッシュボード起動

```sh
$ minikube dashboard
🤔  Verifying dashboard health ...
🚀  Launching proxy ...
🤔  Verifying proxy health ...
🎉  Opening http://127.0.0.1:34009/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/ in your default browser...
👉  http://127.0.0.1:34009/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/
```

### ⬢ ダッシュボード表示
「👉」で示されたURLへアクセスします。

### ⬢ アクセス結果
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405376/9dd6e79e-dbe9-1f26-e0bb-af657ce57208.png">



# ➐ Podへログインする
無理に入ることはないです（必須手順ではないです）が、Podの中で処理をしたい場合は、こちらのコマンドで入れます。

### ⬢ Podのリストを表示
Podのリストを表示します。

```sh
$ kubectl get pods
NAME                       READY   STATUS    RESTARTS   AGE
mnister-64ff478f7d-w29hf   1/1     Running   0          84m
```

### ⬢ Podの中に入る
Pod名「`mnister-64ff478f7d-w29hf`」を指定してアクセスします。

```sh
$ kubectl exec --stdin --tty mnister-64ff478f7d-w29hf -- /bin/bash
(base) root@mnister-64ff478f7d-w29hf:/bg# ls
__pycache__  colab_mnist.hdf5  server.py  static  templates
```

# ➑ リソースの削除
グチャグチャに遊んだらキレイに消す手順も確認しておきましょう。

> 整理しますと、追加したのは、**Deployment**、**Service**に「`mnister`」を追加しました。また、「`minikube-m02`」という**Worker Node**を1つ追加しました。これらを削除したいと思います。

### ⬢ Deploymentの削除
**Deployment**に追加した「`mnister`」を削除します。

```sh
$ kubectl delete deploy mnister
deployment.apps "mnister" deleted
```
### ⬢ Serviceの削除
**Service**に追加した「`mnister`」を削除します。

```sh
$ kubectl delete svc mnister
service "mnister" deleted
```

### ⬢ Nodeの削除
今回追加した「`minikube-m02`」ノードを削除します。

```sh
$  minikube node delete minikube-m02
🔥  Deleting node minikube-m02 from cluster minikube
✋  Stopping node "minikube-m02"  ...
🛑  Powering off "minikube-m02" via SSH ...
🔥  Deleting "minikube-m02" in docker ...
💀  Node minikube-m02 was successfully deleted.
```

### ⬢ 削除できたか確認
nodes, pods, deployments, servicesを表示して確認する。(no, po, deploy, svcはそれぞれの省略形です)

```sh
$ kubectl get no,po,deploy,svc --all-namespaces
NAME            STATUS   ROLES                  AGE   VERSION
node/minikube   Ready    control-plane,master   21d   v1.22.3

NAMESPACE              NAME                                             READY   STATUS    RESTARTS         AGE
kube-system            pod/coredns-78fcd69978-b4n2v                     1/1     Running   8 (5h37m ago)    21d
kube-system            pod/etcd-minikube                                1/1     Running   8 (5h37m ago)    21d
kube-system            pod/kindnet-4zc4b                                1/1     Running   0                139m
kube-system            pod/kube-apiserver-minikube                      1/1     Running   9 (5h37m ago)    21d
kube-system            pod/kube-controller-manager-minikube             1/1     Running   8 (5h37m ago)    21d
kube-system            pod/kube-proxy-gm527                             1/1     Running   8 (5h37m ago)    21d
kube-system            pod/kube-scheduler-minikube                      1/1     Running   8 (5h37m ago)    21d
kube-system            pod/storage-provisioner                          1/1     Running   17 (5h24m ago)   21d
kubernetes-dashboard   pod/dashboard-metrics-scraper-5594458c94-f2f9c   1/1     Running   4 (5h37m ago)    20d
kubernetes-dashboard   pod/kubernetes-dashboard-654cf69797-rk879        1/1     Running   7 (5h24m ago)    20d

NAMESPACE              NAME                                        READY   UP-TO-DATE   AVAILABLE   AGE
kube-system            deployment.apps/coredns                     1/1     1            1           21d
kubernetes-dashboard   deployment.apps/dashboard-metrics-scraper   1/1     1            1           20d
kubernetes-dashboard   deployment.apps/kubernetes-dashboard        1/1     1            1           20d

NAMESPACE              NAME                                TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                  AGE
default                service/kubernetes                  ClusterIP   10.96.0.1        <none>        443/TCP                  21d
kube-system            service/kube-dns                    ClusterIP   10.96.0.10       <none>        53/UDP,53/TCP,9153/TCP   21d
kubernetes-dashboard   service/dashboard-metrics-scraper   ClusterIP   10.102.195.221   <none>        8000/TCP                 20d
kubernetes-dashboard   service/kubernetes-dashboard        ClusterIP   10.107.185.79    <none>        80/TCP                   20d
```

# ➒ Minikubeの停止と削除
## (1) Minikubeの停止
Minikubeクラスターを停止します。

```sh
$ minikube stop
✋  Stopping node "minikube"  ...
🛑  Powering off "minikube" via SSH ...
🛑  1 node stopped.
```

## (2) Minikubeの削除
Minikubeクラスターを削除します。これをやると追加したNodeもDeploymentもServiceも全て無くなります。一気に初期化したい場合は、これがオススメです。

```sh
$ minikube delete
🔥  Deleting "minikube" in docker ...
🔥  Deleting container "minikube" ...
🔥  Deleting container "minikube-m02" ...
🔥  Removing /home/popcorn/.minikube/machines/minikube ...
🔥  Removing /home/popcorn/.minikube/machines/minikube-m02 ...
💀  Removed all traces of the "minikube" cluster.
```

# ➓ 以上
ここまでやれば「**Kubernetes**ってなぁに？」と聞かれたときに、「クバァ...ええと、クバネティスはね………」と答えることができるはずです。これで**超初心者から初心者へ一段階段を登ったはず**です。しかし、DockerからKubernetesへ勉強をスライドしてきましたが、一気に難しくなりましたね。頭から煙がでそうです。我慢ならないので、今日はもう寝て、明日以降勉強することとします😪

お疲れ様でした😊