怎样创作一个自己的Helm Chart
发布时间:2022-01-13 10:29:45 所属栏目:系统 来源:互联网
导读:如何创作一个自己的Helm Chart,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。 前言 我们平时在日常生活中会经常在不同的平台上与各种各样的应用打交道,比如从苹果的 App Store 里下载的
如何创作一个自己的Helm Chart,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。 前言 我们平时在日常生活中会经常在不同的平台上与各种各样的应用打交道,比如从苹果的 App Store 里下载的淘宝、高德、支付宝等应用,或者是在 PC 端安装的 Word、Photoshop、Steam。这些各类平台上的应用程序,对用户而言,大多只需要点击安装就可使用。 然而,在云 (Kubernetes)上,部署一个应用往往却不是那么简单。如果想要部署一个应用程序到云上,首先要准备好它所需要的环境,打包成 Docker 镜像,进而把镜像放在部署文件 (Deployment) 中、配置服务 (Service)、应用所需的账户 (ServiceAccount) 及权限 (Role)、命名空间 (Namespace)、密钥信息 (Secret)、可持久化存储 (PersistentVolumes) 等资源。也就是编写一系列互相相关的 YAML 配置文件,将它们部署在 Kubernetes 集群上。 但是即便应用的开发者可以把这些 Docker 镜像存放在公共仓库中,并且将所需的 YAML 资源文件提供给用户,用户仍然需要自己去寻找这些资源文件,并把它们一一部署。倘若用户希望修改开发者提供的默认资源,比如使用更多的副本 (Replicas) 或是修改服务端口 (Port),他还需要自己去查需要在这些资源文件的哪些地方修改,更不用提版本变更与维护会给开发者和用户造成多少麻烦了。 可见最原始的 Kubernetes 应用形态并不便利。 Helm 与 Helm Chart 在这样的大环境下,有一系列基于 Kubernetes 的应用包管理工具横空出世。而我们今天的主角 Helm,就是这其中最受欢迎的选择之一。 开发者按照 Helm Chart 的格式,将应用所需的资源文件包装起来,通过模版化 (Templating) 的方式将一些可变字段(比如我们之前提到的暴露哪个端口、使用多少副本)暴露给用户,最后将封装好的应用包,也就是 Helm Chart,集中存放在统一的仓库中供用户浏览下载。 站在用户角度,用户只需要一行简单的命令就可以完成应用的安装、卸载与升级。对于安装之后状态,也可以通过 helm list 或者是原生的 kubectl 进行查询。 $ helm install redis stable/redis $ kubectl get pods NAME READY STATUS RESTARTS AGE redis-master-0 1/1 Running 0 63s redis-slave-0-0 1/1 Running 0 63s redis-slave-1-0 1/1 Running 0 13s $ helm delete redis 创作 Helm Chart 那么站在开发者的角度上,我们应该如何去创作一个 Helm 应用包呢? 准备工作 首先我们需要一个准备部署的镜像。这个镜像可以是一个 Java 程序、一个 Python 脚本、甚至是一个空的 linux 镜像跑几条命令。 这里我们使用一个简单的基于 golang 的 hello world HTTP 服务。该服务通过读取环境变量 USERNAME 获得用户自己定义的名称,然后监听 80 端口。对于任意 HTTP 请求,返回 Hello ${USERNAME}。比如如果设置 USERNAME=world(默认场景),该服务会返回 Hello world。 然后我们使用 Dockerfile 对镜像进行打包。先对 Golang 代码进行编译,然后将编译后的程序放在基于 alpine 的镜像中,以缩小镜像体积。 在 Docker 构建好镜像之后,我们把镜像上传到仓库中,比如 Docker Hub 或是阿里云容器镜像仓库。准备工作做好之后,我们就可以开始创作 Helm Chart 了。 开始创作 运行 helm create my-hello-world,会得到一个 helm 自动生成的空 chart。这个 chart 里的名称是 my-hello-world。 需要注意的是,Chart 里面的 my-hello-world 名称需要和生成的 Chart 文件夹名称一致。如果修改 my-hello-world,则需要做一致的修改。 现在,我们看到 Chart 的文件夹目录如下: my-hello-world ├── charts ├── Chart.yaml ├── templates │ ├── deployment.yaml │ ├── _helpers.tpl │ ├── ingress.yaml │ ├── NOTES.txt │ └── service.yaml └── values.yaml 在根目录下的 Chart.yaml 文件内,声明了当前 Chart 的名称、版本等基本信息,这些信息会在该 Chart 被放入仓库后,供用户浏览检索。比如我们可以把 Chart 的 Description 改成 "My first hello world helm chart"。在 Chart.yaml 里有两个跟版本相关的字段,其中 version 指明的是 Chart 的版本,也就是我们应用包的版本;而 appVersion 指明的是内部实际使用的应用版本。 在 templates 文件夹内存放了各类应用部署所需要使用的 YAML 文件,比如 Deployment 和 Service。在我们当前的应用内,我们只需要一个 deployment,而有的应用可能包含不同组件,需要多个 deployments,那么我们就可以在 templates 文件夹下放置 deploymentA、deploymentB 等。同样的,如果我们需要配置 serviceaccount, secret, volumes 等内容,也可以在里面添加相应的配置文件。 apiVersion: apps/v1beta2 kind: Deployment metadata: name: {{ template "my-hello-world.fullname" . }} labels: {{ include "my-hello-world.labels" . | indent 4 }} spec: replicas: {{ .Values.replicaCount }} selector: matchLabels: app.kubernetes.io/name: {{ include "my-hello-world.name" . }} app.kubernetes.io/instance: {{ .Release.Name }} template: metadata: labels: app.kubernetes.io/name: {{ include "my-hello-world.name" . }} app.kubernetes.io/instance: {{ .Release.Name }} spec: containers: - name: {{ .Chart.Name }} image: "{{ .Values.image.repository }}:{{ .Chart.AppVersion }}" imagePullPolicy: {{ .Values.image.pullPolicy }} env: - name: USERNAME value: {{ .Values.Username }} ...... replicaCount: 1 image: repository: somefive/hello-world pullPolicy: IfNotPresent nameOverride: "" fullnameOverride: "" service: type: ClusterIP port: 80 ...... Username: AppHub 在根目录下我们看到有一个 values.yaml 文件,这个文件提供了应用在安装时的默认参数。在默认的 Values 中,我们看到 replicaCount: 1,说明该应用在默认部署的状态下只有一个副本。 为了使用我们要部署应用的镜像,我们看到 deployment.yaml 中,在 spec.template.spec.containers 里, image 和 imagePullPolicy 都使用了 Values 中的值。其中 image 字段由 .Values.image.repository 和 .Chart.AppVersion 组成。 看到这里,同学们应该就知道需要变更的字段了:一个是位于 values.yaml 内的 image.repository,另一个是位于 Chart.yaml 里的 AppVersion。将它们与我们需要部署应用的 docker 镜像匹配起来,这里我们把 values.yaml 里的 image.repository 设置成 somefive/hello-world,把 Chart.yaml 里的 AppVersion 设置成 1.0.0 即可。 类似的,我们可以查看 service.yaml 内要部署的服务,其中的主要配置也在 values.yaml 中。默认生成的服务将 80 端口暴露在 Kubernetes 集群内部。我们暂时不需要对这一部分进行修改。 由于部署的 hello-world 服务会从环境变量中读取 USERNAME 环境变量,所以将这个配置加入 deployment.yaml。 - name: {{ .Chart.Name }} image: "{{ .Values.image.repository }}:{{ .Chart.AppVersion }}" imagePullPolicy: {{ .Values.image.pullPolicy }} env: - name: USERNAME value: {{ .Values.Username }} 现在我们的 deployment.yaml 模版会从 values.yaml 中加载 Username 字段,因此相应的,我们也在 values.yaml 中添加 Username: AppHub。这样,我们的应用就会从 values.yaml 中读取 Username,把它放入镜像的环境变量中启动了。 校验打包 在准备好我们的应用后,我们可以使用 Helm lint 来粗略地检查一下制作的 Chart 有没有什么语法上的错误。如果没有问题的话,就可以使用 helm package 命令对我们的 Chart 文件夹进行打包,打包后我们可以得到一个 my-hello-world-0.1.0.tgz 的应用包。这个便是我们完成的应用了。 (编辑:晋中站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |