nがひとつ多い。

えぬなおの技術的なことを書いていくとこ。

multipassでOSX上にmicro-k8sを立てる。

はじめに

この記事はCyberAgent Advent Calendarの20日目の記事になります。

adventar.org

ローカルにkuberentesを立てる時、皆さんどうしてますか?
うん、多くの人は minikube をたてて試していることでしょう。

github.com

しかし minikube は色々なプラグインや特定のCRDが動かないなどお試しするにも難しい部分も多いです。
さて、実はubuntuコミュニティのなかで micro-k8s というものが開発されているらしいです。

MicroK8s - Fast, Light, Upstream Developer Kubernetes

しかもみてください、

[FEATURES]
Istio
GPGPU bindings
Daily builds
Local storage
Local registry
Updates
Dashboard
Metrics
Upgrades
Ingress
DNS
Conformant

Istio とか GPGPU binding も動くらしいです。
すごい、試してみたいです。

よしMacにインストール・・・ってあれ!?

公式のGetting Starttedが・・・あ・・・あ・・・。

$ sudo snap install microk8s --classic

Ubuntu専用のインストーラ使ってんじゃねーか、ってことで、VMに入れるかって話になってくる。

multipassを使ってぶち込む。

えーまた Vagrant とか使ってVM使うのん?めんどくないん? ってことで、以下のサイトでおすすめされていた multipass とかいうUbuntuVM管理ツールが便利だったので使う。

discourse.ubuntu.com

github.com

リリースページにある pkg ファイルから入れるのが早い。

https://github.com/CanonicalLtd/multipass/releases/download/2018.11.1-pre3/multipass-2018.10.1-full-141-g2b7f2bd-Darwin.pkg

なんでmultipassだといいのん?

現状で「手っ取り早くOSX上でUbuntuVMが欲しい」と言う用途に対して一番適したツールだからです。

$ multipass launch --name nnao45-k8s-vm --mem 4G --disk 40G --cpus 2
Launched: nnao45-k8s-vm

VMデプロイがこれで終わり。やばない?
(注意点だが、 デフォルトのメモリ1Gでやると、Addonがろくに動かないのである程度増やして指定しておくといい。4Gもあれば色々遊ぶには十分でしょう。)

$ multipass exec nnao45-k8s-vm  -- sudo snap install microk8s --classic
2018-12-18T11:36:00Z INFO Waiting for restart...
microk8s v1.13.0 from 'canonical' installed

はい、kubernetesインスコ終了っす。 一応NWも通しておく。

$ multipass exec nnao45-k8s-vm -- sudo iptables -P FORWARD ACCEPT

このように kubectl execっぽく multipass exec hoge-vm -- 形式でホストからゲストVMにシームレスにOSコマンドを入れることができるのがおすすめポイントです。

minikubeとの差別点としては、純粋なUbuntu VMとして管理がしやすいでの、ちょっとVMに小細工する事も出来る所が魅力です。

各種セットアップ

multipassの中に入る

$ multipass shell nnao45-k8s-vm 

VMに入れる。

/snap/bin/microk8s.status

micro-k8sのステータスっつーかアドオンが見える。
プラグインで管理されてるのねん。

$ multipass exec nnao45-k8s-vm -- /snap/bin/microk8s.status
microk8s is running
addons:
gpu: disabled
storage: disabled
registry: disabled
ingress: disabled
dns: disabled
metrics-server: disabled
istio: disabled
dashboard: disabled

kubectl

とりあえず入れておく。
これも脳死したいのでsnapで入れる。

$ multipass exec nnao45-k8s-vm -- sudo snap install kubectl --classic

kubectl 1.13.0 from Canonical✓ installed

やばい簡単すぎる逆に大丈夫か?

そしてmicrok8sのkubeconfigを所定の位置においておく。

$ multipass exec nnao45-k8s-vm -- sh -c '/snap/bin/microk8s.config > /home/multipass/.kube/kubeconfig'

ドキドキ

$ multipass exec nnao45-k8s-vm -- /snap/bin/kubectl get node
NAME            STATUS   ROLES    AGE   VERSION
nnao45-k8s-vm   Ready    <none>   25m   v1.13.0

わっしょーい🤗

んーでも何にもないね😷 corednskube-dns もない。

$ multipass exec nnao45-k8s-vm -- /snap/bin/kubectl get all --all-namespaces 
NAMESPACE   NAME                 TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
default     service/kubernetes   ClusterIP   10.152.183.1   <none>        443/TCP   28m

