标签 Kubernetes 下的文章

Kubernetes 2.0 畅想:告别 YAML、etcd 束缚与 Helm 之痛,K8s 的下一站是什么?

本文永久链接 – https://tonybai.com/2025/06/21/kubernetes-2-0

大家好,我是Tony Bai。

自 2014 年首次提交以来,Kubernetes 已走过辉煌的十年。它从一个“没人能念对名字”的希腊词汇,成长为容器编排领域无可争议的事实标准,深刻地改变了我们构建、部署和管理应用的方式。我们不再满足于在服务器层面“管理基础设施”,一切都变得声明式、可扩展、可恢复,甚至(如果你足够幸运的话)能够自我修复。

然而,正如任何伟大的技术旅程一样,Kubernetes 的发展也并非一帆风顺。尽管它带来了巨大的生产力提升,但其陡峭的学习曲线、某些领域“不够固执己见 (not opinionated enough)”导致的常见错误和配置失误、以及生态系统中持续的“变动”,仍然让许多开发者和运维者“痛并快乐着”。我们依然会踩到那些文档早已记录的“地雷”。

站在十年的重要节点,回望过去,展望未来,一个有趣的问题自然而然地浮现:如果我们有机会基于今天的认知和经验,重新构想一个 Kubernetes 2.0,它会是什么样子?我们能做哪些改变,让这个伟大的工具更普惠、更强大、更易用?

最近,一篇题为《What Would a Kubernetes 2.0 Look Like》的博文,就针对这个问题提出了一系列大胆而深刻的畅想,直指当前 K8s 生态中的核心痛点。今天,我们就来一起探讨这些引人深思的观点。

注:本文观点主要源自上述博文,并结合我个人的一些思考,希望能为大家带来启发。

Kubernetes 的十年功与过:为何我们需要畅想“2.0”?

在畅想未来之前,我们必须承认 Kubernetes 取得的巨大成功。它之所以能成为云原生时代的基石,离不开其核心价值:

  • 大规模容器化: 将容器从本地开发环境无缝推向数千台服务器的生产集群,赋予了组织前所未有的灵活性,催生了微服务架构的繁荣。
  • 低维护性: 推动了基础设施从“宠物 (Pets)”到“牛群 (Cattle)”再到“UUID时代”的演进。服务器变得完全可替代,运维模式从手动修复转向“销毁节点,让K8s重组”。
  • 改进的作业系统: 提供了比传统“孤岛式 cron01 服务器”更可靠、更灵活的批处理作业和消息队列任务执行方案。
  • 简化的服务发现与负载均衡: 通过 Service API 提供了稳定的内部 DNS 和 IP,极大地简化了服务间的调用和依赖管理。

然而,正如文章作者所言,“旅程并非没有问题”。“默认值是技术中最强大的力量 (defaults are the most powerful force in technology)”,而 Kubernetes 在某些方面的“默认”或“缺失”,恰恰是许多痛点的根源。 这正是我们畅想“K8s 2.0”的出发点——通过设定更优的“快乐路径 (happy path)”,提升整个生态的健康度和用户体验。

畅想一:抛弃 YAML,拥抱 HCL——配置语言的救赎?

“YAML 之所以吸引人,是因为它既不是 JSON 也不是 XML,这就像说你的新车很棒,因为它既不是马也不是独轮车一样。” 文章作者对 YAML 的这句犀利点评,道出了许多 K8s 用户的心声。

YAML最初凭借其看似简洁的格式在 Kubernetes 中胜出,但其在实践中暴露的问题也日益突出:

  • 模糊性与易错性: 缩进敏感、类型不明确(著名的“挪威问题”——NO 被解析为布尔值 false)、缺乏引用的数字可能被误解等。
  • 难以扩展和调试: 超长的 YAML 文件令人望而生畏,调试错误往往如同大海捞针。
  • 表达能力不足: 缺乏内置的变量、函数、条件逻辑等,导致大量依赖外部模板工具(如 Helm templates, Kustomize)。

文章大胆提议,Kubernetes 2.0 应该用 HCL (HashiCorp Configuration Language) 替换 YAML。 HCL 作为 Terraform 的配置语言,早已被广大云原生开发者所熟悉。其核心优势在于:

  • 强类型与显式类型: 从源头上避免了 YAML 的许多类型相关错误。
  • 内置变量、引用、函数和表达式: 能够动态生成配置,减少重复,提高可维护性。
  • 条件逻辑与循环: 支持更灵活的环境特定配置和重复性配置的简化。
  • 更好的注释、错误处理和模块化能力。

