此前文章猪齿鱼 Agent——基于GitOps的云原生持续交付模型介绍了Choerodon Agent基于helm2版本在猪齿鱼平台持续交付部署流水线中的作用以及实现原理。

现在最新helm版本已经到helm3,继续使用helm2会面临着如下问题:

  1. helm2版本使用的k8s api较老,不利于Choerodon Agent对k8s高版本进行支持
  2. helm2架构是client-server架构。其中tiller-pod需要高集群权限,不方便集群中权限管理。同时在Choerodon Agent这边又属于客户端,出现问题后不方便进行调试

因此Choerodon Agent需要支持helm3版本,同时迁移helm2版本下安装的实例。

helm2与helm3区别

  1. tiller被删除

如图所示,helm2中部署Release需要经过tiller-pod,但是在helm3就直接通过kubeconfig部署实例

  1. helm2中Release是全局资源,在helm3中Release存储在各自的命名空间

  2. Values支持JSON Schema校验器,自动检查所有输入的变量格式

  3. 移除了用于本地临时搭建Chart Repository的helm serve 命令

  4. helm install 不再默认生成一个Release的名称,除非指定了–generate-name

  5. Helm Cli个别更名

    helm2到helm3的迁移

helm2到helm3的迁移包括如下步骤:

  • helm2的配置迁移

  • helm2的release迁移

  • 清除helm2的配置、release数据以及Tileer deployment

    使用helm-2to3进行数据迁移

安装2to3插件

helm3 plugin install https://github.com/helm/helm-2to3

插件特性

支持功能:

  • 迁移helm2的配置

  • 迁移helm2的releases

  • 清除helm2的配置,rel ease 数据以及Tiller deployment

    迁移helm2的配置

首先需要迁移helm2的配置和数据文件夹,包括如下内容:

  • Chart starters
  • Repositories
  • Plugins

通过如下命令开始迁移:

helm3 2to3 move config

迁移helm2的实例

通过如下命令开始迁 移:

helm3 2to3 convert [ReleaseName]

清除helm2的数据

如果迁移完成后没有出现错误,就可以通过 此条命令清楚helm2的数据,包括如下内容:

  • Configuration(Helm homedirectory)
  • v2release data
  • Tiller deployment

通过如下命令开始清楚数据:

helm3 2to3 cleanup

注意:如果运行清楚命令,所有被删掉的 数据都不能恢复。所以没必要的话,还是将以前的数据保留下来

Choerodon Agent的升级处理

helm2到helm3的变动非常大,所以Choerdon Agent调用helm也发生巨大变化。其中有两部分需要进行修改

  1. helm客户端获取、安装、升级、卸载实例需要重构

  2. 需要迁移helm2安装的实例到helm3,不然升级后Choerodon Agent无法继续管理以前的实例

    helm客户端重构

在helm2的时候,Choerodon Agent直接将helm源代码作为Choerodon Agent部分代码进行使用。而在helm3,直接对helm3的源码进行二次开发,然后通过依赖引用。这样做的好处是将helm代码与Choerodon Agent代码解藕,有利于helm相关代码更新升级。

在Choerodon Agent里面,安装或升级实例会对Chart中的资源添加Choeordon Agent相关的label,比如choerodon.io/release、choeroodn.io/command等等,所以helm3的二次开发主要是添加资源label,以安装(Install)操作举例,其他操作(升级、删除)大同小异。

1. 修改模块名称

进行二次开发,首先需要修改该项目的模块名称,该步骤也是最麻烦的,因为修改后需要修改代码里面所有的包引用路径

如图所示,go.mod文件中的module进行如下修改

github.com/choerodon/helm => github.com/open-hand/helm

然后代码文件中修改引用路径

2. 加入添加label逻辑

通过断点调试,找到helm3安装逻辑由open-hand-helm/pkg/action/install.go::Run()方法实现,在该方法中插入添加标签步骤。下面省略不必要的代码

func (i *Install) Run(chrt *chart.Chart, vals map[string]interface{}, valsRaw string) (*release.Release, error) {// ···省略的步骤是helm对chart包进行校验渲染,生成k8s对象,并保存到resources变量中// 以下为修改的内容,遍历resources对象,添加Labelfor _, r := range resources {err = action.AddLabel(i.ImagePullSecret, i.Command, i.AppServiceId, r, i.ChartVersion, i.ReleaseName, i.ChartName, i.AgentVersion, "", i.TestLabel, i.IsTest, false, nil)if err != nil {return nil, err}}// ···省略的步骤是helm将resources更新到集群中
}

接下来看看open-hand-helm/pkg/agent/action/label.go::AddLabel()方法

