Skip to main content

Command Palette

Search for a command to run...

酒话:Copilot 和运维代码

Updated
2 min read

这个话题是前些天和一位同学在饭桌上喝着啤酒闲聊产生的内容,叙事极其杂乱,错过本文不会有任何损失。

背景

前些天跟同事讲,Learnk8s 的 A visual guide on troubleshooting Kubernetes deployments 是个很明显可以转换成工具运用到实际运维工作当中的东西,一套组合拳下来,基本问题搞清楚,是个挺方便的事儿,要不我周末把它搓出来给你看看。听者无意说者有心,我试了试,还真是个挺无聊的事情,设计各种场景,根据条件,捕获各种 K8s 输出,最终汇总成报表。不小心发散了一下,前一阵得到试用资格的 Github copilot 好像就很适合这种工作,周末趁娃补觉,用 Copilot + PyCharm 就真的实现了个差不多。

Copilot

首先介绍下 Copilot,这东西是使用 AI 技术凭借 Github 上的海量代码,用编辑器/ide 插件的形式提供辅助编程能力的一个产品,和 Tab Nine 这样的“传统”插件最大区别是,可以用“面向注释开发”的方式来使用 Copilot,例如输入 # Import Kubernetes 的注释,他就会推荐出 from kubernetes import client, config 这样的语句,按 Tab 接受之后,因为还没有在 venv 中安装相应的库,PyCharm 会做出提示,安装包即可。

整段脚本大概一百行,其中有一半是注释除了前面简单的 Import 之外,比较复杂的遍历、判断,还有使用 API 时候最头秃的对象结构的拆解,都是 Copilot 完成的,例如:

# Import kubernetes
from kubernetes import client, config
# Connect to kubernetes
config.load_kube_config()
# List all pods
v1 = client.CoreV1Api()
print("Listing pods with their IPs:")
ret = v1.list_pod_for_all_namespaces(watch=False)
for i in ret.items:
    print("%s\t%s\t%s" % (i.status.pod_ip, i.metadata.namespace, i.metadata.name))

这其中只有三行注释是手工输入的,对列表的遍历和 print 语句都是自动生成的,非常类似我们在试探阶段编写代码的方法。Copilot 的自动推荐方面还会根据本地代码有所变更,例如:

# define a list to store event messages
pending_event_list = []
...
# save namespace, pod name and message in to an object
pending_event_list.append({'namespace': event.involved_object.namespace, 'pod': event.involved_object.name,
        'message': event.message})
...
# if length of event_list is greater than 0, then print items into a table
if len(pending_event_list) > 0:
    print('Pending Pods:\n')
    print('{:<20}{:<30}{:<20}'.format('Namespace', 'Pod', 'Message'))
    print('{:<20}{:<30}{:<20}'.format('---------', '----', '-------'))
    for item in pending_event_list:
        print('{:<20}{:<30}{:<20}'.format(item['namespace'], item['pod'], item['message']))
    print('\n')

在定义了这个列表之后,仅凭一行注释,她就机智地把这三个字段形成的对象直接塞进了前面定义的列表之中(中间的 Pending Pods:\n 是我的手工输入),后面更是直接输出了表头和间隔线。更有意思的是,Pod 名称一栏的宽度原本是设置为 20 的,我手工改成了 30,后续输出第二个表格时,他就自动将 Pod 字段的宽度修改成了 30。

情况当然不总是一帆风顺的,例如我在输入 # get all events for pod 时,它就推荐了一行错误代码,调用了不存在的成员函数,使用 PyCharm 的自动完成纠正一下也就可以了;在判断容器重启次数时,他也会直接给出 pod.status.container_statuses[0].restart_count > 5 这样的粗暴判断。

总之两个小时下来,我主要的工作就在于几个点:

  1. 设计故障场景
  2. 琢磨英文注释
  3. 纠正错误代码
  4. 运行、调试、更正再运行