作者通过对比简单的 YAML 和 HCL 示例,直观地展示了 HCL 在类型安全和动态配置生成方面的优越性:

# YAML doesn't enforce types
replicas: "3"  # String instead of integer
resources:
  limits:
    memory: 512  # Missing unit suffix
  requests:
    cpu: 0.5m    # Typo in CPU unit (should be 500m)

vs.

# HCL 

replicas = 3  # Explicitly an integer

resources {
  limits {
    memory = "512Mi"  # String for memory values
  }
  requests {
    cpu = 0.5  # Number for CPU values
  }
}

尽管 HCL 可能略显冗长,且其 MPL-2.0 许可证与 K8s 的 Apache 2.0 许可证的整合需要法律审查,但作者认为,为了大幅改善配置体验,这些障碍值得克服。

畅想二:开放后端存储,etcd 不再是唯一选择——灵活性的追求

etcd 作为 Kubernetes 集群状态的权威存储,一直以来都扮演着至关重要的角色。然而,文章指出,etcd 作为唯一的默认后端存储,也带来了一些局限:

  • 资源消耗: 对于小型集群或资源受限的边缘环境,etcd 可能显得过于“庞大”和资源密集。
  • “强绑定”关系: Kubernetes 几乎是 etcd 现存唯一的“大客户”,这种高度绑定可能不利于双方的独立发展和技术选择的灵活性。

因此,文章建议 Kubernetes 2.0 应该官方化 kine (k3s-io/kine) 等项目的工作,提供可插拔的后端存储抽象层。 这将允许:

  • 根据硬件和集群规模选择更合适的后端: 例如,对于小型或边缘集群,可以使用像 dqlite (基于 Raft 的分布式 SQLite) 这样的轻量级方案,它们资源占用小,升级维护可能更简单。
  • 促进存储技术的创新与竞争: 开放后端接口,可以鼓励更多针对 K8s 优化的存储方案涌现。
  • 降低对单一项目的依赖。

此外,Go 语言在构建分布式一致性存储方面拥有优秀的库(如 hashicorp/raft,etcd 本身也是 Go 编写的)。这些技术积累能否为 Kubernetes 构建更灵活、更高效的可插拔存储后端提供更多思路?

畅想三:超越 Helm,构建原生包管理器——生态治理的进化

Helm 作为 Kubernetes 事实上的包管理器,为社区贡献了标准化的应用分发和管理方式。文章作者首先感谢了 Helm 维护者的辛勤工作。但紧接着,便毫不留情地指出了 Helm 在实践中的诸多“噩梦”:

  • Go模板的复杂性与调试困难: 复杂的模板逻辑、令人困惑的错误场景、以及难以理解的错误信息。
  • 依赖管理能力的孱弱: 难以优雅地处理传递性依赖和版本冲突,尤其在多个应用依赖同一子 Chart 的不同版本时。
  • 其他痛点: 跨命名空间安装不便、Chart 验证过程繁琐且少有人用(作者甚至吐槽了 Artifact Hub 上官方 Chart 的验证状态)、元数据搜索能力弱、不严格执行语义化版本控制、以及卸载/重装包含 CRD 的 Chart 可能导致用户数据丢失的严重安全隐患。

作者断言:“没有办法让 Helm 足够好地完成‘管理地球上所有关键基础设施的包管理器’这项任务。”

因此,文章畅想了一个名为 KubePkg 的 Kubernetes 原生包管理系统,其核心设计理念借鉴了成熟的 Linux 包管理系统,并充分利用了 Kubernetes CRD 的能力:

  • 一切皆为 Kubernetes 资源: 包定义、仓库、安装实例等都通过 CRD 管理,拥有标准的 status 和 events。
  • 一流的状态管理: 内置对有状态应用备份、恢复、升级策略的支持。
  • 增强的安全性: 强制的包签名、验证机制和安全扫描集成。
  • 声明式配置,告别模板: 使用结构化的配置(可能基于 HCL 或类似带有 Schema 的语言),而非难以调试的文本模板。
  • 完善的生命周期管理: 提供全面的 pre/post-install/upgrade/remove 钩子。
  • 强大的依赖解析: 类似 Linux 包管理器的、基于语义化版本的依赖管理和冲突解决能力。
  • 完整的审计追踪: 记录所有变更的“who, what, when”。
  • 策略执行与简化的用户体验。

