前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >controller-manager学习三部曲之一:通过脚本文件寻找程序入口

controller-manager学习三部曲之一:通过脚本文件寻找程序入口

作者头像
程序员欣宸
发布2023-10-03 08:37:49
2810
发布2023-10-03 08:37:49
举报
文章被收录于专栏:实战docker实战docker
关于《controller-manager学习三部曲》
  • 《controller-manager学习三部曲》是欣宸原创的kubernetes深入学习系列之一,在前面的《client-go实战》系列中,咱们通过反复的实践,对controller的开发和使用已经很熟练了,接下来就该称热打铁去研究kubernetes的源码,了解它的controller是如何设计和实现的,这里面一定有很多值得学习的地方,掌握了这些,反过来又能对咱们自己开发controller有所帮助,所以,别犹豫啦,一起来看看kubernetes的controller吧
  • 整个《controller-manager学习三部曲》由以下三部分内容组成
  1. 寻找入口:kubernetes博大精深,那么多代码和脚本,如何找到controller-manager的代码,以及程序启动的入口?
  2. 源码分析:这个整个系列的核心,面对诸多controller,kubernetes如何做到这两件事情:第一,将启动命令中的各种flag(cobra中的flag)传递给各个controller,第二,创建和启动每个controller
  3. 典型controller:controller-manager只负责将controller启动,具体的controller功能是各不相同的,这里会挑一个典型的controller来学习
  • 注意:整个系列用的源码来自kubernetes的master分支,go版本是1.20
关于controller-manager
  • 下图是kube-system这个namespace下面所有pod的信息,黄色箭头所指即controller-manager,它负责诸多内置controller的创建和启动,还有就是从启动命令中搜集参数,以便各controller使用
在这里插入图片描述
在这里插入图片描述
本篇概览
  • 本文是《三部曲》的第一篇,咱们要从kubernetes源码中找到controller-manager的入口,以便后续的学习
  • controller-manager是个典型的go模块工程,所以结构和脚本也是咱们常见的格式(只不过内容多了些)
  • 本篇从Makefile入手开始分析,找到编译controller-manager的详细逻辑,没什么难度,只是几个脚本的阅读而已
编译文件
  • 执行make命令会用到Makefile文件,里面会调用hack/make-rules/build.sh
在这里插入图片描述
在这里插入图片描述
  • 打开build.sh,里面调用了kube::golang::build_binaries
在这里插入图片描述
在这里插入图片描述
  • 在golang.sh文件中查看kube::golang::build_binaries方法,下面摘取最重要的内容,可见构建用的参数来自KUBE_ALL_TARGETS这个全局变量,咱们先记住这个KUBE_ALL_TARGETS,然后继续看构建的逻辑
在这里插入图片描述
在这里插入图片描述
  • 这时候应该看到了build_binaries_for_platform,可见binaries的内容会被分别存入statics和nonstatics
