kubernetes v1.18.6编译

Kubernetes是一个容器集群管理平台。大多数情况下,并不需要修改K8s代码即可直接使用。但如果,我们在环境中发现了某个问题/缺陷,或按照特定业务需求需要修改K8s代码时,如定制Kubelet的StopContainer 逻辑、kube-scheduler的pod调度逻辑等。为了让修改生效,那么就需要编译K8s代码了。

Kubernetes源码编译,大致分为本地二进制可执行文件编译和docker镜像编译两种。

1 安装依赖

1.1 安装Golang

官方地址为:https://golang.org/dl/,建议通过:https://golang.google.cn/dl/下载,根据操作系统情况,下载合适的版本,本次使用的是CentOS7.6(x86架构),所以选择下载go1.14.6.linux-amd64.tar.gz (118MB)

wget -c https://golang.google.cn/dl/go1.14.6.linux-amd64.tar.gz /opt/
cd /opt/
tar -C /usr/local -xzf go1.14.6.linux-amd64.tar.gz
echo "export PATH=$PATH:/usr/local/go/bin" >> /etc/profile && source /etc/profile  
echo "export GOPATH=/home/go" >> /etc/profile && source /etc/profile # 配置GOPATH
mkdir -p $GOPATH

1.2 安装docker

使用docker仓库进行安装

  • 设置仓库

安装所需的软件包。yum-utils 提供了 yum-config-manager ,并且 device mapper 存储驱动程序需要 device-mapper-persistent-data 和 lvm2。

yum install -y yum-utils \
  device-mapper-persistent-data \
  lvm2

使用以下命令来设置稳定的仓库。

yum-config-manager \
    --add-repo \
    http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
  • 安装docker engine-community

直接执行以下命令默认安装最新版本的docker

yum install docker-ce docker-ce-cli containerd.io

1.3 安装其他依赖软件

yum install gcc make -y
yum install rsync jq -y

2 下载源码

可根据自己的需要去下载不同版本的源码,本文主要编译的为v1.18.6.

mkdir -p $GOPATH/src/k8s.io
cd $GOPATH/src/k8s.io
git clone https://github.com/kubernetes/kubernetes -b v1.18.6
cd kubernetes

国内受限于网速,大概率会下载失败,可参考其他帖子在码云 上做仓库同步,将github的kubernetes仓库同步到码云,目前已经有其他童鞋做过同步,可直接进行下载。

cd $GOPATH/src/k8s.io
git clone https://gitee.com/mirrors/Kubernetes.git -b v1.18.6 
cd Kubernetes

3 编译

3.1 编译为可执行的二进制文件

3.1.1 使用官方镜像编译
  1. 查看 kube-cross 的 TAG 版本号
[root@yaopei Kubernetes]# cat ./build/build-image/cross/VERSION
v1.13.9-5

这里我们使用官方容器对代码进行编译:k8s.gcr.io/kube-cross:v1.13.6-1(当前只有1.13.6-1)

  1. 获取镜像
docker pull gcrcontainer/kube-cross:v1.13.6-1
  1. 编译
docker run --rm -v /home/go/src/k8s.io/Kubernetes:/go/src/k8s.io/kubernetes -it gcrcontainer/kube-cross:v1.13.6-1 bash
cd /go/src/k8s.io/kubernetes
GOOS=linux GOARCH=amd64 KUBE_BUILD_PLATFORMS=linux/amd64 make all GOFLAGS=-v GOGCFLAGS="-N -l" WHAT=cmd/kubeadm (编译为x86架构平台下二进制文件)

注意:

  • 直接执行编译命令可能会报如下错误
root@dcd81846919b:/go/src/k8s.io/kubernetes# CGO_ENABLED=0 GOOS=linux GOARCH=amd64 make all GOFLAGS=-v
Makefile:1: *** missing separator.  Stop.

​ 可通过如下方法解决:

rm Makefile Makefile.generated_files
ln -s build/root/Makefile Makefile
ln -s build/root/Makefile.generated_files Makefile.generated_files
  • 若在windows上下载的代码,再上传到linux可能会报如下错误:
root@dcd81846919b:/go/src/k8s.io/kubernetes# GOOS=linux GOARCH=amd64 KUBE_BUILD_PLATFORMS=linux/amd64 make all GOFLAGS=-v GOGCFLAGS="-N -l"
/usr/bin/env: 'bash\r': No such file or directory
  • 需要编译arm64架构的二进制,执行以下命令:
GOOS=linux GOARCH=arm64 KUBE_BUILD_PLATFORMS=linux/arm64 make all GOFLAGS=-v GOGCFLAGS="-N -l" WHAT=cmd/kubeadm (编译为arm64架构平台下二进制文件)

WHAT参数指定编译的组件,若不指定,则默认编译全部组件

3.1.2 本地环境编译

使用本地环境编译时,执行的命令和上述镜像编译一样,只是x86架构的服务器只能编译x86的二进制,而无法编译arm64架构的,需要在arm64的平台去编译arm64架构的二进制

编译完成的二进制文件在_output/bin/下,可通过kubeadm version查看版本。

kubeadm version
kubeadm version: &version.Info{Major:"1", Minor:"18+", GitVersion:"v1.18.7-rc.0.18+3ccee83c2885e0", GitCommit:"3ccee83c2885e0d3ea1364181bfac8a64913e42b", GitTreeState:"clean", BuildDate:"2020-08-05T09:02:37Z", GoVersion:"go1.13.6", Compiler:"gc", Platform:"linux/amd64"}

3.2 编译为容器镜像

3.2.1 x86架构平台镜像
  1. 查看kube-cross的TAG版本号
root@b529f9ce0ca9:/go/src/k8s.io/kubernetes# cat ./build/build-image/cross/VERSION
v1.13.14-1
  1. 查看debian_iptables_version版本号
