关于helm:企业级云原生应用交付及管理系列-Helm-调试及维护-二

5次阅读

共计 5456 个字符,预计需要花费 14 分钟才能阅读完成。

大家好,我是张晋涛。

在上一篇《企业级云原生利用交付及治理系列 – Helm 根底 (一)》中,我次要介绍了
Helm 的诞生及其倒退,包含 Helm 各个版本的状况及社区的倒退。

此外,还介绍了 Helm 的架构,概念,插件以及其根本用法。

本节我将默认读者曾经有肯定的 Helm 和 Kubernetes 根底,
介绍 Helm 的一些高阶个性和用法,
如果有不分明的概念能够看我的历史文章。

筹备

这里咱们应用 helm create 命令来创立一个 Helm chart。执行实现后,会在当前目录创立一个新的目录,其中蕴含了 Helm 事后创立的一个模板。
本文中的后续内容均会基于该 Helm chart 实现。

tao@moelove:~$ helm create moelove
Creating moelove                
tao@moelove:~$ ls                    
moelove
tao@moelove:~$ tree
.
└── moelove
    ├── Chart.yaml
    ├── charts
    ├── templates
    │   ├── NOTES.txt
    │   ├── _helpers.tpl
    │   ├── deployment.yaml
    │   ├── hpa.yaml
    │   ├── ingress.yaml
    │   ├── service.yaml
    │   ├── serviceaccount.yaml
    │   └── tests
    │       └── test-connection.yaml
    └── values.yaml

4 directories, 10 files

Debug

在咱们去创立 / 保护,或者应用 Helm chart 进行利用部署的时候,有时候可能会遇到一些谬误。
那么如何对 Helm chart 进行 debug 呢?这是很多人都会遇到的一个问题。

Helm chart 是通过 YAML 进行保护的,而 YAML 是缩进 / 语法敏感的。
如果你的缩进或者语法有问题,都将会导致报错。
最简略的查看方法是应用 helm lint 进行查看。

比方咱们进行如下批改:

diff --git a/values.yaml b/values.yaml
index 4a8b237..696a77d 100644
--- a/values.yaml
+++ b/values.yaml
@@ -5,7 +5,7 @@
 replicaCount: 1
 
 image:
-  repository: nginx
+ repository: nginx
   pullPolicy: IfNotPresent
   # Overrides the image tag whose default is the chart appVersion.
   tag: ""

能够看到,咱们将 image.repository 的缩进搞错了。
这时进行装置将看到如下报错:

tao@moelove:~$ helm install foo .
Error: INSTALLATION FAILED: cannot load values.yaml: error converting YAML to JSON: yaml: line 9: mapping values are not allowed in this context

我倡议你能够应用 helm lint 先进行查看,防止一些低级谬误。如下:

tao@moelove:~$ helm lint .
==> Linting .
[INFO] Chart.yaml: icon is recommended
[ERROR] values.yaml: unable to parse YAML: error converting YAML to JSON: yaml: line 9: mapping values are not allowed in this context
[ERROR] templates/: cannot load values.yaml: error converting YAML to JSON: yaml: line 9: mapping values are not allowed in this context
[ERROR] : unable to load chart
        cannot load values.yaml: error converting YAML to JSON: yaml: line 9: mapping values are not allowed in this context

Error: 1 chart(s) linted, 1 chart(s) failed

咱们将该内容复原原样,并进行如下变更:

diff --git a/values.yaml b/values.yaml
index 4a8b237..c86c0be 100644
--- a/values.yaml
+++ b/values.yaml
@@ -2,7 +2,7 @@
 # This is a YAML-formatted file.
 # Declare variables to be passed into your templates.
 
-replicaCount: 1
+replicaCount: "this should not be string"
 
 image:
   repository: nginx

replicaCount 批改成了一段字符串。这时候咱们应用 helm lint 是无奈查看进去的。

tao@moelove:~$ helm lint .
==> Linting .
[INFO] Chart.yaml: icon is recommended

1 chart(s) linted, 0 chart(s) failed

因为从 YAML 语法上是无奈查看进去类型的,并且这也是咱们具体的业务逻辑(Kubernetes)限度的。

这时,如果进行装置将失去如下谬误:

tao@moelove:~$ helm install foo .
Error: INSTALLATION FAILED: unable to build kubernetes objects from release manifest: error validating "": error validating data: ValidationError(Deployment.spec.replicas): invalid type for io.k8s.api.apps.v1.DeploymentSpec.replicas: got"string", expected"integer"

能够看到,对于这种类型谬误是能够很间接的失去反馈的。

但还有一种状况,就是语法规定,类型均失常,然而不合乎业务的理论预期。

比方咱们进行如下变更:

diff --git a/values.yaml b/values.yaml
index 4a8b237..8feedd6 100644
--- a/values.yaml                                                                                    
+++ b/values.yaml                                                                                    
@@ -8,7 +8,7 @@ image:
   repository: nginx
   pullPolicy: IfNotPresent
   # Overrides the image tag whose default is the chart appVersion.
-  tag: ""+  tag:"1.20"
  
 imagePullSecrets: []
 nameOverride: ""

