こんにちは。X イノベーション 本部 クラウド イノベーション センターの柴田です。 本記事では Renovate を使った Kubernetes エコシステムの自動バージョンアップを紹介します。 なお本記事の内容は Kubernetes Meetup Tokyo #48 で紹介された 個人運用k8sクラスタの構成要素の技術選定 - でこてっくろぐ ねお にインスパイアされています。 背景 Renovateとは Platform Manager Datasource Versioning RenovateでKubernetesエコシステムを自動更新する 更新対象のKubernetesクラスタ Renovateを実行する Renovateの設定 実行結果 おわりに 背景 Kubernetes では、 Kubernetes と連携して動作する様々な OSS やサービスを活用することで、アプリケーションの開発・運用に関する生産性向上や効率化を図ることができます。 本記事ではそれらを Kubernetes エコシステムと呼びます。 多くの Kubernetes エコシステムは開発元が提供しているコンテナイメージや マニフェスト ファイルを自分たちの Kubernetes クラスタ へデプロイして利用します。 開発が盛んな Kubernetes エコシステムでは、頻繁に新機能やセキュリティ改善が実装され、新しいバージョンとしてリリースされます。 Kubernetes エコシステムの恩恵を最大限に享受するにはなるべく新しいバージョンを使用することが望ましいです。 また Kubernetes では、 マニフェスト ファイルを GitOps と呼ばれる手法で管理・デプロイすることが多いです。 GitOpsはWeaveworks社が提唱した継続的デプロイの方法であり、以下の特徴があります。 システム全体が宣言的に記述されていること。 マニフェスト がgitで管理され、それが信頼できる唯一の情報源(Single Source of Truth)であること。 承認された マニフェスト の変更が自動的にデプロイされること。またその際 Kubernetes クラスタ への認証情報を外部(例えばCIサーバなど)に持たせる必要がないこと。 マニフェスト と Kubernetes クラスタ の間に差分がある場合、それを検知したり、自動的に修正したりできること。 GitOpsを実現するツールには例えば Argo CD 、 Flux 、 PipeCD があります。 以上から、 Kubernetes エコシステムの新しいバージョンがリリースされる度に、git リポジトリ で管理されたそれらの マニフェスト を最新の内容に更新できることが望ましいです。 また、運用負荷がかからないよう、 マニフェスト の更新はなるべく自動的に行えることが望ましいです。 Renovateとは Renovate はプロジェクトの依存関係の更新を自動化するツールです。 似たようなツールに Dependabot などがあります。 Renovateはアプリケーションのライブラリの自動バージョンアップに使われることが多いですが、アプリケーション開発以外の用途でも利用できます。 ここからはRenovateで何ができるかを簡単に説明します。 なお本記事では Renovate v32.97.0 を前提とします。 Platform Renovateは以下に格納された依存関係ファイルを更新できます。 Azure DevOps Azure DevOps Server Bitbucket Cloud Bitbucket Server Gitea GitHub GitHub Enterprise Server GitLab Manager Renovateは以下の依存関係を更新できます。 docker : ansible , docker-compose , dockerfile , droneci , gitlabci , kubernetes dotnet : cake , nuget elixir : mix golang : gomod java : gradle , maven js : meteor , npm node : nodenv , nvm , travis php : composer python : pip-compile , pip_requirements , pip_setup , pipenv , poetry , pyenv , setup-cfg ruby : bundler , ruby-version rust : cargo other : ansible-galaxy , argocd , azure-pipelines , batect , batect-wrapper , bazel , bitbucket-pipelines , buildkite , cdnurl , circleci , cloudbuild , cocoapods , conan , deps-edn , flux , fvm , git-submodules , github-actions , gitlabci-include , gradle-wrapper , helm-requirements , helm-values , helmfile , helmsman , helmv3 , homebrew , html , jenkins , jsonnet-bundler , kustomize , leiningen , pre-commit , pub , regex , sbt , swift , terraform , terraform-version , terragrunt , terragrunt-version , velaci Datasource Renovateは以下の依存先の更新を検知できます。 adoptium-java , artifactory , aws-machine-image , bitbucket-tags , cdnjs , clojure , conan , conda , crate , dart , docker , flutter-version , galaxy , galaxy-collection , git-refs , git-tags , github-releases , github-tags , gitlab-packages , gitlab-releases , gitlab-tags , go , golang-version , gradle-version , helm , hex , jenkins-plugins , maven , node , npm , nuget , orb , packagist , pod , pypi , repology , ruby-version , rubygems , sbt-package , sbt-plugin , terraform-module , terraform-provider Versioning 依存関係を更新するためにはバージョン表記を比較できる必要があります。 Renovateでは以下のフォーマットのバージョン表記を扱えます。 aws-machine-image , cargo , composer , conan , debian , docker , git , gradle , hashicorp , helm , hex , ivy , loose , maven , node , npm , nuget , pep440 , poetry , regex , rez , ruby , semver , semver-coerced , swift , ubuntu Renovateで Kubernetes エコシステムを自動更新する では実際にRenovateを使って Kubernetes エコシステムの更新作業を自動化したいと思います。 更新対象の Kubernetes クラスタ 今回は私が検証用途で使用している Kubernetes クラスタ を対象にします。 この Kubernetes クラスタ には以下の特徴があります。 すべての マニフェスト は GitHub リポジトリ で管理しています。 マニフェスト を Kubernetes クラスタ へデプロイするために Argo CD と Flux を使用しています。 通常は片方だけで十分ですが、検証用途の環境のため両方とも動かしています。 Kubernetes エコシステムの マニフェスト は、以下のいずれかの方法で管理しています。 Helm : 公式や3rd partyが提供するHelm Chartを利用します。 具体的にはArgo CDの Application リソースやFluxの HelmRelease リソースとして Kubernetes クラスタ へデプロイします。 またローカル環境で マニフェスト を生成できるよう helmfile も使用しています。 Kustomize : kustomize を使って公式が提供する マニフェスト を https 経由で参照します。 イメージタグを書き換えることもあります。 以下は amazon-vpc-cni-k8s の マニフェスト を生成する kustomization.yaml の例です。 apiVersion : kustomize.config.k8s.io/v1beta1 kind : Kustomization resources : - https://raw.githubusercontent.com/aws/amazon-vpc-cni-k8s/v1.10.3/config/master/aws-k8s-cni.yaml images : - name : 602401143452.dkr.ecr.us-west-2.amazonaws.com/amazon-k8s-cni newName : 602401143452.dkr.ecr.ap-northeast-1.amazonaws.com/amazon-k8s-cni newTag : v1.10.3 - name : 602401143452.dkr.ecr.us-west-2.amazonaws.com/amazon-k8s-cni-init newName : 602401143452.dkr.ecr.ap-northeast-1.amazonaws.com/amazon-k8s-cni-init newTag : v1.10.3 Renovateを実行する Renovateには大まかに2種類の実行方法があります。 GitHub App を使用する 自分たちでRenovateを実行する(Self-Hosting) 今回は GitHub Actions renovatebot/github-action を使用して自分たちでRenovateを実行します。 その他のSelf-Hostingの実行方法は Self-Hosting Renovate を参照してください。 以下は GitHub Actionsのワークフローです。 # .github/workflows/renovate.yaml name : Renovate on : schedule : - cron : '0 0 * * *' # Run workflow at 09:00 AM JST every day jobs : renovate : name : Renovate runs-on : ubuntu-latest steps : - uses : actions/checkout@v3 - name : Run renovate uses : renovatebot/github-action@v32.97.0 with : token : ${{ secrets.GH_TOKEN }} configurationFile : renovate.json GH_TOKEN は https://github.com/renovatebot/github-action#token に従って作成した GitHub のPersonal Access Tokenです。 GitHub Actionsでは GITHUB_TOKEN が利用できますが、 https://github.com/renovatebot/github-action#token に Note that the GITHUB_TOKEN secret can't be used for authenticating Renovate. とあるためこのようにしています。 Renovateの設定 次にRenovateの設定ファイル renovate.json を作成します。 今回使用した設定は以下のとおりです。 { " repositories ": [ " ISID/renovate-sample " ] , " extends ": [ " config:base ", " :prHourlyLimitNone ", " :prConcurrentLimitNone " ] , " enabledManagers ": [ " argocd ", " flux ", " helmfile ", " kustomize ", " regex " ] , " labels ": [ " renovate " ] , " assignees ": [ " @ShibataTakao " ] , " argocd ": { " fileMatch ": [ " ^manifests/argo-cd-apps/.* \\ .ya?ml$ " ] } , " flux ": { " fileMatch ": [ " ^manifests/flux/.* \\ .ya?ml$ ", " ^manifests/flux-ks/.* \\ .ya?ml$ " ] } , " regexManagers ": [ { " fileMatch ": [ " (^|/)kustomization \\ .ya?ml$ " ] , " matchStrings ": [ " https://raw \\ .githubusercontent \\ .com/(?<depName>[^/]+/[^/]+)/(?<currentValue>[^/]+)/.* ", " https://github \\ .com/(?<depName>[^/]+/[^/]+)/releases/download/(?<currentValue>[^/]+)/.* " ] , " datasourceTemplate ": " github-releases ", " versioningTemplate ": " semver " } ] , " packageRules ": [ { " matchPackageNames ": [ " kubernetes/autoscaler " ] , " matchDatasources ": [ " github-tags ", " github-releases " ] , " versioning ": " regex:^cluster-autoscaler-(?<major> \\ d+) \\ .(?<minor> \\ d+) \\ .(?<patch> \\ d+)?$ ", " allowedVersions ": " < 1.23.0 " } , { " matchPackageNames ": [ " k8s.gcr.io/autoscaling/cluster-autoscaler " ] , " matchDatasources ": [ " docker " ] , " allowedVersions ": " < 1.23.0 " } ] } 各設定を順に見ていきましょう。 " repositories ": [ " ISID/renovate-sample " ] repositories にはRenovateの対象とする リポジトリ を指定します。 リポジトリ 名を直接指定するかわりに autodiscover と autodiscoverFilter を設定してRenovateの対象とする リポジトリ を自動的に検出することもできます。 " extends ": [ " config:base ", " :prHourlyLimitNone ", " :prConcurrentLimitNone " ] extends には Preset を指定します。 Presetは定義済みの設定の集合です。 デフォルトで定義されたPresetを使うだけでなく、独自のPresetを定義することもできます。 今回は以下のPresetを使用します。 config:base :prHourlyLimitNone :prConcurrentLimitNone " enabledManagers ": [ " argocd ", " flux ", " helmfile ", " kustomize ", " regex " ] enabledManagers を設定して明示的に指定したManagerのみを有効化します。 多くのManagerはデフォルトで有効になっています。 各Managerの有効/無効は <manager>.enabled の値を true または false に設定することで変更できます。 または enabledManagers に有効にするManagerを明示的に指定することで、指定したManagerのみを有効にできます。 詳細は Enabling and disabling managers を参照してください。 今回は以下のManagerのみを有効化します。 argocd flux helmfile kustomize regex 今回の更新対象のうち Helm : 公式や3rd partyが提供するHelm Chartを利用します。 具体的にはArgo CDの Application リソースやFluxの HelmRelease リソースとして Kubernetes クラスタ へデプロイします。 またローカル環境で マニフェスト を生成できるよう helmfile も使用しています。 は argocd と flux と helmfile を使ってHelm ChartをバージョンアップするためのPRを自動成します。 また Kustomize : kustomize を使って公式が提供する マニフェスト を https 経由で参照します。 イメージタグを書き換えることもあります。 は kustomize と regex を使って参照先の マニフェスト のURLやイメージタグをバージョンアップするためのPRを自動作成します。 regex については後ほどもう少し詳しく説明します。 " labels ": [ " renovate " ] , " assignees ": [ " @ShibataTakao " ] labels と assignees にはRenovateが依存関係を更新するために作成するPRのLabelsとAssigneesを設定します。 " argocd ": { " fileMatch ": [ " ^manifests/argo-cd-apps/.* \\ .ya?ml$ " ] } , " flux ": { " fileMatch ": [ " ^manifests/flux/.* \\ .ya?ml$ ", " ^manifests/flux-ks/.* \\ .ya?ml$ " ] } fileMatch には各Managerの依存関係ファイルの追加パスを 正規表現 で記述します。 多くのManagerにはデフォルトの fileMatch が設定されていますが、デフォルトの fileMatch が設定されていない場合や独自のファイルパスを追加で設定したい場合には、 fileMatch にそれらを追加設定できます。 " regexManagers ": [ { " fileMatch ": [ " (^|/)kustomization \\ .ya?ml$ " ] , " matchStrings ": [ " https://raw \\ .githubusercontent \\ .com/(?<depName>[^/]+/[^/]+)/(?<currentValue>[^/]+)/.* ", " https://github \\ .com/(?<depName>[^/]+/[^/]+)/releases/download/(?<currentValue>[^/]+)/.* " ] , " datasourceTemplate ": " github-releases ", " versioningTemplate ": " semver " } ] regexManagers には regex Managerの設定を記述します。 regex を用いることで 正規表現 を使用して依存関係を検出・自動更新するユーザー独自の仕組みを構築できます。 今回は Kustomize : kustomize を使って公式が提供する マニフェスト を https 経由で参照します。 イメージタグを書き換えることもあります。 以下は amazon-vpc-cni-k8s の マニフェスト を生成する kustomization.yaml の例です。 yaml apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - https://raw.githubusercontent.com/aws/amazon-vpc-cni-k8s/v1.10.3/config/master/aws-k8s-cni.yaml images: - name: 602401143452.dkr.ecr.us-west-2.amazonaws.com/amazon-k8s-cni newName: 602401143452.dkr.ecr.ap-northeast-1.amazonaws.com/amazon-k8s-cni newTag: v1.10.3 - name: 602401143452.dkr.ecr.us-west-2.amazonaws.com/amazon-k8s-cni-init newName: 602401143452.dkr.ecr.ap-northeast-1.amazonaws.com/amazon-k8s-cni-init newTag: v1.10.3 で述べた参照先の マニフェスト のURLを自動更新するためにこの仕組みを利用します。 fileMatch には更新対象のファイル kustomization.yaml のファイルパスを 正規表現 で設定します。 matchStrings には kustomization.yaml 内の更新対象の文字列を設定します。 今回は https://raw.githubusercontent.com/<user>/<repo>/<tag>/<filepath> ( GitHub リポジトリ のコンテンツ) https://github.com/<user>/<repo>/releases/download/<release>/<filepath> ( GitHub リポジトリ のリリースのアセット) が更新対象です。 regex では更新対象の依存関係に関する以下の設定をする必要があります。 これらは、該当する設定項目に値を設定するか、 matchStrings の 正規表現 に名前付きキャプチャグループを用いることで設定できます。 Capture Group Config Field 必須 説明 currentValue なし 必須 現在のバージョン。Renovateによって更新される。 depName depNameTemplate 必須 依存関係の名前。 packageName packageNameTemplate オプション パッケージ名。省略した場合 depName と同じになる。 datasource datasourceTemplate 必須 依存関係の参照先( Datasource )。 depType depTypeTemplate オプション 依存関係の種類。 versioning versioningTemplate オプション 依存関係のバージョン表記( Versioning )。デフォルトは semver 。 extractVersion extractVersionTemplate オプション キャプチャしたバージョンと Datasource のバージョンの表記が異なる場合に使用する。詳細は extractVersion を参照。 currentDigest なし オプション 現在のDigest。Renovateによって更新される。 registryUrl registryUrlTemplate オプション 依存関係の参照先のURL。詳細は registryUrls を参照。 " packageRules ": [ { " matchPackageNames ": [ " kubernetes/autoscaler " ] , " matchDatasources ": [ " github-tags ", " github-releases " ] , " versioning ": " regex:^cluster-autoscaler-(?<major> \\ d+) \\ .(?<minor> \\ d+) \\ .(?<patch> \\ d+)?$ ", " allowedVersions ": " < 1.23.0 " } , { " matchPackageNames ": [ " k8s.gcr.io/autoscaling/cluster-autoscaler " ] , " matchDatasources ": [ " docker " ] , " allowedVersions ": " < 1.23.0 " } ] packageRules には特定の依存関係の更新における追加ルールを設定します。 今回は Cluster Autoscaler に関する以下の追加ルールを設定します。 Cluster AutoscalerのGiHub リポジトリ におけるタグやリリースの 命名規則 は cluster-autoscaler-<major>.<minor>.<patch> です(例: cluster-autoscaler-1.22.3 )。それを解釈できるよう versioning に regex の 正規表現 を指定します。 Cluster Autoscalerは対象の Kubernetes クラスタ に対応したバージョンを動かす必要があります。 今回の対象である Kubernetes クラスタ は現時点でv1.22です。 よってCluster Autoscalerのバージョンもv1.22.Xである必要があります。 RenovateがCluster Autoscalerをv1.23.X以降に更新しないよう allowedVersions を指定します。 実行結果 設定に従い GitHub Actionsが毎朝9時にRenovateを実行します。 Helm Chartに更新がある場合は以下のようなPRが自動的に作成されます。 Kustomizeが参照する マニフェスト のURLやイメージタグに更新がある場合は以下のようなPRが自動的に作成されます。 PRの説明文には公式 GitHub リポジトリ のReleaseからRelease Notesが転記されており、具体的な変更内容を知ることができます。 また Dependency Dashboard を有効にしておくと、Renovateが作成したPRを一覧して管理できるIssueが作成されます。 Dependency Dashboard を有効化する設定はPreset config:base に含まれています。 あとはこれらのPRをマージし、Argo CDやFluxを使って Kubernetes クラスタ へデプロイするだけで、 Kubernetes エコシステムの更新は完了です。 なお今回は全てのPRの承認・マージを手動で行う形にしましたが、特定の更新のみ承認・マージを必要にしてそれ以外はPRを自動的にマージするよう設定することも可能です。 特定の更新として、例えば特定のパッケージやメジャーバージョンの更新などが設定できます。 おわりに 本記事ではRenovateを使った Kubernetes エコシステムの自動バージョンアップを紹介しました。 開発が盛んな Kubernetes エコシステムでは、頻繁に新機能やセキュリティ改善が実装され、新しいバージョンとしてリリースされます。 Renovateを活用し、 Kubernetes エコシステムを頻繁かつ自動的にバージョンアップすることで、それらの恩恵を最大限に享受できます。 本記事が少しでも Kubernetes クラスタ を運用している方のお役に立てば幸いです。 私たちは同じチームで働いてくれる仲間を探しています。 クラウド アーキテクトの業務に興味がある方のご応募をお待ちしています。 クラウドアーキテクト 執筆: @shibata.takao 、レビュー: @yamashita.tsuyoshi ( Shodo で執筆されました )