使用 –dry-run 和 generateName 验证 Kubernetes 配置

36次阅读
没有评论

问题描述

正在使用 ArgoCD 管理部署,并且正在整理配置存储库。他计划对配置进行验证,以确保不会出现任何问题。他找到了一些选项,如 kubeval、kubeconform 或使用 kubectl 的 –dry-run 选项。由于 kubectl 实际上会连接到集群,并让集群执行验证,因此他更喜欢这种方法,因为它应该能捕捉到所有可能的错误。然而,他遇到了一个问题。其中一个资源使用了 generateName,这与 kubectl apply 不兼容。因此,如果他尝试使用 kubectl apply -f manifest.yaml –dry-run=server 进行验证,就会出现 cannot use generate name with apply 的错误。为了解决这个问题,他尝试使用 kubectl create -f manifest.yaml –dry-run=server,但是却出现了一堆关于资源已经存在的错误(可以理解)。那么他应该如何解决这个问题呢?除了 apply 和 create,还有其他选项吗?有人知道 Argo 使用什么来进行验证吗?因为如果我推送了无效的内容,它会在同步之前显示错误。

解决方案

请注意以下操作注意版本差异及修改前做好备份。

方案1

经过一番尝试,我找到了一个可行的解决方案,我在原问题的评论中简要提到了它。现在,CI 在集群上创建一个命名空间,在运行 dry run apply 后删除该命名空间。虽然这可能不是完美的解决方案,但它按照我希望的方式工作。
以下是一个示例脚本,展示了如何使用这种方法:

helm template . \
  --values common/values-common.yaml \
  --values variants/$VARIANT/values-$VARIANT.yaml \
  --name-template=github-actions-test \
  --set image.tag=github-actions-test \
  --namespace $NAMESPACE \
  --debug > dry-run.yaml

kubectl create namespace $NAMESPACE --dry-run=client -o yaml | kubectl apply -f -

echo "errors=$(kubectl create -f dry-run.yaml -n $NAMESPACE --dry-run=server -o yaml 2>&1 > /dev/null)" >> $GITHUB_OUTPUT

kubectl delete namespace $NAMESPACE

在上面的示例中,我们首先使用 helm template 命令生成一个包含所有配置的 dry-run.yaml 文件。然后,我们使用 kubectl create 命令创建一个命名空间,并将其保存为 dry-run.yaml 文件的一部分。接下来,我们使用 kubectl apply 命令将 dry-run.yaml 文件中的配置应用到命名空间中。最后,我们使用 kubectl delete 命令删除命名空间。
请注意,这只是一个示例脚本,你需要根据自己的需求进行适当的修改。

方案2

使用 k3s 进行测试可能会更方便,你可以在 Kubernetes 集群内(或者在你的笔记本电脑上)启动一个 k3s 实例,然后使用该临时 API 进行测试,测试完成后删除该容器。
另一种方法是编写脚本或使用工具来控制容器的运行顺序。你可以使用docker run命令来手动控制容器的启动顺序,或者使用一些第三方工具来管理容器的依赖关系。

示例:

以下是一个简单的bash脚本示例,可以在容器A启动后启动容器B:

#!/bin/bash
# 启动容器A
docker run -d --name container_a your_image_a
# 等待容器A完全启动
while ! docker exec container_a echo "Container A is ready"; do
  sleep 1
done
# 启动容器B
docker run -d --name container_b your_image_b

在这个示例中,我们首先使用docker run命令启动容器A,并将其命名为container_a。然后,使用一个循环来等待容器A完全启动(这里是通过在容器内运行echo命令来测试)。一旦容器A就绪,我们再使用docker run命令启动容器B,并将其命名为container_b

正文完