DataKit 主配置¶
DataKit 主配置用来配置 DataKit 自己的运行行为。
Datakit 主配置示例¶
Datakit 主配置示例如下,我们可以根据该示例来开启各种功能(当前版本 1.65.0):
datakit.conf
################################################
# Global configures
################################################
# Default enabled input list.
default_enabled_inputs = [
"cpu",
"disk",
"diskio",
"host_processes",
"hostobject",
"mem",
"net",
"swap",
"system",
]
# enable_pprof: bool
# If pprof enabled, we can profiling the running datakit
enable_pprof = true
pprof_listen = "localhost:6060" # pprof listen
# protect_mode: bool, default false
# When protect_mode eanbled, we can set radical collect parameters, these may cause Datakit
# collect data more frequently.
protect_mode = true
# The user name running datakit. Generally for audit purpose. Default is root.
datakit_user = "root"
################################################
# ulimit: set max open-files limit(Linux only)
################################################
ulimit = 64000
################################################
# point_pool: use point pool for better memory usage
################################################
[point_pool]
enable = false
reserved_capacity = 4096
################################################
# DCA configure
################################################
[dca]
# Enable or disable DCA
enable = false
# DCA websocket server address
websocket_server = "ws://localhost:8000/ws"
################################################
# Upgrader
################################################
[dk_upgrader]
# host address
host = "0.0.0.0"
# port number
port = 9542
################################################
# Pipeline
################################################
[pipeline]
# IP database type, support iploc and geolite2
ipdb_type = "iploc"
# How often to sync remote pipeline
remote_pull_interval = "1m"
#
# reftab configures
#
# Reftab remote HTTP URL(https/http)
refer_table_url = ""
# How often reftab sync the remote
refer_table_pull_interval = "5m"
# use sqlite to store reftab data to release memory usage
use_sqlite = false
# or use pure memory to cache the reftab data
sqlite_mem_mode = false
# append run info
disable_append_run_info = false
# default pipeline
[pipeline.default_pipeline]
# logging = "<your_script.p>"
# metric = "<your_script.p>"
# tracing = "<your_script.p>"
# Offload data processing tasks to post-level data processors.
[pipeline.offload]
receiver = "datakit-http"
addresses = [
# "http://<ip>:<port>"
]
################################################
# HTTP server(9529)
################################################
[http_api]
# HTTP server address
listen = "localhost:9529"
# Disable 404 page to hide detailed Datakit info
disable_404page = false
# only enable these APIs. If list empty, all APIs are enabled.
public_apis = []
# Datakit server-side timeout
timeout = "30s"
close_idle_connection = false
# API rate limit(QPS)
request_rate_limit = 20.0
#
# RUM related: we should port these configures to RUM inputs(TODO)
#
# When serving RUM(/v1/write/rum), extract the IP address from this HTTP header
rum_origin_ip_header = "X-Forwarded-For"
# When serving RUM(/v1/write/rum), only accept requests from these app-id.
# If the list empty, all app's requests accepted.
rum_app_id_white_list = []
# only these domains enable CORS. If list empty, all domains are enabled.
allowed_cors_origins = []
# Start Datakit web server with HTTPS
[http_api.tls]
# cert = "path/to/certificate/file"
# privkey = "path/to/private_key/file"
################################################
# io configures
################################################
[io]
# How often Datakit flush data to dataway.
# Datakit will upload data points if cached(in memory) points
# reached(>=) the max_cache_count or the flush_interval triggered.
max_cache_count = 1000
flush_workers = 0 # default to (cpu_core * 2)
flush_interval = "10s"
# Queue size of feed.
feed_chan_size = 1
# Set blocking if queue is full.
# NOTE: Global blocking mode may consume more memory on large metric points.
global_blocking = false
# Data point filter configures.
# NOTE: Most of the time, you should use web-side filter, it's a debug helper for developers.
#[io.filters]
# logging = [
# "{ source = 'datakit' or f1 IN [ 1, 2, 3] }"
# ]
# metric = [
# "{ measurement IN ['datakit', 'disk'] }",
# "{ measurement CONTAIN ['host.*', 'swap'] }",
# ]
# object = [
# { class CONTAIN ['host_.*'] }",
# ]
# tracing = [
# "{ service = re("abc.*") AND some_tag CONTAIN ['def_.*'] }",
# ]
[recorder]
enabled = false
#path = "/path/to/point-data/dir"
encoding = "v2" # use protobuf-json format
duration = "30m" # record for 30 minutes
# only record these inputs, if empty, record all
inputs = [
#"cpu",
#"mem",
]
# only record these categoris, if empty, record all
category = [
#"logging",
#"object",
]
################################################
# Dataway configure
################################################
[dataway]
# urls: Dataway URL list
# NOTE: do not configure multiple URLs here, it's a deprecated feature.
urls = [
# "https://openway.guance.com?token=<YOUR-WORKSPACE-TOKEN>"
]
# Dataway HTTP timeout
timeout_v2 = "30s"
# max_retry_count specifies at most how many times will be tried when dataway API fails(not 4xx),
# default value(and minimal) is 1 and maximum value is 10.
#
# The default set to 1 to makes the API fails ASAP to release memroy.
max_retry_count = 1
# The interval between two retry operation, valid time units are "ns", "us", "ms", "s", "m", "h"
retry_delay = "1s"
# HTTP Proxy
# Format: "http(s)://IP:Port"
http_proxy = ""
max_idle_conns = 0 # limit idle TCP connections for HTTP request to Dataway
enable_httptrace = false # enable trace HTTP metrics(connection/NDS/TLS and so on)
idle_timeout = "90s" # not-set, default 90s
# HTTP body content type, other candidates are(case insensitive):
# - v1: line-protocol
# - v2: protobuf
content_encoding = "v2"
# Enable GZip to upload point data.
#
# do NOT disable gzip or your get large network payload.
gzip = true
max_raw_body_size = 1048576 # max body size(before gizp) in bytes
# Customer tag or field keys that will extract from exist points
# to build the X-Global-Tags HTTP header value.
global_customer_keys = []
enable_sinker = false # disable sinker
# use dataway as NTP server
[dataway.ntp]
interval = "5m" # sync dataway time each 5min
# if datakit local time and dataway time's ABS value reach the diff,
# datakit's soft time will update to the dataway time.
# NOTE: diff MUST larger than "1s"
diff = "30s"
# WAL queue for uploading points
[dataway.wal]
max_capacity_gb = 2.0 # 2GB reserved disk space for each category(M/L/O/T/...)
#workers = 4 # flush workers on WAL(default to CPU limited cores)
#mem_cap = 4 # in-memory queue capacity(default to CPU limited cores)
#fail_cache_clean_interval = "30s" # duration for clean fail uploaded data
################################################
# Datakit logging configure
################################################
[logging]
# log path
log = "/var/log/datakit/log"
# HTTP access log
gin_log = "/var/log/datakit/gin.log"
# level level(info/debug)
level = "info"
# Disable log color
disable_color = false
# log rotate size(in MB)
# DataKit will always keep at most n+1(n backup log and 1 writing log) splited log files on disk.
rotate = 32
# Upper limit count of backup log
rotate_backups = 5
################################################
# Global tags
################################################
# We will try to add these tags to every collected data point if these
# tags do not exist in orignal data.
#
# NOTE: we can get the real IP of current note, we just need
# to set "$datakit_ip" or "__datakit_ip" here. Same for the hostname.
[global_host_tags]
ip = "$datakit_ip"
host = "$datakit_hostname"
[election]
# Enable election
enable = false
# Election whitelist
# NOTE: Empty to disable whitelist
node_whitelist = []
# Election namespace.
# NOTE: for single workspace, there can be multiple election namespace.
namespace = "default"
# If enabled, every data point will add a tag with election_namespace = <your-election-namespace>
enable_namespace_tag = false
# Like global_host_tags, but only for data points that are remotely collected(such as MySQL/Nginx).
[election.tags]
# project = "my-project"
# cluster = "my-cluster"
###################################################
# Tricky: we can rename the default hostname here
###################################################
[environments]
ENV_HOSTNAME = ""
################################################
# resource limit configures
################################################
[resource_limit]
# enable or disable resource limit
enable = true
# Linux only, cgroup path
path = "/datakit"
# set max CPU usage(%, max 100.0, no matter how many CPU cores here)
cpu_max = 30.0
# set max memory usage(MB)
mem_max_mb = 4096
################################################
# git_repos configures
################################################
# We can hosting all input configures on git server
[git_repos]
# git pull interval
pull_interval = "1m"
# git repository settings
[[git_repos.repo]]
# enable the repository or not
enable = false
# the branch name to pull
branch = "master"
# git repository URL. There are 3 formats here:
# - HTTP(s): such as "https://github.datakit.com/path/to/datakit-conf.git"
# - Git: such as "git@github.com:path/to/datakit.git"
# - SSH: such as "ssh://git@github.com:9000/path/to/repository.git"
url = ""
# For formats Git and SSH, we need extra configures:
ssh_private_key_path = ""
ssh_private_key_password = ""
################################################
# crypto key or key filePath.
################################################
[crypto]
aes_key = ""
aes_Key_file = ""
[remote_job]
enable=false
envs = ["OSS_BUCKET_HOST=host","OSS_ACCESS_KEY_ID=key","OSS_ACCESS_KEY_SECRET=secret","OSS_BUCKET_NAME=bucket"]
interval = "30s"
java_home=""
HTTP 服务的配置¶
DataKit 会开启 HTTP 服务,用来接收外部数据,或者对外提供基础的数据服务。
修改 HTTP 服务地址¶
默认的 HTTP 服务地址是 localhost:9529
,如果 9529 端口被占用,或希望从外部访问 DataKit 的 HTTP 服务(比如希望接收 RUM 或 Tracing 数据),可将其修改成:
注意,IPv6 支持需 Datakit 升级到 1.5.7。
使用 Unix domain socket¶
Datakit 支持 UNIX domain sockets 访问。开启方式如下:listen
字段配置为一个不存在文件的全路径,这里以 datakit.sock
举例,可以为任意文件名。
curl
命令测试是否配置成功:sudo curl --no-buffer -XGET --unix-socket /tmp/datakit.sock http:/localhost/v1/ping
。更多关于 curl
的测试命令的信息可以参阅这里。
HTTP 请求频率控制¶
Version-1.62.0 已经默认开启该功能。
由于 DataKit 需要大量接收外部数据写入,为了避免给所在节点造成巨大开销,可修改如下 HTTP 配置(默认不开启):
其它设置¶
参见这里
HTTP API 访问控制¶
出于安全考虑,Datakit 默认限制了一些自身 API 的访问(这些 API 只能通过 localhost 访问)。如果 DataKit 部署在公网环境,又需要通过公网(或从本地局域网的其它机器)来请求这些 API,可以在 datakit.conf 中,修改如下 public_apis
字段配置:
默认情况下,只开启了 Ping 接口以及基本的数据上传接口访问,所有其它接口都是禁止外部访问的,而采集器对应的接口,比如 trace 类采集器,一旦开启采集器之后,默认就能外部访问。Kubernetes 中增加 API 白名单参见这里。
全局标签(Tag)修改¶
Datakit 允许给其采集的所有数据配置全局标签,全局标签分为两类:
- 主机类全局标签(GHT):采集的数据跟当前主机绑定,比如 CPU/内存等指标数据
- 选举类全局标签(GET):采集的数据来自某个公共(远程)实体,比如 MySQL/Redis 等,这些采集一般都参与选举,故这些数据上不会带上当前主机相关的标签
[global_host_tags] # 这里面的我们称之为「全局主机标签」
ip = "__datakit_ip"
host = "__datakit_hostname"
[election]
[election.tags] # 这里面的我们称之为「全局选举标签」
project = "my-project"
cluster = "my-cluster"
加全局标签时,有几个地方要注意:
-
这些全局标签的值可以用 Datakit 目前已经支持的几个通配(双下划线(
__
)前缀和$
都是可以的):__datakit_ip/$datakit_ip
:标签值会设置成 DataKit 获取到的第一个主网卡 IP__datakit_hostname/$datakit_hostname
:标签值会设置成 DataKit 的主机名
-
由于 DataKit 数据传输协议限制,不要在全局标签(Tag)中出现任何指标(Field)字段,否则会因为违反协议导致数据处理失败。具体参见具体采集器的字段列表。当然,也不要加太多标签,而且每个标签的 Key 以及 Value 长度都有限制。
- 如果被采集上来的数据中,本来就带有同名的标签,那么 DataKit 不会再追加这里配置的全局标签
- 即使 GHT 中没有任何配置,DataKit 仍然会在其中添加一个
host=__datakit_hostname
的标签。因为 hostname 是目前观测云平台数据关联的默认字段,故日志/CPU/内存等采集上,都会带上host
这个 tag。 - 这俩类全局标签(GHT/GET)是可以有交集的,比如都可以在其中设置一个
project = "my-project"
的标签 - 当没有开启选举的情况下,GET 沿用 GHT(它至少有一个
host
的标签)中的所有标签 - 选举类采集器默认追加 GET,非选举类采集器默认追加 GHT。
如何区分选举和非选举采集器?
在采集器文档中,在顶部有类似如下标识,它们表示当前采集器的平台适配情况以及采集特性:
·
若带有 则表示当前采集器是选举类采集器。
全局 Tag 在远程采集时的设置¶
因为 DataKit 会默认给采集到的所有数据追加标签 host=<DataKit 所在主机名>
,但某些情况这个默认追加的 host
会带来困扰。
以 MySQL 为例,如果 MySQL 不在 DataKit 所在机器,但又希望这个 host
标签是被采集的 MySQL 的真实主机名(或云数据库的其它标识字段),而非 DataKit 所在的主机名。
对这种情况,我们有两种方式可以绕过 DataKit 上的全局 tag:
- 在具体采集器中,一般都有一个如下配置,我们可以在这里面新增 Tag,比如,如果不希望 DataKit 默认添加
host=xxx
这个 Tag,可以在这里覆盖这个 Tag,以 MySQL 为例:
- 以 HTTP API 方式往 DataKit 推送数据时,可以通过 API 参数
ignore_global_tags
来屏蔽所有全局 Tag
Tip
自 1.4.20 之后,DataKit 默认会以被采集服务连接地址中的的 IP/Host 作为 host
的标签值。
DataKit 自身运行日志配置¶
DataKit 自身日志有两个,一个是自身运行日志(/var/log/datakit/log),一个是 HTTP Access 日志(/var/log/datakit/gin.log)。
DataKit 默认日志等级为 info
。编辑 datakit.conf
,可修改日志等级以及分片大小:
level
:置为debug
后,即可看到更多日志(目前只支持debug/info
两个级别)。rotate
:DataKit 默认会对日志进行分片,默认分片大小为 32MB,总共 6 个分片(1 个当前写入分片加上 5 个切割分片,分片个数尚不支持配置)。如果嫌弃 DataKit 日志占用太多磁盘空间(最多 32 x 6 = 192MB),可减少rotate
大小(比如改成 4,单位为 MB)。HTTP 访问日志也按照同样的方式自动切割。
高级配置¶
下面涉及的内容涉及一些高级配置,如果对配置不是很有把握,建议咨询我们的技术专家。
Point 缓存¶
Point 缓存目前有额外的性能问题,不建议使用。
为了优化 Datakit 高负载情况下的内存占用,可以开启 Point Pool 来缓解:
同时,Datakit 配置中可以开启 content_encoding = "v2"
的传输编码( Version-1.32.0 已默认启用 v2),相比 v1,它的内存和 CPU 开销都更低。
Attention
- 在低负载(Datakit 内存占用 100MB 左右)的情况下,开启 point pool 会增加 Datakit 自身的内存占用。所谓的高负载,一般指占用内存在 2GB+ 的场景。同时开启后也能改善 Datakit 自身的 CPU 消耗
IO 模块调参¶
某些情况下,DataKit 的单机数据采集量非常大,如果网络带宽有限,可能导致部分数据的采集中断或丢弃。可以通过配置 io 模块的一些参数来缓解这一问题:
[io]
feed_chan_size = 1 # 数据处理队列长度
max_cache_count = 1000 # 数据批量发送点数的阈值,缓存中超过该值即触发发送
flush_interval = "10s" # 数据发送的间隔阈值,每隔 10s 至少发送一次
flush_workers = 0 # 数据上传 worker 数(默认配额 CPU 核心 * 2)
阻塞模式参见 k8s 中的对应说明
参见这里
资源限制¶
由于 DataKit 上处理的数据量无法估计,如果不对 DataKit 消耗的资源做物理限制,将有可能消耗所在节点大量资源。这里我们可以借助 Linux 的 cgroup 和 Windows 的 job object 来限制,在 datakit.conf 中有如下配置:
[resource_limit]
path = "/datakit" # Linux cgroup 限制目录,如 /sys/fs/cgroup/memory/datakit, /sys/fs/cgroup/cpu/datakit
# 允许 CPU 最大使用率(百分制)
cpu_max = 20.0
# 默认允许 4GB 内存(memory + swap)占用
# 如果置为 0 或负数,则不启用内存限制
mem_max_mb = 4096
如果 DataKit 超出内存限制后,会被操作系统强制杀掉,通过命令可以看到如下结果,此时需要手动启动服务:
$ systemctl status datakit
● datakit.service - Collects data and upload it to DataFlux.
Loaded: loaded (/etc/systemd/system/datakit.service; enabled; vendor preset: enabled)
Active: activating (auto-restart) (Result: signal) since Fri 2022-02-30 16:39:25 CST; 1min 40s ago
Process: 3474282 ExecStart=/usr/local/datakit/datakit (code=killed, signal=KILL)
Main PID: 3474282 (code=killed, signal=KILL)
Attention
- 资源限制只在宿主机安装的时候会默认开启
- 只支持 CPU 使用率和内存使用量(mem+swap)控制,且只支持 Linux 和 windows ( Version-1.15.0) 操作系统。
- CPU 使用率控制目前不支持这些 windows 操作系统: Windows 7, Windows Server 2008 R2, Windows Server 2008, Windows Vista, Windows Server 2003 和 Windows XP。
- 非 root 用户改资源限制配置时,必须重装 service。
- CPU 核心数限制会影响 Datakit 部分子模块的 worker 数配置(一般是 CPU 核心数的整数倍)。比如数据上传 worker 就是 CPU 核心数 * 2。而单个上传 worker 会占用默认 10MB 的内存用于数据发送,故 CPU 核心数如果开放较多,会影响 Datakit 整体内存的占用
Tip
Datakit 自 1.5.8 开始支持 cgroup v2。如果不确定 cgroup 版本,可通过命令 mount | grep cgroup
来确认。
Datakit 用量计量标准¶
为了规范 Datakit 用量统计,现对 Datakit 的逻辑计量方法进行如下说明:
- 如果没有开启以下这些采集器,则 Datakit 逻辑计量个数为 1
- 如果 Datakit 运行时长(中间断档不超过 30 分钟)超过 12 小时,则参与计量,否则不参与计量
- 对于以下开启的采集器,按照 Datakit 当前配置的 CPU 核心数进行计量,最小值为 1,最大值为物理 CPU 核数 1,小数点按照四舍五入规则取整:
- RUM 采集器
- 通过 TCP/UDP 收取日志数据的采集器
- 通过 kafkamq 采集器同步日志/指标/RUM 等数据的采集器
- 通过 prom_remote_write 采集器同步 Prometheus 指标的采集器
- 通过 beats_output 同步日志数据的采集器
通过上述规则,可以更加合理地反映 Datakit 的实际使用情况,为用户提供更加透明、公平的计费方式。
选举配置¶
参见这里
DataWay 参数配置¶
Dataway 部分有如下几个配置可以配置,其它部分不建议改动:
timeout
:上传观测云的超时时间,默认 30smax_retry_count
:设置 Dataway 发送的重试次数(默认 1 次,最大 10 次) Version-1.17.0retry_delay
:设置重试间隔基础步长,默认 200ms。所谓基础步长,即第一次 200ms,第二次 400ms,第三次 800ms,以此类推(以 $2^n$ 递增) Version-1.17.0max_raw_body_size
:控制单个上传包的最大大小(压缩前),单位字节 Version-1.17.1content_encoding
:可选择 v1 或 v2 Version-1.17.1- v1 即行协议(默认 v1)
- v2 即 Protobuf 协议,相比 v1,它各方面的性能都更优越。运行稳定后,后续将默认采用 v2
Kubernetes 下部署相关配置参见这里。
WAL 队列配置¶
在 [dataway.wal]
中,我们可以调整 WAL 队列的配置:
[dataway.wal]
max_capacity_gb = 2.0 # 2GB reserved disk space for each category(M/L/O/T/...)
workers = 0 # flush workers on WAL(default to CPU limited cores)
mem_cap = 0 # in-memory queue capacity(default to CPU limited cores)
fail_cache_clean_interval = "30s" # duration for clean fail uploaded data
磁盘文件位于 Datakit 安装目录的 cache/dw-wal 目录下:
/usr/local/datakit/cache/dw-wal/
├── custom_object
│ └── data
├── dialtesting
│ └── data
├── dynamic_dw
│ └── data
├── fc
│ └── data
├── keyevent
│ └── data
├── logging
│ ├── data
│ └── data.00000000000000000000000000000000
├── metric
│ └── data
├── network
│ └── data
├── object
│ └── data
├── profiling
│ └── data
├── rum
│ └── data
├── security
│ └── data
└── tracing
└── data
13 directories, 14 files
此处,除了 fc 是失败重传队列,其它目录分别对应一种数据类型。当数据上传失败,这些数据会缓存到 fc 目录下,后续 Datakit 会间歇性将它们上传上去。
Sinker 配置¶
参见这里
使用 Git 管理 DataKit 配置¶
参见这里
本地设置 Pipeline 默认脚本¶
支持通过本地设置默认 Pipeline 脚本,如果与远程设置的默认脚本冲突,则倾向本地设置。
可通过两种方式配置:
-
主机方式部署,可在 DataKit 主配置文件中指定各类别的默认脚本,如下:
-
容器方式部署,可使用环境变量,
ENV_PIPELINE_DEFAULT_PIPELINE
,其值例如{"logging":"abc.p","metric":"xyz.p"}
设置打开的文件描述符的最大值¶
Linux 环境下,可以在 Datakit 主配置文件中配置 ulimit
项,以设置 Datakit 的最大可打开文件数,如下:
ulimit 默认配置为 64000。在 Kubernetes 中,通过设置 ENV_ULIMIT
即可。
资源限制 CPU 使用率说明¶
CPU 使用率是百分比制(最大值 100.0),以一个 8 核心的 CPU 为例,如果限额 cpu_max
为 20.0(即 20%),则 DataKit 最大的 CPU 消耗,在 top 命令上将显示为 160% 左右。
采集器密码保护¶
如果您希望避免在配置文件中以明文存储密码,则可以使用该功能。
DataKit 在启动加载采集器配置文件时遇到 ENC[]
时会在文件、env、或者 AES 加密得到密码后替换文本并重新加载到内存中,以得到正确的密码。
ENC 目前支持三种方式:
-
文件形式(推荐):
配置文件中密码格式: ENC[file:///path/to/enc4dk] ,在对应的文件中填写正确的密码即可。
-
AES 加密方式。
需要在主配置文件
datakit.conf
中配置秘钥: crypto_AES_key 或者 crypto_AES_Key_filePath, 秘钥长度是 16 位。 密码处的填写格式为:ENC[aes://5w1UiRjWuVk53k96WfqEaGUYJ/Oje7zr8xmBeGa3ugI=]
接下来以 mysql
为例,说明两种方式如何配置使用:
1 文件形式
首先,将明文密码放到文件 /usr/local/datakit/enc4mysql
中,然后修改配置文件 mysql.conf:
# 部分配置
[[inputs.mysql]]
host = "localhost"
user = "datakit"
pass = "ENC[file:///usr/local/datakit/enc4mysql]"
port = 3306
# sock = "<SOCK>"
# charset = "utf8"
DK 会从 /usr/local/datakit/enc4mysql
中读取密码并替换密码,替换后为 pass = "Hello*******"
2 AES 加密方式
首先在 datakit.conf
中配置秘钥:
# crypto key or key filePath.
[crypto]
# 配置秘钥
aes_key = "0123456789abcdef"
# 或者,将秘钥放到文件中并在此配置文件位置。
aes_Key_file = "/usr/local/datakit/mykey"
mysql.conf
配置文件:
注意,通过 AES
加密得到的密文需要完整的填入。以下是代码示例:
// AESEncrypt 加密。
func AESEncrypt(key []byte, plaintext string) (string, error) {
block, err := aes.NewCipher(key)
if err != nil {
return "", err
}
// PKCS7 padding
padding := aes.BlockSize - len(plaintext)%aes.BlockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
plaintext += string(padtext)
ciphertext := make([]byte, aes.BlockSize+len(plaintext))
iv := ciphertext[:aes.BlockSize]
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
return "", err
}
mode := cipher.NewCBCEncrypter(block, iv)
mode.CryptBlocks(ciphertext[aes.BlockSize:], []byte(plaintext))
return base64.StdEncoding.EncodeToString(ciphertext), nil
}
// AESDecrypt AES 解密。
func AESDecrypt(key []byte, cryptoText string) (string, error) {
ciphertext, err := base64.StdEncoding.DecodeString(cryptoText)
if err != nil {
return "", err
}
block, err := aes.NewCipher(key)
if err != nil {
return "", err
}
if len(ciphertext) < aes.BlockSize {
return "", fmt.Errorf("ciphertext too short")
}
iv := ciphertext[:aes.BlockSize]
ciphertext = ciphertext[aes.BlockSize:]
mode := cipher.NewCBCDecrypter(block, iv)
mode.CryptBlocks(ciphertext, ciphertext)
// Remove PKCS7 padding
padding := int(ciphertext[len(ciphertext)-1])
if padding > aes.BlockSize {
return "", fmt.Errorf("invalid padding")
}
ciphertext = ciphertext[:len(ciphertext)-padding]
return string(ciphertext), nil
}
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.SecureRandom;
import java.util.Base64;
public class AESUtils {
public static String AESEncrypt(byte[] key, String plaintext) throws Exception {
javax.crypto.Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
SecureRandom random = new SecureRandom();
byte[] iv = new byte[16];
random.nextBytes(iv);
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
byte[] encrypted = cipher.doFinal(plaintext.getBytes());
byte[] ivAndEncrypted = new byte[iv.length + encrypted.length];
System.arraycopy(iv, 0, ivAndEncrypted, 0, iv.length);
System.arraycopy(encrypted, 0, ivAndEncrypted, iv.length, encrypted.length);
return Base64.getEncoder().encodeToString(ivAndEncrypted);
}
public static String AESDecrypt(byte[] key, String cryptoText) throws Exception {
byte[] ciphertext = Base64.getDecoder().decode(cryptoText);
SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
if (ciphertext.length < 16) {
throw new Exception("ciphertext too short");
}
byte[] iv = new byte[16];
System.arraycopy(ciphertext, 0, iv, 0, 16);
byte[] encrypted = new byte[ciphertext.length - 16];
System.arraycopy(ciphertext, 16, encrypted, 0, ciphertext.length - 16);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
byte[] decrypted = cipher.doFinal(encrypted);
return new String(decrypted);
}
}
public static void main(String[] args) {
try {
String key = "0123456789abcdef"; // 16, 24, or 32 bytes AES key
String plaintext = "HelloAES9*&.";
byte[] keyBytes = key.getBytes("UTF-8");
String encrypted = AESEncrypt(keyBytes, plaintext);
System.out.println("Encrypted text: " + encrypted);
String decrypt = AESDecrypt(keyBytes, encrypted);
System.out.println("解码后的是:"+decrypt);
} catch (Exception e) {
System.out.println(e);
e.printStackTrace();
}
}
K8S 环境下可以通过环境变量方式添加私钥:ENV_CRYPTO_AES_KEY
和 ENV_CRYPTO_AES_KEY_FILEPATH
可以参考:DaemonSet 安装-其他
远程任务¶
DataKit 接收中心下发任务并执行。目前支持 JVM dump
功能。
安装 DK 之后会在安装目录下 template/service-task
生成两个文件:jvm_dump_host_script.py
和 jvm_dump_k8s_script.py
前者是宿主机模式下的脚本,后者是虚拟(k8s)环境下的。
DK 启动之后会定时执行脚本,如果修改脚本 那么 DK 重启之后会覆盖掉。
宿主机环境下,当前的环境需要有 python3
以及 requests
包。如果没有 需要安装 :
K8S 环境下需要调用 Kubernetes API 所以需要 RBAC 基于角色的访问控制
配置相关:
其目录一般位于:
- Linux/Mac:
/usr/local/datakit/conf.d/datakit.conf
- Windows:
C:\Program Files\datakit\conf.d\datakit.conf
修改配置,如果没有在最后添加:
修改 DataKit yaml 文件,添加 RBAC 权限
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: datakit
rules:
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["clusterroles"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["nodes", "nodes/stats", "nodes/metrics", "namespaces", "pods", "pods/log", "events", "services", "endpoints", "persistentvolumes", "persistentvolumeclaims", "pods/exec"]
verbs: ["get", "list", "watch", "create"]
- apiGroups: ["apps"]
resources: ["deployments", "daemonsets", "statefulsets", "replicasets"]
verbs: ["get", "list", "watch"]
- apiGroups: ["batch"]
resources: ["jobs", "cronjobs"]
verbs: [ "get", "list", "watch"]
- apiGroups: ["guance.com"]
resources: ["datakits"]
verbs: ["get","list"]
- apiGroups: ["monitoring.coreos.com"]
resources: ["podmonitors", "servicemonitors"]
verbs: ["get", "list"]
- apiGroups: ["metrics.k8s.io"]
resources: ["pods", "nodes"]
verbs: ["get", "list"]
- nonResourceURLs: ["/metrics"]
verbs: ["get"]
---
在上面的配置中,添加了 "pod/exec",其他的保持和 yaml 一致即可。
添加 remote_job 环境变量:
配置说明:
enable ENV_REMOTE_JOB_ENABLE remote_job
功能开关。envs ENV_REMOTE_JOB_ENVS
OSS 配置,其中包括 OSShost
access key
secret key
bucket
信息,将获取到的 JVM dump 文件发送到 OSS 中。interval ENV_REMOTE_JOB_INTERVAL
DataKit 主动调用接口获取最新任务的时间间隔。java_home ENV_REMOTE_JOB_JAVA_HOME
宿主机环境自动从环境变量($JAVA_HOME)中获取,可以不用配置。
注意,使用的 Agent:
dd-java-agent.jar
版本不应低于v1.4.0-guance
延伸阅读¶
-
如果没有配置 CPU 限额,则 N 取物理机/Node 的 CPU 核心数 ↩