root@b529f9ce0ca9:/go/src/k8s.io/kubernetes# egrep -Rn "debian_iptables_version=" ./
./build/common.sh:98:  local debian_iptables_version=v12.1.0
./build/dependencies.yaml:122:      match: debian_iptables_version=
  1. 查看debian_base_version版本号
root@b529f9ce0ca9:/go/src/k8s.io/kubernetes# egrep -Rn "debian_base_version=" ./
./build/common.sh:97:  local debian_base_version=v2.1.0
./build/dependencies.yaml:86:      match: debian_base_version=

目前还无法从官方下载到这两种tag的镜像,只能通过其他镜像替代,如拉取以下镜像:

docker pull registry.aliyuncs.com/google_containers/pause:3.2
docker pull registry.aliyuncs.com/google_containers/kube-cross:v1.13.6-1
docker pull hassioaddons/debian-base-amd64:3.2.1
docker pull googlecontainersmirrors/debian-iptables-amd64:v12.0.1

docker tag registry.aliyuncs.com/google_containers/pause:3.2 k8s.gcr.io/pause-amd64:3.2
docker tag registry.aliyuncs.com/google_containers/kube-cross:v1.13.6-1 us.gcr.io/k8s-artifacts-prod/build-image/kube-cross:v1.13.14-1
docker tag hassioaddons/debian-base-amd64:3.2.1 k8s.gcr.io/debian-base-amd64:v2.1.0
docker tag googlecontainersmirrors/debian-iptables-amd64:v12.0.1 k8s.gcr.io/debian-iptables-amd64:v12.1.0

docker rmi registry.aliyuncs.com/google_containers/pause:3.2
docker rmi registry.aliyuncs.com/google_containers/kube-cross:v1.13.6-1
docker rmi hassioaddons/debian-base-amd64:3.2.1
docker rmi googlecontainersmirrors/debian-iptables-amd64:v12.0.1
  1. 执行编译命令
KUBE_BASE_IMAGE_REGISTRY=k8s.gcr.io GOOS=linux GOARCH=amd64 KUBE_BUILD_PLATFORMS=linux/amd64 KUBE_BUILD_CONFORMANCE=n KUBE_BUILD_HYPERKUBE=n make release-images GOFLAGS=-v GOGCFLAGS="-N -l" KUBE_BUILD_PULL_LATEST_IMAGES=false
3.2.2 arm64架构平台镜像

前三步和x86架构的步骤相同,需要先查看依赖的镜像版本,下载以下镜像:

docker pull googlecontainersmirrors/debian-iptables-arm64:v12.0.1
docker pull mirrorgooglecontainers/debian-base-arm64:1.0.0
docker pull mirrorgooglecontainers/pause-arm64:3.1

docker tag mirrorgooglecontainers/pause-arm64:3.1 k8s.gcr.io/pause-arm:3.1
docker tag docker.io/googlecontainersmirrors/debian-iptables-arm64:v12.0.1 k8s.gcr.io/debian-iptables-arm64:v12.1.0
docker tag mirrorgooglecontainers/debian-base-arm64:1.0.0 k8s.gcr.io/debian-base-arm64:v2.1.0

docker rmi mirrorgooglecontainers/pause-arm64:3.1
docker rmi docker.io/googlecontainersmirrors/debian-iptables-arm64:v12.0.1
docker rmi mirrorgooglecontainers/debian-base-arm64:1.0.0

执行编译命令:

KUBE_BASE_IMAGE_REGISTRY=k8s.gcr.io GOOS=linux GOARCH=arm64 KUBE_BUILD_PLATFORMS=linux/arm64 KUBE_BUILD_CONFORMANCE=n KUBE_BUILD_HYPERKUBE=n make release-images GOFLAGS=-v GOGCFLAGS="-N -l" KUBE_BUILD_PULL_LATEST_IMAGES=false

KUBE_BASE_IMAGE_REGISTRY:指定镜像仓库,与以上步骤中修改后的tag要相同

GOOS:目标平台系统类型

GOARCH: 目标平台架构类型

KUBE_BUILD_PLATFORMS: kubernetes要编译的目标平台架构和系统类型

KUBE_BUILD_PULL_LATEST_IMAGES: 是否从镜像仓库获取最新镜像

GOFLAGS=v:开启verbose日志

GOGCFLAGS=”-N -l”:禁止编译优化和内联,减小可执行程序大小

镜像编译完成后在_output/release-stage/server/linux-amd64/kubernetes/server/bin/_output/release-stage/server/linux-arm64/kubernetes/server/bin/下保存了编译生成的二进制可执行程序和docker镜像tar包。如导入kube-apiserver.tar镜像,并更新环境上部署的kube-apiserver镜像。

3.2.3 使用编译好的镜像

如导入kube-apiserver.tar镜像,并更新环境上部署的kube-apiserver镜像。

# docker load -i kube-apiserver.tar
b1d170ccb364: Loading layer [==================================================>]  162.4MB/162.4MB

整个编译过程结束后,现在就可以到master节点上,修改/etc/kubernetes/manifests/kube-apiserver.yaml描述文件中的image,修改完立即生效。

3.2.4 编译为镜像总结
  • 在v1.18.x中,编译脚本中,kube-cross的镜像被写死为us.gcr.io/k8s-artifacts-prod/build-image/kube-cross:v1.13.14-1,所以需要将google_containers/kube-cross:v1.13.6-1的镜像标签修改为此标签
  • kube-cross没有arm64架构平台的镜像,因此编译为镜像时只能在x86架构下编译
  • 此教程只适用于v1.18.X版本,其他版本未进行测试
Logo

开源、云原生的融合云平台

更多推荐