k8s :构建系统

前端之家收集整理的这篇文章主要介绍了k8s :构建系统前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

前言

大型软件(linux,android .etc)一般都有自己的构建系统,k8s 也不例外,本文简要介绍 k8s 构建系统

构建流程

release

以 quick-release 为例,在命令行执行以下命令

  1. # make quick-release

make 在源代码根目录 Makefile 文件中定位到 quick-release 目标,该目标的动作是执行 build/release.sh 脚本

  1. # kubernetes/Makefile
  2. .PHONY: release-skip-tests quick-release
  3. ifeq ($(PRINT_HELP),y)
  4. release-skip-tests quick-release:
  5. @echo "$$RELEASE_SKIP_TESTS_HELP_INFO"
  6. else
  7. release-skip-tests quick-release: KUBE_RELEASE_RUN_TESTS = n
  8. release-skip-tests quick-release: KUBE_FASTBUILD = true
  9. release-skip-tests quick-release:
  10. build/release.sh <--- 执行 kubernetes/build/release.sh
  11. endif

release.sh 将构建过程拆分成一个个步骤,每个步骤对应一个 shell function

  1. # kubernetes/build/release.sh
  2. ...
  3. kube::build::verify_prereqs
  4. kube::build::build_image
  5. kube::build::run_build_command make cross
  6. ...
  7. kube::build::copy_output
  8. kube::release::package_tarballs

verify_prereqs 对构建环境进行检查,比如是否缺少一些工具软件
build_image 创建构建需要的 docker 镜像 ???
run_build_command make cross 启动容器,运行 make cross
copy_output,package_tar 处理构建生成的各个文件

这里比较有意思的是 k8s 使用 docker 容器进行构建,可能是为了交叉编译吧

构建镜像

kube::build::build_image 方法构建基础镜像,同步 kubernetes 源代码到 data container(数据卷容器)

  1. function kube::build::build_image() {
  2. mkdir -p "${LOCAL_OUTPUT_BUILD_CONTEXT}"
  3. # Make sure the context directory owned by the right user for syncing sources to container.
  4. chown -R ${USER_ID}:${GROUP_ID} "${LOCAL_OUTPUT_BUILD_CONTEXT}"
  5.  
  6. cp /etc/localtime "${LOCAL_OUTPUT_BUILD_CONTEXT}/"
  7. # 准备镜像构建所需文件
  8. cp build/build-image/Dockerfile "${LOCAL_OUTPUT_BUILD_CONTEXT}/Dockerfile"
  9. cp build/build-image/rsyncd.sh "${LOCAL_OUTPUT_BUILD_CONTEXT}/"
  10. 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"
  11. chmod go= "${LOCAL_OUTPUT_BUILD_CONTEXT}/rsyncd.password"
  12.  
  13. kube::build::update_dockerfile
  14. kube::build::set_proxy
  15. # 构建镜像
  16. kube::build::docker_build "${KUBE_BUILD_IMAGE}" "${LOCAL_OUTPUT_BUILD_CONTEXT}" 'false'
  17. ...
  18. # 构建数据卷镜像,注意 ensure 这个词~数据卷镜像是可以复用的
  19. kube::build::ensure_data_container
  20. # 同步 kubernetes 源代码到数据卷镜像
  21. kube::build::sync_to_container
  22. }

k8s 构建过程中使用了以下几种容器:

  • 数据卷容器:存储 k8s 源代码,其它容器启动时通过 --volume-from 共享数据卷
  • rsyncd 容器:运行 rsyncd 服务(一种文件同步服务),将 k8s 源代码从 host 同步到数据卷容器中
  • 构建容器:运行构建命令

代码同步

上文说到 k8s 构建的时候会启动一个容器运行 rsyncd 服务,将 k8s 源代码同步到数据卷容器,那么源代码码会被同步到哪里呢?

  1. # kubernete/build/common.sh
  2. function kube::build::sync_to_container() {
  3. kube::log::status "Syncing sources to container"
  4.  
  5. kube::build::start_rsyncd_container
  6.  
  7. kube::build::rsync \
  8. --delete \
  9. --filter='H /.git' \
  10. --filter='- /.make/' \
  11. --filter='- /_tmp/' \
  12. --filter='- /_output/' \
  13. --filter='- /' \
  14. --filter='H zz_generated.*' \
  15. --filter='H generated.proto' \
  16. "${KUBE_ROOT}/" "rsync://k8s@${KUBE_RSYNC_ADDR}/k8s/"
  17. }

kube::build::rsync 方法将 KUBE_ROOT 目录下的源代码同步到 k8s@${KUBE_RSYNC_ADDR}/k8s/

查看 rsync 配置文件可以知道 k8s 这个虚拟目录对应的实际目录

  1. # kubernetes/build/build-image/rsyncd.sh
  2. ...
  3. VOLUME=${HOME}
  4.  
  5. cat <<EOF >"${CONFFILE}"
  6. pid file = ${PIDFILE}
  7. use chroot = no
  8. log file = /dev/stdout
  9. reverse lookup = no
  10. munge symlinks = no
  11. port = 8730
  12. [k8s]
  13. numeric ids = true
  14. $USER_CONFIG
  15. hosts deny = *
  16. hosts allow = ${ALLOW} ${ALLOW_HOST-}
  17. auth users = k8s
  18. secrets file = ${SECRETS}
  19. read only = false
  20. path = ${VOLUME} <-- k8s 对应的路径 ${VOLUME} = ${HOME}
  21. filter = - /.make/ - /_tmp/
  22. EOF

这个 HOME 变量一般指向 用户主目录,但是从 go语言工程目录结构 来看 HOME 应该指向类似 $GOPATH/src/k8s.io/kubernetes 的目录,所以经验和直觉告诉我们肯定有什么地方设置了 HOME 变量,通过搜索代码,证实确实如此

  1. # kubernetes/build/build-image/Dockerfile
  2. ...
  3. ENV HOME /go/src/k8s.io/kubernetes
  4. WORKDIR ${HOME}
  5. ...

总结

通过分析 k8s 构建系统,可以学习像 Google 这样的大厂是如何规划大型软件工程结构,构建,发布

猜你在找的Go相关文章