(実は /snap/bin/microk8s.kubectl コマンドがあり、これだけでもデフォルトの kubeconfig だけでいいなら十分。が、何かと kubeconfig は自分好みに加筆することもあるだろうし、プラグインとかも入れる人は入れておけば良い)

アドオンの有効化

とりあえず

dns
dashboard
metrics-server

これくらいは有効化しておきたいのでしておきます。

$ multipass exec nnao45-k8s-vm -- /snap/bin/microk8s.enable dns dashboard metrics-server 
Enabling DNS
Applying manifest
service/kube-dns created
serviceaccount/kube-dns created
configmap/kube-dns created
deployment.extensions/kube-dns created
Restarting kubelet
DNS is enabled
Enabling dashboard
secret/kubernetes-dashboard-certs created
serviceaccount/kubernetes-dashboard created
deployment.apps/kubernetes-dashboard created
service/kubernetes-dashboard created
service/monitoring-grafana created
service/monitoring-influxdb created
service/heapster created
deployment.extensions/monitoring-influxdb-grafana-v4 created
serviceaccount/heapster created
configmap/heapster-config created
configmap/eventer-config created
deployment.extensions/heapster-v1.5.2 created
dashboard enabled
Enabling metrics-server
clusterrolebinding.rbac.authorization.k8s.io/metrics-server:system:auth-delegator created
rolebinding.rbac.authorization.k8s.io/metrics-server-auth-reader created
apiservice.apiregistration.k8s.io/v1beta1.metrics.k8s.io created
serviceaccount/metrics-server created
configmap/metrics-server-config created
deployment.extensions/metrics-server-v0.2.1 created
service/metrics-server created
clusterrole.rbac.authorization.k8s.io/system:metrics-server created
clusterrolebinding.rbac.authorization.k8s.io/system:metrics-server created
metrics-server enabled

ドキドキ

$ multipass exec nnao45-k8s-vm -- /snap/bin/kubectl get all --all-namespaces 
NAMESPACE     NAME                                                  READY   STATUS    RESTARTS   AGE
kube-system   pod/heapster-v1.5.2-64874f6bc6-p4l8v                  4/4     Running   0          45s
kube-system   pod/kube-dns-6ccd496668-rmsf8                         3/3     Running   0          2m2s
kube-system   pod/kubernetes-dashboard-654cfb4879-v457l             1/1     Running   0          116s
kube-system   pod/metrics-server-v0.2.1-6f76659f47-nhx4g            2/2     Running   0          31s
kube-system   pod/monitoring-influxdb-grafana-v4-6679c46745-d5gll   2/2     Running   0          116s

NAMESPACE     NAME                           TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)             AGE
default       service/kubernetes             ClusterIP   10.152.183.1     <none>        443/TCP             6m12s
kube-system   service/heapster               ClusterIP   10.152.183.93    <none>        80/TCP              116s
kube-system   service/kube-dns               ClusterIP   10.152.183.10    <none>        53/UDP,53/TCP       2m2s
kube-system   service/kubernetes-dashboard   ClusterIP   10.152.183.208   <none>        443/TCP             116s
kube-system   service/metrics-server         ClusterIP   10.152.183.61    <none>        443/TCP             114s
kube-system   service/monitoring-grafana     ClusterIP   10.152.183.143   <none>        80/TCP              116s
kube-system   service/monitoring-influxdb    ClusterIP   10.152.183.151   <none>        8083/TCP,8086/TCP   116s

NAMESPACE     NAME                                             READY   UP-TO-DATE   AVAILABLE   AGE
kube-system   deployment.apps/heapster-v1.5.2                  1/1     1            1           116s
kube-system   deployment.apps/kube-dns                         1/1     1            1           2m2s
kube-system   deployment.apps/kubernetes-dashboard             1/1     1            1           116s
kube-system   deployment.apps/metrics-server-v0.2.1            1/1     1            1           114s
kube-system   deployment.apps/monitoring-influxdb-grafana-v4   1/1     1            1           116s

NAMESPACE     NAME                                                        DESIRED   CURRENT   READY   AGE
kube-system   replicaset.apps/heapster-v1.5.2-56c546dbb8                  0         0         0       61s
kube-system   replicaset.apps/heapster-v1.5.2-64874f6bc6                  1         1         1       46s
kube-system   replicaset.apps/heapster-v1.5.2-6bc7c4965d                  0         0         0       116s
kube-system   replicaset.apps/kube-dns-6ccd496668                         1         1         1       2m2s
kube-system   replicaset.apps/kubernetes-dashboard-654cfb4879             1         1         1       116s
kube-system   replicaset.apps/metrics-server-v0.2.1-6f76659f47            1         1         1       32s
kube-system   replicaset.apps/metrics-server-v0.2.1-7d7d77666c            0         0         0       114s
kube-system   replicaset.apps/monitoring-influxdb-grafana-v4-6679c46745   1         1         1       116s

