1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ElasticsearchとFilebeatを使用したKubernetesのロギング Part1  〜ElasticsearchとKibanaのデプロイメント編〜

Last updated at Posted at 2020-11-12

image.png

#はじめに
この記事は、クラスターにデプロイされたアプリケーションとクラスター自体の本番環境グレードのKubernetesログを設定する2部構成のシリーズのPart1です。 当記事ではロギングバックエンドとしてElasticsearchを使用します。 Elasticsearchのセットアップは、非常にスケーラブルで耐障害性の高いものになります。

# デプロイメントアーキテクチャ

image.png

  • Elasticsearch データノードポッドは、安定したネットワークIDを提供するヘッドレスサービスを備えたステートフルセットとしてデプロイされます。

  • Elasticsearch マスターノードポッドは、自動検出に役立つヘッドレスサービスを備えたレプリカセットとしてデプロイされます。

  • Elasticsearch クライアントノードポッドは、R / Wリクエストのデータノードへのアクセスを許可する内部サービスを備えたレプリカセットとしてデプロイされます。

  • KibanaポッドElasticHQポッドは、Kubernetesクラスターの外部からアクセスできるサービスを備えたレプリカセットとしてデプロイされますが、サブネットワークの内部にはあります(特に必要がない限り、公開されません)。

  • HPA(Horizontal Pod Auto-scaler)がクライアントノードに導入され、高負荷での自動スケーリングが可能になりました。

####覚えておくべき重要なこと:

  1. ES_JAVA_OPTS環境変数を設定します。

  2. CLUSTER_NAME環境変数を設定します。

  3. マスター展開用にNUMBER_OF_MASTERS(スプリットブレインの問題を回避するため)環境変数を設定します。 マスターが3つの場合、2に設定しました。

  4. ワーカーノードに障害が発生した場合にHAを確保するために、同様のポッド間で正しいPod-AntiAffinityポリシーを設定します。

これらのサービスをGKEクラスターにデプロイするところから始めましょう。

###マスターノードのデプロイメントとヘッドレスサービス

次のマニフェストをデプロイして、マスターノードとヘッドレスサービスを作成します。


apiVersion: v1
kind: Namespace
metadata:
  name: elasticsearch
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: es-master
  namespace: elasticsearch
  labels:
    component: elasticsearch
    role: master
spec:
  replicas: 3
  template:
    metadata:
      labels:
        component: elasticsearch
        role: master
    spec:
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: role
                  operator: In
                  values:
                  - master
              topologyKey: kubernetes.io/hostname
      initContainers:
      - name: init-sysctl
        image: busybox:1.27.2
        command:
        - sysctl
        - -w
        - vm.max_map_count=262144
        securityContext:
          privileged: true
      containers:
      - name: es-master
        image: quay.io/pires/docker-elasticsearch-kubernetes:6.2.4
        env:
        - name: NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: NODE_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: CLUSTER_NAME
          value: my-es
        - name: NUMBER_OF_MASTERS
          value: "2"
        - name: NODE_MASTER
          value: "true"
        - name: NODE_INGEST
          value: "false"
        - name: NODE_DATA
          value: "false"
        - name: HTTP_ENABLE
          value: "false"
        - name: ES_JAVA_OPTS
          value: -Xms256m -Xmx256m
        - name: PROCESSORS
          valueFrom:
            resourceFieldRef:
              resource: limits.cpu
        resources:
          limits:
            cpu: 2
        ports:
        - containerPort: 9300
          name: transport
        volumeMounts:
        - name: storage
          mountPath: /data
      volumes:
          - emptyDir:
              medium: ""
            name: "storage"
---
apiVersion: v1
kind: Service
metadata:
  name: elasticsearch-discovery
  namespace: elasticsearch
  labels:
    component: elasticsearch
    role: master
spec:
  selector:
    component: elasticsearch
    role: master
  ports:
  - name: transport
    port: 9300
    protocol: TCP
  clusterIP: None

マスターノードポッドのいずれかのログをたどると、それらの間でマスターが選出されます。 これは、マスターノードポッドがグループのリーダーを選択するときです。 マスターノードのログを追跡すると、新しいデータとクライアントノードがいつ追加されたかがわかります。

