嵌入式容器化:资源受限设备轻量级K8s实践
|
上季度那破事,记不清是哪天了,凌晨三点被监控叫起来——告警灯闪得跟迪厅似的,屏上并排开着三个终端,跳板机密码又过期了,输入三次才进去。负载飚到95%,磁盘inode全满,可机器上根本没跑新业务啊?我原以为又是哪个开发偷偷传了日志,结果翻半天发现是k8s的etcd把历史快照存爆了——对,就是那个号称‘轻量级’的k8s分支,在嵌入式设备上跑着跑着,把/var/lib给撑成了气球。 开发当时拍着胸脯说‘资源占用比原生k8s低60%’,结果呢?我蹲在机房里数了数,那台4核8G的边缘盒子,跑着3个pod就占满内存了——swap都开了,可swap一开,磁盘IO直接跪,日志写不进去,监控采集器自己先崩了。最绝的是,它那个‘精简版kubelet’居然没做僵尸进程回收,我查进程树的时候,发现有个容器挂了半个月,对应的pause进程还在吃CPU,像极了大学宿舍里那个占着茅坑不拉屎的室友。 可老板不管这些啊,他只看到友商的宣传页上写着‘嵌入式k8s落地案例’,就逼着我们上。我跟开发吵了三天,他们说‘这是行业趋势’,我说‘趋势个屁,你先把资源泄漏修了再说’。结果你猜怎么着?他们连夜改了代码,把kubelet的日志级别从debug调成error——对,不是解决泄漏,是让日志少写点,这样磁盘就不会爆。我当时盯着屏幕上的commit记录,差点把咖啡喷在键盘上。 不过话说回来,这玩意儿也不是完全没用。记得有次设备掉电重启,换以前得手动挨个拉起容器,现在至少能靠k8s的重启策略自己恢复——虽然偶尔会抽风,比如把A容器重启了三次,B容器根本没管。但跟以前比,确实省了点半夜爬起来拔电源的时间。我原以为这种‘轻量级’方案就是个玩具,结果发现,在那些连docker都跑不动的老设备上,它居然真能凑合用——就像用诺基亚功能机刷微信,虽然卡,但至少能发消息。 那天在机房改配置的时候,旁边开发小哥在吃泡面,外卖袋子上的水汽弄湿了桌角,我盯着湿痕看了半天,突然想起个事:这k8s的‘轻量’,是不是就轻在砍了监控和告警?上次设备宕机,集群里根本没报异常,还是用户打电话来说‘摄像头黑了’,我们才查出来是kube-proxy挂了。后来我偷偷给那台机器装了老版的cAdvisor,结果被开发发现后给删了——他们说‘资源不够,得优先保证业务’。 最搞笑的是证书问题。那套‘轻量级’方案为了省资源,把证书轮换周期从90天改成了365天,结果有台设备的时间没同步,证书过期了,整个集群的pod都连不上API server。我们翻日志的时候,发现kubelet一直在报‘x509: certificate has expired’,可开发坚持说‘时间同步是运维的事,我们只管k8s’。那天我蹲在机房角落里改NTP配置,听着冷风机嗡嗡响,突然觉得,这所谓的‘嵌入式容器化’,是不是就是把大厂的坑,原封不动搬到了资源更少的设备上? 但话说回来,有些场景还真得靠它。比如上个月有个客户,非要在256M内存的网关上跑容器,换以前得手动改cgroup,现在至少能用k8s的ResourceQuota限制资源——虽然偶尔会超限,但至少比裸跑强。我测过几次,在内存紧张的时候,它的OOM Killer确实比原生的更激进,会优先杀掉低优先级的pod——虽然偶尔会误杀,但总比整个机器卡死好。就像用菜刀削苹果,虽然容易切到手,但至少比用石头砸快。 现在我们的策略是:新设备用原生k8s,老设备用‘轻量版’,但必须配额外的监控——开发不同意,说‘这样就不轻量了’,我说‘不监控,你连问题出在哪都不知道’。最后折中方案是,用prometheus的node exporter,但只采集最关键的指标——结果发现,连cpu_usage这种基础指标,在某些设备上都会漏采,因为inode又爆了。 那天凌晨处理完问题,我靠在椅子上发呆,轮子卡着一根网线,硌得腰疼。突然想到,这‘轻量级k8s’的生存逻辑,是不是跟自然界一样?优胜劣汰——在资源够的环境里,它被原生k8s吊打;可在那些连docker都跑不动的设备上,它反而成了唯一选择。就像沙漠里的仙人掌,长得丑,但能活。而我们这群测试,就像沙漠里的探险队,一边骂它扎手,一边还得靠它续命。
文章配图,仅供参考 现在我最怕的是,哪天开发突然说‘我们发现了个更轻量的方案’,然后又要重新测一遍。不过至少目前,这套东西还能用——虽然偶尔会抽风,但至少比以前手动管理强。下次再遇到资源泄漏,我打算直接写个脚本,定期杀掉那些吃CPU的pause进程——开发不肯修,我们只能自己动手,就像以前给安卓手机刷第三方ROM一样。(编辑:站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |


逻辑清晰代码让嵌入式调试时间锐减70%
5G模组功耗优化:嵌入式工程师的移动互联新规则