Kubernetes 由 Golang 编写,Golang 社区提出了 Standard Go Project Layout 方案,以对 Golang 项目的目录结构进行规范划分。
根据 Standard Go Project Layout 方案,我们对标一下 Kubernetes Project Layout 的设计。
由于 Kubernetes 项目全球开发者众多,这导致早期的代码包较多,尤其是 kube-apiserver 组件,其内部所引用的代码包特别多。随着 Kubernetes 系统版本的迭代,逐渐将部分包进行了合并,其中 staging/ 目录为核心包暂存目录,该目录下的核心包多以软连接的方式链接到 vendor/k8s.io 目录。
Kubernetes系统组件较多,各组件的代码入口 main 结构设计风格高度一致,我们以核心组件为例,命令示例如下:
$ tree cmd/ -L 2
cmd/
├── BUILD
├── OWNERS
├── kube-apiserver
│ ├── BUILD
│ ├── OWNERS
│ ├── apiserver.go
│ └── app
├── kube-controller-manager
│ ├── BUILD
│ ├── OWNERS
│ ├── app
│ └── controller-manager.go
├── kube-proxy
│ ├── BUILD
│ ├── app
│ └── proxy.go
├── kube-scheduler
│ ├── BUILD
│ ├── OWNERS
│ ├── app
│ └── scheduler.go
├── kubectl
│ ├── BUILD
│ ├── OWNERS
│ └── kubectl.go
└── kubelet
├── BUILD
├── OWNERS
├── app
└── kubelet.go
每个组件的初始化过程也非常类似:
main 中定义了进程运行的周期,包括从进程启动、运行到退出的过程。以 kube-apiserver 组件为例,kube-apiserver 初始化过程如下图所示:
- rand.Seed:组件中的全局随机数生成对象。
- app.NewCommand:实例化命令行参数。通过 flags 对命令行参数进行解析并存储至 Options 对象中。
- logs.InitLogs:实例化日志对象,用于日志管理。
- command.Execute:组件进程运行的逻辑。运行前通过 Complete 函数填充默认参数,通过 Validate 函数验证所有参数,最后通过 Run 函数持久运行。只有当进程收到退出信号时,进程才会退出。