开发 Kubernetes debug 的几种手段
我们在开发 Kubernetes 遇到最大的难题就是如何调试组件,因为它涉及到的组件较多,工作流程较长,如果是较小的代码改动,我们可以通过添加单元测试、E2E 等手段进行功能验证。
但是如果遇到较大功能的功能,还是需要进行测试,乃至于进行 debug,但是存在如下几个问题:
- 通常开发都是基于最新代码开发的,就导致版本较新;那依赖的组件版本也需要比较高才行;比如开发
Kubelet, 那依赖的kube-apiserver版本就需要接近最新,具体可以看kubernetes官网的版本匹配文档。 Kubernetes组件启动通常会依赖其它服务,以及集群配置,解决起来比较麻烦。- 使用
IDE进行debug有难度,需要解决服务依赖问题。
下面从本人的开发 debug 经验中总结了常用的两种方式,一种是通过打印日志然后部署服务来分析执行逻辑、一种是直接通过 IDE 进行 DEBUG.
要开发一个 Kubernetes 的需求,通常需要有准备工作、实现需求和测试三个步骤;
准备工作
- 一台
Linux服务器,最好是安装Ubuntu22.04的操作系统,或者根据需求来决定需要安装什么。资源最少8核 CPU16G的内存150G的磁盘。 Linux服务器机器安装好最新的golang版本,开通ssh端口,修改使其可以通过root进行远程登录。- 部署一个最新的
Kubernetes集群,最好使用二进制启动k8s的核心组件,这样便于调试;单节点足够。
安装 Kubernetes 集群
这里介绍一个工具 kubeasz , 可以快速的安装出一个 kubernetes 单机集群,并且以二进制的形式启动核心组件。
我们为什么不用 kubeadm 呢?因为它启动的核心 pod 的方式是通过 static 的形式启动的,这样就导致不能进行调试,而且需要编译镜像才能进行日志调试。
安装步骤:
$ export release=3.6.5
$ wget https://github.com/lengrongfu/kubeasz/releases/download/${release}/ezdown
$ chmod +x ./ezdown
$ ./ezdown -D
$ ./ezdown -S
$ docker exec -it kubeasz ezctl start-aio
$ source ~/.bashrc
$ kubectl version
实现需求
因为 Kubernetes 大多数都是在 Linux 上运行,很多逻辑需要 Linux 操作系统下才可以编辑,通常大家的本地开机都是 MacOS ,导致不能编写 Linux 相关的逻辑。
下面我以本人经常使用的两种方案来介绍,一种是在本地开发,一种是在远程开发。
本地开发 K8s
我们在本机上启动一个 Linux 操作系统的容器,或者是用 Multipass 来启动 Ubuntu 虚拟机.
Multipass 功能很强大,就是使用比较繁琐,之前小编也用过,但是后面发现启动一个容器也够用了,就一直沿用到现在。
构建一个包含环境的镜像,首先通过如下的 Dockerfile:
FROM ubuntu:22.04
RUN apt-get update
RUN apt-get install -y openssh-server
RUN sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
RUN sed -i 's/PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config
RUN echo 'root:123456' | chpasswd
RUN apt-get install -y git vim curl wget cmake
RUN apt install software-properties-common -y
RUN add-apt-repository ppa:longsleep/golang-backports
RUN apt update
RUN apt install golang-go -y
RUN /etc/init.d/ssh start
然后进行构建:
$ docker build -t golang-env:dev -f Dockerfile .
启动容器,并且把本地的 golang 目录挂载到容器目录中,这样避免修改的代码丢失:
$ docker run -d -p 50024:22 -v /Users/{local}/goworspace/code/src:/root/go/src golang-env:dev /usr/sbin/sshd -D
然后继续参考远程开发 k8s 部分,用本地开发的好处是可以给 Docker 配置本地的代理、可以登录 Github Copilot 等插件。
远程开发 K8s
这里我们通过连接远程 Linux 服务器或者是本地的容器来构建一个开发环境。
- 首先需要下载一个
jetbrains****家最新的任意一个编辑器,打开编辑器之后不要打开项目,在编辑器首页有一个Remote Development的菜单。

- 点击
SSH进行创建 Project 和配置;这里填写用户名、主机地址和端口

- 连接之后点击 + 号添加项目

- 之后选择好 IDE version 和 项目目录,点击右下角的 Start IDE and Connect. 按钮即可。

成功之后将打开 Golang 编辑器的界面,和在本地开发一样;剩下的就是编写代码。
测试需求
这里我们以测试 Kubelet 为例来说明,使用 kubeaze 安装的 Kubernetes 集群核心组件都是使用 systemctl 启动的,所以我们测试的时候可以使其停止,然后启动自己修改代码的服务即可。
假如我们通过打印日志的方式来进行测试, 只需要把本地代码提价到服务器上即可。然后执行 make all 或者 make all WHAT=cmd/kubelet GOFLAGS=-v 只编译指定项目。
编译生成的二进制文件在 _output/bin/ 目录下,这个是网络上通常的说法,但是很奇怪我的编译后不再这个目录下,在 ~/go/bin 目录下,可以都找找看。
然后查看下编译后的版本信息 ~/go/bin/kubelet —version .
命令行测试
- 通过
ps获取kubelet启动命令,需要先找到启动参数。 - 停止之前的
kubelet服务systemctl stop kubelet.service - 使用编译后的二进制启动以及添加默认的参数。
IDE debug
- 通过
ps获取kubelet启动命令,需要先找到启动参数。 - 停止之前的
kubelet服务systemctl stop kubelet.service - 把启动参数填写进去即可进行 Debug.
