DataKit Operator¶
概述和安装¶
DataKit Operator 是 DataKit 在 Kubernetes 编排的联动项目,旨在协助 DataKit 更方便的部署,以及其他诸如验证、注入的功能。
目前 DataKit-Operator 提供以下功能:
先决条件:
- 推荐 Kubernetes v1.24.1 及以上版本,且能够访问互联网(下载 yaml 文件并拉取对应镜像)
- 确保启用
MutatingAdmissionWebhook和ValidatingAdmissionWebhook控制器 - 确保启用了
admissionregistration.k8s.io/v1API
安装步骤¶
下载 datakit-operator.yaml,步骤如下:
前提条件
- Kubernetes >= 1.14
- Helm >= 3.0+
$ helm install datakit-operator datakit-operator \
--repo https://pubrepo.guance.com/chartrepo/datakit-operator \
-n datakit --create-namespace
查看部署状态:
可以通过如下命令来升级:
$ helm -n datakit get values datakit-operator -a -o yaml > values.yaml
$ helm upgrade datakit-operator datakit-operator \
--repo https://pubrepo.guance.com/chartrepo/datakit-operator \
-n datakit \
-f values.yaml
可以通过如下命令来卸载:
Note
- DataKit-Operator 有严格的程序和 yaml 对应关系,如果使用一份过旧的 yaml 可能无法安装新版 DataKit-Operator,请重新下载最新版 yaml。
- 如果出现
InvalidImageName报错,可以手动 pull 镜像。
配置说明¶
DataKit Operator 配置是 JSON 格式,在 Kubernetes 中单独以 ConfigMap 存放,以环境变量方式加载到容器中。
默认配置如下:
{
"server_listen": "0.0.0.0:9543",
"log_level": "info",
"admission_inject": {
"ddtrace": {
"enabled_namespaces": [],
"enabled_labelselectors": [],
"images": {
"java_agent_image": "pubrepo.guance.com/datakit-operator/dd-lib-java-init:latest"
},
"envs": {
"DD_AGENT_HOST": "datakit-service.datakit.svc.cluster.local",
"DD_TRACE_AGENT_PORT": "9529",
"DD_JMXFETCH_STATSD_HOST": "datakit-service.datakit.svc.cluster.local",
"DD_JMXFETCH_STATSD_PORT": "8125",
"DD_SERVICE": "{fieldRef:metadata.labels['service']}",
"POD_NAME": "{fieldRef:metadata.name}",
"POD_NAMESPACE": "{fieldRef:metadata.namespace}",
"NODE_NAME": "{fieldRef:spec.nodeName}",
"DD_TAGS": "pod_name:$(POD_NAME),pod_namespace:$(POD_NAMESPACE),host:$(NODE_NAME)"
},
"resources": {
"requests": {
"cpu": "100m",
"memory": "64Mi"
},
"limits": {
"cpu": "200m",
"memory": "128Mi"
}
}
},
"profiler": {
"images": {
"java_profiler_image": "pubrepo.guance.com/datakit-operator/async-profiler:0.5.0",
"python_profiler_image": "pubrepo.guance.com/datakit-operator/py-spy:0.1.0",
"golang_profiler_image": "pubrepo.guance.com/datakit-operator/go-pprof:0.1.0"
},
"envs": {
"DK_AGENT_HOST": "datakit-service.datakit.svc.cluster.local",
"DK_AGENT_PORT": "9529",
"DK_PROFILE_VERSION": "1.2.333",
"DK_PROFILE_ENV": "prod",
"DK_PROFILE_DURATION": "240",
"DK_PROFILE_SCHEDULE": "0 * * * *"
},
"resources": {
"requests": {
"cpu": "100m",
"memory": "64Mi"
},
"limits": {
"cpu": "500m",
"memory": "512Mi"
}
}
},
"logfwd": {
"images": {
"logfwd_image": "pubrepo.guance.com/datakit/logfwd:1.86.0"
},
"envs": {
"LOGFWD_DATAKIT_HOST": "{fieldRef:status.hostIP}",
"LOGFWD_DATAKIT_PORT": "9533",
"LOGFWD_DATAKIT_OPERATOR_ENDPOINT": "datakit-operator.datakit.svc:443",
"LOGFWD_GLOBAL_SERVICE": "{fieldRef:metadata.labels['app']}",
"LOGFWD_POD_NAME": "{fieldRef:metadata.name}",
"LOGFWD_POD_NAMESPACE": "{fieldRef:metadata.namespace}",
"LOGFWD_POD_IP": "{fieldRef:status.podIP}"
},
"resources": {
"requests": {
"cpu": "100m",
"memory": "64Mi"
},
"limits": {
"cpu": "500m",
"memory": "512Mi"
}
}
}
},
"admission_mutate": {
"loggings": [
{
"namespace_selectors": ["test01"],
"label_selectors": ["app=logging"],
"config":"[{\"disable\":false,\"type\":\"file\",\"path\":\"/tmp/opt/**/*.log\",\"storage_index\":\"logging-index\"\"source\":\"logging-tmp\"},{\"disable\":true,\"type\":\"file\",\"path\":\"/var/log/opt/**/*.log\",\"source\":\"logging-var\"}]"
}
]
}
}
主要配置项是 ddtrace、logfwd 和 profiler,指定注入的镜像和环境变量。此外,ddtrace 还支持根据 enabled_namespaces 和 enabled_selectors 批量注入,详见后文的“注入方式”。
指定镜像地址¶
DataKit Operator 主要作用就是注入镜像和环境变量,使用 images 配置镜像地址。images 是多个 Key/Value,Key 是固定的,修改 Value 值指定镜像地址。
正常情况下,镜像统一存放在 pubrepo.guance.com/datakit-operator,对于一些特殊环境不方便访问此镜像库,可以使用以下方法(以 dd-lib-java-init 镜像为例):
- 在可以访问
pubrepo.guance.com的环境中,pull 镜像pubrepo.guance.com/datakit-operator/dd-lib-java-init:v1.30.1-ext,并将其转存到自己的镜像库,例如inside.image.hub/datakit-operator/dd-lib-java-init:v1.30.1-ext - 修改 JSON 配置,将
admission_inject->ddtrace->images->java_agent_image修改为inside.image.hub/datakit-operator/dd-lib-java-init:v1.30.1-ext,应用此 yaml - 此后 DataKit Operator 会使用的新的 Java Agent 镜像路径
DataKit Operator 不检查镜像,如果该镜像路径错误,Kubernetes 创建 Pod 会报错。
添加环境变量¶
所有需要注入的环境变量,都必须在配置文件指定,DataKit Operator 不默认添加任何环境变量。
环境变量配置项是 envs,由多个 Key/Value 组成:Key 是固定值;Value 可以是固定值,也可以是占位符,根据实际情况取值。
例如在 envs 中添加一个 testing-env:
{
"admission_inject": {
"ddtrace": {
"envs": {
"DD_AGENT_HOST": "datakit-service.datakit.svc",
"DD_TRACE_AGENT_PORT": "9529",
"testing-env": "ok"
}
}
}
}
所有注入 ddtrace agent 的容器,都会添加 envs 的 3 个环境变量。
在 DataKit Operator v1.4.2 及以后版本,envs 支持 Kubernetes Downward API 的 环境变量取值字段。现支持以下几种:
metadata.name:Pod 的名称metadata.namespace: Pod 的命名空间metadata.uid: Pod 的唯一 IDmetadata.annotations['<KEY>']: Pod 的注解<KEY>的值(例如:metadata.annotations['myannotation'])metadata.labels['<KEY>']: Pod 的标签<KEY>的值(例如:metadata.labels['mylabel'])spec.serviceAccountName: Pod 的服务账号名称spec.nodeName: Pod 运行时所处的节点名称status.hostIP: Pod 所在节点的主 IP 地址status.hostIPs: 这组 IP 地址是 status.hostIP 的双协议栈版本,第一个 IP 始终与 status.hostIP 相同。 该字段在启用了 PodHostIPs 特性门控后可用。status.podIP: Pod 的主 IP 地址(通常是其 IPv4 地址)status.podIPs: 这组 IP 地址是 status.podIP 的双协议栈版本,第一个 IP 始终与 status.podIP 相同。
举个例子,现有一个 Pod 名称是 nginx-123,namespace 是 middleware,要给它注入环境变量 POD_NAME 和 POD_NAMESPACE,参考以下:
{
"admission_inject": {
"ddtrace": {
"envs": {
"POD_NAME": "{fieldRef:metadata.name}",
"POD_NAMESPACE": "{fieldRef:metadata.namespace}"
}
}
}
}
最终在该 Pod 可以看到:
Note
如果该 Value 占位符无法识别,会以纯字符串添加到环境变量。例如 "POD_NAME": "{fieldRef:metadata.PODNAME}",这是错误的写法,在环境变量是 POD_NAME={fieldRef:metadata.PODNAME}。
注入方式¶
DataKit-Operator 支持两种资源输入方式,分别是“全局配置 namespaces 和 selectors”,以及在目标 Pod 添加指定 Annotation。它们的区别如下:
-
全局配置 namespace 和 selector:通过修改 DataKit-Operator config,指定目标 Pod 的 Namespace 和 Selector,如果发现 Pod 符合条件,就执行注入资源。
- 优点:不需要在目标 Pod 添加 Annotation(但是需要重启目标 Pod)
- 缺点:范围不够精确,可能存在无效注入
-
在目标 Pod 添加 Annotation:在目标 Pod 添加 Annotation,DataKit-Operator 会检查 Pod Annotation,如果符合条件就执行注入。
- 优点:范围足够精确,不存在无效注入
- 缺点:必须在目标 Pod 添加 Annotation,且需要重启目标 Pod
Note
截止到 DataKit-Operator v1.5.8,全局配置 namespaces 和 selectors 方式只在注入 DDtrace 生效,对于 logfwd 和 profiler 无效,后者仍需添加 annotation 注入。
全局配置 namespaces 和 selectors 配置¶
enabled_namespaces 和 enabled_labelselectors 是 ddtrace 专属,它们是对象数组,需要指定 namespace 和 language。数组之间是“或”的关系,写法如下(详见后文的配置说明):
{
"server_listen": "0.0.0.0:9543",
"log_level": "info",
"admission_inject": {
"ddtrace": {
"enabled_namespaces": [
{
"namespace": "testns", # 指定 namespace,支持正则表达式匹配。如需精确匹配,请使用 ^ 和 $ 将模式包围,例如 ^testns$
"language": "java" # 指定需要注入的 agent 语言
}
],
"enabled_labelselectors": [
{
"labelselector": "app=log-output", # 指定 labelselector
"language": "java" # 指定需要注入的 agent 语言
}
]
# other..
}
}
}
如果一个 Pod 即满足 enabled_namespaces 规则,又满足 enabled_labelselectors,以 enabled_labelselectors 配置为准(通常在 language 取值用到)。
关于 labelselector 的编写规范,可参考此官方文档。
Note
- 在 Kubernetes 1.16.9 或更早版本,Admission 不记录 Pod Namespace,所以无法使用
enabled_namespaces功能。
添加 Annotation 配置注入¶
在 Deployment 添加指定 Annotation,表示需要注入 ddtrace 文件。注意 Annotation 要添加在 template 中。
其格式为:
- key 是
admission.datakit/%s-lib.version,%s需要替换成指定的语言,目前支持java - value 是指定版本号。默认是 DataKit-Operator 配置
java_agent_image指定的版本
例如添加 Annotation 如下:
表示这个 Pod 需要注入的镜像版本是 v1.36.2-ext,镜像地址取自配置 admission_inject->ddtrace->images->java_agent_image,替换镜像版本为"v1.36.2-ext",即 pubrepo.guance.com/datakit-operator/dd-lib-java-init:v1.36.2-ext。
DataKit Operator 注入¶
在大型 Kubernetes 集群中,批量修改配置是比较麻烦的事情。DataKit-Operator 会根据 Annotation 配置,决定是否对其修改或注入。
目前支持的功能有:
- 注入
ddtraceagent 和 environment 的功能 - 挂载
logfwdsidecar 并开启日志采集的功能 - 注入
async-profiler采集 JVM 程序的 profile 数据 Experimental - 注入
py-spy采集 Python 应用的 profile 数据 Experimental
Info
只支持 v1 版本的 deployments/daemonsets/cronjobs/jobs/statefulsets 这五类 Kind,且因为 DataKit-Operator 实际对 PodTemplate 操作,所以不支持 Pod。 在本文中,以 Deployment 代替描述这五类 Kind。
DDtrace Agent¶
使用说明¶
- 在目标 Kubernetes 集群,下载和安装 DataKit-Operator
- 在 deployment 添加指定 Annotation
admission.datakit/java-lib.version: "",表示需要注入默认版本的 DDtrace Java Agent。
用例¶
下面是一个 Deployment 示例,给 Deployment 创建的所有 Pod 注入 dd-java-lib:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
annotations:
admission.datakit/java-lib.version: ""
spec:
containers:
- name: nginx
image: nginx:1.22
ports:
- containerPort: 80
使用 yaml 文件创建资源:
验证如下:
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-deployment-7bd8dd85f-fzmt2 1/1 Running 0 4s
$ kubectl get pod nginx-deployment-7bd8dd85f-fzmt2 -o=jsonpath={.spec.initContainers\[\*\].name}
datakit-lib-init
logfwd¶
前置条件¶
logfwd 是 DataKit 的专属日志采集应用,需要先在同一个 Kubernetes 集群中部署 DataKit,且达成以下两点:
- DataKit 开启
logfwdserver采集器,例如监听端口是9533 - DataKit service 需要开放
9533端口,使得其他 Pod 能访问datakit-service.datakit.svc:9533
使用说明 (1.6.0 及以后){#datakit-operator-1-6-0-inject-logfwd-instructions}¶
DataKit-Operator 1.6.0 对 logfwd 注入进行了大幅优化:
- 集中管理采集配置:支持监听 Kubernetes
ClusterLoggingConfigCRD,并暴露匹配结果供 logfwd sidecar 轮询获取(sidecar 默认每 60 秒向 Operator 发起 HTTP 请求,logfwd 需 ≥ 1.86.0)。 - 热更新 & 精细匹配:CRD selector(Namespace/Pod/Label/Container)随改随生效,无需重建 Workload。
- 与手动配置兼容:仍可通过注解覆盖单个 Pod 的采集逻辑,适配调试或特殊场景。
若尚未了解 ClusterLoggingConfig 的定义及编写方式,请先阅读容器日志采集 CRD 配置文档。
操作流程:
- 注册
ClusterLoggingConfigCRD(如 DataKit 文档中所述)。 - 升级/安装 DataKit-Operator 1.6.0,并添加 CRD 的 RBAC 读权限。
- 在目标命名空间为 Pod 添加 logfwd 注解(启用 + 可选覆盖配置)。
- 创建
ClusterLoggingConfig资源,logfwd sidecar 将定期(默认 60 秒)向 DataKit-Operator 发送 HTTP 请求并拉取采集配置。
安装最新的 datakit-operator.yaml 即可带上必要权限,或参考下列最小示例:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: datakit-operator
rules:
- apiGroups: ["logging.datakits.io"]
resources: ["clusterloggingconfigs"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: datakit-operator
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: datakit-operator
subjects:
- kind: ServiceAccount
name: datakit-operator
namespace: datakit
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: datakit-operator
namespace: datakit
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: datakit-operator
namespace: datakit
labels:
app: datakit-operator
spec:
replicas: 1 # Do not change the ReplicaSet number!
selector:
matchLabels:
app: datakit-operator
template:
metadata:
labels:
app: datakit-operator
spec:
# Add serverAccountName
serviceAccountName: datakit-operator
containers:
- name: operator
# other..
logfwd 注入新增若干环境变量与镜像版本要求,可在 datakit-operator-config ConfigMap 中配置:
"logfwd": {
"images": {
"logfwd_image": "pubrepo.guance.com/datakit/logfwd:1.86.0"
},
"envs": {
"LOGFWD_DATAKIT_HOST": "{fieldRef:status.hostIP}",
"LOGFWD_DATAKIT_PORT": "9533",
"LOGFWD_DATAKIT_OPERATOR_ENDPOINT": "datakit-operator.datakit.svc:443",
"LOGFWD_GLOBAL_SERVICE": "{fieldRef:metadata.labels['app']}",
"LOGFWD_POD_NAME": "{fieldRef:metadata.name}",
"LOGFWD_POD_NAMESPACE": "{fieldRef:metadata.namespace}",
"LOGFWD_POD_IP": "{fieldRef:status.podIP}"
}
}
| 环境变量名 | 配置项含义 |
|---|---|
LOGFWD_DATAKIT_HOST |
DataKit 实例地址(IP 或可解析域名)。 |
LOGFWD_DATAKIT_PORT |
DataKit logfwdserver 监听端口,例如 9533。 |
LOGFWD_DATAKIT_OPERATOR_ENDPOINT |
DataKit-Operator Endpoint,形如 datakit-operator.datakit.svc:443 或 https://datakit-operator.datakit.svc:443,用于查询 CRD 配置;留空则不会尝试拉取。支持自动添加 https:// 前缀。 |
LOGFWD_GLOBAL_SOURCE |
全局 source,优先级高于单条配置中的 source 字段。 |
LOGFWD_GLOBAL_SERVICE |
全局 service,若单条配置中未指定 service,则使用全局值;若全局值也为空,则回退为 source。 |
LOGFWD_GLOBAL_STORAGE_INDEX |
全局 storage_index,优先级高于单条配置中的 storage_index 字段。 |
LOGFWD_POD_NAME |
自动写入 pod_name tag,通常通过 Downward API 注入。 |
LOGFWD_POD_NAMESPACE |
自动写入 namespace tag。 |
LOGFWD_POD_IP |
自动写入 pod_ip tag,便于定位容器实例。 |
即便启用了 CRD,Pod 仍需通过注解表明是否挂载 logfwd;同时可结合注解覆写 CRD 下发的默认行为:
admission.datakit/logfwd.enabled:只有值为"true"才会注入。admission.datakit/logfwd.log_configs:允许手写采集配置(JSON 数组),用于调试或覆盖 CRD 内容,结构示例:
[
{
"type": "file",
"disable": false,
"source": "nginx-access",
"service": "nginx",
"path": "/var/log/nginx/access.log",
"pipeline": "nginx-access.p",
"storage_index": "app-logs",
"multiline_match": "^\\d{4}-\\d{2}-\\d{2}",
"remove_ansi_escape_codes": false,
"from_beginning": false,
"character_encoding": "utf-8",
"tags": {
"env": "production",
"team": "backend"
}
}
]
| 字段 | 类型 | 必填 | 说明 | 示例 |
|---|---|---|---|---|
type |
string | 是 | logfwd 采集类型只能是 "file" |
"file" |
disable |
boolean | 否 | 是否禁用此采集配置 | false |
source |
string | 是 | 日志来源标识,用于区分不同日志流 | "nginx-access" |
service |
string | 否 | 日志隶属的服务,默认值为日志来源(source) | "nginx" |
path |
string | 条件必填 | 日志文件路径(支持 glob 模式),type=file 时必填 | "/var/log/nginx/*.log" |
multiline_match |
string | 否 | 多行日志起始行的正则表达式,注意 JSON 中需要转义反斜杠 | "^\\d{4}-\\d{2}-\\d{2}" |
pipeline |
string | 否 | 日志解析管道配置文件名称(需在 DataKit 端配置) | "nginx-access.p" |
storage_index |
string | 否 | 日志存储的索引名称 | "app-logs" |
remove_ansi_escape_codes |
boolean | 否 | 是否删除日志数据的 ANSI 转义字符(颜色代码等) | false |
from_beginning |
boolean | 否 | 是否从文件首部开始采集日志(默认从文件末尾开始) | false |
from_beginning_threshold_size |
int | 否 | 搜寻到文件时,如果文件 size 小于此值就从文件首部采集日志,单位字节,默认 20MB | 1000 |
character_encoding |
string | 否 | 字符编码,支持 utf-8, utf-16le, utf-16be, gbk, gb18030 或空字符串(自动检测)。默认为空即可 |
"utf-8" |
tags |
object | 否 | 额外的标签键值对,会附加到每条日志记录上 | {"env": "prod"} |
admission.datakit/logfwd.volume_paths:声明需要挂载的宿主路径列表(JSON 数组),用于让 sidecar 能访问真实日志文件,例如'["/var/log", "/data/log"]'。请避免父子路径同时存在,防止 Volume 冲突。
ClusterLoggingConfig 示例:
apiVersion: logging.datakits.io/v1alpha1
kind: ClusterLoggingConfig
metadata:
name: nginx-logs
spec:
selector:
namespaceRegex: "^(middleware)$"
podLabelSelector: "app=logging"
podTargetLabels:
- app
- env
configs:
- type: file
source: nginx-access
service: nginx
path: /var/log/nginx/access.log
pipeline: nginx-access.p
storage_index: app-logs
multiline_match: "^\\d{4}-\\d{2}-\\d{2}"
tags:
team: web
以下 Deployment 展示了 CRD + 注解组合的完整流程:
apiVersion: apps/v1
kind: Deployment
metadata:
name: logging-demo
namespace: middleware
labels:
app: logging
spec:
replicas: 1
selector:
matchLabels:
app: logging
template:
metadata:
labels:
app: logging
annotations:
admission.datakit/logfwd.enabled: "true"
admission.datakit/logfwd.volume_paths: '["/var/log/nginx"]'
# 按需覆盖 CRD 下发的配置;若无需覆盖可删除该项
# admission.datakit/logfwd.log_configs: '[{...}]'
spec:
containers:
- name: log-app
image: nginx:1.25
应用上述资源后,DataKit-Operator 会:
- 监听 Deployment 创建事件并注入
datakit-logfwd容器。 - 根据
ClusterLoggingConfig选择器匹配 Pod,持续维护匹配结果,供 sidecar 在轮询时读取。 - sidecar 启动后通过
LOGFWD_DATAKIT_OPERATOR_ENDPOINT与 Operator 交互,每 60 秒拉取一次 CRD 配置,并将任务转发至 DataKitlogfwdserver。
使用说明 (1.6.0 之前){#datakit-operator-1-6-0-inject-logfwd-instructions-legacy}¶
Attention
此配置方式在 1.6.0 版本之前使用,1.6.0 及以后版本推荐使用上述新的配置方式(支持 ClusterLoggingConfig CRD 和新的 Annotation)。
- 在目标 Kubernetes 集群,下载和安装 DataKit-Operator
- 在 deployment 添加指定 Annotation,表示需要挂载 logfwd sidecar。注意 Annotation 要添加在 template 中
- key 统一是
admission.datakit/logfwd.instances - value 是一个 JSON 字符串,是具体的 logfwd 配置,示例如下:
- key 统一是
[
{
"datakit_addr": "datakit-service.datakit.svc:9533",
"loggings": [
{
"logfiles": ["<your-logfile-path>"],
"ignore": [],
"storage_index": "<your-storage-index>",
"source": "<your-source>",
"service": "<your-service>",
"pipeline": "<your-pipeline.p>",
"character_encoding": "",
"multiline_match": "<your-match>",
"tags": {}
},
{
"logfiles": ["<your-logfile-path-2>"],
"source": "<your-source-2>"
}
]
}
]
参数说明,可参考 logfwd 配置:
datakit_addr是 DataKit logfwdserver 地址loggings为主要配置,是一个数组,可参考 DataKit logging 采集器logfiles日志文件列表,可以指定绝对路径,支持使用 glob 规则进行批量指定,推荐使用绝对路径ignore文件路径过滤,使用 glob 规则,符合任意一条过滤条件将不会对该文件进行采集storage_index指定日志存储索引source数据来源,如果为空,则默认使用 'default'service新增标记 tag,如果为空,则默认使用 $sourcepipelinePipeline 脚本路径,如果为空将使用 $source.p,如果 $source.p 不存在将不使用 Pipeline(此脚本文件存在于 DataKit 端)character_encoding选择编码,如果编码有误会导致数据无法查看,默认为空即可。支持utf-8/utf-16le/utf-16le/gbk/gb18030multiline_match多行匹配,详见 DataKit 日志多行配置,注意因为是 JSON 格式所以不支持 3 个单引号的“不转义写法”,正则^\d{4}需要添加转义写成^\\d{4}tags添加额外tag,书写格式是 JSON map,例如{ "key1":"value1", "key2":"value2" }
Note
注入 logfwd 时,DataKit Operator 默认复用相同路径的 volume,避免因为存在同样路径的 volume 而注入报错。
路径末尾有斜线和无斜线的意义不同,例如 /var/log 和 /var/log/ 是不同路径,不能复用。
用例¶
下面是一个 Deployment 示例,使用 shell 持续向文件写入数据,且配置该文件的采集:
apiVersion: apps/v1
kind: Deployment
metadata:
name: logging-deployment
labels:
app: logging
spec:
replicas: 1
selector:
matchLabels:
app: logging
template:
metadata:
labels:
app: logging
annotations:
admission.datakit/logfwd.instances: '[{"datakit_addr":"datakit-service.datakit.svc:9533","loggings":[{"logfiles":["/var/log/log-test/*.log"],"source":"deployment-logging","tags":{"key01":"value01"}}]}]'
spec:
containers:
- name: log-container
image: busybox
args: [/bin/sh, -c, 'mkdir -p /var/log/log-test; i=0; while true; do printf "$(date "+%F %H:%M:%S") [%-8d] Bash For Loop Examples.\\n" $i >> /var/log/log-test/1.log; i=$((i+1)); sleep 1; done']
使用 yaml 文件创建资源:
验证如下:
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
logging-deployment-5d48bf9995-vt6bb 1/1 Running 0 4s
$ kubectl get pod logging-deployment-5d48bf9995-vt6bb -o=jsonpath={.spec.containers\[\*\].name}
log-container datakit-logfwd
最终可以在观测云日志平台查看日志是否采集。
async-profiler¶
前置条件¶
- 集群已安装 DataKit。
- 开启 profile 采集器。
- Linux 内核参数 kernel.perf_event_paranoid 值设置为 2 及以下。
Note
async-profiler 使用 perf_events 工具来抓取 Linux 的内核调用堆栈,非特权进程依赖内核的相应设置,可以使用以下命令来修改内核参数:
在你的 Pod 控制器 资源配置文件中的
.spec.template.metadata.annotations 节点下添加 annotation:admission.datakit/java-profiler.version: "latest",然后应用该资源配置文件,
DataKit-Operator 会自动在相应的 Pod 中创建一个名为 datakit-profiler 的容器来辅助进行 profiling。
接下来以一个名为 movies-java 的 Deployment 资源配置文件为例进行说明。
kind: Deployment
metadata:
name: movies-java
labels:
app: movies-java
spec:
replicas: 1
selector:
matchLabels:
app: movies-java
template:
metadata:
name: movies-java
labels:
app: movies-java
annotations:
admission.datakit/java-profiler.version: "0.4.4"
spec:
containers:
- name: movies-java
image: zhangyicloud/movies-java:latest
imagePullPolicy: IfNotPresent
securityContext:
seccompProfile:
type: Unconfined
env:
- name: JAVA_OPTS
value: ""
restartPolicy: Always
应用配置文件并检查是否生效:
$ kubectl apply -f deployment-movies-java.yaml
$ kubectl get pods | grep movies-java
movies-java-784f4bb8c7-59g6s 2/2 Running 0 47s
$ kubectl describe pod movies-java-784f4bb8c7-59g6s | grep datakit-profiler
/app/datakit-profiler from datakit-profiler-volume (rw)
datakit-profiler:
/app/datakit-profiler from datakit-profiler-volume (rw)
datakit-profiler-volume:
Normal Created 12m kubelet Created container datakit-profiler
Normal Started 12m kubelet Started container datakit-profiler
稍等几分钟后即可在观测云控制台 应用性能检监测-Profiling 页面查看应用性能数据。
Note
默认使用命令 jps -q -J-XX:+PerfDisableSharedMem | head -n 20 来查找容器中的 JVM 进程,出于性能的考虑,最多只会采集 20 个进程的数据。
Note
可以通过修改 datakit-operator.yaml 配置文件中的 datakit-operator-config 下的环境变量来配置 profiling 的行为。
| 环境变量 | 说明 | 默认值 |
|---|---|---|
DK_PROFILE_SCHEDULE |
profiling 的运行计划,使用与 Linux Crontab 相同的语法,如 */10 * * * * |
0 * * * *(每小时调度一次) |
DK_PROFILE_DURATION |
每次 profiling 持续的时间,单位秒 | 240(4 分钟) |
Note
若无法看到数据,可以进入 datakit-profiler 容器查看相应日志进行排查:
py-spy¶
前置条件¶
- 当前只支持 Python 官方解释器(
CPython)
在你的 Pod 控制器 资源配置文件中的
.spec.template.metadata.annotations 节点下添加 annotation:admission.datakit/python-profiler.version: "latest",然后应用该资源配置文件,
DataKit-Operator 会自动在相应的 Pod 中创建一个名为 datakit-profiler 的容器来辅助进行 profiling。
接下来将以一个名为 "movies-python" 的 Deployment 资源配置文件为例进行说明。
apiVersion: apps/v1
kind: Deployment
metadata:
name: movies-python
labels:
app: movies-python
spec:
replicas: 1
selector:
matchLabels:
app: movies-python
template:
metadata:
name: movies-python
labels:
app: movies-python
annotations:
admission.datakit/python-profiler.version: "latest"
spec:
containers:
- name: movies-python
image: zhangyicloud/movies-python:latest
imagePullPolicy: Always
command:
- "gunicorn"
- "-w"
- "4"
- "--bind"
- "0.0.0.0:8080"
- "app:app"
应用资源配置并验证是否生效:
$ kubectl apply -f deployment-movies-python.yaml
$ kubectl get pods | grep movies-python
movies-python-78b6cf55f-ptzxf 2/2 Running 0 64s
$ kubectl describe pod movies-python-78b6cf55f-ptzxf | grep datakit-profiler
/app/datakit-profiler from datakit-profiler-volume (rw)
datakit-profiler:
/app/datakit-profiler from datakit-profiler-volume (rw)
datakit-profiler-volume:
Normal Created 98s kubelet Created container datakit-profiler
Normal Started 97s kubelet Started container datakit-profiler
稍等几分钟后即可在观测云控制台 应用性能检监测-Profiling 页面查看应用性能数据。
Note
默认使用命令 ps -e -o pid,cmd --no-headers | grep -v grep | grep "python" | head -n 20 来查找容器中的 Python 进程,出于性能考虑,最多只会采集 20 个进程的数据。
Note
可以通过修改 datakit-operator.yaml 配置文件中的 ConfigMap datakit-operator-config 下的环境变量来配置 profiling 的行为。
| 环境变量 | 说明 | 默认值 |
|---|---|---|
DK_PROFILE_SCHEDULE |
profiling 的运行计划,使用与 Linux Crontab 相同的语法,如 */10 * * * * |
0 * * * *(每小时调度一次) |
DK_PROFILE_DURATION |
每次 profiling 持续的时间,单位秒 | 240(4 分钟) |
Note
若无法看到数据,可以进入 datakit-profiler 容器查看相应日志进行排查:
DataKit Operator 资源变动¶
添加 DataKit Logging 采集所需的配置¶
DataKit Operator 可以为指定的 Pod 自动添加 DataKit Logging 采集所需的配置,包括 datakit/logs 注解和对应的文件路径 volume/volumeMount,简化了手动配置的繁杂步骤。这样,用户无需手动干预每个 Pod 配置即可自动启用日志采集功能。
以下是一个配置示例,展示了如何通过 DataKit Operator 的 admission_mutate 配置来实现日志采集配置的自动注入:
{
"server_listen": "0.0.0.0:9543",
"log_level": "info",
"admission_inject": {
# 其他配置
},
"admission_mutate": {
"loggings": [
{
"namespace_selectors": ["middleware"],
"label_selectors": ["app=logging"],
"config": "[{\"disable\":false,\"type\":\"file\",\"path\":\"/tmp/opt/**/*.log\",\"source\":\"logging-tmp\"}]"
}
]
}
}
admission_mutate.loggings:这是一个对象数组,包含多个日志采集配置。每个日志配置包括以下字段:
namespace_selectors:限定符合条件的 Pod 所在的 Namespacce。可以设置多个 Namespace,Pod 必须匹配至少一个 Namespace 才会被选中。与label_selectors是“或”的关系。label_selectors:限定符合条件的 Pod 的 label。Pod 必须匹配至少一个 label selector 才会被选中。与namespace_selectors是“或”的关系。config:这是一个 JSON 字符串,它将被添加到 Pod 的注解中,注解的 Key 是datakit/logs。如果该 Key 已经存在,它不会被覆盖或重复添加。这个配置将告诉 DataKit 如何采集日志。
DataKit Operator 会自动解析 config 配置,并根据其中的路径(path)为 Pod 创建对应的 volume 和 volumeMount。
以上述 DataKit Operator 配置为例,如果发现某个 Pod 的 Namespace 是 middleware,或 Labels 匹配 app=logging,就在 Pod 新增注解和挂载。例如:
apiVersion: v1
kind: Pod
metadata:
annotations:
datakit/logs: '[{"disable":false,"type":"file","path":"/tmp/opt/**/*.log","source":"logging-tmp"}]'
labels:
app: logging
name: logging-test
namespace: default
spec:
containers:
- args:
- |
mkdir -p /tmp/opt/log1;
i=1;
while true; do
echo "Writing logs to file ${i}.log";
for ((j=1;j<=10000000;j++)); do
echo "$(date +'%F %H:%M:%S') [$j] Bash For Loop Examples. Hello, world! Testing output." >> /tmp/opt/log1/file_${i}.log;
sleep 1;
done;
echo "Finished writing 5000000 lines to file_${i}.log";
i=$((i+1));
done
command:
- /bin/bash
- -c
- --
image: pubrepo.guance.com/base/ubuntu:18.04
imagePullPolicy: IfNotPresent
name: demo
volumeMounts:
- mountPath: /tmp/opt
name: datakit-logs-volume-0
volumes:
- emptyDir: {}
name: datakit-logs-volume-0
这个 Pod 存在 label app=logging,能够匹配上,于是 DataKit Operator 就给它添加了 datakit/logs 注解,并且将路径 /tmp/opt 添加 EmptyDir 挂载。
DataKit 日志采集发现到 Pod 后,就会根据 datakit/logs 内容进行定制化采集。
FAQ¶
-
怎样指定某个 Pod 不注入?给该 Pod 添加 Annotation
"admission.datakit/enabled": "false",将不再为它执行任何操作,此优先级最高。 -
DataKit-Operator 使用 Kubernetes Admission Controller 功能进行资源注入,详细机制请查看官方文档
-
在 AWS EKS 环境部署,可能导致 DataKit-Operator 不生效,需要在安全组开启
9543端口。