Skip to main content

Command Palette

Search for a command to run...

我的解题之路: 开篇

Updated
1 min read

参加工作这么多年,碰到过挺多问题,也解决了许多问题,有的留在了记忆中,有的却很模糊。好记性不如一个烂笔头,如果将大脑记忆比作是WAL,那我现在写日志记录算是落盘喽。回归正题,之所以想写这个系列,是因为最近我通过看官方文档、翻开源项目 issues的方式,帮助同事解决了几个看似非常“棘手”的问题,我在前司也有几次类似的经历,这种感觉就很奇妙,至今我都没有彻底明白这些事情的内核是怎么样的,只能提笔记录下来,以作后观。

编译不过?

这是在前司时发生的事情。因为上游业务方使用了腾讯mars库做日志加密,我所在的团队作为下游需要将这些日志解密并保存,负责这个事情的同事H就去github上翻了源码,发现这个库是用C++写的,于是H参照官方文档以及这个issue打算将其编译成可执行文件来用,但是发现按照文档的描述,编译总是失败,于是找我帮忙。虽然上学的时候都学过C/C++,但并没有在工作中使用过,只能死马当活马医。我先从github上将源码clone下来(当然默认是master分支),然后根据H提供的文档进行编译,确实失败了:

❯ gcc decode_log_file.c micro-ecc-master/uECC.c -o decode_log_file -O0 -ggdb -lz
​
decode_log_file.c:26:10: fatal error: 'zstd/lib/zstd.h' file not found
#include "zstd/lib/zstd.h"
         ^~~~~~~~~~~~~~~~~
1 error generated.

这个错误看起来是挺简单的,记得当时我们也尝试了几种方案,均没有成功。于是我开始换思路了,前面提到的issue时间是Apr 25, 2019, 而我们使用的是master分支,距离那个issue最近一个tagv1.3.0(时间是Mar 8, 2019), 于是果断将代码切到v1.3.0, 果不其然,同样的命令,编译成功,而且也跑通了官网的给的示例。

这个不熟悉的问题最终能够得到解决,经验因素居多吧。因为在我的意识里面,一个开源项目的文档更新可能不会那么及时,但是功能要发版本,大概率是要打tag的。

数据迁移?

这是发生在贵司的事情。这个背景有点复杂:贵司跟某银行“联合”开发一套大数据平台(其实是贵司开发,后面用cm指代),这套平台的监控使用的是Prometheus(后面简称prom),prom部署在K8s的kube-system里面,prom数据存储挂PV(使用NFS),只存储最近30天的数据。这套cm部署在某银行的预发环境中,因为最近cm升级,prom的部署需要从kube-system迁移到另一个namespace(后面用xyz指代),但是呢,某银行要求这些监控数据不丢失,需要贵司提供数据迁移的技术方案支持。值得一提的是,因为不是生产环境,所以prom其实可以停服。这事最早是交到同事L手中的。L也就毕业三年,觉得这是运维的事情,于是要求运维提供支持,不巧的是运维出差,于是要求架构师提供支持……然后一周后运维回公司了,这事又流转到运维那里,运维的思路是通过prom提供的API接口,编写go代码将历史数据读取出来再存储到新的prom中去,然后发现prom的读写接口不好使,于是在晨会上提想把这事交出去,因为团队只有我是专职写go的,于是被接受了这个活……

这事的背景终于讲完了,个中曲折,还是稍等有点复杂的。毕竟曾经主导并设计过监控告警方案,此时的我,成竹在胸。先捋清几个事情

  1. prom只存储最近30天的数据;

  2. prom可以停服;

这两点挺关键的,因为prom是支持远程读的,也有联邦部署的架构设计,所以解决方案就呼之欲出了

  1. 保留kube-system中的旧prom实例,并停止scrape

  2. 在xyz中部署新prom实例,与1中旧的prom组成联邦集群