这时,能够装置胜利,但可能咱们预期想要装置的镜像是 1.20-alpine
这种场景下,上述两种形式就都没有成果了。

咱们能够通过 helm install --dry-run --debug 命令进行调试。
当然,如果你想通过 helm template 进行调试也能够。

这两者次要的区别在于,如果减少了 --debug 参数的话,能够输入更加具体的信息,
包含最终应用的 Values 信息等。

这是我比拟举荐的做法,适宜在你开发 / 调试 Helm chart 时应用。

Helm 单元测试

谈到 Helm chart 的单元测试,你可能会产生疑难,YAML 也要写单元测试?

是的。如果你是 Helm chart 的维护者的话,写单元测试是个好主见,能够更好的保障大多数内容都是合乎预期的。

如果想要为 Helm chart 写单元测试,我有三个工具举荐。

  • quintush/helm-unittest 是从 helm-unittest/helm-unittest fork 进去的,然而它更加沉闷,并且蕴含了很多性能和修复,此外,它能够很好的与 Helm 3 配合应用;
  • conftest 这是基于 Open Policy Agent (OPA) 的一个工具,通过应用 Rego 编写策略文件来实现配置的校验。我当初在 Apache APISIX Ingress controller 我的项目中应用它,辅助用户进行降级查看;
  • terratest 这是一个应用 Go 开发的通用测试框架,反对多种配置的测试,包含 Helm,AWS/Docker 等;

其中我最喜爱的是 conftest,因为我更喜爱写 Rego,对 OPA 感兴趣的小伙伴能够参考我之前的文章《Open Policy Agent(OPA) 入门实际》。
最简略的则是 helm-unittest 了,它更加专一一些。

这里咱们应用 helm-unittest 作为示例。

装置

helm-unittest 能够作为 Helm Plugin 进行装置,执行以下命令即可:

tao@moelove:~$ helm plugin install https://github.com/quintush/helm-unittest
Support linux-amd64
...
Installed plugin: unittest

测试

只有在 chart 目录下创立一个 tests 目录,在其中编写测试文件即可。

tao@moelove:~$ cat tests/deployment_test.yaml
suite: test deployment
templates:
  - deployment.yaml
tests:
  - it: should work
    set:
      image.tag: latest
    asserts:
      - isKind:
          of: Deployment
      - matchRegex:
          path: metadata.name
          pattern: -moelove$
      - equal:
          path: spec.template.spec.containers[0].image
          value: nginx:latest

我能够通过如下形式进行运行,留神,肯定要减少 -3 参数,以便能够和 Helm v3 进行兼容。

tao@moelove:~$ helm unittest -3 .

### Chart [moelove] .

 PASS  test deployment  tests/deployment_test.yaml

Charts:      1 passed, 1 total
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshot:    0 passed, 0 total
Time:        5.932023ms

咱们能够此 case 做些调整,看看如果测试不通过会是什么状况:

tao@moelove:~$ cat tests/deployment_test.yaml 
suite: test deployment
templates:
  - deployment.yaml
tests:
  - it: should work
    set:
      image.tag: alpine
    asserts:
      - isKind:
          of: Deployment
      - matchRegex:
          path: metadata.name
          pattern: -moelove$
      - equal:
          path: spec.template.spec.containers[0].image
          value: nginx:latest

这里咱们给 image.tag 设置为 alpine,然而在断言中没有让其匹配,所以执行测试后会看到失败。

tao@moelove:~$ helm unittest -3 .

### Chart [moelove] .

 FAIL  test deployment  tests/deployment_test.yaml
        - should work

                - asserts[2] `equal` fail
                        Template:       moelove/templates/deployment.yaml
                        DocumentIndex:  0
                        Path:   spec.template.spec.containers[0].image
                        Expected to equal:
                                nginx:latest
                        Actual:
                                nginx:alpine
                        Diff:
                                --- Expected
                                +++ Actual
                                @@ -1,2 +1,2 @@
                                -nginx:latest
                                +nginx:alpine


Charts:      1 failed, 0 passed, 1 total
Test Suites: 1 failed, 0 passed, 1 total
Tests:       1 failed, 0 passed, 1 total
Snapshot:    0 passed, 0 total
Time:        5.22252ms

Error: plugin "unittest" exited with error

咱们能够很清晰的看到具体失败的起因和地位。

如果你在保护 Helm chart,并且须要保障其可能高质量交付,那么为其减少单元测试是个不错的方法。
至于工具的抉择,次要看集体爱好。helm-unittest 只须要写 YAML,而其余两个工具别离是写 Rego 和 Go。

总结

在本文中,咱们次要聚焦到了 Helm chart 的调试和保护这个主题上。
介绍了 Helm 内置的对 chart 的一些查看工具,同时也介绍了如何应用 helm-unittest 为 Helm chart 编写
单元测试。

在保护,交付和应用 Helm chart 时,把握这些内容都是十分有用的。如果这篇文章对你有所帮忙,欢送点赞、转发、留言探讨。

如果大家对这个主题感兴趣的话,后续我还会更新 Helm 的一些进阶内容,敬请期待!


欢送订阅我的文章公众号【MoeLove】

正文完
 0