前面我们部署 Kubernetes 集群时,用的是官方已经编译好的 Kubernetes 5 大件。如果有业务需求,需要魔改一些 Kubernetes 特性(尽管不建议,通常也遇不到这种需求,这里只是说个如果),或者因为排障、测试等目的,需要修改 Kubernetes 源码,并将修改后的源码部署到集群中。
这时候,我们就需要能够自己编译源码,并将编译后的二进制文件替换,集群中已经部署的二进制文件。所以,本小节,我再来介绍下,如何编译 Kubernetes 源码,并替换集群中的组件。
编译 Kubernetes 源码#
克隆源码#
首先,我们需要克隆 kubernetes 源码,并切换到 v1.28.3 分支:
$ cd $GOPATH/src/k8s.io/
$ git clone https://github.com/kubernetes/kubernetes.git
$ git checkout -b v1.31.1 v1.31.1
操作系统配置:
Kubernetes 是一个大型项目,编译它会使用大量资源。编译 Kubernetes 建议的资源配置如下:
- CPU >= 2 核;
- 内存 >= 8 GB;
- 磁盘存储空间 >= 50 GB;
编译指定的 Kubernetes 组件#
这里假设你已经在你的操作系统中,安装了 Go 开发环境。直接执行以下命令来编译所有的 Kubernetes 组件:
$ make all
+++ [0524 16:34:11] Building go targets for linux/amd64
github.com/onsi/ginkgo/v2/ginkgo (non-static)
k8s.io/apiextensions-apiserver (static)
k8s.io/component-base/logs/kube-log-runner (static)
k8s.io/kube-aggregator (static)
k8s.io/kubernetes/cluster/gce/gci/mounter (static)
k8s.io/kubernetes/cmd/kubeadm (static)
k8s.io/kubernetes/cmd/kube-apiserver (static)
k8s.io/kubernetes/cmd/kube-controller-manager (static)
k8s.io/kubernetes/cmd/kubectl (static)
k8s.io/kubernetes/cmd/kubectl-convert (static)
k8s.io/kubernetes/cmd/kubelet (non-static)
k8s.io/kubernetes/cmd/kubemark (static)
k8s.io/kubernetes/cmd/kube-proxy (static)
k8s.io/kubernetes/cmd/kube-scheduler (static)
k8s.io/kubernetes/test/conformance/image/go-runner (non-static)
k8s.io/kubernetes/test/e2e/e2e.test (test)
k8s.io/kubernetes/test/e2e_node/e2e_node.test (test)
上述命令会编译所有的 Kubernetes 组件,编译后的组件保存在 _output/bin 目录下。
如果你想编译某个组件可以执行以下命令:
make WHAT=cmd/kube-apiserver
部署编译后的组件#
假设我们想更新魔改后的 kube-apiserver 组件,操作步骤如下:
- 编译魔改后的源码,得到 kube-apiserver 二进制部署文件;
- 更新目标机器上的 kube-apiserver 服务;
- 测试更新后的 kube-apiserver 是否正常工作;
- 滚动更新 kube-apiserver;
- 测试新的 kube-apiserver 功能。
编译魔改后的源码,得到 kube-apiserver 二进制部署文件#
执行以下命令来编译魔改后的 kube-apiserver 源码:
make WHAT=cmd/kube-apiserver
编译后的二进制产物为 _output/bin/kube-apiserver。
更新目标机器上的 kube-apiserver 服务#
首先,需要停止目标机器上的 kube-apiserver 服务,否则在分发 kube-apiserver 到启动路径时,会因为文件 busy 而失败。停止掉目标机器上正在运行的 kube-apiserver 服务:
systemctl stop kube-apiserver
因为 kube-apiserver 通过 Nginx 实现了多副本高可用,所以可以短暂停止 kube-apiserver 服务。
将 _output/bin/kube-apiserver 文件通过 scp 命令分发到目标节点上的部署路径上。本套课程 kube-apiserver 的部署路径为 /opt/k8s/bin/kube-apiserver。
之后,重新启动 kube-apiserver 服务:
systemctl start kube-apiserver
测试更新后的 kube-apiserver 是否正常工作#
在更新完某个节点的 kube-apiserver 后,需要测试该 kube-apiserver 服务是否可以正常工作。测试方法也很简单,直接请求这个节点上 kube-apiserver 的 master 地址即可。
滚动更新 kube-apiserver#
如果节点上更新的 kube-apiserver 工作正常,这时候,再更新其他节点的 kube-apiserver,直到将所有节点都更新完成。
测试新的 kube-apiserver 功能#
所有 Master 节点上的 kube-apiserver 更新完成后,便可以从最上层,做一次端到端的 Kubernetes 功能测试。