是否有使用kubectl v1.17修补多个资源的DRY方法?



我在一些限制下工作,超出了我的控制范围,即CI/CD管道和基础设施。

我一直在本地控制台上测试我的自定义,它有v1.21,但我的管道运行的是v1.17。

所以components出局了,显然是用patches对象来修补多个资源:https://github.com/kubernetes-sigs/kustomize/issues/1373#issuecomment-618439078不,直接调用kustomize(任何版本)也不可用。

不使用组件,我可以处理,但是多补丁支持似乎是非常基本的。

下面是我所做的一个基本例子:

root
|- kube
|- kustomize
|- base
|    |- job_dir
|    |   |- job1.yml
|    |   |- ..
|    |- job.patch.yml 
|    |   # config that applies to some jobs
|    |- kustomization.yml
|         # resources:
|         #   - job_dir/job1.yml
|         #   - ..
|         #     
|         # patches:
|         #   - target:
|         #       kind: Job
|         #     patch: |-
|         #       - op: add
|         #         ..
|         #   - path: job.patch.yml
|         #     target:
|         #       kind: Job
|         #       labelSelector: patchWith=job.patch
|- overlays
|- dev
|   |- kustomization.yml
|        # images: ..
|- prod
|- kustomization.yml
# images: ..

使用kubectl 1.17执行:

$ kubectl apply -k kube/kustomize/base
error: json: cannot unmarshal object into Go struct field Kustomization.patchesStrategicMerge of type patch.StrategicMerge

使用kubectl 1.20+执行:

kubectl apply -k kube/kustomize/base
job.batch/job1 created
job.batch/..

没有多补丁,我能以某种方式模仿相同的行为吗?

最好使用一些模板工具,如jinja2

值得注意的是,基础设施的实际Kubernetes实例运行的是v1.20,所以那里也有一些限制。(例如,为什么我不直接使用索引作业?)所以,如果有一种方法

我找到一个方法. 这可能不是最好的方法。

您可以使用kubectl patch来修补特定的文件-f PATH、目录-f DIR_PATH、自定义-k DIR_PATH或递归目录-Rf DIR_PATH

您应该小心,因为这会将补丁应用于范围内的所有内容。

例如,当一个ConfigMap在你要为作业应用补丁的目录中时,会发生这样的情况:

$ ls kube/kustomize/base
job.yml config.yml
$ patch='[{op: add, path: /spec/template/spec/restartPolicy, value: Never}]'
$ kubectl patch --local=true --type=json -p "$patch" -o name -R kube/kustomize/base
job.batch/job1
error: add operation does not apply: doc is missing path: "/spec/template/spec/restartPolicy": missing value

在这种情况下,它不是太糟糕,因为没有意外得到补丁,但如果您不小心,您可能会将补丁应用到错误的资源。Globs不能工作,所以你不能基于文件模式打补丁,除非只有一个资源匹配。

所以,-f PATH是最好的,最安全的。

您可以使用如下命令编译正确的文件列表,具体取决于系统:

$ kust_dir="kube/kustomize/base"
$ kust_file="${kust_dir}/kustomization.yml"
$ sed -n '/^resources:s*$/,/^[^ t-]/p' ${kust_file} | tail -n +2 | head -n -1 | sed -i "s@s*-s+@$kust_dir@" > manifest_list.tmp

如果你想以一种万无一有的方式使用标签选择器,它会变得相当复杂,但这种有缺陷的方法适用于大多数情况:

# recursive look for label anywhere in $kust_dir, output filenames, filter output by the existing list of filenames
$ grep -lre "$label:s*$value" $kust_dir | grep -Ff manifest_list.tmp > filtered_by_label.tmp

如前所述,它匹配文件中的任何标签。如果您知道清单中的空白字符串是缩进的,并且它们是统一的,可以这样做:

# indent_str="  " if it's two spaces
$ grep -lre "($indent_str){2}$label:s*$value" $kust_dir | grep -Ff manifest_list.tmp > filtered_by_label.tmp

应该只匹配第一个标签。使用-z-P选项来匹配多行以获得更好的结果,但它可能不适用于每个系统,并且您仍然可能需要知道制表符的数量,或者使用一些find -exec awkfind -exec sed


一旦你有了一个你有信心的文件列表,做这样的事情:

$ for file in $file_list; do
>   kubectl patch --local=true --type=json -p '$patch_str' -o yaml -f $file > $file
> done
$ kubectl apply -k kube/kustomize/base
job/job1 created

您可以使用-R -f kube/kustomize/base/jobs-k kube/kustomize/base将补丁应用于多个资源,但输出将不包括---分隔符,因此您不能将输出写入文件,然后不经过一些处理就应用它。但是你可以把它作为一种可能的选择来修改。

最新更新