内容简介

本实验手册系列包含七个主题,涵盖了从应用容器化到 GitOps 工作流的实现与高级特性。通过这些实验手册,您将学习到如何构建、部署和管理应用,以及如何在 Kubernetes 集群上实现高效的持续交付流程。

以下是实验手册的七个章节:

  1. 应用程序容器化实验手册:学习如何将应用程序容器化,并为主流编程语言构建镜像。同时,了解如何缩减镜像体积和使用 GitHub Actions 自动构建镜像。
  2. 单节点 Kubernetes 集群部署实验手册:使用 kind 在本地部署单节点 Kubernetes 集群,安装基础服务,并熟悉 Kubernetes 的基本功能,如运行 Pod、调度工作负载、服务发布和自动扩缩容。
  3. 示例应用的部署和解析实验手册:深入了解示例应用的各个组件,学习如何在 Kubernetes 集群上部署、运行和管理这些组件,实现服务调用、应用配置和扩缩容等功能。
  4. 使用 Helm 定义应用实验手册:通过 Helm 对示例应用进行定义,以满足 GitOps 部署的需求。了解 Helm Chart 的创建和使用,以及预发布和生产环境的部署。
  5. 构建 GitOps 工作流实验手册:在 Kubernetes 集群上安装 ArgoCD,并使用 ArgoCD 定义示例应用进行部署,实现基于镜像版本变化触发的 GitOps 工作流。
  6. 实现 GitOps 高级发布策略实验手册:结合 ArgoCD 的高级特性,如 Argo Rollout、AnalysisTemplate 和 Argo Rollout Dashboard,实现蓝绿发布、金丝雀发布和自动渐进交付。
  7. ArgoCD 高级管理特性实验手册:探讨 ArgoCD 在 GitOps 场景中的高级特性,包括使用 ApplicationSet 实现多环境部署和使用 SealedSecret 保护密钥。

通过这七个实验手册,您将全面掌握应用容器化、Kubernetes 和 GitOps 的相关知识,为应用的持续交付提供可靠和高效的解决方案。

在之前的实验场景基础上,本实验手册将指导您使用 Helm 定义后续 GitOps 环境中所需的示例应用,以满足 GitOps 部署的要求。

本实验手册将涵盖以下主要实验环节:

  1. 改造示例应用:创建 Helm Chart 目录结构,编写 chart.yaml 文件,填充 templates 目录。
  2. 部署 Helm Chart:分别在预发布环境和生产环境中进行部署。
  3. 发布 Helm Chart:将 Helm Chart 推送至 GitHub 仓库。
  4. 常见的 Helm 应用管理操作:了解 Helm 的基本命令和操作,以便更有效地进行应用管理

改造示例应用

创建 Helm Chart 目录结构

cd kubernetes-example && mkdir helm
mkdir helm/templates && touch helm/Chart.yaml && touch helm/values.yaml
$ ls helm                 
Chart.yaml  templates   values.yaml

配置 Chart.yaml 内容

将下面的内容复制到 Chart.yaml 文件内。

apiVersion: v2
name: kubernetes-example
description: A Helm chart for Kubernetes
type: application
version: 0.1.0
appVersion: "0.1.0"
  • <apiVersion> 字段设置为 v2,表示使用 Helm 3 来安装应用。
  • <name> 表示 Helm Chart 的名称,当使用 helm install 命令安装 Helm Chart 时,指定的名称也是此处配置的名称。
  • <description> 表示 Helm Chart 的描述信息,可根据需要填写。
  • <type> 表示类型,此处固定为 application,代表 Kubernetes 应用。
  • <version> 表示打包的 Helm Chart 的版本,当使用 helm install 时,可以指定此处定义的版本号。Helm Chart 的版本通过这个字段来管理,发布新的 Chart 时,需要更新此版本号。
  • <appVersion> 与 Helm Chart 无关,用于定义应用的版本号,建立当前 Helm Chart 和应用版本的关系。

填充 helm/templates

