概述
文章目录
- 1、kubernete 源码编译介绍
- 2、环境、软件准备
- 3、安装依赖 golang、docker
- 3.1、安装 golang
- 3.2、安装 docker
- 4、二进制可执行文件编译 kubernetes
- 5、docker 镜像编译 kubernetes
- 6、如何使用编译产物
1、kubernete 源码编译介绍
我们知道,kubernetes 源码编译,分为本地二进制可执行文件编译和 docker 镜像编译两种。之前演示的 minikube 方式或 kubeadm 方式安装,都是基于第二种 docker 镜像方式运行,当然也可以基于二进制文件方式安装,不管哪种方式,都是直接使用并不需要修改任何 k8s 代码。不过当我们有特殊需求时,比如需要修改 kube-proxy 对 service 的代理逻辑,kube-scheduler 对 pod 的调度逻辑等,这个时候就需要修改 k8s 源码了,为了让修改的代码生效,就需要对 k8s 代码执行编译了。当然 k8s 也为我们提供了 CRD 等可扩展插件,在不修改 k8s 源码的基础上实现自定义功能,但是对于一些底层逻辑策略需要修改的话,还是办不到的。
2、环境、软件准备
本次演示环境,我是在虚拟机 Linux Centos7 系统上操作,以下是安装的软件及版本:
- Oracle VirtualBox: 5.1.20 r114628 (Qt5.6.2)
- Linux: CentOS Linux release 7.3.1611 (Core)
- Docker: 18.06.1-ce
- Golang: go1.11.5
- Kubernetes: v1.13.5
注意:因为 kubernetes 源码是由 go 语言编写的,所以要编译其源码,需要安装 go 环境,若我们想基于 docker 镜像编译 kubernetes 的话,那么还需要安装 docker 环境。
3、安装依赖 golang、docker
3.1、安装 golang
注意:kubernetes 1.13
版本需要依赖的 go 版本 >= 1.11.1
,所以安装时需选择该版本以上,否则下边编译时会报错终止,提示需要升级 go 版本,这里提供两种方式安装 golang 环境。
一、直接下载源码安装(注意此方式需要机器网络可以越过墙)
$ cd /opt && wget -c https://dl.google.com/go/go1.11.5.linux-amd64.tar.gz
$ tar -C /usr/local -xzf go1.11.4.linux-amd64.tar.gz
$ echo "export PATH=$PATH:/usr/local/go/bin" >> /etc/profile
$ source /etc/profile
二、通过 rpm 包 yum 安装
$ cd /opt && wget http://download-ib01.fedoraproject.org/pub/epel/7/x86_64/Packages/g/golang-1.11.5-1.el7.x86_64.rpm
$ yum -y install golang-1.11.5-1.el7.x86_64.rpm
安装完毕后,执行 go version
能输出对应的版本号,说明安装没有问题。最后,为了方便编译,最好配置一下 GOPATH
作为 go 执行的工作路径。
$ echo "GOPATH=/root/go" >> /etc/profile
$ source /etc/profile
3.2、安装 docker
docker 安装非常方便,针对自己系统参照 Docker 官网文档 安装即可,这里简单操作一下吧!
一键式安装方式:
$ curl -fsSL https://get.docker.com -o get-docker.sh
$ sudo sh get-docker.sh
rpm 包 yum 安装方式:
$ wget https://download.docker.com/linux/centos/7/x86_64/stable/Packages/docker-ce-18.06.1.ce-3.el7.x86_64.rpm
$ yum -y install docker-ce-18.06.1.ce-3.el7.x86_64.rpm
$ systemctl enable docker
$ systemctl start docker
yum 源安装方式:
$ yum install -y yum-utils device-mapper-persistent-data lvm2
$ yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
$ yum install docker-ce docker-ce-cli containerd.io
$ systemctl enable docker
$ systemctl start docker
安装完毕后,执行 docker -v
命令能输出对应版本号,说明安装没问题。
4、二进制可执行文件编译 kubernetes
开始执行编译前,我们需要将 kubernetes 源码 拉取到本地 GOPATH
工作路径,并指定好 release-1.13
稳定分支。
$ mkdir -p $GOPATH/src/k8s.io && cd $GOPATH/src/k8s.io
$ git clone
https://github.com/kubernetes/kubernetes -b release-1.13
$ 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
目录下。
$ ll _output/bin/
total 1372584
-rwxr-xr-x 1 root root
39777728 Feb 20 16:32 apiextensions-apiserver
-rwxr-xr-x 1 root root
89522240 Feb 20 16:32 cloud-controller-manager
-rwxr-xr-x 1 root root
5800256 Feb 20 16:09 conversion-gen
-rwxr-xr-x 1 root root
5791968 Feb 20 16:08 deepcopy-gen
-rwxr-xr-x 1 root root
5783808 Feb 20 16:09 defaulter-gen
-rwxr-xr-x 1 root root
38382720 Feb 20 16:32 gendocs
-rwxr-xr-x 1 root root 174569288 Feb 20 16:32 genkubedocs
-rwxr-xr-x 1 root root 181003752 Feb 20 16:32 genman
-rwxr-xr-x 1 root root
3901568 Feb 20 16:32 genswaggertypedocs
-rwxr-xr-x 1 root root
38382720 Feb 20 16:32 genyaml
-rwxr-xr-x 1 root root
8126240 Feb 20 16:32 ginkgo
-rwxr-xr-x 1 root root
4460824 Feb 20 16:08 go2make
-rwxr-xr-x 1 root root
2005984 Feb 20 16:09 go-bindata
-rwxr-xr-x 1 root root 177541000 Feb 20 16:32 hyperkube
-rwxr-xr-x 1 root root
36350048 Feb 20 16:32 kubeadm
-rwxr-xr-x 1 root root 138505440 Feb 20 16:32 kube-apiserver
-rwxr-xr-x 1 root root 103774080 Feb 20 16:32 kube-controller-manager
-rwxr-xr-x 1 root root
39189984 Feb 20 16:32 kubectl
-rwxr-xr-x 1 root root 112883720 Feb 20 16:32 kubelet
-rwxr-xr-x 1 root root 110770664 Feb 20 16:32 kubemark
-rwxr-xr-x 1 root root
34775392 Feb 20 16:32 kube-proxy
-rwxr-xr-x 1 root root
37230848 Feb 20 16:32 kube-scheduler
-rwxr-xr-x 1 root root
4975168 Feb 20 16:32 linkcheck
-rwxr-xr-x 1 root root
1599264 Feb 20 16:32 mounter
-rwxr-xr-x 1 root root
10367840 Feb 20 16:09 openapi-gen
上边讲到单独对某个组件执行编译,除了上述办法之外,还可以进入到 kubernetes/cmd/
目录下对应组件下执行,例如我们编译 kube-apiserver
组件。
$ cd kubernetes/cmd/kube-apiserver
$ go build -v
$ ls
apiserver.go
app
kube-apiserver
BUILD
OWNERS
5、docker 镜像编译 kubernetes
docker 镜像编译 kubernetes,可以编译出各核心组件二进制文件以及对应的镜像文件,这里得提一下,由于国内网络的问题,想顺利的安装 kubernetes,依赖镜像拉取问题比较麻烦,之前文章也提到过,可以通过 Github 配合 DockerHub 的 Auto build 功能,将镜像推送到 DockerHub,然后本地拉取后修改 tag 名称,操作有点麻烦,不过好歹解决了我们镜像拉取不到的问题。现在我们可以本地编译出 kubernetes 依赖的镜像了,那就很方便了,有木有。
具体涉及到的代码目录为 kubernetes/build
,这里主要包含几个核心基础镜像的制作,包括 kube-cross
、pause-amd64
、debian-iptables-amd64
、debian-base-amd64
、debian-hyperkube-base-amd64
。这里我偷个懒,先不挨个构建了,当然依旧可以通过上边提到的途径解决,直接拿别人构建好的镜像,拉取后修改 tag 即可。
$ docker pull xiaoxu780/pause-amd64:3.1
$ docker pull xiaoxu780/kube-cross:v1.11.2-1
$ docker pull xiaoxu780/debian-base-amd64:0.4.0
$ docker pull xiaoxu780/debian-iptables-amd64:v11.0
$ docker pull xiaoxu780/debian-hyperkube-base-amd64:0.12.0
$ docker tag xiaoxu780/pause-amd64:3.1 k8s.gcr.io/pause-amd64:3.1
$ docker tag xiaoxu780/kube-cross:v1.11.2-1 k8s.gcr.io/kube-cross:v1.11.5-1
$ docker tag xiaoxu780/debian-base-amd64:0.4.0 k8s.gcr.io/debian-base-amd64:0.4.0
$ docker tag xiaoxu780/debian-iptables-amd64:v11.0 k8s.gcr.io/debian-iptables-amd64:v11.0
$ docker tag xiaoxu780/debian-hyperkube-base-amd64:0.12.0 k8s.gcr.io/debian-hyperkube-base-amd64:0.12.0
注意:这里通过 kube-cross
组件有指定的版本,可以从 kubernetes/build/build-image/cross/VERSION
文件得到,我这里显示是 v1.11.5-1
,跟上边提供的版本不一致,不过没关系,直接修改为该版本 tag 亲测没有问题的。
依赖的基础镜像本地已经有了,接下来需要修改构建策略,忽略 --pull
参数,不然每次构建还是会去外网拉取基础镜像,要让它直接读取本地镜像。修改 kubernetes/build/lib/release.sh
文件如下:
"${DOCKER[@]}" build --pull -q -t "${docker_image_tag}" "${docker_build_path}" >/dev/null
修改为
"${DOCKER[@]}" build -q -t "${docker_image_tag}" "${docker_build_path}" >/dev/null
其次修改 kubernetes/hack/lib/version.sh
文件,将变量 KUBE_GIT_TREE_STATE="dirty"
修改为 KUBE_GIT_TREE_STATE="clean"
,dirty
表示 Git 提交 ID 之后的源代码有更改,clean
表示 Git 提交 ID 之后没有更改,为了确保版本号干净,都修改为 clean
。
接下来直接执行如下编译命令:
$ KUBE_BUILD_PLATFORMS=linux/amd64 KUBE_BUILD_CONFORMANCE=n KUBE_BUILD_HYPERKUBE=n make release-images GOFLAGS=-v GOGCFLAGS="-N -l"
+++ [0221 10:48:26] Verifying Prerequisites....
+++ [0221 10:48:27] Building Docker image kube-build:build-d0824d4b8f-5-v1.11.5-1
+++ [0221 10:48:49] Creating data container kube-build-data-d0824d4b8f-5-v1.11.5-1
+++ [0221 10:48:53] Syncing sources to container
+++ [0221 10:49:11] Running build command...
......
+++ [0221 10:56:08] Syncing out of container
+++ [0221 10:56:13] Building images: linux-amd64
+++ [0221 10:56:14] Starting docker build for image: cloud-controller-manager-amd64
+++ [0221 10:56:14] Starting docker build for image: kube-apiserver-amd64
+++ [0221 10:56:14] Starting docker build for image: kube-controller-manager-amd64
+++ [0221 10:56:14] Starting docker build for image: kube-scheduler-amd64
+++ [0221 10:56:14] Starting docker build for image: kube-proxy-amd64
+++ [0221 10:56:24] Deleting docker image k8s.gcr.io/kube-scheduler:v1.13.4-beta.0.12_4ef32ffb4e7c35
+++ [0221 10:56:25] Deleting docker image k8s.gcr.io/kube-proxy:v1.13.4-beta.0.12_4ef32ffb4e7c35
+++ [0221 10:56:32] Deleting docker image k8s.gcr.io/cloud-controller-manager:v1.13.4-beta.0.12_4ef32ffb4e7c35
+++ [0221 10:56:33] Deleting docker image k8s.gcr.io/kube-controller-manager:v1.13.4-beta.0.12_4ef32ffb4e7c35
+++ [0221 10:56:33] Deleting docker image k8s.gcr.io/kube-apiserver:v1.13.4-beta.0.12_4ef32ffb4e7c35
+++ [0221 10:56:33] Docker builds done
说明一下:
UBE_BUILD_CONFORMANCE=n
和KUBE_BUILD_HYPERKUBE=n
参数配置是否构建hyperkube-amd64
和conformance-amd64
镜像,默认是 y 构建,这里设置为 n 暂时不需要构建了。make release-images
表示执行编译并生成镜像 tar 包。
稍等片刻,编译的 kubernetes 组件 docker 镜像以 tar 包的形式发布在 kubernetes/_output/release-tars/amd64
目录中。
$ ll _output/release-images/amd64/
total 611988
-rw-r--r-- 2 root root 133416960 Feb 21 10:56 cloud-controller-manager.tar
-rw-r--r-- 2 root root 182395904 Feb 21 10:56 kube-apiserver.tar
-rw-r--r-- 2 root root 147664384 Feb 21 10:56 kube-controller-manager.tar
-rw-r--r-- 2 root root
82071552 Feb 21 10:56 kube-proxy.tar
-rw-r--r-- 2 root root
81121280 Feb 21 10:56 kube-scheduler.tar
生成的核心组件二进制可执行文件以及镜像,在 kubernetes/_output/release-stage/server/linux-amd64/kubernetes/server/bin/
目录可以找到。
$ ll _output/release-stage/server/linux-amd64/kubernetes/server/bin/
total 1006368
-rwxr-xr-x 1 root root
89526336 Feb 21 10:56 cloud-controller-manager
-rw-r--r-- 1 root root
33 Feb 21 10:56 cloud-controller-manager.docker_tag
-rw-r--r-- 2 root root 133416960 Feb 21 10:56 cloud-controller-manager.tar
-rwxr-xr-x 1 root root 138505472 Feb 21 10:56 kube-apiserver
-rw-r--r-- 1 root root
33 Feb 21 10:56 kube-apiserver.docker_tag
-rw-r--r-- 2 root root 182395904 Feb 21 10:56 kube-apiserver.tar
-rwxr-xr-x 1 root root 103774112 Feb 21 10:56 kube-controller-manager
-rw-r--r-- 1 root root
33 Feb 21 10:56 kube-controller-manager.docker_tag
-rw-r--r-- 2 root root 147664384 Feb 21 10:56 kube-controller-manager.tar
-rwxr-xr-x 1 root root
34775392 Feb 21 10:56 kube-proxy
-rw-r--r-- 1 root root
33 Feb 21 10:56 kube-proxy.docker_tag
-rw-r--r-- 2 root root
82071552 Feb 21 10:56 kube-proxy.tar
-rwxr-xr-x 1 root root
37230848 Feb 21 10:56 kube-scheduler
-rw-r--r-- 1 root root
33 Feb 21 10:56 kube-scheduler.docker_t
这些镜像 tar 包是可以直接用的,这下再也不用担心镜像拉不下来了。
6、如何使用编译产物
之前我们使用 minikube 或 kubeadm 方式安装 kubernetes,都是基于 docker 镜像方式运行的,现在本地已经有镜像 tar 包了,只需要导入即可。
$ docker load -i kube-apiserver.tar
8b4af753a2e6: Loading layer
138.5MB/138.5MB
Loaded image: k8s.gcr.io/kube-apiserver:v1.13.4-beta.0.12_4ef32ffb4e7c35
$ docker load -i kube-controller-manager.tar
b6bc9feeea3e: Loading layer
103.8MB/103.8MB
Loaded image: k8s.gcr.io/kube-controller-manager:v1.13.4-beta.0.12_4ef32ffb4e7c35
$ docker load -i kube-proxy.tar
f809931d55f8: Loading layer
34.78MB/34.78MB
Loaded image: k8s.gcr.io/kube-proxy:v1.13.4-beta.0.12_4ef32ffb4e7c35
$ docker load -i kube-scheduler.tar
08c5e224b023: Loading layer
37.23MB/37.23MB
Loaded image: k8s.gcr.io/kube-scheduler:v1.13.4-beta.0.12_4ef32ffb4e7c35
$ docker images | grep kube
REPOSITORY
TAG
IMAGE ID
CREATED
SIZE
k8s.gcr.io/kube-apiserver
v1.13.4-beta.0.12_4ef32ffb4e7c35
478c9f2cf9b0
7 hours ago
181MB
k8s.gcr.io/kube-controller-manager
v1.13.4-beta.0.12_4ef32ffb4e7c35
2095dd7895ac
7 hours ago
146MB
k8s.gcr.io/kube-proxy
v1.13.4-beta.0.12_4ef32ffb4e7c35
b22db5302318
7 hours ago
80.2MB
k8s.gcr.io/kube-scheduler
v1.13.4-beta.0.12_4ef32ffb4e7c35
d17edffb4bca
7 hours ago
79.6MB
kube-build
build-d0824d4b8f-5-v1.11.5-1
1b02b2eeeffd
7 hours ago
2.31GB
对于二进制可执行文件,亦可直接使用,具体可参考 kubeasz 项目,该项目致力于提供快速部署高可用 k8s 集群的工具,它基于二进制可执行程序方式部署和利用 ansible-playbook
实现自动化安装的。
参考资料
- kubernetes build
- 编译和运行Kubernetes源码
最后
以上就是俏皮缘分为你收集整理的国内环境下 Kubernetes 源码编译及运行的全部内容,希望文章能够帮你解决国内环境下 Kubernetes 源码编译及运行所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复