Helm 入门:安装部署与使用


【编者的话】本文将用示例展示 Helm 的基本概念、如何修改 chart 满足你的需求。

在 Kubernetes 上部署应用程序可能需要许多相关的部署组件或规范文件:Deployment、Service、PVC、ConfigMap、ServiceAccount……

管理这些资源并将它们与已部署的应用程序关联起来是一项挑战,尤其是跟踪已部署的应用程序(实际状态)及其原始来源(授权或期望状态)的更改和更新时。该应用程序的版本被锁定在 Kubernetes 平台中,使它们完全脱离了规范本身的版本(通常会在外部源代码管理库中进行跟踪)。

此外,静态规范通常不能在给定域、环境或云提供商之外重复使用,但需要花费大量时间进行创作和调试。工具可用于基于正则表达式提供的字符串进行替换,但这种自动化还需要编写或自定义以执行我们需要的任务,有些时候,这种方式会出现错误。

Helm 通过将相关的 Kubernetes 规范打包成一个简单的部署组件(称为 chart)来解决这些问题,这些组件可以参数化以获得最大的灵活性。同时,Helm 也能使用户在运行时中自定义应用程序包。如果你熟悉 apt 包或 yum 等 OS 包管理器以及 deb 或 rpm 等软件包,那么 Helm 以及 Helm chart 的概念你应该很熟悉。如果你想和更多Helm技术专家交流,可以加我微信liyingjiese,备注『加群』。群里每周都有全球各大公司的最佳实践以及行业最新动态

先决条件

首先,你需要一个正在运行的 Kubernetes 集群,一个本地 Docker 客户端,以及一个预配置的 kubectl 客户端和 Kubernetes 集群配置。Helm 将使用 kubectl 在已配置的集群上部署 Kubernetes 资源。


注:Helm 的默认安装是不安全的!

安装 Helm

Helm 有两个部分:Helm 客户端(Helm)和 Helm 服务器(Tiller)。首先,你需要通过 Helm 客户端在 Kubernetes 集群上安装 Tiller。这里需要注意,用 Helm 客户端来部署 Tiller 服务器不是必须的,但现在这样做很方便。

Helm 客户端可以从源代码或预构建的二进制版本安装,通过 Linux 上的 Snap、macOS 上的 Homebrew 或 Windows 上的 Chocolatey 安装。但 Helm GitHub repo 还拥有一个安装程序 shell 脚本,该脚本将自动获取最新版本的 Helm 客户端并在本地安装。

下面是 Ubuntu 16.04 的演示示例,其中 Kubernetes 使用 kubeadm 在本地安装。
1.png

使脚本可执行并运行它,下载、安装最新版本的 Helm,此步骤需要 sudo 权限。
2.png

我们可以使用 version 带有 client only flag(-c)的命令来确保客户端可用:
3.png

此命令将挂起,并将使用我们的 kubeconfig 查找 Tiller ,但现在我们还没有 Tiller。

默认情况下,Helm 客户端使用 socat 设置端口转发到 Tiller 窗口。但在我们的例子中,由于 socat 已经安装为使用 kubeadm 进行 Kubernetes 集群初步设置的一部分,所以你并不需要执行这一步。

下面是安装时的一个例子:
4.jpg

如果你需要安装 socat,你可以从 apt:sudo apt-get install socat。

此时我们应该在集群上部署 Tiller。

Tiller

Tiller 通常在你部署的 Kubernetes 集群上运行。对于开发,它也可以在本地运行并配置为与远程 Kubernetes 集群通信的方式(这很方便)!

将 Tiller 安装到集群中的最简单方法就是运行 helm init。然后 Helm 将验证 Helm 本地环境是否已正确设置(或在必要时进行设置),使用 kubeconfig 的 current-context 连接到与 kubectl 相同的集群并安装 Tiller Pod。

