メインコンテンツへスキップ
  1. Blogs/

ElasticSearchを使ったlog収集4 -kubernetes integration-

·2800 文字·
Blog ElasticSearch Kubernetes
hiroki
著者
hiroki
クラウドを作るお仕事をしてます。
目次
ElasticSearch - 関連記事
4: << この記事 >>

はじめに
#

kubernetesに展開しているAPPのlog収集をElasticSearchのkubernetes Integrationを使って実施します。

今回は以下の様なAPIサーバー一式を用意して、これらのlog収集を実施します。

$ kubectl get pods -n dev
NAME                                    READY   STATUS    RESTARTS   AGE
api-75969fcbb4-9nzm2                    1/1     Running   0          23d
mysql-cluster-0                         2/2     Running   0          24d
mysql-cluster-1                         2/2     Running   0          24d
mysql-cluster-2                         2/2     Running   0          24d
mysql-cluster-router-57c657f6cf-np6jw   1/1     Running   0          24d
redis-master-0                          1/1     Running   0          24d
redis-replicas-0                        1/1     Running   0          24d
worker-6cfbd5dcd5-5ws4k                 1/1     Running   0          23d

$ kubectl logs api-75969fcbb4-9nzm2 -n dev | jq
{
  "level": "info",
  "timestamp": "2024-07-22 23:11:59",
  "caller": "logging/access_logger.go:82",
  "msg": "handled request",
  "requestId": "01J3DCHV6FPB1QPJERFZVAFSP9",
  "remote": "192.168.1.215",
  "host": "192.168.1.215:30000",
  "uri": "/oauth2/token",
  "method": "POST",
  "status": 200,
  "userAgent": "Go-http-client/1.1",
  "responseTimeMs": 213
}

1. kubernetes integrationの追加
#

1. 検証環境の用意

vSphere Integrationを使うには事前にfleet-serverを構築している必要があります。構築方法は第1回を参照ください。

2. kubernetes integrationの追加

Kibanaでkuberenetesと検索すると出てくるので追加します。

alt text

3. 収集するlog,metricsを選ぶ

かなり多くの項目があるのですが、今回はCollect Kubernetes container logsだけ収集することにします。

alt text

これで全てのpodのlogが収集できます。もちろん特定namespace、podだけに絞り込むことができますが後に解説します。

4. 新規Agentのdeploy用manifestの用意

Elastic Agent自体をkuberetesにpodとしてdeployしたいので、New hostsを選びSave and continueで保存します。

alt text

するとdeploy用のmanifestが生成されるので、これを使ってdeployします。

alt text

4-1. deploy前準備1 -elasticsearchとfleetの名前解決-

docker-elkを使っている場合や、k8sからelastic-search, fleet-serverへの名前解決ができない場合には対処が必要です。

manifestには以下の様に、docker-nw内部でのみ名前解決ができるhostnameが割り当てられています。このままではk8sからhttp://fleet-server:8220には名前解決できません。

- name: FLEET_URL
  value: "http://fleet-server:8220"
- name: KIBANA_HOST
  value: "http://kibana:5601"

従ってnameserverや、k8sのnodeの/etc/hostsを変更する等でfleet-serverkibanaが名前解決ができるようします。

私は検証環境である + dnsmasqで独自のDNS-serverを構築しているので、以下の様に無理やり名前解決ができる様にしています。。。

# cat /etc/hosts

192.168.1.203 fleet-server elasticsearch

4-2 deploy前準備2 -HTTPSでFleetと接続するか-

docker-elkを使っている場合や、FleetとElastic AgentがHTTPSで疎通できない場合は対処が必要です。

Elastic AgentとFleetの接続がHTTPSでできない場合は、manifest内部のFLEET_INSECUREをtrueにしておきましょう。

# Set to true to communicate with Fleet with either insecure HTTP or unverified HTTPS
- name: FLEET_INSECURE
  value: "false" # ここをtrueにする

5. k8sにAgentをdeploy

前準備が終わったらmanifestを使ってagentをdeployします。defaultだとnamespace: kube-systemにdeployされます。

$ kubectl apply -f elastic-agent-managed-kubernetes.yml

$ kubectl get pods -n kube-system | grep elastic
elastic-agent-b4nhz                   1/1     Running   
elastic-agent-bjv6k                   1/1     Running  
elastic-agent-m6vkk                   1/1     Running  

deployが成功すると、fleet画面にagentが表示されます。

alt text

6. logの確認

fleetからData streams名を確認します。今回はlogs-kubernetes.container_logs-defaultでした。

alt text

