赞
踩
作者:玄飏
长话短说:
在 SLS 控制台,一个简单的采集配置长这样:
通过控制台管理采集配置,终究是不够自动化。
试想:若是每次发布,都需要手动上控制台修改一批采集配置,岂不是太麻烦了?更何况可能改错。
在云原生时代,我们需要更方便的方式,来管理采集配置。这种方式,它最好是可灵活扩展的,不与业务耦合;它最好是可以集中管理和监控的,来简化运维的操作;它最好是方便集成与自动化部署的,来降低部署的难度……
基于以上需求,CRD 就这样进入了我们的视线。
在 Kubernetes 环境中,CRD 是一种扩展 K8s API 的方法,允许用户定义和管理自己的资源。使用 CRD,可以将采集配置作为 Kubernetes 对象进行管理,使其与其他 Kubernetes 资源(如 Pod、Service、Deployment)保持一致。
看着真不错,那就整一个 CRD 吧!
是的,我们有一个 CRD——AliyunLogConfig。
让我们先看一个简单的 AliyunLogConfig 配置示例:
apiVersion: log.alibabacloud.com/v1alpha1 kind: AliyunLogConfig metadata: # 设置资源名,在当前Kubernetes集群内唯一。 name: example-k8s-file namespace: kube-system spec: # 【可选】目标project project: k8s-log-xxxx # 设置Logstore名称。如果您所指定的Logstore不存在,日志服务会自动创建。 logstore: k8s-file # 【可选】Logstore shard数 shardCount: 10 # 【可选】Logstore存储时间 lifeCycle: 30 # 【可选】Logstore热存储时间 logstoreHotTTL: 7 # 设置iLogtail采集配置。 logtailConfig: # 设置采集的数据源类型。采集文本日志时,需设置为file。 inputType: file # 设置iLogtail采集配置的名称,必须与资源名(metadata.name)相同。 configName: example-k8s-file inputDetail: # 指定通过极简模式采集文本日志。 logType: common_reg_log # 设置日志文件所在路径。 logPath: /data/logs/app_1 # 设置日志文件的名称。支持通配符星号(*)和半角问号(?),例如log_*.log。 filePattern: test.LOG # 采集容器的文本日志时,需设置dockerFile为true。 dockerFile: true # 设置容器过滤条件。 advanced: k8s: K8sNamespaceRegex: ^(default)$ K8sPodRegex: '^(demo-0.*)$' K8sContainerRegex: ^(demo)$ IncludeK8sLabel: job-name: "^(demo.*)$"
AliyunLogConfig 内置了默认 Project,使用时,只需要指定目标 Logstore,并编辑采集配置,就可以实现数据接入。后来,随着 AliyunLogConfig 不断发展,还新增了一些新功能,比如支持定义 Logstore 的创建参数、支持指定目标 project、支持简单的跨地域、跨账号能力等等。
AliyunLogConfig 会把 CR 的处理结果反馈到 Status 字段中,内有 statusCode 与 statu 两个字段。
status:
statusCode: 200
status: OK
总的来说,AliyunLogConfig 作为管理采集配置的 CRD,可以满足基本的功能需求,且可以支持一些复杂场景。
随着 SLS 不断发展,AliyunLogConfig 的局限性也不断凸显出来。
我们全新的 CRD——AliyunPipelineConfig,来了!
相较于 AliyunLogConfig,AliyunPipelineConfig 在配置格式、行为逻辑上做了很大改进,主打的就是灵活、简单、稳定。
类型 | AliyunPipelineConfig(全新升级) | AliyunLogConfig |
---|---|---|
ApiGroup | telemetry.alibabacloud.com/v1alpha1 | log.alibabacloud.com/v1alpha1 |
CRD资源名 | ClusterAliyunPipelineConfig | AliyunLogConfig |
作用域 | 集群 | 默认集群 |
采集配置格式 | 基本等价于日志服务API中的“LogtailPipelineConfig [ 1] ” | 基本等价于日志服务API中的“LogtailConfig [ 2] ” |
跨地域能力 | 支持 | 支持 |
跨账号能力 | 支持 | 支持 |
webhook校验参数 | 支持 | 不支持 |
配置冲突检测 | 支持 | 不支持 |
配置难度 | 较低 | 较高 |
配置可观测性 | Status包含错误详情、更新时间、上次应用成功配置、上次应用成功时间等信息 | Status包含错误码与错误信息 |
AliyunPipelineConfig 的整体结构如下:
apiVersion: telemetry.alibabacloud.com/v1alpha1 kind: ClusterAliyunPipelineConfig metadata: name: test-config spec: project: # 目标project name: k8s-your-project # project名 uid: 11111 #【选填】账号 endpoint: cn-hangzhou-intranet.log.aliyuncs.com # 【选填】endpoint logstores: #【选填】需要创建的 logstore 列表,与 CreateLogstore 接口基本一致 - name: your-logstore # logstore名 ttl: 30 #【选填】数据保存时间 shardCount: 10 #【选填】shard 数 ... #【选填】其他 Logstore 参数 machineGroups: #【选填】需要与采集配置关联的机器组列表 - name: machine-group-1 # 机器组名 - name: machine-group-2 # 机器组名 config: # 采集配置,格式与 CreateLogtailPipelineConfig 接口基本一致 sample: #【选填】日志样例 global: #【选填】全局配置 inputs: # 输入插件,必须有且只有一个 ... processors: #【选填】处理插件,可以自由组合 ... aggregators: #【选填】聚合插件 ... flushers: # 输出插件,只能有一个flusher_sls ... enableUpgradeOverride: false #【选填】用于升级 AliyunLogConfig
AliyunPipelineConfig 的配置有几个特点:
下面,我们详细讲讲 spec 字段里的字段。
project 字段列表如下:
参数 | 数据类型 | 是否必填 | 说明 |
---|---|---|---|
name | string | 是 | 目标 Project 的名称。 |
description | string | 否 | 目标 Project 的描述。 |
endpoint | string | 否 | 目标 Project 的服务入口。仅在有跨地域的需求时填写。 |
uid | string | 否 | 目标账号的 uid。仅在有跨账号的需求时填写。 |
有一些注意点:
config 字段列表如下:
参数 | 数据类型 | 是否必填 | 说明 |
---|---|---|---|
sample | string | 否 | 日志样例。 |
global | object | 否 | 全局配置。 |
inputs | object列表 | 是 | 输入插件列表。 |
processors | object列表 | 否 | 处理插件列表。 |
aggregators | object列表 | 否 | 聚合插件列表。 |
flushers | object列表 | 是 | 输出插件列表。 |
configTags | map | 否 | 用于标记iLogtail采集配置的自定义标签。 |
为了追求使用体验的统一、功能的完善,config的详细信息与插件参数,与 SLS CreateLogtailPipelineConfig [ 3] 接口的 “请求参数” 完全一致,并支持所有功能。
这里需要注意:
logstores 字段,里面支持配置多个 logstore 属性。单个 logstore 的参数列表如下:
这里的 Logstore 参数,完全支持了 SLSCreateLogstore [ 4] 接口中的参数,并且支持修改计费模式。
这里的注意点有:
machineGroups 字段,里面支持配置多个机器组。下面是单个机器组的参数列表:
参数 | 数据类型 | 是否必填 | 说明 |
---|---|---|---|
name | string | 是 | 需要与iLogtail采集配置关联的机器组名。 |
机器组配置做了简化处理,只需要填写 name,就会创建一个标识型机器组,机器组的名字与自定义标识一致。
需要注意:
相信大家都有遇到过,面对一个不熟悉的配置,乱填一通参数,提交上去,发现又没有成功,又没有报错,整个流程卡死在那了。
AliyunPipelineConfig 不会让你受这样的委屈!你只管填写参数,其他的事情,AliyunPipelineConfig 全兜了!
AliyunPipelineConfig 具有详细的 CRD 格式规范,同时搭配了 webhook 进行校验,让格式问题无所遁形!
全方位为你保驾护航。
虽然有参数值的校验,但参数内容也还是可能填错的,就比如我们的 Logstore,创建的时候参数那么多,难免填错一个;或者,机器组配额超限了,写了一些机器组怎么都创建不出来;或者,填写的 uid 错了,没有获取到跨账号的权限……
这些情况,可以由我们 AliyunPipelineConfig 的 Status 字段,全部展示出来!下面是一段采集配置,在配置时指定错了 project,使用了其他用户的 project,那么这里就会有报错:
apiVersion: telemetry.alibabacloud.com/v1alpha1 kind: ClusterAliyunPipelineConfig metadata: finalizers: - finalizer.pipeline.alibabacloud.com name: example-k8s-file # 预期的配置 spec: config: flushers: - Endpoint: cn-hangzhou.log.aliyuncs.com Logstore: k8s-file Region: cn-hangzhou TelemetryType: logs Type: flusher_sls inputs: - EnableContainerDiscovery: true FilePaths: - /data/logs/app_1/**/test.LOG Type: input_file logstores: - encryptConf: {} name: k8s-file project: name: k8s-log-clusterid # CR的应用状态 status: # CR 是否应用成功 success: false # CR 当前的状态信息,应用失败会展示报错详情 message: |- { "httpCode": 401, "errorCode": "Unauthorized", "errorMessage": "The project does not belong to you.", "requestID": "xxxxxx" } # 当前 status 的更新时间 lastUpdateTime: '2024-06-19T09:21:34.215702958Z' # 上次成功应用的配置信息,该配置信息为填充默认值后实际生效的配置。本次没有应用成功,所以这里为空 lastAppliedConfig: config: flushers: null global: null inputs: null project: name: ""
通过这些报错信息,就可以很方便地定位到问题。
另外,AliyunPipelineConfig 会进行失败重试,如果是临时发生的报错(例如某个project 的 logstore 额度不够,很快调整好了),后续都会重试到正常为止(重试间隔指数增长)。
在 AliyunLogConfig 时代,我们可能会遇到这样的问题:一不小心好几个 CR 指向了同一个 project/config,导致整个采集配置被几个 CR 相互覆盖,日志采集被影响。
AliyunPipelineConfig 会帮你解决这个问题!在创建采集配置时,AliyunPipelineConfig 会给采集配置打上标签,记录CR所在的集群、类型、命名空间:
对于有标签的采集配置,只有创建者可以对它进行修改,其他 CR 的请求会被拒绝。当然,被拒绝的 CR 也会把拒绝信息写到 Status 中,告诉你它与 xx 集群 xx 命名空间 xx 类型的名为 xx 的 CR 出现了冲突,这样可以快速定位,解决问题。
你可能会说了:你 balabala 说了这么一大堆,我好像看懂了但还是不会配置啊!
别急,下面来几个例子,实操练手。
这是 ACK ingress 组件配置日志采集的文档 [ 5] ,可以看到里面配置了一个比较复杂的 AliyunLogConfig CR,并配上了很长的说明:
我们现在用 AliyunPipelineConfig 来实现它:
apiVersion: telemetry.alibabacloud.com/v1alpha1 kind: ClusterAliyunPipelineConfig metadata: name: k8s-nginx-ingress spec: # 指定目标 project project: name: <your-project-name> logstores: # 创建 Logstore,用于存储Ingress日志 - name: nginx-ingress # 产品Code,请勿更改。 productCode: k8s-nginx-ingress # 添加采集配置 config: # 定义输入插件 inputs: # 使用service_docker_stdout插件采集容器内文本日志 - Type: service_docker_stdout Stdout: true Stderr: true # 过滤目标容器,这里是容器label。 IncludeLabel: io.kubernetes.container.name: nginx-ingress-controller # 定义解析插件 processors: - Type: processor_regex KeepSource: false Keys: - client_ip - x_forward_for - remote_user - time - method - url - version - status - body_bytes_sent - http_referer - http_user_agent - request_length - request_time - proxy_upstream_name - upstream_addr - upstream_response_length - upstream_response_time - upstream_status - req_id - host - proxy_alternative_upstream_name NoKeyError: true NoMatchError: true # 提取字段使用的正则表达式。符合该格式的日志,会将每个捕获组中内容映射到对应的字段上。 Regex: ^(\S+)\s-\s\[([^]]+)]\s-\s(\S+)\s\[(\S+)\s\S+\s"(\w+)\s(\S+)\s([^"]+)"\s(\d+)\s(\d+)\s"([^"]*)"\s"([^"]*)"\s(\S+)\s(\S+)+\s\[([^]]*)]\s(\S+?(?:,\s\S+?)*)\s(\S+?(?:,\s\S+?)*)\s(\S+?(?:,\s\S+?)*)\s(\S+?(?:,\s\S+?)*)\s(\S+)\s*(\S*)\s*\[*([^]]*)\]*.* SourceKey: content # 定义输出插件 flushers: # 使用flusher_sls插件输出到指定Logstore。 - Type: flusher_sls Logstore: nginx-ingress Endpoint: <your-endpoint> Region: <your-region> TelemetryType: logs
这样,一个 ingress 解析配置就好了,结构非常清晰。
首先,我们需要明确一点,就是数据采集依赖:
要做到跨地域和跨账号,不仅需要修改采集配置的生成端(alibaba-log-controller)的配置,也需要修改采集器侧(iLogtail)的配置。
下面我们举一个例子,来介绍我们的跨地域和跨账号能力。
我们假设数据源在 A 账号杭州地域,要投递到 B 账号的上海地域。
首先,需要修改 iLogtail 的启动参数。
logtail 的启动参数可以参考文档 [ 6] ,这里我们只关心 ilogtail_config.json 文件里面的两个参数:config_server_address 和 data_server_list。
初始的启动参数文件只包含一个 region,就如文档里的:
{ "config_server_address" : "http://logtail.cn-hangzhou.log.aliyuncs.com", "config_server_address_list": [ "http://logtail.cn-shanghai.log.aliyuncs.com" "http://logtail.cn-hangzhou.log.aliyuncs.com" ], "data_server_list" : [ { "cluster" : "cn-shanghai", "endpoint" : "cn-shanghai.log.aliyuncs.com" }, { "cluster" : "cn-hangzhou", "endpoint" : "cn-hangzhou.log.aliyuncs.com" }, ] }
可以把这个文件保存到 configMap 中,挂载到 kube-system 命名空间下,名为logtail-ds 的 daemonset 里,容器内路径假设为 /etc/ilogtail/ilogtail_config.json
然后,在集群中,在 kube-system 命名空间下,找到名为 alibaba-log-configuration 的 configmap
编辑 log-ali-uid 的值,添加B账号的uid(多个账号之间使用半角逗号(,)相隔,例如 17397,12456)
编辑 log-config-path 的值,改为上面挂载的 /etc/ilogtail/ilogtail_config.json
记录下 log-machine-group 配置项的值
至此,iLogtail 就直接拉取上海地域的采集配置、发送数据到上海,并拥有了 B 账号的用户标识。
alibaba-log-controller 的改动比较简单:
在 kube-system 命名空间下,找到名为 alibaba-log-controller 的 deployment。
添加环境变量 ALICLOUD_LOG_ACCOUNT_INFOS={“”:{“accessKeyID”:“<your_access_key_id>”,“accessKeySecret”:“<your_access_key_secret>”}},这里的 uid 是 B 账号的,ak/sk 需要具备 SLS 相关的权限。
至此,alibaba-log-controller 就拥有了在 B 账号下创建 SLS 资源(logstore、采集配置等)的权限。
编辑 AliyunPipelineConfig 的 CR 是最简单的一步,只需要添加上 uid 和 endpoint 即可。不要忘记修改 flusher_sls 中的 endpoint 和 region。
apiVersion: telemetry.alibabacloud.com/v1alpha1 kind: ClusterAliyunPipelineConfig metadata: name: k8s-nginx-ingress spec: # 指定目标 project project: # B账号的project name: <your-project-name> # B账号的uid uid: <uid-user-b> # 目标endpoint endpoint: cn-shanghai.log.aliyuncs.com # 添加采集配置 config: # 定义输入插件 inputs: # 这里省略 ... # 定义输出插件 flushers: # 使用flusher_sls插件输出到指定Logstore。 - Type: flusher_sls Logstore: nginx-ingress Endpoint: cn-shanghai.log.aliyuncs.com Region: cn-shanghai TelemetryType: logs
这样,采集配置就会创建在 B 账号的 project 下,数据也可以采集过来了。
还记得我们上面讲解 AliyunPipelineConfig 参数时,省略了一个吗?就是 enableUpgradeOverride!
当满足以下条件时,可以把 AliyunLogConfig 直接升级到 AliyunPipelineConfig:
AliyunLogConfig 与 AliyunPipelineConfig 在同一集群内
a. 如果不在同一集群,AliyunPipelineConfig 会因配置冲突而应用失败
AliyunLogConfig 与 AliyunPipelineConfig 指向同一个采集配置:
a. 目标 project 相同
AliyunLogConfig 中为集群默认的 project 或 spec.project
AliyunPipelineConfig 中为 spec.project.name
b. 目标 iLogtail 采集配置名相同
AliyunPipelineConfig 打开了 enableUpgradeOverride 开关
apiVersion: telemetry.alibabacloud.com/v1alpha1
kind: ClusterAliyunPipelineConfig
metadata:
name: k8s-nginx-ingress
spec:
# 只需要打开这个开关,就可以覆盖更新指向project:<your-project-name>、采集配置名为:k8s-nginx-ingress的AliyunLogConfig
enableUpgradeOverride: true
project:
name: <your-project-name>
config:
inputs:
...
flushers:
...
满足以上条件,我们的 CRD 管理器 alibaba-log-controller 就会执行以下操作:
应用 AliyunPipelineConfig,将原本的采集配置覆盖。
如果应用成功,删除已有的 AliyunLogConfig。
这样,AliyunLogConfig 就可以升级到 AliyunPipelineConfig 了。
AliyunPipelineConfig 的介绍就到这里了,不知道你有没有会用了呢?
AliyunPipelineConfig 会先在“自建 K8s 集群部署日志组件 [ 6] ”上线,后续会正式登陆 ACK 等容器产品,欢迎大家使用并反馈意见,我们会虚心采纳和改正。相关链接:
[1] LogtailPipelineConfig
https://help.aliyun.com/zh/sls/developer-reference/api-sls-2020-12-30-struct-logtailpipelineconfig
[2] LogtailConfig
https://help.aliyun.com/zh/sls/developer-reference/api-sls-2020-12-30-struct-logtailconfig
[3] CreateLogtailPipelineConfig
https://help.aliyun.com/zh/sls/developer-reference/api-sls-2020-12-30-createlogtailpipelineconfig
[4] CreateLogstore
https://help.aliyun.com/zh/sls/developer-reference/api-sls-2020-12-30-createlogstore
[5] 文档
https://help.aliyun.com/zh/ack/ack-managed-and-ack-dedicated/user-guide/analyze-and-monitor-the-access-log-of-nginx-ingress?spm=a2c4g.11186623.0.i33#e73d30b45c8rw
[6] 文档
https://help.aliyun.com/zh/sls/user-guide/logtail-configuration-files-and-record-files?spm=a2c4g.11186623.0.0.282e8a80VCedLM
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。