argocdでデフォルトではないネームスペースを使う場合はtracking labelを変更したほうがよさそう
この記事を書こうと思って argocd のドキュメントを見てたら似たようなことを書いてた。(けど本質的には別問題)
Switch resource tracking method¶
Also, while technically not necessary, it is strongly suggested that you switch the application tracking method from the default label setting to either annotation or annotation+label. The reasoning for this is, that application names will be a composite of the namespace’s name and the name of the Application, and this can easily exceed the 63 characters length limit imposed on label values. Annotations have a notably greater length limit.
変更する必要はないけど推奨とのこと。 理由は、label の文字数制限が 63 文字ということを挙げています。
複数の Namespace で Application リソースを扱えるように設定すると、デフォルト以外のネームスペースでデプロイすると、tracking 用の名前を <Namespace>_<アプリケーション名>
といった形式に置き換えるため、文字数制限を超えてしまいデプロイできない可能性が生まれるためです。
そのため、文字数制限が label よりも長い annotations に変更することを推奨していました。
これ以外に別の問題にも当たったので紹介します。
tracking 用のラベルが汎用的なラベルを使っており、それを変更するコトによる問題
argocd はデフォルトで app.kubernetes.io/instance
という各所で使われているラベルを追跡用ラベルとして利用しています。
デフォルトではないネームスペースのアプリケーションの場合 <Namespace>_<アプリケーション名>
という形式に置き換えるという話をしました。
これは文字通り app.kubernetes.io/instance
の値を置き換えます。
しかし、例えばラベルセレクターで指定している値は変更されません。
そうすると、ラベルセレクターで選択されなくなるのでアプリケーションが正常に動作しなくなります。
例: kube-prometheus-stack
kube-prometheus-stack という Helm Chart があります。 これを使うと、Prometheus Operator や NodeExporter など諸々をセットアップすることができます。
Prometheus Operator には ServiceMonitor というリソースがあります。 このリソースは任意の Service リソースを Prometheus で scrape する設定を行うためのリソースです。 この任意の Service リソースを選択するのにラベルセレクターを用いています。
1 selector:
2 matchLabels:
3 {{- with .Values.prometheus.monitor.selectorOverride }}
4 {{- toYaml . | nindent 6 }}
5 {{- else }}
6 {{- include "prometheus-node-exporter.selectorLabels" . | nindent 6 }}
7 {{- end }}
デフォルトでは include "prometheus-node-exporter.selectorLabels"
が展開されます。
この変数は _helpers.tpl
で定義されています。
1{{/*
2Selector labels
3*/}}
4{{- define "prometheus-node-exporter.selectorLabels" -}}
5app.kubernetes.io/name: {{ include "prometheus-node-exporter.name" . }}
6app.kubernetes.io/instance: {{ .Release.Name }}
7{{- end }}
このテンプレートを見ると release name が設定されることがわかります。
こんな感じの Application だと kube-prometheus-stack
(デフォルトで Application の名前) になります。
1apiVersion: argoproj.io/v1alpha1
2kind: Application
3metadata:
4 name: kube-prometheus-stack
5 namespace: argocds-other-ns
6spec:
7 syncPolicy:
8 syncOptions:
9 - CreateNamespace=true
10 project: default
11 sources:
12 - chart: kube-prometheus-stack
13 repoURL: https://prometheus-community.github.io/helm-charts
14 targetRevision: 62.3.1
つまり以下のように生成されます。(app.kubernetes.io/name
はデフォルトでチャート名が入ります)
1selector:
2 matchLabels:
3 app.kubernetes.io/name: kube-prometheus-stack
4 app.kubernetes.io/instance: kube-prometheus-stack
次に ServiceMonitor がマッチさせたい Service の定義を見ます。
1 labels:
2 {{- include "prometheus-node-exporter.labels" $ | nindent 4 }}
3 {{- with .Values.service.labels }}
4 {{- toYaml . | nindent 4 }}
5 {{- end }}
prometheus-node-exporter.labels
変数を見ます。これも _helpers.tpl
に定義されています。
1{{/*
2Common labels
3*/}}
4{{- define "prometheus-node-exporter.labels" -}}
5helm.sh/chart: {{ include "prometheus-node-exporter.chart" . }}
6app.kubernetes.io/managed-by: {{ .Release.Service }}
7app.kubernetes.io/component: metrics
8app.kubernetes.io/part-of: {{ include "prometheus-node-exporter.name" . }}
9{{ include "prometheus-node-exporter.selectorLabels" . }}
10{{- with .Chart.AppVersion }}
11app.kubernetes.io/version: {{ . | quote }}
12{{- end }}
13{{- with .Values.commonLabels }}
14{{ tpl (toYaml .) $ }}
15{{- end }}
16{{- if .Values.releaseLabel }}
17release: {{ .Release.Name }}
18{{- end }}
19{{- end }}
いろいろありますが、{{ include "prometheus-node-exporter.selectorLabels" . }}
とあるので以下のように生成されることがわかります。
1labels:
2 ...
3 app.kubernetes.io/name: kube-prometheus-stack
4 app.kubernetes.io/instance: kube-prometheus-stack
5 ...
ここで、生成したマニフェストのmetadata.labels."app.kubernetes.io/instance"
を argocd が書き換えるので実際には以下のようなものがデプロイされます。
1labels:
2 ...
3 app.kubernetes.io/name: kube-prometheus-stack
4 app.kubernetes.io/instance: argocd-other-ns_kube-prometheus-stack
5 ...
Prometheus は ServiceMonitor を元にapp.kubernetes.io/instance: kube-prometheus-stack
なものを scrape するので、argocd が label を書き換えた Service を scrape してくれないことがわかります。
まとめ
- ラベルセレクターで使われる可能性が高い
app.kubernetes.io/instance
を tracking label として使用していると、argocd によって書き換えられてラベルセレクターが意図した選択をしなくなります - これを回避するため、argocd 以外のネームスペースで Application を扱うときは、tracking label を別のものに変更しておくとよさそうです