init 有一堆选项来影响它的行为:
  • --canary-image:安装 Tiller 的 canary 版本(测试最新功能);
  • --client-only:本地配置,但不安装 Tiller;
  • --kube-context:使用命名 context 来替代 ~/.kube/config 文件中的 current-context;
  • --node-selectors:指定安排 Tiller Pod 所需的节点标签;
  • --override:操纵最终 Tiller 清单的指定属性;
      * 接受 Tiller 部署清单中任何有效属性的有效值
  • --output:跳过 Tiller 部署清单的安装,只需将部署清单以 JSON 或 YAML 格式输出到 stdout 中;
  • --tiller-image:使用除最新版本之外的特定 Tiller 版本;
  • --upgrade:将 Tiller 升级到最新版本。


你也可以通过这个文档了解更多:https://docs.helm.sh/helm/#helm-init。

让我们 init 通过使用 --output 标志来看一下将要部署的内容并通知它 output yaml(或者如果你愿意,可以使用 json):
5.jpg

在这里,我们看到了 Tiller 部署及其服务;我们可以简单地保存这些文件并使用 kubectl 进行部署,但这会有什么好处呢?

请注意两个环境变量:TILLER_NAMESPACE 和 TILLER_HISTORY_MAX 。--tiller-namespace 会影响的命名空间;TILLER_HISTORY_MAX 用于限制每个版本保存的最大修订数(0 表示没有限制),具有无限数量的修订会对性能产生影响,因此你需要在实践中使用 --history-max 标志将其设置为合理值。

Tiller 和 RBAC

限制 Tiller 将资源安装到某些命名空间是个好主意。使用 RBAC 时,我们可以通过为 Kubernetes API 提供身份(Kubernetes 服务帐户)并使用 Kubernetes 角色和绑定为其分配范围权限来限制任何应用程序对 Kubernetes API 进行访问。

这次超时我们可以将配置保持在最低限度,为 Tiller 分配集群管理集群角色,以便它可以部署到任何命名空间。

如果你的集群不是本地集群或测试集群,请不要在家中执行此操作!

首先,创建服务帐户:
6.png

现在创建集群角色绑定,将集群管理员角色分配给 Tiller 服务帐户:
7.png

部署 Tiller

现在我们可以部署 Tiller。首先使用 --service-account 标志来使用 Tiller 服务帐户:
8.jpg

Helm 会自动将其配置的文件放入 ~/.helm 中。将 Helm 客户端文件放在除 ~/.helm 之外的其他位置,$HELM_HOME 在运行之前设置环境变量 helm init,然后使用重要说明部署 Tiller:

请注意,默认情况下,Tiller 会使用不安全的 “允许未经身份验证的用户” 策略进行部署。为了防止这种情况,请 helm init 使用-tiller-tls-verify 标志运行。有关保护安装的更多信息,请参阅:https://docs.helm.sh/using_helm/#securing-your-helm-installation。


注:默认的 Tiller 是不安全的!
我们可以像在任何其他 Kubernetes 资源上一样在我们的集群上找到 Tiller:
9.jpg

在没有 -c 的情况下运行 version 命令应该同时显示 Helm 和 Tiller 版本,并确保 Helm 可以找到并与 Tiller 对话。
10.png

是时候开始 Helming 了!

探索 chart

众所周知,chart 是一组 spec 文件,它们定义了一组 Kubernetes 资源(如服务、部署等),通常包含将应用程序部署为模板所需的所有资源。chart 资源模板使用户能够通过为模板中定义的某些(或所有)变量提供值来自定义,在安装时部署呈现资源的方式。

chart 还包括所有已定义变量的默认值,只需要很少(或不需要)自定义就能轻松部署 chart。与其他软件包管理器一样,我们希望使用 update 命令从我们配置的 repos 中获取 chart 的最新列表和更新:
11.png

请注意,Helm 跳过了“本地 chart 存储库”,但从我们唯一的“稳定”存储库中获得了更新。当你第一次安装 Helm 时,它预先配置为与本地存储库和官方 Kubernetes chart 存储库通信。官方存储库(名为 “stable”)包含一些精心策划和维护的常用软件 chart,如 elasticsearch、Influxdb、mariadb、nginx、prometheus、redis 等等。

