ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

kubernetes-handbook 实战:使用 Helm 管理 Kubernetes 应用(Chart 结构、模板渲染与版本管理)

kubernetes-handbook 实战:使用 Helm 管理 Kubernetes 应用(Chart 结构、模板渲染与版本管理) kubernetes-handbook 实战使用 Helm 管理 Kubernetes 应用Chart 结构、模板渲染与版本管理【免费下载链接】kubernetes-handbookKubernetes 架构与生态从云原生到 AI 原生基础设施的构建指南项目地址: https://gitcode.com/gh_mirrors/ku/kubernetes-handbookHelm 是 Kubernetes 生态中最流行的应用包管理工具它把一组预配置好的 Kubernetes 资源Chart打包、分发、安装并纳入版本管理其定位类似于 Ubuntu 的 APT 与 CentOS 的 YUM。本篇基于 kubernetes-handbook 仓库的 practice/helm.md 展开并结合仓库内完整的mychart实例见 manifests/charts/mychart逐层剖析 Chart 目录结构、Go template 渲染机制与helm install/upgrade/rollback/uninstall的完整生命周期操作读完即可独立创建、打包、发布并运维自己的 Helm Chart。Helm 与 Chart 的核心概念Helm 用于管理 Chart——预先配置好的 Kubernetes 应用安装包。Chart 本质上是封装了 Kubernetes 原生应用的一组 YAML 文件可以在部署应用时自定义应用程序的部分 metadata如镜像地址、副本数、Service 端口等从而方便应用的分发。Helm 和 Chart 的主要作用可归纳为四点应用程序封装将 Deployment、Service、Ingress、ConfigMap 等一组相关资源打包为一个可复用的单元版本管理每次helm upgrade都会产生一个新的 release 版本号支持随时回滚依赖检查通过charts/子目录或依赖声明管理子 Chart 之间的依赖关系便于应用程序分发Chart 可打包为.tgz文件托管在任意静态 Web 服务器GitHub Pages、S3、GCS 等上形成 Chart 仓库。关于版本需要特别说明Helm 3 于 2019 年 11 月 13 日发布2020 年 4 月 30 日从 CNCF 毕业本文基于 Helm 3 讲解。Helm 3 移除了 Helm 2 时代的服务端组件 Tiller这也是仓库内 ceph-helm 安装文档 中helm init、helm serve等命令只适用于 Helm 2 的原因客户端直接通过 kubeconfig 与 Kubernetes API Server 通信安全性大幅提升。从工作流程上看Helm 可以安装本地或远程的 Chart当 Chart 被安装到 Kubernetes 集群后会产生一个release一次独立部署实例同一个 Chart 可以部署多次形成多个互不干扰的 release。每次修改 Chart 配置并执行helm upgrade该 release 的版本号revision就会加 1。安装 Helm前提要求Kubernetes 1.5 以上版本执行helm命令的主机可以访问到 Kubernetes 集群即持有有效的 kubeconfig 且网络可达。安装方式请参考 Helm 官方安装说明对于 Mac 用户直接运行brew install helm即可。安装完成后可以通过helm version验证客户端与服务端的连接情况Helm 3 下仅验证客户端版本及集群访问。Chart 目录结构详解下面我们一步步创建一个 Chart 来说明其组织结构。首先使用helm create mychart创建一个名为mychart的示例再用tree mychart查看目录结构mychart ├── Chart.yaml ├── charts # 该目录保存其他依赖的 chart子 chart ├── templates # chart 配置模板用于渲染最终的 Kubernetes YAML 文件 │ ├── NOTES.txt # 用户运行 helm install 时候的提示信息 │ ├── _helpers.tpl # 用于创建模板时的帮助类 │ ├── deployment.yaml # Kubernetes deployment 配置 │ ├── ingress.yaml # Kubernetes ingress 配置 │ ├── service.yaml # Kubernetes service 配置 │ ├── serviceaccount.yaml # Kubernetes serviceaccount 配置 │ └── tests │ └── test-connection.yaml └── values.yaml # 定义 chart 模板中的自定义配置的默认值可以在执行 helm install 或 helm update 的时候覆盖以上仅为 Helm 自动创建的目录结构还可以在templates目录下添加其他 Kubernetes 对象的配置如ConfigMap、DaemonSet、StatefulSet等。对照仓库中的真实实例本仓库 manifests/charts/mychart 保存了一个较早期版本的helm create生成实例其文件略有差异mychart/ ├── Chart.yaml # chart 元信息名称、版本、描述 ├── values.yaml # 模板默认值 └── templates/ ├── NOTES.txt # helm install 成功后的提示信息含访问方式 ├── _helpers.tpl # name / fullname 模板帮助函数 ├── deployment.yaml # Deployment 模板 └── service.yaml # Service 模板对比可见新版helm create会额外生成ingress.yaml、serviceaccount.yaml与tests/test-connection.yaml用于helm test而仓库实例省略了这些文件但保留了核心骨架。各文件职责如下Chart.yamlChart 的元数据文件声明名称、版本、描述等。仓库实例内容见 Chart.yamlapiVersion: v1 description: A Helm chart for Kubernetes name: mychart version: 0.1.0values.yaml定义模板中自定义配置的默认值可在helm install或helm upgrade时通过-f/--set覆盖。仓库实例见 values.yaml它完整覆盖了镜像、副本数、Service 端口与资源配额# Default values for mychart. # This is a YAML-formatted file. # Declare variables to be passed into your templates. replicaCount: 1 image: repository: harbor-001.jimmysong.io/library/nginx tag: 1.9 pullPolicy: IfNotPresent service: name: nginx type: ClusterIP externalPort: 80 internalPort: 80 resources: limits: cpu: 100m memory: 128Mi requests: cpu: 100m memory: 128Mitemplates/Chart 配置模板目录用于渲染最终的 Kubernetes YAML 文件templates/_helpers.tpl模板帮助函数类似编程语言中的公共工具库集中定义可复用的命名逻辑templates/NOTES.txt用户运行helm install时的提示信息如何访问应用templates/tests/存放用于验证 release 是否正常工作的测试 Pod 模板。关于 Chart 的组织规范可进一步参考仓库内的 构建私有 Chart 仓库 文档Chart 中包括一系列 YAML 描述文件一个 Chart 只用来部署单个应用不应过于复杂、不应包含过多依赖相当于一个微服务Chart 有固定的目录结构可打包成压缩包进行版本控制。模板渲染机制Go template 与 values 注入查看helm create自动生成的templates/service.yamlapiVersion: v1 kind: Service metadata: name: {{ include mychart.fullname . }} labels: {{- include mychart.labels . | nindent 4 }} spec: type: {{ .Values.service.type }} ports: - port: {{ .Values.service.port }} targetPort: http protocol: TCP name: http selector: {{- include mychart.selectorLabels . | nindent 4 }}可以看到其中有很多{{ }}包围的字段这是使用 Go templatetext/template创建的自定义字段其中mychart开头的都是在_helpers.tpl中生成的定义。渲染时Helm 将values.yaml及命令行传入的覆盖值、Chart.yaml元数据、release 信息名称、命名空间、版本号等一并注入模板上下文.最终输出可被kubectl应用的完整 YAML。例如_helpers.tpl中对mychart.fullname的定义该函数负责生成符合 DNS 命名规范的应用全名{{/* Create a default fully qualified app name. We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). If release name contains chart name it will be used as a full name. */}} {{- define mychart.fullname -}} {{- if .Values.fullnameOverride -}} {{- .Values.fullnameOverride | trunc 63 | trimSuffix - -}} {{- else -}} {{- $name : default .Chart.Name .Values.nameOverride -}} {{- if contains $name .Release.Name -}} {{- .Release.Name | trunc 63 | trimSuffix - -}} {{- else -}} {{- printf %s-%s .Release.Name $name | trunc 63 | trimSuffix - -}} {{- end -}} {{- end -}} {{- end -}}这段定义体现了几个关键设计63 字符截断Kubernetes 部分名称字段受 DNS 命名规范限制最长 63 字符因此用trunc 63截断并用trimSuffix -去除结尾连字符优先级链fullnameOverride显式覆盖 release 名直接包含 chart 名时复用 release 名 printf %s-%s拼接 release 名与 chart 名默认值兜底default .Chart.Name .Values.nameOverride保证未设置nameOverride时回退到 Chart.yaml 中的 chart 名称。再看values.yaml中的一段配置新版模板简化为两层结构service: type: ClusterIP port: 80在使用helm install或helm upgrade时Helm 会渲染templates/service.yaml文件中的{{ .Values.service.type }}和{{ .Values.service.port }}的值。若缺少对应的 values 配置Helm 渲染时会报错因此在模板中应始终为每个.Values.*引用提供默认值。仓库实例的对照仓库中的 templates/_helpers.tpl 是更早期的写法定义了name与fullname两个函数{{/* vim: set filetypemustache: */}} {{/* Expand the name of the chart. */}} {{- define name -}} {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix - -}} {{- end -}} {{/* Create a default fully qualified app name. We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). */}} {{- define fullname -}} {{- $name : default .Chart.Name .Values.nameOverride -}} {{- printf %s-%s .Release.Name $name | trunc 63 | trimSuffix - -}} {{- end -}}对应的 templates/service.yaml 使用{{ template fullname . }}引用该函数并直接消费 values 中的端口与类型apiVersion: v1 kind: Service metadata: name: {{ template fullname . }} labels: chart: {{ .Chart.Name }}-{{ .Chart.Version | replace _ }} spec: type: {{ .Values.service.type }} ports: - port: {{ .Values.service.externalPort }} targetPort: {{ .Values.service.internalPort }} protocol: TCP name: {{ .Values.service.name }} selector: app: {{ template fullname . }}注意仓库实例的 values 中 Service 端口字段名为externalPort/internalPort而非文档示例的port这正是模板字段必须与 values 键名严格对应的直观体现——改错任何一个键名都会导致渲染出空值或直接报错。仓库的 templates/deployment.yaml 则演示了更丰富的模板语法toYaml将resources结构体原样序列化为 YAML 并用indent 12控制缩进镜像通过{{ .Values.image.repository }}:{{ .Values.image.tag }}拼接livenessProbe与readinessProbe直接引用内部端口apiVersion: extensions/v1beta1 kind: Deployment metadata: name: {{ template fullname . }} labels: chart: {{ .Chart.Name }}-{{ .Chart.Version | replace _ }} spec: replicas: {{ .Values.replicaCount }} template: metadata: labels: app: {{ template fullname . }} spec: containers: - name: {{ .Chart.Name }} image: {{ .Values.image.repository }}:{{ .Values.image.tag }} imagePullPolicy: {{ .Values.image.pullPolicy }} ports: - containerPort: {{ .Values.service.internalPort }} livenessProbe: httpGet: path: / port: {{ .Values.service.internalPort }} readinessProbe: httpGet: path: / port: {{ .Values.service.internalPort }} resources: {{ toYaml .Values.resources | indent 12 }}而 templates/NOTES.txt 演示了如何按 Service 类型分支给出不同的访问指引NodePort类型输出NODE_IP:NODE_PORTLoadBalancer类型等待外部 IP 就绪ClusterIP类型则给出kubectl port-forward命令1. Get the application URL by running these commands: {{- if contains NodePort .Values.service.type }} export NODE_PORT$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath{.spec.ports[0].nodePort} services {{ template fullname . }}) export NODE_IP$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath{.items[0].status.addresses[0].address}) echo http://$NODE_IP:$NODE_PORT/login {{- else if contains LoadBalancer .Values.service.type }} NOTE: It may take a few minutes for the LoadBalancer IP to be available. You can watch the status of by running kubectl get svc -w {{ template fullname . }} export SERVICE_IP$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template fullname . }} -o jsonpath{.status.loadBalancer.ingress[0].ip}) echo http://$SERVICE_IP:{{ .Values.service.externalPort }} {{- else if contains ClusterIP .Values.service.type }} export POD_NAME$(kubectl get pods --namespace {{ .Release.Namespace }} -l app{{ template fullname . }} -o jsonpath{.items[0].metadata.name}) echo Visit http://127.0.0.1:8080 to use your application kubectl port-forward $POD_NAME 8080:{{ .Values.service.externalPort }} {{- end }}这就是模板 values解耦的核心价值同一套模板仅通过改变 values 即可部署到不同环境、不同命名空间、不同 Service 暴露方式而无需复制粘贴多份 YAML。Helm 常用命令Helm 常用命令如下helm create在本地创建新的 charthelm dependency管理 chart 依赖helm install安装 charthelm lint检查 chart 配置是否有误helm list列出所有 releasehelm package打包本地 charthelm repo列出、增加、更新、删除 chart 仓库helm rollback回滚 release 到历史版本helm pull拉取远程 chart 到本地helm search使用关键词搜索 charthelm uninstall卸载 releasehelm upgrade升级 release使用helm -h可以查看 Helm 命令行使用详情各子命令亦支持helm 子命令 -h查看详细参数。安装 Chart安装 Chart 的命令格式为helm install [NAME] [CHART] [flags]常用示例# 安装本地 chart helm install -f myvalues.yaml myredis ./redis # 指定变量 helm install --set nameprod myredis ./redis # 指定变量的值为 string 类型 helm install --set-string long_int1234567890 myredis ./redis # 指定引用的文件地址 helm install --set-file my_scriptdothings.sh myredis ./redis # 同时指定多个变量 helm install --set foobar --set foonewbar myredis ./redis其中参数含义如下myvalues.yaml自定义变量配置文件通过-f传入可同时传入多个文件后者合并覆盖前者myredisrelease 名称./redis本地的 chart 目录也可以是指定的 chart 压缩包或仓库中的 chart如stable/nginx--set nameprod直接在命令行覆盖单个变量优先级高于-f文件--set-string long_int1234567890强制把值作为 string 类型传入防止长整型被 YAML 解析为数字--set-file my_scriptdothings.sh把文件内容作为变量的值传入常用于注入证书、脚本等大段文本多个--set同时存在时后者会覆盖前者的同名键如上例foo最终为newbar。关于 Chart 的安装方式仓库内 构建私有 Chart 仓库 一文做了系统归纳安装本地 charthelm install .本地目录或helm install nginx-1.2.3.tgz本地打包文件安装仓库中的 charthelm install stable/nginx默认远程仓库或helm install localhost:8879/nginx-1.2.3.tgz指定仓库地址。Chart 安装后会转化为 Kubernetes 中的资源对象生成一个 chart release可以使用helm list命令查看。提示helm install 中的 install 是正式命令名原文档中出现的 intsall 为笔误实际命令行工具中不存在该拼写请以helm install为准。升级、回滚与卸载 Chart升级修改本地的 chart 配置后执行helm upgrade [RELEASE] [CHART] [flags]升级时可以同样使用-f、--set等方式传入新配置。每次执行helm upgraderelease 的版本号revision递增。回滚使用helm list或helm ls查看当前运行 chart 的 release 版本号然后回滚到指定历史版本helm rollback RELEASE [REVISION] [flags]例如helm rollback myredis 1将 release 回滚到第一个版本。release 的完整升级历史可以通过helm history RELEASE查看回滚操作本身也会作为一个新版本记录在案。卸载helm uninstall RELEASE_NAME [...] [flags]卸载会删除该 release 关联的所有 Kubernetes 资源默认保留 release 的发布历史可通过--keep-history与--no-hooks等参数控制行为因此必要时仍可基于历史记录重建。从 Chart 到 Chart 仓库生态延伸单个 Chart 解决了应用如何打包、如何参数化部署的问题而企业内部应用变多、互相依赖、部署环境复杂之后直接使用散落的 YAML 文件管理已不再适应生产需要此时应构建自己的 Chart 仓库。Chart 仓库repository本质是一个托管index.yaml文件和打包后 chart 文件的 Web 服务器因为其只是通过 HTTP GET 获取 YAML 与压缩包所以可以托管在 GCS、Amazon S3、GitHub Pages 等任意静态存储上。完整流程打包 → 生成 index → 推送静态服务器 →helm repo add→ 安装参见仓库内 构建私有 Chart 仓库 一文。依赖管理方面有两种方式直接在本地 chart 的charts/目录下放置子 chart或在requirements.yamlHelm 2 语法Helm 3 中为Chart.yaml的dependencies字段中声明依赖。子 chart 的特点是无法访问父 chart 中的配置但父 chart 可以覆盖子 chart 中的配置。仓库中另外两个与 Helm 深度相关的实战文档也值得延伸阅读用 Helm 托管安装 Ceph 集群并提供后端存储展示如何用 ceph-helm 项目在 Kubernetes 中以托管方式部署 Ceph注意其中helm init/helm serve为 Helm 2 时代命令Helm 3 下已不再需要 Tiller构建私有 Chart 仓库基于 GitHub Pages 构建私有 Chart 仓库并部署 Monocular UI 前端进行 Chart 的展示与搜索。小结本文以 kubernetes-handbook 仓库的 practice/helm.md 为主线结合 manifests/charts/mychart 的完整实例系统梳理了 Helm 3 下从 Chart 目录结构、Go template 渲染、values 参数注入到 install / upgrade / rollback / uninstall 完整生命周期的使用方式。核心要点可概括为Chart 是模板 默认值的组合templates/目录存放 Go template 渲染的资源定义values.yaml提供默认值并在安装/升级时按优先级默认值 -f文件 --set命令行被覆盖release 是 Chart 的一次独立部署实例同一 Chart 可部署多次版本号随helm upgrade递增可随时helm rollback回滚模板中的命名函数应遵循 63 字符截断等 Kubernetes 命名约束公共逻辑收敛到_helpers.tpl中复用。在此基础上可通过helm package打包、托管静态服务器构建私有 Chart 仓库实现企业级应用的分发与版本治理。参考practice/helm.md本文主体来源manifests/charts/mychart仓库内完整的 Chart 实例Chart.yaml、values.yaml、templates/ 全套模板practice/create-private-charts-repo.md构建私有 Chart 仓库与 Monocular UIpractice/ceph-helm-install-guide-zh.mdHelm 托管安装 Ceph 的实战案例【免费下载链接】kubernetes-handbookKubernetes 架构与生态从云原生到 AI 原生基础设施的构建指南项目地址: https://gitcode.com/gh_mirrors/ku/kubernetes-handbook创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表