Kubernetes クラスターにおけるログ収集のさまざまな方法¶
はじめに¶
企業のアプリケーションシステムにとって、ログは非常に重要な役割を果たします。特に Kubernetes 環境ではログ収集がさらに複雑になるため、DataKit はログ収集に対して非常に強力なサポートを提供し、多様な環境や技術スタックに対応しています。ここでは、DataKit のログ収集の使用方法について詳しく説明します。
前提条件¶
Guance にログインし、【インテグレーション】→【Datakit】→【Kubernetes】の順に進み、案内に従って Kubernetes クラスターに DataKit をインストールしてください。デプロイに使用する datakit.yaml ファイルは、以降の操作で使用します。
DataKit の詳細設定¶
1 ログレベルの設定¶
DataKit のデフォルトのログレベルは Info です。ログレベルを Debug に変更する場合は、datakit.yaml に環境変数を追加します。
2 ログ出力方法の設定¶
DataKit はデフォルトでログを /var/log/datakit/gin.log および /var/log/datakit/log に出力します。コンテナ内にログファイルを生成したくない場合は、datakit.yaml に環境変数を追加します。
DataKit が生成したログは、kubectl コマンドと POD 名を使用して確認できます。『注意』:ENV_LOG_LEVEL を debug に設定すると大量のログが生成されるため、その場合は ENV_LOG を stdout に設定することは推奨しません。
ログ収集¶
1 stdout 収集¶
1.1 stdout ログの全収集¶
DataKit は stdout に出力されたコンテナログを収集できます。datakit.yaml を使用して DataKit をデプロイすると、デフォルトで container 収集機能が有効になります。
- name: ENV_DEFAULT_ENABLED_INPUTS
value: cpu,disk,diskio,mem,swap,system,hostobject,net,host_processes,container
この時、DataKit コンテナ内に /usr/local/datakit/conf.d/container/container.conf 設定ファイルが生成されます。デフォルト設定では、pubrepo.guance.com/datakit/logfwd で始まるイメージを除くすべての stdout ログを収集します。
container_include_log = [] # 相当于image:*
container_exclude_log = ["image:pubrepo.guance.com/datakit/logfwd*"]
1.2 カスタム stdout ログ収集¶
ログの発生源をより明確に区別し、タグを追加したり、ログを解析する pipeline ファイルを指定するには、カスタム方式を使用します。つまり、デプロイする yaml ファイルに annotations を追加します。
apiVersion: apps/v1
kind: Deployment
metadata:
name: log-demo-service
labels:
app: log-demo-service
spec:
replicas: 1
selector:
matchLabels:
app: log-demo-service
template:
metadata:
labels:
app: log-demo-service
annotations:
# 以下を追加
datakit/logs: |
[
{
"source": "pod-logging-testing-demo",
"service": "pod-logging-testing-demo",
"pipeline": "pod-logging-demo.p",
"multiline_match": "^\\d{4}-\\d{2}-\\d{2}"
}
]
Annotations パラメータの説明
- source: データソース
- service: タグマーク
- pipeline: pipeline スクリプト名
- ignore_status:
- multiline_match: 1行のログを一致させる正規表現。例では日付(2021-11-26 など)で始まるものを1行のログとして扱い、次の行がこの日付で始まらない場合は、その行のログは前の行の一部と見なされます。
- remove_ansi_escape_codes: ANSI エスケープコード(標準出力のテキスト色など)を削除するかどうか
1.3 コンテナの stdout ログを収集しない¶
コンテナ収集機能を有効にすると、コンテナが stdout に出力するログが自動的に収集されます。収集したくないログがある場合は、以下の方法があります。
1.3.1 POD の stdout ログ収集を無効にする¶
アプリケーションをデプロイする yaml ファイルに annotations を追加し、disable を true に設定します。
apiVersion: apps/v1
kind: Deployment
metadata:
...
spec:
...
template:
metadata:
annotations:
## 以下を追加
datakit/logs: |
[
{
"disable": true
}
]
1.3.2 標準出力のリダイレクト¶
stdout ログ収集が有効になっており、コンテナのログも stdout に出力されている場合、両方を変更したくない場合は、起動コマンドを変更して標準出力をリダイレクトできます。
1.3.3 container 収集機能のフィルタリング機能¶
stdout ログの収集をより簡単に制御したい場合は、container.conf ファイルを上書きすることを推奨します。つまり、ConfigMap を使用して container.conf を定義し、container_include_log と container_exclude_log の値を変更して、DataKit にマウントします。datakit.yaml で以下のように変更します。
---
apiVersion: v1
kind: ConfigMap
metadata:
name: datakit-conf
namespace: datakit
data:
#### container
container.conf: |-
[inputs.container]
docker_endpoint = "unix:///var/run/docker.sock"
containerd_address = "/var/run/containerd/containerd.sock"
enable_container_metric = true
enable_k8s_metric = true
enable_pod_metric = true
## Containers logs to include and exclude, default collect all containers. Globs accepted.
container_include_log = []
container_exclude_log = ["image:pubrepo.guance.com/datakit/logfwd*", "image:pubrepo.guance.com/datakit/datakit*"]
exclude_pause_container = true
## Removes ANSI escape codes from text strings
logging_remove_ansi_escape_codes = false
kubernetes_url = "https://kubernetes.default:443"
## Authorization level:
## bearer_token -> bearer_token_string -> TLS
## Use bearer token for authorization. ('bearer_token' takes priority)
## linux at: /run/secrets/kubernetes.io/serviceaccount/token
## windows at: C:\var\run\secrets\kubernetes.io\serviceaccount\token
bearer_token = "/run/secrets/kubernetes.io/serviceaccount/token"
# bearer_token_string = "<your-token-string>"
[inputs.container.tags]
# some_tag = "some_value"
# more_tag = "some_other_value"
volumeMounts:
- mountPath: /usr/local/datakit/conf.d/container/container.conf
name: datakit-conf
subPath: container.conf
container_includeとcontainer_excludeはimageで始まる必要があり、形式は"image:<glob规则>"です。glob ルールがコンテナイメージに対して適用されることを示します。- Glob ルール は軽量な正規表現で、
*?などの基本的なマッチングユニットをサポートします。
例えば、イメージ名に log-order を含み、log-pay を含まないものだけを収集したい場合は、以下のように設定します。
『注意』:ある POD で stdout ログ収集が有効になっている場合、logfwd や socket ログ収集を併用しないでください。ログが重複して収集されます。
2 logfwd 収集¶
これは Sidecar パターンを使用したログ収集方法です。同じ POD 内のコンテナがストレージを共有する仕組みを利用し、logfwd が Sidecar としてビジネスコンテナのログファイルを読み取り、DataKit に送信します。具体的な使用方法については、Pod ログ収集ベストプラクティス の方法2を参照してください。
3 socket 収集¶
DataKit が Socket ポート(例:9542)を開放すると、ログがこのポートにプッシュされます。Java の log4j や logback はログプッシュをサポートしています。以下では、SpringBoot に Logback を組み込んだ場合を例に、socket ログ収集を実装します。
3.1 Appender の追加¶
logback-spring.xml ファイルに socket Appender を追加します。
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<springProperty scope="context" name="dkSocketHost" source="datakit.socket.host" />
<springProperty scope="context" name="dkSocketPort" source="datakit.socket.port" />
<contextName>logback</contextName>
<!-- ログルートディレクトリ -->
<property name="log.path" value="./logs"/>
<!-- ログ出力形式 -->
<property name="log.pattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - - %msg%n" />
<!-- コンソールにログを出力 -->
<appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
</appender>
...
<!-- 以下は追加する Socket appender -->
<appender name="socket" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<!-- datakit host: logsocket_port -->
<destination>${dkSocketHost}:${dkSocketPort}</destination>
<!-- ログ出力エンコーディング -->
<encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
<providers>
<timestamp>
<timeZone>UTC+8</timeZone>
</timestamp>
<pattern>
<pattern>
{
"severity": "%level",
"appName": "${logName:-}",
"trace": "%X{dd.trace_id:-}",
"span": "%X{dd.span_id:-}",
"pid": "${PID:-}",
"thread": "%thread",
"class": "%logger{40}",
"msg": "%message\n%exception"
}
</pattern>
</pattern>
</providers>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="Console"/>
<appender-ref ref="file_info"/>
<appender-ref ref="socket" />
</root>
</configuration>
3.2 設定の追加¶
SpringBoot プロジェクトの application.yml ファイルに設定を追加します。
3.3 依存関係の追加¶
SpringBoot プロジェクトの pom.xml に依存関係を追加します。
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>4.9</version>
</dependency>
3.4 DataKit に logging-socket.conf ファイルを追加¶
DataKit の datakit.yaml ファイルに以下の内容を追加します。
volumeMounts: # この位置に以下の3行を追加
- mountPath: /usr/local/datakit/conf.d/log/logging-socket.conf
name: datakit-conf
subPath: logging-socket.conf
---
apiVersion: v1
kind: ConfigMap
metadata:
name: datakit-conf
namespace: datakit
data:
logging-socket.conf: |-
[[inputs.logging]]
# only two protocols are supported:TCP and UDP
sockets = [
"tcp://0.0.0.0:9542",
#"udp://0.0.0.0:9531",
]
ignore = [""]
source = "demo-socket-service"
service = ""
pipeline = ""
ignore_status = []
character_encoding = ""
# multiline_match = '''^\S'''
remove_ansi_escape_codes = false
[inputs.logging.tags]
# some_tag = "some_value"
# more_tag = "some_other_value"
Socket ログ収集の詳細については、logback socket ログ収集ベストプラクティス を参照してください。
4 ログファイル収集¶
Linux ホストにインストールされた DataKit がそのホストのログを収集する方法は、logging.conf ファイルをコピーし、logging.conf ファイル内の logfiles の値をログの絶対パスに変更することです。
Kubernetes 環境では、まず POD が生成するログディレクトリ /data/app/logs/demo-system をホストマシンの /var/log/k8s/demo-system にマウントし、次に DaemonSet で DataKit をデプロイし、/var/log/k8s/demo-system ディレクトリをマウントします。これにより、DataKit はホストマシン上の /rootfs/var/log/k8s/demo-system/info.log ログファイルを収集できます。
volumeMounts:
- name: app-log
mountPath: /data/app/logs/demo-system
...
volumes:
- name: app-log
hostPath:
path: /var/log/k8s/demo-system
volumeMounts: # この位置に以下の3行を追加
- mountPath: /usr/local/datakit/conf.d/log/logging.conf
name: datakit-conf
subPath: logging.conf
---
apiVersion: v1
kind: ConfigMap
metadata:
name: datakit-conf
namespace: datakit
data:
#### logging
logging.conf: |-
[[inputs.logging]]
## required
logfiles = [
"/rootfs/var/log/k8s/demo-system/info.log",
]
## glob filteer
ignore = [""]
## your logging source, if it's empty, use 'default'
source = "k8s-demo-system-log"
## add service tag, if it's empty, use $source.
#service = "k8s-demo-system-log"
## grok pipeline script path
pipeline = ""
## optional status:
## "emerg","alert","critical","error","warning","info","debug","OK"
ignore_status = []
## optional encodings:
## "utf-8", "utf-16le", "utf-16le", "gbk", "gb18030" or ""
character_encoding = ""
## The pattern should be a regexp. Note the use of '''this regexp'''
## regexp link: https://golang.org/pkg/regexp/syntax/#hdr-Syntax
multiline_match = '''^\d{4}-\d{2}-\d{2}'''
[inputs.logging.tags]
# some_tag = "some_value"
# more_tag = "some_other_value"
Pipeline¶
Pipeline は主に、非構造化テキストデータを解析したり、構造化テキスト(JSON など)から部分的な情報を抽出するために使用されます。ログに関しては、主にログの生成時間やログレベルなどの情報を抽出します。特に、Socket で収集されたログは JSON 形式であるため、検索ボックスでキーワード検索できるように解析する必要があります。Pipeline の詳細については、以下の記事を参照してください。
異常検知¶
ログに異常が発生し、アプリケーションに大きな影響を与える場合、Guance のログ異常検知機能を使用し、アラートを設定することで、異常を適切な監視対象に迅速に通知できます。Guance のアラートは、メール、DingTalk、SMS、WeCom、Lark などの通知方法をサポートしています。以下では、メールを例にアラートを説明します。
1 通知先の作成¶
Guance にログインし、【管理】→【通知先管理】→【通知先を作成】の順に進み、メールグループを選択し、名前とメールアドレスを入力します。
2 モニターの作成¶
【モニター】→【モニターを作成】→【ログモニタリング】の順にクリックします。
ルール名を入力します。検出指標の log_fwd_demo はログ収集時に設定した source で、その後の error はログに含まれる内容、host_ip はログのタグです。イベント内容では {{host_ip}} を使用して特定のタグの値を出力できます。トリガー条件は 1 を入力し、タイトルと内容はメールで送信されます。入力後、【保存】をクリックします。
3 アラートの設定¶
【モニター】画面で、先ほど作成したモニターをクリックし、【アラート設定】をクリックします。
アラート通知先は、最初の手順で作成したメールグループを選択し、アラートサイレント時間を選択して、【確定】をクリックします。
4 アラートのトリガー¶
アプリケーションで error ログがトリガーされると、通知メールが届きます。