总结一下解题思路:客户要的是数据不丢,并没有说数据必须合为一处,采用联邦部署方式,30天之后旧的prom就可停服了,代价小,落地快,现场的同事操作起来也很方便,甚至基于我的思路提供了一份更详实的操作文档给到了客户方。

NFS不管用了?

这也是发生在贵司的事情。这次背景并不复杂,贵司跟某行谈合作,要去某行现场进行poc部署。贵司的大数据平台cm部署在K8s中,数据持久化依赖NFS,需要在K8s中安装nfs-subdir-external-provisioner。现场部署的运维同事发现部署不上,遇到以下问题:

unexpected error getting claim reference: selfLink was empty, can't make reference

然后我就被拉到了某个工作群,跟进这个问题。查了一下,原来

Kubernetes v1.20 (opens new window)开始,默认删除了 metadata.selfLink 字段,然而,部分应用仍然依赖于这个字段,例如 nfs-client-provisioner。如果仍然要继续使用这些应用,您将需要重新启用该字段。

不幸的是cm在测试的过程中一直使用的K8s均是1.20以下的,这次客户现场正好是1.20以上的K8s版本,仓促之下现场运维也找到解法,需要修改apiserver的启动参数:

- --feature-gates=RemoveSelfLink=false

但是某行的安全部门需要贵司给出:selfLink是干什么的,有什么风险?然的现场运维也给不出所以然来。

以下是我让AI(claude)帮忙总结的selfLink知识要点:

在 Kubernetes(K8s)中,selfLink 是一个对象的 URL 标识符。每个 Kubernetes 对象都会有一个 selfLink 属性,它指向该对象的唯一 URL。selfLink 的主要作用有:1. 定位对象通过 selfLink 可以唯一地定位到 Kubernetes 集群中的某个对象。可以通过 GET 请求来获取对象的详细信息。例如,对于一个 Pod 对象,其 selfLink 属性可能是:

/api/v1/namespaces/default/pods/my-pod

发送 GET 请求到这个 URL 就可以获取该 Pod 的完整信息。2. 跨命名空间引用对象某些 Kubernetes 对象需要引用其他对象,如果这两个对象在不同的命名空间,则需要使用 selfLink 来实现跨命名空间引用。例如,ServiceAccount 对象可以引用 Secret,如果 Secret 在另一个命名空间,则需要使用 Secret 的 selfLink 作为引用。3. 语言无关性selfLink 使用 URL 作为对象标识符,这使得它对编程语言无依赖。你可以在任何语言中使用 selfLink 来获取 Kubernetes 对象的相关信息。4. 稳定性对象的 selfLink 在对象创建后不会更改。这使得你可以安全地保存一个对象的 selfLink,以便将来引用该对象。即使对象的名称或命名空间发生变化,通过 selfLink 仍然可以访问到该对象。所以,总的来说,selfLink 为每个 Kubernetes 对象提供了一个唯一的 URL 标识符。通过 selfLink,你可以定位、引用和访问对象,而且这种访问方式稳定可靠且语言无关。这使得 selfLink 在 Kubernetes 对象管理与交互中发挥着重要的作用。

看完之后,其实我对selfLink从一无所知到有了一个具体的印象:它是URL的标识符。之所以被废弃掉,是因为它的创建和维护会影响性能。了解了这些之后,我觉得这不应该成为一个阻塞点,我笃定社区一定有其它更合理的解法,果然我在issue中翻到了

No more workarounds please :-) - this issue was closed for a reason guys! Just use new available docker image: gcr.io/k8s-staging-sig-storage/nfs-subdir-external-provisioner:v4.0.0 and it works fine. Do not edit kube-apiserver.yaml, there is no need to.

嗯,果然,这个方法被证实是可行的。于是我将此方法同步给现场运维,算是以较小代价解决了问题,但这次cm暴露出来的问题还是比较多的,先按下不表。

总结

