はじめに
仕事でJenkinsパイプラインを開発しています。このJenkinsパイプラインは、GitLabリポジトリにあるHelmチャートをgit clone
し、そのHelmチャートをhelm upgrade --install
します。
その際、Helmチャートの正常性は、どのように確認したらいいのでしょうか。生成AIを使って確認してみました。
# helm upgrade --install
実行前に必要な処理
プロンプト
以下のJenkinsパイプラインhelm-install.jenkinsfileは、GitLabリポジトリにあるHelmチャートを
git clone
し、Helmチャートをhelm upgrade --install
します。このJenkinsパイプラインで
helm upgrade --install
を実行する前に、helm upgrade --install
が実行可能であることを確認する処理を追加したいです。そのために、何を実行するべきですか?現在私は、helm lint
、helm upgrade --install --dry-run
を実行する処理を追加しようと考えています。helm-install.jenkinsfile
省略
回答
helm lint
とhelm upgrade --install --dry-run
を実行する処理を追加することは、Helmチャートが正しく構成されているか、そしてhelm upgrade --install
が問題なく実行できるかを確認するための良い方法です。これらのコマンドをJenkinsパイプラインに組み込むためには、新たなステージを追加することをお勧めします。このステージでは、Helmチャートの検証を行います。以下にその例を示します:
stage('Verify Helm Chart') { steps { sh """ helm lint ${env.HELM_CHART_PATH} helm upgrade --install --dry-run test-release ${env.HELM_CHART_PATH} \ --values ${env.HELM_CHART_PATH}/${env.VALUES_FILE} \ --namespace ${env.NAMESPACE} """ } }
このステージを
Setup Helm
とDeploy PostgreSQL
の間に追加します。これにより、Helmチャートが適切に構成されていること、そしてhelm upgrade --install
が問題なく実行できることを確認できます。もし何か問題があれば、このステージでエラーが発生し、デプロイが中止されます。これにより、問題のあるHelmチャートがデプロイされることを防ぐことができます。ただし、helm upgrade --install --dry-run
は実際のリソースを作成しないため、実際のデプロイ時に問題が発生する可能性はあります。それらの問題をキャッチするためには、デプロイ後のテストやヘルスチェックを行うことをお勧めします。また、helm lint
はHelmチャートの構文をチェックしますが、値ファイル(values file)のエラーは検出できません。そのため、値ファイルのエラーを検出するためには別の方法を検討する必要があります。
値ファイル(values file)のエラー検出方法
プロンプト
Helmコマンドの
helm lint
では、値ファイル(values file)のエラーは検出できないと聞きました。値ファイルのエラーを検出する別の方法を教えてください。
回答
はい、その通りです。
helm lint
コマンドは主にチャートの構造と構文をチェックしますが、値ファイル(values file)のエラーは検出できません。値ファイルのエラーを検出するためには、以下のような方法があります:
- Helmのテンプレートレンダリングを使用する:
helm template
コマンドを使用して、値ファイルを適用した結果のマニフェストを生成します。これにより、値が正しく適用されているか、またはエラーが発生していないかを確認できます。以下にそのコマンドを示します:helm template -f your-values-file.yaml your-chart-directory/
- Kubernetesのドライランを使用する:
kubectl apply --dry-run=client -f
コマンドを使用して、生成されたマニフェストがKubernetes APIに対して有効であることを確認します。これにより、Kubernetesリソースとして適切でない値(例えば、不適切なリソースタイプやプロパティ)が検出されます。以下にそのコマンドを示します:helm template -f your-values-file.yaml your-chart-directory/ | kubectl apply --dry-run=client -f -
これらの方法を使用することで、値ファイルのエラーをより効果的に検出できます。ただし、これらの方法でも値の論理的なエラー(例えば、期待する範囲外の数値)は検出できないため、そのようなエラーを防ぐためには、適切なデフォルト値の設定や値の検証を行うことが重要です。また、CI/CDパイプラインにこれらのチェックを組み込むことで、エラーを早期に検出し、修正することができます。
サンプルコード
生成AIの指摘を受け、私が作成したコードが、以下の通りです。実際にhelm upgrade --install
を実行する前に、3段階のチェックを設けました。
helm lint
- helmチャートの構造と構文が正しいことを確認する。
helm template -f your-values-file.yaml your-chart-directory/ | kubectl apply --dry-run=client -f -
- 値ファイル(values file)が正しいことを確認する。
- 生成されたマニフェストがKubernetes APIに対して有効であることを確認する。
helm upgrade --install --dry-run
helm upgrade --install
の仮実行ができることを確認する。
pipeline { agent any parameters { string(name: 'OPENSHIFT_PROJECT', defaultValue: 'test-namespace', description: 'OpenShift project') string(name: 'GIT_CREDENTIALS', defaultValue: 'test-namespace-git-sshkey', description: 'GitLab credentials ID') string(name: 'SERVICE_ACCOUNT_NAME', defaultValue: 'jenkins-dbaas-test-namespace', description: 'serviceAccountName') } environment { HELM_CHART_PATH = '.' VALUES_FILE = 'guest-values.yaml' NAMESPACE = "${params.OPENSHIFT_PROJECT}" // デプロイ先のKubernetes名前空間 SERVICE_ACCOUNT_NAME = "${params.SERVICE_ACCOUNT_NAME}" } triggers { gitlab( triggerOnPush: true, triggerOnMergeRequest: false, branchFilterType: 'All', includeBranchesSpec: 'master' ) } stages { stage('Extract Parameters') { steps { script { echo "OpenShift Project: ${env.OPENSHIFT_PROJECT}" echo "Git Credentials: ${env.GIT_CREDENTIALS}" echo "Service Account Name: ${env.SERVICE_ACCOUNT_NAME}" } } } stage('Clone Repository') { steps { script { git branch: 'master', url: "${gitlabSourceRepoSshUrl}", credentialsId: "${params.GIT_CREDENTIALS}" } } } stage('Setup Helm') { steps { sh 'helm version' } } stage('Helm Lint') { steps { script { def lintResult = sh(script: "helm lint ${env.HELM_CHART_PATH}", returnStatus: true) if (lintResult != 0) { echo "Helm lint failed with exit code: ${lintResult}" currentBuild.result = 'FAILURE' error("Helm lint failed") } } } } stage('Check Helm Template Validity') { steps { script { def templateResult = sh(script: "helm template . -f ${env.VALUES_FILE} --namespace ${env.NAMESPACE} | oc apply --dry-run=client -f - --namespace ${env.NAMESPACE}", returnStatus: true) if (templateResult != 0) { echo "Helm template failed with exit code: ${templateResult}" currentBuild.result = 'FAILURE' error("Helm template failed") } } } } stage('Get Helm Release Name') { steps { script { def releaseName = sh(script: "helm template . -f ${env.VALUES_FILE} --show-only templates/cluster.yaml --namespace ${env.NAMESPACE} | oc apply --dry-run=client -f - --namespace ${env.NAMESPACE} -o json | jq -r '.metadata.name'", returnStdout: true).trim() env.RELEASE_NAME = releaseName echo "Release Name: ${env.RELEASE_NAME}" } } } stage('Helm Dry Run') { steps { script { def dryRunResult = sh(script: """ helm upgrade --install ${env.RELEASE_NAME} ${env.HELM_CHART_PATH} \ --values ${env.HELM_CHART_PATH}/${env.VALUES_FILE} \ --namespace ${env.NAMESPACE} --dry-run """, returnStatus: true) if (dryRunResult != 0) { echo "Helm dry run failed with exit code: ${dryRunResult}" currentBuild.result = 'FAILURE' error("Helm dry run failed") } } } } stage('Helm Install') { steps { script { sh """ helm upgrade --install ${env.RELEASE_NAME} ${env.HELM_CHART_PATH} \ --values ${env.HELM_CHART_PATH}/${env.VALUES_FILE} \ --namespace ${env.NAMESPACE} """ } } } } post { success { echo 'PostgreSQL deployed successfully!' } failure { echo 'Deployment failed!' } } }
やってみた感想
- 「これらの方法を使用することで、値ファイルのエラーをより効果的に検出できます。」
- 完璧ではないですが、まあまあいい感じの事前チェックができたのではと思います。
- 「ただし、これらの方法でも値の論理的なエラー(例えば、期待する範囲外の数値)は検出できないため、そのようなエラーを防ぐためには、適切なデフォルト値の設定や値の検証を行うことが重要です。」
- 時間があったら、この件も調べて対応したいと思います。
helm template -f your-values-file.yaml your-chart-directory/ | kubectl apply --dry-run=client -f -
- 一度マニフェストを生成し、applyし、その結果によってHelmチャートの正常性を確認する、というのはなかなかのテクニックだと思いました。
- 「
helm upgrade --install --dry-run
は実際のリソースを作成しないため、実際のデプロイ時に問題が発生する可能性はあります。それらの問題をキャッチするためには、デプロイ後のテストやヘルスチェックを行うことをお勧めします。」- 今回は追加していませんが、「デプロイ後のテスト」は必要な処理だと思います。生成AIによって気づかされた点です。