本文转载自Rancher Labsdocker
不管你喜欢与否,你都不得不认可Helm是管理Kubernetes应用程序独一无二的工具,你甚至能够经过不一样的方式使用它。网络
在Helm的使用过程当中,咱们注意到有几个问题不断出现:架构
你是使用app文件保存它们仍是使用chart仓库?app
你是使用一个共享的chart或是为每一个服务维护一个chart?运维
我正在经过我以往在各类创业公司的经验来尝试解决这些问题,可是我也借鉴了大型公司的作法。分布式
如下是我要概述的几个方法:微服务
而后,我将介绍在决定这些选项时应该考虑的因素,例如依赖项差别和团队结构等。工具
在咱们一个项目中,咱们从一个用于部署多个服务的大型chart开始。它存储在ChartMuseum中,并由负责部署基础架构的人员进行维护。测试
若是你的各个服务在本质上十分相似,那么共享chart能够为你省去不少麻烦。这里咱们采用Helm维护者Josh Dolitsky在KubeCon 2019上描述的状况:spa
我最近在负责一个项目,这个项目包含9个微服务……我意识到它们几乎都是相同的HTTP监听服务。因此我决定仅仅构建一个helm chart来部署9个不一样的服务,为每一个服务作不一样的配置——仅为特定的服务设置一个新的docker标签。
在这种状况下,将Helm chart存储在ChartMuseum等chart仓库中是有意义的,由于只有值须要保存在这些特定服务的仓库中。
特定于服务的chart优点在于,你能够更改一项服务,而无需担忧会破坏另外一项服务。可是它们可能会致使重复的工做——若是你要更新通用配置,则必须在每一个chart中进行相同的更改。
是否须要在一个chart仓库中保存它们则是另外一个问题了。若是这些chart是特定于服务的,那么将它们存储在一块儿尚没有强有力的架构论证。固然,若是你有专门的人员或团队来维护全部的chart,一块儿存储多个特定于服务的chart一般会比较容易。
例如,与我一块儿工做的一位DevOps工程师,他在一个中心chart仓库中维护15种不一样的微服务chart。对于他而言,在同一个位置更新全部chart比向15个不一样的仓库提交拉取请求要容易得多。开发人员固然清楚如何更新chart,可是处理资源相关的设置显然更吸引他们。
对于基于微服务的应用程序来讲,特定于服务的chart是一个很好的选择。而当你将每一个chart与服务代码保存在同一仓库中时,使用特定于服务的chart则会更好。
若是你在服务仓库中存储Helm chart,那么能够更轻松地独立于其余项目持续部署服务。而且你能够将chart更新(例如添加新变量)与应用程序逻辑的更改一块儿提交,使其更易于识别和还原重大更改。
然而,本选项的优点取决于你所维护的微服务的数量。若是你的微服务数量正迈入两位数,那么这一选项的优点则没有那么明显,更多的是阻碍。若是你要处理很是同质的服务(如Josh Dolisky),则尤为如此。
通常状况下,有两个方面须要考虑:
若是你将你的chart和应用程序分开维护,它们的版本将彼此不一样。若是你在部署时遇到问题,而且须要重现致使该问题的条件,则须要肯定:a)服务版本;b)用于部署它的chart版本。你可能想要走捷径,使用“latest” chart来测试服务x.x.x,但这并非一个好想法,由于这样你将永远没法重现形成问题的确切条件。
那么,若是你常常须要更改的chart版本怎么办?是否是应该一块儿测试这些改动呢?
考虑到许多开发人员须要建立同一共享chart中的分支版本这一场景:
开发人员(图中的Edeltraud和Eberhardt)分别在不一样的分支中工做,而且想要在开发环境中测试他们的更改以及图表更改——因此他们还须要分支chart。同时,DevOps工程师在他的共享chart的分支中更新一些经常使用组件。
若是没有人将他们的chart更改更新到各个分支,那么就有可能破坏另外一个服务部署。
不久前,咱们正好遇到了这个问题。Chart维护者用一个新的条件块更新了共享chart。该语句检查了一个新的变量“foo”是否被设置为“启用”。然而,变量“foo”尚未在全部服务的值文件中定义。对于缺乏该变量的服务,部署中断了。不幸的是,当时chart中没有定义默认的回滚行为。
若是chart和代码位于同一个仓库中,而且能够在同一个分支中进行测试,则针对这些问题的测试将更加容易。
即便一开始彷佛是矫枉过正,咱们也会这样作。咱们的工做对象是不多有依赖项的服务。对于每一个服务,Helm chart只部署一个带有特定Docker标签的主容器。chart的名称和docker标签是经过变量传递进来的。尽管如此,咱们仍然避免了使用共享chart,而是选择在每一个服务仓库中放置单独的chart。
这主要是由于咱们只处理了四个服务。但咱们的开发人员也更喜欢掌控全部可以影响CI/CD的配置。然而状况并不是老是如此,因此如今是研究另外一个维度的好时机。
Chart维护的问题同时也取决于谁管理部署流程。
这里推荐另外一篇文章,由Helm维护者Matt Farina撰写的,在文章中他阐述了关于Helm正在尝试解决复杂性的话题。文章连接:
https://codeengineered.com/bl...
他阐明了必须处理Kubernetes复杂性的三个主要角色。为了清楚起见,我将对其内容进行一些解释,并将角色描述以下:
第一个和第三个角色你都能在公司里找到与其负责内容相符的职位,而Deployer这个角色则有些模糊,这个角色所负责的内容经常会被其余两个角色的人接管——这会影响你如何管理你的Helm chart。
如前所述,咱们的业务是为初创企业提供运维支持,这些企业每每须要快速扩大规模。咱们见过不少“很是规”的设置和分工。在早期阶段,App开发者可能会负责各类事情,有些人甚至会帮忙完成系统管理员的任务,好比设置打印机或配置办公室网络等。他们会尽力去了解其余两个角色所须要负责的内容,由于没有人能够帮助他们(直到咱们参与进来)。
一旦他们想了解Helm,大多数应用开发者会把他们的chart放在最容易处理的地方——也就是他们维护的同一个repo。
你可能在一个更大的、架构更分明的团队中工做,
在这种状况下,你可能有本身的DevOps工程师甚至是整个DevOps部门。而这我的或团队常常会以为本身也要负责 “Deployer”的角色。颇有可能,他们会倾向于采用更集中的方法,好比将全部的chart存储在ChartMuseum这样的chart仓库中。更不肯意让应用开发者过多地参与到Helm chart中来(每每是有合理原因的)。
例如,我最近看了一个经典的技术讲座,叫《从头开始构建Helm chart》,由VMWare系统工程师Amy Chen主讲。在她的开场白中,她说:
在基础设施方面,你的主要目标是时刻准备着应对故障,没有信任——在这个意义上说,就像我不太愿意信任个人APP开发者,而且我也不太须要信任个人APP开发者。
这是能够理解的。你不想让应用开发者去搞乱设置,好比CPU和内存限制,或者是pod中断预算。但整个 “DevOps文化”的概念是专门为了改善基础设施维护者和开发者之间有时会出现的疏离关系而演化出来的。
Atlassian(JIRA和Trello的全部者)出版了一本“团队手册”,其中定义了DevOps文化:
DevOps文化是关于开发者和运维之间的共同理解,并为他们所构建的软件分担责任。这意味着增长透明度、沟通和协做,并在开发、IT/运维和 “业务”之间进行合做。
若是将其实际应用到Helm chart维护和通常的基础架构配置中,就会把大部分的责任放在应用开发者的手中。他们也会承担起“Deployer”的角色,并改变他们拥有的仓库中的配置。
系统工程师仍然能够把他们专门维护的设置集中起来。例如,一些团队也会维护一个中央基础架构repo,该repo中保存着Terraform配置或Helm文件等经常使用资源,这些资源是启动新项目所须要的(例如,用于设置ingress controller和cert manager)。Helm 3还支持所谓的 “library chart”,它只能做为另外一个chart的一部分进行部署。这让咱们更容易区分常见的和服务特定的变动责任。
即便当chart存储在服务仓库中,系统工程师仍然能够做为重要更改的把关人。例如,你可使用GitHub CODEOWNERS文件来确保系统工程师在你的repo中的chart目录中的任何更改都会被添加为审核者。
若是系统工程师须要主动作一些与应用开发无关的改动,能够指导开发人员为他们作更改,并解释为何这些改动是必须的。如下图片也许能反映这种状况:
开发者能够了解更多关于基础设施的内容以及这些更改如何影响他们的服务。
若是有简单的经验法则,那就是:先了解选项3。尝试为服务仓库中的每一个服务维护一个Helm chart。或者至少考虑一下我以前描述的混合方法。
若是你有几十个服务都很是类似,那么共享chart是更好的选择。只是要记住,你必须把它维护在一个中心repo中。可是这增长了意外耦合的风险,可能会破坏一个服务部署。风险增长意味着你在部署的时候须要更加谨慎,这反过来又意味着你会减小部署的频率。
即便你有特定服务的chart,你可能也须要集中存储,由于你没有足够的人员或专业知识以分布式的方式来管理这些chart。或者,也许你的团队须要在“Deployer”和“应用开发者”之间明确划分责任。
不管你决定作什么,我但愿我已经说明清楚了你在作最后决定时须要考虑的问题。作一个“Deployer”并不容易,尤为是当它不是你的平常工做时。
做者:Merlin Carter,专一于早期创业公司的风险投资家,擅长撰写开发人员创新和新技术的文章