加分项:默认拥抱 IPv6——未雨绸缪的网络升级

除了上述三大核心变革,文章还提出了一个颇具前瞻性的建议:Kubernetes 2.0 应将默认网络模式切换到 IPv6。

其理由在于,IPv4 带来的 NAT 穿透复杂性、IP 地址耗尽焦虑(即使在私有网络中,大规模集群也可能迅速耗尽 /20 这样的网段)等问题,已经浪费了全球开发者和运维者大量的时间和精力。

在 K8s 内部默认使用 IPv6,可以:

  • 极大简化集群内部网络拓扑。
  • 在组织层面,如果使用公网 IPv6 地址,可以更容易地忽略多集群之间的界限。
  • 提升网络流量的可理解性。
  • 更好地利用 IPv6 内置的 IPSec 等安全特性。

作者强调,这并非要求整个互联网立即切换到 IPv6,而是 Kubernetes 自身可以主动进化,以解决其在当前规模下面临的 IP 地址管理和网络复杂性问题。

小结:“默认即王道”,Kubernetes 的未来在于更优体验

“Kubernetes is an open platform, so the community can build these solutions.” (K8s 是一个开放平台,所以社区可以构建这些解决方案。)这是对类似“2.0”畅想的常见反驳。但文章作者一针见血地指出,这种说法忽略了一个关键点:“默认值是技术中最强大的力量。” 核心项目定义的“快乐路径”将主导 90% 用户的交互方式。

如果 Kubernetes 2.0 能够在配置语言、后端存储、包管理乃至网络模型这些核心体验上,提供更简洁、更安全、更强大、更易用的“默认选项”,那么整个生态系统都将因此受益。

这无疑是一份雄心勃勃的畅想清单。但正如作者所言:“如果我们打算做梦,那就做个大梦。毕竟,我们是那个认为将一项技术命名为‘Kubernetes’也能流行起来的行业,而且不知何故它确实做到了!”

Kubernetes 的第一个十年,奠定了其在云原生领域的王者地位。下一个十年,它需要在保持核心优势的同时,勇于直面和解决用户在实践中遇到的真实痛点,不断进化,提供更极致的用户体验。这些“2.0”的畅想,无论最终能否完全实现,都为我们指明了值得努力的方向。

参考文章地址:https://matduggan.com/what-would-a-kubernetes-2-0-look-like


聊一聊,也帮个忙:

  • 对于文中提出的 Kubernetes 2.0 的三大核心变革(HCL替换YAML、可插拔etcd、原生包管理器KubePkg),你最期待哪一个?为什么?
  • 你认为当前使用 Kubernetes 最大的痛点是什么?这些“2.0畅想”是否触及了你的痛点?
  • 关于默认使用 IPv6,你认为在实际推行中会遇到哪些挑战?

欢迎在评论区留下你的真知灼见。如果你觉得这篇文章引发了你的思考,也请转发给你身边的云原生同道们,一起畅想 Kubernetes 的未来!


精进有道,更上层楼

极客时间《Go语言进阶课》上架刚好一个月,受到了各位读者的热烈欢迎和反馈。在这里感谢大家的支持。目前我们已经完成了课程模块一『语法强化篇』的 13 讲,为你系统突破 Go 语言的语法认知瓶颈,打下坚实基础。

现在,我们已经进入模块二『设计先行篇』,这不仅包括 API 设计,更涵盖了项目布局、包设计、并发设计、接口设计、错误处理设计等构建高质量 Go 代码的关键要素。

这门进阶课程,是我多年 Go 实战经验和深度思考的结晶,旨在帮助你突破瓶颈,从“会用 Go”迈向“精通 Go”,真正驾驭 Go 语言,编写出更优雅、更高效、更可靠的生产级代码!

扫描下方二维码,立即开启你的 Go 语言进阶之旅!


如果你对Go语言的底层原理和高级技巧充满好奇,渴望构建更坚实的技术壁垒,我诚挚地邀请您关注我的微专栏系列。在这里,我们拒绝浮光掠影,只做深度挖掘:



商务合作方式:撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。如有需求,请扫描下方公众号二维码,与我私信联系。

当一切皆可用Python:Go这样的通用语言与DSL的未来价值何在?

本文永久链接 – https://tonybai.com/2025/06/19/language-design-in-the-era-of-llm

大家好,我是Tony Bai。

