开发 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.