k8s :構建系統

前言

大型軟件(linux,android .etc)通常都有本身的構建系統,k8s 也不例外,本文簡要介紹 k8s 構建系統linux

構建流程

release

以 quick-release 爲例,在命令行執行如下命令android

# make quick-release

make 在源代碼根目錄 Makefile 文件中定位到 quick-release 目標,該目標的動做是執行 build/release.sh 腳本git

# kubernetes/Makefile
.PHONY: release-skip-tests quick-release
ifeq ($(PRINT_HELP),y)
release-skip-tests quick-release:
    @echo "$$RELEASE_SKIP_TESTS_HELP_INFO"
else
release-skip-tests quick-release: KUBE_RELEASE_RUN_TESTS = n
release-skip-tests quick-release: KUBE_FASTBUILD = true
release-skip-tests quick-release:
    build/release.sh <--- 執行 kubernetes/build/release.sh
endif

release.sh 將構建過程拆分紅一個個步驟,每一個步驟對應一個 shell functiondocker

# kubernetes/build/release.sh
...
kube::build::verify_prereqs
kube::build::build_image
kube::build::run_build_command make cross
...
kube::build::copy_output
kube::release::package_tarballs

verify_prereqs 對構建環境進行檢查,好比是否缺乏一些工具軟件
build_image 建立構建須要的 docker 鏡像 ???
run_build_command make cross 啓動容器,運行 make cross
copy_output, package_tar 處理構建生成的各個文件shell

這裏比較有意思的是 k8s 使用 docker 容器進行構建,多是爲了交叉編譯吧dom

構建鏡像

kube::build::build_image 方法構建基礎鏡像,同步 kubernetes 源代碼到 data container(數據卷容器)工具

function kube::build::build_image() {
  mkdir -p "${LOCAL_OUTPUT_BUILD_CONTEXT}"
  # Make sure the context directory owned by the right user for syncing sources to container.
  chown -R ${USER_ID}:${GROUP_ID} "${LOCAL_OUTPUT_BUILD_CONTEXT}"

  cp /etc/localtime "${LOCAL_OUTPUT_BUILD_CONTEXT}/"
  # 準備鏡像構建所需文件
  cp build/build-image/Dockerfile "${LOCAL_OUTPUT_BUILD_CONTEXT}/Dockerfile"
  cp build/build-image/rsyncd.sh "${LOCAL_OUTPUT_BUILD_CONTEXT}/"
  dd if=/dev/urandom bs=512 count=1 2>/dev/null | LC_ALL=C tr -dc 'A-Za-z0-9' | dd bs=32 count=1 2>/dev/null > "${LOCAL_OUTPUT_BUILD_CONTEXT}/rsyncd.password"
  chmod go= "${LOCAL_OUTPUT_BUILD_CONTEXT}/rsyncd.password"

  kube::build::update_dockerfile
  kube::build::set_proxy
  # 構建鏡像
  kube::build::docker_build "${KUBE_BUILD_IMAGE}" "${LOCAL_OUTPUT_BUILD_CONTEXT}" 'false'
  ...
  # 構建數據卷鏡像,注意 ensure 這個詞~數據卷鏡像是能夠複用的
  kube::build::ensure_data_container
  # 同步 kubernetes 源代碼到數據卷鏡像
  kube::build::sync_to_container
}

k8s 構建過程當中使用瞭如下幾種容器:學習

  • 數據卷容器:存儲 k8s 源代碼,其它容器啓動時經過 --volume-from 共享數據卷
  • rsyncd 容器:運行 rsyncd 服務(一種文件同步服務),將 k8s 源代碼從 host 同步到數據卷容器中
  • 構建容器:運行構建命令

源代碼同步

上文說到 k8s 構建的時候會啓動一個容器運行 rsyncd 服務,將 k8s 源代碼同步到數據卷容器,那麼源代碼碼會被同步到哪裏呢?ui

# kubernete/build/common.sh
function kube::build::sync_to_container() {
  kube::log::status "Syncing sources to container"

  kube::build::start_rsyncd_container

  kube::build::rsync \
    --delete \
    --filter='H /.git' \
    --filter='- /.make/' \
    --filter='- /_tmp/' \
    --filter='- /_output/' \
    --filter='- /' \
    --filter='H zz_generated.*' \
    --filter='H generated.proto' \
    "${KUBE_ROOT}/" "rsync://k8s@${KUBE_RSYNC_ADDR}/k8s/"
}

kube::build::rsync 方法將 KUBE_ROOT 目錄下的源代碼同步到 k8s@${KUBE_RSYNC_ADDR}/k8s/命令行

查看 rsync 配置文件能夠知道 k8s 這個虛擬目錄對應的實際目錄

# kubernetes/build/build-image/rsyncd.sh
...
VOLUME=${HOME}

cat <<EOF >"${CONFFILE}"
pid file = ${PIDFILE}
use chroot = no
log file = /dev/stdout
reverse lookup = no
munge symlinks = no
port = 8730
[k8s]
  numeric ids = true
  $USER_CONFIG
  hosts deny = *
  hosts allow = ${ALLOW} ${ALLOW_HOST-}
  auth users = k8s
  secrets file = ${SECRETS}
  read only = false
  path = ${VOLUME} <-- k8s 對應的路徑 ${VOLUME} = ${HOME}
  filter = - /.make/ - /_tmp/
EOF

這個 HOME 變量通常指向 用戶主目錄,可是從 go語言工程目錄結構 來看 HOME 應該指向相似 $GOPATH/src/k8s.io/kubernetes 的目錄,因此經驗和直覺告訴咱們確定有什麼地方設置了 HOME 變量,經過搜索源代碼,證明確實如此

# kubernetes/build/build-image/Dockerfile
...
ENV HOME /go/src/k8s.io/kubernetes
WORKDIR ${HOME}
...

總結

經過分析 k8s 構建系統,能夠學習像 Google 這樣的大廠是如何規劃大型軟件工程結構,構建,發佈

相關文章
相關標籤/搜索