前回から新しいバージョンがリリースされ前回の記事で軽く紹介した機能なども追加されたのでまとめて紹介しようと思います。
ApplicationSet自体の話は前回の記事に記載してあるのでよければ見てみてください。
v0.2.0
リリースノート: https://github.com/argoproj-labs/applicationset/releases/tag/v0.2.0
リリース日: 2021/8/10
新機能
Matrix generator
Matrix generatorは2つのジェネレータを組み合わせてそれぞれのジェネレータで検知された内容でApplicationを生成します。
Specは以下のように記述します。
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: cluster-git
spec:
generators:
- matrix: # 'Parent' Matrix Generator
generators:
- git: # 'Child' generator A
repoURL: https://github.com/argoproj-labs/applicationset.git
revision: HEAD
directories:
- path: examples/matrix/cluster-addons/*
- clusters: # 'Child' generator B
selector:
matchLabels:
argocd.argoproj.io/secret-type: cluster
template:
# (...)
サンプルは https://github.com/argoproj-labs/applicationset/releases/tag/v0.2.0 より抜粋
このジェネレータによって、複数のクラスタに複数のApplicationを一つのApplicationSetでデプロイするといったことができるようになります。
SCM Provider generator
SCM Provider generatorは、GitHub/GitLabのAPIを利用してorg内のリポジトリを自動的に検出し、生成されたArgo CDアプリケーションのターゲットにリポジトリの値を使用できるようにする新しいジェネレータです。これは、マイクロサービスを多くのリポジトリに分割するGitOpsのレイアウトパターンによく合っており、単一のリポジトリに固執するパターン(これは他のApplicationSetジェネレータで処理できます)よりも適しています。
Specは以下のように記述します。
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: myapps
spec:
generators:
- scmProvider:
github:
organization: myorg # The GitHub organization to scan.
tokenRef: { } # Reference to a Secret containing an access token. (optional)
template:
# ...
サンプルは https://github.com/argoproj-labs/applicationset/releases/tag/v0.2.0 より抜粋
上手くチーム内でルールを作れればかなりの Application をまとめることができそうです
リリースノートには書いてないですがブランチ単位やリポジトリのラベルをフィルタすることもできるようです
個人的には pull request 単位で作りたいことがあってこれでは地味に解決できなくて困りました
Cluster Decision Resource generator
Cluster Decision Resource generatorは、外部のカスタムリソース(CR)の内容に基づいてArgo CDのクラスターのリストを生成する新しいジェネレーターで、そのカスタムリソースは外部のコントローラーによって管理されます。このジェネレータでは、どのクラスターをターゲットにするかというロジックを、Open Cluster ManagementのPlacementsのようなサードパーティのコントローラー/CRに「アウトソース」することができます。
これは、参照されるKubernetesリソースの完全な形状の知識を必要としないduck-typingを使用してシームレスに処理されます。以下は、cluster-decision-resourceベースのApplicationSetジェネレータの例です。
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: guestbook
spec:
generators:
- clusterDecisionResource:
# ConfigMap with GVK information for the duck type resource
configMapRef: my-configmap
name: quak # Choose either "name" of the resource or "labelSelector"
apiVersion: mallard.io/v1beta1
kind: Duck
metadata:
name: quak
spec: {}
status:
decisions: # Duck-typing ignores all other aspects of the resource except the "decisions" list
- clusterName: cluster-01
- clusterName: cluster-02
apiVersion: v1
kind: ConfigMap
metadata:
name: my-configmap
data:
# apiVersion of the target resource
apiVersion: mallard.io/v1beta1
# kind of the target resource
kind: ducks
# status key name that holds the list of Argo CD clusters
statusListKey: decisions
# The key in the status list whose value is the cluster name found in Argo CD
matchKey: clusterName
サンプルは https://github.com/argoproj-labs/applicationset/releases/tag/v0.2.0 より抜粋
Open Cluster Management の Placements は https://open-cluster-management.io/concepts/placement/ のことのようで、マルチクラスタの管理をするための仕組みのようです。
個人的には面白い使い方ができそうには思ってますが、有用なユースケースがまだ発見できていません。
Preserve Application child resources on deletion of parent ApplicationSet
デフォルトでは、ApplicationSetコントローラによって作成、管理されるアプリケーションには、Argo CDのリソース削除ファイナライザーが含まれています。つまり、ApplicationSetが削除されると、その子のApplicationも削除され、その子のApplicationのクラスタリソースも削除されます。これは、Argo CDのカスケード削除と同じ動作です。
しかし、この動作は必ずしも望ましいものではありません。親アプリケーションが削除されても、子アプリケーションのリソースを保持したい場合があります。これを可能にするには、親の ApplicationSet で .spec.syncPolicy.prespreserveResourcesOnDeletion
の値を使用します。
kind: ApplicationSet
spec:
generators:
- clusters: {}
template:
# (...)
syncPolicy:
# Don't delete Application's child resources, on parent deletion:
preserveResourcesOnDeletion: true
地味に欲しかった機能でこの機能がないときは ApplicationSet の移行をする際に Application リソースでデプロイしたリソースが削除されてしまい、デプロイしているアプリケーションのダウンタイムが発生してしまうので困りましたが、この機能が追加されたので削除することなく移行できるようになりました。
Add YAML configuration file support to Git File generator
ApplicationSetの前のリリースでは、JSON形式の設定ファイルのみがGitファイルジェネレータでサポートされていました。今回のリリースでは、JSONとYAMLの両方のファイルがサポートされ、互換性を持って使用できるようになりました。
Allow any key/value pair in List generator
リスト・ジェネレーターはこれまで、クラスター名/URL値の固定リストのみをサポートしていましたが、オプションでユーザー定義値用の値フィールドが用意されていました。今回、任意のキー/値のペアを指定できるようになりました。
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
spec:
generators:
- list:
elements:
# current form, still supported:
- cluster: engineering-dev
url: https://kubernetes.default.svc
values:
additional: value
# new form, does not require cluster/URL keys:
- staging: true
gitRepo: https://kubernetes.default.svc
template:
# (...)
https://qiita.com/shmurata/items/a6ee4193e2d2c8a2d34c#list-generator で言っていた件ですが指定できるようになりました
Added additional path params to Git File generator
Git File generator は、{{ path }}
と {{ path.basename }}
パラメータを生成するようになりました。これは、Git Directory ジェネレーターで生成されるパラメータと同様に、設定ファイルのパスを含んでいます。
Add exclude path support to Git directories
Git Directoryジェネレータは、Gitリポジトリ内のディレクトリをスキャンし、特定の条件にマッチするディレクトリを探します。しかし、以前のApplicationSetのリリースでは、スキャン対象からフォルダを除外する方法がありませんでした。
今回のリリースでは、個々のパスをスキャン対象から外すことができるようになりました。
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: cluster-addons
spec:
generators:
- git:
repoURL: https://github.com/argoproj-labs/applicationset.git
revision: HEAD
directories:
# Include this first path
- path: examples/git-generator-directory/excludes/cluster-addons/*
# But, exclude this second path:
- path: examples/git-generator-directory/excludes/cluster-addons/exclude-helm-guestbook
exclude: true
Quality of Life Improvements
- Gitディレクトリジェネレータが'.'で始まるすべてのフォルダを無視するようになりました
- アプリケーションのテンプレートにカスタムの'finalizer'をサポートするようになりました
- ApplicationSetコントローラの起動時にログレベルを設定する機能を有効になりました
- ApplicationSetのCRDに'appset/appsets'のショートネームを追加されました
- コントローラ起動時のログにappsetのバージョンを記録するようになりました
その他細かいバグ修正なども入っていますがそちらはリリースノートを参照ください。
v0.3.0
リリースノート: https://github.com/argoproj-labs/applicationset/releases/tag/v0.3.0
リリース日: 2021/12/16
新機能
Pull Request generator
ApplicationSet v0.3.0では、SCMaaSプロバイダー(例:GitHub)のAPIを利用して、リポジトリ内のオープンなプルリクエストを自動的に検出するプルリクエストジェネレーターを新たに追加しました。これは、公開されているプルリクエストに基づいてテスト環境を構築したいというユーザーに適しています。
この例では、オープンなプルリクエストごとにArgo CD Applicationリソースを作成します。
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: myapps
spec:
generators:
- pullRequest:
github:
# The GitHub organization or user.
owner: myorg
# The Github repository
repo: myrepository
# For GitHub Enterprise (optional)
api: https://git.example.com/
# Reference to a Secret containing an access token. (optional)
tokenRef:
secretName: github-token
key: token
# Labels is used to filter the PRs that you want to target. (optional)
labels:
- preview
template:
# ...
自分のチームだと PR が投げられた時に preview 環境を自動的に作るようにしているんですが ApplicationSet でその再現ができなかったため、generator をコントリビュートして追加しました。
Merge generator
このジェネレーターは、あるジェネレーターで生成されたパラメータを、別のジェネレーターで生成されたパラメータで選択的に上書きしたい場合に便利です。
この例では、まずArgo CDからクラスターのリストを収集し、use-kakfa: falseのラベルを持つクラスターのみを「パッチ」し、最後に特定のクラスターでredisを有効にします。
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: cluster-git
spec:
generators:
# merge 'parent' generator
- merge:
mergeKeys:
- server
generators:
# Generate parameters for all Argo CD clusters
- clusters:
values:
kafka: 'true'
redis: 'false'
# For clusters with a specific label, enable Kafka.
- clusters:
selector:
matchLabels:
use-kafka: 'false'
values:
kafka: 'false'
# For a specific cluster, enable Redis.
- list:
elements:
- server: https://2.4.6.8
values.redis: 'true'
これは spec を見ただけでは動作を予想するのは難しそうですが、ドキュメントに詳しい説明が追加されていますのでそちらを見てみることをおすすめします
簡単に説明すると mergeKeys に指定したキーの値が一致する対象に対して上から順番に他のキーの値を上書きしていくという動作をするようです。(結果的に下に記載した値の優先度が高い)
Report error conditions/status for ApplicationSet CR
ユーザーが提供したジェネレータ/テンプレートで無効なArgo CDアプリケーションが生成された場合、ApplicationSetリソースのステータスフィールドにエラーが表示されるようになりました。例えば、以下のようになります。
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: myapps
spec:
generators: # (...)
template: # (...)
status:
conditions:
- lastTransitionTime: "2021-11-23T05:47:08Z"
type: ErrorOccurred
status: "False"
reason: ApplicationSetUpToDate
message: Successfully generated parameters for all Applications
- lastTransitionTime: "2021-11-23T05:47:08Z"
type: ParametersGenerated
message: Successfully generated parameters for all Applications
reason: ParametersGenerated
status: "True"
- lastTransitionTime: "2021-11-23T05:47:08Z"
type: ResourcesUpToDate
status: "True"
reason: ApplicationSetUpToDate
message: ApplicationSet up to date
Git Generator: Refresh ApplicationSet resource with Git generator using webhook
この機能は、GitHub/GitLab webhookトリガーによるApplicationSetの更新をサポートします。この機能は、受信するWebhook payload を listen するサービスを公開し、受信するとApplicationSetコントローラをトリガーしてリソースを再生成します。一方、以前のリリースでは、ApplicationSetコントローラは、Gitジェネレーターが使用するGitリポジトリを3分ごとにポーリングすることしかサポートしていませんでした(ただし、これは少なくともカスタマイズ可能です)。
今まではポーリングでリポジトリの差分検知を行っていたところを webhook でも検知できるように追加したという話です
Pull Request generator: Support for webhooks
Pull Requestジェネレーターを使用する場合、ApplicationSetコントローラは、変更を検出するためにrequeueAfterSeconds間隔(デフォルトでは30分ごと)でポーリングを行います。このポーリングによる遅延をなくすために、ApplicationSetのWebhookサーバーをWebhookイベントを受信するように設定することができ、これがPull Requestジェネレーターでサポートされるようになりました。
git generator と同様に pull requests generator も webhook での差分検知を追加しました
Support -logformat=json as parameter to applicationset-controller
applicationset-controller のログ出力を json に変更するオプションが追加されました。
SCM Generator: Provide SHA for latest commit on a branch in variables
SCM Generator に最新コミットハッシュ(SHA)のパラメータが追加されました。
Improve Git files generator performance
Gitファイル生成機能は、リポジトリ内で発見されたファイルごとに git fetch/git checkout
を不用意に実行するため、時間がかかりすぎていました(Gitリクエストも増加していました)。ApplicationSet v0.3.0では、これが改善され、1回の更新ごとにGitチェックアウト/フェッチレポを発行するようになりました。
Upgrade Notes
0.1.0/0.2.0 から 0.3.0 にアップグレードする場合の挙動の変更が2点あります。
cluster generator の {{name}}
パラメータの値は正規化されなくなりました
cluster generator の {{name}}
パラメータは元の動作に戻りました。Argo CD内のクラスタ名はもはや正規化されません。ApplicationSet内のCluster generatorで生成された{{name}}
パラメータはApplicationSetテンプレートにそのまま渡されるようになりました。
0.2.0の動作を維持する新しいパラメータ{{nameNormalized}}
が導入されました。これにより、パラメータを定義したまま使用するか、正規化された形で使用するか(Applicationリソースのnameフィールドで使用可能)、使用される状況に応じてApplicationSetで使用する動作を選択することができます。
Argo CDのクラスタ名がすでに有効な場合は、変更する必要はありません。ただし、アプリケーションセットのv0.2.0の動作を維持するためには、アプリケーションセットのテンプレート内で{{name}}
を{{nameNormalized}}
に置き換えてください。
正規化というのはこちらのコードの処理のことのようで、ドメイン名として利用できるように利用できる文字と文字数の調整などを行っているようです。詳細はコードを参照してください。
ApplicationSet に無効な生成アプリケーションが含まれていても、有効な生成アプリケーションは処理されます
ApplicationSetコントローラは、ApplicationSetリソースを1つまたは複数のApplicationリソースに変換することを責務としています。しかし、以前のリリースでは、生成されたアプリケーション・リソースの少なくとも1つが無効な場合(例えば、内部の検証ロジックに失敗した場合)、生成されたアプリケーションはどれも処理されませんでした(作成も変更もされません)。
最新のApplicationSetリリースでは、ジェネレーターが無効なApplicationを生成した場合、それらの無効な生成されたApplicationはまだスキップされますが、有効な生成されたApplicationは処理(作成/変更)されるようになりました。
このため、今回のアップグレードではApplicationSetのリソースの変更は必要ありませんが、失敗したApplicationによってブロックされていたApplicationSetがブロックされなくなる可能性があることは覚えておいた方がよいでしょう。この変更により、以前は処理されなかった有効なアプリケーションが作成/変更されるようになるかもしれません。
気づいていなかったですが、一つの ApplicationSet リソースから生成される Application のうちどれか不正なものがあった場合はその ApplicationSet から生成されるすべての Application の生成が止まっていたようです。この修正で問題あるものだけ生成されなくなるようです。
その他細かいバグ修正などはリリースノートを参照ください。
最後に
今回はArgoCD ApplicationSet v0.2.0/0.3.0 の変更点についてまとめました。ApplicationSetはまだ作られ始めということもあり、小さなツールの割には大きな変更がたくさんあり変更点の把握は大変です。その分新しい機能を追加したい場合は気軽に変更を受け入れてもらえるようなので改善したい点などがあればissueを作ったりコントリビュートしてみるとよいと思います。