天天看點

kubernetes源碼閱讀及編譯

kubernetes源碼閱讀

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

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

kubernetes源碼編譯

kubernetes的源碼編譯可以分為兩種方式。一種是在主控端/實體機上進行編譯,這就意味着你需要完整的搭建編譯環境,這個會依賴于各種問題,做法相當不fashion。另外一種則是使用docker進行編譯。這也是目前最為流行的編譯方式。

使用docker進行編譯

本文以kubernetes 1.2為例進行介紹。

kubernetes自身提供了基于docker的編譯方式,按照說明,隻需要運作

run.sh hack/build-go.sh

即可從源碼編譯出對應的二進制檔案。

流程詳解

可以看到run.sh中有如下幾個步驟:

kube::build::verify_prereqs
kube::build::build_image
kube::build::run_build_command "$@"
           

verify_prereqs

kube::build::verify_prereqs

是為編譯做一些檢查,包括檢查需要的鏡像是否存在等。

build_image

kube::build::build_image

這一步驟主要是根據Dockerfile,進行建構鏡像。這一步驟如下:

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

的目錄結構如下:

[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檔案。

之後

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檔案,縮短編譯時間。

作者:xuxinkun

出處:xinkun的部落格

連結:https://www.cnblogs.com/xuxinkun/

本文版權歸作者所有,歡迎轉載。

未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。

歡迎掃描右側二維碼關注微信公衆号

xinkun的部落格 進行訂閱。也可以通過微信公衆号留言同作者進行交流。
kubernetes源碼閱讀及編譯

繼續閱讀