你的Helm安全吗?
一、背景
Kubernetes是目前最为流行、成为事实标准的容器集群管理平台,为容器化应用提供了部署运行、资源调度、服务发现和动态伸缩等一系列完整功能。在Kubernetes当中,用户通过使用API对象,如Pod、Service、Deployment等,来描述应用的程序规则,而这些资源对象的定义一般需要写入一系列的YAML文件中,然后通过 Kubernetes 命令行工具Kubectl进行部署。由于通常应用程序都涉及到多个Kubernetes API对象,而要描述这些API对象就可能要同时维护多个YAML文件,从而在进行 Kubernetes 软件部署时,通常会面临下述几个问题:
· 如何管理、编辑和更新这些这些分散的 Kubernetes 应用配置文件
· 如何把一套相关的配置文件作为一个应用进行管理
· 如何分发和重用 Kubernetes 的应用配置
Helm (https://helm.sh)的出现就是为了很好地解决上面这些问题,是Kubernetes官方提供的包管理工具,主要是是通过管理被称作Helm Chart的包来描述和管理云服务的。使用 Helm后就不需要再编写复杂的应用部署文件,可以以简单的方式在 Kubernetes 上查找、安装、升级、回滚、卸载应用程序。
在现在常用的Helm V2架构中,有一个称为“Tiller”的服务端组件。Tiller是一个集群内服务器,可与Helm客户端进行交互,并与Kubernetes API服务器连接。但由于Tiller具有root用户访问权限,使得有人可以未经授权访问Kubernetes服务器你,从而构成了很大的风险。
JFrog的专家,也是Helm的联合创始人,Rimas Mocevicius,提供了一种创新的、优雅的方法——Tillerless Helm,来解决这种情况,从而保护用户的Kubernetes集群。
二、Helm V2的应用架构
从Helm v2开始,Helm的架构中有一个名为The Tiller Server的服务器部分,该服务器部分是一个与helm客户端交互并与Kubernetes API服务器连接的集群内服务器。服务器负责以下各项工作:
· 监听来自Helm客户端的传入请求
· 结合Chart和配置以创建发布版本
· 将Chart安装到Kubernetes中,然后跟踪后续版本
· 通过与Kubernetes交互来升级和卸载Chart
简而言之,客户端负责管理Chart,Tiller负责管理发布版本,其架构如下图所示:
默认情况下,执行如下命令将Tiller部署安装到Kubernetes集群:
helm init
同时还需要为Tiller创建并部署RBAC授权,使其拥有执行任务的权限。Tiller常用的RBAC授权如下所示:
目前这样的架构工作得很好,为用户提供了灵活和方便,但同时也存在一些安全问题。从上面的RBAC文件中可以看出,Tiller被授予了cluster-admin的角色,也就是说,Tiller在用户的Kubernetes集群中具有完全的管理权限,这就具备了有人未经授权而访问和控制集群的风险。
三、Helm V2 中的Tillerless方案
其实,在Helm V2中创建Tillerless的架构也并不困难,能够为Helm的应用提供更高的安全保障。JFrog的专家Rimas给出了优化的解决方案,而本节将通过细节的描述来解释该方案如何运行。
首先,可以将Helm客户端和Tiller都部署在工作站上,或者运行在CI/CD流水线中,而不需要将Tiller安装到Kubernetes集群之中。示例的安装方式如下:
在这种安装方式下,Helm的运行架构如下图所示:
在这种架构下,Tiller使用和Helm客户端一样的配置(kubeconfig)连接到Kubernetes集群,并按照指定的命名空间(namespace)存储和管理Helm的发行版本信息。用户可以通过这种方式创建许多名称空间,并在Tiller启动时指定应该使用哪个命名空间。用户定义的RBAC规则可以存储在运行指定的名称空间中的密钥/配置映射中,而不再需要为Tiller创建和指定ServiceAccount。而这个架构的另一个好处就是不再限定Kubernetes集群中只能运行一个Tiller实例。
注意,在这种架构下,必须使用如下的命令来初始化Helm客户端,否则Tiller仍然被安装到Kubernetes集群中:
helm init --client-only
四、Helm V2中的Tillerless插件
那么,有没有更加方便的安装方式呢?Rimas为大家提供了一个简单的Helm Tillerless插件,请参见https://github.com/rimusz/helm-tiller。
插件的安装非常方便,如下:
该插件提供了四个简单的命令:start,start-ci,stop和run。
4.1 在本地使用Tillerless插件
对于在本地开发或访问远程Kubernetes集群时,请使用helm tiller start命令:
该命令将在本地启动Tiller,并利用Tiller默认的设置,在kube-system名称空间存储和管理Helm版本。
也可以通过下述命令指定Tiller使用的命名空间:
该命令还会打开一个新bash shell,带有预设的环境变量:
HELM_HOST=localhost:44134
这样,Helm客户端就知道如何连接Tiller了。
现在,就可以开始部署或更新Helm的发布版本了。
当完成了所有工作之后,只需要运行下述命令,就可以关闭Tiller了。
接下来,用户也可以重复上面的过程,通过指定新的命名空间来部署和更新其他团队的发布版本。
4.2 在CI/CD流水线中使用Tillerless插件
那如何在CI/CD流水线当中使用该插件呢?有两种方法:
第一种与上面的过程非常相似,只是没有启动带有预设变量的bash shell。
然后,Helm客户端将知道连接到Tiller的位置,而无需在CI流水线中进行任何更改。并且在流水线的结尾执行:
结束全部工作。
第二种也很容易,就是运行helm tiller run,可以使Tiller在指定命令之前或之后启动/停止:
举例来看:
附加功能:该插件还能够检查安装的Helm客户端和Tiller的版本,如果不匹配,则下载正确的Tiller版本文件。
五、总结
Helm作为Kubenetes的官方包管理工具,为用户提供了方便、快捷的在Kubernetes集群里部署和管理自己应用程序的方式。然而,Helm V2架构中的Tiller组件,在提供了操作便利的同时,也带来了安全上的隐患。
本文为大家介绍了一种在Helm V2中实现Tillerless的Helm部署和应用的解决方案,在保留了Helm V2灵活性和便利性的同时,也大大提升了应用和管理的安全性。
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341