AKS ( Kubernetes ) のPod からログをfluentd を使って収集してelasticsearch + kibanaで解析する方法

2020年4月13日

はじめに

くどうです。

今回はKubernetesでのログの収集方法です。
その中でも、各Nodeに配置されたPodからログを収集す方法になります。
本検証自体はAKSで行っていますが、ACS、ACS-Engineなどで構築されたKubernetes環境でも同様のことが可能です。本稿でもAKS自体には触れておらず、Azureに関係なく利用可能です。

Podから出力されるログとは、kubectl log {Pod名} で出力されるログになります。
例えば、nginxをpodで配置した場合は、アクセスログが出力されたりします。

前提条件として、ElasticsearchおよびKubernetes環境はすでに整っていることが前提となります。
また、本内容はAzureで構築されたKubernetesを利用しています。

こちらも参考を
AKS ( Kubernetes ) のPod からログをfluentd を使って収集してelasticsearch + kibanaで解析する方法(k8s 1.8以上RBAC対応版)
https://level69.net/archives/25458

elasticsearchの構築方法については下記に記載しています。
elasticsearch + kibana を5分ぐらいで構築する。

構成

簡単に構成を説明します。
構成は単純です。Kubernetes環境と、同ネットワーク内にelasticsearch + kibana が構成されています。
事前に環境が正しく動作していることが前提となります。

Podからログを収集するため各Nodeへfluentdを配置します。DaemonSetで各Nodeへ配置します。
次に、fluentdにより収集されたログはelasticsearchへと送られます。
そして最後に、ユーザーはkibanaを通じて解析を行います。

準備

配置するfluentdは公式に用意されているものを利用し配置します。
定義ファイルは下記です。
fluentd-daemonset-elasticsearch.yaml

利用するためcloneして自分の環境へ持ってきましょう。

git clone https://github.com/fluent/fluentd-kubernetes-daemonset

次に展開する前に設定を変更します。
設定を変更しているenv箇所のみを記載します。

fluentd-daemonset-elasticsearch.yaml

・・・・
        env:
          - name:  FLUENT_ELASTICSEARCH_HOST
            value: "10.240.0.7"
          - name:  FLUENT_ELASTICSEARCH_PORT
            value: "9200"
          - name: FLUENT_ELASTICSEARCH_SCHEME
            value: "http"
          # X-Pack Authentication
          # =====================
          #- name: FLUENT_ELASTICSEARCH_USER
          #  value: "elastic"
          #- name: FLUENT_ELASTICSEARCH_PASSWORD
          #  value: "changeme"
        resources:
・・・・

FLUENT_ELASTICSEARCH_HOST: elasticsearchのホスト名もしくはIPアドレスを指定
FLUENT_ELASTICSEARCH_PORT: elasticsearchのポート番号で通常は変更しません
FLUENT_ELASTICSEARCH_SCHEME: elasticsearchの利用するプロトコルで通常は変更しません
X-Pack Authentication: X-Packによる認証を行っていないため今回はコメントアウトしています

注意:indexの名前が変更できない?

展開

定義を保存しkubectlコマンドで DaemonSetを展開します。

kubectl create -f fluentd-daemonset-elasticsearch.yaml

fluentdが展開されていることが確認できます。
本環境ではNodeは3台です。

$ kubectl get daemonsets --namespace=kube-system
NAME                DESIRED   CURRENT   READY     UP-TO-DATE   AVAILABLE   NODE SELECTOR                 AGE
fluentd             3         3         3         3            3           < none >                        14m
kube-proxy          3         3         3         3            3           beta.kubernetes.io/os=linux   1d
kube-svc-redirect   3         3         3         3            3           beta.kubernetes.io/os=linux   1d
$ kubectl get pods --namespace=kube-system
NAME                                    READY     STATUS    RESTARTS   AGE
fluentd-h4hp7                           1/1       Running   0          16m
fluentd-j62f4                           1/1       Running   0          16m
fluentd-v6d8s                           1/1       Running   0          16m
・・・・

以上で、fluentdの配置は完了です。

確認

次にログが正しく転送されるか確認を行います。
nginxを例に進ます。

nginx.yaml

apiVersion: v1
kind: Service
metadata:
    name: nginx-service
spec:
    type: LoadBalancer
    ports:
    - name: http
      port: 80
      targetPort: nginx-http
      protocol: TCP
    selector:
        app: nginx
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: nginx-deploy
spec:
  replicas: 100
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - name: nginx-http
          containerPort: 80
kubectl create -f nginx.yaml

上記の定義を展開することで下記のような構成が出来上がります。

LoadBalancerを通してnginxにアクセスしログがfluentdからelasticsearchへ送られているか確認します。

最初に、Podでログが出力されているが確認します。
下記はCURLによる簡単なアクセスログになります。

$ kubectl logs nginx-deploy-cfbfb9c8d-zwzrd
10.240.0.4 - - [15/Feb/2018:09:34:42 +0000] "HEAD / HTTP/1.1" 200 0 "-" "curl/7.47.0" "-"
10.240.0.6 - - [15/Feb/2018:09:34:43 +0000] "HEAD / HTTP/1.1" 200 0 "-" "curl/7.47.0" "-"
10.240.0.6 - - [15/Feb/2018:09:34:53 +0000] "HEAD / HTTP/1.1" 200 0 "-" "curl/7.47.0" "-"
10.240.0.4 - - [15/Feb/2018:09:34:54 +0000] "HEAD / HTTP/1.1" 200 0 "-" "curl/7.47.0" "-"
10.240.0.6 - - [15/Feb/2018:09:35:03 +0000] "HEAD / HTTP/1.1" 200 0 "-" "curl/7.47.0" "-"
10.240.0.4 - - [15/Feb/2018:09:35:03 +0000] "HEAD / HTTP/1.1" 200 0 "-" "curl/7.47.0" "-"
・・・・・

kibana自体の操作方法は割愛します。

logとkubernetes.pod_nameのフィールドを表示さえるログが上記と同じこと、各Podから収集できていることが確認できます。

以上でkubernetesのPodからfluentdを利用してelasticsearch + kibanaの環境ができました。
これで、解析する準備が整いました。

削除

DaeamonSetの削除

kubectl delete ds fluentd -n=kube-system

まとめ

kubernetesでログの収集し解析する機会は増えると思います。今回はその方法のひとつとしてfluentd+elasticsearch+kibanaという従来よくある方法を紹介しました。
これ以外にも収集方法はあるかと思いますが、使い慣れた方法の一つとしてノウハウがたまっている分、大きく解析方法を変えなくて済むという利点が恩恵を受けれると思います。

参考:
https://kubernetes.io/docs/tasks/debug-application-cluster/logging-elasticsearch-kibana/
https://docs.fluentd.org/v0.12/articles/kubernetes-fluentd