kubernetes源碼閱讀及編譯

kubernetes源碼閱讀

工欲善其事,必先利其器。在閱讀kubernetes源碼時,我也前後使用過多個IDE,最終仍是停留在IDEA上。python

我慣用的是pycharm(IDEA的python IDE版本),配上go的插件,把源碼目錄進行合理組織後,加入到go的lib,便可實現跳轉。更多的方法能夠參看這裏linux

kubernetes源碼編譯

kubernetes的源碼編譯能夠分爲兩種方式。一種是在宿主機/物理機上進行編譯,這就意味着你須要完整的搭建編譯環境,這個會依賴於各類問題,作法至關不fashion。另一種則是使用docker進行編譯。這也是目前最爲流行的編譯方式。git

使用docker進行編譯

本文以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 "$@"

verify_prereqs

kube::build::verify_prereqs是爲編譯作一些檢查,包括檢查須要的鏡像是否存在等。ide

build_image

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

run_build_command

到如今爲止,必要的工做已經基本作完,代碼也已經打包進入鏡像,此時只要使用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這個鏡像。可是因爲網絡緣由,每每沒法正常拉取該鏡像。因此會致使鏡像構建失敗。

對於這一問題,有兩種方式能夠解決:

  • 本身進行構建kube-cross鏡像
  • 經過代理或者其餘方式,獲取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文件,縮短編譯時間。

相關文章
相關標籤/搜索