忆昔某夜,漏下三刻,三军忽溃。研发大匠趋步来告,急索行军日志。余登临台阁(控制台)视之,则神荚因贪墨资粮(OOM)早已灰飞烟灭,片甲不留,欲哭无泪,莫过如此。
今日不坐论泰西之玄理,唯倾囊相授,直言 ECS 与 EKS 多神荚日志收罗之变法实战。此策历经百战,涉险坑无数,皆乃碧血换得之真知。
初登云汉之同僚,常陷一误区:不论青红皂白,先于 EKS 营寨中强塞一 Logstash 臃肿之物,或以“戴曼护卫”(DaemonSet)强行钩连宿主机之栈道。
然于今之云原生变局中,此法必致全军覆没:
/var/log/pods 之栈道,无门可入。由是,余等痛下决心,尽毁旧制,重整乾坤。其核心要奥,唯“解耦”二字而已。

若尔等所御者乃 ECS Fargate,听余一言:切莫于业务神舟内自造漏卮以导日志,亦休得折腾 Sidecar 共用卷之繁文缛节。云汉官家特为 ECS 赐造神器,名曰 FireLens。此物本是 Fluent Bit 或 Fluentd 之锦衣外袍,与 ECS 差事之法度契合得天衣无缝。
余等彼时擢用 Fluent Bit 为三军基石。何不用 Fluentd?盖因 Fluentd 乃 Ruby 蛮语所制,吞噬内存之状,极其骇人。而 Fluent Bit 乃 C 语言淬炼,精悍敏捷,居万马奔腾之势,所耗资粮不过十数兆,省下者皆乃库银真金。
于 ECS 差事法度(Task Definition)中安设 FireLens,实乃于业务神舟之侧,垂挂一掌灯法船。
然此处隐一巨坑。诸多同僚按图索骥,事毕却见 CloudWatch 或 S3 幽冥之海中,寂然无声,死活不见日志。按部班排查良久,始知乃 awslogs 与 firelens 二驭者互搏,气血冲撞。
且看余等当年精简之法度图谱(此即筑宇之墨线):
{
"containerDefinitions": [
{
"name": "log_router",
"image": "amazon/aws-for-fluent-bit:stable",
"essential": true,
"firelensConfiguration": {
"type": "fluentbit",
"options": {
"enable-ecs-log-metadata": "true"
}
},
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "firelens-container-errors",
"awslogs-region": "ap-southeast-1",
"awslogs-stream-prefix": "firelens"
}
}
},
{
"name": "app-service",
"image": "your-app-image:latest",
"essential": true,
"logConfiguration": {
"logDriver": "awsfirelens",
"options": {
"Name": "cloudwatch",
"region": "ap-southeast-1",
"log_group_name": "/aws/ecs/app-cluster",
"log_stream_name": "app-logs-$(ecs_task_id)",
"auto_create_group": "true"
}
}
}
]
}诸君拭目:业务神舟(app-service)之 logDriver 必得遥尊 awsfirelens。
且看那 log_stream_name 尾缀,赫然缀以 $(ecs_task_id) 变数,此乃绝妙之笔!若无此变数,诸路神荚之墨迹尽皆涌入同一溪流。洪流至时,CloudWatch 阀门(API 限制)必将厉声断流,致日志溃散殆尽。
及至 EKS 疆场,变阵更为繁复,亦最易使人目眩神迷。
余等今日所奉之王道架构,乃是:Fluent Bit (戴曼护卫) -> Amazon Kinesis Data Firehose -> Amazon S3 / OpenSearch。
何故居中横插一尊 Firehose 巨鼎?直入 OpenSearch 或 S3 岂不痛快?
非也。诸君听真,若贵司业务日产数武(TB)之墨迹,直教数百神荚之 Fluent Bit 纷乱叩击 S3 龙门,则 S3 问卷之资(API 费用),翌月定教诸君卷席除名。Firehose 之功,在于聚沙成塔、御压缓冲,积满五兆(5MB)或候六十息,方倾泻入 S3 库房,既省帑银,又显儒雅。
于安设 Fluent Bit 之前,须棒喝一安全隐患。余阅寰宇诸多公司之 EKS 营寨,皆将染指 CloudWatch 或 S3 之权柄,径直加诸 EKS 节点(底层 EC2)之 IAM 袍服上。
此举无异于将阖里之锁钥,高悬于辕门。寨中但凡有一心怀鬼胎之行军卒,皆可透过乾坤地址(Metadata)窃得此袍,进而将贵司 S3 宝库焚毁一空。
必得奉行 IRSA (IAM Roles for Service Accounts)。将 IAM 权柄法袍,遥绑定于 K8s 之“役事账房”(ServiceAccount)之身。
简而言之,布阵唯三步(莫嫌繁复,此乃保命之圭臬):
YAML
apiVersion: v1
kind: ServiceAccount
metadata:
name: fluent-bit-sa
namespace: logging
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/EKS-FluentBit-LogRole如是,Fluent Bit 游走之时,独奉此特定法袍之金牌(临时 Token)与云汉钦差交涉,稳若泰山。
尔后乃是全军之重器:Fluent Bit 之法度。诸多同僚尝陷于日志残缺、多行墨迹(如 Java 之 Exception 绝命堆栈)被斩为寸断之苦境。
日日听闻研发大匠怨声载道:“此恶报缺首断足,如何按图索骥?”
此乃“句读编排器”(Parser)未得其法耳。余特将线上海战所悬之贝叶经核心定规录于下方,尤以规训多行墨迹、斥退无用微恙检查(健康检查)之法度为要:
YAML
apiVersion: v1
kind: ConfigMap
metadata:
name: fluent-bit-config
namespace: logging
data:
fluent-bit.conf: |
[SERVICE]
Flush 1
Log_Level info
Daemon off
Parsers_File parsers.conf
[INPUT]
Name tail
Tag kube.*
Path /var/log/containers/*.log
Parser docker
DB /var/log/flb_kube.db
Mem_Buf_Limit 50MB
Skip_Long_Lines On
Refresh_Interval 10
[FILTER]
Name kubernetes
Match kube.*
Kube_URL https://kubernetes.default.svc:443
Kube_CA_File /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
Kube_Token_File /var/run/secrets/kubernetes.io/serviceaccount/token
Kube_Tag_Prefix kube.var.log.containers.
Merge_Log On
Keep_Log Off
K8S-Logging.Parser On
K8S-Logging.Exclude On
# 要义:屏退 Nginx 聒噪之微恙检查,还府库以清宁空间
[FILTER]
Name grep
Match kube.*
Exclude log kube-probe|HealthCheck
[OUTPUT]
Name cloudwatch_logs
Match kube.*
region ap-southeast-1
log_group_name /eks/prod-cluster-logs
log_stream_prefix k8s-
auto_create_group true其中隐匿三般细节:
DB /var/log/flb_kube.db:必得置一 SQLite 账本以录寻墨之位(Position)。如若不然,Fluent Bit 但凡惊变重启,必将旧墨重抄一遍,致案牍连篇,研发势必与尔论剑。Mem_Buf_Limit 50MB:乃是对纳墨闸口强行限流。若下游云汉府库微有凝滞,Fluent Bit 必拼死将墨汁纳于腹中(内存),若无此限制,彼必因腹胀(OOM)而遭 K8s 天雷殛之。演练诸般阵法,终得血泪教训数条:
multiline.parser。否则,那长蛇般的绝命堆栈化作数十条残笔呈递,非但面目可憎,亦将索引天书撑爆。大抵云原生之御史,皆如是也。风平浪静之下,暗礁密布。天下安有万全之阵?唯适宜自家兵刃与军费预算者,方为上策。
今夕姑且言尽于此。诸君于折腾 AWS ECS 或 EKS 日志之时,若遇权柄胶着、或墨迹延宕等诡异妖变,愿乞言于评论区,吾辈当秉烛共研之。
诸君若觉此文击中痛处,或助尔等避开疆场之暗枪,切莫吝惜双指,赞、在看、转发三连走一波!生产一线之玄机,吾辈下期再行切磋。