func AddLabel(imagePullSecret []v1.LocalObjectReference,command int64,appServiceId int64,info *resource.Info,version, releaseName, chartName, agentVersion, testLabel, namespace string,isTest bool,isUpgrade bool,clientSet *kubernetes.Clientset) error {// 该方法内容比较多,不在这里展示,具体可参考源代码。其作用就是根据不同的资源类型添加不同的Label值
}

3. Choerodon Agent 引用二次开发的helm库

参照helm3源码install命令的初始化方式,将分为以下几个步骤

  1. 获取helm配置信息

    // 获取helm的配置信息
    func getCfg(namespace string) (*action.Configuration, *cli.EnvSettings) {
    settings := cli.New()
    settings.SetNamespace(namespace)
    actionConfig := &action.Configuration{}
    helmDriver := os.Getenv("HELM_DRIVER")
    if err := actionConfig.Init(settings.RESTClientGetter(), settings.Namespace(), helmDriver, debug); err != nil {log.Fatal(err)
    }
    return action config, settings
    }
  2. 创建Install操作对象

       installClient := action.NewInstall(cfg,chartPathOptions,request.Command,request.ImagePullSecrets,request.Namespace,request.ReleaseName,request.ChartName,request.ChartVersion,request.AppServiceId,envkube.AgentVersion,"",false)
  3. 校验chart包并生成values值 ```go ··· valueOpts := getValueOpts(request.Values) p := getter.All(envSettings) vals, err := valueOpts.MergeValues(p) if err != nil { return nil, err }

// Check chart dependencies to make sure all are present in /charts chartRequested, err := loader.Load(cp) if err != nil { return nil, err }

validInstallableChart, err := isChartInstallable(chartRequested) if !validInstallableChart { return nil, err } ···


4. 调用安装方法,执行安装命令
```go
···
responseRelease, err := installClient.Run(chartRequested, vals, request.Values)
···

具体的逻辑可查看choerodon-cluster-agent/pkg/helm/helm.go::InstallRelease()

总结来说就是以下4个步骤:

获取配置对象->生成操作对象->校验chart包并生成values值->执行操作

对已安装的Release进行迁移

对Release的迁移需要用到helm迁移工具,该工具是直接集成到Choerodon Agent项目代码中的。

在Choeordon Agent的启动逻辑中,接收到的第一个命令是agent_init。该命令负责命名空间的创建和监听,因此Release迁移逻辑也就放到这一步操作中。