列出你的 Helm repos 以显示已配置的内容:
12.png

你可以随时使用 helm repo add 命令添加其他的 repo。下面我们将使用稳定的 repo。

该 helm search 命令将向我们显示官方存储库中的所有可用 chart(因为它是唯一配置和更新的 repo):
13.jpg

请注意使用 stable/ 前置所有可用 chart。在 helm/charts 项目中,stable 文件夹包含经过严格升级并满足某些技术要求的所有 chart。孵化器 chart 也可用,但在满足这些标准之前还需要不断改进。你可以使用该 helm repo add 命令添加孵化器存储库(与任何其他存储库一样)并将其指向正确的 URL。

另外,请注意 CHART VERSION 和 APP VERSION 列。前者是 Helm chart 版本,必须按照 Helm 项目的规则,遵循 SemVer 2 格式。后者是实际软件的版本,在 Helm 中以自由形式存在,但与软件的发布规则相关。

helm search 可以显示所有可用的 chart。你可以通过使用过滤器进行搜索来缩小搜索结果范围:
14.jpg

为什么 traefik 在名单中?因为它的包描述与入口有关。我们可以 helm inspect chart 看看发生了什么:
15.jpg

traefik chart 的关键字部分包含关键字“ingress”,因此它会显示在我们的搜索中。

部署 chart

稍后我们将探索 chart 的结构,但为了说明部署 chart 是多么容易,我们可以使用 repo 中的 chart。要安装 chart,请使用 helm install 命令,该命令仅需要一个参数:chart 的名称。你可以使用官方 helm repo 提供的容器化 Docker 注册表。

部署注册表:
16.jpg

刚刚发生了什么?

Helm 通过为所有变量注入默认值来呈现 Kubernetes 资源模板,然后通过将它们作为静态规范文件提交到 Kubernetes API 来部署 Kubernetes 集群上的资源。

安装 chart 后会创建一个新的 Helm 发布对象,上面的这个版本被命名为“kissable-clownfish”(如果你想使用你自己的版本名称,只需使用带有 install 命令标志的 --name)。

Helm Release 是一组基于 chart 的已部署资源。每次安装 chart 时,它都会使用自己的版本名称部署一整套 Kubernetes 资源。独特的命名有助于我们跟踪 Kubernetes 资源的相关性,并允许我们使用不同的自定义方式多次部署 chart。

在安装过程中,Helm 将打印有关创建资源的有用信息,在我们的示例中,就是 ConfigMap、Deployment、Secret 和 Service。要再次查看它,你可以使用 helm status 版本名称。我们需要使用我们新的注册表服务器,NOTES 输出的部分提供了一些使用它的线索:
17.png

此时,你的终端应该被劫持以进行端口转发。启动一个新终端并使用 Docker 与注册表进行交互。从 Kubernetes 主机上的 Docker 客户端,拉出一个像 alpine 这样的轻量级镜像:
18.jpg

现在重新标记它,在镜像仓库名称前加上 IP 端口并尝试推送它:
19.png

查询注册表 API ,确认注册表拥有我们的镜像:
20.png

成功!

这很简单,但我们只使用此 chart 的默认配置选项。你可能希望在部署之前自定义 chart。要查看给定 chart 可配置的选项,请使用 helm inspect values。

使用 Ctrl + C(^C)杀死你的进程端口,然后检查 chart 值:
21.jpg

我们可以进行许多配置更改。最值得注意的是,我们可以为注册表部署入口记录(如果我们部署了入口控制器,则非常有用)。我们还可以配置许多不同的存储后端,比如 S3 bucket 和存储 AWS 访问密钥的相关 Secret。

但这些值来自哪里?

chart 剖析

chart 是以 chart 命名目录中的文件集合。到目前为止,我们只从远程仓库部署了一个 chart ,你可以通过查看 GitHub 上 docker-registry chart 的链接看到这些文件。

安装 chart 时,Helm 将目录的内容作为存档下载,并将其本地缓存在 Helm 客户端的工作空间目录中。默认位置是 ~/.helm :
22.png

