「Kyverno Chainsaw」で宣言的なE2Eテストを実施する
はじめに
こんにちは。3-shakeのSreake事業部に所属する長澤翼(@toversus26)です。第8回目の今回は、Kubernetes Operatorのエンドツーエンド(E2E)テストツールである「Kyverno Chainsaw」について紹介します。
Kyverno Chainsawは、Kubernetes OperatorのE2Eの挙動を宣言的に定義してテストするCLIツールです。2023年12月にKubernetes向けのポリシーエンジンを開発しているKyvernoから初期バージョンがリリースされました。2024年9月17日時点でバージョンはv0.2.9となっています。Kyverno内で利用されていることもあり比較的活発に開発が進められています。
開発の背景
Kyverno Chainsawが開発された経緯は公式の「Kyverno Chainsaw - The ultimate end to end testing tool!」の記事にまとめられています。
Kubernetes Operatorの品質を担保するためにE2Eテストを実装することは重要です。Kubernetes Operatorでは主にGinkgoを利用したBehavior-Driven Development(BDD)を採用しており、実装が想定通りかを確認します。しかし、Kubernetes OperatorのE2Eテストを実装して保守するには、時間やコストが掛かります。E2Eテストのコストが高くなるとテストのカバー率が悪くなり、結果としてKubernetes Operatorの品質が低下してしまいます。とりわけOSSプロジェクトの場合、プロジェクト毎にE2Eテストの実装方法(テスト用の内部フレームワーク)が異なるため、学習コストが高くなりがちです。この課題を解決するために、YAML形式で宣言的にE2Eテストを書くことができるシンプルなKyverno Chainsawが開発されました。
基本的な使い方
Kyverno Chainsawは、実行するテストの流れをYAML形式で宣言します。例えば、Deploymentリソースを作成したときにPodが正しく作成されるかを確認するテストを書いてみましょう。
以下のファイルをchainsaw-test.yaml
として保存します。
apiVersion: chainsaw.kyverno.io/v1alpha1 kind: Test metadata: name: deployment-to-pod spec: # steps以下にテストの流れを定義 steps: - try: # Deploymentリソースを作成 - apply: resource: apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment labels: app: nginx spec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 80 # DeploymentからPodが作成され、Podが正常に動作していることを確認 - assert: resource: apiVersion: v1 kind: Pod metadata: labels: app: nginx status: containerStatuses: - name: nginx ready: true restartCount: 0 state: running: {} phase: Running
Kyverno ChainsawではTest
と呼ばれるカスタムリソース風の設定ファイルにE2Eテストを定義します。
Test
の中のsteps
配下にテストの流れを記載する。stepには4つのアクションを記述できるが、今回はtry
のみを利用try
のアクションの下に実際に実行するオペレーションを定義する。オペレーションは複数用意されているが、今回の例ではapply
とassert
の基本的なオペレーションのみを利用している。try
のアクションの中で定義したオペレーションが1つでもエラーになると、テストは失敗となるapply
でDeploymentリソースを作成する。実際にリソースが作成されるためテストを実行する際にKubernetesクラスタが必要。今回はresource
にインラインでリソースを定義しているが、fileを利用することでリソースを定義したYAMLファイルを参照することもできるassert
でDeploymentリソースからPodが作成されることと、Podが正常な状態であることを確認する。 一定時間経過してもPodが期待通りの状態に遷移しない場合はタイムアウトエラーとなり、テストが失敗する
Kyverno chainsawでテストを実行するには、事前にKubernetesクラスタを準備します。kindなどのツールを利用してKubernetesクラスタを準備するか、既存のクラスタを利用する場合はコンテキストを正しく設定してください。
kind create cluster
公式のインストール手順に従ってCLI をインストールして実行します。「.」を指定すると、現在のディレクトリから再起的にchainsaw-test.yaml
を探してテストを実行します。
❯ chainsaw test . Version: 0.2.9 (...) Running tests... === RUN chainsaw === PAUSE chainsaw === CONT chainsaw === RUN chainsaw/deployment-to-pod === PAUSE chainsaw/deployment-to-pod === CONT chainsaw/deployment-to-pod | 13:35:52 | deployment-to-pod | @chainsaw | CREATE | OK | v1/Namespace @ chainsaw-cuddly-elephant | 13:35:52 | deployment-to-pod | step-1 | TRY | BEGIN | | 13:35:52 | deployment-to-pod | step-1 | APPLY | RUN | apps/v1/Deployment @ chainsaw-cuddly-elephant/nginx-deployment | 13:35:52 | deployment-to-pod | step-1 | CREATE | OK | apps/v1/Deployment @ chainsaw-cuddly-elephant/nginx-deployment | 13:35:52 | deployment-to-pod | step-1 | APPLY | DONE | apps/v1/Deployment @ chainsaw-cuddly-elephant/nginx-deployment | 13:35:52 | deployment-to-pod | step-1 | ASSERT | RUN | v1/Pod @ chainsaw-cuddly-elephant/* | 13:35:53 | deployment-to-pod | step-1 | ASSERT | DONE | v1/Pod @ chainsaw-cuddly-elephant/* | 13:35:53 | deployment-to-pod | step-1 | TRY | END | | 13:35:53 | deployment-to-pod | step-1 | CLEANUP | BEGIN | | 13:35:53 | deployment-to-pod | step-1 | DELETE | OK | apps/v1/Deployment @ chainsaw-cuddly-elephant/nginx-deployment | 13:35:53 | deployment-to-pod | step-1 | CLEANUP | END | | 13:35:53 | deployment-to-pod | @chainsaw | CLEANUP | BEGIN | | 13:35:53 | deployment-to-pod | @chainsaw | DELETE | OK | v1/Namespace @ chainsaw-cuddly-elephant | 13:35:58 | deployment-to-pod | @chainsaw | CLEANUP | END | --- PASS: chainsaw (0.00s) --- PASS: chainsaw/deployment-to-pod (6.27s) PASS Tests Summary... - Passed tests 1 - Failed tests 0 - Skipped tests 0 Done.
今回の例を元に、Chainsawを実行したときのテストの流れを見ていきます。
- ランダムな名前で新しくテスト用のnamespaceを作成
- Deploymentリソースを作成
- Podリソースが作成され、正常に起動するのを待つ
- Deploymentリソースを削除
- テスト用のnamespaceを削除
chainsaw-test.yaml
を書き換えて必ず失敗するテストに置き換えてみましょう。今回はassert
の中で検証するPodのステータスのフェーズをCompleted
に変更します。
--- chainsaw-test.yaml +++ chainsaw-test.update.yaml @@ -45,4 +45,4 @@ restartCount: 0 state: running: {} - phase: Running + phase: Completed
再度テストを実行すると、今度はassert
の段階でタイムアウトが発生してテストが失敗します。
❯ chainsaw test . Version: 0.2.9 (...) === RUN chainsaw === PAUSE chainsaw === CONT chainsaw === RUN chainsaw/deployment-to-pod === PAUSE chainsaw/deployment-to-pod === CONT chainsaw/deployment-to-pod | 13:48:17 | deployment-to-pod | @chainsaw | CREATE | OK | v1/Namespace @ chainsaw-stirred-gopher | 13:48:17 | deployment-to-pod | step-1 | TRY | BEGIN | | 13:48:17 | deployment-to-pod | step-1 | APPLY | RUN | apps/v1/Deployment @ chainsaw-stirred-gopher/nginx-deployment | 13:48:17 | deployment-to-pod | step-1 | CREATE | OK | apps/v1/Deployment @ chainsaw-stirred-gopher/nginx-deployment | 13:48:17 | deployment-to-pod | step-1 | APPLY | DONE | apps/v1/Deployment @ chainsaw-stirred-gopher/nginx-deployment | 13:48:17 | deployment-to-pod | step-1 | ASSERT | RUN | v1/Pod @ chainsaw-stirred-gopher/* | 13:48:47 | deployment-to-pod | step-1 | ASSERT | ERROR | v1/Pod @ chainsaw-stirred-gopher/* === ERROR ---------------------------------------------------------------- v1/Pod/chainsaw-stirred-gopher/nginx-deployment-77d8468669-96d9b ---------------------------------------------------------------- * status.phase: Invalid value: "Running": Expected value: "Completed" --- expected +++ actual @@ -3,13 +3,27 @@ metadata: labels: app: nginx + name: nginx-deployment-77d8468669-96d9b namespace: chainsaw-stirred-gopher + ownerReferences: + - apiVersion: apps/v1 + blockOwnerDeletion: true + controller: true + kind: ReplicaSet + name: nginx-deployment-77d8468669 + uid: 85049a1c-0307-48eb-aa35-ff1805f0bdfd status: containerStatuses: - - name: nginx + - containerID: containerd://c13e12c915348fa814fc7846bd80058803bd6756cfaf34b2fc83fcbbc29e78a2 + image: docker.io/library/nginx:1.14.2 + imageID: docker.io/library/nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d + lastState: {} + name: nginx ready: true restartCount: 0 + started: true state: - running: {} - phase: Completed + running: + startedAt: "2024-09-15T04:48:18Z" + phase: Running | 13:48:47 | deployment-to-pod | step-1 | TRY | END | | 13:48:47 | deployment-to-pod | step-1 | CLEANUP | BEGIN | | 13:48:47 | deployment-to-pod | step-1 | DELETE | OK | apps/v1/Deployment @ chainsaw-stirred-gopher/nginx-deployment | 13:48:47 | deployment-to-pod | step-1 | CLEANUP | END | | 13:48:47 | deployment-to-pod | @chainsaw | CLEANUP | BEGIN | | 13:48:47 | deployment-to-pod | @chainsaw | DELETE | OK | v1/Namespace @ chainsaw-stirred-gopher | 13:48:52 | deployment-to-pod | @chainsaw | CLEANUP | END | --- FAIL: chainsaw (0.00s) --- FAIL: chainsaw/deployment-to-pod (35.29s) FAIL Tests Summary... - Passed tests 0 - Failed tests 1 - Skipped tests 0 Done with failures. Error: some tests failed
Chainsawは失敗したテストを調査するときに必要な情報を併せて表示してくれます。
- テストが失敗した原因を表示する。今回の例で言うと
status.phase: Invalid value: "Running": Expected value: "Completed"
の部分。PodのフェーズがCompleted
となることを期待しているが、実際にはRunning
であることが分かる - 実際のPodリソースと
assert
で指定したマニフェストのメタデータとステータスの差分を表示する。今回はPodの名前やOwnerReference、Podステータスの一部の情報を記載していないため、それらの差分も一緒に表示されている
他にもcatch
アクションを定義することでPod EventやPodの状態、Podのログなど追加で表示したい情報をカスタマイズできます。
--- chainsaw-test.yaml +++ chainsaw-test.update.yaml @@ -46,3 +46,11 @@ state: running: {} phase: Completed + catch: + - events: {} + - get: + apiVersion: v1 + kind: Pod + selector: app=nginx + - podLogs: + selector: app=nginx
Chainsawのテストを実行すると、リソースを削除する前に上記で追加した情報を表示してくれます。
=== RUN chainsaw === PAUSE chainsaw === CONT chainsaw === RUN chainsaw/deployment-to-pod === PAUSE chainsaw/deployment-to-pod === CONT chainsaw/deployment-to-pod | 14:09:53 | deployment-to-pod | @chainsaw | CREATE | OK | v1/Namespace @ chainsaw-allowing-terrier | 14:09:53 | deployment-to-pod | step-1 | TRY | BEGIN | | 14:09:53 | deployment-to-pod | step-1 | APPLY | RUN | apps/v1/Deployment @ chainsaw-allowing-terrier/nginx-deployment | 14:09:53 | deployment-to-pod | step-1 | CREATE | OK | apps/v1/Deployment @ chainsaw-allowing-terrier/nginx-deployment | 14:09:53 | deployment-to-pod | step-1 | APPLY | DONE | apps/v1/Deployment @ chainsaw-allowing-terrier/nginx-deployment | 14:09:53 | deployment-to-pod | step-1 | ASSERT | RUN | v1/Pod @ chainsaw-allowing-terrier/* | 14:10:23 | deployment-to-pod | step-1 | ASSERT | ERROR | v1/Pod @ chainsaw-allowing-terrier/* (...) | 14:10:23 | deployment-to-pod | step-1 | TRY | END | | 14:10:23 | deployment-to-pod | step-1 | CATCH | BEGIN | | 14:10:23 | deployment-to-pod | step-1 | CMD | RUN | === COMMAND /opt/homebrew/bin/kubectl get events -n chainsaw-allowing-terrier | 14:10:24 | deployment-to-pod | step-1 | CMD | LOG | === STDOUT LAST SEEN TYPE REASON OBJECT MESSAGE 31s Normal Scheduled pod/nginx-deployment-77d8468669-2z4rx Successfully assigned chainsaw-allowing-terrier/nginx-deployment-77d8468669-2z4rx to kind-control-plane 30s Normal Pulled pod/nginx-deployment-77d8468669-2z4rx Container image "nginx:1.14.2" already present on machine 30s Normal Created pod/nginx-deployment-77d8468669-2z4rx Created container nginx 30s Normal Started pod/nginx-deployment-77d8468669-2z4rx Started container nginx 31s Normal SuccessfulCreate replicaset/nginx-deployment-77d8468669 Created pod: nginx-deployment-77d8468669-2z4rx 31s Normal ScalingReplicaSet deployment/nginx-deployment Scaled up replica set nginx-deployment-77d8468669 to 1 | 14:10:24 | deployment-to-pod | step-1 | CMD | DONE | | 14:10:24 | deployment-to-pod | step-1 | CMD | RUN | === COMMAND /opt/homebrew/bin/kubectl get pods -l app=nginx -n chainsaw-allowing-terrier | 14:10:24 | deployment-to-pod | step-1 | CMD | LOG | === STDOUT NAME READY STATUS RESTARTS AGE nginx-deployment-77d8468669-2z4rx 1/1 Running 0 31s | 14:10:24 | deployment-to-pod | step-1 | CMD | DONE | | 14:10:24 | deployment-to-pod | step-1 | CMD | RUN | === COMMAND /opt/homebrew/bin/kubectl logs --prefix -l app=nginx -n chainsaw-allowing-terrier --all-containers | 14:10:24 | deployment-to-pod | step-1 | CMD | DONE | | 14:10:24 | deployment-to-pod | step-1 | CATCH | END | | 14:10:24 | deployment-to-pod | step-1 | CLEANUP | BEGIN | | 14:10:24 | deployment-to-pod | step-1 | DELETE | OK | apps/v1/Deployment @ chainsaw-allowing-terrier/nginx-deployment | 14:10:24 | deployment-to-pod | step-1 | CLEANUP | END | | 14:10:24 | deployment-to-pod | @chainsaw | CLEANUP | BEGIN | | 14:10:24 | deployment-to-pod | @chainsaw | DELETE | OK | v1/Namespace @ chainsaw-allowing-terrier | 14:10:29 | deployment-to-pod | @chainsaw | CLEANUP | END | --- FAIL: chainsaw (0.00s) --- FAIL: chainsaw/deployment-to-pod (35.56s) FAIL Tests Summary... - Passed tests 0 - Failed tests 1 - Skipped tests 0 Done with failures. Error: some tests failed
ユースケース
Kyverno ChainsawはKubernetes Operator向けに開発されたツールですが、Kubernetesクラスタを運用する際にも利用できます。クラスタ管理者はKubernetesクラスタやクラスタ上で動作するサードパーティ製のツールを運用しています。これらのバージョン更新や設定変更の後に、想定通りに動作しているかを確認します。この動作確認をGinkgoなどを利用したE2Eテストとして実装して自動化している人たちも一部いますが、ほとんどが手動だと思います。あらかじめKyverno Chainsawで確認したい項目を宣言的に定義しておくことで、定常作業を効率化できます。
- マネージドKubernetesクラスタやアドオンのバージョン更新後の動作確認
- Pod間で通信できるか
- Podに外部ボリュームをマウントできるか
- External Secrets OperatorのExternalSecretsリソースで外部のシークレット管理ツールに保存した秘密情報をSecretに同期できるか
- IstioのVirtualServiceとテスト用のPodを作成して外部ロードバランサ経由で疎通できるか
- KarpenterがPending状態のPodを検知してノードを自動スケールできるか
- Validating Admission Policy(VAP)で定義したポリシーが期待通りに動作するか
公式ドキュメントのVAPのポリシーを例にKyverno ChainsawでVAPをテストしてみましょう。今回確認するVAPのルールでは、Deploymentのレプリカ数が5以下であることを強制しています。以下のVAPのリソースは既に作成されている前提でテストを書いてみましょう。
apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingAdmissionPolicy metadata: name: replicalimit-policy.example.com spec: failurePolicy: Fail matchConstraints: resourceRules: - apiGroups: ["apps"] apiVersions: ["v1"] operations: ["CREATE", "UPDATE"] resources: ["deployments"] validations: - expression: "object.spec.replicas <= 5" chainsaw-test.yamlにE2Eテストを定義します。 apiVersion: chainsaw.kyverno.io/v1alpha1 kind: Test metadata: name: vap-replicalimit-policy spec: # テスト時に作成するnamespaceの名前を指定 namespace: vap-replicalimit-policy steps: - try: - apply: resource: apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingAdmissionPolicyBinding metadata: name: replicalimit-policy-test.example.com spec: policyName: replicalimit-policy.example.com validationActions: [Deny] # テスト時に作成したnamespaceに対してポリシーを適用 matchResources: namespaceSelector: matchLabels: kubernetes.io/metadata.name: vap-replicalimit-policy # VAPが適用されるまで待機 - try: - sleep: duration: 30s # ポリシーに準拠したレプリカ数を指定したDeploymentを作成 # Deploymentが作成できれば良いのでassertは不要 - try: - apply: resource: apiVersion: apps/v1 kind: Deployment metadata: name: nginx-1 spec: replicas: 1 selector: matchLabels: app: nginx-1 template: metadata: labels: app: nginx-1 spec: containers: - name: nginx image: nginx:1.14.2 # ポリシーに準拠していないレプリカ数を指定したDeploymentを作成 - try: - apply: resource: apiVersion: apps/v1 kind: Deployment metadata: name: nginx-10 spec: replicas: 10 selector: matchLabels: app: nginx-10 template: metadata: labels: app: nginx-10 spec: containers: - name: nginx image: nginx:1.14.2 expect: - match: apiVersion: apps/v1 kind: Deployment metadata: name: nginx-10 check: # エラーとなる場合はテストが成功 ($error != null): true
今回のテストでは、事前に作成されているVAPが想定通りの挙動かを確認します。
- テストを実行するnamespaceの名前を明示的に指定し、Validating Admission Policy Bindingを作成してVAPをテストを実行するnamespaceに紐付ける
- ポリシーに準拠していないDeploymentを作成するテストでは、Operation checkの機能を利用してリソースの作成に失敗することを確認する。このようにKyverno Chainsawでは操作に失敗するテストも定義できる
E2Eテストを実行します。レプリカ数が10のDeploymentを作成するテストでエラーが発生していますが、テストには通過していることが分かります。リソースを反映したときのエラーメッセージも同時に表示してくれるため、想定したVAPのルールでエラーが発生しているかも確認できます。
❯ chainsaw test . Version: 0.2.9 (...) Running tests... === RUN chainsaw === PAUSE chainsaw === CONT chainsaw === RUN chainsaw/vap-replicalimit-policy === PAUSE chainsaw/vap-replicalimit-policy === CONT chainsaw/vap-replicalimit-policy | 14:50:29 | vap-replicalimit-policy | @chainsaw | CREATE | OK | v1/Namespace @ vap-replicalimit-policy | 14:50:29 | vap-replicalimit-policy | step-1 | TRY | BEGIN | | 14:50:29 | vap-replicalimit-policy | step-1 | APPLY | RUN | admissionregistration.k8s.io/v1/ValidatingAdmissionPolicyBinding @ replicalimit-policy-test.example.com | 14:50:29 | vap-replicalimit-policy | step-1 | CREATE | OK | admissionregistration.k8s.io/v1/ValidatingAdmissionPolicyBinding @ replicalimit-policy-test.example.com | 14:50:29 | vap-replicalimit-policy | step-1 | APPLY | DONE | admissionregistration.k8s.io/v1/ValidatingAdmissionPolicyBinding @ replicalimit-policy-test.example.com | 14:50:29 | vap-replicalimit-policy | step-1 | TRY | END | | 14:50:29 | vap-replicalimit-policy | step-2 | TRY | BEGIN | | 14:50:29 | vap-replicalimit-policy | step-2 | SLEEP | RUN | | 14:50:59 | vap-replicalimit-policy | step-2 | SLEEP | DONE | | 14:50:59 | vap-replicalimit-policy | step-2 | TRY | END | | 14:50:59 | vap-replicalimit-policy | step-3 | TRY | BEGIN | | 14:50:59 | vap-replicalimit-policy | step-3 | APPLY | RUN | apps/v1/Deployment @ vap-replicalimit-policy/nginx-1 | 14:50:59 | vap-replicalimit-policy | step-3 | CREATE | OK | apps/v1/Deployment @ vap-replicalimit-policy/nginx-1 | 14:50:59 | vap-replicalimit-policy | step-3 | APPLY | DONE | apps/v1/Deployment @ vap-replicalimit-policy/nginx-1 | 14:50:59 | vap-replicalimit-policy | step-3 | TRY | END | | 14:50:59 | vap-replicalimit-policy | step-4 | TRY | BEGIN | | 14:50:59 | vap-replicalimit-policy | step-4 | APPLY | RUN | apps/v1/Deployment @ vap-replicalimit-policy/nginx-10 | 14:50:59 | vap-replicalimit-policy | step-4 | CREATE | WARN | apps/v1/Deployment @ vap-replicalimit-policy/nginx-10 === ERROR deployments.apps "nginx-10" is forbidden: ValidatingAdmissionPolicy 'replicalimit-policy.example.com' with binding 'replicalimit-policy-test.example.com' denied request: failed expression: object.spec.replicas <= 5 | 14:50:59 | vap-replicalimit-policy | step-4 | APPLY | DONE | apps/v1/Deployment @ vap-replicalimit-policy/nginx-10 | 14:50:59 | vap-replicalimit-policy | step-4 | TRY | END | | 14:50:59 | vap-replicalimit-policy | step-3 | CLEANUP | BEGIN | | 14:50:59 | vap-replicalimit-policy | step-3 | DELETE | OK | apps/v1/Deployment @ vap-replicalimit-policy/nginx-1 | 14:50:59 | vap-replicalimit-policy | step-3 | CLEANUP | END | | 14:50:59 | vap-replicalimit-policy | step-1 | CLEANUP | BEGIN | | 14:50:59 | vap-replicalimit-policy | step-1 | DELETE | OK | admissionregistration.k8s.io/v1/ValidatingAdmissionPolicyBinding @ replicalimit-policy-test.example.com | 14:50:59 | vap-replicalimit-policy | step-1 | CLEANUP | END | | 14:50:59 | vap-replicalimit-policy | @chainsaw | CLEANUP | BEGIN | | 14:51:00 | vap-replicalimit-policy | @chainsaw | DELETE | OK | v1/Namespace @ vap-replicalimit-policy | 14:51:05 | vap-replicalimit-policy | @chainsaw | CLEANUP | END | --- PASS: chainsaw (0.00s) --- PASS: chainsaw/vap-replicalimit-policy (35.36s) PASS Tests Summary... - Passed tests 1 - Failed tests 0 - Skipped tests 0 Done.
このように、Kyverno ChainsawはVAPの挙動を確認するテストツールとしても利用できます。VAPのテストツールとしては、同じくKyvernoが開発しているkyverno testがあります。なおkyverno testでテストを実行する際にKubernetesクラスタは不要ですが、2024年9月17日時点で以下の問題があり、痒いところに手が届いていませんでした。
- テストに失敗したときの原因が分かりづらい
- v1のVAPリソースに対応していない
- VAPのParamRefの機能に対応していない
その点、Kyverno ChainsawはE2Eテストのレポート機能が優れているため、十分に活用できます。また、汎用的な作りをしているため他のユースケースとも併用可能です。
おわりに
今回は、Kyverno Chainsawによる宣言的なE2Eテストの利用例を見てきました。Kubernetes Operatorの開発以外でもクラスタ管理者の定常作業の動作確認としても利用できます。基本的な機能の学習コストは低く、YAMLのマニフェストを管理するだけで良いので、メンテナンス性も高く感じました。
また、今回は紹介していませんが、Kyvernoの機能を元にした少し複雑な機能もあります。ただ、複雑な機能を使うくらいならGoでテストコードを記述した方が柔軟かつ見通しも良いはずです。
Kyverno Chainsawを使ってE2Eテストの導入のハードルを下げてみてはどうでしょうか。
連載バックナンバー
Think ITメルマガ会員登録受付中
全文検索エンジンによるおすすめ記事
- ドメインを考慮した柔軟なPodの配置を実現する「Balancer」
- NGINX Ingress Controllerの柔軟なアプリケーション制御、具体的なユースケースと設定方法を理解する
- Kubernetes上のコンテナをIngressでインターネットに公開するまで
- 「TAURI」と「Rust」の「テスト」機能を試してみよう
- KubernetesのWorkloadsリソース(その1)
- Oracle Cloud Hangout Cafe Season5 #3「Kubernetes のセキュリティ」(2022年3月9日開催)
- サービスメッシュを使ってみよう
- KubernetesのDiscovery&LBリソース(その2)
- Oracle Cloud Hangout Cafe Season 4 #5「Kubernetesのオートスケーリング」(2021年8月4日開催)
- Oracle Cloud Hangout Cafe Season7 #1「Kubnernetes 超入門」(2023年6月7日開催)