工欲善其事,必先利其器。在阅读kubernetes源码时,我也前后使用过多个IDE,最终仍是停留在IDEA上。python
我惯用的是pycharm(IDEA的python IDE版本),配上go的插件,把源码目录进行合理组织后,加入到go的lib,便可实现跳转。更多的方法能够参看这里。linux
kubernetes的源码编译能够分为两种方式。一种是在宿主机/物理机上进行编译,这就意味着你须要完整的搭建编译环境,这个会依赖于各类问题,作法至关不fashion。另一种则是使用docker进行编译。这也是目前最为流行的编译方式。git
本文以kubernetes 1.2为例进行介绍。github
kubernetes自身提供了基于docker的编译方式,按照说明,只须要运行
run.sh hack/build-go.sh
便可从源码编译出对应的二进制文件。docker
能够看到run.sh中有以下几个步骤:网络
kube::build::verify_prereqs kube::build::build_image kube::build::run_build_command "$@"
kube::build::verify_prereqs
是为编译作一些检查,包括检查须要的镜像是否存在等。ide
kube::build::build_image
这一步骤主要是根据Dockerfile,进行构建镜像。这一步骤以下:svn
function kube::build::build_image() { kube::build::ensure_tar mkdir -p "${LOCAL_OUTPUT_BUILD_CONTEXT}" //对于源码进行打包,打成tar包 "${TAR}" czf "${LOCAL_OUTPUT_BUILD_CONTEXT}/kube-source.tar.gz" $(kube::build::source_targets) kube::version::get_version_vars kube::version::save_version_vars "${LOCAL_OUTPUT_BUILD_CONTEXT}/kube-version-defs" //组织待构建镜像的文件夹 cp build/build-image/Dockerfile "${LOCAL_OUTPUT_BUILD_CONTEXT}/Dockerfile" kube::build::update_dockerfile //构建镜像 kube::build::docker_build "${KUBE_BUILD_IMAGE}" "${LOCAL_OUTPUT_BUILD_CONTEXT}" 'false' }
待构建镜像的文件夹位于_output
文件夹中。能够看到_output
的目录结构以下:ui
[root@localhost kubernetes]# tree _output/ _output/ └── images └── kube-build:build-cbc077d244 ├── Dockerfile ├── kube-source.tar.gz └── kube-version-defs
kube-source.tar.gz
即为kubernetes源码打成的tar包。Dockerfile即为build-image/Dockerfile文件。google
以后docker build
将在kube-build:build-cbc077d244
文件夹中进行,编译成kube-build:build-cbc077d244
的镜像。
cbc077d244为git提交时的id,根据源码commit时状况不一样该id不一样。
[root@localhost kubernetes]# docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE kube-build build-cbc077d244 46bca394905f 42 hours ago 1.628 GB gcr.io/google_containers/kube-cross v1.4.2-1 eb4273dc5e30 5 months ago 1.551 GB
到如今为止,必要的工做已经基本作完,代码也已经打包进入镜像,此时只要使用docker从kube-build:build-cbc077d244
的镜像run一个容器出来,进行编译便可。
实际kube::build::run_build_command
也就是这样工做的。不过这里面还作了一些额外的工做,好比把编译输出的文件夹经过-v
参数挂载到_output/dockerized/bin
下。这样当编译完成以后,生成的二进制文件就能够直接在_output/dockerized/bin
目录下获取了。
这一过程参见common.sh#L75
一条命令进行编译的愿望很美好。可是理想很丰满,现实很骨感,在实际中有一些问题,致使这一编译不能正常进行。其中首要的问题就是镜像没法拉取的问题。
Dockerfile中的第一行命令:
FROM gcr.io/google_containers/kube-cross:KUBE_BUILD_IMAGE_CROSS_TAG
。所以须要依赖于gcr.io/google_containers/kube-cross:KUBE_BUILD_IMAGE_CROSS_TAG
这个镜像。可是因为网络缘由,每每没法正常拉取该镜像。因此会致使镜像构建失败。
对于这一问题,有两种方式能够解决:
gcr.io/google_containers/kube-cross:KUBE_BUILD_IMAGE_CROSS_TAG
镜像本文主要介绍前一种方式。其实kube-cross镜像的内容,能够在kube-cross文件夹中获取。固然,要想在国内直接构建这个镜像,仍然会存在没法下载部分包的问题。这里我使用了灵雀云的系统来构建这个镜像。这里是个人kubernetes镜像。
因此你须要作的只是运行如下命令便可:
docker pull index.alauda.cn/xuxinkun/kubernetes docker tag index.alauda.cn/xuxinkun/kubernetes gcr.io/google_containers/kube-cross:v1.4.2-1
当使用run.sh hack/build-go.sh
会编译项目中linux下的全部二进制文件。这一过程极为耗时,大概要十几分钟的样子。根据配置不一样时间或有增减。
其实在实际过程当中,并不须要每次编译全部的文件。好比本次只须要kubelet,那么能够直接运行run.sh hack/build-go.sh cmd/kubelet
,便可只编译kubelet文件,缩短编译时间。