用我弱弱的英文输出能力,不停调试注释,让 Copilot 输出合适的代码,并进行微调,最终完成功能。

运维怎么开始写代码

那这么个破事怎么就联系到运维代码上了呢?其实像这种无聊尝试意义是不大的,但是运维代码的开发特点非常适合使用这个东西进行辅助

  1. 需求描述非常技术化,容易转换为 Copilot 的注释输入
  2. 具体相关内容在网络上会有非常多的代码碎片,适合被 Copilot 抓取提炼和使用
  3. 甚至连注释都会有很多自动完成的机会
  4. 场景相对固定,代码量一般不大,方便进行调试

很多运维同学都在面临类似的焦虑——觉得自己手上的工作价值不大,编程基础不太好,又希望能像《Google SRE 解密》中提到的,从手工、脚本、软件直到 Borg 的过程中飞速进化。但是机会不总是存在的,将日常经验有效地变成代码从而得以积累和传播,对组织和个人都是非常具备实际意义的。在个人长期的运维相关工作过程中的经验来看,不管是哪个阶段,不管这个工作应该算是运维、DevOps、SRE 还是别的什么,现场工作一方面是工具的工作场景,另一方面也是工具的需求源头,同时也是工具实现方法的重要参考。

那么如何在现场开始写代码呢?我总结了一个 3X2 原则:如果在你的手工操作中,遇到如下场景:连续三个命令的序列,重复执行了第二次,那么就建议你将它写成一个 Shell 脚本——通常来说,会执行第二次,就会有第三次第四次,随着不断地使用,身兼作者和用户,会有各种非常具体的需求会加入到这个简陋的脚本之中,诱导你在其中逐步加入原本不太熟悉的判断、循环、管道、启动参数等的处理能力——毕竟每次只加一点点,例如我自己的经验:

  • 起初是为了节约公有云测试开支,根据 gcloud 命令行文档,写了在 GKE 上一次性创建和删除 Kubernetes 集群的两个脚本
  • 后来发现,删除集群时,相应的挂载卷也需要进行遍历删除
  • 为了测试一些兼容性问题,需要创建集群时选择不同的 Kubernetes 版本
  • 我拿到了一个每月 300 美金的 Azure 测试账号,我需要将脚本改造成可以选择 Azure 还是 Google Cloud 的版本
  • ..

这一组脚本已经伴随我走了四五年,经过多年的“随手”改造的积累,已经成为几百行的小怪兽,能够在 GCP、AWS、Azure 创建各种不同规格、不同版本的 Kubernetes 集群,完成工作后能不留后患(账单)的进行彻底清理,帮助我完成了很多的测试,输出了很多的云原生相关的记录内容。

在团队中应该把小工具们组织起来,这里非常要提醒大家的一点就是,在文档中保存的代码段,相当于让代码脱离了生存环境,是很容易死掉的,所以具有相同或相似工作内容的组织内,用版本管理的方式将这些小工具们进行归拢。同行之间互相 Review,取长补短、协同进步会让代码段逐步变得成熟和广普。一致的工具集,紧贴现场需求,有助于形成“一个萝卜一个坑”的一致的问题应对方式,代码本身就成为团队的知识积累和沉淀,新兵加入后,可能就不那么需要从 Linux/Docker/Kubernetes 开始了——对于初出茅庐的新手来说,哪怕是一键提取日志,也是快速进入战场的有效途径。

小工具们成长壮大之后,就进入了抽象和复用的阶段了,这一方面,Kubernetes 生态中充满了绝佳范例:重度依赖调度能力、避免直接和节点/服务器之类的具体环境发生联系、专心解决自己的问题、对外提供稳定的声明式接口(声明式接口同时还意味着可重入、最终一致性等等)。例如我屡屡提到超过 300 行算我输的 Shell Operator,用极其简陋的方式,为运维人提供了用少量代码完成 Validating/Mutating Webhook、Prometheus Server、任务队列等复杂任务的能力。