helm/templates 目录用于存放模板文件,这些模板文件可以是 Kubernetes Manifest。因此,现在可以尝试不使用 Helm Chart 的模板功能,而是直接将 deploy 目录下的 Kubernetes Manifest 复制到 helm/templates 目录下。

cp -r deploy/ helm/templates/
helm
├── Chart.yaml
├── templates
│   └── deploy
│       ├── backend.yaml
│       ├── database.yaml
│       ├── frontend.yaml
│       ├── hpa.yaml
│       └── ingress.yaml
└── values.yaml

其中,values.yaml 的文件内容为空。

到这里,一个最简单的 Helm Chart 就编写完成了。在这个 Helm Chart 中,templates 目录下的 Manifest 的内容是确定的,安装这个 Helm Chart 等同于使用 kubectl apply 命令,接下来尝试使用 helm install 命令来安装这个 Helm Chart。

helm install my-kubernetes-example ./helm --namespace example --create-namespace

在此命令中,指定应用的名称为 my-kubernetes-example,Helm Chart 目录为 ./helm 目录,并为应用指定命名空间为 example。需要注意的是,example 命名空间并不存在,因此同时使用 --create-namespace 选项来让 Helm 自动创建这个命名空间。

此外,这里还涉及一个非常重要的概念:Release Name。在安装时,需要指定 Release Name,即 my-kubernetes-example,它与 Helm Chart Name 存在本质区别。Release Name 是在安装时指定的,而 Helm Chart Name 在定义阶段就已经固定。

使用模板变量

然而,刚才改造的最简单的 Helm Chart 无法满足多环境配置差异化的需求。到目前为止,它只是一个纯静态应用。

为了将这个静态的 Helm Chart 改造成参数动态可控制的,需要使用模板变量和 values.yaml

还记得之前提到的 values.yaml 的概念吗?模板变量的值都会引自这个文件。在这个例子中,根据对不同环境配置差异化的要求,抽象了以下可配置项:

  • 镜像版本
  • HPA CPU 平均使用率
  • 是否启用集群内
  • 数据库连接地址、账号和密码

这些可配置项都需要从 values.yaml 文件中读取,因此,需要将以下内容复制到 helm/values.yaml 文件内。

frontend:
  image: chengzh/frontend
  tag: latest
  autoscaling:
    averageUtilization: 90

backend:
  image: chengzh/backend
  tag: latest
  autoscaling:
    averageUtilization: 90

database:
  enabled: true
  uri: pg-service
  username: postgres
  password: postgres
  

除了 values.yaml,还需要让 helm/templates 目录下的文件能够读取 values.yaml 的内容,这就需要使用模板变量。

以一个简单的例子来说明,要读取 values.yaml 中的 frontend.image 字段,可以通过 {{ .Values.frontend.image }} 模板变量来获取值。

因此,为了将这个“静态”的 Helm Chart 改造成“动态”的,只需用模板变量替换 templates 目录下需要实现“动态”的字段。

了解原理后,接下来修改 helm/templates/backend.yaml 文件,用模板替换需要从 values.yaml 读取的字段

apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend
  ......
spec:
  ......
    spec:
      containers:
      - name: flask-backend
        image: "{{ .Values.backend.image }}:{{ .Values.backend.tag }}"
        env:
        - name: DATABASE_URI
          value: "{{ .Values.database.uri }}"
        - name: DATABASE_USERNAME
          value: "{{ .Values.database.username }}"
        - name: DATABASE_PASSWORD
          value: "{{ .Values.database.password }}"

同理,修改 helm/templates/frontend.yaml 文件的 image 字段。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend
  ......
spec:
  ......
    spec:
      containers:
      - name: react-frontend
        image: "{{ .Values.frontend.image }}:{{ .Values.frontend.tag }}" 

此外,还需要修改 helm/templates/hpa.yaml 文件的 averageUtilization 字段。

......
metadata:
  name: frontend
spec:
  ......
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: {{ .Values.frontend.autoscaling.averageUtilization }}
---
......
metadata:
  name: backend
