AivenでKubernetesログをナビゲートする

<font color="Grey">*[Navigating your Kubernetes logs with Aiven](https://aiven.io/blog/navigating-your-kubernetes-logs-with-aiven)の翻訳です。*</font>

2021年7月19日

# AivenでKubernetesログをナビゲートする

Kubernetesのようなコンテナ・オーケストレーターでは、ログファイルが不足することはありません。その膨大なデータを最大限に活用する方法をご紹介します。

ログはアプリケーションの健全性を把握するために非常に重要であり、問題が発生した場合には問題の診断に役立ちます。ログを取得、集約、検索するための方法やツールは、診断プロセスをよりシンプルにします。Kubernetesのようなマイクロサービスやコンテナオーケストレーターの採用により、ログはより多くの場所から、より多くのフォーマットで送られてくるため、ログの重要性はさらに増しています。


何百、何千ものPodが何十ものノードでログを作成しているため、異なるタイプのサービスごとにログ取得エージェントを各Podにインストールするのは、不可能ではないにしても面倒です。この問題を解決する1つの方法は、各NodeにログエージェントをKubernetesデプロイし、すべてのPodのログをキャプチャし、どこかにエクスポートすることです。各Podで何が実行されているかを知る必要のないKubernetesの抽象化でこれを実現できる：

[DaemonSet](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/)。  

簡単に説明すると、DaemonSetは、ユーザーが定義した基準に基づいて、一部またはすべてのNode上でPodのスケジューリングを可能にします。


全体的なプロセスは次のとおりです：


1.Kubernetesクラスタをセットアップする
2.ログを生成するPodを作成する
3.クラスタ内の各Podから外部の[OpenSearch](https://aiven.io/opensearch)クラスタにログをプッシュする。


[Aiven for OpenSearch](https://aiven.io/)サービスを利用します。これは、直感的で、箱から出しても安全で、拡張のための基盤（例えば、最初は[Apache Kafka](https://aiven.io/kafka)にログをプッシュし、その後OpenSearchにプッシュする）を提供してくれるからです。[Aiven for Apache Kafka Connect](https://aiven.io/kafka-connect)での方法については、Aivenのヘルプ記事をご覧ください。

[Aiven for Apache Kafka用のOpenSearchシンクコネクターの作成](https://help.aiven.io/en/articles/2349675-aiven-kafka-elasticsearch-sink-connector)をご覧ください。


## 依存関係をインストールする


このチュートリアルのコードはすべて<https://github.com/aiven/k8s-logging-demo>にあります。


コードはこのチュートリアルで説明されているとおりに使うことができますが、本当にやり込むのであれば、APIをビルドしてクラスタにデプロイし、Kafkaインテグレーションをセットアップする手順もあります。


まずはリポジトリのクローンから始めよう：



```
git clone https://github.com/aiven/k8s-logging-demo.git
cd k8s-logging-demo`` クリップボードにコピーする
```

以下のローカル依存パッケージがインストールされていることを確認してください：


* [Docker](https://docs.docker.com/get-docker/)
* [Minikube](https://minikube.sigs.k8s.io/docs/start/)
* [Kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl)
* [Helm](https://helm.sh/docs/intro/install/)


## Kubernetesクラスタを作成する


MinikubeでKubernetesクラスタを作成するには、次のように入力します：



```
minikube start`クリップボードにコピーする
```

クラスタが稼働していることを確認するには、次のようにリストします。

このようにクラスタ内のすべてのPodを一覧表示することで、クラスタが起動していることを確認できます：



```
kubectl get pods --all-namespaces`Copy to clipboard
```

するとこのように表示されるはずです：



```
namespace名 ready status restarts age
kube-system coredns-74ff55c5b-mf9dj 1/1 稼働中 0 14d
kube-system etcd-minikube 1/1 稼働中 0 14d
kube-system kube-apiserver-minikube 1/1 ランニング 0 14d
kube-system kube-controller-manager-minikube 1/1 ランニング中 0 14d
kube-system kube-proxy-bx4gl 1/1 ランニング 0 14d
kube-system kube-scheduler-minikube 1/1 ランニング 0 14d
kube-system storage-provisioner 1/1 ランニング 2 14d`Copy to clipboard
```

デフォルト以外の名前空間を使用するので、それを作成しましょう。

を作成しましょう：



```
kubectl create namespace logging`クリップボードにコピーする
```

## クラスタにPodを追加する


Kubernetesクラスタができたので、これを使って何かしてみよう。FluentDと同様に、ランダムなログを生成するPodをクラスタにデプロイする。


[FluentD](https://docs.fluentd.org/)は、何百もの[プラグイン](https://www.fluentd.org/plugins)を持つ、データソーシング、集約、転送クライアントです。多くのソース、変換、出力をサポートしています。例えば、Apacheのログをキャプチャし、Grokパーサーに渡し、カナダ発のログのSlackメッセージを作成し、すべてのログをKafkaに出力することができる。


クラスタ内でログを生成するために、ランダムにログを生成するPodを作ってみよう：



```
kubectl create deployment -n logging --image=chentex/random-logger:latest logger``Copy to clipboard
```

事前にビルドした Helm Chart を使って FluentD をインストールするので、その前にレポを追加して依存関係を更新する必要がある。このリポジトリには、FluentD のすべてのコンポーネントを記述した Kubernetes テンプレートが含まれており、新しいコンポーネントでキャッシュを更新するようチャートに指示します（もしあれば）。



```
helm repo add bitnami https://charts.bitnami.com/bitnami
helm リポジトリ更新
helm dependency update chart``クリップボードにコピーする
```

式の最後の部分は、ログの外部ストアを取得する。そのために、[Aiven](https://aiven.io/) for Elasticsearchを使ってみましょう。無料アカウントを作成してください。


そして、Elasticsearchを実行するための新しいプロジェクトを作成します：


![kubernetes-1](https://cdn.sanity.io/images/sczeoy4w/production/160a945ef8c8ba351ab009b87568a9309b0149ef-268x462.png?q=80&fit=min&auto=format&dpr=1.5 "Aiven Consoleで新しいプロジェクトを作成する")


Create a new service`をクリックし、Elasticsearchを選択します。


次にクラウドプロバイダーと地域を選択します。最後のステップでは、サービスプランを選択します -- 今回はHobbyistプランを使用します。


デフォルト名は後で変更できないので、この時点で識別可能な名前に変更しておくといいだろう。


![kubernetes-2](https://cdn.sanity.io/images/sczeoy4w/production/6dec7156dc73db9e6fb641375f65543a19e47d99-1143x562.png?q=80&fit=min&auto=format&dpr=1.5 "Setting the service name")


1分ほどでElasticsearchサービスが使えるようになります。作成したサービスをクリックすると、コンソールで全ての接続情報を見ることができます。


![kubernetes-3](https://cdn.sanity.io/images/sczeoy4w/production/6c83218634e7f73506c9a426f18e4296aa8bdbfc-878x394.png?q=80&fit=min&auto=format&dpr=1.5 "Connection information")


Host、Port、User、Passwordを控えておきましょう。これらはHelm Chartの設定に必要になります。


これでHelmチャートをデプロイする準備ができました：



```

-set-elasticsearch.hosts=<ESホスト> ୧-͈ᴗ-͈.
-set-elasticsearch.user=<ESユーザー
--set elasticsearch.pw=<ES Password>``Copy to clipboard
```

<ESホスト>`には、Aiven Consoleから取得したホストとポートを連結します。私の場合は以下のようになります：  

https://something-unique-sa-demo.aivencloud.com:24947`。  

(ここで設定されている値は、FluentD の設定のサブセットに過ぎないことに注意してください。

[チャート定義](https://github.com/bitnami/charts/tree/master/bitnami/fluentd/#installing-the-chart))


logging`名前空間のPodを調べることで、正しくビルドされていることを確認できます。



```
kubectl -n logging get pods`クリップボードにコピーする
```

以下のように表示されるはずです。



```
名前 ready status restartarts age
log-demo-fluentd-0 1/1 実行中 0 7m32s
log-demo-fluentd-wj56t 1/1 実行中 0 7m32s
logger-56db6f88d9-h8r8d 1/1 実行中 0 7m8s`クリップボードへコピー
```

すべてのPodの準備がまだできていない場合は、数秒待ってからもう一度確認してください。


## ログの表示と検索


デプロイされた [configuration](https://github.com/aiven/k8s-logging-demo/blob/main/chart/templates/fluentd-configmap.yaml) は全ての Node から全てのログを取得します（取得しないように設定することも可能です）ので、OpenSearch のダッシュボードに向かうとログが表示されているはずです。Aiven は自動的に Elasticsearch と一緒に OpenSearch ダッシュボードをデプロイし、接続情報もコンソールで確認できます。


![kubernetes-4](https://cdn.sanity.io/images/sczeoy4w/production/da49fff76d4ee584cf51f494d577fad7ae27d841-849x366.png?q=80&fit=min&auto=format&dpr=1.5 "Kibana 接続情報")


OpenSearch ダッシュボードにログインしたら、開発ツールに移動します。


![kubernetes-5](https://cdn.sanity.io/images/sczeoy4w/production/f49ee1611dab4c131034abaaf00ee33c43adef50-339x675.png?q=80&fit=min&auto=format&dpr=1.5 "Kibana dev tools")


以下のクエリを実行し、`kube-system` ネームスペースに由来するログを探します：



```
GET /search
{
 "query"：{
 "term"：{
 "kubernetes.namespace_name.keyword"：{
 "value"："kube-system"
 }
 }
 }
クリップボードにコピー
```

結果は次のようになるはずだ：



```
`{
 "\_index" : "minikube-2021.05.27"、
 "index"："minikube-2021.05.27"、"type"："˶_doc
 "\_id" : "6dXGrnkBn7BUvoFdGaNm"、
 "\_score" : 0.0020360171、
 "\_source" : {
[ "log" : """I0527 17:01:23.041467 1 client.go:360] parsed scheme："passthrough" """、
 "stream" : "stderr"、
 "docker" : {
 "container\_id" : "b8a38739fc4a2694995837f2dfe773e011432b73f641b02eb54a7622ba3baffc"
 },
 "kubernetes" : {
 "container_name" : "kube-apiserver"、
 "namespace_name" : "kube-system"、
 "Pod_name" : "kube-apiserver-minikube"、
 "container_image" : "k8s.gcr.io/kube-apiserver:v1.20.2"、
 "container\_image\_id" : "docker-pullable://k8s.gcr.io/kube-apiserver@sha256:465ba895d578fbc1c6e299e45689381fd01c54400beba9e8f1d7456077411411",
 "Pod_id" : "d825fef1-15d4-4202-818a-5deef0a30666"、
 "host" : "minikube"、
 "labels" : {
 "component" ："kube-apiserver"、
 "tier" : "control-plane"
 },
 "master_url" : "https://10.96.0.1:443/api"、
 "namespace_id" : "9925f802-c2c1-44a0-9a71-534d16a609af"
 },
 "@timestamp" : "2021-05-27T17:01:23.041773900+00:00"、
 "tag" : "kubernetes.var.log.containers.kube-apiserver-minikube\_kube-system\_kube-apiserver-b8a38739fc4a2694995837f2dfe773e011432b73f641b02eb54a7622ba3baffc.log"
 }
 クリップボードにコピーする
```

ログドキュメントには、ログメッセージ、ログが発生した名前空間、ログが発生したタイムスタンプ、その他いくつかの識別情報が記載されている。


OpenSearch のダッシュボードに戻り、別のリクエストを発行して、ロギングポッドからログが見つかるか確認してみましょう：



```
GET /search
{
 "query"：{
 "match"：{
 "log"：{
 "query"："例外"
 }
 }
 }
クリップボードにコピーする
```

たいていの場合、いくつかの結果が出るだろうが、最初のものはロガー・ポッドのランダム・エラー・ログに関連するログであるはずだ。


## 更新とクリーンアップ


例えば、FluentD の設定を変更したり、既存のサービスにエンドポイントを追加したり、全く新しいサービスを追加したりします：



```
helm upgrade -n logging log-demo <インストール時に設定したその他のパラメータ>`クリップボードにコピーする
```

変更を有効にするには、Pod を再デプロイする必要があるかもしれません。


インストールを破棄するには



```
helm delete -n logging log-demo
kubectl delete -n logging deployment/logger`クリップボードにコピーする
```

## まとめ


このガイドでは、何もないところから始めて、ロギングレイヤーを持つKubernetesアプリケーションを作成した。


ここでのコードと手順は、[Google Kubernetes Engine](https://cloud.google.com/kubernetes-engine) (GKE)や[Elastic Kubernetes Service](https://aws.amazon.com/eks/) (EKS)のような別のKubernetesプロバイダを使用するように簡単に拡張でき、Helmの設定もKafkaへのデータ送信やメトリクスのキャプチャのような他のユースケースを含むように簡単に拡張できます。


データがどこから来るのか、どこへ行くのか、どのような種類のデータであるかにかかわらず、Aivenプラットフォームには、あなたの旅を支援するツールとサービスがあります。


## 続きを読む


[外部 Elasticsearch ロギング](https://aiven.io/blog/external-elasticsearch-logging-output-now-supported-by-aiven)


[Kubernetes ロギングアーキテクチャ](https://kubernetes.io/docs/concepts/cluster-administration/logging/)


[Kubernetes Logging with ELK Stack](https://logz.io/blog/deploying-the-elk-stack-on-kubernetes-with-helm/#:~:text=ELK%20integrates%20natively%20with%20Kubernetes,deploying%20and%20managing%20the%20former.)


Aivenのサービスをまだお使いではありませんか？<https://console.aiven.io/signup>から今すぐ無料トライアルにお申し込みください！


また、[changelog](https://aiven.io/changelog)や[blog](https://aiven.io/blog)のRSSフィード、または[LinkedIn](https://www.linkedin.com/company/aiven/)や[Twitter](https://twitter.com/aiven_io)のアカウントをフォローし、製品や機能関連の最新情報をご確認ください。