root$ kubectl -n elasticsearch logs -f po/es-master-594b58b86c-9jkj2 | grep ClusterApplierService
[2018-10-21T07:41:54,958][INFO ][o.e.c.s.ClusterApplierService] [es-master-594b58b86c-9jkj2] detected_master {es-master-594b58b86c-bj7g7}{1aFT97hQQ7yiaBc2CYShBA}{Q3QzlaG3QGazOwtUl7N75Q}{10.9.126.87}{10.9.126.87:9300}, added {{es-master-594b58b86c-lfpps}{wZQmXr5fSfWisCpOHBhaMg}{50jGPeKLSpO9RU_HhnVJCA}{10.9.124.81}{10.9.124.81:9300},{es-master-594b58b86c-bj7g7}{1aFT97hQQ7yiaBc2CYShBA}{Q3QzlaG3QGazOwtUl7N75Q}{10.9.126.87}{10.9.126.87:9300},}, reason: apply cluster state (from master [master {es-master-594b58b86c-bj7g7}{1aFT97hQQ7yiaBc2CYShBA}{Q3QzlaG3QGazOwtUl7N75Q}{10.9.126.87}{10.9.126.87:9300} committed version [3]])

上記のように、es-master-594b58b86c-bj7g7という名前のes-masterポッドがリーダーとして選出され、他の2つのポッドがクラスターに追加されました。

Elasticsearch-discoveryという名前のヘッドレスサービスは、デフォルトでDockerイメージの環境変数として設定され、ノード間の検出に使用されます。 もちろん、これはオーバーライドできます。

###データノードのデプロイメント
次のマニフェストを使用して、データノードにステートフルセットとヘッドレスサービスをデプロイします。

apiVersion: v1
kind: Namespace
metadata:
  name: elasticsearch
---
apiVersion: storage.k8s.io/v1beta1
kind: StorageClass
metadata:
  name: fast
provisioner: kubernetes.io/gce-pd
parameters:
  type: pd-ssd
  fsType: xfs
allowVolumeExpansion: true
---
apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
  name: es-data
  namespace: elasticsearch
  labels:
    component: elasticsearch
    role: data
spec:
  serviceName: elasticsearch-data
  replicas: 3
  template:
    metadata:
      labels:
        component: elasticsearch
        role: data
    spec:
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: role
                  operator: In
                  values:
                  - data
              topologyKey: kubernetes.io/hostname
      initContainers:
      - name: init-sysctl
        image: busybox:1.27.2
        command:
        - sysctl
        - -w
        - vm.max_map_count=262144
        securityContext:
          privileged: true
      containers:
      - name: es-data
        image: quay.io/pires/docker-elasticsearch-kubernetes:6.2.4
        env:
        - name: NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: NODE_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: CLUSTER_NAME
          value: my-es
        - name: NODE_MASTER
          value: "false"
        - name: NODE_INGEST
          value: "false"
        - name: HTTP_ENABLE
          value: "false"
        - name: ES_JAVA_OPTS
          value: -Xms256m -Xmx256m
        - name: PROCESSORS
          valueFrom:
            resourceFieldRef:
              resource: limits.cpu
        resources:
          limits:
            cpu: 2
        ports:
        - containerPort: 9300
          name: transport
        volumeMounts:
        - name: storage
          mountPath: /data
  volumeClaimTemplates:
  - metadata:
      name: storage
      annotations:
        volume.beta.kubernetes.io/storage-class: "fast"
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: fast
      resources:
        requests:
          storage: 10Gi
---
apiVersion: v1
kind: Service
metadata:
  name: elasticsearch-data
  namespace: elasticsearch
  labels:
    component: elasticsearch
    role: data
spec:
  ports:
  - port: 9300
    name: transport
  clusterIP: None
  selector:
    component: elasticsearch
    role: data

データノードの場合のヘッドレスサービスは、ノードに安定したネットワークIDを提供し、ノード間のデータ転送にも役立ちます。

永続ボリュームをポッドに接続する前にフォーマットすることが重要です。 これは、ストレージクラスの作成時にボリュームタイプを指定することで実行できます。 また、その場でボリュームを拡張できるようにフラグを設定することもできます。 詳細については、こちらをご覧ください。

...
parameters: 
 type: pd-ssd 
 fsType: xfs
allowVolumeExpansion: true
...

#クライアントノードのデプロイメント
次のマニフェストを使用して、クライアントノードのデプロイメントおよび外部サービスを作成します。

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: es-client
  namespace: elasticsearch
  labels:
    component: elasticsearch
    role: client