上述几次解题,单独看起来真的毫无技术含量,它们当然不如高并发、大流量、分布式等问题高级,但它却真真实实地发生在工作中,组成了我们日常工作的部分。经验是挺重要的,但思路、方法、方式同样不可忽视,我能感觉到当年从后端开发转测开,以及云原生、DevOps、监控告警等经历,真的极大地开拓了我的个人技术视野,解放了我的思维局限性。当然,我也深知,经验是一把双刃剑,它也可能过时,我能做的,只有持续保持学习而已。

75 views

More from this blog

2025: 祛魅 灰度 念头通达

今天是2025年的最后一天,当大家都在准备下班的时候,好巧不巧的,我刚好发现了一个不大不小的问题,大胆猜想,小心求证,向上反馈,暴露风险,作为2025年工作注解,实在是再有趣不过了。 今年的工作,从结果上看,还算平稳,至于过程,有太多不可言说的部分。厂里打镙丝的牛马,有工资可拿,理应知足了,至于其它的,与己无关,也没那么重要了。 祛魅 近距离观察大厂,才发现一些违背常识/直觉的事实:路人以为的高大

Feb 28, 20261 min read21

大厂祛魅:破碎的专注力

毁掉一个人最直接的方法,就是毁掉ta的专注力。 这句话的出处已然模糊,但放在大厂环境中,却显得格外深刻。 围城 大厂宛如一座围城。城外的人满怀憧憬,目之所及皆是光鲜;城内的人却如困笼之鸟,翅膀日渐退化,每日挣扎求生。 高大上 不可否认,大厂的硬件设施确实令人艳羡:宽敞的独立园区内,来往穿梭的人群中,几乎人人手握智能设备。这看似现代化的景象背后,却藏着一个无奈的事实:在工作时段,每台电脑都被严密监控,连听音乐都成奢望。于是,工作之余玩手机,成了许多人难得的解压方式。 大厂的品牌效应确实强大。外界对...

Jul 29, 20251 min read138

Black Swan

黑天鹅理论 是指极不可能发生,实际上却又发生的事件 来到大厂打工已经满一个月了,从一开始的手足无措,到逐渐度过不适期,也算是适应了吧。 不适应 刚入职时,不适应的地方还是挺多的。 第一次只使用台式机工作,这就限制了我一天中的绝大部分时间,都必须呆在自己的工位上,好在工位足够大。只是人与人的沟通少了很多,有问题只能在工位上通过 IM 呼对方,有种魔幻又现实的感觉 第一次只能用 Windows,也不能 WSL,这给我的工作效率带来了很大影响,不能用熟悉的软件,就连写代码用的 VSCode 的...

Jan 24, 20251 min read74

2024年: 逐渐平静

这个世界是一面镜子,会把你的感受反射给你 2024 开端: 相由心生 那时,还带着一着愤懑,因为拿到了低绩效,虽然内心知道这是公司经营困难,想让我离开的一种策略,但仍然感受到自己那可笑的自尊受到了践踏。自那之后,非必要不加班,只做份内事,尽可能地不去涉及份外之事。 2024 年中: 与人为善 组里的项目眼见不行了,我被迫去支援 AI 项目,久违地写起了 python,项目接近完成时,意外收到通知:我拿到大礼包了。在这之前,架构师因故裸辞。在我离开之后不到两周,我的 TL 也裸辞了,直到同事告诉...

Jan 9, 20251 min read92

企业软件之殇

殇 动词 未成年而死。 名词 战死者。 笔者经历了两家打着云原生旗号的企业软件/解决方案公司,都是中途加入,项目都以解(失)散(败)告终。 云原生解决方案 NB 公司:一个传统的 IDC 小厂,想着借云原生的热度,进军企业软件市场。 在加入这个项目之前,笔者考取了 CKAD 认证,彼时对 K8s 相当着迷。先简要介绍一下这个项目背景: 基于 Rancher (换皮肤)的二次开发项目,名字叫:HCaaS ,在笔者加入这个团队之前,项目已经开发近两年了,除了 TL 之外,其它人之前都...

Jul 1, 20241 min read103

just for fun

57 posts

I'm a Software Engineer