工作原理 ¶
1) CLI ¶
目前,kops
中的一切都由命令行界面驱动。我们使用 cobra 来定义我们所有的命令行 UX。
kOps 的所有 CLI 代码都可以在 /cmd/kops
链接 中找到。
例如,如果你想找到 kops create cluster
的入口点,可以查看 /cmd/kops/create_cluster.go
。在那里你会找到一个名为 RunCreateCluster()
的函数。那就是该命令的入口点。
2) 存储 ¶
我们有一种与存储进行交互的抽象方式,称为 clientset
。这是一种与 kops
的远程存储进行交互的抽象方式。这通常被称为 kops
的 **状态存储**。
我们可以通过 util.Factory
结构访问它,如下所示
func RunMyCommand(f *util.Factory, out io.Writer, c *MyCommandOptions) error {
clientset, _ := f.Clientset()
cluster, _ := clientset.Clusters().Get(clusterName)
fmt.Println(cluster)
}
可用的 Clientset 函数是
Create()
Update()
Get()
List()
3) API ¶
a) 集群规范 ¶
kops
API 是 Go 代码中结构成员的定义,可以在 这里 找到。kops
API **不**与命令行界面匹配(这是设计使然)。我们使用原生 Kubernetes API 机制来管理 kops
API 的版本控制。
API 的基础级别结构是 api.Cluster{}
,它定义在 这里。顶级结构包含有关对象的一些元信息,例如类型和版本,而集群本身的主要数据可以在 cluster.Spec
中找到。
需要注意的是,API 成员是 Kubernetes 集群的表示。这些值存储在上面提到的 kops
**状态存储** 中,以便以后使用。按照设计,kOps 不会在状态存储中存储有关云状态的信息,如果它可以从查看云的实际状态中推断出来,则会这样做。
有关 API 的更多信息,请查看 这里。
b) 实例组 ¶
为了让 kops
创建任何服务器,我们需要定义实例组。这些是一系列指向 kops.InstanceGroup
结构的指针。
var instanceGroups []*kops.InstanceGroup
每个实例组代表云中的一组实例。每个实例组 (或 IG) 定义有关实例组的值,例如它们的大小、卷信息等。定义也可以在 /pkg/apis/kops/instancegroup.go
文件中找到,这里。
4) Cloudup ¶
a) ApplyClusterCmd
¶
在用户构建出有效的 api.Cluster{}
和有效的 []*kops.InstanceGroup
之后,他们就可以开始与 kops
中的核心逻辑进行交互。
用户可以构建一个 cloudup.ApplyClusterCmd
,定义在 这里,如下所示
applyCmd := &cloudup.ApplyClusterCmd{
Cluster: cluster,
Clientset: clientset,
TargetName: "target", // ${GOPATH}/src/k8s.io/kops/upup/pkg/fi/cloudup/target.go:19
OutDir: c.OutDir,
DryRun: isDryrun,
MaxTaskDuration: 10 * time.Minute, // ${GOPATH}/src/k8s.io/kops/upup/pkg/fi/cloudup/apply_cluster.go
InstanceGroups: instanceGroups,
}
现在 ApplyClusterCmd
已经填充完毕,我们可以尝试运行应用。
err = applyCmd.Run()
这就是我们进入 kops
逻辑 **核心** 的地方。起点可以在 这里 找到。根据上面 ApplyClusterCmd
中定义的指令,应用操作将根据提供的输入以不同的方式进行。
b) 验证 ¶
在 ApplyClusterCmd.Run()
函数内部,我们首先尝试通过验证操作来清理我们的输入。在函数的开头有很多示例,我们会在其中验证输入。
c) 云 ¶
cluster.Spec.CloudProvider
应该在之前已经填充,并且可以用来切换到构建我们的云,如 这里 所示。如果你想实现新的云实现,该接口定义在 这里,AWS 示例在 这里。
**注意** 就目前而言,FindVPCInfo()
函数是接口中定义的成员。这仅限于 AWS,最终会从接口中移除。现在,请将该函数实现为一个无操作函数。
d) 模型 ¶
模型是将模棱两可的集群规范(之前定义)映射到 **任务** 的东西。每个 **任务** 都是对云发起的 API 请求的表示。如果你打算实现新的云,一种选择是定义新的模型上下文类型,并为你的云对象构建自定义模型构建器。
现有的模型代码可以在 这里 找到。
一旦模型构建器定义好,如 这里 所示,代码就会自动调用。
在构建器内部,我们注意到每个构建器都有具体的逻辑。逻辑将决定需要调用哪些任务才能将资源应用到云。这些任务通过调用 AddTask()
函数添加,这里。
一旦模型构建器被调用,所有任务都应该被设置。
e) 任务 ¶
任务通常是单个 API 调用的表示。任务接口定义在 这里。
**注意** 对于像 AWS 这样的更高级的云,在执行定义在 这里 的任务的核心逻辑中,还有 Find()
和 Render()
函数。
5) Nodeup ¶
Nodeup 是一个独立的二进制文件,它负责引导 Kubernetes 集群。有一个 shell 脚本 这里 将引导 nodeup。AWS 实现使用 cloud-init
在实例上运行该脚本。所有新的云都需要找出在平台上引导 nodeup
的最佳实践。