云原生应用管理:原理与实践
上QQ阅读APP看书,第一时间看更新

4.2.1 prepareRelease

prepareRelease函数在接收客户端传递过来的参数后,首先进行一些预处理,部分代码如下所示。


func (s *ReleaseServer) prepareRelease(req *services.InstallReleaseRequest) (*release.Release, error) {
  if req.Chart == nil {
    return nil, errMissingChart
  }
  // 这里会检查用户执行的Release名称是否唯一,如果是自动生成的,会自动保证该名称的唯一性
  // 如果名称是用户指定的,这里会检查集群是否含有重名的Release
  name, err := s.uniqName(req.Name, req.ReuseName)
  // 检查客户端和服务端之间的兼容性,判断客户端、服务端以及ApiServer是否兼容
  caps, err := capabilities(s.clientset.Discovery())
  // 每一个Release默认都有一个版本号,这里就是第一个版本号
  revision := 1
  ts := timeconv.Now()
  options := Chartutil.ReleaseOptions{
    Name:      name,
    Time:      ts,
    Namespace: req.Namespace,
    Revision:  revision,
    IsInstall: true,
  }
  // 将传入的value进行渲染,组成新的values.yaml
  valuesToRender, err := Chartutil.ToRenderValuesCaps(req.Chart, req.Values, options, caps)
  // 分离出安装资源、Hooks资源,以及将当前集群的ApiServer信息填入结构体,为下一步构造安装结构做铺垫
  hooks, manifestDoc, notesTxt, err := s.renderResources(req.Chart, valuesToRender, req.SubNotes, caps.APIVersions)
  
  // 该结构体就是最终会存储的结构体,将需要安装的信息、Hooks信息和状态等内容进行初始化
  rel := &release.Release{
    Name:      name,
    Namespace: req.Namespace,
    Chart:     req.Chart,
    Config:    req.Values,
    Info: &release.Info{
      FirstDeployed: ts,
      LastDeployed:  ts,
      Status:        &release.Status{Code: release.Status_PENDING_INSTALL},
      Description:   "Initial install underway", // Will be overwritten.
    },
    Manifest: manifestDoc.String(),
    Hooks:    hooks,
    Version:  int32(revision),
  }
  return rel, nil

·首先检查当前Release名称是否是集群唯一,这是Release唯一性的标志,如果没有指定Relense名称,那么就创建一个全集群唯一的名称。

·检查客户端、服务端、Kubernetes ApiServer的版本兼容性。

·初始化ReleaseOptions结构体,填入名称、版本号、命名空间等信息。

·ToRenderValuesCaps将手动传递的参数和默认已经存在的values渲染到一起。

·renderResources将上一步构建的信息和Kubernetes ApiServer等信息合并在一起,同时分离出安装Chart Yaml信息和hooks等。

·拼接出Release对象,真正开始进入安装步骤。