庚子夜半漏下三刻,众微机突发雪崩!余施大华胄日志天网,救大匠于九死一生

庚子夜半漏下三刻,众微机突发雪崩!余施大华胄日志天网,救大匠于九死一生

近岁余总督诸省大算,每念及往昔跨云汉(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 幽冥之海中,寂然无声,死活不见日志。按部班排查良久,始知乃awslogsfirelens二驭者互搏,气血冲撞。

且看余等当年精简之法度图谱(此即筑宇之墨线):

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)之身。

简而言之,布阵唯三步(莫嫌繁复,此乃保命之圭臬):

  1. 于 AWS IAM 秘阁中勒石立盟,特许往 CloudWatch/Firehose 录入墨迹。
  2. 铸一 IAM 权柄法袍,遥信尔等 EKS 营寨之 OIDC 执符者。
  3. 于 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 天雷殛之。

终章总结与行军碎碎念

演练诸般阵法,终得血泪教训数条:

  1. 墨迹留存之策(Retention):新辟之 CloudWatch 墨池,公家默认“万寿无疆”。昔有一愚卒未察,于生产大阵中驰骋三月,数百神荚日夜狂喷墨汁,及至月底觇视账单,CloudWatch 存墨之资竟僭越 EC2 铁骑,几近革职。切记将其拘于七日或十四日之限,不常用者,借生命周期沉降至 S3 寒冰冷灶中归档。
  2. 多行句读(Multiline):倘系 Java 或 Python 之属,速于 INPUT 或 FILTER 阵线加持multiline.parser。否则,那长蛇般的绝命堆栈化作数十条残笔呈递,非但面目可憎,亦将索引天书撑爆。

大抵云原生之御史,皆如是也。风平浪静之下,暗礁密布。天下安有万全之阵?唯适宜自家兵刃与军费预算者,方为上策。

今夕姑且言尽于此。诸君于折腾 AWS ECS 或 EKS 日志之时,若遇权柄胶着、或墨迹延宕等诡异妖变,愿乞言于评论区,吾辈当秉烛共研之。

诸君若觉此文击中痛处,或助尔等避开疆场之暗枪,切莫吝惜双指,赞、在看、转发三连走一波!生产一线之玄机,吾辈下期再行切磋。