spec:
  ......
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: {{ .Values.backend.autoscaling.averageUtilization }}

需要注意的是,与其他模板变量不同,在这里没有在模板变量的外部使用双引号。这是因为 averageUtilization 字段是一个整数(integer)类型,而双引号加上模板变量表示字符串(string)类型。

最后,希望使用 values.yaml 中的 database.enable 字段来控制是否向集群提交 helm/templates/database.yaml 文件。因此,在文件的首行和最后一行可以添加以下内容:

{{- if .Values.database.enabled -}}
......
{{- end }}

到这里,就成功地将“静态”的 Helm Chart 改造为了“动态”的 Helm Chart。

部署 Helm Chart

在将示例应用改造成 Helm Chart 之后,就可以使用 helm install 进行安装了。这里我会将 Helm Chart 分别安装到 helm-staging 和 helm-prod 命名空间,它们对应预发布环境和生产环境,接着我会介绍如何为不同的环境传递不同的参数。

部署预发布环境

为 Helm Chart 创建的 values.yaml 实际上是默认值,在预发布环境,希望将前后端的 HPA CPU averageUtilization 从默认的 90 调整为 60,可以在安装时使用 --set 来调整特定的字段,不需要修改 values.yaml 文件。

helm install my-kubernetes-example ./helm --namespace helm-staging --create-namespace --set frontend.autoscaling.averageUtilization=60 --set backend.autoscaling.averageUtilization=60
controlplane $ helm install my-kubernetes-example ./helm --namespace helm-staging --create-namespace --set frontend.autoscaling.averageUtilization=60 --set backend.autoscaling.averageUtilization=60
NAME: my-kubernetes-example
LAST DEPLOYED: Thu Feb 23 03:00:51 2023
NAMESPACE: helm-staging
STATUS: deployed
REVISION: 1
TEST SUITE: None

小插曲,可能会遇到如下错误

Error: unable to build kubernetes objects from release manifest: unable to recognize "": no matches for kind "HorizontalPodAutoscaler" in version "autoscaling/v2beta2"

解决方案,查询一下当前版本的 k8s 支持的 api 版本,对 hap.yaml 进行必要的调整

kubectl api-versions | grep autoscaling
autoscaling/v1
autoscaling/v2

在这个安装例子中,使用 --set 参数来调整 frontend.autoscaling.averageUtilization 字段值,其它的字段值仍然采用 values.yaml 提供的默认值。

部署完成后,可以查看为预发布环境配置的后端服务 HPA averageUtilization 字段值。

kubectl get hpa backend -n helm-staging --output jsonpath='{.spec.metrics[0].resource.target.averageUtilization}'
controlplane $ kubectl get hpa backend -n helm-staging --output jsonpath='{.spec.metrics[0].resource.target.averageUtilization}'
60controlplane $ 

返回值为 60,和配置的安装参数一致。

同时,也可以查看是否部署了数据库,也就是 postgres 工作负载。

kubectl get deployment postgres -n helm-staging
controlplane $ kubectl get deployment postgres -n helm-staging
NAME       READY   UP-TO-DATE   AVAILABLE   AGE
postgres   1/1     1            1           4m32s

postgres 工作负载存在,符合预期。

最后,可以查看 backend Deployment 的 Env 环境变量,以便检查是否使用集群内的数据库实例

kubectl get deployment backend -n helm-staging --output jsonpath='{.spec.template.spec.containers[0].env[*]}'

controlplane $ kubectl get deployment backend -n helm-staging --output jsonpath='{.spec.template.spec.containers[0].env[*]}'
{"name":"DATABASE_URI","value":"pg-service"} {"name":"DATABASE_USERNAME","value":"postgres"} {"name":"DATABASE_PASSWORD","value":"postgres"}controlplane $ 

部署生产环境

部署到生产环境的例子相对来说配置项会更多,除了需要修改 database.enable 字段,禁用集群内数据库实例以外,还需要修改数据库连接的三个环境变量。所以,使用另一种安装参数传递方式:使用文件传递。要使用文件来传递安装参数,