大型语言模型 (LLM) 的浪潮正以前所未有的速度和深度席卷软件开发领域。从代码生成、Bug 修复到文档撰写,AI 似乎正成为每一位开发者身边无所不能的“副驾驶”。在这股浪潮中,一个略显“刺耳”但又无法回避的论调开始浮现,正如一篇引人深思的博文《Programming Language Design in the Era of LLMs: A Return to Mediocrity?》中所指出的那样:“一切都更容易用 Python 实现 (Everything is Easier in Python)”——当然,这里指的是在 LLM 的强力辅助下。

这并非危言耸听。文章中展示的图表(来源于论文 “Knowledge Transfer from High-Resource to Low-Resource Programming Languages for Code LLMs“)清晰地揭示了一个趋势:LLM 在那些训练数据量巨大的“高资源”语言(如 Python, JavaScript, Java, C# 等)上,代码生成和任务解决的效能显著高于像 Go、Rust 这样的“低资源”语言:

如果 LLM 能够如此轻松地用 Python(或其他高资源语言)根据自然语言需求生成大部分“胶水代码”甚至核心逻辑,那么我们不禁要问:

  • 精心设计和构建领域特定语言 (DSL) 的价值还剩下多少?当消除冗余、封装领域知识这些 DSL 的核心优势,似乎可以被 LLM+通用语言轻易取代时,DSL 的未来是否会因此停滞?
  • 对于像 Go 这样以简洁、高效、工程化著称的通用语言,当其在 LLM 训练数据中的“声量”不及 Python 时,它的核心竞争力又将面临怎样的挑战与机遇?

今天,我们就来聊聊在 LLM 时代,DSL 和像 Go 这样的通用语言,其未来的价值究竟何在。

DSL 的黄昏?当 LLM 成为“万能代码生成器”

领域特定语言 (DSL) 的核心价值在于“专为特定领域而生”。通过精心设计的语法和语义,DSL 能够:

  • 提升表达力: 让领域专家或开发者能用更接近自然语言或领域术语的方式描述问题。
  • 消除样板代码: 将领域内的通用模式和“常识性规则”编码到语言自身。
  • 降低认知负荷: 开发者可以更专注于问题的“有趣”部分,而非底层实现细节。
  • 减少错误面: 通过语言层面的约束,使得编写出不正确的程序变得更加困难。

文章中那个视频游戏对话的例子就非常典型:从繁琐的 API 调用序列

# example code for a VN
character.draw("alice", character.LEFT, 0.1)
character.draw("bob", character.RIGHT, 0.1)
character.say("alice", "hello there!")
character.say("bob", "hi!")
character.state("alice", "sad")
character.say("alice", "did you hear the news?")

到简洁的 DSL 描述

# example DSL for dialog
[ alice @ left in 0.1, bob @right in 0.1  ]
alice: hello there!
bob: hi!
alice[sad]: did you hear the news?...

DSL 的优势一目了然。

然而,LLM 的出现,似乎正在侵蚀 DSL 的这些传统护城河。当开发者可以用自然语言向 Copilot 或 ChatGPT 描述“我想要一个能让 Alice 和 Bob 在屏幕两侧对话的场景”,并且 LLM 能够直接生成 Python 或 JavaScript 代码来实现这个功能时,我们不禁要问:为什么还要费心去学习、设计、构建和推广一个全新的 DSL 呢?

这里隐含的“机会成本”的问题非常现实:

  • DSL 的学习与生态位:使用一个“小众”的 DSL,意味着开发者可能要放弃使用 LLM 在主流语言上生成代码的巨大便利。LLM 在小众 DSL 上的表现(如果未经专门微调)几乎可以预见会非常糟糕。
  • DSL 的构建成本:设计和实现一个高质量的 DSL 本身就需要巨大的投入。在 LLM 时代,这个投入的“性价比”似乎正在下降。

这引发了一个令人担忧的趋势:DSL 的发展是否会因此停滞不前?语言设计的多样性是否会因此受到冲击,最终导致“人人皆写 Python (在 LLM 辅助下)”的局面?

Go 语言:在 LLM 时代的“低资源”挑战与独特优势

Go语言虽然在全球拥有数百万开发者,并且在云原生、后端开发等领域占据主导地位,但在 LLM 的训练数据占比上,相较于 Python、JavaScript 等拥有更长历史和更广泛应用场景(尤其是 Web 前端、数据科学等产生大量开源代码的领域)的语言,仍然处于“低资源”状态。

这意味着,LLM 在直接生成高质量、复杂 Go 代码方面的能力,目前可能还无法与它在 Python 等语言上的表现相媲美。 这对 Go 社区和开发者来说,既是挑战,也是反思和寻求新机遇的契机。

挑战:

  • 如果 LLM 生成 Go 代码的效率和质量暂时落后,可能会降低新手或寻求快速原型验证的开发者选择 Go 的意愿。
  • Go 社区可能需要投入更多精力来构建 LLM 友好的工具、库和高质量的训练数据。

然而,Go 语言的独特优势在 LLM 时代或许会更加凸显:

  • 简洁性与明确性对 LLM 的“友好”:
    • Go 语言语法精炼,关键字少,没有复杂的继承和隐式转换。这种“所见即所得”的特性,可能使得 LLM 更容易理解 Go 代码的结构和语义。
    • Go 的强类型系统和明确的错误处理机制 (if err != nil),虽然在手动编码时有时显得冗余,但在 LLM 生成或分析代码时,这些明确的信号可能有助于 LLM 生成更健壮、更易于验证的代码。
  • 强大的标准库与工程化特性:
    • Go 丰富的标准库覆盖了网络、并发、编解码等常见场景。LLM 在生成 Go 代码时,可以更多地依赖这些经过充分测试和优化的标准组件,减少对第三方库的复杂依赖。
    • Go 内置的测试、性能分析、代码格式化等工具,以及其对模块化的良好支持,有助于对 LLM 生成的代码进行有效的质量控制和集成。
  • 并发模型与性能优势的不可替代性:
    • Go 的 Goroutine 和 Channel 提供的轻量级并发模型,在构建高并发网络服务和分布式系统方面具有独特优势。这部分逻辑的复杂性和对性能的极致要求,可能难以完全由 LLM 在 Python 等语言中通过简单生成来完美复制。
    • Go 编译后的静态二进制文件和高效的执行性能,在许多后端和基础设施场景中依然是硬核需求。
  • Go 作为“基础设施”语言的潜力:
    • LLM 本身就需要强大的基础设施来训练和运行。Go 在构建这些大规模、高并发的 AI 基础设施方面,已经扮演了重要角色(如 Ollama 等项目)。
    • Go 的简洁性和安全性,也使其成为定义和执行 AI Agent 行为、编排复杂 AI 工作流的理想语言。

LLM 时代,语言设计(DSL 与通用语言)的破局之路

面对大型语言模型(LLM)带来的挑战,编程语言的设计(无论是领域特定语言(DSL)还是通用语言如 Go)并非只能被动应对。学术界正在探索一些富有前景的新方向,旨在实现语言设计与 LLM 的协同进化,而非零和博弈。

首先,有研究提出教会 LLM 理解 DSL 的方法,核心思路是利用 LLM 擅长的语言(如 Python 的受限子集)来表达核心逻辑。由于 LLM 对特定 DSL 的理解和生成能力有限,开发者可以设计工具或方法,将这些 Python 表达式“提升”或自动翻译到目标 DSL 中。这一思路启示未来的 DSL 设计者应考虑为其语言提供一个 LLM 友好的“语义映射层”,例如用 Python 或其他高资源语言来描述其核心概念和操作。

其次,在 DSL 中弥合“形式化”与“非形式化”的鸿沟也是一个重要方向。开发者在编写复杂系统内核时,往往需要精确控制每一行代码,此时 LLM 的帮助有限。然而,在编写不常用的“一次性”脚本时,LLM 能够根据自然语言描述生成“胶水代码”,使得开发者只需关注核心的“有趣”部分。因此,未来的 DSL 设计可以探索如何无缝集成“非形式化”自然语言描述,作为规范、注释,甚至直接融入代码中。与此同时,是否可以从 DSL 的类型系统或静态分析结果中,自动生成高质量的自然语言规范,反过来帮助 LLM 更好地理解和生成 DSL 代码,值得深入研究。

最后,面向 LLM 辅助验证的语言设计也成为一种趋势。研究者们不再满足于 LLM 生成“能运行”的代码,而是期望 LLM 能生成带有形式化规约(specifications)的代码,并利用验证语言(如 Dafny、Boogie)来证明这些代码的正确性。这一趋势对 DSL 和通用语言(如 Go)的设计提出了新要求,开发者需要考虑如何更好地支持“规约即代码”和“验证即开发”的模式。例如,Go 语言的强类型和接口设计,为形式化验证提供了一定的基础,未来的改进可以在此基础上进一步发展。

通过以上几个方向的探索,编程语言设计有望与 LLM 实现更为紧密的协同进化,推动软件开发的进步和创新。

小结:挑战之下,价值重塑

LLM 的崛起,无疑对整个编程语言生态带来了深刻的冲击和前所未有的挑战。那种“学会一门语言,用好一个框架,就能高枕无忧”的时代可能正在远去。

“一切皆可用 Python (在 LLM 辅助下)”的论调,虽然略显夸张,但也点出了一个事实:对于那些仅仅是为了减少样板代码、提供简单抽象的 DSL,或者在表达力和生态丰富度上不及 Python 的通用语言,其生存空间确实受到了挤压。

然而,这并不意味着语言设计本身会走向“平庸化”或消亡。相反,LLM 可能会迫使我们重新思考编程语言的核心价值:

  • 对于 DSL,未来可能需要更高的“门槛”——它们必须提供真正深刻的领域洞察和远超通用语言的表达效率与安全性,才能证明其存在的必要性。同时,与 LLM 的协同将是关键。
  • 对于像 Go 这样的通用语言,其价值将更多地体现在那些难以被 LLM 轻易复制的领域:极致的工程效率、经过实战检验的并发模型、强大的底层控制能力、以及构建大规模、高可靠系统的综合实力。Go 需要继续打磨其核心优势,并积极拥抱 AI,成为 AI 时代不可或缺的基石。

最终,技术的浪潮会淘汰掉不适应变化的,也会催生出新的、更强大的生命体。对于我们开发者而言,保持学习的热情,理解不同工具的本质和边界,拥抱变化,或许才是应对这个“AI 定义一切”时代的不二法门。

你认为 LLM 会如何改变你使用的编程语言?Go 和 DSL 的未来将走向何方?欢迎在评论区留下你的真知灼见!


精进有道,更上层楼

极客时间《Go语言进阶课》上架刚好一个月,受到了各位读者的热烈欢迎和反馈。在这里感谢大家的支持。目前我们已经完成了课程模块一『语法强化篇』的 13 讲,为你系统突破 Go 语言的语法认知瓶颈,打下坚实基础。

现在,我们即将进入模块二『设计先行篇』,这不仅包括 API 设计,更涵盖了项目布局、包设计、并发设计、接口设计、错误处理设计等构建高质量 Go 代码的关键要素。

这门进阶课程,是我多年 Go 实战经验和深度思考的结晶,旨在帮助你突破瓶颈,从“会用 Go”迈向“精通 Go”,真正驾驭 Go 语言,编写出更优雅、
更高效、更可靠的生产级代码!

扫描下方二维码,立即开启你的 Go 语言进阶之旅!

感谢阅读!

如果这篇文章让你对AI时代的DSL和通用语言设计和未来有了新的认识,请帮忙转发,让更多朋友一起学习和进步!


商务合作方式:撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。如有需求,请扫描下方公众号二维码,与我私信联系。

如发现本站页面被黑,比如:挂载广告、挖矿等恶意代码,请朋友们及时联系我。十分感谢! Go语言第一课 Go语言进阶课 Go语言精进之路1 Go语言精进之路2 Go语言第一课 Go语言编程指南
商务合作请联系bigwhite.cn AT aliyun.com

欢迎使用邮件订阅我的博客

输入邮箱订阅本站,只要有新文章发布,就会第一时间发送邮件通知你哦!

这里是 Tony Bai的个人Blog,欢迎访问、订阅和留言! 订阅Feed请点击上面图片

如果您觉得这里的文章对您有帮助,请扫描上方二维码进行捐赠 ,加油后的Tony Bai将会为您呈现更多精彩的文章,谢谢!

如果您希望通过微信捐赠,请用微信客户端扫描下方赞赏码:

如果您希望通过比特币或以太币捐赠,可以扫描下方二维码:

比特币:

以太币:

如果您喜欢通过微信浏览本站内容,可以扫描下方二维码,订阅本站官方微信订阅号“iamtonybai”;点击二维码,可直达本人官方微博主页^_^:
本站Powered by Digital Ocean VPS。
选择Digital Ocean VPS主机,即可获得10美元现金充值,可 免费使用两个月哟! 著名主机提供商Linode 10$优惠码:linode10,在 这里注册即可免费获 得。阿里云推荐码: 1WFZ0V立享9折!


View Tony Bai's profile on LinkedIn
DigitalOcean Referral Badge

文章

评论

  • 正在加载...

分类

标签

归档



View My Stats