抽象和复用程度代表了一个小工具在时间和场景上的适应能力,也代表了其需求和功能的稳定性,此时就完全可以考虑将其纳入具体的产品,甚至其自身就具备成为产品的潜在能力了——例如我偶尔一写的“介绍一个小工具”。

最后,运维人们,Happy Coding..

More from this blog

龙虾恐慌:AIOps 又要改名了?

ChatGPT 开始,把 AI 拉近到普罗大众的面前,让无数人感受到 AI 的亲民魅力。而龙虾,则把大模型驱动的自动化能力,突然间变得水灵灵、活泼泼地走进千家万户。它不只是“风口上的猪”,而是风口本身。热度高到让 Mac mini 一度断货,不知道这在不在库克的预料之内。 每代人都有每代人的鸡蛋,春节期间,我就领了我的鸡蛋。翻出古老的 MacBook Air M1,充值各种大模型。当然了,这个工具

Mar 9, 20261 min read

再见 2025

我猜不少人以为这个号废了吧?并没有,只是今年变化有点大,一直有种抄起键盘,无从说起的感觉,所以一直偷懒到今天,2025 的最后一天。 今年是我的第四个本命年,去年末一期播客里,大内说本命年不是灾年,是变化年,有危也有机。可是讲真啊,只看到危,没看到机。 各种因缘际会,从鹅厂跳槽到前东家,已经接近四年,第一个合同期已经进入尾声。除了前两年还在云原生领域嗷嗷叫,后两年基本都是些鸡零狗碎的东西了,用老东家的术语说是——偏离主航道,可谓是前景暗淡了。 一旦确定要滚蛋,反倒心思轻松起来,每天骑着我的小红车...

Jan 5, 20261 min read

辅助编程?dora 说:我知道你很急可是请你别急

从 OpenGPT 把大模型的火烧旺了之后,这三年来,相信很多组织或摩拳擦掌、或躬身入局,希望借助聪明能干的大模型,或想偿还技术宅,或想降本增效,或想弯道超车。一时间,沉寂许久的 AIxx 又活过来了,LLM Ops、Vibe Coding、中医大模型、GPT 算命等等,全都老树发新芽,焕发了勃勃生机。那么视角拉回从业者最关注的饭碗相关的领域之一——AI 辅助开发,产生了什么触动,应该如何拥抱呢? DORA 的年度报告中给出了很有意思的结论——强者恒强。 执行摘要部分总结了几个有趣的点: 问题...

Oct 6, 20251 min read

[译]dora:ai 辅助软件开发状态报告

执行摘要 在 2025 年,科技领导者面临的核心问题已不再是“是否要采用 AI”,而是“如何实现其价值”。 DORA 的研究基于超过 100 小时的定性访谈和来自全球近 5,000 名技术专业人士的问卷调查。研究揭示了一个关键事实:AI 在软件开发中的主要角色是“放大器”。它会放大高效能组织的优势,也会凸显组织的缺陷。 关键结论:AI 是放大器 AI 投资的最大回报并非来自工具本身,而是来自组织底层系统的战略性建设: 高质量的内部平台 清晰的工作流 团队的协同能力 缺少这些基础,AI ...

Oct 2, 202514 min read

僭越了,有人在用 Rust 写 Kubernetes

一个新语言问世,最爱做的事情之一,就是重写存量软件了。 云原生喝酒 SIG 重点扶持项目——rk8s(https://github.com/rk8s-dev/rk8s) 也可以归在这个范畴里,只不过这个项目重写的东西比较大,是 Kubernetes。 从 2025 年 1 月第一个 Commit 开始,到现在有了 200 多次 Commit,十几万行代码。当然距离 Kubernetes 的几百万行代码还差得远——老马就是喜欢整这种大无畏项目。 另外该项目也是国内第一个脱离 Cargo 转向使用 ...

Sep 27, 20253 min read

【伪】架构师

342 posts