Add VictoriaMetrics observability stack + sync catalog for monitoring test

- VM stack 10 charts: victoria-metrics-cluster/auth, victoria-logs-cluster,
  victoria-metrics-agent/alert, opentelemetry-collector, kube-state-metrics,
  prometheus-node-exporter, alertmanager, perses (JWT/OIDC, Infisical-ready)
- ArgoCD ApplicationSet (syncWave) + per-chart dip-values overlays
- doc/victoria-metrics-architecture.md, define-chart-resources updates
- includes pending working-tree changes (mlflow, kubeflow, apisix, CLAUDE.md)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
wbsong111
2026-06-25 11:10:51 +09:00
parent a55427730e
commit 6290322f1b
514 changed files with 68103 additions and 40 deletions
@@ -0,0 +1,29 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/
*.md.gotmpl
CHANGELOG.md
_changelog.md
_index.md
e2e/
lint/
tests/
@@ -0,0 +1,70 @@
# victoria-metrics-auth 버전 갱신 가이드
> **카탈로그 업데이트 방식**: 기존 버전 디렉토리는 유지하고, 신규 버전 디렉토리를 새로 생성한다.
> `manifests/helm/victoria-metrics-auth/<new-version>/` 디렉토리를 직접 추가하는 방식으로 관리한다.
## 1. git 작업 환경 구성
- dip-catalog git 다운로드
```sh
git clone https://github.com/paasup/dip-catalog.git
```
- 작업 브랜치로 체크아웃
```sh
git checkout -b update-victoria-metrics-auth/<new-version>
```
## 2. helm chart 업데이트
### 1) 기존 버전 디렉토리 복사
신규 버전 디렉토리를 기존 버전에서 복사하여 시작한다.
`BUILD-README.md`, `CUSTOM-README.md`, `custom-values.yaml`가 함께 복사된다.
```sh
cd ~/dip-catalog/manifests/helm/victoria-metrics-auth
# 기존 버전에서 신규 버전 디렉토리 복사
cp -r 0.33.0 <new-version>
```
### 2) 업스트림 차트 파일 업데이트
신규 버전 디렉토리에서 업스트림 차트 파일만 교체한다.
`BUILD-README.md`, `CUSTOM-README.md`, `custom-values.yaml`는 유지한다.
```sh
cd ~/dip-catalog/manifests/helm/victoria-metrics-auth
# helm repo 추가
helm repo add victoria-metrics https://victoriametrics.github.io/helm-charts/
helm repo update
# 신규 버전 차트 다운로드 후 압축 해제
helm pull victoria-metrics/victoria-metrics-auth --version="<new-version>"
tar xzvf victoria-metrics-auth-<new-version>.tgz -C <new-version> --strip-components=1
# 불필요한 파일 삭제
rm victoria-metrics-auth-<new-version>.tgz
```
## 3. git push 및 tag 추가
```sh
git add .
git commit -m "update victoria-metrics-auth/<new-version>"
git checkout main
git merge update-victoria-metrics-auth/<new-version>
git push -u origin main
git branch -d update-victoria-metrics-auth/<new-version>
git tag victoria-metrics-auth/<new-version>
git push origin victoria-metrics-auth/<new-version>
```
## 4. 차트 버전 정보
- victoria-metrics-auth/0.33.0
- Chart version: 0.33.0
- App version: v1.144.0
- 업스트림: https://victoriametrics.github.io/helm-charts/
@@ -0,0 +1,207 @@
# vmauth 배포 (Keycloak JWT/OIDC 멀티테넌시)
vmauth는 VictoriaMetrics 에코시스템의 인증·라우팅 프록시다. vmselect(메트릭)·vlselect(로그) 앞단에 위치해 클라이언트 요청을 단일 엔드포인트(`:8427`)로 받고, **Keycloak이 발급한 JWT를 검증한 뒤 테넌트(accountID)별로 라우팅**한다.
## 1. 배포 방법
### 배포 시 주의사항
- vmauth **v1.138.0+** 부터 `jwt.oidc.issuer`로 OIDC Discovery 기반 JWT 검증을 지원한다 (Enterprise 아님). 본 카탈로그는 v1.144.0 기준이다.
- 쓰기 경로(remote_write)는 vmauth를 경유하지 않는다. vmagent는 vminsert에 직접 쓴다.
- vmcluster, (로그 사용 시) vlogs가 먼저 배포되어 있어야 한다.
```sh
helm upgrade vmauth ./ -f custom-values.yaml --install -n monitoring
```
## 2. custom-values.yaml 설정 설명
### 2.1 인증 모델 — 전면 JWT/OIDC
`config.users` 항목에 정적 password 대신 `jwt.oidc.issuer`를 선언한다. 클라이언트는 Keycloak 액세스 토큰을 `Authorization: Bearer <JWT>`로 제시하고, vmauth가 Discovery 엔드포인트에서 공개키를 자동 fetch·rotate하여 서명을 검증한다.
```yaml
config:
users:
- jwt:
oidc:
issuer: "https://keycloak.example.org/realms/paasup"
url_map:
# 메트릭: accountID를 URL 경로로 (VictoriaMetrics = 경로 기반)
- src_paths: ["/api/v1/.*"]
url_prefix: "http://...vmselect:8481/select/{{.MetricsAccountID}}/prometheus"
# 로그: accountID를 HTTP 헤더로 (VictoriaLogs = 헤더 기반)
- src_paths: ["/select/logsql/.*"]
url_prefix: "http://...vlselect:9471"
headers:
- "AccountID: {{.LogsAccountID}}"
- "ProjectID: 0"
unauthorized_user:
url_prefix: "http://...vmselect:8481/select/0/prometheus"
```
> **vm vs vl 격리 메커니즘이 다르다**: VictoriaMetrics는 accountID를 **URL 경로**(`/select/{N}/`)로, VictoriaLogs는 **HTTP 헤더**(`AccountID`/`ProjectID`)로 받는다. 동일한 토큰의 `vm_access`가 두 차원(`metrics_account_id`/`logs_account_id`)을 함께 담고, vmauth가 `src_paths`별로 경로 치환 vs 헤더 주입을 다르게 적용한다. 즉 **테넌트별 계정을 나눌 필요 없이 단일 vmauth 항목**으로 둘 다 격리된다.
### 2.2 vm_access 클레임 → accountID 동적 라우팅
토큰의 `vm_access` 클레임이 테넌트를 결정한다. vmauth는 `url_prefix`의 플레이스홀더로 이를 참조한다.
| vm_access 필드 | 플레이스홀더 | 용도 |
|----------------|-------------|------|
| `metrics_account_id` | `{{.MetricsAccountID}}` | 메트릭 테넌트(vmselect `/select/{N}/`) |
| `metrics_project_id` | `{{.MetricsProjectID}}` | 메트릭 프로젝트 |
| (account+project) | `{{.MetricsTenant}}` | `accountID:projectID` 결합 |
| `logs_account_id` | `{{.LogsAccountID}}` | 로그 테넌트 |
JWT payload 예시:
```json
{ "exp": 1771953418, "vm_access": { "metrics_account_id": 1, "logs_account_id": 1 } }
```
### 2.3 unauthorized_user
토큰 없이 들어오는 내부 서비스(vmalert 등)는 `unauthorized_user` 정책으로 accountID 0에 폴백된다.
## 3. Keycloak 설정 (paasup realm)
> 배포 환경에는 **항상 `paasup` realm이 존재**한다. **realm을 새로 만들지 않고** 아래 리소스를 `paasup` realm에 추가한다. issuer는 `https://keycloak.example.org/realms/paasup`.
> 아래는 **Keycloak Admin REST API(curl)** 기준 명령이다. **별도 스크립트 파일은 제공하지 않으며, 운영자가 이 절차를 직접 실행/커스터마이징한다.**
```sh
# 0) 관리자 토큰 발급 + 공통 변수
KC=https://keycloak.example.org
REALM=paasup
TOKEN=$(curl -s -X POST "$KC/realms/master/protocol/openid-connect/token" \
-d grant_type=password -d client_id=admin-cli \
-d username=admin -d password="$KC_ADMIN_PW" | jq -r .access_token)
H="Authorization: Bearer $TOKEN"
JSON="Content-Type: application/json"
```
### 3.1 Client Scope `vm-access` + Protocol Mapper (1회, 배포 시점)
`vm_access` 클레임을 주입하는 매퍼를 Client Scope로 묶어 여러 Client에 공유한다.
```sh
# Client Scope 생성
curl -s -X POST "$KC/admin/realms/$REALM/client-scopes" -H "$H" -H "$JSON" \
-d '{"name":"vm-access","protocol":"openid-connect"}'
SID=$(curl -s "$KC/admin/realms/$REALM/client-scopes" -H "$H" \
| jq -r '.[]|select(.name=="vm-access").id')
# metrics_account_id 매퍼 (claim.name에 점(.) → 중첩 JSON vm_access.metrics_account_id)
curl -s -X POST "$KC/admin/realms/$REALM/client-scopes/$SID/protocol-mappers/models" -H "$H" -H "$JSON" -d '{
"name":"vm-metrics-account","protocol":"openid-connect",
"protocolMapper":"oidc-usermodel-attribute-mapper",
"config":{"user.attribute":"vm_metrics_account_id","claim.name":"vm_access.metrics_account_id",
"jsonType.label":"int","access.token.claim":"true","id.token.claim":"false"}}'
# logs_account_id 매퍼
curl -s -X POST "$KC/admin/realms/$REALM/client-scopes/$SID/protocol-mappers/models" -H "$H" -H "$JSON" -d '{
"name":"vm-logs-account","protocol":"openid-connect",
"protocolMapper":"oidc-usermodel-attribute-mapper",
"config":{"user.attribute":"vm_logs_account_id","claim.name":"vm_access.logs_account_id",
"jsonType.label":"int","access.token.claim":"true","id.token.claim":"false"}}'
```
결과 토큰: `{"vm_access":{"metrics_account_id":1,"logs_account_id":1}}`
### 3.2 Clients (1회, 배포 시점)
| Client | 유형 | 용도 |
|--------|------|------|
| `perses` | confidential (Auth Code + PKCE) | Perses UI 로그인 (vmauth 쿼리 아님) |
| `perses-vmauth` | confidential (Service Accounts / client_credentials) | Perses datasource → vmauth 쿼리 토큰 |
| `vmauth-client` (선택) | public/confidential | curl·Grafana 등 직접 API 접근 |
```sh
# Perses 로그인 Client
curl -s -X POST "$KC/admin/realms/$REALM/clients" -H "$H" -H "$JSON" -d '{
"clientId":"perses","enabled":true,"publicClient":false,"standardFlowEnabled":true,
"redirectUris":["https://perses.example.org/api/auth/providers/oidc/keycloak/callback"]}'
# Perses datasource service-account Client
curl -s -X POST "$KC/admin/realms/$REALM/clients" -H "$H" -H "$JSON" -d '{
"clientId":"perses-vmauth","enabled":true,"publicClient":false,
"standardFlowEnabled":false,"serviceAccountsEnabled":true}'
# vm-access Client Scope를 default로 연결
CID=$(curl -s "$KC/admin/realms/$REALM/clients?clientId=perses-vmauth" -H "$H" | jq -r '.[0].id')
curl -s -X PUT "$KC/admin/realms/$REALM/clients/$CID/default-client-scopes/$SID" -H "$H"
# perses-vmauth 서비스계정에 플랫폼 조회용 account attribute 설정
SAU=$(curl -s "$KC/admin/realms/$REALM/clients/$CID/service-account-user" -H "$H" | jq -r .id)
curl -s -X PUT "$KC/admin/realms/$REALM/users/$SAU" -H "$H" -H "$JSON" -d '{
"attributes":{"vm_metrics_account_id":["0"],"vm_logs_account_id":["0"]}}'
```
> client_secret(`perses-vmauth`)은 perses `files/perses-provisioning.yaml`의 OAuth secret과 일치시켜야 한다 → **perses 차트 설치 전에 생성**한다. (secret 조회: `GET $KC/admin/realms/$REALM/clients/$CID/client-secret`)
### 3.3 테넌트 온보딩 (테넌트마다, 재배포 불필요)
새 테넌트 = `paasup` realm에 **Group 생성 + account 번호 결정 + 멤버 attribute 설정**. vmauth values 수정이나 `helm upgrade`가 필요 없다.
```sh
# 예: demo01 = accountID 1
curl -s -X POST "$KC/admin/realms/$REALM/groups" -H "$H" -H "$JSON" -d '{"name":"tenant-demo01"}'
# 사용자에 account attribute 부여 (그룹 가입과 별개로 토큰에는 user attribute가 실림)
UID=$(curl -s "$KC/admin/realms/$REALM/users?username=alice" -H "$H" | jq -r '.[0].id')
# 기존 표현을 GET 후 attributes만 병합해 PUT (다른 필드 보존)
curl -s "$KC/admin/realms/$REALM/users/$UID" -H "$H" \
| jq '.attributes = (.attributes // {}) + {"vm_metrics_account_id":["1"],"vm_logs_account_id":["1"]}' \
| curl -s -X PUT "$KC/admin/realms/$REALM/users/$UID" -H "$H" -H "$JSON" -d @-
# 그룹 가입
GID=$(curl -s "$KC/admin/realms/$REALM/groups?search=tenant-demo01" -H "$H" | jq -r '.[0].id')
curl -s -X PUT "$KC/admin/realms/$REALM/users/$UID/groups/$GID" -H "$H"
```
> ⚠️ Keycloak에는 그룹 attribute→클레임 빌트인 매퍼가 없다. account 번호는 **사용자 attribute**에 들어가야 토큰에 실린다. 그룹은 관리 단위로 쓰고, 그룹 멤버십 변경 시 멤버 attribute를 채우는 운영 절차(또는 자동화)를 둔다.
>
> Perses 쪽 권한(Project/RoleBinding)은 perses `CUSTOM-README.md` 3장 참조(OIDC groups 미동기화 → UUID subject 수동 관리).
> **vm/vl 비대칭**: 메트릭은 `/select/multitenant/`로 전체 집계 조회가 되지만, VictoriaLogs는 "모든 테넌트 합산" 엔드포인트가 없어 `(AccountID, ProjectID)` 단위로만 조회된다. 플랫폼 통합 로그 뷰는 특정 account(예: 0)로 한정된다.
### 3.4 설정 변경 시 hot reload
vmauth config(`-auth.config`)는 정적 파일이지만 hot reload를 지원한다. 원격 URL/시크릿 로딩은 미지원이며 `%{ENV_VAR}` 치환만 가능하다.
```sh
# 설정 변경 후 (예: 새 url_map 추가)
kubectl exec -n monitoring deploy/vmauth-victoria-metrics-auth -- \
wget -qO- --post-data='' http://localhost:8427/-/reload
# 또는 -configCheckInterval 플래그로 주기적 자동 재로딩
```
## 4. basic-auth fallback (선택)
토큰을 사용할 수 없는 CI/레거시 클라이언트에 한해 정적 basic-auth 항목을 추가한다. 평문 금지 — `%{ENV_VAR}` 치환을 사용한다(`custom-values.yaml` 주석 참조).
## 5. 배포 검증
```sh
kubectl port-forward -n monitoring svc/vmauth-victoria-metrics-auth 8427:8427
# Keycloak 토큰 발급 (client_credentials 예시)
TOKEN=$(curl -s -d "grant_type=client_credentials" \
-d "client_id=<client>" -d "client_secret=<secret>" \
"https://keycloak.example.org/realms/paasup/protocol/openid-connect/token" | jq -r .access_token)
# JWT를 제시해 PromQL 조회 (vm_access의 accountID로 라우팅됨)
curl -s -H "Authorization: Bearer $TOKEN" \
'http://localhost:8427/api/v1/query?query=count(up)' | jq '.status'
# → "success"
```
## 6. 아키텍처
```
클라이언트 ──Bearer JWT──▶ vmauth:8427 ──(vm_access.accountID)──▶ vmselect:8481 /select/{N}/prometheus
└──────────────────────▶ vlselect:9471 (로그)
vmalert(내부) ──(토큰 없음)──▶ vmauth ──unauthorized_user──▶ vmselect /select/0/prometheus
```
> 쓰기 경로는 별도: vmagent ──remote_write──▶ vminsert:8480 (vmauth 미경유)
@@ -0,0 +1,6 @@
dependencies:
- name: victoria-metrics-common
repository: oci://ghcr.io/victoriametrics/helm-charts
version: 0.3.0
digest: sha256:cadb4ced35cde20c5f8437f6ff223ded677542490848e1b3a3b5f330f3069ebc
generated: "2026-04-16T10:13:36.166870712Z"
@@ -0,0 +1,46 @@
annotations:
artifacthub.io/category: monitoring-logging
artifacthub.io/changes: |
- bump version of VM components to [v1.144.0](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.144.0)
artifacthub.io/license: Apache-2.0
artifacthub.io/links: |
- name: Sources
url: https://github.com/VictoriaMetrics/helm-charts/tree/master/charts/victoria-metrics-auth
- name: Charts repo
url: https://victoriametrics.github.io/helm-charts/
- name: Docs
url: https://docs.victoriametrics.com/victoriametrics/vmauth/
- name: Changelog
url: https://docs.victoriametrics.com/victoriametrics/changelog/
artifacthub.io/readme: |
# VictoriaMetrics Auth Helm chart
Chart documentation is available [here](https://docs.victoriametrics.com/helm/victoria-metrics-auth/).
Changelog is [here](https://docs.victoriametrics.com/helm/victoria-metrics-auth/changelog/).
apiVersion: v2
appVersion: v1.144.0
dependencies:
- name: victoria-metrics-common
repository: oci://ghcr.io/victoriametrics/helm-charts
version: 0.3.*
description: VictoriaMetrics Auth - is a simple auth proxy and router for VictoriaMetrics.
home: https://github.com/VictoriaMetrics/helm-charts
icon: https://avatars.githubusercontent.com/u/43720803?s=200&v=4
keywords:
- victoriametrics
- vmauth
- auth
- proxy
- router
- balancer
- monitoring
- kubernetes
- observability
- metrics
- timeseries
kubeVersion: '>=1.25.0-0'
name: victoria-metrics-auth
sources:
- https://github.com/VictoriaMetrics/helm-charts
type: application
version: 0.33.0
@@ -0,0 +1,4 @@
# VictoriaMetrics Auth Helm chart
Chart documentation is available [here](https://docs.victoriametrics.com/helm/victoria-metrics-auth/).
Changelog is [here](https://docs.victoriametrics.com/helm/victoria-metrics-auth/changelog/).
@@ -0,0 +1,7 @@
# Release notes for version 0.33.0
**Release date:** 25 May 2026
![Helm: v3](https://img.shields.io/badge/Helm-v3.14%2B-informational?color=informational&logo=helm&link=https%3A%2F%2Fgithub.com%2Fhelm%2Fhelm%2Freleases%2Ftag%2Fv3.14.0) ![AppVersion: v1.144.0](https://img.shields.io/badge/v1.144.0-success?logo=VictoriaMetrics&labelColor=gray&link=https%3A%2F%2Fdocs.victoriametrics.com%2Fvictoriametrics%2Fchangelog%2F%23v11440)
- bump version of VM components to [v1.144.0](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.144.0)
@@ -0,0 +1,26 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/
*.md.gotmpl
CHANGELOG.md
_changelog.md
_index.md
@@ -0,0 +1,3 @@
dependencies: []
digest: sha256:643d5437104296e21d906ecb15b2c96ad278f20cfc4af53b12bb6069bd853726
generated: "2024-11-13T12:10:17.363248379Z"
@@ -0,0 +1,33 @@
annotations:
artifacthub.io/category: monitoring-logging
artifacthub.io/changes: |
- reverted usage of `app` label in `vm.selectorLabels`
artifacthub.io/license: Apache-2.0
artifacthub.io/links: |
- name: Sources
url: https://github.com/VictoriaMetrics/helm-charts/tree/master/charts/victoria-metrics-common
- name: Charts repo
url: https://victoriametrics.github.io/helm-charts/
artifacthub.io/readme: |
# VictoriaMetrics Common Helm chart
Chart documentation is available [here](https://docs.victoriametrics.com/helm/victoria-metrics-common/).
Changelog is [here](https://docs.victoriametrics.com/helm/victoria-metrics-common/changelog/).
apiVersion: v2
description: VictoriaMetrics Common - contains shared templates for all Victoria Metrics
helm charts
keywords:
- victoriametrics
- monitoring
- kubernetes
- observability
- tsdb
- metrics
- metricsql
- timeseries
kubeVersion: '>=1.23.0-0'
name: victoria-metrics-common
sources:
- https://github.com/VictoriaMetrics/helm-charts
type: library
version: 0.3.0
@@ -0,0 +1,4 @@
# VictoriaMetrics Common Helm chart
Chart documentation is available [here](https://docs.victoriametrics.com/helm/victoria-metrics-common/).
Changelog is [here](https://docs.victoriametrics.com/helm/victoria-metrics-common/changelog/).
@@ -0,0 +1,7 @@
# Release notes for version 0.3.0
**Release date:** 16 Apr 2026
![Helm: v3](https://img.shields.io/badge/Helm-v3.14%2B-informational?color=informational&logo=helm&link=https%3A%2F%2Fgithub.com%2Fhelm%2Fhelm%2Freleases%2Ftag%2Fv3.14.0)
- reverted usage of `app` label in `vm.selectorLabels`
@@ -0,0 +1,87 @@
{{- define "vm.license.secret.key" -}}
{{- $Values := (.helm).Values | default .Values -}}
{{- $plain := (($Values.license).secret).key | default ((($Values.global).license).secret).key -}}
{{- $managed := (($Values.license).keyRef).key | default ((($Values.global).license).keyRef).key }}
{{- if $plain -}}
{{- $plain -}}
{{- else if $managed -}}
{{- $managed -}}
{{- end -}}
{{- end -}}
{{- define "vm.license.secret.name" -}}
{{- $Values := (.helm).Values | default .Values -}}
{{- $plain := (($Values.license).secret).name | default ((($Values.global).license).secret).name -}}
{{- $managed := (($Values.license).keyRef).name | default ((($Values.global).license).keyRef).name -}}
{{- if $plain -}}
{{- $plain -}}
{{- else if $managed -}}
{{- $managed -}}
{{- end -}}
{{- end -}}
{{- define "vm.license.key" -}}
{{- $Values := (.helm).Values | default .Values }}
{{- ($Values.license).key | default (($Values.global).license).key | default "" -}}
{{- end -}}
{{- define "vm.enterprise.disabled" -}}
{{- $licenseKey := (include "vm.license.key" .) -}}
{{- $licenseSecretKey := (include "vm.license.secret.key" .) -}}
{{- $licenseSecretName := (include "vm.license.secret.name" .) -}}
{{- or .noEnterprise (and (empty $licenseKey) (and (empty $licenseSecretName) (empty $licenseSecretKey))) -}}
{{- end -}}
{{- define "vm.enterprise.only" -}}
{{- if eq (include "vm.enterprise.disabled" .) "true" }}
{{ fail `Pass valid license at .Values.license or .Values.global.license if you have an enterprise license for running this software.
See https://victoriametrics.com/legal/esa/ for details.
Documentation - https://docs.victoriametrics.com/victoriametrics/enterprise/
for more information, visit https://victoriametrics.com/products/enterprise/
To request a trial license, go to https://victoriametrics.com/products/enterprise/trial/` }}
{{- end -}}
{{- end -}}
{{/*
Return license volume mount
*/}}
{{- define "vm.license.volume" -}}
{{- $licenseSecretKey := (include "vm.license.secret.key" .) -}}
{{- $licenseSecretName := (include "vm.license.secret.name" .) -}}
{{- if and $licenseSecretName $licenseSecretKey -}}
- name: license-key
secret:
secretName: {{ $licenseSecretName }}
{{- end -}}
{{- end -}}
{{/*
Return license volume mount for container
*/}}
{{- define "vm.license.mount" -}}
{{- $licenseSecretKey := (include "vm.license.secret.key" .) -}}
{{- $licenseSecretName := (include "vm.license.secret.name" .) -}}
{{- if and $licenseSecretName $licenseSecretKey -}}
- name: license-key
mountPath: /etc/vm-license-key
readOnly: true
{{- end -}}
{{- end -}}
{{/*
Return license flag if necessary.
*/}}
{{- define "vm.license.flag" -}}
{{- $licenseKey := (include "vm.license.key" .) -}}
{{- $licenseSecretKey := (include "vm.license.secret.key" .) -}}
{{- $licenseSecretName := (include "vm.license.secret.name" .) -}}
{{- if $licenseKey -}}
license: {{ $licenseKey }}
{{- else if and $licenseSecretName $licenseSecretKey -}}
{{- $flagName := "licenseFile" -}}
{{- if eq .flagStyle "kebab" }}
{{- $flagName = "license-file" -}}
{{- end -}}
{{- $flagName }}: /etc/vm-license-key/{{ $licenseSecretKey }}
{{- end -}}
{{- end -}}
@@ -0,0 +1,249 @@
{{- define "vm.namespace" -}}
{{- include "vm.validate.args" . -}}
{{- $Release := (.helm).Release | default .Release -}}
{{- $Values := (.helm).Values | default .Values -}}
{{- $Values.namespaceOverride | default ($Values.global).namespaceOverride | default $Release.Namespace -}}
{{- end -}}
{{- define "vm.validate.args" -}}
{{- $Chart := (.helm).Chart | default .Chart -}}
{{- $Capabilities := (.helm).Capabilities | default .Capabilities -}}
{{- if semverCompare "<3.14.0" $Capabilities.HelmVersion.Version }}
{{- fail "This chart requires helm version 3.14.0 or higher" }}
{{- end }}
{{- if empty $Chart -}}
{{- fail "invalid template data" -}}
{{- end -}}
{{- end -}}
{{- /* Expand the name of the chart. */ -}}
{{- define "vm.name" -}}
{{- include "vm.validate.args" . -}}
{{- $Chart := (.helm).Chart | default .Chart -}}
{{- $Values := (.helm).Values | default .Values -}}
{{- $nameOverride := $Values.nameOverride | default ($Values.global).nameOverride | default $Chart.Name -}}
{{- if or ($Values.global).disableNameTruncation $Values.disableNameTruncation -}}
{{- $nameOverride -}}
{{- else -}}
{{- $nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
{{- /*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/ -}}
{{- define "vm.fullname" -}}
{{- include "vm.validate.args" . -}}
{{- $Values := (.helm).Values | default .Values -}}
{{- $Chart := (.helm).Chart | default .Chart -}}
{{- $Release := (.helm).Release | default .Release -}}
{{- $fullname := "" -}}
{{- if $Values.fullnameOverride -}}
{{- $fullname = $Values.fullnameOverride -}}
{{- else if ($Values.global).fullnameOverride -}}
{{- $fullname = $Values.global.fullnameOverride -}}
{{- else -}}
{{- $name := default $Chart.Name $Values.nameOverride -}}
{{- if contains $name $Release.Name -}}
{{- $fullname = $Release.Name -}}
{{- else -}}
{{- $fullname = (printf "%s-%s" $Release.Name $name) }}
{{- end -}}
{{- end -}}
{{- $fullname = tpl $fullname . -}}
{{- if or ($Values.global).disableNameTruncation $Values.disableNameTruncation -}}
{{- $fullname -}}
{{- else -}}
{{- $fullname | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end }}
{{- define "vm.cr.fullname" -}}
{{- $Values := (.helm).Values | default .Values -}}
{{- $_ := set . "overrideKey" "name" -}}
{{- $fullname := include "vm.internal.key" . -}}
{{- $_ := unset . "overrideKey" -}}
{{- if empty $fullname -}}
{{- $fullname = include "vm.fullname" . -}}
{{- end -}}
{{- $fullname = tpl $fullname . -}}
{{- if or ($Values.global).disableNameTruncation $Values.disableNameTruncation -}}
{{- $fullname -}}
{{- else -}}
{{- $fullname | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
{{- define "vm.managed.fullname" -}}
{{- $Values := (.helm).Values | default .Values -}}
{{- $_ := set . "overrideKey" "name" -}}
{{- $fullname := include "vm.internal.key" . -}}
{{- $_ := unset . "overrideKey" -}}
{{- if empty $fullname -}}
{{- $fullname = include "vm.fullname" . -}}
{{- end -}}
{{- with include "vm.internal.key.default" . -}}
{{- $prefix := ternary . (printf "vm%s" .) (or (hasPrefix "vm" .) (hasPrefix "vl" .)) -}}
{{- $fullname = printf "%s-%s" $prefix $fullname -}}
{{- end -}}
{{- $fullname = tpl $fullname . -}}
{{- if or ($Values.global).disableNameTruncation $Values.disableNameTruncation -}}
{{- $fullname -}}
{{- else -}}
{{- $fullname | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
{{- define "vm.plain.fullname" -}}
{{- $Values := (.helm).Values | default .Values -}}
{{- $_ := set . "overrideKey" "fullnameOverride" -}}
{{- $fullname := include "vm.internal.key" . -}}
{{- $_ := unset . "overrideKey" -}}
{{- if empty $fullname -}}
{{- $fullname = include "vm.fullname" . -}}
{{- with include "vm.internal.key.default" . -}}
{{- $fullname = printf "%s-%s" $fullname . -}}
{{- end -}}
{{- end -}}
{{- $fullname = tpl $fullname . -}}
{{- if or ($Values.global).disableNameTruncation $Values.disableNameTruncation -}}
{{- $fullname -}}
{{- else -}}
{{- $fullname | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
{{- define "vm.internal.key" -}}
{{- include "vm.validate.args" . -}}
{{- $overrideKey := .overrideKey | default "fullnameOverride" -}}
{{- $Values := (.helm).Values | default .Values -}}
{{- $key := "" -}}
{{- if .appKey -}}
{{- $appKey := ternary (list .appKey) .appKey (kindIs "string" .appKey) -}}
{{- $ctx := . -}}
{{- $values := $Values -}}
{{- range $ak := $appKey }}
{{- $values = ternary (dict) (index $values $ak | default dict) (empty $values) -}}
{{- $ctx = ternary (dict) (index $ctx $ak | default dict) (empty $ctx) -}}
{{- if and (empty $values) (empty $ctx) -}}
{{- fail (printf "No data for appKey %s" (join "->" $appKey)) -}}
{{- end -}}
{{- if and (kindIs "map" $values) (index $values $overrideKey) -}}
{{- $key = index $values $overrideKey -}}
{{- else if and (kindIs "map" $ctx) (index $ctx $overrideKey) -}}
{{- $key = index $ctx $overrideKey -}}
{{- end -}}
{{- end }}
{{- if and (empty $key) .fallback -}}
{{- $key = include "vm.internal.key.default" . -}}
{{- end -}}
{{- end -}}
{{- $key -}}
{{- end -}}
{{- define "vm.internal.key.default" -}}
{{- with .appKey -}}
{{- $key := ternary (list .) . (kindIs "string" .) -}}
{{- last (without $key "spec") -}}
{{- end -}}
{{- end -}}
{{- /* Create chart name and version as used by the chart label. */ -}}
{{- define "vm.chart" -}}
{{- include "vm.validate.args" . -}}
{{- $Values := (.helm).Values | default .Values -}}
{{- $Chart := (.helm).Chart | default .Chart -}}
{{- $chart := printf "%s-%s" $Chart.Name $Chart.Version | replace "+" "_" -}}
{{- if or ($Values.global).disableNameTruncation $Values.disableNameTruncation -}}
{{- $chart -}}
{{- else -}}
{{- $chart | trunc 63 | trimSuffix "-" -}}
{{- end }}
{{- end }}
{{- /* Create the name of the service account to use */ -}}
{{- define "vm.sa.name" -}}
{{- include "vm.validate.args" . -}}
{{- $Values := (.helm).Values | default .Values -}}
{{- if $Values.serviceAccount.create }}
{{- default (include "vm.fullname" .) $Values.serviceAccount.name }}
{{- else -}}
{{- default "default" $Values.serviceAccount.name -}}
{{- end }}
{{- end }}
{{- define "vm.metaLabels" -}}
{{- include "vm.validate.args" . -}}
{{- $Release := (.helm).Release | default .Release -}}
{{- $labels := .extraLabels | default dict -}}
{{- $_ := set $labels "helm.sh/chart" (include "vm.chart" .) -}}
{{- $_ := set $labels "app.kubernetes.io/managed-by" $Release.Service -}}
{{- toYaml $labels -}}
{{- end -}}
{{- define "vm.podLabels" -}}
{{- include "vm.validate.args" . -}}
{{- $Release := (.helm).Release | default .Release -}}
{{- $labels := fromYaml (include "vm.selectorLabels" .) -}}
{{- with $labels.app -}}
{{- $_ := set $labels "app.kubernetes.io/component" . -}}
{{- end -}}
{{- $labels = mergeOverwrite $labels (.extraLabels | default dict) -}}
{{- $_ := set $labels "app.kubernetes.io/managed-by" $Release.Service -}}
{{- toYaml $labels -}}
{{- end -}}
{{- /* Common labels */ -}}
{{- define "vm.labels" -}}
{{- include "vm.validate.args" . -}}
{{- $Values := (.helm).Values | default .Values -}}
{{- $globalLabels := deepCopy (($Values.global).extraLabels | default dict) -}}
{{- $labels := fromYaml (include "vm.commonLabels" .) -}}
{{- $labels = mergeOverwrite $globalLabels $labels (fromYaml (include "vm.metaLabels" .)) -}}
{{- with (include "vm.image.tag" .) }}
{{- $_ := set $labels "app.kubernetes.io/version" (regexReplaceAll "(.*)(@sha.*)" . "${1}") -}}
{{- end -}}
{{- toYaml $labels -}}
{{- end -}}
{{- define "vm.release" -}}
{{- include "vm.validate.args" . -}}
{{- $Release := (.helm).Release | default .Release -}}
{{- $Values := (.helm).Values | default .Values -}}
{{- $release := default $Release.Name $Values.argocdReleaseOverride -}}
{{- if or ($Values.global).disableNameTruncation $Values.disableNameTruncation -}}
{{- $release -}}
{{- else -}}
{{- $release | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
{{- define "vm.app.name" -}}
{{- $_ := set . "overrideKey" "name" -}}
{{- $_ := set . "fallback" true -}}
{{- tpl (include "vm.internal.key" .) . -}}
{{- $_ := unset . "overrideKey" -}}
{{- $_ := unset . "fallback" -}}
{{- end -}}
{{- /* Selector labels */ -}}
{{- define "vm.selectorLabels" -}}
{{- $labels := .extraLabels | default dict -}}
{{- $_ := set $labels "app.kubernetes.io/name" (include "vm.name" .) -}}
{{- $_ := set $labels "app.kubernetes.io/instance" (include "vm.release" .) -}}
{{- with (include "vm.app.name" .) -}}
{{- $_ := set $labels "app" . -}}
{{- end -}}
{{- toYaml $labels -}}
{{- end }}
{{- define "vm.commonLabels" -}}
{{- $labels := fromYaml (include "vm.selectorLabels" . ) -}}
{{- with $labels.app -}}
{{- $_ := set $labels "app.kubernetes.io/component" . -}}
{{- $_ := unset $labels "app" -}}
{{- end -}}
{{- toYaml $labels -}}
{{- end -}}
@@ -0,0 +1,61 @@
{{/*
Victoria Metrics Image
*/}}
{{- define "vm.image" -}}
{{- $image := (fromYaml (include "vm.internal.image" .)).image | default dict -}}
{{- $tag := include "vm.image.tag" . -}}
{{- if empty $image.repository -}}
{{- fail "cannot create image without `.repository` defined" -}}
{{- end -}}
{{- $result := tpl (printf "%s:%s" $image.repository $tag) . -}}
{{- with $image.registry | default "" -}}
{{- $result = (printf "%s/%s" . $result) -}}
{{- end -}}
{{- $result -}}
{{- end -}}
{{- define "vm.image.tag" -}}
{{- $Chart := (.helm).Chart | default .Chart -}}
{{- $image := (fromYaml (include "vm.internal.image" .)).image | default dict -}}
{{- $tag := $image.tag -}}
{{- if empty $tag }}
{{- $tag = $Chart.AppVersion -}}
{{- $variant := $image.variant }}
{{- if eq (include "vm.enterprise.disabled" .) "false" -}}
{{- if $variant }}
{{- $variant = printf "enterprise-%s" $variant }}
{{- else }}
{{- $variant = "enterprise" }}
{{- end }}
{{- end -}}
{{- with $variant -}}
{{- $tag = (printf "%s-%s" $tag .) -}}
{{- end -}}
{{- end -}}
{{- $tag -}}
{{- end -}}
{{- define "vm.internal.image" -}}
{{- $Values := (.helm).Values | default .Values -}}
{{- $values := $Values -}}
{{- $ctx := . -}}
{{- with .appKey -}}
{{- $appKey := ternary (list .) . (kindIs "string" .) -}}
{{- range $ak := $appKey -}}
{{- $values = ternary (dict) (index $values $ak | default dict) (empty $values) -}}
{{- $ctx = ternary (dict) (index $ctx $ak | default dict) (empty $ctx) -}}
{{- if and (empty $values) (empty $ctx) -}}
{{- fail (printf "No data for appKey %s" (join "->" $appKey)) -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- $image := ternary (deepCopy ($ctx.image | default dict)) (deepCopy ($values.image | default dict)) (hasKey $ctx "image") -}}
{{- if not $image.registry }}
{{- if (($Values.global).image).registry -}}
{{- $_ := set $image "registry" (($Values.global).image).registry -}}
{{- else if hasKey $image "registry" -}}
{{- $_ := unset $image "registry" -}}
{{- end -}}
{{- end -}}
{{- toYaml (dict "image" $image) -}}
{{- end -}}
@@ -0,0 +1,8 @@
{{- define "vm.ingress.port" }}
{{- $port := dict "name" "http" }}
{{- with .port }}
{{- $numberTypes := list "int" "float64" }}
{{- $port = dict (ternary "number" "name" (has (kindOf .) $numberTypes)) . }}
{{- end -}}
{{- toYaml $port -}}
{{- end }}
@@ -0,0 +1,117 @@
{{- define "vm.port.from.flag" -}}
{{- $port := .default -}}
{{- with .flag -}}
{{- $port = regexReplaceAll ".*:(\\d+)" . "${1}" -}}
{{- end -}}
{{- $port -}}
{{- end }}
{{- /*
Return true if the detected platform is Openshift
Usage:
{{- include "vm.isOpenshift" . -}}
*/ -}}
{{- define "vm.isOpenshift" -}}
{{- $Capabilities := (.helm).Capabilities | default .Capabilities -}}
{{- if $Capabilities.APIVersions.Has "security.openshift.io/v1" -}}
{{- true -}}
{{- end -}}
{{- end -}}
{{- /*
Render a compatible securityContext depending on the platform.
Usage:
{{- include "vm.securityContext" (dict "securityContext" .Values.containerSecurityContext "helm" .) -}}
*/ -}}
{{- define "vm.securityContext" -}}
{{- $securityContext := omit .securityContext "enabled" -}}
{{- $Values := (.helm).Values | default .Values -}}
{{- $adaptMode := (((($Values).global).compatibility).openshift).adaptSecurityContext | default "" -}}
{{- if or (eq $adaptMode "force") (and (eq $adaptMode "auto") (include "vm.isOpenshift" .)) -}}
{{- $securityContext = omit $securityContext "fsGroup" "runAsUser" "runAsGroup" "seLinuxOptions" -}}
{{- end -}}
{{- toYaml $securityContext -}}
{{- end -}}
{{- /*
Render probe
*/ -}}
{{- define "vm.probe" -}}
{{- /* undefined value */ -}}
{{- $null := (fromYaml "value: null").value -}}
{{- $probe := dig .type (dict) .app.probe -}}
{{- $probeType := "" -}}
{{- $defaultProbe := dict -}}
{{- if ne (dig "httpGet" $null $probe) $null -}}
{{- /* httpGet probe */ -}}
{{- $defaultProbe = dict "path" (include "vm.probe.http.path" .) "scheme" (include "vm.probe.http.scheme" .) "port" (include "vm.probe.port" .) -}}
{{- $probeType = "httpGet" -}}
{{- else if ne (dig "tcpSocket" $null $probe) $null -}}
{{- /* tcpSocket probe */ -}}
{{- $defaultProbe = dict "port" (include "vm.probe.port" .) -}}
{{- $probeType = "tcpSocket" -}}
{{- end -}}
{{- $defaultProbe = ternary (dict) (dict $probeType $defaultProbe) (empty $probeType) -}}
{{- $probe = mergeOverwrite $defaultProbe $probe -}}
{{- range $key, $value := $probe -}}
{{- if and (has (kindOf $value) (list "object" "map")) (ne $key $probeType) -}}
{{- $_ := unset $probe $key -}}
{{- end -}}
{{- end -}}
{{- tpl (toYaml $probe) . -}}
{{- end -}}
{{- /*
HTTP GET probe path
*/ -}}
{{- define "vm.probe.http.path" -}}
{{- index .app.extraArgs "http.pathPrefix" | default "" | trimSuffix "/" -}}/health
{{- end -}}
{{- /*
HTTP GET probe scheme
*/ -}}
{{- define "vm.probe.http.scheme" -}}
{{- $isSecure := false -}}
{{- with ((.app).extraArgs).tls -}}
{{- $isSecure = eq (toString .) "true" -}}
{{- end -}}
{{- ternary "HTTPS" "HTTP" $isSecure -}}
{{- end -}}
{{- /*
Net probe port
*/ -}}
{{- define "vm.probe.port" -}}
{{- dig "ports" "name" "http" (.app | dict) -}}
{{- end -}}
{{- define "vm.arg" -}}
{{- if and (empty .value) (kindIs "string" .value) (ne (toString .list) "true") }}
{{- .key -}}
{{- else if eq (toString .value) "true" -}}
-{{ ternary "" "-" (eq (len .key) 1) }}{{ .key }}
{{- else -}}
-{{ ternary "" "-" (eq (len .key) 1) }}{{ .key }}={{ ternary (toJson .value | squote) .value (has (kindOf .value) (list "map" "slice")) }}
{{- end -}}
{{- end -}}
{{- /*
command line arguments
*/ -}}
{{- define "vm.args" -}}
{{- $args := list -}}
{{- range $key, $value := . -}}
{{- if not $key -}}
{{- fail "Empty key in command line args is not allowed" -}}
{{- end -}}
{{- if kindIs "slice" $value -}}
{{- range $v := $value -}}
{{- $args = append $args (include "vm.arg" (dict "key" $key "value" $v "list" true)) -}}
{{- end -}}
{{- else -}}
{{- $args = append $args (include "vm.arg" (dict "key" $key "value" $value)) -}}
{{- end -}}
{{- end -}}
{{- toYaml (dict "args" $args) -}}
{{- end -}}
@@ -0,0 +1,88 @@
{{- /* Create the name for VM service */ -}}
{{- define "vm.service" -}}
{{- include "vm.validate.args" . -}}
{{- $Values := (.helm).Values | default .Values -}}
{{- $nameTpl := "" -}}
{{- if eq .style "managed" -}}
{{- $nameTpl = "vm.managed.fullname" }}
{{- else if eq .style "plain" -}}
{{- $nameTpl = "vm.plain.fullname" }}
{{- else -}}
{{- fail ".style argument should be either `plain` or `managed`"}}
{{- end -}}
{{- include $nameTpl . -}}
{{- end }}
{{- define "vm.fqdn" -}}
{{- $name := (include "vm.service" .) -}}
{{- if hasKey . "appIdx" -}}
{{- $name = (printf "%s-%d.%s" $name .appIdx $name) -}}
{{- end -}}
{{- $Values := (.helm).Values | default .Values -}}
{{- $ns := (include "vm.namespace" .) -}}
{{- $fqdn := printf "%s.%s.svc" $name $ns -}}
{{- with (($Values.global).cluster).dnsDomain -}}
{{- $fqdn = printf "%s.%s" $fqdn . -}}
{{- end -}}
{{- $fqdn -}}
{{- end -}}
{{- define "vm.host" -}}
{{- $fqdn := (include "vm.fqdn" .) -}}
{{- $port := 80 -}}
{{- $isSecure := ternary false true (empty .appSecure) -}}
{{- $Values := (.helm).Values | default .Values -}}
{{- if .appKey -}}
{{- $appKey := ternary (list .appKey) .appKey (kindIs "string" .appKey) -}}
{{- $values := $Values -}}
{{- $ctx := . -}}
{{- range $ak := $appKey -}}
{{- $values = ternary (dict) (index $values $ak | default dict) (empty $values) -}}
{{- $ctx = ternary (dict) (index $ctx $ak | default dict) (empty $ctx) -}}
{{- end -}}
{{- $spec := dict -}}
{{- if $ctx -}}
{{- $spec = $ctx -}}
{{- else if $values -}}
{{- $spec = $values -}}
{{- end -}}
{{- with ($spec.extraArgs).tls -}}
{{- $isSecure = eq (toString .) "true" -}}
{{- end -}}
{{- $port = (ternary 443 80 $isSecure) -}}
{{- $port = $spec.port | default ($spec.service).servicePort | default ($spec.service).port | default $port -}}
{{- if hasKey . "appIdx" -}}
{{- $port = (include "vm.port.from.flag" (dict "flag" ($spec.extraArgs).httpListenAddr "default" $port)) -}}
{{- end }}
{{- end }}
{{- $fqdn }}:{{ $port }}
{{- end -}}
{{- define "vm.url" -}}
{{- $host := (include "vm.host" .) -}}
{{- $Values := (.helm).Values | default .Values -}}
{{- $proto := "http" -}}
{{- $path := .appRoute | default "/" -}}
{{- $isSecure := ternary false true (empty .appSecure) -}}
{{- if .appKey -}}
{{- $appKey := ternary (list .appKey) .appKey (kindIs "string" .appKey) -}}
{{- $values := $Values -}}
{{- $ctx := . -}}
{{- range $ak := $appKey -}}
{{- $values = ternary (dict) (index $values $ak | default dict) (empty $values) -}}
{{- $ctx = ternary (dict) (index $ctx $ak | default dict) (empty $ctx) -}}
{{- end -}}
{{- $spec := dict -}}
{{- if $values -}}
{{- $spec = $values -}}
{{- else if $ctx -}}
{{- $spec = $ctx -}}
{{- end -}}
{{- with ($spec.extraArgs).tls -}}
{{- $isSecure = eq (toString .) "true" -}}
{{- end -}}
{{- $proto = (ternary "https" "http" $isSecure) -}}
{{- $path = dig "http.pathPrefix" $path ($spec.extraArgs | default dict) -}}
{{- end -}}
{{- printf "%s://%s%s" $proto $host (trimSuffix "/" $path) -}}
{{- end -}}
@@ -0,0 +1,56 @@
# =============================================================================
# vmauth — PaaSup 커스텀 오버라이드 (Keycloak JWT/OIDC 멀티테넌시)
# 차트: victoria-metrics/victoria-metrics-auth
# 포트: 8427 / 역할: vmselect·vlselect 앞단 인증·라우팅 프록시
#
# 인증 모델: 전면 JWT/OIDC (vmauth v1.138.0+, Enterprise 아님)
# - 클라이언트는 Keycloak이 발급한 액세스 토큰(JWT)을 Bearer로 제시
# - vmauth가 jwt.oidc.issuer Discovery로 공개키를 자동 fetch/rotate → 서명 검증
# - 토큰의 vm_access 클레임(metrics_account_id 등)으로 테넌트를 동적 라우팅
# - 테넌트 추가 = Keycloak 그룹/attribute 추가만 → vmauth 재배포 불필요
#
# Keycloak 측 준비: vm_access 클레임을 주입하는 Protocol Mapper 필요
# {"vm_access": {"metrics_account_id": <N>, "logs_account_id": <N>}}
# 자세한 절차는 CUSTOM-README.md 참조.
# =============================================================================
replicaCount: 1
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
cpu: 200m
memory: 128Mi
config:
users:
# ── 권장: Keycloak JWT 검증 + vm_access 동적 라우팅 ──────────────────────
# 모든 사용자/팀이 단일 항목을 공유한다. 테넌트 구분은 토큰의 vm_access 클레임이 담당.
- jwt:
oidc:
# 배포 환경에 항상 존재하는 paasup realm 사용 (realm 신규 생성 금지)
issuer: "https://keycloak.example.org/realms/paasup"
url_map:
# 메트릭(PromQL): vm_access.metrics_account_id → URL 경로 /select/{accountID}/ (경로 기반 격리)
- src_paths: ["/api/v1/.*"]
url_prefix: "http://vmcluster-victoria-metrics-cluster-vmselect.monitoring.svc.cluster.local:8481/select/{{.MetricsAccountID}}/prometheus"
# 로그(LogsQL): vlselect + AccountID 헤더 (VictoriaLogs는 헤더 기반 테넌트 격리)
- src_paths: ["/select/logsql/.*"]
url_prefix: "http://vlogs-victoria-logs-cluster-vlselect.monitoring.svc.cluster.local:9471"
headers:
- "AccountID: {{.LogsAccountID}}"
- "ProjectID: 0"
# ── 대안(주석): 정적 basic-auth ──────────────────────────────────────────
# 토큰을 사용할 수 없는 CI/레거시 클라이언트에 한해 추가한다. 평문 금지 → %{ENV_VAR} 치환 사용.
# - username: ci-bot
# password: "%{CI_BOT_PASSWORD}"
# url_map:
# - src_paths: ["/api/v1/.*"]
# url_prefix: "http://vmcluster-victoria-metrics-cluster-vmselect.monitoring.svc.cluster.local:8481/select/9000/prometheus"
# 인증 없는 내부 서비스(vmalert 등) — accountID 0으로 폴백
unauthorized_user:
url_prefix: "http://vmcluster-victoria-metrics-cluster-vmselect.monitoring.svc.cluster.local:8481/select/0/prometheus"
@@ -0,0 +1,53 @@
{{- $ctx := dict "helm" . "style" "plain" }}
{{- $fullname := include "vm.plain.fullname" $ctx }}
{{- $ns := include "vm.namespace" $ctx }}
Write API:
The Victoria Metrics Auth can be accessed via port {{ .Values.service.servicePort }} on the following DNS name from within your cluster:
{{ $fullname }}
Get the Victoria Metrics Auth service URL by running these commands in the same shell:
{{- if contains "NodePort" .Values.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ $ns }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ $fullname }})
export NODE_IP=$(kubectl get nodes --namespace {{ $ns }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{- else if contains "LoadBalancer" .Values.service.type }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status of by running 'kubectl get svc --namespace {{ $ns }} -w {{ $fullname }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ $ns }} {{ $fullname }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo http://$SERVICE_IP:{{ .Values.service.servicePort }}
{{- else if contains "ClusterIP" .Values.service.type }}
export POD_NAME=$(kubectl get pods --namespace {{ $ns }} -l "app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
kubectl --namespace {{ $ns }} port-forward $POD_NAME {{ .Values.service.servicePort }}
{{- end }}
You need to update your prometheus configuration file and add next lines into it:
prometheus.yml
```yaml
remote_write:
- url: "http://<insert-service>/insert/0/prometheus/"
```
for e.g. inside the kubernetes cluster:
```yaml
remote_write:
- url: {{ include "vm.url" $ctx }}/insert/0/prometheus/
```
Read API:
You need to update specify select service URL in your Grafana:
NOTE: you need to use Prometheus Data Source
Input for URL field in Grafana
```
http://<select-service>:{{ .Values.service.servicePort }}/select/0/prometheus/
```
for e.g. inside the kubernetes cluster:
```
{{ include "vm.url" $ctx }}/select/0/prometheus/"
```
@@ -0,0 +1,8 @@
{{- define "vmauth.args" -}}
{{- $args := dict -}}
{{- $Values := (.helm).Values | default .Values }}
{{- $_ := set $args "auth.config" "/config/auth.yml" -}}
{{- $args = mergeOverwrite $args (fromYaml (include "vm.license.flag" .)) -}}
{{- $args = mergeOverwrite $args $Values.extraArgs -}}
{{- toYaml (fromYaml (include "vm.args" $args)).args -}}
{{- end -}}
@@ -0,0 +1,4 @@
{{ range .Values.extraObjects }}
---
{{ tpl (ternary . (toYaml .) (typeIs "string" .)) $ }}
{{ end }}
@@ -0,0 +1,45 @@
{{- $app := .Values }}
{{- $ctx := dict "helm" . }}
{{- $ingresses := dict "" $app.ingress "internal" $app.ingressInternal }}
{{- range $suffix, $ingress := $ingresses }}
{{- if $ingress.enabled }}
{{- $_ := set $ctx "extraLabels" $ingress.extraLabels }}
{{- $fullname := include "vm.plain.fullname" $ctx }}
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
{{- with $ingress.annotations }}
annotations: {{ toYaml . | nindent 4 }}
{{- end }}
{{- $_ := set $ctx "extraLabels" $app.ingress.extraLabels }}
labels: {{ include "vm.labels" $ctx | nindent 4 }}
{{- $_ := unset $ctx "extraLabels" }}
name: {{ $fullname }}{{ ternary "" (printf "-%s" $suffix) (empty $suffix) }}
namespace: {{ include "vm.namespace" $ctx }}
spec:
{{- with $ingress.ingressClassName }}
ingressClassName: {{ . }}
{{- end }}
{{- with $ingress.tls }}
tls: {{ tpl (toYaml .) $ | nindent 4 }}
{{- end }}
rules:
{{- range $host := $ingress.hosts }}
{{- $paths := ternary (list $host.path) $host.path (kindIs "string" $host.path) }}
- host: {{ tpl $host.name $ | quote }}
http:
paths:
{{- range $path := $paths }}
- path: {{ $path }}
{{- with $ingress.pathType }}
pathType: {{ . }}
{{- end }}
backend:
service:
name: {{ $fullname }}
port: {{ include "vm.ingress.port" $host | nindent 18 }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
@@ -0,0 +1,47 @@
{{- if .Values.serviceMonitor.enabled -}}
{{- $serviceMonitor := .Values.serviceMonitor -}}
{{- $ctx := dict "helm" . }}
{{- $fullname := include "vm.plain.fullname" $ctx }}
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
{{- with $serviceMonitor.annotations }}
annotations: {{ toYaml . | nindent 4 }}
{{- end }}
{{- $_ := set $ctx "extraLabels" $serviceMonitor.extraLabels }}
labels: {{ include "vm.labels" $ctx | nindent 4 }}
{{- $_ := unset $ctx "extraLabels" }}
name: {{ $fullname }}
{{- with $serviceMonitor.namespace }}
namespace: {{ . }}
{{- end }}
spec:
namespaceSelector:
matchNames:
- {{ include "vm.namespace" $ctx }}
selector:
matchLabels: {{ include "vm.commonLabels" $ctx | nindent 6 }}
endpoints:
- port: http
{{- with $serviceMonitor.basicAuth }}
basicAuth: {{ toYaml . | nindent 8 }}
{{- end }}
{{- with $serviceMonitor.scheme }}
scheme: {{ . }}
{{- end }}
{{- with $serviceMonitor.interval }}
interval: {{ . }}
{{- end }}
{{- with $serviceMonitor.scrapeTimeout }}
scrapeTimeout: {{ . }}
{{- end }}
{{- with $serviceMonitor.tlsConfig }}
tlsConfig: {{ toYaml . | nindent 8 }}
{{- end }}
{{- with $serviceMonitor.relabelings }}
relabelings: {{ toYaml . | nindent 8 }}
{{- end }}
{{- with $serviceMonitor.metricRelabelings }}
metricRelabelings: {{ toYaml . | nindent 8 }}
{{- end }}
{{- end }}
@@ -0,0 +1,26 @@
{{- $pdb := .Values.podDisruptionBudget }}
{{- if $pdb.enabled }}
{{- $ctx := dict "helm" . }}
{{- $fullname := include "vm.plain.fullname" $ctx }}
{{- $ns := include "vm.namespace" $ctx }}
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: {{ $fullname }}
namespace: {{ $ns }}
{{- $_ := set $ctx "extraLabels" $pdb.labels }}
labels: {{ include "vm.labels" $ctx | nindent 4 }}
{{- $_ := unset $ctx "extraLabels"}}
spec:
{{- with $pdb.minAvailable }}
minAvailable: {{ . }}
{{- end }}
{{- with $pdb.maxUnavailable }}
maxUnavailable: {{ . }}
{{- end }}
{{- with $pdb.unhealthyPodEvictionPolicy }}
unhealthyPodEvictionPolicy: {{ . }}
{{- end }}
selector:
matchLabels: {{ include "vm.selectorLabels" $ctx | nindent 6 }}
{{- end }}
@@ -0,0 +1,43 @@
{{- $app := .Values }}
{{- $route := $app.route }}
{{- if $route.enabled }}
{{- $ctx := dict "helm" . }}
{{- $fullname := include "vm.plain.fullname" $ctx }}
{{- $ns := include "vm.namespace" $ctx }}
---
apiVersion: {{ $route.apiVersion | default "gateway.networking.k8s.io/v1" }}
kind: {{ $route.kind | default "HTTPRoute" }}
metadata:
name: {{ $fullname }}
namespace: {{ $ns }}
{{- $_ := set $ctx "extraLabels" $app.route.extraLabels }}
labels: {{ include "vm.labels" $ctx | nindent 4 }}
{{- $_ := unset $ctx "extraLabels" }}
{{- with $route.annotations }}
annotations: {{ tpl (toYaml .) $ | nindent 4 }}
{{- end }}
spec:
{{- with $route.parentRefs }}
parentRefs: {{ toYaml . | nindent 4 }}
{{- end }}
{{- with $route.hostnames }}
hostnames: {{ tpl (toYaml .) $ | nindent 4 }}
{{- end }}
rules:
{{- with $route.extraRules }}
{{- tpl (toYaml .) $ | nindent 4 }}
{{- end }}
- backendRefs:
- name: {{ $fullname }}
port: {{ $route.port | default (include "vm.port.from.flag" (dict "flag" ($app.extraArgs).httpListenAddr)) }}
group: ''
kind: Service
weight: 1
{{- with $route.filters }}
filters: {{ toYaml . | nindent 8 }}
{{- end }}
{{- with $route.matches }}
matches: {{ tpl (toYaml .) $ | nindent 8 }}
{{- end }}
{{- end }}
@@ -0,0 +1,17 @@
{{- if eq .Values.secretName "" }}
{{- $ctx := dict "helm" . }}
{{- $fullname := include "vm.plain.fullname" $ctx }}
{{- $ns := include "vm.namespace" $ctx }}
apiVersion: v1
kind: Secret
metadata:
name: {{ $fullname }}
namespace: {{ $ns }}
{{- with .Values.configAnnotations }}
annotations: {{- toYaml . | nindent 4 }}
{{- end }}
labels: {{ include "vm.labels" $ctx | nindent 4 }}
type: Opaque
data:
auth.yml: |{{ toYaml .Values.config | b64enc | nindent 4 }}
{{- end }}
@@ -0,0 +1,143 @@
{{- $app := .Values }}
{{- $mode := $app.mode }}
{{- if and $mode (hasKey $app $mode) }}
{{- $modeOpts := index $app $mode }}
{{- $ctx := dict "helm" . }}
{{- $fullname := include "vm.plain.fullname" $ctx }}
{{- $ns := include "vm.namespace" $ctx }}
apiVersion: apps/v1
kind: {{ title $mode }}
metadata:
name: {{ $fullname }}
namespace: {{ $ns }}
{{- $_ := set $ctx "extraLabels" $app.extraLabels }}
labels: {{ include "vm.labels" $ctx | nindent 4 }}
{{- $_ := unset $ctx "extraLabels" }}
{{- with $app.annotations }}
annotations: {{ toYaml . | nindent 4 }}
{{- end }}
spec:
{{- with $modeOpts.spec }}
{{- toYaml . | nindent 2 }}
{{- end }}
{{- if ne $mode "daemonSet" }}
replicas: {{ $app.replicaCount }}
{{- end }}
selector:
matchLabels: {{ include "vm.selectorLabels" . | nindent 6 }}
template:
metadata:
{{- $_ := set $ctx "extraLabels" $app.podLabels }}
labels: {{ include "vm.podLabels" $ctx | nindent 8 }}
{{- $_ := unset $ctx "extraLabels" }}
{{- $annotations := merge (dict "checksum/config" (include (print .Template.BasePath "/secret.yaml") . | sha256sum)) $app.podAnnotations }}
annotations: {{ toYaml $annotations | nindent 8 }}
spec:
{{- with $app.priorityClassName }}
priorityClassName: {{ . }}
{{- end }}
{{- with $app.schedulerName }}
schedulerName: {{ . }}
{{- end }}
{{- if or (.Values.serviceAccount).name (.Values.serviceAccount).create }}
serviceAccountName: {{ tpl ((.Values.serviceAccount).name | default $fullname) $ctx }}
automountServiceAccountToken: {{ .Values.serviceAccount.automountToken }}
{{- end }}
{{- if $app.podSecurityContext.enabled }}
securityContext: {{ include "vm.securityContext" (dict "securityContext" $app.podSecurityContext "helm" .) | nindent 8 }}
{{- end }}
{{- with ($app.imagePullSecrets | default "" (.Values.global).imagePullSecrets) }}
imagePullSecrets: {{ toYaml . | nindent 8 }}
{{- end }}
{{- with $app.initContainers }}
initContainers: {{ toYaml . | nindent 8 }}
{{- end }}
containers:
- name: vmauth
{{- if $app.securityContext.enabled }}
securityContext: {{ include "vm.securityContext" (dict "securityContext" $app.securityContext "helm" .) | nindent 12 }}
{{- end }}
{{- $_ := set $ctx "app" $app }}
image: {{ include "vm.image" $ctx }}
imagePullPolicy: {{ $app.image.pullPolicy }}
{{- if $app.containerWorkingDir }}
workingDir: {{ $app.containerWorkingDir }}
{{- end }}
args: {{ include "vmauth.args" $ctx | nindent 12 }}
{{- with $app.lifecycle }}
lifecycle: {{ . | toYaml | nindent 12 }}
{{- end }}
ports:
- name: http
containerPort: {{ include "vm.port.from.flag" (dict "flag" $app.extraArgs.httpListenAddr "default" "8427") }}
{{- with $app.envFrom }}
envFrom: {{ toYaml . | nindent 12 }}
{{- end }}
{{- with $app.env }}
env: {{ toYaml . | nindent 12 }}
{{- end }}
{{- with (fromYaml (include "vm.probe" (dict "app" $app "type" "readiness"))) }}
readinessProbe: {{ toYaml . | nindent 12 }}
{{- end }}
{{- with (fromYaml (include "vm.probe" (dict "app" $app "type" "liveness"))) }}
livenessProbe: {{ toYaml . | nindent 12 }}
{{- end }}
{{- with (fromYaml (include "vm.probe" (dict "app" $app "type" "startup"))) }}
startupProbe: {{ toYaml . | nindent 12 }}
{{- end }}
volumeMounts:
- name: config
mountPath: /config
{{- range $app.extraHostPathMounts }}
- name: {{ .name }}
mountPath: {{ .mountPath }}
{{- with .subPath }}
subPath: {{ . }}
{{- end }}
{{- with .readOnly }}
readOnly: {{ . }}
{{- end }}
{{- end }}
{{- with $app.extraVolumeMounts }}
{{- toYaml . | nindent 12 }}
{{- end }}
{{- include "vm.license.mount" . | nindent 12 }}
{{- with $app.resources }}
resources: {{ toYaml . | nindent 12 }}
{{- end }}
{{- with $app.extraContainers }}
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with $app.nodeSelector }}
nodeSelector: {{ toYaml . | nindent 8 }}
{{- end }}
{{- with $app.affinity }}
affinity: {{ toYaml . | nindent 8 }}
{{- end }}
{{- with $app.topologySpreadConstraints }}
topologySpreadConstraints:
{{- range $constraint := . }}
- {{ toYaml $constraint | nindent 10 | trim }}
{{- if not $constraint.labelSelector }}
labelSelector:
matchLabels: {{ include "vm.selectorLabels" $ctx | nindent 14 }}
{{- end }}
{{- end }}
{{- end }}
{{- with $app.tolerations }}
tolerations: {{ toYaml . | nindent 8 }}
{{- end }}
volumes:
- name: config
secret:
secretName: {{ ternary $fullname $app.secretName (empty $app.secretName) }}
{{- range $app.extraHostPathMounts }}
- name: {{ .name }}
hostPath:
path: {{ .hostPath }}
{{- end }}
{{- with $app.extraVolumes }}
{{- toYaml . | nindent 8 }}
{{- end }}
{{- include "vm.license.volume" . | nindent 8 }}
{{- end }}
@@ -0,0 +1,55 @@
{{- $service := .Values.service }}
{{- if $service.enabled -}}
{{- $ctx := dict "helm" . }}
{{- $fullname := include "vm.plain.fullname" $ctx }}
{{- $ns := include "vm.namespace" $ctx }}
apiVersion: v1
kind: Service
metadata:
{{- with $service.annotations }}
annotations: {{ toYaml . | nindent 4}}
{{- end }}
{{- $_ := set $ctx "extraLabels" .Values.service.extraLabels }}
labels: {{ include "vm.labels" $ctx | nindent 4 }}
{{- $_ := unset $ctx "extraLabels" }}
name: {{ $fullname }}
namespace: {{ $ns }}
spec:
{{- with $service.trafficDistribution }}
trafficDistribution: {{ . }}
{{- end }}
{{- with $service.clusterIP }}
clusterIP: {{ . }}
{{- end }}
{{- with $service.externalIPs }}
externalIPs: {{ toYaml . | nindent 4 }}
{{- end }}
{{- with $service.loadBalancerIP }}
loadBalancerIP: {{ . }}
{{- end }}
{{- with $service.loadBalancerSourceRanges }}
loadBalancerSourceRanges: {{ toYaml . | nindent 4 }}
{{- end }}
type: {{ $service.type }}
{{- with $service.healthCheckNodePort }}
healthCheckNodePort: {{ . }}
{{- end }}
{{- with $service.externalTrafficPolicy }}
externalTrafficPolicy: {{ . }}
{{- end }}
{{- with $service.ipFamilyPolicy }}
ipFamilyPolicy: {{ . }}
{{- end }}
{{- with $service.ipFamilies }}
ipFamilies: {{ toYaml . | nindent 4 }}
{{- end }}
ports:
- name: http
port: {{ $service.servicePort }}
protocol: TCP
targetPort: http
{{- with $service.nodePort }}
nodePort: {{ . }}
{{- end }}
selector: {{ include "vm.selectorLabels" $ctx | nindent 4 }}
{{- end }}
@@ -0,0 +1,14 @@
{{- if .Values.serviceAccount.create -}}
{{- $ctx := dict "helm" . -}}
{{- $fullname := include "vm.plain.fullname" $ctx }}
{{- $ns := include "vm.namespace" $ctx }}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ tpl ((.Values.serviceAccount).name | default $fullname) $ctx }}
namespace: {{ $ns }}
labels: {{ include "vm.labels" $ctx | nindent 4 }}
{{- with .Values.serviceAccount.annotations }}
annotations: {{ toYaml . | nindent 4 }}
{{- end }}
{{- end -}}
@@ -0,0 +1,389 @@
# Default values for victoria-metrics-auth.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
global:
# -- Image pull secrets, that can be shared across multiple helm charts
imagePullSecrets: []
image:
# -- Image registry, that can be shared across multiple helm charts
registry: ""
# -- Openshift security context compatibility configuration
compatibility:
openshift:
adaptSecurityContext: "auto"
cluster:
# -- K8s cluster domain suffix, uses for building storage pods' FQDN. Details are [here](https://kubernetes.io/docs/tasks/administer-cluster/dns-custom-nameservers/)
dnsDomain: cluster.local.
# -- Number of replicas of vmauth
replicaCount: 1
# -- Name of Priority Class
priorityClassName: ""
image:
# -- Image registry
registry: ""
# -- Victoria Metrics Auth Docker repository and image name
repository: victoriametrics/vmauth
# -- Tag of Docker image
tag: "" # rewrites Chart.AppVersion
# -- Variant of the image to use.
# e.g. enterprise, scratch
variant: ""
# -- Pull policy of Docker image
pullPolicy: IfNotPresent
# -- Image pull secrets
imagePullSecrets: []
# -- Override chart name
nameOverride: ""
# -- Override resources fullname
fullnameOverride: ""
containerWorkingDir: "/"
# -- Specify pod lifecycle
lifecycle: {}
# -- Init containers for vmauth
initContainers:
[]
# - name: example
# image: example-image
serviceAccount:
# -- Specifies whether a service account should be created
create: true
# -- Annotations to add to the service account
annotations: {}
# -- The name of the service account to use. If not set and create is true, a name is generated using the fullname template
name:
# -- See `kubectl explain poddisruptionbudget.spec` for more. Official guide is [here](https://kubernetes.io/docs/tasks/run-application/configure-pdb/)
podDisruptionBudget:
enabled: false
# -- min number or percentage of pods that can be unavailable
minAvailable: 0
# -- max number or percentage of pods that can be unavailable
maxUnavailable: 0
# -- Defines criteria when unhealthy pods should be considered for eviction
unhealthyPodEvictionPolicy:
labels: {}
# -- Extra command line arguments for container of component
extraArgs:
envflag.enable: true
envflag.prefix: VM_
loggerFormat: json
httpListenAddr: :8427
# Enable IPv6 support. Useful for running in IPv6-only Kubernetes clusters
# enableTCP6: true
# -- Additional environment variables (ex.: secret tokens, flags). Check [here](https://docs.victoriametrics.com/victoriametrics/#environment-variables) for details
env: []
# -- Pod topologySpreadConstraints
topologySpreadConstraints: []
# - maxSkew: 1
# topologyKey: topology.kubernetes.io/zone
# whenUnsatisfiable: DoNotSchedule
# -- Specify alternative source for env variables
envFrom: []
#- configMapRef:
# name: special-config
# -- Additional hostPath mounts
extraHostPathMounts: []
# - name: certs-dir
# mountPath: /etc/kubernetes/certs
# subPath: ""
# hostPath: /etc/kubernetes/certs
# readOnly: true
# -- Extra Volumes for the pod
extraVolumes: []
# - name: example
# configMap:
# name: example
# -- Extra Volume Mounts for the container
extraVolumeMounts: []
# - name: example
# mountPath: /example
# -- Extra containers to run in a pod with vmauth
extraContainers:
[]
# - name: config-reloader
# image: reloader-image
# -- Pod's security context. Details are [here](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/)
podSecurityContext:
enabled: true
# fsGroup: 2000
# -- Container security context. Check [here](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) for details.
securityContext:
enabled: true
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
service:
# -- Service traffic distribution. Details are [here](https://kubernetes.io/docs/concepts/services-networking/service/#traffic-distribution)
trafficDistribution: ""
# -- Enable vmauth service
enabled: true
# -- Service annotations
annotations: {}
# -- Service labels
extraLabels: {}
# -- Service ClusterIP
clusterIP: ""
# -- Service external IPs. Check [here](https://kubernetes.io/docs/concepts/services-networking/service/#external-ips) for details
externalIPs: []
# -- Service load balancer IP
loadBalancerIP: ""
# -- Load balancer source range
loadBalancerSourceRanges: []
# -- Service port
servicePort: 8427
# nodePort: 30000
# -- Service type
type: ClusterIP
# -- Service external traffic policy. Check [here](https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip) for details
externalTrafficPolicy: ""
# -- Health check node port for a service. Check [here](https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip) for details
healthCheckNodePort: ""
# -- Service IP family policy. Check [here](https://kubernetes.io/docs/concepts/services-networking/dual-stack/#services) for details.
ipFamilyPolicy: ""
# -- List of service IP families. Check [here](https://kubernetes.io/docs/concepts/services-networking/dual-stack/#services) for details.
ipFamilies: []
route:
# -- Enable deployment of HTTPRoute for VMAuth
enabled: false
# -- HTTPRoute annotations
annotations: {}
# -- HTTPRoute extra labels
extraLabels: {}
# -- HTTPGateway objects refs
parentRefs: []
# -- Array of hostnames
hostnames: []
# -- Extra rules to prepend to route. This is useful when working with annotation based services.
extraRules: []
# -- Filters for a default rule in HTTPRoute
filters: []
# -- Matches for a default rule in HTTPRoute
matches:
- path:
type: PathPrefix
value: /
ingress:
# -- Enable deployment of ingress for vmauth component
enabled: false
# -- Ingress annotations
annotations: {}
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: 'true'
# -- Ingress extra labels
extraLabels: {}
# -- Array of host objects
hosts:
- name: vmauth.local
path:
- /
port: http
# -- Array of TLS objects
tls: []
# - secretName: vmauth-ingress-tls
# hosts:
# - vmauth.local
# -- Ingress controller class name
ingressClassName: ""
# -- Ingress path type
pathType: Prefix
ingressInternal:
# -- Enable deployment of internal ingress for vmauth component
enabled: false
# -- Ingress annotations
annotations: {}
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: 'true'
# -- Ingress extra labels
extraLabels: {}
# -- Array of host objects
hosts:
- name: vmauth.local
path:
- /
port: http
# -- Array of TLS objects
tls: []
# - secretName: vmauth-ingress-tls
# hosts:
# - vmauth.local
# -- Ingress controller class name
ingressClassName: ""
# -- Ingress path type
pathType: Prefix
# -- We usually recommend not to specify default resources and to leave this as a conscious choice for the user. This also increases chances charts run on environments with little resources, such as Minikube. If you do want to specify resources, uncomment the following lines, adjust them as necessary, and remove the curly braces after `resources:`.
resources: {}
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
# -- Annotations to be added to the deployment
annotations: {}
# -- Annotations to be added to pod
podAnnotations: {}
# -- Labels to be added to pod
podLabels: {}
# -- Labels to be added to the deployment
extraLabels: {}
# -- NodeSelector configurations. Check [here](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector) for details
nodeSelector: {}
# -- Tolerations configurations. Check [here](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/) for details
tolerations: []
# - key: "key"
# operator: "Equal|Exists"
# value: "value"
# effect: "NoSchedule|PreferNoSchedule"
# -- Affinity configurations
affinity: {}
# -- vmauth mode: deployment, daemonSet
mode: deployment
# -- [K8s DaemonSet](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/) specific variables
daemonSet:
spec: {}
# -- [K8s Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/) specific variables
deployment:
spec:
strategy:
type: RollingUpdate
serviceMonitor:
# -- Enable deployment of Service Monitor for server component. This is Prometheus operator object
enabled: false
# -- Service Monitor labels
extraLabels: {}
# -- Service Monitor annotations
annotations: {}
# -- Service Monitor relabelings
relabelings: []
# -- Basic auth params for Service Monitor
basicAuth: {}
# -- Service Monitor metricRelabelings
metricRelabelings: []
# interval: 15s
# scrapeTimeout: 5s
# -- Commented. HTTP scheme to use for scraping.
# scheme: https
# -- Commented. TLS configuration to use when scraping the endpoint
# tlsConfig:
# insecureSkipVerify: true
# -- Use existing secret if specified otherwise .config values will be used. Check [here](https://docs.victoriametrics.com/victoriametrics/vmauth/) for details.
# Configuration in the given secret must be stored under `auth.yml` key.
secretName: ""
# -- Config file content.
config:
# Arbitrary number of usernames may be put here.
# Usernames must be unique.
# users:
# The user for querying local single-node VictoriaMetrics.
# All the requests to http://vmauth:8427 with the given Basic Auth (username:password)
# will be routed to http://localhost:8428 .
# For example, http://vmauth:8427/api/v1/query is routed to http://localhost:8428/api/v1/query
# - username: "local-single-node"
# password: "***"
# url_prefix: "http://localhost:8428"
# The user for querying account 123 in VictoriaMetrics cluster
# See https://github.com/VictoriaMetrics/VictoriaMetrics/blob/cluster/README.md#url-format
# All the requests to http://vmauth:8427 with the given Basic Auth (username:password)
# will be routed to http://vmselect:8481/select/123/prometheus .
# For example, http://vmauth:8427/api/v1/query is routed to http://vmselect:8481/select/123/prometheus/api/v1/select
# - username: "cluster-select-account-123"
# password: "***"
# url_prefix: "http://vmselect:8481/select/123/prometheus"
# The user for inserting Prometheus data into VictoriaMetrics cluster under account 42
# See https://github.com/VictoriaMetrics/VictoriaMetrics/blob/cluster/README.md#url-format
# All the requests to http://vmauth:8427 with the given Basic Auth (username:password)
# will be routed to http://vminsert:8480/insert/42/prometheus .
# For example, http://vmauth:8427/api/v1/write is routed to http://vminsert:8480/insert/42/prometheus/api/v1/write
# - username: "cluster-insert-account-42"
# password: "***"
# url_prefix: "http://vminsert:8480/insert/42/prometheus"
# -- Annotations for config secret
configAnnotations: {}
# -- Add extra specs dynamically to this chart
extraObjects: []
probe:
# -- Readiness probe
readiness:
tcpSocket: {}
initialDelaySeconds: 5
periodSeconds: 15
# -- Liveness probe
liveness:
tcpSocket: {}
initialDelaySeconds: 5
periodSeconds: 15
timeoutSeconds: 5
# -- Startup probe
startup: {}
# -- Enterprise license key configuration for VictoriaMetrics enterprise.
# Required only for VictoriaMetrics enterprise. Check docs [here](https://docs.victoriametrics.com/victoriametrics/enterprise/),
# for more information, visit [site](https://victoriametrics.com/products/enterprise/).
# Request a trial license [here](https://victoriametrics.com/products/enterprise/trial/)
# Supported starting from VictoriaMetrics v1.94.0
license:
# -- License key
key: ""
# -- Use existing secret with license key
secret:
# -- Existing secret name
name: ""
# -- Key in secret with license key
key: ""