缓存目录包含归档格式的远程 chart 存储库的本地克隆:
23.png

如果我们想要浏览 chart,我们可以自己扩展存档,或者使用 Helm 命令!

使用 fetch 命令和 --untar 会在我们的本地系统上生成一个 unpacked chart:
24.jpg

关于其中大部分内容的解释,请参考 Helm 文档。现在我们将专注于 .yaml 值。之前我们用 helm inspect values 命令检查了这些值,现在,我们来看看使用 values.yaml 所展示的内容:
25.jpg

值文件是 chart 的作者为所有 chart 变量设置默认值的地方。你只需键入 helm install,chart 就会起作用。有些 chart 具有先决条件,通常会记录这些 chart,所以你可以提前知道它们。例如,WordPress chart 声明了以下先决条件:

先决条件:启用 Beta API 的 Kubernetes 1.4+ —— 底层基础架构中的 PV 配置器支持。

更新发布

如果要更改发行版的配置,你可以使用 helm upgrade 命令。Helm 会更新自上次发布以来发生过变化的内容。Upgrade 与 install 使用相同的覆盖标志,因此你可以在初始安装或稍后的某个时候自定义 chart 。

我们最初的 Docker Registry Service 是 ClusterIP 类型,这就是我们需要端口转发的原因:
26.png

要确认它是以这种方式部署的,我们需要列出 Kubernetes 服务:
27.png

让我们更新服务以使用 NodePort,以便我们可以将注册表公开给外部世界。

在更新期间或初始安装期间,有两种方法可以传递配置数据:
  • --values(或 -f):指定带有覆盖的 YAML 文件
  • --set:在命令行上指定覆盖
    • 基本:--set name=value==name: value(键值对以逗号分隔)
    • * 集支持多个复杂值,--set servers.port=80 变为:
      28.png

      29.png

      30.png


我们知道这个 type 是一个服务,所以我们可以设置它的值为 --set service.type=:
31.jpg

根据上面的输出,Kubernetes 已更新我们的服务配置。该 NOTES 部分甚至已经更改,表明我们现在可以通过 http:// NODE_IP:NODE_PORT 访问我们的 docker-registry 服务。

我们可以用 helm get values 来查看新设置是否生效。
32.png

没有这里提供的信息。Helm 只关注 yaml 键/值对的变化。

让我们看看它是否有效:
33.png

成功!让我们通过推动镜像来测试它。

默认情况下,Docker 只信任 localhost 上的安全远程注册表或不安全注册表。由于 Kubernetes 在容器中运行我们的注册表,即使 Docker 守护程序和 docker-registry 在同一主机上运行,注册表也被视为“远程”。我们的 port-forward 使用了 localhost,因此 Docker 允许我们推送,但这次不会让我们这样通过:
34.png

有两种方法可以解决这种情况。一种方法是配置注册表服务器以支持 TLS。我们可以告诉 Docker 信任我们的非安全注册表(仅在非生产环境中执行此操作),而不是保护 docker-registry。这允许我们在不使用 SSL 证书的情况下使用注册表。

在 Kubernetes 主机上执行下一步很可能会破坏部署 kubeadm 的集群,因为它需要重新启动 Docker 并且所有 Kubernetes 服务都在容器中运行。因此,请使用 Kubernetes 主机外部的 Docker 安装 。

通过在下面创建一个配置文件来配置我们的 Docker 守护程序 /etc/docker (将示例 IP 替换为你之前存储在 NODE_IP 中的节点的 IP):
35.png

要使这些更改生效,你需要重新启动 Docker:
36.png

现在,你的 Docker 守护程序是否应该信任我们的注册表:
37.png

看它是否有效:
38.png

现在你已经拥有了一个团队可以共享的注册表!但其他人也可以使用它,记得对此加以限制哦!

原文链接:https://mp.weixin.qq.com/s/BTlkX9fRlxV1qo8eNs0qAQ

0 个评论

要回复文章请先登录注册