マイクロサービス アプリケーションのログ チェーンは通常長く、ログ収集 → ログ バッファリング → ログのフィルタリングとクリーニング → ログの保存 → ログの表示というリンクが含まれます。各リンクには、問題を解決するための複数の対応するコンポーネントがあり、その結果、業界ではさまざまな全体的なソリューションが組み合わされています。 以前、マイクロサービスが IDC コンピュータ ルームの仮想マシンにデプロイされていたとき、マイクロサービス アプリケーションで一般的なログ ソリューションでもある ELK (Elasticsearch、Logstash、Kibana) ソリューションを使用していました。数年前、アプリケーションの展開全体が Kubernetes に切り替えられた後も、私はこのソリューションを使い続けました。 以下では、Kubernetes シナリオにおける ELK ベースのログ ソリューションを紹介します。全体的なアイデア: Filebeat -> Kafka -> Logstash -> Elasticsearch -> Kibana。 1. ログデータフローログデータの流れを下図に示します。 2. ログ収集2.1 コンテナログはどこにありますか?まず、コンテナは K8S クラスター ノード上の単なるプロセスであるという概念を理解する必要があります。 K8S クラスター マシン上でこの Docker プロセスを見つけるには、対応するフォルダーに移動してログ ファイルを表示します。 通常、コンテナ ログはホスト上の /var/lib/docker/containers/ ディレクトリに保存されます。 # 日志在宿主机的这个文件夹下cd /var/lib/docker/containers # 用这个命令可以查找对应的日志文件find /var/lib/docker/containers -name "*-json.log" /var/lib/docker/containers/ に移動すると、不規則なフォルダーが多数表示されます。 これらの不規則なフォルダー名を見ると少し混乱するかもしれませんが、よく見ると、これらのコードは実際には対応する Docker コンテナーの ID であることがわかります。引き続き、名前でコンテナ ID を表示します。 # docker命令查看容器docker ps -a コンテナ ID を見つけると、コンテナ ID の最初の数桁がログ フォルダー名の最初の数桁と完全に一致することがわかります。 docker ps によって表示されるコンテナ ID には、ID 全体の最初の数桁のみが表示されます。 ログフォルダに入ると、特定の json ログファイルが表示されます。 これで、ログ ファイルが保存される場所がわかりました。もちろん、ログ レベルを制御し、ログのクリーニングを適切に行う必要があります。そうしないと、ログの数が多くなり、ディスク領域が不足することになります。 Pod が破棄されると、ログ ファイルも破棄されます。 ファイルが見つかったら、次のステップはログを収集する方法を確認することです。 2.2 ログ収集ツールログ収集ツールは多数あります。この記事では、ログ収集ツールとして Filebeat を使用します。 Filebeat は、ログとファイルを転送および集約するための軽量の配送プログラムです。 Filebeat はサーバーにエージェントとしてインストールされ、指定したログ ファイルまたは場所を監視します。ログ イベントは収集され、Elasticsearch、Logstash、または Kafka に転送されます。公式ドキュメントに示されているワークフローは次のとおりです。 Filebeat の主な利点は次のとおりです。 - 軽量で使いやすい
- 無料でオープンソース
- リソース利用率が低い
- 良いパフォーマンス
2.3 ログの収集方法ログ収集ツールを選択したら、次のステップはデータの収集方法です。 K8S デプロイメント シナリオでは、各ノードでコンテナ ログを収集する場合、自動デプロイメントに Deamonset コントローラーを使用する必要があります。これにより、新しいノードが追加されるたびに、Filebeat Pod が自動的にデプロイされます。 Filebeat が各ノードに自動的にインストールされると、各ノードのログが自動的に収集され、Kafka に出力されます。 Filebeat の一般的な構成 yaml は次のとおりです。 apiVersion: v1 kind: ConfigMap metadata: name: filebeat-config namespace: ops-monit labels: k8s-app: filebeat data: filebeat.yml: |- filebeat.inputs: - type: container #因为是采集的容器日志,所以这里要用container 不能用log,否则拿不到容器日志enable: true stream: stdout #只取stdout日志paths: - /var/log/containers/*demo*.log #采集了demo环境的所有日志processors: - add_kubernetes_metadata: # 增加kubernetes的属性in_cluster: true host: ${NODE_NAME} matchers: - logs_path: logs_path: "/var/log/containers/" - drop_event: when: contains: message: "INFO" - drop_event: when: contains: message: "DEBUG" # 配置多行显示multiline.type: pattern multiline.pattern: '^[0-9]{4}-[0-9]{2}-[0-9]{2}' multiline.negate: true multiline.match: after fields: logtype: applog output.kafka: hosts: ['172.10.10.10:9092','172.10.10.11:9092','172.10.10.12:9092'] topic: 'topic-bizlog' partition.round_robin: reachable_only: false --- apiVersion: apps/v1 kind: DaemonSet metadata: name: filebeat namespace: ops-monit labels: k8s-app: filebeat spec: selector: matchLabels: k8s-app: filebeat template: metadata: labels: k8s-app: filebeat spec: serviceAccountName: filebeat terminationGracePeriodSeconds: 30 dnsPolicy: ClusterFirstWithHostNet containers: - name: filebeat image: elastic/filebeat:7.12.1 args: [ "-c", "/etc/filebeat.yml", "-e", ] env: - name: ELASTICSEARCH_HOST value: "172.10.20.10" - name: ELASTICSEARCH_PORT value: "9200" - name: ELASTICSEARCH_USERNAME value: - name: ELASTICSEARCH_PASSWORD value: - 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: cpu: 3000m memory: 2000Mi requests: cpu: 500m memory: 100Mi volumeMounts: - name: timezone mountPath: /etc/localtime - 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 volumes: - name: timezone hostPath: path: /usr/share/zoneinfo/Asia/Shanghai - name: config configMap: defaultMode: 0640 name: filebeat-config - name: varlibdockercontainers hostPath: path: /var/lib/docker/containers - name: varlog hostPath: path: /var/log - name: data hostPath: path: /var/lib/filebeat-data type: DirectoryOrCreate --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: filebeat namespace: ops-monit subjects: - kind: ServiceAccount name: filebeat namespace: ops-monit roleRef: kind: ClusterRole name: filebeat apiGroup: rbac.authorization.k8s.io --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: filebeat namespace: ops-monit labels: k8s-app: filebeat rules: - apiGroups: [""] # "" indicates the core API group resources: - namespaces - pods - nodes verbs: - get - watch - list --- apiVersion: v1 kind: ServiceAccount metadata: name: filebeat namespace: ops-monit labels: k8s-app: filebeat --- 3. ログのバッファリング、フィルタリング、クリーニング、保存、表示3.1 バッファKafka はメッセージ処理エンジンであり、ここではログ データのバッファ ツールとして Kafka が使用されます。 Kafka には 2 つの用途があります。 - バッファとして、ダウンストリームが時間内にログ データを大量に消費するのを防ぐために、メッセージ バッファ レイヤーを追加する必要があります。このレイヤーは必須です。
- Kafka メッセージは他のアプリケーションによって監視および消費され、フィルタリングされて WeChat、DingTalk、電子メールなどにアラーム情報として出力されます。
3.2.フィルタリング、クリーニング、転送Logstash は、さまざまなソースからデータを取り込むためのさまざまなプラグインが付属するログ収集および処理エンジンです。そして、データを変換してから宛先に転送することができます。私は、ログの取り込み、フィルタリング、クリーニング、転送のためのツールとして Logstash を使用しています。 これは大まかな Logstash Conf ファイルです。ファイルの内容は、入力、フィルター、出力の 3 つの部分に分かれています。 input { kafka { bootstrap_servers=>"172.10.7.79:9092" topics=>["topic-bizlogs"] codec => "json" } } filter{ mutate{ split => ["message", "|"] add_field => { "log_time" => "%{[message][0]}"} add_field => { "level" => "%{[message][1]}"} add_field => { "class" => "%{[message][2]}"} add_field => { "line" => "%{[message][3]}"} add_field => { "thread" => "%{[message][4]}"} add_field => { "log_message" => "%{[message][5]}"} add_field => { "env" => "%{[kubernetes][namespace]}"} add_field => { "podName" => "%{[kubernetes][pod][name]}"} add_field => { "podId" => "%{[kubernetes][pod][uid]}"} add_field => { "image" => "%{[container][image][name]}"} add_field => { "imageId" => "%{[container][id]}"} add_field => { "nodeId" => "%{[kubernetes][node][uid]}"} add_field => { "nodeName" => "%{[kubernetes][node][name]}"} add_field => { "nodeHostName" => "%{[kubernetes][node][hostname]}"} add_field => { "logPath" => "%{[log][file][path]}"} add_field => { "appName" => "%{[kubernetes][labels][app]}"} remove_field => ["agent","fields","input","ecs","host","@version","kubernetes","stream","log","container"] } } output{ elasticsearch{ hosts=>["172.11.4.82:9200"] index => "%{appName}‐%{+YYYY.MM.dd}" } } 3.3 保存と検索Elasticsearch はスケーラブルな検索エンジンです。ここでは、ログの保存および検索ツールとして Elasticsearch を使用します。 3.4 ディスプレイKibana を使用して、ログの視覚的な UI を構築します。 4. まとめこの記事では主に、Kubernetes シナリオでより実用的で簡単に実装できる ELK ベースのログ ソリューションを紹介します。全体的なアイデア: Filebeat -> Kafka -> Logstash -> Elasticsearch -> Kibana。 この記事では、Kafka、Logstash、Elasticsearch、Kibana のインストールについては紹介しません。いくつかの構成ファイルについてのみ言及されています。読者はインストールプロセス中に情報を参照し、自分で構築することができます。 |