わっしょーい🤗

kube proxy

さてせっかくだからgrafanaにアクセスしてみたいわけです。

$ multipass exec nnao45-k8s-vm -- /snap/bin/kubectl cluster-info
Kubernetes master is running at http://localhost:8080
Heapster is running at http://localhost:8080/api/v1/namespaces/kube-system/services/heapster/proxy
KubeDNS is running at http://localhost:8080/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
Metrics-server is running at http://localhost:8080/api/v1/namespaces/kube-system/services/https:metrics-server:/proxy
Grafana is running at http://localhost:8080/api/v1/namespaces/kube-system/services/monitoring-grafana/proxy
InfluxDB is running at http://localhost:8080/api/v1/namespaces/kube-system/services/monitoring-influxdb:http/proxy

localhostって言われてもね・・・。そういえばVMのIPは・・・?

$ multipass list 
Name                    State             IPv4             Release
nnao45-k8s-vm           RUNNING           192.168.64.4     Ubuntu 18.04 LTS

192.168.64.4 らしい。じゃあ、

http://192.168.64.4:8080/api/v1/namespaces/kube-system/services/monitoring-grafana/proxy

f:id:nnao45:20181218213101p:plain

衝撃的なくらい簡単なんだが・・・。

(ちなみにいえば servicetype:NodePort で作れば multipassのVMのIPでリッスンするので それでもアクセスできます。)

metrics-server

kubectk topコマンドはもちろん使えます。

$ multipass exec nnao45-k8s-vm -- /snap/bin/kubectl top pod --all-namespaces
NAMESPACE     NAME                                              CPU(cores)   MEMORY(bytes)
kube-system   heapster-v1.5.2-64874f6bc6-p4l8v                  2m           32Mi
kube-system   kube-dns-6ccd496668-rmsf8                         5m           22Mi
kube-system   kubernetes-dashboard-654cfb4879-v457l             0m           12Mi
kube-system   metrics-server-v0.2.1-6f76659f47-nhx4g            0m           15Mi
kube-system   monitoring-influxdb-grafana-v4-6679c46745-d5gll   3m           23Mi

$ multipass exec nnao45-k8s-vm -- /snap/bin/kubectl top node
NAME            CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%
nnao45-k8s-vm   378m         37%    1395Mi          36%

外からkubectlを叩く

まぁホストVMからkubectlを叩きたいわけです。 でもmicro-k8sの場合は何にも難しくなくてkubectl cluster-infoで見た通り、
わかりやすく kuberenetes サービスの endpoint<ゲストVMのIP>:8080を向いています。 ので、何にも手を加えずにアクセスできます。

$ multipass exec nnao45-k8s-vm -- /home/multipass/.kube/kubeconfig > ./kubeconfig

終わりです・・・圧倒的に簡単・・・!

$ cat ./kubeconfig
apiVersion: v1
clusters:
- cluster:
    server: http://192.168.64.4:8080
  name: microk8s-cluster
contexts:
- context:
    cluster: microk8s-cluster
    user: admin
  name: microk8s
current-context: microk8s
kind: Config
preferences: {}
users:
- name: admin
  user:
    username: admin
$ kubectl --kubeconfig ./kubeconfig get pods --all-namespaces                                                                                                                                                                  18-12-18 22:00:36
NAMESPACE     NAME                                              READY   STATUS    RESTARTS   AGE
kube-system   heapster-v1.5.2-64874f6bc6-p4l8v                  4/4     Running   1          38m
kube-system   kube-dns-6ccd496668-rmsf8                         3/3     Running   0          39m
kube-system   kubernetes-dashboard-654cfb4879-v457l             1/1     Running   0          39m
kube-system   metrics-server-v0.2.1-6f76659f47-nhx4g            2/2     Running   0          38m
kube-system   monitoring-influxdb-grafana-v4-6679c46745-d5gll   2/2     Running   0          39m

最後に初期化をお手持ちのシェルで自動化

bashrcやzshrcに書いておくとちょうどいい関数をご用意しました。
適当にカスタマイズしてご使用ください。

