技术交流28群

服务热线

135-6963-3175

微信服务号

kubernetes源码编译 更新时间 2020-9-23 浏览2336次

kubernetes 源码编译,分为本地二进制可执行文件编译和 docker 镜像编译两种。之前演示的 minikube 方式或 kubeadm 方式安装,都是基于第二种 docker 镜像方式运行,当然也可以基于二进制文件方式安装,不管哪种方式,都是直接使用并不需要修改任何 k8s 代码。不过当我们有特殊需求时,比如需要修改 kube-proxy 对 service 的代理逻辑,kube-scheduler 对 pod 的调度逻辑等,这个时候就需要修改 k8s 源码了,为了让修改的代码生效,就需要对 k8s 代码执行编译了。当然 k8s 也为我们提供了 CRD 等可扩展插件,在不修改 k8s 源码的基础上实现自定义功能,但是对于一些底层逻辑策略需要修改的话,还是办不到的。

需要准备环境:Golang\Git\gcc\docker

Golang安装

注意:kubernetes 1.16+ 版本需要依赖的 go 版本 >= 1.13.4,所以安装时需选择该版本以上,否则下边编译时会报错终止,提示需要升级 go 版本,这里提供两种方式安装 golang 环境。

一、直接下载源码安装(注意此方式需要机器网络可以越过墙)

$ cd /opt && wget -c https://dl.google.com/go/go1.13.15.linux-amd64.tar.gz 
$ tar -C /usr/local -xzf go1.13.15.linux-amd64.tar.gz 
$ echo "export PATH=$PATH:/usr/local/go/bin" >> /etc/profile$ source /etc/profile

安装完毕后,执行 go version 能输出对应的版本号,说明安装没有问题。最后,为了方便编译,最好配置一下 GOPATH 作为 go 执行的工作路径。

[root@localhost app]# go version  
go version go1.13.15 linux/amd64 
$ echo "GOPATH=/root/go" >> /etc/profile 
$ source /etc/profile

Docker安装

参考docker章节

gcc安装

$ yum install gcc
$ gcc -v
使用内建 specs。
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/lto-wrapper
目标:x86_64-redhat-linux
配置为:../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-languages=c,c++,objc,obj-c++,java,fortran,ada,go,lto --enable-plugin --enable-initfini-array --disable-libgcj --with-isl=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/isl-install --with-cloog=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/cloog-install --enable-gnu-indirect-function --with-tune=generic --with-arch_32=x86-64 --build=x86_64-redhat-linux
线程模型:posix
gcc 版本 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC)

Git

$ yum install git

kubernetes源码编译

代码下载

$ mkdir -p $GOPATH/src/k8s.io && cd $GOPATH/src/k8s.io 
$ git clone  https://github.com/kubernetes/kubernetes -b release-1.16
$ cd kubernetes

我们从 kubernetes/hack/lib/golang.sh 代码中可以看到,该脚本会检测当前系统环境来安装对应的必要的服务,默认不指定 KUBE_BUILD_PLATFORMS(当前构建平台环境类型)的话,它会分别编译多种环境,编译时间很长,而且没有必要。这里我们可以直接修改文件中 KUBE_SERVER_PLATFORMS KUBE_NODE_PLATFORMS KUBE_CLIENT_PLATFORMS KUBE_TEST_PLATFORMS 配置,只保留当前系统对应环境,例如我们的系统环境为 linux/amd64。另一种方式就是在编译时,直接指定 KUBE_BUILD_PLATFORMS 参数即可。编译命令如下:

$ KUBE_BUILD_PLATFORMS=linux/amd64 make all GOFLAGS=-v GOGCFLAGS="-N -l"

对参数简单说明一下:

KUBE_BUILD_PLATFORMS=linux/amd64 指定当前编译平台环境类型为 linux/amd64。

make all 表示在本地环境中编译所有组件。

GOFLAGS=-v 编译参数,开启 verbose 日志。

GOGCFLAGS="-N -l" 编译参数,禁止编译优化和内联,减小可执行程序大小。

注意:执行以上命令时,需要机器可用内存在 4G 左右,否则编译时会报内存不够错误。若我们只想编译某个组件,例如,只想编译 kube-apiserver ,那么可以执行 make WHAT=cmd/kube-apiserver 命令。这里可选组件有很多,详细可参考 kubernetes/cmd/ 目录下所有组件。

稍等片刻,全部组件编译耗时较长,执行完毕后,二进制可执行文件默认生成到 kubernetes/_output/bin 目录下。

k8s.io/kubernetes/vendor/github.com/stretchr/objx
k8s.io/kubernetes/vendor/github.com/stretchr/testify/assert
k8s.io/kubernetes/vendor/github.com/stretchr/testify/mock
k8s.io/kubernetes/pkg/kubelet/cadvisor/testing
k8s.io/kubernetes/vendor/github.com/golang/mock/gomock
k8s.io/kubernetes/pkg/kubelet/container/testing
k8s.io/kubernetes/vendor/github.com/stretchr/testify/require
k8s.io/kubernetes/test/utils
k8s.io/kubernetes/pkg/kubemark
k8s.io/kubernetes/pkg/util/iptables/testing
k8s.io/kubernetes/pkg/util/sysctl/testing
k8s.io/kubernetes/vendor/k8s.io/utils/exec/testing
k8s.io/kubernetes/cmd/kubemark
[root@localhost kubernetes]#
[root@localhost bin]# pwd
/root/go/src/k8s.io/kubernetes/_output/bin
[root@localhost bin]# ls
apiextensions-apiserver  e2e_node.test  genman              go2make     kubeadm                  kubelet         linkcheck
conversion-gen           e2e.test       genswaggertypedocs  go-bindata  kube-apiserver           kubemark        mounter
deepcopy-gen             gendocs        genyaml             go-runner   kube-controller-manager  kube-proxy      openapi-gen
defaulter-gen            genkubedocs    ginkgo              hyperkube   kubectl                  kube-scheduler
[root@localhost bin]#

上边讲到单独对某个组件执行编译,除了上述办法之外,还可以进入到 kubernetes/cmd/ 目录下对应组件下执行,例如我们编译 kube-apiserver 组件。

$ cd kubernetes/cmd/kube-apiserver
$ go build -v
$ ls 
apiserver.go  app  kube-apiserver  BUILD  OWNERS