庚子夜半漏下三刻,众微机突发雪崩!余施大华胄日志天网,救大匠于九死一生
近岁余总督诸省大算,每念及往昔跨云汉(AWS)御集群、收罗流言日志之役,至今犹惊心动魄。昔者居方寸机房,构筑 ELK 塔台,不过如庭院戏沙,自娱自乐耳。及至转战天朝上国之云端(AWS),御 ECS Fargate 与 EKS 战阵,面对百千瞬息生灭之“神荚”(Pod)与“差事”(Task),始知旧法胶柱鼓瑟,决计难行。
忆昔某夜,漏下三刻,三军忽溃。研发大匠趋步来告,急索行军日志。余登临台阁(控制台)视之,则神荚因贪墨资粮(OOM)早已灰飞烟灭,片甲不留,欲哭无泪,莫过如此。
今日不坐论泰西之玄理,唯倾囊相授,直言 ECS 与 EKS 多神荚日志收罗之变法实战。此策历经百战,涉险坑无数,皆乃碧血换得之真知。
势逼其变:何故弃旧因循?
初登云汉之同僚,常陷一误区:不论青红皂白,先于 EKS 营寨中强塞一 Logstash 臃肿之物,或以“戴曼护卫”(DaemonSet)强行钩连宿主机之栈道。
然于今之云原生变局中,此法必致全军覆没:
- Fargate 御风无形,无迹可寻: 彼乃无碑之神兵(Serverless),底层躯壳(EC2)隐匿于虚空,欲寻
/var/log/pods之栈道,无门可入。 - 资粮内讧,同室操戈: 尝有恶战,业务洪流猝至,收罗日志之卒(Agent)暴食机杼(CPU),竟将身侧核心业务之神荚驱逐出境。此正所谓“逐麋鹿而丧其家”,本末倒置。
- 聚散无常,收罗莫及: 军阵暴涨,收罗未及置办;军阵暴缩,而存诸内存之残墨,随风蒸发。
由是,余等痛下决心,尽毁旧制,重整乾坤。其核心要奥,唯“解耦”二字而已。
ECS Fargate 阵线:FireLens 乃天子赤子
若尔等所御者乃 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 二驭者互搏,气血冲撞。
且看余等当年精简之法度图谱(此即筑宇之墨线):
JSON
{
"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(K8s)多神荚阵线:Fluent Bit 与 IRSA 之铁血杀伐
及至 EKS 疆场,变阵更为繁复,亦最易使人目眩神迷。
余等今日所奉之王道架构,乃是:Fluent Bit (戴曼护卫) -> Amazon Kinesis Data Firehose -> Amazon S3 / OpenSearch。
何故居中横插一尊 Firehose 巨鼎?直入 OpenSearch 或 S3 岂不痛快?
非也。诸君听真,若贵司业务日产数武(TB)之墨迹,直教数百神荚之 Fluent Bit 纷乱叩击 S3 龙门,则 S3 问卷之资(API 费用),翌月定教诸君卷席除名。Firehose 之功,在于聚沙成塔、御压缓冲,积满五兆(5MB)或候六十息,方倾泻入 S3 库房,既省帑银,又显儒雅。
权柄警示:切莫乞灵于群节点之 IAM 旧袍!
于安设 Fluent Bit 之前,须棒喝一安全隐患。余阅寰宇诸多公司之 EKS 营寨,皆将染指 CloudWatch 或 S3 之权柄,径直加诸 EKS 节点(底层 EC2)之 IAM 袍服上。
此举无异于将阖里之锁钥,高悬于辕门。寨中但凡有一心怀鬼胎之行军卒,皆可透过乾坤地址(Metadata)窃得此袍,进而将贵司 S3 宝库焚毁一空。
必得奉行 IRSA (IAM Roles for Service Accounts)。将 IAM 权柄法袍,遥绑定于 K8s 之“役事账房”(ServiceAccount)之身。
简而言之,布阵唯三步(莫嫌繁复,此乃保命之圭臬):
- 于 AWS IAM 秘阁中勒石立盟,特许往 CloudWatch/Firehose 录入墨迹。
- 铸一 IAM 权柄法袍,遥信尔等 EKS 营寨之 OIDC 执符者。
- 于 K8s 之中辟一“役事账房”,钤印法袍之流派(Annotation)。
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 贝叶经(ConfigMap)如何运笔方不至崩裂?
尔后乃是全军之重器: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 天雷殛之。
终章总结与行军碎碎念
演练诸般阵法,终得血泪教训数条:
- 墨迹留存之策(Retention): 新辟之 CloudWatch 墨池,公家默认“万寿无疆”。昔有一愚卒未察,于生产大阵中驰骋三月,数百神荚日夜狂喷墨汁,及至月底觇视账单,CloudWatch 存墨之资竟僭越 EC2 铁骑,几近革职。切记将其拘于七日或十四日之限,不常用者,借生命周期沉降至 S3 寒冰冷灶中归档。
- 多行句读(Multiline): 倘系 Java 或 Python 之属,速于 INPUT 或 FILTER 阵线加持
multiline.parser。否则,那长蛇般的绝命堆栈化作数十条残笔呈递,非但面目可憎,亦将索引天书撑爆。
大抵云原生之御史,皆如是也。风平浪静之下,暗礁密布。天下安有万全之阵?唯适宜自家兵刃与军费预算者,方为上策。
今夕姑且言尽于此。诸君于折腾 AWS ECS 或 EKS 日志之时,若遇权柄胶着、或墨迹延宕等诡异妖变,愿乞言于评论区,吾辈当秉烛共研之。
诸君若觉此文击中痛处,或助尔等避开疆场之暗枪,切莫吝惜双指,赞、在看、转发三连走一波!生产一线之玄机,吾辈下期再行切磋。
公众号:耕云躬行录
个人博客:躬行笔记
关注@运维躬行录,领诸君勘破更多秘而不宣之云原生硬核实战,少走弯路,拂袖早归!