代码语言:javascript
复制
kube::golang::build_binaries_for_platform() {
  # This is for sanity.  Without it, user umasks can leak through.
  umask 0022

  local platform=$1

  local -a statics=()
  local -a nonstatics=()
  local -a tests=()

  for binary in "${binaries[@]}"; do
    if [[ "${binary}" =~ ".test"$ ]]; then
      tests+=("${binary}")
      kube::log::info "    ${binary} (test)"
    elif kube::golang::is_statically_linked_library "${binary}"; then
      statics+=("${binary}")
      kube::log::info "    ${binary} (static)"
    else
      nonstatics+=("${binary}")
      kube::log::info "    ${binary} (non-static)"
    fi
  done
  • 然后调用build_some_binaries方法
代码语言:javascript
复制
  if [[ "${#statics[@]}" != 0 ]]; then
    build_args=(
      -installsuffix=static
      ${goflags:+"${goflags[@]}"}
      -gcflags="${gogcflags}"
      -asmflags="${goasmflags}"
      -ldflags="${goldflags}"
      -tags="${gotags:-}"
    )
    CGO_ENABLED=0 kube::golang::build_some_binaries "${statics[@]}"
  fi

  if [[ "${#nonstatics[@]}" != 0 ]]; then
    build_args=(
      ${goflags:+"${goflags[@]}"}
      -gcflags="${gogcflags}"
      -asmflags="${goasmflags}"
      -ldflags="${goldflags}"
      -tags="${gotags:-}"
    )
    kube::golang::build_some_binaries "${nonstatics[@]}"
  fi
  • 最终在build_some_binaries方法中完成编译构建
在这里插入图片描述
在这里插入图片描述
  • 至此,输入make后的大致流程算是知道了,接下来该回头看看那个重要的参数KUBE_SERVER_TARGETS了
关于KUBE_ALL_TARGETS
  • 前面曾经提到,构建参数来自KUBE_ALL_TARGETS,这里来看下这个变量里面是啥,定义在golang.sh文件中,如下所示,是由多个变量组成的
代码语言:javascript
复制
readonly KUBE_ALL_TARGETS=(
  "${KUBE_SERVER_TARGETS[@]}"
  "${KUBE_CLIENT_TARGETS[@]}"
  "${KUBE_TEST_TARGETS[@]}"
  "${KUBE_TEST_SERVER_TARGETS[@]}"
)
  • 选其中一个来看看,这里选KUBE_SERVER_TARGETS,可见是每个需要构建的模块的路径
代码语言:javascript
复制
kube::golang::server_targets() {
  local targets=(
    cmd/kube-proxy
    cmd/kube-apiserver
    cmd/kube-controller-manager
    cmd/kubelet
    cmd/kubeadm
    cmd/kube-scheduler
    vendor/k8s.io/component-base/logs/kube-log-runner
    vendor/k8s.io/kube-aggregator
    vendor/k8s.io/apiextensions-apiserver
    cluster/gce/gci/mounter
  )
  echo "${targets[@]}"
}

IFS=" " read -ra KUBE_SERVER_TARGETS <<< "$(kube::golang::server_targets)"
  • 现在终于清楚了,在编译构建kubernetes源码的时候,kube-controller-manager模块是用go install命令编译cmd/kube-controller-manager包下的源码生成的,也就是说这个服务的入口在下图位置
在这里插入图片描述
在这里插入图片描述
启动命令分析
  • 找到了程序的入口,还要了解启动服务时的参数,这样在阅读源码时,面对各种不同入参的处理,也能做到心里有数,找准关键代码去看
查看启动命令
  • 找个现成的kubernetes系统,看一下真正运行的controller-manager的启动命令是啥样的
  • 以我自己测试用的kubernetes环境为例,先查看pod名
代码语言:javascript
复制
kubectl get pods -n kube-system
NAME                           READY   STATUS    RESTARTS       AGE
coredns-78fcd69978-jztff       1/1     Running   6 (35d ago)    125d
coredns-78fcd69978-ts7gq       1/1     Running   6 (35d ago)    125d
etcd-hedy                      1/1     Running   6 (35d ago)    125d
kube-apiserver-hedy            1/1     Running   7 (35d ago)    125d
kube-controller-manager-hedy   1/1     Running   11 (30h ago)   125d
kube-proxy-2qx6k               1/1     Running   6              125d
kube-scheduler-hedy            1/1     Running   11 (30h ago)   125d
  • 可见controller-manager的pod名是kube-controller-manager-hedy,执行以下命令即可查看看pod的详细信息
代码语言:javascript
复制
kubectl describe pod kube-controller-manager-hedy -n kube-system
  • 上述命令会输出大量信息,这里只展示我们最关心的内容,即controller-manager的启动命令
代码语言:javascript
复制
    Command:
      kube-controller-manager
      --allocate-node-cidrs=true
      --authentication-kubeconfig=/etc/kubernetes/controller-manager.conf
      --authorization-kubeconfig=/etc/kubernetes/controller-manager.conf
      --bind-address=0.0.0.0
      --client-ca-file=/etc/kubernetes/pki/ca.crt
      --cluster-cidr=100.64.0.0/10
      --cluster-name=kubernetes
      --cluster-signing-cert-file=/etc/kubernetes/pki/ca.crt
      --cluster-signing-key-file=/etc/kubernetes/pki/ca.key
      --controllers=*,bootstrapsigner,tokencleaner
      --experimental-cluster-signing-duration=876000h
      --feature-gates=TTLAfterFinished=true,EphemeralContainers=true
      --kubeconfig=/etc/kubernetes/controller-manager.conf
      --leader-elect=true
      --port=0
      --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.crt
      --root-ca-file=/etc/kubernetes/pki/ca.crt
      --service-account-private-key-file=/etc/kubernetes/pki/sa.key
      --service-cluster-ip-range=10.96.0.0/22
      --use-service-account-credentials=true
  • 可见启动controller-manager的时候,kubernetes向其传递了大量的flag
  • 至此,本篇的任务已经完成,咱们找到了应用的入口,也清楚了启动时会大概传入哪些参数,在接下来的文章该一同去深入学习controller-manager的源码了
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 关于《controller-manager学习三部曲》
  • 关于controller-manager
  • 本篇概览
  • 编译文件
  • 关于KUBE_ALL_TARGETS
  • 启动命令分析
  • 查看启动命令
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档