首先需要准备这个文件。需要将下面的内容保存为 helm/values-prod.yaml 文件。

frontend:
  autoscaling:
    averageUtilization: 50

backend:
  autoscaling:
    averageUtilization: 50

database:
  enabled: false
  uri: 10.10.10.10
  username: external_postgres
  password: external_postgres

接下来,使用 helm install 命令来安装它,同时指定新的 values-prod.yaml 文件作为安装参数。

helm install my-kubernetes-example ./helm -f ./helm/values-prod.yaml --namespace helm-prod --create-namespace

部署完成后,可以查看为生产环境配置的后端服务 HPA averageUtilization 字段值。

kubectl get hpa backend -n helm-prod --output jsonpath='{.spec.metrics[0].resource.target.averageUtilization}'
controlplane $ kubectl get hpa backend -n helm-prod --output jsonpath='{.spec.metrics[0].resource.target.averageUtilization}'
50controlplane $ 

返回值为 50,和在 values-prod.yaml 文件中定义的安装参数一致。

同时,也可以查看是否部署了数据库,也就是 postgres 工作负载。

kubectl get deployment postgres -n helm-prod   
controlplane $ kubectl get deployment postgres -n helm-prod   
Error from server (NotFound): deployments.apps "postgres" not found

可以发现,postgres 工作负载并不存在,符合预期。最后,可以查看 backend Deployment 的 Env 环境变量,检查是否使用了外部数据库。

kubectl get deployment backend -n helm-prod --output jsonpath='{.spec.template.spec.containers[0].env[*]}'
controlplane $ kubectl get deployment backend -n helm-prod --output jsonpath='{.spec.template.spec.containers[0].env[*]}'
{"name":"DATABASE_URI","value":"10.10.10.10"} {"name":"DATABASE_USERNAME","value":"external_postgres"} {"name":"DATABASE_PASSWORD","value":"external_postgres"}

返回结果同样符合预期。到这里,将实例应用改造成 Helm Chart 的工作已经全部完成了。

发布 Helm Chart

在 Helm Chart 编写完成之后,便能够在本地安装它了。不过,通常还会有和其他人分享 Helm Chart 的需求。

为实现这个需求,需要将在上面创建的 Helm Chart 打包并且上传到 Helm 仓库中即可。这里以 GitHub Package 为例,介绍如何将 Helm Chart 上传到镜像仓库。

创建 GitHub Token

为了创建一个GitHub Token,用于发布Helm Chart,您需要执行以下步骤:

  1. 登录到您的GitHub帐户。

  2. 点击右上角的头像,然后从下拉菜单中选择Settings(设置)。

  3. 在左侧的导航菜单中,点击Developer settings(开发者设置)。

  4. 点击Personal access tokens(个人访问令牌)选项卡。

  5. 点击页面右上角的Generate new token(生成新令牌)按钮。

  6. 输入一个描述性的令牌名称,例如“Helm Chart Publishing”。

  7. 选择要授予此访问令牌的权限范围。对于Helm Chart发布,通常需要以下权限:

    • repo(仓库):允许对私有仓库和公共仓库的完全访问。
    • write:packages:允许将容器镜像发布到GitHub Packages。
    • delete:packages:允许删除GitHub Packages中的容器镜像(可选,取决于您是否需要删除功能)。

    根据您的需求选择其他权限。

  8. 点击页面底部的Generate token(生成令牌)按钮。

  9. 成功创建令牌后,页面顶部会显示一个绿色的通知,其中包含新生成的访问令牌。请务必立即复制此令牌,因为您以后将无法再次查看它。如果您不小心关闭了页面,您需要生成一个新的访问令牌。

现在您已经创建了一个GitHub个人访问令牌,可以在API调用、命令行工具或GitHub Actions工作流程中使用它进行身份验证。为了安全起见,请不要在公共场所共享您的个人访问令牌。

