kubernetes修改源码手动编译镜像

对于 kubectl 还有 kubelet 这种比较简单,go build 之后直接把生成的二进制文件替换掉原来 /usr/bin 下面的就可以了,
但是有一些组件是需要启动一个 pod 来执行的,比如 apiserver,这就需要我们把修改后的源码编译成镜像,在编译的时候也是遇到了许多的坑,记录一下整个编译过程。

OS:centos7.6

kubernetes version:1.20.0

就拿 apiserver 组件来举例子

默认你已经有一个可用的k8s集群并且clone下来了k8s的源代码。

方法一

1.首先按照你自己的需要修改源代码

这个根据需要自己改就可以

2.执行镜像编译命令

KUBE_BUILD_PLATFORMS=linux/amd64 make quick-release
# KUBE_BUILD_PLATFORMS=linux/amd64 只编译生成针对linux的镜像,但是这个参数好像没必要,因为quick-release就有这样的效果
# quick-release 只生成linux64 位系统的镜像,不走test,主要是为了节省编译时间
# WHAT=cmd/kube-apiserver 只编译apiserver组件

直接在 kubernetes 代码目录下面执行就行,但是一般来说执行的时候肯定会报错,因为需要依赖的三个基础镜像是需要FQ的,我这边公司内部有对应的镜像资源,所以就直接修改了一下
/data/gopath/src/k8s.io/kubernetes/build/common.sh
这个脚本,更换了一下镜像仓库的地址。

(line 46) readonly KUBE_BASE_IMAGE_REGISTRY="${KUBE_BASE_IMAGE_REGISTRY:-k8s.gcr.io/build-image}"

把这个命令里面的 k8s.gcr.io/build-image 换成你能获取镜像的仓库地址就行了。另外还可以去 dockerhub 上面找找有没有能用得上的,拉下来到本地,看看报错提示的是缺少哪个镜像,需要找到相对应的版本才行。

大概需要的就是下面这三个镜像,但是版本有可能有出入

k8s.gcr.io/build-image/go-runner         buster-v2.2.2                  
k8s.gcr.io/build-image/kube-cross        v1.15.5-1
k8s.gcr.io/build-image/debian-iptables   buster-v1.3.0

总之,可以修改脚本里面的镜像仓库地址,保证 docker pull 可以成功,或者从别的地方 pull 下来对应的镜像,然后修改 tag。

做完这些之后,在执行KUBE_BUILD_PLATFORMS=linux/amd64 make quick-release应该就不会报错了,如果还有错,需要你自己看看错误信息然后去解决一下了。

编译对硬件要求还是比较高的,我看推荐 需要 8G 内存,然后找了台 8G 的服务器,倒是没什么问题,就是编译的时间有点长。

然后可以在 kubernetes/_output/release-images/amd64/ 下面找到编译成功的镜像压缩包了。

3.部署新的镜像

把你需要的镜像压缩包copy到集群的master上面,如果集群使用的是 docker 搭建的,应该直接使用 docker load 命令就可以把 tar 文件家在城 image 了,我这边是用的是 containerd 搭建的集群,需要使用

sudo ctr -n=k8s.io images import xxxxx.tar

去导入镜像,使用

crictl images list

查看镜像是不是导入成功,如果成功了,接着修改

/etc/kubernetes/manifests/kube-apiserver.yaml

文件,把里面的 image 字段修改成你刚刚导入的镜像名字,等一会,k8s 集群会自动重启。
大概等个几十秒就 应该重启完毕了,使用
kubectl get pod -A 看看是不是所有 pod 都正常了,有可能会出现以下问题

Q1:Unable to connect to the server: x509: certificate signed by unknown authority (possibly because of "crypto/rsa: verification error" while trying to verify candidate authority certificate "kubernetes")
把 $HOME/.kube 这个删除了再试试
Q2:The connection to the server localhost:8080 was refused - did you specify the right host or port?
执行 export KUBECONFIG=/etc/kubernetes/admin.conf 命令试试

一般来说整个系统应该就可以使用新的镜像来正常工作了。

方法二

上面那种方法缺点是对应的镜像确实比较难找,我当初也是在网上找了半天,没找到我需要的版本,后来从同事口中得知公司内部镜像库都有的,然后就是编译环节,对机器配置要求高,编译时间长,每次都需要把四个组件全部编译一遍,具体能不能只编译单个组件我还没试过。

那么可以使用下面这种方法,就是自己写一个 dockerfile,还是用 apiserver 来举例:

apiserver 需要依赖一个 debian 的基础镜像,也就是我在上面列出的
k8s.gcr.io/build-image/debian-iptables:buster-v1.3.0 这个镜像,这就可以随便换了,随便找一个 debian 的基础镜像就可以,我试过其他的 linux 发行版基础镜像也是可以的,把 debain 换成 centos 照样可以编译成功并且能正常工作。

1.首先把 apiserver 的代码 build 一下,生成二进制文件

2.写一个 dockerfile:
(第一行根据你的实际情况换一下基础依赖镜像)

FROM k8s.gcr.io/build-image/debian-iptables:buster-v1.3.0
ADD apiserver /usr/local/bin/kube-apiserver
WORKDIR /usr/local/bin/

3.然后执行
docker build . -t xxxxxxx (随便取个名字,版本号最好和其他的组件保持一致,比如写成 xxxxxxx:v1.20.0)

4.修改
/etc/kubernetes/manifests/kube-apiserver.yaml 文件,把里面的 image 字段修改成你刚刚导入的镜像名字,等待集群重启

posted @ 2021-01-13 10:22  navist2020  阅读(1878)  评论(0编辑  收藏  举报