これでDiscoverからcheckすると、kube-systemを含めた全てのpodのログが取得できていることがわかります。

alt text

2. log取得の調整
#

logの取得はこれでできましたが、不要な情報もあったりとカスタマイズしたい点がいくつかあると思います。このカスタマイズはkubernetes integrationの画面から実施できます。

alt text

取得するlogの絞り込み
#

Conditionセクションでは、収集するlogの絞り込みができます。

defaultだと全てのpodsのlogを取得し数が膨大になるので、必要に応じて任意のpod,namespaceだけなど絞り込みをしましょう。

# 特定podのみ
${kubernetes.container.name} == "api"

# 特定namespaceのみ
${kubernetes.namespace} == "dev"

基本的にkubernetes integrationで取得できるfield名でgrepをかけることができます。ドキュメントとして確認したい場合は以下です。

jsonをparseする
#

Additional parsers configurationセクションでは、logのparse処理ができます。

例えばコメントアウトされているndjsonを使うと、jsonのmessageをparseすることができます。

# - ndjson:
#     target: json
#     ignore_decoding_error: true

これによってjsonの文字列が丸ごと入ってしまっている状態から、

alt text

ndjsonを有効にすることで、jsonがparseされてfield毎に保存されます。

alt text

このndjsonには他にもoptionがあるので、ドキュメントを確認しておきましょう

不要なfieldを削除する
#

Processorセクションを使うと、logに様々な処理を追加でかけることができます。 例えばdrop_fieldsを使うことで、任意のfieldを削除しlogの容量を削減することができます。

 - drop_fields:
      fields: [
        "/kubernetes.labels*/"
      ]
      ignore_missing: true
他にも複数の処理がProcessorではできるので、ドキュメントを確認しましょう。

3. トラブルシューティング
#

名前解決ができない
#

fleet-serverとAgentが疎通できないと、ステータスがhealthにならないので注意しましょう。

alt text

elasticsearchへAgentが接続できない
#

まずはElastic Agentのlogを見て状態をcheckしましょう。

kubectl -n kube-system logs <pod名> | jq -r -R 'fromjson?'

その上で401 Unauthorizedが出ている場合は、tokenがreset等で変わったのにAgentには反映されないAgentのbugの可能性があります。

  "log.level": "error",
  "@timestamp": "2024-08-15T10:07:30.230Z",
  "message": "Failed to connect to backoff(elasticsearch(http://elasticsearch:9200)): 401 Unauthorized: {\"error\":{\"root_cause\":[{\"type\":\"security_exception\",\"reason\":\"unable to authenticate with provided credentials and anonymous access is not allowed for this request\",\"additional_unsuccessful_credentials\":\"API key: unable to find apikey with id FYsk05ABBKobXbf_vkfx\",\"header\":{\"WWW-Authenticate\":[\"Basic realm=\\\"security\\\" charset=\\\"UTF-8\\\"\",\"ApiKey\"]}}],\"type\":\"security_exception\",\"reason\":\"unable to authenticate with provided credentials and anonymous access is not allowed for this request\",\"additional_unsuccessful_credentials\":\"API key: unable to find apikey with id FYsk05ABBKobXbf_vkfx\",\"header\":{\"WWW-Authenticate\":[\"Basic realm=\\\"security\\\" charset=\\\"UTF-8\\\"\",\"ApiKey\"]}},\"status\":401}",

Agentのtoken等の状態がhostpathでnodeに保存されて使いまわされることが原因なので、rm -r /var/lib/elastic-agent-managed/kube-system/state等で削除すると新しいtokenが反映されます。

# Mount /var/lib/elastic-agent-managed/kube-system/state to store elastic-agent state
# Update 'kube-system' with the namespace of your agent installation
- name: elastic-agent-state
  hostPath:
    path: /var/lib/elastic-agent-managed/kube-system/state
    type: DirectoryOrCreate

おわりに
#

kubernetes intgrationを使うことで、k8s上のAPPのログ収集をかなり簡単に実施することができました。Elastic Agentもk8s上にdeployされたので冗長化ができ運用も楽そうです。

次回はElasticSearch自体をk8sで稼働させる、Elastic Cloud on Kubernetes (ECK)を紹介したいと思います。

ElasticSearch - 関連記事
4: << この記事 >>

Related

ElasticSearchを使ったlog収集2 -Elastic Agentの追加-
·3798 文字
Blog ElasticSearch
ElasticSearchを使ったlog収集1 -Elastic Agentとは?-
·3778 文字
Blog ElasticSearch
MySQL InnoDB Cluster3 -helmで利用できるoption-
·1613 文字
Blog Kubernetes Mysql