(可选)接下来,您可以在GitHub仓库中创建一个Secret,用于存储您刚刚创建的访问令牌。这样,在GitHub Actions工作流程中,您可以通过${{ secrets.YOUR_SECRET_NAME }}引用这个Secret。

推送 Helm Chart

在推送之前,还需要使用 GitHub ID 和刚才创建的 Token 登录到 GitHub Package。

helm registry login -u cloudzun https://ghcr.io
~/kubernetes-example$ helm registry login -u cloudzun https://ghcr.io
Password:
Login Succeeded

请注意,由于 GitHub Package 使用的是 OCI 标准的存储格式,如果使用的 helm 版本小于 3.8.0,则需要在运行这条命令之前增加 HELM_EXPERIMENTAL_OCI=1 的环境变量启用实验性功能。然后,返回到示例应用的根目录下,执行 helm package 命令来打包 Helm Chart。

然后,返回到示例应用的根目录下,执行 helm package 命令来打包 Helm Chart。

helm package ./helm

这条命令会将 helm 目录打包,并生成 kubernetes-example-0.1.0.tgz 文件。接下来,就可以使用 helm push 命令推送到 GitHub Package 了。

helm push kubernetes-example-0.1.0.tgz oci://ghcr.io/cloudzun/helm

命令运行结束后将展示 Digest 字段,就说明 Helm Chart 推送成功了。

helm package ./helm
Successfully packaged chart and saved it to: /home/chengzh/kubernetes-example/kubernetes-example-0.1.0.tgz
helm push kubernetes-example-0.1.0.tgz oci://ghcr.io/cloudzun/helm
Pushed: ghcr.io/cloudzun/helm/kubernetes-example:0.1.0
Digest: sha256:2f3d04c9f2fda3e948dd31a96ba60b9bd2a939f16708ef5fb964f5d81314281f

安装远端仓库的 Helm Chart

当成功把 Helm Chart 推送到 GitHub Package 之后,就可以直接使用远端仓库来安装 Helm Chart 了。和一般的安装步骤不同的是,由于 GitHub Package 仓库使用的是 OCI 标准的存储方式,所以无需执行 helm repo add 命令添加仓库,可以直接使用 helm install 命令来安装。

helm install my-kubernetes-example oci://ghcr.io/cloudzun/helm/kubernetes-example --version 0.1.0 --namespace remote-helm-staging --create-namespace --set frontend.autoscaling.averageUtilization=60 --set backend.autoscaling.averageUtilization=60

在上面的安装命令中,oci://ghcr.io/cloudzun/helm/kubernetes-example 是 Helm Chart 的完整的地址,并标识了 OCI 关键字。另外,version 字段指定的是 Helm Chart 的版本号。在安装时,同样可以使用 --set 或者指定 -f 参数来覆写 values.yaml 的字段。

 helm install my-kubernetes-example oci://ghcr.io/cloudzun/helm/kubernetes-example --version 0.1.0 --namespace remote-helm-staging --create-namespace --set frontend.autoscaling.averageUtilization=60 --set backend.autoscaling.averageUtilization=60
Pulled: ghcr.io/cloudzun/helm/kubernetes-example:0.1.0
Digest: sha256:2f3d04c9f2fda3e948dd31a96ba60b9bd2a939f16708ef5fb964f5d81314281f
NAME: my-kubernetes-example
LAST DEPLOYED: Thu Feb 23 11:39:04 2023
NAMESPACE: remote-helm-staging
STATUS: deployed
REVISION: 1
TEST SUITE: None

Helm 应用管理

总结来说,Helm Chart 和 Manifest 之间一个最大的区别是,Helm 从应用的角度出发,提供了应用的管理功能,通常在实际使用 Helm 过程中会经常遇到下面几种场景。

调试 Helm Chart

在编写 Helm Chart 的过程中,为了方便验证,会经常渲染完整的 Helm 模板而又不安装它,这时候就可以使用 helm template 命令来调试 Helm Chart。

