自动检查 Kubernetes YAML 的质量
如果您曾经想过如何确保 YAML Kubernetes 对象定义正确并遵循行业最佳实践,那么这篇博文正适合您。我将用几段文字向您展示如何创建一个 GitHub Actions 工作流,该工作流首先使用 Datree 分析 K8s 对象定义,然后将其部署到集群上并运行一些测试。
无论您是 Kubernetes 新手还是专家,编写对象定义都不是一件容易的事。您很容易犯错,如果部署到生产环境,这可能会付出高昂的代价。如果您才刚刚开始学习 Kubernetes,您可能需要帮助了解应该提供哪些元数据和规范,但根据设计,这些并非强制性的。
应对这些挑战的理想方法是请一位经验丰富的同事审查你的代码更改。但有时你身边没有这样的人,或者很难从他们那里获得反馈。即使你确实有一位优秀的人来帮助你,也无法避免你偶尔犯错。
相反,我想向您展示另一种方法:使用Datree.io、Google Kubernetes Engine和Github Actions对您的 K8s 对象定义创建一个简单的自动化质量检查。
我们将构建一个 GitHub Actions 工作流,该工作流将在主分支上每次发生更改后触发。该工作流将分为两个阶段:
- Datree缺失配置分析和质量检查,
- 在真实集群( GKE )中部署和测试示例应用程序。
所以,卷起袖子,让我们实现自动化吧!
工作流结构
首先,你需要一个 GitHub 仓库来保存我们的 YAML 文件。我使用的是我的旧项目 - k8s-helm-helmfile 。这个仓库包含三个文件夹,每个文件夹包含一种将应用程序部署到 Kubernetes 集群的不同方法。你可以在我之前关于原生 K8s、Helm和helmfile部署的博客文章中了解更多关于这些方法的信息。
为了使这篇博文简短,我将展示如何创建使用 Helm 部署应用程序的工作流,但您也可以使用其他方法(例如前面提到的方法)轻松完成此操作。
第一步是创建工作流定义文件。在仓库的根文件夹中创建一个新目录./github/workflows,其中包含一个master.yaml
文件:
name: Quality check
on:
push:
branches:
- 'master'
它包含以下规范:
name
- 我们的工作流程的名称on
- 触发工作流的条件。仅当master
分支上提交更改时,工作流才会启动。
有了它,您就可以进入最好的部分——定义工作。
数据树分析
在本部分中,您将使用一个名为Datree的免费工具,它可以分析 K8s 定义,并在发现任何问题时停止工作流程。拥有这样的安全网非常重要,这样您就可以放心,即使您犯了错误,或者不了解最佳实践,助手也会帮助您保持正轨。
在定义 GitHub 工作流程之前,让我们先在本地安装Datree。为此,请访问他们的官方网站,该网站将指导您如何安装Datree CLI。我使用的是 Linux(或者更准确地说是 WSL),因此只需要以下命令:
> curl https://get.datree.io | /bin/bash
几秒钟后,Datree 就会安装完毕。
要进行测试,请转到 Kubernetes YAML 文件所在的文件夹并运行Datree测试命令(在我的情况下,我使用来自k8s-helm-helmfile 项目的 vanilla K8s 文件):
> datree test adminer-deployment.yaml
其中该adminer-deployment.yaml
文件是 Kubernetes 对象定义。
这是我得到的输出:
如您所见,Datree准备了一份简短的摘要,列出了此 YAML 文件违反的规则数量。它提供了非常有用的解释,并提示了如何修复这些规则。
从这里开始,您可以逐一处理问题,确保这些测试通过。这是一种很好的学习和练习方式。但是,如果您故意选择不遵守某些规则,该怎么办?幸运的是,Datree提供了自定义策略的功能,即一组用于检查 YAML 文件的规则。
要设置策略,您需要前往您的仪表板。您的个人链接位于每次扫描的末尾,在摘要表的最后一行See all rules in policy
(我在之前的截图中标记了它)。它会带您进入登录页面。
然后你需要登录。为了方便起见,我建议使用 GitHub 帐户。授权成功后,你将进入“策略”页面。
您可以在此处查看所有可启用和禁用的规则。默认情况下,只有部分规则处于启用状态。要启用或禁用这些规则,请使用规则名称旁边的切换按钮。
如果规则名称过于晦涩难懂,您可以点击其名称查看其详细信息。它会显示更多信息,以及违反此规则时的示例输出。
另一个很酷的功能是,您可以自定义解决问题的提示。默认设置应该足够了,但如果您想扩展它,使用您自己的语言查看,或者添加博客文章、Stack Overflow 讨论或任何其他在线资料的链接,只需点击“编辑”按钮即可将其添加在此处。
最后,您可以创建自己的规则集(称为策略),以针对不同的应用程序、环境和阶段运行。只需点击页面顶部的“创建策略”按钮即可。
现在让我们查看左侧面板上的第二个页面,名为“历史记录”。顾名思义,在这里您可以方便地查看所有之前测试运行的摘要。
在写这篇文章之前,我已经尝试过Datree,这就是为什么我在历史面板中已经列出了几次测试运行,但在你的情况下你应该只有一次。
这就是对Datree仪表板的快速浏览!
现在让我们构建一个 GitHub Actions 工作流程。
首先,在工作流中将您的Datree令牌作为环境变量提供。为此,请点击Datree仪表板右上角的头像,然后点击“设置”。它会引导您进入可以找到令牌的页面。
复制令牌后,转到 GitHub 项目/存储库的“设置”页面。然后选择“Secrets”,并单击“New repository secret”按钮。
在名称字段中输入从Datree复制的令牌DATREE_TOKEN
,并在值字段中输入。
现在您可以转到工作流的定义文件并定义第一个作业:
jobs:
datree:
name: Validate Helm charts
runs-on: ubuntu-latest
container:
image: dtzar/helm-kubectl:3.6.3
它名为datree
,运行在最新的 Ubuntu 系统上的dtzar/helm-kubectl Docker 容器中。我选择这个设置是因为我想针对 Helm 版本运行测试(而不是像以前那样使用原生 K8s)。选择这个 Docker 镜像的原因是它包含必要的依赖项(K8s 和 Helm),这样我就可以跳过它们的安装,从而加快我的工作流程。
让我们定义接下来的三个步骤:
steps:
- name: Checkout 🛎️
uses: actions/checkout@v2
- name: Install Datree 🔨
run: |
helm plugin install https://github.com/datreeio/helm-datree
- name: Datree test 🔥
env:
DATREE_TOKEN: ${{ secrets.DATREE_TOKEN }}
run: |
helm datree test ./helm/app -- --values ./helm/adminer.yaml
第一步,actions/checkout@v2
您可以从代码库中获取代码。第二步,安装Datree Helm 插件,以便使用 Helm 运行Datree测试。第三步,使用 Helm CLI 运行实际测试。环境变量已添加到其中,因此结果将与DatreeDATREE_TOKEN
帐户关联。
最后,在实际运行脚本中,我提供了 Helm 模板的位置和测试values.yaml
文件的位置。
之后,您可以提交更改并将其推送到 GitHub。它将触发一个工作流,该工作流将在“操作”选项卡中可用。
在我的例子中,有几个测试失败了,这体现在工作流的失败状态上。要了解更多信息,请点击失败的作业。它会带你到控制台输出,在那里你可以调查出了什么问题。
除了在工作流控制台中检查策略检查结果之外,您还可以返回Datree仪表板中的历史记录页面并在那里分析错误。
如果您遇到与我类似的屏幕,请在此处停止,更正错误并将更改推送到 GitHub。如果您觉得某些规则对您来说已经过时,请在Datree仪表板中将其关闭,但不要关闭太多!
修复所有问题并重新运行工作流后,之前标记为红色的 [X] 将变成绿色复选标记 [V],表示工作流已通过验证和策略检查。
还有一些关于工作的详细信息:
成功结果也将显示在Datree仪表板中:
太棒了!我们现在可以进入下一部分了。
在 GKE 上测试
从Datree的角度确保模板没问题后,将其部署到真正的 Kubernetes 集群(非生产环境),然后检查那里的一切是否正常工作,例如,网站是否可以通过互联网访问等。
第一步是创建一个集群。我选择了Google Kubernetes Engine ( GKE ),因为它有免费套餐。但如果你有自己的集群(在 AWS 或其他云提供商上),也可以直接使用它。
现在我将按照为GKE设置作业所需的步骤进行操作,因此如果您已经启动并运行GKE或任何其他 Kubernetes 集群,请跳过此部分。
在将新作业添加到工作流之前,您需要在GKE中设置几项内容(这些说明基于官方GKE 快速入门指南):
- 创建 Google Cloud 帐户。您可以从主页开始,
- 创建或选择一个现有的 Google Cloud 项目。您可以通过Google Cloud 控制台或Google 项目选择器完成此操作。
- 为项目启用计费功能。您需要提供您的信用卡信息,具体方法请参考此处。请放心,我们不会向您收取任何费用。此步骤仅用于验证您是人类用户。
- 启用GKE API,可在此页面完成。
到目前为止,所有配置都是在网络浏览器中进行的,但现在您需要转到Google Cloud Shell,或者安装 Cloud SDK并按照终端中的说明进行操作:
在工具中设置基本配置gcloud
,例如默认项目、区域和可用区。在我的例子中,项目名称为k8s-helm-helmfile
,区域为europe-central2
,但您的项目名称可能有所不同。
> gcloud config set project k8s-helm-helmfile
> gcloud config set compute/region europe-central2
> gcloud config set compute/zone europe-central2-a
创建一个IAM 服务账户,该账户将在 GitHub Action 工作流中使用。我的账户名为helm-github-actions-service
:
> gcloud iam service-accounts create helm-github-actions-service
从新创建的服务帐户获取一封电子邮件。下一步您将需要它:
> gcloud iam service-accounts list
为服务帐户分配角色,其中<EMAIL>
标签取自上一步:
> gcloud projects add-iam-policy-binding k8s-helm-helmfile \
--member=serviceAccount:<EMAIL> \
--role=roles/container.admin \
--role=roles/storage.admin \
--role=roles/container.clusterAdmin \
--role=roles/iam.serviceAccountUser \
--role=roles/container.developer
导出服务帐户密钥:
> gcloud iam service-accounts keys create key.json --iam-account=<EMAIL>
> export GKE_SA_KEY=$(cat key.json | base64)
将其作为 GitHub Secret 添加到项目中(方法与 for 相同DATREE_TOKEN
),并使用GKE_SA_KEY
as 键。要查看导出密钥的值,可以使用以下命令:
> printenv GKE_SA_KEY
一切都已设置完毕,现在返回到工作流定义,您首先在GKE上创建了一个 Kubernetes 集群,部署了一个示例 Helm 版本并对其进行了测试。
首先创建一个名为的新作业gke
:
gke:
name: Test Helm chart on GKE
needs: datree
runs-on: ubuntu-latest
env:
PROJECT_ID: k8s-helm-helmfile
GKE_CLUSTER: helm-test
GKE_REGION: europe-central2
与上一个示例类似,您有name
和runs-on
配置。此外,还有一个needs
配置,这意味着要运行此作业,首先需要成功完成该作业。这可以防止在Datreedatree
检查期间出现问题时启动集群并部署示例应用程序。作业配置的最后一部分是环境变量(),它们将在工作流步骤中使用。它们是我的 GCP 项目 ID、K8S 集群名称和我的GKE区域。env
继续下一步:
steps:
- name: Checkout 🛎️
uses: actions/checkout@v2
- name: Setup gcloud CLI ⚡
uses: google-github-actions/setup-gcloud@master
with:
service_account_key: ${{ secrets.GKE_SA_KEY }}
project_id: ${{ env.PROJECT_ID }}
第一个是从项目中获取代码。
第二个是配置(登录并设置项目)Google Cloud CLI,它将在后续步骤中用到。
- name: Create Autopilot GKE cluster 🔨
run: |
gcloud container clusters create-auto ${{ env.GKE_CLUSTER }} \
--project=${{ env.PROJECT_ID }} \
--region=${{ env.GKE_REGION }}
- name: Config kubectl for GKE cluster ⚡
uses: google-github-actions/get-gke-credentials@main
with:
cluster_name: ${{ env.GKE_CLUSTER }}
location: ${{ env.GKE_REGION }}
credentials: ${{ secrets.GKE_SA_KEY }}
上述步骤创建了一个新的 GKE 集群,并配置了 kubectl,使其与新创建的集群连接。之后,您可以继续安装管理员 Helm 版本的步骤:
- name: Deploy test Helm release 🚀
uses: deliverybot/helm@v1
with:
release: adminer
namespace: default
chart: ./helm/app
helm: helm3
value-files: ./helm/adminer.yaml
values: |
app:
service:
type: LoadBalancer
到这里就停下来,分析一下发生了什么。首先,您正在使用deliverybot/helm GitHub Actions,它提供了一种便捷的 Helm 使用方式。只需添加一些参数,就可以将应用程序部署到 Kubernetes 集群上。完整的可用参数列表可以在官方网站上找到。
在上面的例子中,我单独使用了以下步骤:
release
- 版本名称,namespace
- 指定将安装应用程序的 K8s 命名空间,chart
- 提供有关舵图位置的信息,helm
- 表示将使用哪个版本的 Helm,value-files
- 用于覆盖 Helm chart 中默认值的文件,在我的例子中,它是 Adminer 的 values.yaml 文件(我用于测试的 Helm chart,它部署了流行的数据库客户端 - Adminer),values
- 此参数的工作方式与上一个参数非常相似 - 它用于覆盖 Helm 图表中的默认值,但我们不是使用文件来执行此操作,而是直接指定需要覆盖的值;在这里,我只覆盖服务类型,因为默认情况下它是ClusterIP
,但我不想在 adminer.yaml 文件中更改它。
安装成功后,我们的工作流程就可以进行测试了。我决定运行一个非常简单的测试,它只检查页面是否打开,当然,你也可以构建一个更复杂的测试链。
- name: Test installed application 🔥
run: |
export IP_ADDRESS=$(kubectl get services -o=jsonpath='{.items[0].status.loadBalancer.ingress[0].ip}')
echo "$IP_ADDRESS"
curl http://"$IP_ADDRESS":8080
测试脚本的第一行用于找出管理员应用程序暴露在哪个 IP 地址下。第二行用于调试,最后一行用于实际测试。
测试完成后,您需要销毁一个集群:
- name: Delete cluster GKE Cluster 💥
if: ${{ always() }}
run: |
gcloud container clusters delete ${{ env.GKE_CLUSTER }} --zone=${{ env.GKE_REGION }} --quiet
这if: ${{ always() }}
部分非常重要。它确保即使前面任何一个步骤失败,这一步也能始终运行。否则,你可能会在月底收到谷歌的账单。
提交更改并将其推送到 GitHub 后,工作流程将如下所示:
首先执行Datree步骤,然后在GKE上完成安装。要查看第二步的详细信息,请点击其名称。
结论
今天就到这里!我希望这篇博文能鼓励您自己构建类似的项目,尝试一下Datree(或任何其他静态代码分析工具),并设置一个集群进行自动化测试,这样您就可以对代码库中所做的更改更有信心。所有这些都可以在一瞬间完成设置和运行。
文章来源:https://dev.to/wkrzywiec/automating-quality-checks-for-kubernetes-yamls-398