整个流程如下图所示:

  1. 首先从choerodon-cluster-agent/pkg/command/agent/agent.go::InitAgent()方法开始 ```go func InitAgent(opts *commandutil.Opts, cmd *model.Packet) ([]*model.Packet, *model.Packet) { // ···省略的步骤是处理初始化的参数

// 下面的代码开始对需要监听的命名空间进行初始化 for _, envPara := range agentInitOpts.Envs { nsList = append(nsList, envPara.Namespace) err := createNamespace(opts, envPara.Namespace, envPara.Releases) if err != nil { return nil, commandutil.NewResponseError(cmd.Key, cmd.Type, err) } }

// ···省略的步骤是开启gitops监听、controller监听、以及返回集群信息 }

2. 在[choerodon-cluster-agent/pkg/command/agent/agent.go::createNamespace()](https://github.com/open-hand/choerodon-cluster-agent/blob/master/pkg/command/agent/agent.go#L196)开始初始化命名空间
```go
func createNamespace(opts *commandutil.Opts, namespaceName string, releases []string) error {ns, err := opts.KubeClient.GetKubeClient().CoreV1().Namespaces().Get(namespaceName, metav1.GetOptions{})if err != nil {// 如果命名空间不存在的话,则创建if errors.IsNotFound(err) {_, err = opts.KubeClient.GetKubeClient().CoreV1().Namespaces().Create(&corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name:   namespaceName,Labels: map[string]string{model.HelmVersion: "helm3"},},})return err}return err}labels := ns.Labelsannotations := ns.Annotations// 如果命名空间存在,则检查labels标签if _, ok := labels[model.HelmVersion]; !ok {// 开始迁移实例return update(opts, releases, namespaceName, labels, annotations)}return nil
}
  1. 在choerodon-cluster-agent/pkg/command/agent/agent.go::update()中迁移实例 ```go func update(opts *commandutil.Opts, releases []string, namespaceName string, labels, annotations map[string]string) error { releaseCount := len(releases) upgradeCount := 0

    // 此处不对choerodon命名空间下的实例进行迁移处理 // 安装agent的时候,会直接创建choerodon命名空间而不打上 model.HelmVersion 标签 // 然后用户直接创建pv,会导致choerodon没有标签也纳入环境管理(如果通过agent安装了prometheus或者cert-manager就会出现问题) // 所以直接默认choeordon不需要进行helm迁移 if namespaceName != “choerodon” && releaseCount != 0 { for i := 0; i < releaseCount; i++ { getReleaseRequest := &helm.GetReleaseContentRequest{ ReleaseName: releases[i], Namespace: namespaceName, }

        // 查看该实例是否helm3管理,如果是upgradeCount加1,如果不是,进行迁移操作然后再加1_, err := opts.HelmClient.GetRelease(getReleaseRequest)if err != nil {// 实例不存在有可能是实例未迁移,尝试迁移操作if strings.Contains(err.Error(), helm.ErrReleaseNotFound) {helm2to3.RunConvert(releases[i])if opts.ClearHelmHistory {helm2to3.RunCleanup(releases[i])}upgradeCount++}} else {// 实例存在表明实例被helm3管理,尝试进行数据清理,然后upgradeCount加1if opts.ClearHelmHistory {helm2to3.RunCleanup(releases[i])}upgradeCount++}
    }if releaseCount != upgradeCount {return fmt.Errorf("env %s : failed to upgrade helm2 to helm3 ", namespaceName)
    }

    }

// 添加label if labels == nil { labels = make(map[string]string) }

labels[model.HelmVersion] = "helm3"
_, err := opts.KubeClient.GetKubeClient().CoreV1().Namespaces().Update(&corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name:        namespaceName,Labels:      labels,Annotations: annotations,},
})
return err

} ``` 由此完成了Choerodon Agent对Release的迁移逻辑

常见问题解决

  1. 有时候Choerodon Agent重启后,会出现启动失败的问题,查看日志有实例迁移失败,tiller-pod不存在错误

该问题可能是实例迁移完成后,命名空间的label添加失败。解决办法是手动给该命名空间添加”choerodon.io/helm-version”:“helm3” 标签,以此表示该命名空间的实例迁移已完成,不需要再次迁移

  1. 修改资源后,部署失败,且错误信息提示为超时

首先在devops的环境层检查三个commit值是否一致,有如下情况:

  • 前两个commit不一致:说明devops在gitlab的webhook回调处理上有问题,应该从gitlab的webhook执行记录以及devops日志进行排查
  • 前两个一致,第三个落后于前两个:说明devops同步相关gitops操作已完成,但是在Choerodon Agent同步gitops库上出了问题。

这时先保留一份日志,供开发人员查找分析,然后kubectl -n choerodon delete [podName]删除Choerodon Agent进行重启。

如果重启完成后,Choerodon Agent仍然没有同步gitops库,这时应该考虑该环境库在gitlab的密钥是否与devops数据库中存储的一致。先在本地验证能否通过该密钥拉取gitops库。如果不行,重置该gitops库的密钥,最好的办法就是删掉该环境重新创建。如果可以,那么说明Choerodon Agent与gitlab连接有问题,检查gitlab的端口开发情况以及Choerodon Agent与外部网络的访问连接情况

  • 三个commit都一致,但是实例部署失败,且提示访问chart仓库超时:这个问题经常遇到。排查后发现是Choerodon Agent与Chart Museum网络连接有问题

本文由猪齿鱼技术团队原创,转载请注明出处:猪齿鱼官网

关于猪齿鱼

猪齿鱼Choerodon全场景效能平台,提供体系化方法论和协作、测试、DevOps及容器工具,帮助企业拉通需求、设计、开发、部署、测试和运营流程,一站式提高管理效率和质量。从团队协同到DevOps工具链、从平台工具到体系化方法论,猪齿鱼全面满足协同管理与工程效率需求,贯穿端到端全流程,助力团队效能更快更强更稳定。戳此处试用猪齿鱼

全场景效能平台猪齿鱼 Agent——helm组件升级相关推荐

  1. 如何一站式快速构建企业全场景数据库管理平台?

    简介:Gartner 的报告显示预计到2022年将有75%数据库将采用云数据库,与此同时,IDC预计到2024年传统部署数据库市场将达到13亿美元,企业数字化转型升级,积极拥抱开源.云原生数据库成为重 ...

  2. 产品解读 | 敏捷版数据库场景 一站式快速构建企业全场景数据库管理平台

    简介:Gartner 的报告显示预计到2022年将有75%数据库将采用云数据库,与此同时,IDC预计到2024年传统部署数据库市场将达到13亿美元,企业数字化转型升级,积极拥抱开源.云原生数据库成为重 ...

  3. 猪齿鱼数智化效能平台亮相 2021 中国开源年会

    10月30日至31日,由开源社主办.业界最具影响力的开源年度盛会 2021第六届中国开源年会 (COSCon'21) 圆满举办.本次大会以"开心开源"为主题,采取线上线下相结合的形 ...

  4. 昇思MindSpore全场景AI框架 1.6版本,更高的开发效率,更好地服务开发者

    本文分享自华为云社区<昇思MindSpore全场景AI框架 1.6版本,更高的开发效率,更好地服务开发者>,作者: 技术火炬手. 全新的昇思MindSpore全场景AI框架1.6版本已发布 ...

  5. 从818发烧购物节,看苏宁的全场景零售

    一年一度的818发烧购物节来了. 7月25日, 818发布会现场,苏宁易购总裁侯恩龙首次全面解读场景互联时代,苏宁全场景零售的最新探索和迄今为止最全面的布局. 在零售变革剧烈,消费趋势多元化的今天,& ...

  6. 经纬恒润AUTOSAR全面适配芯驰车规芯片,联合打造全场景国产解决方案

    近日,经纬恒润与车规芯片企业芯驰科技共同宣布,经纬恒润AUTOSAR系列产品已全面适配芯驰全场景车规芯片,助力芯驰中央网关芯片"网之芯"G9.智能座舱芯片"舱之芯&quo ...

  7. Kubernetes 弹性伸缩全场景解读(五) - 定时伸缩组件发布与开源

    作者| 阿里云容器技术专家刘中巍(莫源) 导读:Kubernetes弹性伸缩系列文章为读者一一解析了各个弹性伸缩组件的相关原理和用法.本篇文章中,阿里云容器技术专家莫源将为你带来定时伸缩组件  kub ...

  8. 构建全渠道零售平台及营销场景解读

    阅读原文 1.中国"新零售"发展趋势与机遇 根据阿里研究院与BCG合作的<中国消费新趋势>研究报告显示,在未来5年, "新零售"将激活总共六万亿美元 ...

  9. 重磅!全场景覆盖、全方位智能感知的视联网平台来了

    在云计算.人工智能.物联网等技术的助推下,视频无处不在.我们看到,在不同应用场景中,海量视频设备和视频数据通过互联互通的方式形成强大的视联网,在智慧城市.智慧交通.工业能源.智慧零售等诸多领域中发挥着 ...

  10. cat全链路监控_谛听全链路监控平台实践与思考

    一.项目背景 近几年,信也科技的研发技术伴随着业务的快速增长逐步演化为微服务化的分布式体系架构,但随之带来的系统间的上下游依赖关系的复杂度也呈指数级上升,已有的烟囱式的监控产品(CAT.ELK等)存在 ...

最新文章

  1. arduino雨滴传感器原理_Arduino酸度计(PH计)
  2. Python 3 os.walk使用详解
  3. 用c语言实现随机无向图的生成,C ++程序为给定数量的边生成随机无向图
  4. 李炎恢+php+下载,李炎恢thinkphp视频教程
  5. 小技巧!CSS 整块文本溢出省略特性探究
  6. spring集合的注入
  7. 00_python安装与配置(mac)
  8. opython3l_python之 数据类型判定与类型转换
  9. spring boot 使用 websocket tomcat刚启动就关闭到问题
  10. 大熊君学习html5系列之------Online Offline(在线状态检测)
  11. Optional Interview with Benny the Irish Polyglot abo---coursera课程Learn how to learn
  12. 修改Solaris系统时间
  13. 360粉碎文件可以恢复吗,如何恢复360强力删除的文件
  14. 9月18日博文阅读数异常波动公告
  15. debian中双网卡上内外网的设置方法
  16. 到底是人玩了游戏,还是游戏玩了人?----随笔心情
  17. python伪原创工具开发_现在有哪些好用的伪原创工具?
  18. 互联网产品上线前,做些什么——产品、开发、测试的视角(转载)
  19. Faker生成测试数据
  20. 激活win10管理员身份

热门文章

  1. Android打码函数,Android 马赛克(Mosaics)效果
  2. 朴素贝叶斯算法实现新闻分类(Sklearn实现)
  3. png图片怎么缩小kb?压缩png图片怎么弄?
  4. Vue router 默认加载 views 文件夹下全部vue文件
  5. 马克思对“货币之谜”的 历史唯物主义解答
  6. 产品设计 - AARRR模型,增长和变现
  7. php计算距离商家距离,php 计算3公里内所以用户的距离
  8. 通过路由器管理界面刷openwrt
  9. 复习Python爬取必应的壁纸
  10. 美国大学网站一网打尽