Kubernetes 1.12にmetrics-serverをインストール

[前回、Kubernetes 1.12環境にIngress Controllerをインストールして](https://qiita.com/rk05231977/items/146e1e13e877874f06a2)、サンプルアプリケーションもデプロイしてみたが、気になるのは現在のリソース使用状況。

kubeadmから素でKubernetesインストールするとHeapsterもmetrics-serverも導入されないのでkubectl topコマンドは何も状況を返してくれない。

```
# kubectl top node
Error from server (NotFound): the server could not find the requested resource (get services http:heapster:)
root@m16:~# kubectl top pod
Error from server (NotFound): the server could not find the requested resource (get services http:heapster:)
```

従って、今回はとりあえずmetrics-serverを導入したい。なお、HeapsterはKubernetes 1.11でDeprecateされた。Prometheus対応が難しいとかそんな理由。
https://github.com/kubernetes/heapster/blob/master/docs/deprecation.md

現時点で、Kubernetes Dashboardがmetrics-server未対応でリソース使用率が表示されないとかいう問題はあるらしいが、まあ近いうちに解消されるだろう。個人的にはDashboard使わないし無問題。
https://github.com/kubernetes/dashboard/issues/2986

#metrics-serverの導入
さっそく以下のURLを参考しつつ導入。
https://github.com/kubernetes-incubator/metrics-server
まずはGitHubからマニフェストファイル一式を取ってきて、デプロイ。

```bash
git clone https://github.com/kubernetes-incubator/metrics-server
kubectl create -f metrics-server/deploy/1.8+/
```

さて、これでkubectl top用のmetricsが収集され始めるかというとさにあらず。

```
# kubectl top node
error: metrics not available yet
# kubectl top pod
W0929 21:07:59.456361   24148 top_pod.go:263] Metrics not available for pod default/my-db-f55786649-ppfl5, age: 3h50m57.456303002s
error: Metrics not available for pod default/my-db-f55786649-ppfl5, age: 3h50m57.456303002s
```

metrics-serverのログを見ると以下のとおりであり、"x509: certificate signed by unknown authority"ということである。

```
# kubectl logs -n kube-system metrics-server-7df4c4484d-h5mhj
E0929 12:08:04.472964       1 manager.go:102] unable to fully collect metrics: [unable to fully scrape metrics from source kubelet_summary:192.168.0.133: unable to fetch metrics from Kubelet 192.168.0.133 (192.168.0.133): Get https://192.168.0.133:10250/stats/summary/: x509: certificate signed by unknown authority, unable to fully scrape metrics from source kubelet_summary:192.168.0.132: unable to fetch metrics from Kubelet 192.168.0.132 (192.168.0.132): Get https://192.168.0.132:10250/stats/summary/: x509: certificate signed by unknown authority, unable to fully scrape metrics from source kubelet_summary:192.168.0.131: unable to fetch metrics from Kubelet 192.168.0.131 (192.168.0.131): Get https://192.168.0.131:10250/stats/summary/: x509: certificate signed by unknown authority]
E0929 12:08:16.291804       1 reststorage.go:101] unable to fetch node metrics for node "192.168.0.131": no metrics known for node "192.168.0.131"
E0929 12:08:16.291857       1 reststorage.go:101] unable to fetch node metrics for node "192.168.0.132": no metrics known for node "192.168.0.132"
E0929 12:08:16.291864       1 reststorage.go:101] unable to fetch node metrics for node "192.168.0.133": no metrics known for node "192.168.0.133"
...
```

ノード登録する際にkubeadmの--node-nameオプションでノードのIPアドレスを指定しているため、それに接続しにいっているっぽいのは狙い通りで良い。
k8s 1.12でkubeletが証明書を自動的に生成してなんとかいうことだったのでここら辺も上手いこと行くようになったのかちょっと期待したのだけど、そんなことは無かった。
しゃーないので起動オプションに--kubelet-insecure-tlsオプションを追加。

```
kubectl edit deploy -n kube-system metrics-server
---
(変更前)
 37     spec:
 38       containers:
 39       - image: k8s.gcr.io/metrics-server-amd64:v0.3.0
 40         imagePullPolicy: Always
(変更後)
 37     spec:
 38       containers:
 39       - image: k8s.gcr.io/metrics-server-amd64:v0.3.0
 40         command:
 41         - /metrics-server
 42         - --kubelet-insecure-tls
 43         imagePullPolicy: Always
```

変更後のmetrics-serverのログは以下。

```
# kubectl logs -n kube-system metrics-server-6985c94f4b-w79c9
I0929 12:19:13.301994       1 serving.go:273] Generated self-signed cert (apiserver.local.config/certificates/apiserver.crt, apiserver.local.config/certificates/apiserver.key)
[restful] 2018/09/29 12:19:13 log.go:33: [restful/swagger] listing is available at https://:443/swaggerapi
[restful] 2018/09/29 12:19:13 log.go:33: [restful/swagger] https://:443/swaggerui/ is mapped to folder /swagger-ui/
I0929 12:19:13.845362       1 serve.go:96] Serving securely on [::]:443
root@m16:~#
```

しばらくするとkubectl topコマンドにそれらしい内容が表示され始める。

```
~# kubectl top node
NAME            CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%
192.168.0.131   370m         18%    858Mi           22%
192.168.0.132   163m         8%     613Mi           32%
192.168.0.133   156m         7%     587Mi           31%
# kubectl top pod --all-namespaces
NAMESPACE       NAME                                    CPU(cores)   MEMORY(bytes)
default         my-db-f55786649-ppfl5                   2m           131Mi
default         my-node-54d74b647-4spfm                 0m           13Mi
default         my-node-54d74b647-5896h                 0m           12Mi
default         my-node-54d74b647-lsh6l                 0m           12Mi
ingress-nginx   default-http-backend-6d6985d9d4-hv9dk   1m           4Mi
ingress-nginx   nginx-ingress-controller-j6fjn          21m          116Mi
ingress-nginx   nginx-ingress-controller-pjxkc          22m          104Mi
kube-system     calico-node-d2mmz                       29m          70Mi
kube-system     calico-node-f6qs4                       36m          103Mi
kube-system     calico-node-xfvtz                       35m          99Mi
kube-system     coredns-576cbf47c7-dtxwp                0m           0Mi
kube-system     coredns-576cbf47c7-kmt2m                0m           0Mi
kube-system     etcd-192.168.0.131                      64m          61Mi
kube-system     kube-apiserver-192.168.0.131            96m          393Mi
kube-system     kube-controller-manager-192.168.0.131   66m          70Mi
kube-system     kube-proxy-85m57                        5m           18Mi
kube-system     kube-proxy-94nsk                        8m           18Mi
kube-system     kube-proxy-bqvwd                        8m           16Mi
kube-system     kube-scheduler-192.168.0.131            14m          11Mi
kube-system     metrics-server-6985c94f4b-xfcb4         2m           13Mi
```

ところで、corednsがCrashLoopBackOffになり始めた。。

```
# kubectl get pod -n kube-system
NAME                                    READY   STATUS             RESTARTS   AGE
calico-node-d2mmz                       2/2     Running            0          20h
calico-node-f6qs4                       2/2     Running            4          19h
calico-node-xfvtz                       2/2     Running            12         19h
coredns-576cbf47c7-dtxwp                0/1     CrashLoopBackOff   234        20h
coredns-576cbf47c7-kmt2m                0/1     CrashLoopBackOff   234        20h
etcd-192.168.0.131                      1/1     Running            0          20h
kube-apiserver-192.168.0.131            1/1     Running            0          20h
kube-controller-manager-192.168.0.131   1/1     Running            0          20h
kube-proxy-85m57                        1/1     Running            6          19h
kube-proxy-94nsk                        1/1     Running            2          19h
kube-proxy-bqvwd                        1/1     Running            0          20h
kube-scheduler-192.168.0.131            1/1     Running            0          20h
metrics-server-6985c94f4b-w79c9         1/1     Running            0          12m
```

たぶん以下のissueと同じ事象。相変わらずDNS関連不安定だな。
https://github.com/coredns/coredns/issues/2087

・・・と思ったら違う理由。calicoの導入時にCALICO_IPV4POOL_CIDRの値をデフォルトの192.168.0.0/16のままにしていたのが原因らしい。それを修正するためにKubernetesを再インストール。
なお、現在のcalicoのIPv4 Pool設定は、[calicoctlコマンドを導入し](https://github.com/projectcalico/calicoctl/releases/tag/v3.2.3)、以下のコマンドを実行して確認できる。

```
# DATASTORE_TYPE=kubernetes KUBECONFIG=~/.kube/config calicoctl get ipPool default-ipv4-ippool
NAME                  CIDR
default-ipv4-ippool   10.0.0.0/16
```

再インストール後は正常。

```
# kubectl get pod --all-namespaces                                                            NAMESPACE       NAME                                    READY   STATUS    RESTARTS   AGE
default         my-db-f55786649-pznng                   1/1     Running   0          23m
default         my-node-7488b97dd8-56wk6                1/1     Running   0          20m
default         my-node-7488b97dd8-9btbs                1/1     Running   1          20m
ingress-nginx   default-http-backend-6d6985d9d4-qwhwn   1/1     Running   0          25m
ingress-nginx   nginx-ingress-controller-2s4d4          1/1     Running   0          25m
ingress-nginx   nginx-ingress-controller-7t4zj          1/1     Running   0          25m
kube-system     calico-node-gxpkn                       2/2     Running   0          31m
kube-system     calico-node-nxnn9                       2/2     Running   0          28m
kube-system     calico-node-wjzzv                       2/2     Running   0          27m
kube-system     coredns-576cbf47c7-dqwkv                1/1     Running   0          38m
kube-system     coredns-576cbf47c7-n2vtz                1/1     Running   0          38m
kube-system     etcd-192.168.0.131                      1/1     Running   0          37m
kube-system     kube-apiserver-192.168.0.131            1/1     Running   0          38m
kube-system     kube-controller-manager-192.168.0.131   1/1     Running   0          38m
kube-system     kube-proxy-lhjb9                        1/1     Running   0          38m
kube-system     kube-proxy-vbh4p                        1/1     Running   0          28m
kube-system     kube-proxy-vrvkm                        1/1     Running   0          27m
kube-system     kube-scheduler-192.168.0.131            1/1     Running   0          38m
kube-system     metrics-server-6985c94f4b-t8b2c         1/1     Running   0          16m
```

corednsがCrashLoopBackOffになる以外に、例えばmetrics-serverのPodにexec -it...shでログインしてデフォルトゲートウェイ（192.168.0.1）にpingを打っても通らないとかいう不具合が有り、ネットワークドライバの問題か？と思い至った次第。

いやはや。