spec:
  replicas: 2
  template:
    metadata:
      labels:
        component: elasticsearch
        role: client
    spec:
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: role
                  operator: In
                  values:
                  - client
              topologyKey: kubernetes.io/hostname
      initContainers:
      - name: init-sysctl
        image: busybox:1.27.2
        command:
        - sysctl
        - -w
        - vm.max_map_count=262144
        securityContext:
          privileged: true
      containers:
      - name: es-client
        image: quay.io/pires/docker-elasticsearch-kubernetes:6.2.4
        env:
        - name: NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: NODE_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: CLUSTER_NAME
          value: my-es
        - name: NODE_MASTER
          value: "false"
        - name: NODE_DATA
          value: "false"
        - name: HTTP_ENABLE
          value: "true"
        - name: ES_JAVA_OPTS
          value: -Xms256m -Xmx256m
        - name: NETWORK_HOST
          value: _site_,_lo_
        - name: PROCESSORS
          valueFrom:
            resourceFieldRef:
              resource: limits.cpu
        resources:
          limits:
            cpu: 1
        ports:
        - containerPort: 9200
          name: http
        - containerPort: 9300
          name: transport
        volumeMounts:
        - name: storage
          mountPath: /data
      volumes:
          - emptyDir:
              medium: ""
            name: storage
---
apiVersion: v1
kind: Service
metadata:
  name: elasticsearch
  namespace: elasticsearch
  labels:
    component: elasticsearch
    role: client
spec:
  selector:
    component: elasticsearch
    role: client
  ports:
  - name: http
    port: 9200
  type: LoadBalancer

ここでデプロイされるサービスの目的は、Kubernetesクラスターの外部からESクラスターにアクセスすることですが、それでもサブネットの内部にあります。 アノテーション「cloud.google.com/load-balancer-type:Internal」はこれを保証します。

ただし、ESクラスターへのアプリケーションの読み取り/書き込みがクラスター内にデプロイされている場合は、http://elasticsearch.elasticsearch:9200からElasticsearchサービスにアクセスできます。

すべてのコンポーネントがデプロイされたら、次のことを確認する必要があります。

1.Ubuntuコンテナを使用したKubernetesクラスター内からのElasticsearchデプロイメント。

root$ kubectl run my-shell --rm -i --tty --image ubuntu -- bash
root@my-shell-68974bb7f7-pj9x6:/# curl http://elasticsearch.elasticsearch:9200/_cluster/health?pretty
{
"cluster_name" : "my-es",
"status" : "green",
"timed_out" : false,
"number_of_nodes" : 7,
"number_of_data_nodes" : 2,
"active_primary_shards" : 0,
"active_shards" : 0,
"relocating_shards" : 0,
"initializing_shards" : 0,
"unassigned_shards" : 0,
"delayed_unassigned_shards" : 0,
"number_of_pending_tasks" : 0,
"number_of_in_flight_fetch" : 0,
"task_max_waiting_in_queue_millis" : 0,
"active_shards_percent_as_number" : 100.0
}
  1. GCP内部ロードバランサーIP(この場合は10.9.120.8)を使用して、クラスターの外部からElasticsearchをデプロイします。 curl http://10.9.120.8:9200/_cluster/health?pretty
    を使用してヘルスをチェックすると、出力は上記と同じになります。

  2. ESポッドの非アフィニティルール:

root$ kubectl -n elasticsearch get pods -o wide 
NAME                         READY     STATUS    RESTARTS   AGE       IP            NODE
es-client-69b84b46d8-kr7j4   1/1       Running   0          10m       10.8.14.52   gke-cluster1-pool1-d2ef2b34-t6h9
es-client-69b84b46d8-v5pj2   1/1       Running   0          10m       10.8.15.53   gke-cluster1-pool1-42b4fbc4-cncn
es-data-0                    1/1       Running   0          12m       10.8.16.58   gke-cluster1-pool1-4cfd808c-kpx1
es-data-1                    1/1       Running   0          12m       10.8.15.52   gke-cluster1-pool1-42b4fbc4-cncn
es-master-594b58b86c-9jkj2   1/1       Running   0          18m       10.8.15.51   gke-cluster1-pool1-42b4fbc4-cncn
es-master-594b58b86c-bj7g7   1/1       Running   0          18m       10.8.16.57   gke-cluster1-pool1-4cfd808c-kpx1
es-master-594b58b86c-lfpps   1/1       Running   0          18m       10.8.14.51   gke-cluster1-pool1-d2ef2b34-t6h9

#スケーリングに関する考慮事項
CPUのしきい値に応じて、クライアントノードに自動スケーラーをデプロイできます。 クライアントノードのサンプルHPAは、次のようになります。

apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
 name: es-client
 namespace: elasticsearch
spec:
 maxReplicas: 5
 minReplicas: 2
 scaleTargetRef:
   apiVersion: extensions/v1beta1
   kind: Deployment
   name: es-client
targetCPUUtilizationPercentage: 80

オートスケーラーが起動するたびに、マスターノードポッドのログを監視することで、新しいクライアントノードポッドがクラスターに追加されるのを監視できます。

