Ubuntuに軽量KubernetesクラスターのMicroK8sをインストールしてKubernetesを体験してみよう

# 概要
本書ではUbuntuの開発元であるCanonical Ltd.が開発した、軽量Kubernetesクラスターである「[MicroK8s](https://microk8s.io/)」をUbuntu上にインストールします。またMicroK8sをインストール後、Kubernetesクラスター上にNginxのPodを作成します。

## 著者の環境
OS : Ubuntu 20.04.1 LTS (Focal Fossa)

## 1.snapの更新

パッケージ管理ツールであるsnapがインストールされているか確認します。

```
sudo snap version
```

<details><summary>実行例</summary>

```
$ snap version
snap    2.45.2
snapd   2.45.2
series  16
ubuntu  20.04
kernel  5.15.0-91-generic
```

</details>


snapがインストールされていない場合は以下のコマンドを実行します。

```
sudo apt update
sudo apt install snap
```

以下のコマンドを実行し、snapを更新します。

```
sudo snap refresh
sudo snap version
```

<details><summary>実行例</summary>

```
$ sudo snap refresh
snap-store 41.3-71-g709398e from Canonical✓ refreshed
gtk-common-themes 0.1-81-g442e511 from Canonical✓ refreshed

$ sudo snap version
snap    2.61.1
snapd   2.61.1
series  16
ubuntu  20.04
kernel  5.15.0-91-generic
```

</details>


## 2. MicroK8sのインストール

以下のコマンドを実行し、MicroK8sをインストールします。

 ```
 sudo snap install microk8s --classic
 ```

<details><summary>実行例</summary>

```
$ sudo snap install microk8s --classic
microk8s (1.28/stable) v1.28.3 from Canonical✓ installed
```

</details>

以下のコマンドを実行し、MicroK8sがインストールされたか確認します。

```
sudo microk8s version
```

<details><summary>実行例</summary>

```
$ sudo microk8s version
MicroK8s v1.28.3 revision 6089
```

</details>

## 3. ユーザーグループへの追加

sudoコマンドを利用しなくてもmicrok8sコマンドが利用できるように以下のコマンドを実行して権限を変更します。

```
sudo usermod -a -G microk8s $USER
sudo chown -f -R $USER ~/.kube
```

権限変更後、セッションを更新します。

```
su - $USER
```

## 4. アドオンのインストール

以下のコマンドを実行し、core-dns、ダッシュボード、ストレージのアドオンをインストールします。

```
microk8s enable dns 
microk8s enable dashboard
microk8s enable storage
```

<details><summary>実行例</summary>

```
$ microk8s enable dns
Infer repository core for addon dns
Addon core/dns is already enable

$ microk8s enable dashboard
Infer repository core for addon dashboard
Enabling Kubernetes Dashboard
Infer repository core for addon metrics-server
Enabling Metrics-Server
serviceaccount/metrics-server created
clusterrole.rbac.authorization.k8s.io/system:aggregated-metrics-reader created
clusterrole.rbac.authorization.k8s.io/system:metrics-server created
rolebinding.rbac.authorization.k8s.io/metrics-server-auth-reader created
clusterrolebinding.rbac.authorization.k8s.io/metrics-server:system:auth-delegator created
clusterrolebinding.rbac.authorization.k8s.io/system:metrics-server created
service/metrics-server created
deployment.apps/metrics-server created
apiservice.apiregistration.k8s.io/v1beta1.metrics.k8s.io created
clusterrolebinding.rbac.authorization.k8s.io/microk8s-admin created
Metrics-Server is enabled
Applying manifest
serviceaccount/kubernetes-dashboard created
service/kubernetes-dashboard created
secret/kubernetes-dashboard-certs created
secret/kubernetes-dashboard-csrf created
secret/kubernetes-dashboard-key-holder created
configmap/kubernetes-dashboard-settings created
role.rbac.authorization.k8s.io/kubernetes-dashboard created
clusterrole.rbac.authorization.k8s.io/kubernetes-dashboard created
rolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created
clusterrolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created
deployment.apps/kubernetes-dashboard created
service/dashboard-metrics-scraper created
deployment.apps/dashboard-metrics-scraper created
secret/microk8s-dashboard-token created

If RBAC is not enabled access the dashboard using the token retrieved with:

microk8s kubectl describe secret -n kube-system microk8s-dashboard-token

Use this token in the https login UI of the kubernetes-dashboard service.

In an RBAC enabled setup (microk8s enable RBAC) you need to create a user with restricted
permissions as shown in:
https://github.com/kubernetes/dashboard/blob/master/docs/user/access-control/creating-sample-user.md

$ microk8s enable storage

Infer repository core for addon storage
DEPRECATION WARNING: 'storage' is deprecated and will soon be removed. Please use 'hostpath-storage' instead.

Infer repository core for addon hostpath-storage
Enabling default storage class.
WARNING: Hostpath storage is not suitable for production environments.
         A hostpath volume can grow beyond the size limit set in the volume claim manifest.

deployment.apps/hostpath-provisioner created
storageclass.storage.k8s.io/microk8s-hostpath created
serviceaccount/microk8s-hostpath created
clusterrole.rbac.authorization.k8s.io/microk8s-hostpath created
clusterrolebinding.rbac.authorization.k8s.io/microk8s-hostpath created
Storage will be available soon.
test@test-VirtualBox:~$
```

</details>

## 5. Kubernetesクラスター起動確認

以下のコマンドを実行し、Kubernetesクラスターが立ち上がっているか確認します。

```
microk8s status
```

<details><summary>実行例</summary>

```
$ microk8s status
microk8s is running
high-availability: no
  datastore master nodes: 127.0.0.1:19001
  datastore standby nodes: none
addons:
  enabled:
    dashboard            # (core) The Kubernetes dashboard
    dns                  # (core) CoreDNS
    ha-cluster           # (core) Configure high availability on the current node
    helm                 # (core) Helm - the package manager for Kubernetes
    helm3                # (core) Helm 3 - the package manager for Kubernetes
    hostpath-storage     # (core) Storage class; allocates storage from host directory
    metrics-server       # (core) K8s Metrics Server for API access to service metrics
    storage              # (core) Alias to hostpath-storage add-on, deprecated
  disabled:
    cert-manager         # (core) Cloud native certificate management
    cis-hardening        # (core) Apply CIS K8s hardening
    community            # (core) The community addons repository
    gpu                  # (core) Automatic enablement of Nvidia CUDA
    host-access          # (core) Allow Pods connecting to Host services smoothly
    ingress              # (core) Ingress controller for external access
    kube-ovn             # (core) An advanced network fabric for Kubernetes
    mayastor             # (core) OpenEBS MayaStor
    metallb              # (core) Loadbalancer for your Kubernetes cluster
    minio                # (core) MinIO object storage
    observability        # (core) A lightweight observability stack for logs, traces and metrics
    prometheus           # (core) Prometheus operator for monitoring and logging
    rbac                 # (core) Role-Based Access Control for authorisation
    registry             # (core) Private image registry exposed on localhost:32000
    rook-ceph            # (core) Distributed Ceph storage using Rook
```

</details>

## 6. ノード確認

MicroK8sを操作するための独自のkubectlコマンドである`microk8s kubectl`コマンドを使用し、ノードが立ち上がっているか確認します。

```
microk8s kubectl get node
```

<details><summary>実行例</summary>

```
$ microk8s kubectl get node
NAME              STATUS   ROLES    AGE   VERSION
test-virtualbox   Ready    <none>   23m   v1.28.3
```

</details>

## 7. Pod確認

Podが存在しないことを確認します。

```
microk8s get pod
```

<details><summary>実行例</summary>

```
$ microk8s kubectl get pod
No resources found in default namespace.
```

</details>

ただしKubernetesコンポーネントが配置されている「kube-system」のNamespaceにはcore-dns等のPodが配置されています。

```
$ microk8s kubectl get namespace
NAME              STATUS   AGE
kube-system       Active   33m
kube-public       Active   33m
kube-node-lease   Active   33m
default           Active   33m

$ microk8s kubectl get pod -n kube-system
NAME                                         READY   STATUS    RESTARTS       AGE
calico-node-4bbc7                            1/1     Running   0              33m
coredns-864597b5fd-z57pp                     1/1     Running   0              33m
calico-kube-controllers-77bd7c5b-xlp82       1/1     Running   0              33m
dashboard-metrics-scraper-5657497c4c-j8pl2   1/1     Running   0              18m
kubernetes-dashboard-54b48fbf9-v9zbc         1/1     Running   0              18m
hostpath-provisioner-7df77bc496-twknc        1/1     Running   1 (5m7s ago)   17m
metrics-server-848968bdcd-t7797              1/1     Running   0              18m
```

## 8. Pod作成

以下のコマンドを実行し、NginxのPodを作成します。

```
microk8s kubectl run test-nginx --image=nginx:latest
```

<details><summary>実行例</summary>

```
$ microk8s kubectl run test-nginx --image=nginx:latest
pod/test-nginx created
```

</details>

以下のコマンドを実行し、NginxのPodが作成されたか確認します。

```
microk8s kubectl get pod -o wide
```

<details><summary>実行例</summary>

```
$ microk8s kubectl get pod -o wide
NAME         READY   STATUS    RESTARTS   AGE    IP          NODE              NOMINATED NODE   READINESS GATES
test-nginx   1/1     Running   0          106s   10.1.84.8   test-virtualbox   <none>           <none>
```

</details>

Nginx Podが起動したかログを確認します。

```
microk8s kubectl logs test-nginx
```

<details><summary>実行例</summary>

```
$ microk8s kubectl logs test-nginx
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2024/01/08 16:04:26 [notice] 1#1: using the "epoll" event method
2024/01/08 16:04:26 [notice] 1#1: nginx/1.25.3
2024/01/08 16:04:26 [notice] 1#1: built by gcc 12.2.0 (Debian 12.2.0-14)
2024/01/08 16:04:26 [notice] 1#1: OS: Linux 5.15.0-91-generic
2024/01/08 16:04:26 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 65536:65536
2024/01/08 16:04:26 [notice] 1#1: start worker processes
2024/01/08 16:04:26 [notice] 1#1: start worker process 28
2024/01/08 16:04:26 [notice] 1#1: start worker process 29
10.0.2.15 - - [08/Jan/2024:16:12:43 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.68.0" "-"
```

</details>

curlコマンドを使用してNginx PodのIPアドレスに対してアクセスし、「Welcome to nginx!」が表示されるか確認します。

```
curl (Nginx PodのIPアドレス)
```

<details><summary>実行例</summary>

```
$ curl 10.1.84.8
<!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>
```

</details>

# 最後に

MicroK8sを利用することで、Ubuntu環境があれば勉強用途にKubernetesクラスターを作成することができます。またMicroK8sをより深く利用したい場合は[公式サイト](https://microk8s.io/)を確認してみてください。