helm template ./helm -f ./helm/values-prod.yaml

此外,还可以在运行 helm install 命令时增加 --dry-run 参数来实现同样的效果。

helm install my-kubernetes-example oci://ghcr.io/cloudzun/helm/kubernetes-example --version 0.1.0 --dry-run

查看已安装的 Helm Release

要查看已安装的 Helm Release,可以使用 helm list 命令。

helm list -A

更新 Helm Release

要更新 Helm Release,可以使用 helm upgrade 命令,Helm 会自动对比新老版本之间的 Manifest 差异,并执行升级。

helm upgrade my-kubernetes-example ./helm -n example

查看 Helm Release 历史版本

要查看 Helm Release 的历史版本,可以使用 helm history 命令。

helm history my-kuebrnetes-example -n example

回滚 Helm Release

当 Helm Release 有多个版本时,可以通过 helm rollback 命令回滚到指定的版本。

helm rollback my-kubernetes-example 1 -n example

卸载 Helm Release

要卸载 Helm Release,可以使用 helm uninstall

helm uninstall my-kubernetes-example -n example

后记

本课程体系旨在为学员提供一套全面的云原生技术学习路径,包括容器技术、Kubernetes 部署和管理、Ingress 管理、持久化存储、应用部署、可观测性、服务网格、DevOps 工具链和流水线以及 GitOps 等方面的内容。通过学习这套课程体系,学员将掌握云原生技术的关键概念、原理和实践方法,从而提升云原生应用的部署、管理和协作效率。

  1. Docker 技术实战:学习容器技术的基础知识,包括 Docker 的运作原理、核心组件以及应用部署和监控管理。
  2. Kubernetes 部署和管理实战:深入了解 Kubernetes 的核心概念和基础组件,掌握 Kubernetes 集群的部署、管理和监控技能。
  3. Kubernetes Ingress 管理与运维:学习 Kubernetes Ingress 的概念、工作机制和运维管理方法,提升 Ingress 的部署和管理能力。
  4. Kubernetes 持久化存储实践:探讨 Kubernetes 持久化存储的原理、实现方式和实际应用,提高在 Kubernetes 上实现持久化存储的能力。
  5. Kubernetes 应用部署和管理:学习 Kubernetes 应用部署和管理的基本概念、原理和实现方法,掌握在 Kubernetes 上部署和管理应用的技巧。
  6. Kubernetes 可观测性实践:研究 Kubernetes 可观测性实践的概念、原理和实现方法,涉及监控、日志记录和分析等方面。
  7. 基于 Istio 的服务网格实战:深入了解基于 Istio 的服务网格概念、原理和实现方法,包括服务路由、流量管理、弹性能力和微服务可观测性等。
  8. DevOps 工具链与流水线实践:探讨 DevOps 工具链与流水线的概念、原理和实现方法,涵盖自动化构建、测试、部署和监控等环节。
  9. GitOps 云原生应用的高效部署与管理:全面掌握 GitOps 原理、技术和工具,提高云原生应用部署、管理和协作效率。

通过对这九门课程的学习,学员可以:

  1. 熟练运用 Docker 和 Kubernetes 进行容器化应用的部署和管理。
  2. 掌握 Ingress 和持久化存储在 Kubernetes 集群中的配置和管理方法。
  3. 了解 Kubernetes 可观测性实践,提高应用监控、日志和分析的能力。
  4. 探究 Istio 服务网格的原理和实现,实现微服务的高可用、弹性和安全。
  5. 运用 DevOps 工具链和流水线实现自动化构建、测试、部署和监控。
  6. 掌握 GitOps 的原理和技术,提升云原生应用的部署、管理和协作效率。

本课程体系适合对云原生技术感兴趣的开发者、运维工程师、架构师等专业人士。课程内容丰富、实践性强,旨在帮助学员在实际工作中更好地应用云原生技术,为企业的数字化转型做出贡献。

如果希望获得更详细的课程介绍,请联系: info@cloudzun.com

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