データノードポッドの場合、K8ダッシュボードまたはGKEコンソールを使用してレプリカの数を増やすだけです。 新しく作成されたデータノードは自動的にクラスターに追加され、他のノードからのデータの複製を開始します。

マスターノードポッドは、クラスター状態情報のみを格納するため、自動スケーリングは必要ありません。 さらにデータノードを追加する場合は、クラスター内に偶数のマスターノードがないことを確認してください。 また、それに応じて環境変数NUMBER_OF_MASTERSが更新されていることを確認してください。

#Check logs of es-master leader pod
root$ kubectl -n elasticsearch logs po/es-master-594b58b86c-bj7g7 | grep ClusterApplierService
[2018-10-21T07:41:53,731][INFO ][o.e.c.s.ClusterApplierService] [es-master-594b58b86c-bj7g7] new_master {es-master-594b58b86c-bj7g7}{1aFT97hQQ7yiaBc2CYShBA}{Q3QzlaG3QGazOwtUl7N75Q}{10.9.126.87}{10.9.126.87:9300}, added {{es-master-594b58b86c-lfpps}{wZQmXr5fSfWisCpOHBhaMg}{50jGPeKLSpO9RU_HhnVJCA}{10.9.124.81}{10.9.124.81:9300},}, reason: apply cluster state (from master [master {es-master-594b58b86c-bj7g7}{1aFT97hQQ7yiaBc2CYShBA}{Q3QzlaG3QGazOwtUl7N75Q}{10.9.126.87}{10.9.126.87:9300} committed version [1] source [zen-disco-elected-as-master ([1] nodes joined)[{es-master-594b58b86c-lfpps}{wZQmXr5fSfWisCpOHBhaMg}{50jGPeKLSpO9RU_HhnVJCA}{10.9.124.81}{10.9.124.81:9300}]]])

[2018-10-21T07:41:55,162][INFO ][o.e.c.s.ClusterApplierService] [es-master-594b58b86c-bj7g7] added {{es-master-594b58b86c-9jkj2}{x9Prp1VbTq6_kALQVNwIWg}{7NHUSVpuS0mFDTXzAeKRcg}{10.9.125.81}{10.9.125.81:9300},}, reason: apply cluster state (from master [master {es-master-594b58b86c-bj7g7}{1aFT97hQQ7yiaBc2CYShBA}{Q3QzlaG3QGazOwtUl7N75Q}{10.9.126.87}{10.9.126.87:9300} committed version [3] source [zen-disco-node-join[{es-master-594b58b86c-9jkj2}{x9Prp1VbTq6_kALQVNwIWg}{7NHUSVpuS0mFDTXzAeKRcg}{10.9.125.81}{10.9.125.81:9300}]]])

[2018-10-21T07:48:02,485][INFO ][o.e.c.s.ClusterApplierService] [es-master-594b58b86c-bj7g7] added {{es-data-0}{SAOhUiLiRkazskZ_TC6EBQ}{qirmfVJBTjSBQtHZnz-QZw}{10.9.126.88}{10.9.126.88:9300},}, reason: apply cluster state (from master [master {es-master-594b58b86c-bj7g7}{1aFT97hQQ7yiaBc2CYShBA}{Q3QzlaG3QGazOwtUl7N75Q}{10.9.126.87}{10.9.126.87:9300} committed version [4] source [zen-disco-node-join[{es-data-0}{SAOhUiLiRkazskZ_TC6EBQ}{qirmfVJBTjSBQtHZnz-QZw}{10.9.126.88}{10.9.126.88:9300}]]])

[2018-10-21T07:48:21,984][INFO ][o.e.c.s.ClusterApplierService] [es-master-594b58b86c-bj7g7] added {{es-data-1}{fiv5Wh29TRWGPumm5ypJfA}{EXqKGSzIQquRyWRzxIOWhQ}{10.9.125.82}{10.9.125.82:9300},}, reason: apply cluster state (from master [master {es-master-594b58b86c-bj7g7}{1aFT97hQQ7yiaBc2CYShBA}{Q3QzlaG3QGazOwtUl7N75Q}{10.9.126.87}{10.9.126.87:9300} committed version [5] source [zen-disco-node-join[{es-data-1}{fiv5Wh29TRWGPumm5ypJfA}{EXqKGSzIQquRyWRzxIOWhQ}{10.9.125.82}{10.9.125.82:9300}]]])

