Kubernetes クラスタに ElasticStack を ECK で入れてログメトリクス表示環境を構築

## はじめに
オンプレで Kubernetes クラスタを構築するにあたり、ログメトリクス表示環境を ElasticStack で実施してみた。
ElasticStack の Kubernetes Operator / CRD である Elastic Cloud on Kubernetes (ECK) が [1.0 でリリース(2020.01.16)](https://www.elastic.co/jp/blog/elastic-cloud-on-kubernetes-ECK-is-now-generally-available?blade=tw&hulk=social) されたので ECK による構築を実施した。
Beats に関しては ECK ではカバーされていないので、マニフェストを作成して構築した。

例えば、Kubernetes クラスタ上にある Pod のログ表示は、
全体の Pod から (CPU利用率などが高いものをみて) クリックして Pod 単位で見ることが可能になる。
![kibana_metrics_pods_logs2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326183/f1871a5d-369b-f566-9413-2da3482a2b7c.gif)

上記の他にも、最後に Kibana での表示確認結果も Gif or 画像で複数載せてみた。


## Elastic Cloud on Kubernetes / 動作環境
Elastic Cloud on Kubernetes (ECK) および動作環境については下記に動作含めまとめている。

https://qiita.com/suzuyui/items/365fa09fc7c065fa642d

### Version

ElasticStack : 7.6.0
ECK : 1.0.1
Kubernetes : 1.16.3
kube-state-metrics : 1.9.4

## 構成全体概要図
リソース全体の整理のために全体の概要図を記載する。 (ServiceAccount, Role, ConfigMap など一部は省略している)

![elasticstack-k8s.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326183/c726010e-d1a5-8110-287c-c683722c5be6.png)


これから作成するマニフェスト別に整理すると下記のようになる。

![elasticstack-k8s_manifest.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326183/1d20597d-4206-866b-3578-b82db212f650.png)

今回は赤文字のマニフェストを作成する。
PV 作成 (iscsi-pv.yaml) や iSCSI 設定ついては [QNAP での PV 作成](https://qiita.com/suzuyui/items/0efa505f3db03390f181)や [ECK のオンプレ動作確認時](https://qiita.com/suzuyui/items/365fa09fc7c065fa642d)に記載した通りなので省略する。

## 構築ステップ

下記のステップで構築していく。

1. namespace の構築
2. ECK の導入
3. Elasticsearch の構築
4. Kibana の構築
5. filebeat の構築
6. metricbeat の構築
7. auditbeat の構築

 - 1. ~ 2. : 今回 ElasticStack 配置の namespaceの作成. ECK Operator の構築
 - 3. ~ 4. : Elasticsearch / Kibana 環境の構築
 - 5. ~ 6. : 今回構築する 3種の beats の構築

## 1. namespace の構築
namespace は default と分けて elastic-monitoring で作成する。
これは default や kube-system とは分けておきたいため。

```elastic-namespace.yaml
kind: Namespace
apiVersion: v1
metadata:
  name: elastic-monitoring
  labels:
    name: elastic-monitoring
```

上記マニフェストを適用して namespace を作成する。

```
$ kubectl apply -f elastic-namespace.yaml 
namespace/elastic-monitoring created
```

## 2. ECK の導入

ECK を導入する。これで Elasticsearch/Kibana/ApmServer の CRD や Operator などが構築される。
(詳細は [ECK オンプレ動作確認](https://qiita.com/suzuyui/items/365fa09fc7c065fa642d) に記載しているのでそちらを参照. Versionのみ異なる(記載時の最新版を適応))

```
$ curl -OL https://download.elastic.co/downloads/eck/1.0.1/all-in-one.yaml
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 93520  100 93520    0     0  94865      0 --:--:-- --:--:-- --:--:-- 94847

$ kubectl apply -f all-in-one.yaml 
customresourcedefinition.apiextensions.k8s.io/apmservers.apm.k8s.elastic.co created
customresourcedefinition.apiextensions.k8s.io/elasticsearches.elasticsearch.k8s.elastic.co created
customresourcedefinition.apiextensions.k8s.io/kibanas.kibana.k8s.elastic.co created
clusterrole.rbac.authorization.k8s.io/elastic-operator created
clusterrolebinding.rbac.authorization.k8s.io/elastic-operator created
namespace/elastic-system created
statefulset.apps/elastic-operator created
serviceaccount/elastic-operator created
validatingwebhookconfiguration.admissionregistration.k8s.io/elastic-webhook.k8s.elastic.co created
service/elastic-webhook-server created
secret/elastic-webhook-server-cert created

$ kubectl get po -n elastic-system
NAME                 READY   STATUS    RESTARTS   AGE
elastic-operator-0   1/1     Running   1          3m13s
```


## 3. Elasticsearch の構築

Elasticsearch クラスタを作成する。
(詳細は [ECK オンプレ動作確認](https://qiita.com/suzuyui/items/365fa09fc7c065fa642d) に記載している.namespace, name を今回ように書き換えているのみ。)
(StorageClass: standard, storageサイズ 50Gi が用意されていることが前提.詳細は [ECK オンプレ動作確認](https://qiita.com/suzuyui/items/365fa09fc7c065fa642d)参照)

```elasticsearch.yaml
apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
  name: monitoring-elasticsearch
  namespace: elastic-monitoring
spec:
  version: 7.6.0
  nodeSets:
  - name: master-data
    count: 3
    config:
      node.master: true
      node.data: true
      node.ingest: true
      node.store.allow_mmap: false
    volumeClaimTemplates:
    - metadata:
        name: elasticsearch-data
      spec:
        accessModes:
        - ReadWriteOnce
        resources:
          requests:
            storage: 50Gi
        storageClassName: standard
```

上記 yaml の apply を実施する。

```
$ kubectl apply -f elasticsearch.yaml 
elasticsearch.elasticsearch.k8s.elastic.co/monitoring-elasticsearch created

$ kubectl get po -n elastic-monitoring
NAME                                        READY   STATUS    RESTARTS   AGE
monitoring-elasticsearch-es-master-data-0   1/1     Running   0          53s
monitoring-elasticsearch-es-master-data-1   1/1     Running   0          53s
monitoring-elasticsearch-es-master-data-2   1/1     Running   0          52s

$ kubectl get es -n elastic-monitoring
NAME                       HEALTH   NODES   VERSION   PHASE   AGE
monitoring-elasticsearch   green    3       7.6.0     Ready   79s
```

## 4. Kibana の構築

Kibana を構築する。
(詳細は [ECK オンプレ動作確認](https://qiita.com/suzuyui/items/365fa09fc7c065fa642d) に記載している.namespace, name を今回ように書き換えているのみ。)

```kibana.yaml
apiVersion: kibana.k8s.elastic.co/v1
kind: Kibana
metadata:
  name: monitoring-kibana
  namespace: elastic-monitoring
spec:
  version: 7.6.0
  count: 1
  elasticsearchRef:
    name: monitoring-elasticsearch
```

上記 yaml を apply する。

```
$ kubectl apply -f kibana.yaml 
kibana.kibana.k8s.elastic.co/monitoring-kibana created

$ kubectl get kibana -n elastic-monitoring
NAME                HEALTH   NODES   VERSION   AGE
monitoring-kibana   green    1       7.6.0     117s
```

ログイン用パスワード取得。

```
$ kubectl get secret monitoring-elasticsearch-es-elastic-user -n elastic-monitoring -o=jsonpath='{.data.elastic}' | base64 --decode; echo
s2gqmsd5vxbknqlqpvsjmztg
```

ポートフォワード実施。

```
$ kubectl port-forward service/monitoring-kibana-kb-http 5601 -n elastic-monitoring
Forwarding from 127.0.0.1:5601 -> 5601
Forwarding from [::1]:5601 -> 5601
```

`https://127.0.0.1:5601` でブラウザでの表示・username:`elastic` passowrd: `上記で取得したパスワード(例だと: s2gqmsd5vxbknqlqpvsjmztg)`ログイン可能。
(この時点でのログイン、画像での例などは [ECK オンプレ動作確認](https://qiita.com/suzuyui/items/365fa09fc7c065fa642d) に記載している.)


## 5. filebeat の構築
ログ取得のため filebeat を導入する。
elastic公式に用意している kubernetes 用の yaml を元に変更する。

ベースとなる yaml をダウンロード。

```
curl -L -O https://raw.githubusercontent.com/elastic/beats/7.6/deploy/kubernetes/filebeat-kubernetes.yaml
```

下記に変更していく。

### 5.1 namespace の変更
デフォルトでは`kube-system`が指定されているので、`elastic-monitoring`に変更する。

```
$ sed -e 's/namespace: kube-system/namespace: elastic-monitoring/g' filebeat-kubernetes.yaml > filebeat.yaml 
```

### 5.2 Elasticsearch/Kibana host指定, 認証の追加, secret の参照追加
ECK によって、Elasticsearch, Kibana のService, Secret が作成されているのでそれらを指定する。

 - elasticsearch
    - Service: `monitoring-elasticsearch-es-http`
        - [name]-es-http で作成される
    - Secret: `monitoring-elasticsearch-es-http-certs-public`
        - [name]-es-http-certs-public で作成される
 - kibana
    - Service: `monitoring-kibana-kb-http`
        - [name]-kb-http で作成される
    - Secret: `monitoring-kibana-kb-http-certs-public`
        - [name]-kb-http-certs-public で作成される

#### DaemonSet
```beats_daemonset_認証抜粋.yaml
        env:
        - name: ELASTICSEARCH_HOST
          value: monitoring-elasticsearch-es-http
        - name: ELASTICSEARCH_PORT
          value: "9200"
        - name: ELASTICSEARCH_USERNAME
          value: elastic
        - name: ELASTICSEARCH_PASSWORD
          valueFrom:
            secretKeyRef:
              key: elastic
              name: monitoring-elasticsearch-es-elastic-user
        - name: KIBANA_HOST
          value: monitoring-kibana-kb-http
~~中略~~
        volumeMounts:
~~中略~~
        - name: es-certs
          mountPath: /mnt/elastic/tls.crt
          readOnly: true
          subPath: tls.crt
        - name: kb-certs
          mountPath: /mnt/kibana/tls.crt
          readOnly: true
          subPath: tls.crt
~~中略~~
      volumes:
~~中略~~
      - name: es-certs
        secret:
          secretName: monitoring-elasticsearch-es-http-certs-public
      - name: kb-certs
        secret:
          secretName: monitoring-kibana-kb-http-certs-public
```
#### ConfigMap
```beats_configMap_認証抜粋.yaml
data:
  filebeat.yml: |-
~~中略~~
    output.elasticsearch:
      hosts: ['https://${ELASTICSEARCH_HOST:elasticsearch}:${ELASTICSEARCH_PORT:9200}']
      username: ${ELASTICSEARCH_USERNAME}
      password: ${ELASTICSEARCH_PASSWORD}
      ssl.certificate_authorities:
      - /mnt/elastic/tls.crt

    setup.dashboards.enabled: true

    setup.kibana:
      host: "https://${KIBANA_HOST}:5601"
      username: ${ELASTICSEARCH_USERNAME}
      password: ${ELASTICSEARCH_PASSWORD}
      protocol: "https"
      ssl.certificate_authorities:
        - /mnt/kibana/tls.crt
```

### 5.3 tolerations 追加で master node からも取得
MasterNode のデータも取得したいので、tolerations を設定する。
#### DaemonSet
```beats_daemonset_tolerations抜粋.yaml
    spec:
      tolerations:
        - key: node-role.kubernetes.io/master
          effect: NoSchedule
```

### 5.4 autodiscover
kubernetes 用の autodiscover 機能があるので有効化する。
#### ConfigMap
デフォルトにコメントがある通り、filebeat.inputをコメントアウト(remove)して、コメントアウトされているfilebeat.autodiscoverをコメント解除する

```beats_configMap_autodiscover抜粋.yaml
  filebeat.yml: |-
    # filebeat.inputs:
    # - type: container
    #   paths:
    #     - /var/log/containers/*.log
    #   processors:
    #     - add_kubernetes_metadata:
    #         host: ${NODE_NAME}
    #         matchers:
    #         - logs_path:
    #             logs_path: "/var/log/containers/"

    # To enable hints based autodiscover, remove `filebeat.inputs` configuration and uncomment this:
    filebeat.autodiscover:
      providers:
       - type: kubernetes
         host: ${NODE_NAME}
         hints.enabled: true
         hints.default_config:
           type: container
           paths:
             - /var/log/containers/*${data.kubernetes.container.id}.log
```

### 5.5 module 追加
syslog, auth の module を追加する。

#### ConfigMap

```beats_configMap_modules抜粋.yaml
  filebeat.yml: |-
~~中略~~
    filebeat.config:
      modules:
        path: ${path.config}/modules.d/*.yml
        reload.enabled: false

    filebeat.modules:
      - module: system
        syslog:
          enabled: true
          var.paths: ["/var/log/messages"]
          var.convert_timezone: true
        auth:
          enabled: true
          var.paths: ["/var/log/secure"]
          var.convert_timezone: true
```

### 5.6 timezone の適応
このままだと、UTC の Timezone になってしまうので、サーバの localtime をマウントして JST を反映させる
(ただ Kibana 表示方法によって UTCtime で Now が表示されたり。。。これは改良の余地あり)

#### ConfigMap

```beats_configMap_localtime抜粋.yaml
  filebeat.yml: |-
~~中略~~
    spec:
        volumeMounts:
        - name: localtime
          mountPath: /etc/localtime
          readOnly: true
~~中略~~
      volumes:
      - name: localtime
        hostPath:
          path: /etc/localtime
          type: File
```

### 5.7 変更後のyaml. 適応

これまでの変更を適応した yaml が下記の通り。

```filebeat.yaml
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: filebeat-config
  namespace: elastic-monitoring
  labels:
    k8s-app: filebeat
data:
  filebeat.yml: |-
    # filebeat.inputs:
    # - type: container
    #   paths:
    #     - /var/log/containers/*.log
    #   processors:
    #     - add_kubernetes_metadata:
    #         host: ${NODE_NAME}
    #         matchers:
    #         - logs_path:
    #             logs_path: "/var/log/containers/"

    # To enable hints based autodiscover, remove `filebeat.inputs` configuration and uncomment this:
    filebeat.autodiscover:
     providers:
       - type: kubernetes
         node: ${NODE_NAME}
         hints.enabled: true
         hints.default_config:
           type: container
           paths:
             - /var/log/containers/*${data.kubernetes.container.id}.log

    processors:
      - add_cloud_metadata:
      - add_host_metadata:
      - add_locale: ~

    cloud.id: ${ELASTIC_CLOUD_ID}
    cloud.auth: ${ELASTIC_CLOUD_AUTH}

    output.elasticsearch:
      hosts: ['https://${ELASTICSEARCH_HOST:elasticsearch}:${ELASTICSEARCH_PORT:9200}']
      username: ${ELASTICSEARCH_USERNAME}
      password: ${ELASTICSEARCH_PASSWORD}
      ssl.certificate_authorities:
      - /mnt/elastic/tls.crt

    setup.dashboards.enabled: true

    setup.kibana:
      host: "https://${KIBANA_HOST}:5601"
      username: ${ELASTICSEARCH_USERNAME}
      password: ${ELASTICSEARCH_PASSWORD}
      protocol: "https"
      ssl.certificate_authorities:
        - /mnt/kibana/tls.crt

    filebeat.config:
      modules:
        path: ${path.config}/modules.d/*.yml
        reload.enabled: false

    filebeat.modules:
      - module: system
        syslog:
          enabled: true
          var.paths: ["/var/log/messages"]
          var.convert_timezone: true
        auth:
          enabled: true
          var.paths: ["/var/log/secure"]
          var.convert_timezone: true
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: filebeat
  namespace: elastic-monitoring
  labels:
    k8s-app: filebeat
spec:
  selector:
    matchLabels:
      k8s-app: filebeat
  template:
    metadata:
      labels:
        k8s-app: filebeat
    spec:
      tolerations:
        - key: node-role.kubernetes.io/master
          effect: NoSchedule
      serviceAccountName: filebeat
      terminationGracePeriodSeconds: 30
      hostNetwork: true
      dnsPolicy: ClusterFirstWithHostNet
      containers:
      - name: filebeat
        image: docker.elastic.co/beats/filebeat:7.6.0
        args: [
          "-c", "/etc/filebeat.yml",
          "-e",
        ]
        env:
        - name: ELASTICSEARCH_HOST
          value: monitoring-elasticsearch-es-http
        - name: ELASTICSEARCH_PORT
          value: "9200"
        - name: ELASTICSEARCH_USERNAME
          value: elastic
        - name: ELASTICSEARCH_PASSWORD
          valueFrom:
            secretKeyRef:
              key: elastic
              name: monitoring-elasticsearch-es-elastic-user
        - name: KIBANA_HOST
          value: monitoring-kibana-kb-http
        - name: ELASTIC_CLOUD_ID
          value:
        - name: ELASTIC_CLOUD_AUTH
          value:
        - name: NODE_NAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        securityContext:
          runAsUser: 0
          # If using Red Hat OpenShift uncomment this:
          #privileged: true
        resources:
          limits:
            memory: 200Mi
          requests:
            cpu: 100m
            memory: 100Mi
        volumeMounts:
        - name: config
          mountPath: /etc/filebeat.yml
          readOnly: true
          subPath: filebeat.yml
        - name: data
          mountPath: /usr/share/filebeat/data
        - name: varlibdockercontainers
          mountPath: /var/lib/docker/containers
          readOnly: true
        - name: varlog
          mountPath: /var/log
          readOnly: true
        - name: es-certs
          mountPath: /mnt/elastic/tls.crt
          readOnly: true
          subPath: tls.crt
        - name: kb-certs
          mountPath: /mnt/kibana/tls.crt
          readOnly: true
          subPath: tls.crt
        - name: localtime
          mountPath: /etc/localtime
          readOnly: true
      volumes:
      - name: config
        configMap:
          defaultMode: 0600
          name: filebeat-config
      - name: varlibdockercontainers
        hostPath:
          path: /var/lib/docker/containers
      - name: varlog
        hostPath:
          path: /var/log
      # data folder stores a registry of read status for all files, so we don't send everything again on a Filebeat pod restart
      - name: data
        hostPath:
          path: /var/lib/filebeat-data
          type: DirectoryOrCreate
      - name: es-certs
        secret:
          secretName: monitoring-elasticsearch-es-http-certs-public
      - name: kb-certs
        secret:
          secretName: monitoring-kibana-kb-http-certs-public
      - name: localtime
        hostPath:
          path: /etc/localtime
          type: File
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: filebeat
subjects:
- kind: ServiceAccount
  name: filebeat
  namespace: elastic-monitoring
roleRef:
  kind: ClusterRole
  name: filebeat
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: filebeat
  labels:
    k8s-app: filebeat
rules:
- apiGroups: [""] # "" indicates the core API group
  resources:
  - namespaces
  - pods
  verbs:
  - get
  - watch
  - list
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: filebeat
  namespace: elastic-monitoring
  labels:
    k8s-app: filebeat
---
```

上記 yaml を apply する。

```
$ kubectl apply -f filebeat.yaml 
configmap/filebeat-config created
daemonset.apps/filebeat created
clusterrolebinding.rbac.authorization.k8s.io/filebeat created
clusterrole.rbac.authorization.k8s.io/filebeat created
serviceaccount/filebeat created

$ kubectl get po -n elastic-monitoring | grep filebeat
filebeat-4gqlc                              1/1     Running   3          83s
filebeat-h2zh2                              1/1     Running   3          83s
filebeat-lmb4f                              1/1     Running   3          83s
filebeat-ngfrx                              1/1     Running   3          83s
filebeat-ngnwt                              1/1     Running   3          83s
filebeat-pmjdh                              1/1     Running   0          83s
filebeat-tk4g6                              1/1     Running   0          83s
filebeat-xwxv6                              1/1     Running   0          83s
```

## 6. metricbeat の構築
メトリクス取得のため metricbeat を導入する。
metricbeat は前提として kube-state-metrics が必要なため、そちらも導入する。

elastic公式に用意している kubernetes 用の yaml を元に変更する。

ベースとなる yaml をダウンロード。

```
curl -L -O https://raw.githubusercontent.com/elastic/beats/7.6/deploy/kubernetes/metricbeat-kubernetes.yaml
```

下記に変更していく。

### 6.0 kube-state-metrics

kube-state-metrics を Github から clone する。


```
git clone https://github.com/kubernetes/kube-state-metrics.git
```

サンプルマニフェストをコピーする。

```
cp -Rp kube-state-metrics/examples/standard/ elastic-kube-state-metrics
```

コピーした下記4ファイルの namespace を修正します。

 - 変更箇所
    - `namespace: kube-system` -> `namespace: elastic-monitoring`

```
$ sed -i -e 's/namespace: kube-system/namespace: elastic-monitoring/g' elastic-kube-state-metrics/*.yaml
```


#### kube-state-metrics name変更 (2020.03.14更新)

このままだと、Prometheus を kube-prometheus などで入れる際に入れる、kube-state-metrics と、
namespacesが関係ない clusterrolebinding と clusterrole が同じものになってしまい、どちらかの削除で消えたりもする。
影響回避するために、kube-state-metrics の名前を変更する

 - 変更箇所
    - `kube-state-metrics` -> `elastic-kube-state-metrics`
        - ただし、イメージ名は `kube-state-metrics` のまま

```
$ sed -i -e 's/kube-state-metrics/elastic-kube-state-metrics/g' elastic-kube-state-metrics/*.yaml
$ sed -i -e 's/quay.io\/coreos\/elastic-kube-state-metrics/quay.io\/coreos\/kube-state-metrics/g' elastic-kube-state-metrics/deployment.yaml
```


変更後、 フォルダまるごと apply して elastic-monitoring namespace 上に `kube-state-metrics` を構築する。


```
$ kubectl apply -f elastic-kube-state-metrics/
clusterrolebinding.rbac.authorization.k8s.io/elastic-kube-state-metrics created
clusterrole.rbac.authorization.k8s.io/elastic-kube-state-metrics created
deployment.apps/elastic-kube-state-metrics created
serviceaccount/elastic-kube-state-metrics created
service/elastic-kube-state-metrics created
```

kube-sate-metrics ができたことを確認。

```
$ kubectl get po -n elastic-monitoring | grep kube-state
elastic-kube-state-metrics-547876f486-7v892   1/1     Running   0          60s
```


### 6.1 namespace の変更

filebeats と同様なので下記コマンド以外は省略。

```
$ sed -e 's/namespace: kube-system/namespace: elastic-monitoring/g' metricbeat-kubernetes.yaml > metricbeat.yaml 
```


### 6.2 Elasticsearch/Kibana host指定, 認証の追加, secret の参照追加

filebeat と同様なので省略。
※ metricbeat は daemonset と deployment の似た二つのリソースがあるので どちらも 実施

### 6.3 tolerations 追加で master node からも取得

filebeat と同様なので省略。
※ metricbeat は daemonset と deployment の似た二つのリソースがあるので daemonset のみ実施

### 6.4 autodiscover

filebeat とほぼ同様なので省略。

### 6.5 demonset kubernetes.yml へ設定追加
このままだと、Podのメトリクスが取得できないので、下記を追加する。 
([Githubの最新版](https://github.com/elastic/cloud-on-k8s/blob/master/config/recipes/beats/3_metricbeat-kubernetes.yaml)ではこのように修正がされているが、2020.02.23時点でcurlで取得時は下記がなかった)

#### ConfigMap (DaemonSet側のみ)

変更前

```metricbeat_daemonset_configMap_変更前_対象抜粋.yaml
  kubernetes.yml: |-
      metricsets:
        - node
        - system
        - pod
        - container
        - volume
      period: 10s
      host: ${NODE_NAME}
      hosts: ["localhost:10255"]
```

変更後

```metricbeat_daemonset_configMap_変更後_対象抜粋.yaml
  kubernetes.yml: |-
    - module: kubernetes
      metricsets:
        - node
        - system
        - pod
        - container
        - volume
      period: 10s
      host: ${NODE_NAME}
      hosts: ["https://${HOSTNAME}:10250"]
      bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
      ssl.verification_mode: "none"
```

### 6.6 kube-state-metrics 名称変更 (2020.03.14更新)

`kube-state-metrics` の名称を変更したので、合わせて metricbeat で指定する箇所も修正する。

変更前

```yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: metricbeat-deployment-modules
〜〜中略〜〜
      hosts: ["kube-state-metrics:8080"]
```

変更後

```yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: metricbeat-deployment-modules
〜〜中略〜〜
      hosts: ["elastic-kube-state-metrics:8080"]
```


### 6.5 変更後のyaml. 適応

これまでの変更を適応した yaml が下記の通り。

```metricbeat.yaml
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: metricbeat-daemonset-config
  namespace: elastic-monitoring
  labels:
    k8s-app: metricbeat
data:
  metricbeat.yml: |-
    metricbeat.config.modules:
      # Mounted `metricbeat-daemonset-modules` configmap:
      path: ${path.config}/modules.d/*.yml
      # Reload module configs as they change:
      reload.enabled: false

    # To enable hints based autodiscover uncomment this:
    metricbeat.autodiscover:
     providers:
       - type: kubernetes
         node: ${NODE_NAME}
         hints.enabled: true

    processors:
      - add_cloud_metadata:

    cloud.id: ${ELASTIC_CLOUD_ID}
    cloud.auth: ${ELASTIC_CLOUD_AUTH}

    output.elasticsearch:
      hosts: ['https://${ELASTICSEARCH_HOST:elasticsearch}:${ELASTICSEARCH_PORT:9200}']
      username: ${ELASTICSEARCH_USERNAME}
      password: ${ELASTICSEARCH_PASSWORD}
      ssl.certificate_authorities:
        - /mnt/elastic/tls.crt

    setup.kibana:
      host: "https://${KIBANA_HOST}:5601"
      username: ${ELASTICSEARCH_USERNAME}
      password: ${ELASTICSEARCH_PASSWORD}
      protocol: "https"
      ssl.certificate_authorities:
        - /mnt/kibana/tls.crt
    setup.dashboards:
      enabled: true

    xpack.monitoring.enabled: true
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: metricbeat-daemonset-modules
  namespace: elastic-monitoring
  labels:
    k8s-app: metricbeat
data:
  system.yml: |-
    - module: system
      period: 10s
      metricsets:
        - cpu
        - load
        - memory
        - network
        - process
        - process_summary
        #- core
        #- diskio
        #- socket
      processes: ['.*']
      process.include_top_n:
        by_cpu: 5      # include top 5 processes by CPU
        by_memory: 5   # include top 5 processes by memory

    - module: system
      period: 1m
      metricsets:
        - filesystem
        - fsstat
      processors:
      - drop_event.when.regexp:
          system.filesystem.mount_point: '^/(sys|cgroup|proc|dev|etc|host|lib)($|/)'
  kubernetes.yml: |-
    - module: kubernetes
      metricsets:
        - node
        - system
        - pod
        - container
        - volume
      period: 10s
      host: ${NODE_NAME}
      hosts: ["https://${HOSTNAME}:10250"]
      bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
      ssl.verification_mode: "none"
      # If using Red Hat OpenShift remove the previous hosts entry and
      # uncomment these settings:
      #hosts: ["https://${HOSTNAME}:10250"]
      #bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
      #ssl.certificate_authorities:
        #- /var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt
    - module: kubernetes
      metricsets:
        - proxy
      period: 10s
      host: ${NODE_NAME}
      hosts: ["localhost:10249"]
---
# Deploy a Metricbeat instance per node for node metrics retrieval
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: metricbeat
  namespace: elastic-monitoring
  labels:
    k8s-app: metricbeat
spec:
  selector:
    matchLabels:
      k8s-app: metricbeat
  template:
    metadata:
      labels:
        k8s-app: metricbeat
    spec:
      tolerations:
        - key: node-role.kubernetes.io/master
          effect: NoSchedule
      serviceAccountName: metricbeat
      terminationGracePeriodSeconds: 30
      hostNetwork: true
      dnsPolicy: ClusterFirstWithHostNet
      containers:
      - name: metricbeat
        image: docker.elastic.co/beats/metricbeat:7.6.0
        args: [
          "-c", "/etc/metricbeat.yml",
          "-e",
          "-system.hostfs=/hostfs",
        ]
        env:
        - name: ELASTICSEARCH_HOST
          value: monitoring-elasticsearch-es-http
        - name: ELASTICSEARCH_PORT
          value: "9200"
        - name: ELASTICSEARCH_USERNAME
          value: elastic
        - name: ELASTICSEARCH_PASSWORD
          # value: changeme
          valueFrom:
            secretKeyRef:
              key: elastic
              name: monitoring-elasticsearch-es-elastic-user
        - name: KIBANA_HOST
          value: monitoring-kibana-kb-http
        - name: ELASTIC_CLOUD_ID
          value:
        - name: ELASTIC_CLOUD_AUTH
          value:
        - name: NODE_NAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        securityContext:
          runAsUser: 0
        resources:
          limits:
            memory: 200Mi
          requests:
            cpu: 100m
            memory: 100Mi
        volumeMounts:
        - name: config
          mountPath: /etc/metricbeat.yml
          readOnly: true
          subPath: metricbeat.yml
        - name: modules
          mountPath: /usr/share/metricbeat/modules.d
          readOnly: true
        - name: dockersock
          mountPath: /var/run/docker.sock
        - name: proc
          mountPath: /hostfs/proc
          readOnly: true
        - name: cgroup
          mountPath: /hostfs/sys/fs/cgroup
          readOnly: true
        - name: es-certs
          mountPath: /mnt/elastic/tls.crt
          readOnly: true
          subPath: tls.crt
        - name: kb-certs
          mountPath: /mnt/kibana/tls.crt
          readOnly: true
          subPath: tls.crt
      volumes:
      - name: proc
        hostPath:
          path: /proc
      - name: cgroup
        hostPath:
          path: /sys/fs/cgroup
      - name: dockersock
        hostPath:
          path: /var/run/docker.sock
      - name: config
        configMap:
          defaultMode: 0600
          name: metricbeat-daemonset-config
      - name: modules
        configMap:
          defaultMode: 0600
          name: metricbeat-daemonset-modules
      - name: data
        hostPath:
          path: /var/lib/metricbeat-data
          type: DirectoryOrCreate
      - name: es-certs
        secret:
          secretName: monitoring-elasticsearch-es-http-certs-public
      - name: kb-certs
        secret:
          secretName: monitoring-kibana-kb-http-certs-public
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: metricbeat-deployment-config
  namespace: elastic-monitoring
  labels:
    k8s-app: metricbeat
data:
  metricbeat.yml: |-
    metricbeat.config.modules:
      # Mounted `metricbeat-daemonset-modules` configmap:
      path: ${path.config}/modules.d/*.yml
      # Reload module configs as they change:
      reload.enabled: false

    processors:
      - add_cloud_metadata:

    cloud.id: ${ELASTIC_CLOUD_ID}
    cloud.auth: ${ELASTIC_CLOUD_AUTH}

    output.elasticsearch:
      hosts: ['https://${ELASTICSEARCH_HOST:elasticsearch}:${ELASTICSEARCH_PORT:9200}']
      username: ${ELASTICSEARCH_USERNAME}
      password: ${ELASTICSEARCH_PASSWORD}
      ssl.certificate_authorities:
        - /mnt/elastic/tls.crt

    setup.kibana:
      host: "https://${KIBANA_HOST}:5601"
      username: ${ELASTICSEARCH_USERNAME}
      password: ${ELASTICSEARCH_PASSWORD}
      protocol: "https"
      ssl.certificate_authorities:
        - /mnt/kibana/tls.crt
    setup.dashboards:
      enabled: true
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: metricbeat-deployment-modules
  namespace: elastic-monitoring
  labels:
    k8s-app: metricbeat
data:
  # This module requires `kube-state-metrics` up and running under `kube-system` namespace
  kubernetes.yml: |-
    - module: kubernetes
      metricsets:
        - state_node
        - state_deployment
        - state_replicaset
        - state_pod
        - state_container
        - state_cronjob
        - state_resourcequota
        # Uncomment this to get k8s events:
        #- event
      period: 10s
      host: ${NODE_NAME}
      hosts: ["elastic-kube-state-metrics:8080"]
---
# Deploy singleton instance in the whole cluster for some unique data sources, like kube-state-metrics
apiVersion: apps/v1
kind: Deployment
metadata:
  name: metricbeat
  namespace: elastic-monitoring
  labels:
    k8s-app: metricbeat
spec:
  selector:
    matchLabels:
      k8s-app: metricbeat
  template:
    metadata:
      labels:
        k8s-app: metricbeat
    spec:
      serviceAccountName: metricbeat
      hostNetwork: true
      dnsPolicy: ClusterFirstWithHostNet
      containers:
      - name: metricbeat
        image: docker.elastic.co/beats/metricbeat:7.6.0
        args: [
          "-c", "/etc/metricbeat.yml",
          "-e",
        ]
        env:
        - name: ELASTICSEARCH_HOST
          value: monitoring-elasticsearch-es-http
        - name: ELASTICSEARCH_PORT
          value: "9200"
        - name: ELASTICSEARCH_USERNAME
          value: elastic
        - name: ELASTICSEARCH_PASSWORD
          # value: changeme
          valueFrom:
            secretKeyRef:
              key: elastic
              name: monitoring-elasticsearch-es-elastic-user
        - name: KIBANA_HOST
          value: monitoring-kibana-kb-http
        - name: ELASTIC_CLOUD_ID
          value:
        - name: ELASTIC_CLOUD_AUTH
          value:
        - name: NODE_NAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        securityContext:
          runAsUser: 0
        resources:
          limits:
            memory: 200Mi
          requests:
            cpu: 100m
            memory: 100Mi
        volumeMounts:
        - name: config
          mountPath: /etc/metricbeat.yml
          readOnly: true
          subPath: metricbeat.yml
        - name: modules
          mountPath: /usr/share/metricbeat/modules.d
          readOnly: true
        - name: es-certs
          mountPath: /mnt/elastic/tls.crt
          readOnly: true
          subPath: tls.crt
        - name: kb-certs
          mountPath: /mnt/kibana/tls.crt
          readOnly: true
          subPath: tls.crt
      volumes:
      - name: config
        configMap:
          defaultMode: 0600
          name: metricbeat-deployment-config
      - name: modules
        configMap:
          defaultMode: 0600
          name: metricbeat-deployment-modules
      - name: es-certs
        secret:
          secretName: monitoring-elasticsearch-es-http-certs-public
      - name: kb-certs
        secret:
          secretName: monitoring-kibana-kb-http-certs-public
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: metricbeat
subjects:
- kind: ServiceAccount
  name: metricbeat
  namespace: elastic-monitoring
roleRef:
  kind: ClusterRole
  name: metricbeat
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: metricbeat
  labels:
    k8s-app: metricbeat
rules:
- apiGroups: [""]
  resources:
  - nodes
  - namespaces
  - events
  - pods
  verbs: ["get", "list", "watch"]
- apiGroups: ["extensions"]
  resources:
  - replicasets
  verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
  resources:
  - statefulsets
  - deployments
  verbs: ["get", "list", "watch"]
- apiGroups:
  - ""
  resources:
  - nodes/stats
  verbs:
  - get
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: metricbeat
  namespace: elastic-monitoring
  labels:
    k8s-app: metricbeat
---

```

上記 yaml を apply する。

```
$ kubectl apply -f metricbeat.yaml 
configmap/metricbeat-daemonset-config created
configmap/metricbeat-daemonset-modules created
daemonset.apps/metricbeat created
configmap/metricbeat-deployment-config created
configmap/metricbeat-deployment-modules created
deployment.apps/metricbeat created
clusterrolebinding.rbac.authorization.k8s.io/metricbeat created
clusterrole.rbac.authorization.k8s.io/metricbeat created
serviceaccount/metricbeat created

$ kubectl get po -n elastic-monitoring | grep metricbeat
metricbeat-57jpz                            1/1     Running   0          15s
metricbeat-67b75b56b5-4r9jn                 1/1     Running   0          15s
metricbeat-8kmg7                            1/1     Running   0          15s
metricbeat-fwfmn                            1/1     Running   0          15s
metricbeat-jckss                            1/1     Running   0          15s
metricbeat-r9vkj                            1/1     Running   0          15s
metricbeat-rrm69                            1/1     Running   0          15s
metricbeat-sx5b8                            1/1     Running   0          15s
metricbeat-wq498                            1/1     Running   0          15s
```



## 7. auditbeat の構築
auditbeat では ファイル整合性チェックに使用できるようなので入れておく。(下記は [auditbeat サイト](https://www.elastic.co/guide/en/beats/auditbeat/7.6/running-on-kubernetes.html)記載引用)
`Auditbeat Docker images can be used on Kubernetes to check files integrity.`

```
$ curl -L -O https://raw.githubusercontent.com/elastic/beats/7.6/deploy/kubernetes/auditbeat-kubernetes.yaml
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  4288  100  4288    0     0   9329      0 --:--:-- --:--:-- --:--:--  9342
$ sed -e 's/namespace: kube-system/namespace: elastic-monitoring/g' auditbeat-kubernetes.yaml > auditbeat.yaml 
```

修正内容は filebeat で挙げた namespace. 認証. tolerations のため省略して、下記の通り。

```auditbeat.yaml
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: auditbeat-config
  namespace: elastic-monitoring
  labels:
    k8s-app: auditbeat
data:
  auditbeat.yml: |-
    auditbeat.config.modules:
      # Mounted `auditbeat-daemonset-modules` configmap:
      path: ${path.config}/modules.d/*.yml
      # Reload module configs as they change:
      reload.enabled: false

    processors:
      - add_cloud_metadata:

    cloud.id: ${ELASTIC_CLOUD_ID}
    cloud.auth: ${ELASTIC_CLOUD_AUTH}

    output.elasticsearch:
      hosts: ['https://${ELASTICSEARCH_HOST:elasticsearch}:${ELASTICSEARCH_PORT:9200}']
      username: ${ELASTICSEARCH_USERNAME}
      password: ${ELASTICSEARCH_PASSWORD}
      ssl.certificate_authorities:
        - /mnt/elastic/tls.crt

    setup.kibana:
      host: "https://${KIBANA_HOST}:5601"
      username: ${ELASTICSEARCH_USERNAME}
      password: ${ELASTICSEARCH_PASSWORD}
      protocol: "https"
      ssl.certificate_authorities:
        - /mnt/kibana/tls.crt
    setup.dashboards:
      enabled: true

    xpack.monitoring.enabled: true
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: auditbeat-daemonset-modules
  namespace: elastic-monitoring
  labels:
    k8s-app: auditbeat
data:
  system.yml: |-
    - module: file_integrity
      paths:
      - /hostfs/bin
      - /hostfs/usr/bin
      - /hostfs/sbin
      - /hostfs/usr/sbin
      - /hostfs/etc
      exclude_files:
      - '(?i)\.sw[nop]$'
      - '~$'
      - '/\.git($|/)'
      scan_at_start: true
      scan_rate_per_sec: 50 MiB
      max_file_size: 100 MiB
      hash_types: [sha1]
      recursive: true
---
# Deploy a auditbeat instance per node for node metrics retrieval
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: auditbeat
  namespace: elastic-monitoring
  labels:
    k8s-app: auditbeat
spec:
  selector:
    matchLabels:
      k8s-app: auditbeat
  template:
    metadata:
      labels:
        k8s-app: auditbeat
    spec:
      tolerations:
        - key: node-role.kubernetes.io/master
          effect: NoSchedule
      serviceAccountName: auditbeat
      terminationGracePeriodSeconds: 30
      hostNetwork: true
      dnsPolicy: ClusterFirstWithHostNet
      containers:
      - name: auditbeat
        image: docker.elastic.co/beats/auditbeat:7.6.0
        args: [
          "-c", "/etc/auditbeat.yml"
        ]
        env:
        - name: ELASTICSEARCH_HOST
          value: monitoring-elasticsearch-es-http
        - name: ELASTICSEARCH_PORT
          value: "9200"
        - name: ELASTICSEARCH_USERNAME
          value: elastic
        - name: ELASTICSEARCH_PASSWORD
          valueFrom:
            secretKeyRef:
              key: elastic
              name: monitoring-elasticsearch-es-elastic-user
        - name: KIBANA_HOST
          value: monitoring-kibana-kb-http
        - name: ELASTIC_CLOUD_ID
          value:
        - name: ELASTIC_CLOUD_AUTH
          value:
        securityContext:
          runAsUser: 0
        resources:
          limits:
            memory: 200Mi
          requests:
            cpu: 100m
            memory: 100Mi
        volumeMounts:
        - name: config
          mountPath: /etc/auditbeat.yml
          readOnly: true
          subPath: auditbeat.yml
        - name: modules
          mountPath: /usr/share/auditbeat/modules.d
          readOnly: true
        - name: bin
          mountPath: /hostfs/bin
          readOnly: true
        - name: sbin
          mountPath: /hostfs/sbin
          readOnly: true
        - name: usrbin
          mountPath: /hostfs/usr/bin
          readOnly: true
        - name: usrsbin
          mountPath: /hostfs/usr/sbin
          readOnly: true
        - name: etc
          mountPath: /hostfs/etc
          readOnly: true
        - name: es-certs
          mountPath: /mnt/elastic/tls.crt
          readOnly: true
          subPath: tls.crt
        - name: kb-certs
          mountPath: /mnt/kibana/tls.crt
          readOnly: true
          subPath: tls.crt
      volumes:
      - name: bin
        hostPath:
          path: /bin
      - name: usrbin
        hostPath:
          path: /usr/bin
      - name: sbin
        hostPath:
          path: /sbin
      - name: usrsbin
        hostPath:
          path: /usr/sbin
      - name: etc
        hostPath:
          path: /etc
      - name: config
        configMap:
          defaultMode: 0600
          name: auditbeat-config
      - name: modules
        configMap:
          defaultMode: 0600
          name: auditbeat-daemonset-modules
      - name: data
        hostPath:
          path: /var/lib/auditbeat-data
          type: DirectoryOrCreate
      - name: es-certs
        secret:
          secretName: monitoring-elasticsearch-es-http-certs-public
      - name: kb-certs
        secret:
          secretName: monitoring-kibana-kb-http-certs-public
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: auditbeat
subjects:
- kind: ServiceAccount
  name: auditbeat
  namespace: elastic-monitoring
roleRef:
  kind: ClusterRole
  name: auditbeat
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: auditbeat
  labels:
    k8s-app: auditbeat
rules:
- apiGroups: [""]
  resources:
  - nodes
  - namespaces
  - pods
  verbs: ["get", "list", "watch"]
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: auditbeat
  namespace: elastic-monitoring
  labels:
    k8s-app: auditbeat
---

```

上記 yaml を apply する。

```
$ kubectl apply -f auditbeat.yaml 
configmap/auditbeat-config unchanged
configmap/auditbeat-daemonset-modules unchanged
daemonset.apps/auditbeat created
clusterrolebinding.rbac.authorization.k8s.io/auditbeat created
clusterrole.rbac.authorization.k8s.io/auditbeat created
serviceaccount/auditbeat created

$ kubectl get po -n elastic-monitoring | grep audit
auditbeat-5s6rh                             1/1     Running   0          53s
auditbeat-6xrkc                             1/1     Running   0          53s
auditbeat-846pz                             1/1     Running   0          53s
auditbeat-8szhp                             1/1     Running   0          53s
auditbeat-9kqsf                             1/1     Running   0          53s
auditbeat-njf45                             1/1     Running   0          53s
auditbeat-v7swg                             1/1     Running   0          53s
auditbeat-vx4hv                             1/1     Running   0          53s
```


## Kibanaでの表示確認
構築ステップが完了すると kibana で色々表示できるので確認する。

### Metrics
メトリクスを見ながら必要な単位でログを閲覧することが可能となる。

 - Host, Pod 単位での CPU/Memory/Traffic などのメトリクス表示が可能
 - Pod は Namespace, Node などに囲って表示も可能
 - **Host, Pod 単位で Log 確認が可能**

Node 単位での Metrics, Log の表示
![kibana_metrics_node.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326183/d8133f5e-a21d-1be0-587f-c7cdacec8ba7.gif)

Pod 全体 -> Pod Namespace 単位 -> Pod Namespace & Node 単位
(Pod 単位で出ている % は CPU Usage. 他にも Memory Usage, Inbound Traffic, Outbound Traffic に変更可能) 
![kibana_metrics_pods.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326183/d32c5f51-3232-2680-f29e-d3f60bec3017.gif)

Pod 単位での Metrics 表示
![kibana_metrics_pods_metrics.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326183/74208283-4db4-4653-d7ab-b73562b09ec4.gif)

Pod 単位での Log 表示
![kibana_metrics_pods_logs.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326183/e2a736fa-5c82-07fc-23ce-80e7992c589d.gif)

### Dashboard [Filebeat System] Syslog dashboard ECS
 - syslogがノード単位で取得できていることが確認できる
 - ノードへのログイン履歴等も確認可能

Syslog 表示 (ノード単位)

![スクリーンショット 2020-02-23 22.00.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326183/5765ca64-d117-a1c3-1cac-927557bc4ea5.png)

SSH ログイン時系列
![スクリーンショット 2020-02-23 22.00.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326183/5ff281f5-6694-3761-9157-8a6d5e9eebc4.png)
※ testerror と言うユーザでログインミスをした結果

### Dashboard [Metricbeat Kubernetes] Overview ECS
 - Pod/Devployment や各種リソースが一覧で見れる
![スクリーンショット 2020-02-23 22.01.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326183/016566ce-317e-b905-b23c-02ad8e64b46d.png)


### Dashboard [Auditbeat File Integrity] Overview ECS
 - ファイル整合性チェック結果の表示
![スクリーンショット 2020-02-23 22.04.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326183/ff2b7c55-d696-f5d2-477e-8da4e53e42a6.png)
※作ったばかりなので initial scan 結果しか出てない

## おわりに
Kubernetes クラスタのログ・メトリクス表示環境の構築を ElasticStack で実現できた。
Kubernetes でのノード・ Pod 単位で何かがあった際に、メトリクスを確認しながら対象のログを絞って見ることができるようになった。
今後は外部の Netflow, log などの取得・可視化を、この環境に filebeat などを別途構築して連携実施する予定。