Kubernetesのmetrics-serverを構築する

#はじめに
Kubernetesのクラスタのリソースを取得するのにmetrics-serverが必要になる。
kubeadmでKubernetesをインストールすると、metrics-serverはインストールされないので、別途インストールする。
これをインストールすると、「kubectl top」コマンドが使用できるようになる。

Kubernetesのバージョンは以下。

```
$ kubectl version --short
Client Version: v1.17.3
Server Version: v1.17.3
```

#コードのダウンロード
[ここ](https://github.com/kubernetes-sigs/metrics-server) からmetrics-serverのコードをmasterノードにダウンロードする。


```
$ git clone https://github.com/kubernetes-sigs/metrics-server
Cloning into 'metrics-server'...
remote: Enumerating objects: 16, done.
remote: Counting objects: 100% (16/16), done.
remote: Compressing objects: 100% (16/16), done.
remote: Total 11718 (delta 1), reused 7 (delta 0), pack-reused 11702
Receiving objects: 100% (11718/11718), 12.34 MiB | 1.48 MiB/s, done.
Resolving deltas: 100% (6102/6102), done.
```

#デプロイ

READMEに沿ってデプロイする。

```
$ cd metrics-server/
$ kubectl create -f deploy/kubernetes/
clusterrole.rbac.authorization.k8s.io/system:aggregated-metrics-reader created
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
deployment.apps/metrics-server created
service/metrics-server created
clusterrole.rbac.authorization.k8s.io/system:metrics-server created
clusterrolebinding.rbac.authorization.k8s.io/system:metrics-server created
```

Podがデプロイされていることを確認し、kubectl topコマンドの動作を確認する。

```
$ kubectl -n kube-system get pod | grep metric
metrics-server-5cc8d5c4df-cbwx5           1/1     Running   0          95s
$ kubectl top node
error: metrics not available yet
```
metricsの収集に時間がかかるので、少し待ってみたが「まだ使えない」状態が続く。

#調査と修正
とりあえず、Podの詳細を確認する。

```
$ kubectl -n kube-system describe pod metrics-server-5cc8d5c4df-cbwx5
・・・
Events:
  Type    Reason     Age    From                   Message
  ----    ------     ----   ----                   -------
  Normal  Scheduled  2m30s  default-scheduler      Successfully assigned kube-system/metrics-server-5cc8d5c4df-cbwx5 to k8s-worker02
  Normal  Pulled     2m28s  kubelet, k8s-worker02  Container image "k8s.gcr.io/metrics-server-amd64:v0.3.6" already present on machine
  Normal  Created    2m28s  kubelet, k8s-worker02  Created container metrics-server
  Normal  Started    2m27s  kubelet, k8s-worker02  Started container metrics-server
```
問題なさそう。
次にログを確認する。

```
$ kubectl -n kube-system logs metrics-server-5cc8d5c4df-cbwx5
I0303 12:34:22.007118       1 serving.go:312] Generated self-signed cert (/tmp/apiserver.crt, /tmp/apiserver.key)
I0303 12:34:22.811469       1 secure_serving.go:116] Serving securely on [::]:4443
E0303 12:35:23.086889       1 manager.go:111] unable to fully collect metrics: [unable to fully scrape metrics from source kubelet_summary:k8s-worker01: unable to fetch metrics from Kubelet k8s-worker01 (k8s-worker01): Get https://k8s-worker01:10250/stats/summary?only_cpu_and_memory=true: dial tcp: lookup k8s-worker01 on 10.96.0.10:53: no such host, unable to fully scrape metrics from source kubelet_summary:k8s-master: unable to fetch metrics from Kubelet k8s-master (k8s-master): Get https://k8s-master:10250/stats/summary?only_cpu_and_memory=true: dial tcp: lookup k8s-master on 10.96.0.10:53: no such host, unable to fully scrape metrics from source kubelet_summary:k8s-worker02: unable to fetch metrics from Kubelet k8s-worker02 (k8s-worker02): Get https://k8s-worker02:10250/stats/summary?only_cpu_and_memory=true: dial tcp: lookup k8s-worker02 on 10.96.0.10:53: no such host]
・・・・
```
このエラーが何度も出ている。どうもメトリクスの収集ができていないみたい。
調べてみると、以下の内容と同じらしい。Deploymentのyamlファイルに追記が必要らしい。

[Metrics not available in Kubernetes 1.16 : kubectl top pods result in error #300](https://github.com/kubernetes-sigs/metrics-server/issues/300)

##yamlファイルの修正
metrics-server-deployment.yamlファイルに「command:」以下の4行を追記する。

```deploy/kubernetes/metrics-server-deployment.yaml
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: metrics-server
  namespace: kube-system
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: metrics-server
  namespace: kube-system
  labels:
    k8s-app: metrics-server
spec:
  selector:
    matchLabels:
      k8s-app: metrics-server
  template:
    metadata:
      name: metrics-server
      labels:
        k8s-app: metrics-server
    spec:
      serviceAccountName: metrics-server
      volumes:
      # mount in tmp so we can safely use from-scratch images and/or read-only containers
      - name: tmp-dir
        emptyDir: {}
      containers:
      - name: metrics-server
        image: k8s.gcr.io/metrics-server-amd64:v0.3.6
        args:
          - --cert-dir=/tmp
          - --secure-port=4443
        ports:
        - name: main-port
          containerPort: 4443
          protocol: TCP
        securityContext:
          readOnlyRootFilesystem: true
          runAsNonRoot: true
          runAsUser: 1000
        imagePullPolicy: IfNotPresent
        command: #added
        - /metrics-server #added
        - --kubelet-insecure-tls #added
        - --kubelet-preferred-address-types=InternalIP #added
        volumeMounts:
        - name: tmp-dir
          mountPath: /tmp
      nodeSelector:
        beta.kubernetes.io/os: linux
        kubernetes.io/arch: "amd64"
```

##Podの再作成
修正したyamlファイルをapplyする。

```
$ kubectl apply -f deploy/kubernetes/metrics-server-deployment.yaml
serviceaccount/metrics-server unchanged
deployment.apps/metrics-server configured
$ kubectl -n kube-system get pod | grep metrics
metrics-server-fbc46dc5f-9k6kt            1/1     Running   0          33s
```

#動作確認
すぐに実行しても「まだ使えない」と言われるので、数分待ってから実行する。

```
$ kubectl top node
NAME           CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%
k8s-master     396m         19%    1036Mi          37%
k8s-worker01   884m         44%    1762Mi          64%
k8s-worker02   686m         34%    1522Mi          55%
$ kubectl -n sock-shop top pods
NAME                            CPU(cores)   MEMORY(bytes)
carts-5fc45568c4-r4fqk          90m          298Mi
carts-db-64ff6c747f-vlghp       49m          143Mi
catalogue-69b7ff5bb4-pm988      15m          7Mi
catalogue-db-69cf48ff8-5sztl    12m          242Mi
front-end-6fc8dff6ff-4lxmn      281m         126Mi
orders-74c6b45f4f-42rns         50m          304Mi
orders-db-df75f545f-vvth6       11m          124Mi
payment-7f95f9f77-n5v7p         4m           6Mi
queue-master-85f5644bf5-pgdkt   18m          267Mi
rabbitmq-c7b9db6cc-bb5hn        11m          101Mi
session-db-67fd8d6d7-f2s96      8m           10Mi
shipping-745b9d8755-nvqng       45m          294Mi
user-559d7f794f-65sxs           46m          7Mi
user-db-87f548457-ldqvh         28m          37Mi
```

#まとめ
これでkubenetesクラスタのリソース確認ができるようになったので、オートスケールの動作確認時にリソースを確認しながら使ってみよう。

今回のエラーが環境に固有のものなのかはわからないので、宿題として覚えておこう。
宿題が増える。。。