[2018-10-21T07:50:51,245][INFO ][o.e.c.s.ClusterApplierService] [es-master-594b58b86c-bj7g7] added {{es-client-69b84b46d8-v5pj2}{MMjA_tlTS7ux-UW44i0osg}{rOE4nB_jSmaIQVDZCjP8Rg}{10.9.125.83}{10.9.125.83:9300},}, reason: apply cluster state (from master [master {es-master-594b58b86c-bj7g7}{1aFT97hQQ7yiaBc2CYShBA}{Q3QzlaG3QGazOwtUl7N75Q}{10.9.126.87}{10.9.126.87:9300} committed version [6] source [zen-disco-node-join[{es-client-69b84b46d8-v5pj2}{MMjA_tlTS7ux-UW44i0osg}{rOE4nB_jSmaIQVDZCjP8Rg}{10.9.125.83}{10.9.125.83:9300}]]])

主要なマスターポッドのログには、各ノードがいつクラスターに追加されるかが明確に示されます。 デバッグの問題の場合に非常に役立ちます。

#KibanaとES-HQの導入
KibanaはESデータを視覚化するためのシンプルなツールであり、ES-HQはElasticsearchクラスターの管理と監視に役立ちます。 KibanaとES-HQの展開では、次の点に注意してください。

  1. Dockerイメージの環境変数としてES-Clusterの名前を指定する必要があります。

  2. Kibana / ES-HQデプロイメントにアクセスするためのサービスは、組織の内部のみです。つまり、パブリックIPは作成されません。 GCP内部ロードバランサーを使用する必要があります。

###Kibanaのデプロイメント
次のマニフェストを使用して、Kibanaのデプロイメントとサービスを作成します。

apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: logging
  name: kibana
  labels:
    component: kibana
spec:
  replicas: 1
  selector:
    matchLabels:
     component: kibana
  template:
    metadata:
      labels:
        component: kibana
    spec:
      containers:
      - name: kibana
        image: docker.elastic.co/kibana/kibana-oss:6.2.2
        env:
        - name: CLUSTER_NAME
          value: my-es
        - name: ELASTICSEARCH_URL
          value: http://elasticsearch.elasticsearch:9200
        resources:
          limits:
            cpu: 200m
          requests:
            cpu: 100m
        ports:
        - containerPort: 5601
          name: http
---
apiVersion: v1
kind: Service
metadata:
  namespace: logging
  name: kibana
  annotations:
    cloud.google.com/load-balancer-type: "Internal"
  labels:
    component: kibana
spec:
  selector:
    component: kibana
  ports:
  - name: http
    port: 5601
  type: LoadBalancer 

###ES-HQのデプロイメント
次のマニフェストを使用して、ES-HQの展開とサービスを作成します。

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: es-hq
  namespace: elasticsearch
  labels:
    component: elasticsearch
    role: hq
spec:
  replicas: 1
  template:
    metadata:
      labels:
        component: elasticsearch
        role: hq
    spec:
      containers:
      - name: es-hq
        image: elastichq/elasticsearch-hq:release-v3.4.0
        env:
        - name: HQ_DEFAULT_URL
          value: http://elasticsearch:9200
        resources:
          limits:
            cpu: 0.5
        ports:
        - containerPort: 5000
          name: http
---
apiVersion: v1
kind: Service
metadata:
  name: hq
  namespace: elasticsearch
  labels:
    component: elasticsearch
    role: hq
spec:
  selector:
    component: elasticsearch
    role: hq
  ports:
  - name: http
    port: 5000
  type: LoadBalancer

新しく作成された内部LoadBalancerを使用して、これら両方のサービスにアクセスできます。
[http:// / app / kibana#/ home?_g =()](http:// / app / kibana#/ home?_g =()
)
にアクセスします。

image.png

Kibanaダッシュボード:

[http:// /#!/ clusters / my-es](http:// /#!/ clusters / my-es)にアクセスします。

image.png

#まとめ
これで、ロギング用のESバックエンドのデプロイは完了です。 デプロイしたElasticsearchは、他のアプリケーションでも使用できます。 クライアントノードは高負荷時に自動的にスケーリングする必要があり、ステートフルセットのレプリカ数を増やすことでデータノードを追加できます。 また、いくつかのenv変数を微調整する必要がありますが、それは簡単です。 次のブログでは、Elasticsearchバックエンドにログを送信するためのFilebeatDaemonSetのデプロイについて学習します。

こちらの記事がこの記事の続きとなるPart2になります。Part 2 では、Filebeatの構成について詳しく解説していきます。

Elasticsearchはログ監視スペースを支配しますが、MetricFireは時系列の監視を専門としています。デモを予約して、自分に合った監視ソリューションについて直接お問い合わせください。 Part2にご期待ください:)

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?