microk8s-init(){
  if ! which multipass >/dev/null 2>&1; then
    echo "Please intall multipass"
    return 1
  fi

  # Set the VM Name.
  local MICROK8S_VM_NAME="nnao45-k8s-vm"

  # Setup the VM.
  multipass launch --name ${MICROK8S_VM_NAME} --mem 4G --disk 40G --cpus 2

  # Echo the VM IP
  local MICROK8S_VM_IP=$(multipass list | tail -n1 | awk '{print $3}')
  echo ${MICROK8S_VM_NAME}"'s" IP is ${MICROK8S_VM_IP}

  # Install the Kubernetes.
  multipass exec ${MICROK8S_VM_NAME} -- sudo snap install microk8s --classic
  multipass exec ${MICROK8S_VM_NAME} -- sudo iptables -P FORWARD ACCEPT

  # Wait during wake up the microk8s.
  echo "Initial Setup is Starting."

  multipass exec ${MICROK8S_VM_NAME} -- sh -c 'while [ ! $(/snap/bin/microk8s.status > /dev/null; echo $?) -eq 0 ]; do echo -n .; sleep 1; done'

  echo "Initial Setup is Done."

  # Install & Setup the dns metrics-server addons.
  multipass exec ${MICROK8S_VM_NAME} -- /snap/bin/microk8s.enable dns metrics-server

  # Install & Setup the kubectl
  multipass exec ${MICROK8S_VM_NAME} -- sudo snap install kubectl --classic
  multipass exec ${MICROK8S_VM_NAME} -- sh -c '/snap/bin/microk8s.config > /home/multipass/.kube/kubeconfig'
  multipass exec ${MICROK8S_VM_NAME} -- cat /home/multipass/.kube/kubeconfig > ./${MICROK8S_VM_NAME}-kubeconfig

  echo "microk8s-init is done."
}
$ microk8s-init
Launched: nnao45-k8s-vm
nnao45-k8s-vm's IP is 192.168.64.4
2018-12-19T10:25:57Z INFO Waiting for restart...
microk8s v1.13.0 from 'canonical' installed
Initial Setup is Starting.
....Initial Setup is Done.
Enabling DNS
Applying manifest
service/kube-dns created
serviceaccount/kube-dns created
configmap/kube-dns created
deployment.extensions/kube-dns created
Restarting kubelet
DNS is enabled
Enabling metrics-server
clusterrolebinding.rbac.authorization.k8s.io/metrics-server:system:auth-delegator created
rolebinding.rbac.authorization.k8s.io/metrics-server-auth-reader created
apiservice.apiregistration.k8s.io/v1beta1.metrics.k8s.io created
serviceaccount/metrics-server created
configmap/metrics-server-config created
deployment.extensions/metrics-server-v0.2.1 created
service/metrics-server created
clusterrole.rbac.authorization.k8s.io/system:metrics-server created
clusterrolebinding.rbac.authorization.k8s.io/system:metrics-server created
metrics-server enabled
kubectl 1.13.0 from Canonical✓ installed
microk8s-init is done.

$ kubectl --kubeconfig ./nnao45-k8s-vm-kubeconfig get all --all-namespaces
NAMESPACE     NAME                                         READY   STATUS    RESTARTS   AGE
kube-system   pod/kube-dns-6ccd496668-lrcw8                3/3     Running   0          76s
kube-system   pod/metrics-server-v0.2.1-6f76659f47-d48zn   2/2     Running   0          39s

NAMESPACE     NAME                     TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)         AGE
default       service/kubernetes       ClusterIP   10.152.183.1    <none>        443/TCP         81s
kube-system   service/kube-dns         ClusterIP   10.152.183.10   <none>        53/UDP,53/TCP   78s
kube-system   service/metrics-server   ClusterIP   10.152.183.87   <none>        443/TCP         71s

NAMESPACE     NAME                                    READY   UP-TO-DATE   AVAILABLE   AGE
kube-system   deployment.apps/kube-dns                1/1     1            1           77s
kube-system   deployment.apps/metrics-server-v0.2.1   1/1     1            1           71s

NAMESPACE     NAME                                               DESIRED   CURRENT   READY   AGE
kube-system   replicaset.apps/kube-dns-6ccd496668                1         1         1       76s
kube-system   replicaset.apps/metrics-server-v0.2.1-6f76659f47   1         1         1       39s
kube-system   replicaset.apps/metrics-server-v0.2.1-7d7d77666c   0         0         0       71s

参考までにMacBook Proデュアルコア16Gメモリでのでの3分くらいでできます。

感想

とても簡単にMac上に kubernetes を構築することができました。 Istio もデプロイできるようなので、ぜひ一度お試しください。