added repo

This commit is contained in:
Your Name
2026-08-26 03:39:42 +05:30
parent 45c25a95af
commit b8575bb8b9
6889 changed files with 1217125 additions and 0 deletions
+106
View File
@@ -0,0 +1,106 @@
# CLAUDE.md — `devops-infra-helm-charts`
# Auto-generated by /meesho-init. Edit freely — re-running suggests improvements, not overwrites.
> Agent entry point for Meesho's infrastructure Helm values + cached/forked charts repo.
>
> **Repo role:** GitOps source-of-truth for *what* infrastructure tooling runs on Meesho's GKE fleet, *where*, and *with what values*. Sister repo `devops-infra-argo-config` is the routing layer — it holds the Argo CD `Application` / `ApplicationSet` manifests that point at paths in this repo. A merge to `main` is a deploy event: Argo CD on each cluster reconciles from `main`.
>
> **Layer:** **Layer 1 — Agent-Writable** (config repo). Generate diffs, open PRs, do **not** apply directly. The default safety property is reviewer discipline + the Argo CD Sync click on each cluster. The longer-term goal is tool-mediated edits via a `helm-values-tool`; until that exists, direct edits to `helm-overrides/<cluster>/<app>/custom-values.yaml` via PR are the supported path. Direct edits to `helm-templates/<chart>/` are gated — see NEVER DO.
>
> **Out of scope:** application/service code (lives in service repos), Argo CD Application manifests (sister repo `devops-infra-argo-config`), workload-cluster `kubectl apply` operations (incident response, not authoring).
>
> See [docs/architecture.md](docs/architecture.md) for the full deploy lifecycle, cluster fleet, chart inventory, hook details, and gotchas.
## NEVER DO
- **NEVER** commit or push directly to `main`. Always work on a feature/fix branch and open a PR. A merge to `main` triggers Argo CD reconciliation against the live fleet.
- **NEVER** force push (`git push --force`). If absolutely required, use `--force-with-lease`.
- **NEVER** make requests to, curl, query, or interact with production endpoints: `int.meesho.int`, `prd.meesho.int`, `int.mrouter.int`, `prd.mrouter.int`, `*.meeshogcp.in`. These are production/pre-prod systems — any accidental call can affect live traffic or data.
- **NEVER** introduce backward-incompatible changes to chart `values.yaml` keys, image tags pinned in overrides, or `fullnameOverride` strings without explicit user approval. Argo CD will silently reconcile the change across every cluster that consumes the chart, and live releases (Service DNS, PVC binding) depend on the existing names.
- **NEVER** commit secrets in any form. The TruffleHog pre-commit hook is the last line of defense — **NEVER bypass it** with `--no-verify`, `git commit -n`, or by removing the hook. Real secrets belong in `external-secrets` (per-cluster) backed by GCP Secret Manager / Vault, not in `custom-values.yaml`.
- **NEVER** copy a `custom-values.yaml` from one cluster directory to another without rewriting `nodeSelector`, `tolerations`, and any `computeClass` references. Each cluster has a bespoke node-pool topology — see `contour-nodeselector-tolerations-summary.md`. GKE Autopilot clusters (`k8s-central-prd-ase1`, `k8s-dsgpu-prd-ase1`, `k8s-shared-int-ase1`) use `cloud.google.com/compute-class:` keys; standard clusters use `dedicated:` keys. Wrong values strand pods on wrong nodes or leave them pending.
- **NEVER** edit files under `helm-templates/<chart>/templates/` or `values.yaml` casually. Most are vanilla upstream charts pulled via `helm pull`. Edits silently fork the chart and get clobbered on the next upstream sync. If a fork is intentional, document the reason in that chart's `README.md` and call it out in the PR.
- **NEVER** delete a `<chart>` / `<chart>-<variant>` sibling without confirming no Argo Application in `devops-infra-argo-config` still references it. Versioned siblings (`argo-cd-green`, `contour-v1.33.3`, `keda-2.17.1`, `opentelemetry-collector-latest`, `sonarqube-old`, `victoria-metrics-cluster-latest`, etc.) exist to support in-flight blue-green migrations — both versions may be live simultaneously.
- **NEVER** edit `manifests/storageclass/*.yaml` or `manifests/priorityclass/<cluster>/*.yaml` without a PR-level reviewer. These are cluster-wide singletons — a wrong StorageClass affects every PVC; a wrong PriorityClass changes scheduling priority for every pod that references it.
- **NEVER** bump a `Chart.yaml` `dependencies[].version` without (a) reading the upstream changelog for breaking template changes, (b) re-running `helm dependency update` to refresh `Chart.lock`, and (c) calling out the bump in the PR description.
- **NEVER** "normalize" values across clusters in the same PR as a feature change. Surgical edits only — touch the cluster × application that was asked, leave the rest. Cross-cluster cleanups belong in their own PR.
- **NEVER** change `fullnameOverride` values in any `custom-values.yaml`. They are load-bearing — Service DNS names, PVC bindings, ConfigMap references, and Argo Application names downstream depend on them being stable.
- **NEVER** treat Argo CD `Application` / `ApplicationSet` manifests as part of this repo. They live in the sister repo `github.com/Meesho/devops-infra-argo-config`. Changes to routing, sync policies, or Application paths are PRs against that repo, not this one.
## Repo at a glance
GitOps Helm values + cached/forked charts for Meesho's GKE infra fleet. Sister repo `devops-infra-argo-config` holds the Argo `Application` / `ApplicationSet` manifests that point at paths in this repo. **A merge to `main` is a deploy** — Argo CD on each cluster reconciles from `main`.
> See [docs/architecture.md](docs/architecture.md) for the full deploy lifecycle, cluster fleet, chart inventory, hook details, and gotchas.
## Repository layout
| Path | Purpose |
|------|---------|
| `helm-templates/<chart>/` | 74 cached/forked upstream charts (Argo CD, Contour, VictoriaMetrics, Grafana, Mimir, Loki, Tempo, Vault, Keda, Kyverno, Jenkins, JFrog, etc.). Some are thin wrappers (deps in `Chart.yaml`); some carry full vendored `templates/`. |
| `helm-overrides/<cluster>/<app>/custom-values.yaml` | Cluster × application Helm values overrides. Edited daily. |
| `helm-overrides/<cluster>/<app>/<extra>.yaml` | Raw manifests applied alongside the Helm release (e.g., `computeclass/*-cc.yaml`, `elastic-cluster/argo-launch.yaml`, `external-dns-services/*.yaml`). |
| `manifests/storageclass/`, `manifests/priorityclass/<cluster>/` | Cluster-wide singletons. High blast radius. |
| `manifests/{jenkins-filestore-caching,jenkins-gcs-caching,jfrog-filestore-data}/{dev,prd}/` | Per-env one-shot PV/PVC manifests. |
| `pre-commit-scripts/` | TruffleHog secret scan (active); CAC and Yaak hooks (no-op here, gated on paths this repo doesn't have). |
| `post-commit-scripts/` | Cursor AI commit metric collector (background, non-blocking). |
| `repository.yaml` | Owners (auto-managed). Primary: `siddharth.pal@meesho.com`. Secondary: `samarth.nag@meesho.com`. |
| `contour-nodeselector-tolerations-summary.md` | Per-cluster Contour scheduling matrix. **Read before editing any Contour values.** |
## Cluster naming
| Pattern | Meaning |
|---------|---------|
| `k8s-<bu>-prd-ase1[c]` | Standard GKE prod cluster, BU-owned. BUs: `central`, `central-mqkafka`, `supply`, `supply-dev`, `demand`, `dataengg`, `datascience`, `dengspark`, `dengspark-di`, `dengspark-notebook`, `dscispark`, `dsgpu`, `farmiso`, `ml-platform`, `admin`, `sec-admin`, `devops-admin`. All in `asia-southeast1`, fleet `meesho-admin-prd-0622`. |
| `k8s-shared-int-ase1` | Shared **integration** (pre-prod) cluster. Only non-prod cluster in the repo. |
| `k8s-aurva-prd-ase1` | Aurva integration. Minimal override set. |
| `db-<numeric-id>-...` | Auto-named dataplane/data-tier clusters. Minimal overrides (`kube-state-metrics`, `victoria-metrics-agent`). Use `fullnameOverride: <kind>-dbc-<bu>-prd`. |
## Editing workflow
1. Branch off `main`. Don't push to `main`.
2. Edit the **single** `helm-overrides/<cluster>/<app>/custom-values.yaml` (or `<app>/<extra>.yaml`) the task targets. Don't drive-by-edit other apps in the same dir.
3. If the change is per-cluster, mirror **only** if the user asked — and rewrite per-cluster scheduling fields (see NEVER DO).
4. `git commit` — TruffleHog runs automatically. If it blocks, fix the secret (don't bypass).
5. Open a PR. Reviewer checks blast radius. Merge to `main`.
6. Argo CD on the target cluster syncs (auto or manual sync, per the Application's `syncPolicy` in `devops-infra-argo-config`).
## Common patterns
- **Multi-Contour clusters** — `contour-external`, `contour-external-1`, `contour-internal-0`, `contour-internal-1`, `contour-internal-intra-{0,1}` are all separate Helm releases per cluster. Each has its own node pool / dedicated taint or compute class. Cross-reference `contour-nodeselector-tolerations-summary.md`.
- **Versioned chart siblings** — `argo-cd``argo-cd-green`, `contour``contour-v1.33.3`, `keda``keda-2.17.1`, `opentelemetry-collector``-latest`, `victoria-metrics-{cluster,agent}``-latest`, `sonarqube``sonarqube-old`. The variant is the upgrade target. Both can be live at once.
- **Image registry** — production overrides pin `asia-southeast1-docker.pkg.dev/meesho-devops-admin-0622/admin/sre/<image>` (Meesho's Artifact Registry mirror), not Docker Hub.
- **Secrets via External Secrets Operator** — most clusters have an `external-secrets/` override; secrets are sourced from GCP Secret Manager / Vault. Reference secret names; never paste secret values.
## Quick reference
This repo has no build, test, or lint commands. Everything is declarative YAML. Useful local commands:
| Task | Command |
|------|---------|
| Install pre-commit hooks (one-time) | `pre-commit install --hook-type pre-commit --hook-type pre-push --hook-type post-commit` |
| Re-run pre-commit on staged changes | `pre-commit run` |
| Render a chart locally to inspect output | `helm template <release> helm-templates/<chart> -f helm-overrides/<cluster>/<app>/custom-values.yaml` |
| Refresh subchart deps after `Chart.yaml` bump | `helm dependency update helm-templates/<chart>` |
| Diff a release against the rendered template | `helm diff upgrade <release> helm-templates/<chart> -f helm-overrides/<cluster>/<app>/custom-values.yaml` (requires `helm-diff` plugin and kube context) |
| Lint a chart | `helm lint helm-templates/<chart>` |
| Find which clusters override a given app | `find helm-overrides -maxdepth 2 -type d -name '<app>'` |
## Layer constraint summary
| Operation | Layer | Agent action |
|-----------|-------|--------------|
| Edit `helm-overrides/<cluster>/<app>/custom-values.yaml` (single cluster × app) | **Layer 1** | Generate the diff, open a PR. Reviewer + Argo CD Sync click are the safety gates. |
| Add a new app override under an existing cluster | **Layer 1** | Same — pair with the matching `Application` PR in `devops-infra-argo-config`. |
| Add a new cluster directory under `helm-overrides/` | **Layer 1 (HIGH RISK)** | Open a PR; pair with the cluster's `ApplicationSet` change in the sister repo. Verify per-cluster `nodeSelector` / `tolerations` / `computeClass` are written from scratch, not copied. |
| Bump a `Chart.yaml` `dependencies[].version` in `helm-templates/<chart>/` | **Layer 1 (HIGH RISK)** | Read upstream changelog, run `helm dependency update`, refresh `Chart.lock`, call out the bump in the PR. |
| Edit `helm-templates/<chart>/templates/` or `values.yaml` | **Layer 1 (HIGH RISK)** | Most charts are vanilla upstream; an edit silently forks the chart and gets clobbered on the next sync. Only allowed if the fork is intentional and documented in that chart's `README.md`. |
| Delete a versioned sibling chart (`<chart>-green`, `-vX.Y.Z`, `-latest`, `-old`) | **Layer 1 (HIGH RISK)** | Confirm no Argo Application in `devops-infra-argo-config` still references it. |
| Edit `manifests/storageclass/*.yaml` or `manifests/priorityclass/<cluster>/*.yaml` | **Layer 1 (HIGH RISK)** | Cluster-wide singleton; affects every PVC / scheduling priority. Requires platform-team review. |
| Run `helm install` / `helm upgrade` against a live cluster | **Out of scope** | This is GitOps; in-cluster mutation is incident response, not authoring. Use Argo CD UI Sync. |
| Run `kubectl apply -f` against a workload cluster | **Out of scope** | Drift will reappear on next reconciliation. |
| Hand-edit `repository.yaml` | **Layer 3** | Owned by `registry-bootstrap` automation. Refuse + redirect upstream. |
| Edit Argo `Application` / `ApplicationSet` manifests | **Out of scope (sister repo)** | These live in `github.com/Meesho/devops-infra-argo-config`. Open the PR there. |
| Recommend a curl/probe against `int.meesho.int`, `prd.meesho.int`, `*.mrouter.int`, or workload `*.meeshogcp.in` services | **Layer 3** | Production traffic surfaces — refuse. (Pre-commit hook telemetry to `observe.meeshogcp.in` is automated infrastructure, not agent-initiated.) |
<!-- meesho-init: generated-at=2026-05-05T17:31:45Z base-sha=debd20fcc510e19bfe3123a08247dde39790643b+dirty -->
+25
View File
@@ -1,2 +1,27 @@
# devops-infra-helm-charts # devops-infra-helm-charts
This branch (`main`) is part of the restructuring process for the `gcp-devops-admin` repository, aimed at organizing helmcharts of all infrastructure tools and their corresponding value files. The purpose of this repository is to centralize and manage these resources efficiently.
## Directory Structure
### helm-templates
This directory is intended for caching or forking helm charts locally. If there's a need to modify or customize any helm chart, it can be done here. Otherwise, the charts will be used directly from the provider.
### helm-overrides
The `helm-overrides` folder stores custom values files for helm charts. These files can be used to override the default values provided by the helm charts, whether they are forked or used directly from the provider.
### cluster_name
Each tool within the repository may have different values based on the specific clusters. This directory is used to manage configurations and values tailored to different clusters.
### manifests
The `manifests` directory contains manifest files that need to be applied only once. Examples include service-to-service configurations, storage classes, and any other manifest-related files necessary for the operation of the infrastructure tools.
## Additional Notes
Please ensure that all changes made to this branch align with the restructuring objectives and follow the best practices for managing helm charts and infrastructure-related configurations.
For any questions or concerns, please reach out to the designated repository maintainers.
+63
View File
@@ -0,0 +1,63 @@
> Per AI Blitz Plan §claude. Layer: 1. Repo: devops-infra-helm-charts.
# 00 — Overview
## Why this repo exists
`devops-infra-helm-charts` is the GitOps source-of-truth for **what infrastructure tooling runs on Meesho's GKE fleet, where, and with what values**. It is one of two repos that together compose the platform's deploy plane:
- **This repo** — values + cached/forked charts. Answers "what does cluster X's Argo CD agent stack look like?"
- **Sister repo** — [`Meesho/devops-infra-argo-config`](https://github.com/Meesho/devops-infra-argo-config) — Argo `Application` / `ApplicationSet` manifests. Answers "which cluster pulls which path from the values repo, with what sync policy?"
A merge to `main` here is a **deploy event**: every Argo CD instance whose Application points at a touched path will reconcile, on its own cadence (auto-sync) or on a human Sync click (manual-sync — the prod default).
See [`../wiki/entities/DevOps Infra Helm Charts.md`](../wiki/entities/DevOps%20Infra%20Helm%20Charts.md) for the conceptual model and [`../docs/architecture.md`](../docs/architecture.md) for the full deploy lifecycle.
## What's in it
| Top-level | Role |
|-----------|------|
| `helm-templates/<chart>/` | 74 cached or forked upstream charts (Argo CD, Contour, VictoriaMetrics, Mimir, Loki, Tempo, Vault, Keda, Kyverno, Jenkins, JFrog, Grafana…). |
| `helm-overrides/<cluster>/<app>/custom-values.yaml` | Per-cluster × per-app Helm values. Edited daily. |
| `helm-overrides/<cluster>/<app>/<extra>.yaml` | Raw manifests applied alongside the Helm release (compute-class definitions, external-DNS records, etc.). |
| `manifests/storageclass/`, `manifests/priorityclass/<cluster>/` | Cluster-wide singletons. High blast radius. |
| `manifests/{jenkins,jfrog}-…/{dev,prd}/` | Per-env one-shot PV/PVC manifests. |
| `pre-commit-scripts/` | TruffleHog (active, blocking); CAC + Yaak (no-op here). |
| `post-commit-scripts/` | Cursor AI commit metric collector (background). |
| `repository.yaml` | Owners, auto-managed by `registry-bootstrap`. |
| `contour-nodeselector-tolerations-summary.md` | Per-cluster Contour scheduling matrix. |
Detailed walkthrough in [`./01-repo-structure.md`](./01-repo-structure.md).
## What's NOT in it
- Argo CD `Application` / `ApplicationSet` manifests — those live in the **sister repo**. See [`../docs/global/coding-guidelines/argocd.md`](../docs/global/coding-guidelines/argocd.md).
- Application / service code — lives in service repos.
- Workload-cluster `kubectl apply` operations — that's incident response, not authoring.
- Production endpoint probes (`*.meesho.int`, `*.mrouter.int`, `*.meeshogcp.in`) — never call from an agent. See [`../docs/global/SANCTITY_RULES.md`](../docs/global/SANCTITY_RULES.md).
## How a change reaches a cluster
1. Branch off `main`.
2. Edit a single `helm-overrides/<cluster>/<app>/custom-values.yaml`.
3. Local dry-run: `helm template <release> helm-templates/<chart> -f helm-overrides/<cluster>/<app>/custom-values.yaml`.
4. Commit — TruffleHog runs (blocking). Never `--no-verify`.
5. Open a PR. Reviewer is the first safety gate.
6. Merge to `main`.
7. Argo CD on the target cluster either auto-reconciles (low-risk leaves) or waits for a human Sync click (prod infra default).
That click is the **second** safety gate. The combined property (reviewer + Sync) is the system's safety floor while a tool-mediated edit path (`helm-values-tool`) is still being built.
See [`./05-deploy-lifecycle.md`](./05-deploy-lifecycle.md) for the full flow with failure modes, and [`./08-pre-commit-and-hooks.md`](./08-pre-commit-and-hooks.md) for the hook details.
## Layer classification
This repo is **Layer 1 — Agent-Writable** (config repo). Most edits are agent-eligible via PR. Several operations are Layer 1 *high-risk* or Layer 3 (refuse). The full mapping is in the root `CLAUDE.md` *Layer constraint summary* table; the agent-facing summary is [`../docs/global/AGENT_BOUNDARIES.md`](../docs/global/AGENT_BOUNDARIES.md) and [`../docs/global/SANCTITY_RULES.md`](../docs/global/SANCTITY_RULES.md).
## Where to go next
- New to the repo: read [`./01-repo-structure.md`](./01-repo-structure.md) → [`./02-cluster-fleet.md`](./02-cluster-fleet.md) → [`./05-deploy-lifecycle.md`](./05-deploy-lifecycle.md).
- About to edit values: [`./04-override-hierarchy.md`](./04-override-hierarchy.md) and [`../docs/global/coding-guidelines/helm-values.md`](../docs/global/coding-guidelines/helm-values.md).
- About to bump a chart: [`../docs/platform/procedures/update-chart-version.md`](../docs/platform/procedures/update-chart-version.md).
- About to onboard an app: [`../skills/infra/onboard-app.md`](../skills/infra/onboard-app.md) and [`../docs/platform/procedures/onboard-app-to-cluster.md`](../docs/platform/procedures/onboard-app-to-cluster.md).
- Glossary: [`./10-glossary-and-references.md`](./10-glossary-and-references.md).
+70
View File
@@ -0,0 +1,70 @@
> Per AI Blitz Plan §claude. Layer: 1. Repo: devops-infra-helm-charts.
# 01 — Repository structure
Directory walkthrough with the *why* attached. The root `CLAUDE.md` *Repository layout* table is the canonical short version; this page extends it with rationale and links into the rest of the tree.
## `helm-templates/<chart>/` — cached / forked upstream charts
About 74 chart directories. Three flavours:
1. **Vanilla upstream cache** — pulled via `helm pull <repo>/<chart>` and committed verbatim. Edits to `templates/` here silently fork the chart and get clobbered on the next refresh. Most charts are this flavour. See [`../wiki/analyses/ADR-A1-cache-vs-upstream-charts.md`](../wiki/analyses/ADR-A1-cache-vs-upstream-charts.md).
2. **Thin wrapper**`Chart.yaml` declares `dependencies:`, `templates/` is small or empty, and the real content lives in the subchart. Used to bind multiple sub-charts as one Argo Application.
3. **Intentional fork**`templates/` is meaningfully edited. Each fork should explain itself in that chart's `README.md`. Forks are rare and need explicit owner approval. See [`../docs/platform/procedures/fork-upstream-chart.md`](../docs/platform/procedures/fork-upstream-chart.md).
Why cache at all? Network/ingress robustness for Argo CD on every cluster, and a stable target for the values to bind against. Trade-off and alternatives in [`../wiki/analyses/ADR-A1-cache-vs-upstream-charts.md`](../wiki/analyses/ADR-A1-cache-vs-upstream-charts.md).
## `helm-overrides/<cluster>/<app>/custom-values.yaml`
The day-to-day editing surface. Path encodes the destination:
- `<cluster>` → directory name matches the GKE cluster name (`k8s-central-prd-ase1`, `k8s-shared-int-ase1`, `k8s-aurva-prd-ase1`, `db-<id>-…`).
- `<app>` → directory name matches the Argo Application name in the sister repo (and usually matches the chart name in `helm-templates/`, but doesn't have to — many apps target a versioned-sibling chart).
The content is a Helm values overlay merged onto `helm-templates/<chart>/values.yaml` at render time. Schema: [`../docs/platform/schemas/custom-values-schema.md`](../docs/platform/schemas/custom-values-schema.md). Composition rules: [`./04-override-hierarchy.md`](./04-override-hierarchy.md).
## `helm-overrides/<cluster>/<app>/<extra>.yaml`
Raw Kubernetes manifests dropped alongside the Helm release. They are NOT consumed by Helm — Argo applies them directly. Common patterns:
- `computeclass/*-cc.yaml` — GKE Autopilot `ComputeClass` objects.
- `elastic-cluster/argo-launch.yaml` — Elasticsearch Operator CR.
- `external-dns-services/*.yaml``Service` objects with `external-dns` annotations to publish DNS records.
Schema and conventions: [`../docs/platform/schemas/raw-manifest-sidecar-schema.md`](../docs/platform/schemas/raw-manifest-sidecar-schema.md). Why they live here rather than in dedicated manifest dirs: [`../wiki/analyses/ADR-A4-raw-manifest-sidecars-in-helm-overrides.md`](../wiki/analyses/ADR-A4-raw-manifest-sidecars-in-helm-overrides.md).
## `manifests/storageclass/` and `manifests/priorityclass/<cluster>/`
Cluster-wide singletons. A wrong StorageClass affects every PVC; a wrong PriorityClass changes scheduling priority for every pod that references it. Two-reviewer policy. Schema: [`../docs/platform/schemas/storageclass-priorityclass-schema.md`](../docs/platform/schemas/storageclass-priorityclass-schema.md). Blast-radius detail: [`./07-singletons-and-blast-radius.md`](./07-singletons-and-blast-radius.md).
## `manifests/{jenkins-filestore-caching,jenkins-gcs-caching,jfrog-filestore-data}/{dev,prd}/`
Per-env one-shot PV / PVC manifests for stateful systems that pre-date a Helm-managed model. Treated as immutable once bound; resize via PVC `resources.requests.storage` rather than re-creating.
## `pre-commit-scripts/`
- **TruffleHog secret scan** — active, blocking. NEVER bypass. See [`./08-pre-commit-and-hooks.md`](./08-pre-commit-and-hooks.md) and [`../docs/global/SANCTITY_RULES.md`](../docs/global/SANCTITY_RULES.md).
- **CAC, Yaak hooks** — gated on file paths this repo doesn't have, so they no-op here. Same scripts run for real in service repos.
## `post-commit-scripts/`
- **Cursor AI commit metric collector** — background, non-blocking. Posts metric pings to `observe.meeshogcp.in`. This is platform-managed infrastructure, not agent-initiated.
## `repository.yaml`
Owners + secondary owners. Managed by the `registry-bootstrap` automation. Editing by hand is on the don't-touch list — see [`../docs/global/escalation-matrix.md`](../docs/global/escalation-matrix.md) row 4.
## `contour-nodeselector-tolerations-summary.md`
Per-cluster Contour scheduling matrix at the repo root. **Read this before any Contour values edit.** Multi-Contour pattern (`contour-external`, `contour-external-1`, `contour-internal-{0,1}`, `contour-internal-intra-{0,1}`) is detailed in [`./03-chart-inventory.md`](./03-chart-inventory.md).
## `docs/`, `claude/`, `skills/`, `wiki/`
The Blitz documentation tree. Entry points:
- [`../docs/architecture.md`](../docs/architecture.md) — full deploy lifecycle and gotchas.
- [`../docs/global/`](../docs/global/) — agent boundaries, sanctity rules, escalation, coding guidelines.
- [`../docs/platform/`](../docs/platform/) — procedures, runbooks, schemas.
- [`../skills/infra/`](../skills/infra/) — task playbooks.
- [`../wiki/`](../wiki/) — entity model and ADRs.
- [`./00-overview.md`](./00-overview.md) — top of this `claude/` index.
+80
View File
@@ -0,0 +1,80 @@
> Per AI Blitz Plan §claude. Layer: 1. Repo: devops-infra-helm-charts.
# 02 — Cluster fleet
The repo's cluster directories under `helm-overrides/<cluster>/` are the canonical list of clusters this platform serves. Naming follows three patterns; each implies a different scheduling primitive set, which is why **schedule fields are never copy-pasted between clusters** (see [`../docs/global/SANCTITY_RULES.md`](../docs/global/SANCTITY_RULES.md)).
## Naming taxonomy
### `k8s-<bu>-prd-ase1[c]`
Standard GKE prod cluster, BU-owned. All in `asia-southeast1`, fleet `meesho-admin-prd-0622`. Trailing `c` denotes a secondary cluster for the same BU.
Known BUs in this repo:
- `central`, `central-mqkafka`
- `supply`, `supply-dev`
- `demand`
- `dataengg`, `datascience`, `dengspark`, `dengspark-di`, `dengspark-notebook`, `dscispark`
- `dsgpu`
- `farmiso`
- `ml-platform`
- `admin`, `sec-admin`, `devops-admin`
A few of these are GKE **Autopilot** clusters (different scheduling primitives — see below):
- `k8s-central-prd-ase1`
- `k8s-dsgpu-prd-ase1`
- `k8s-shared-int-ase1`
The rest are **standard** GKE.
### `k8s-shared-int-ase1`
Shared **integration** (pre-prod) cluster — the only non-prod cluster in the repo. Used for integration testing of platform changes before they hit any prod cluster. Autopilot.
### `k8s-aurva-prd-ase1`
Aurva integration (third-party security tooling). Minimal override set.
### `db-<numeric-id>-...`
Auto-named dataplane / data-tier clusters. Each carries a minimal override set, typically `kube-state-metrics` and `victoria-metrics-agent` only. The `fullnameOverride` convention here is `<kind>-dbc-<bu>-prd` so that metrics labels stay legible across the data-tier fleet.
## Autopilot vs standard scheduling
This is the dominant reason scheduling fields cannot be copy-pasted across clusters.
### Standard GKE clusters
Use:
- `nodeSelector.dedicated: <pool-tag>`
- `tolerations[].key: dedicated`
- Node pools are explicitly provisioned per workload class.
### Autopilot clusters
Use:
- `nodeSelector."cloud.google.com/compute-class": <ComputeClass-name>`
- `tolerations[].key: cloud.google.com/compute-class` (when applicable)
- A `ComputeClass` raw manifest is dropped at `helm-overrides/<cluster>/<app>/computeclass/*-cc.yaml` to declare the class. See [`../docs/platform/schemas/raw-manifest-sidecar-schema.md`](../docs/platform/schemas/raw-manifest-sidecar-schema.md).
Mismatched fields → pods strand on the wrong nodes or stay `Pending`. Diagnosis flow: [`../docs/platform/runbooks/pod-pending-scheduling.md`](../docs/platform/runbooks/pod-pending-scheduling.md). Background: [`../wiki/analyses/ADR-A3-per-cluster-scheduling.md`](../wiki/analyses/ADR-A3-per-cluster-scheduling.md).
## Multi-Contour scheduling
Multi-Contour clusters run `contour-external`, `contour-external-1`, `contour-internal-0`, `contour-internal-1`, `contour-internal-intra-0`, `contour-internal-intra-1` — each a separate Helm release pinned to its own node pool / dedicated taint or compute class. The per-cluster matrix (which Contour goes where) is documented in the repo-root `contour-nodeselector-tolerations-summary.md`. **Always cross-reference that file before touching a Contour values override.**
## Cluster onboarding
Adding a new cluster directory is Layer-1 *high-risk*. The procedure (paired PR with the sister repo's `ApplicationSet`) is in [`../docs/platform/procedures/onboard-new-cluster.md`](../docs/platform/procedures/onboard-new-cluster.md).
## Cluster deboarding
Removing a cluster is rare and requires draining Argo Applications first. There is no in-repo procedure today; escalate to the primary owner — see [`../docs/global/escalation-matrix.md`](../docs/global/escalation-matrix.md).
## See also
- [`./03-chart-inventory.md`](./03-chart-inventory.md) — versioned siblings + multi-Contour pattern
- [`./04-override-hierarchy.md`](./04-override-hierarchy.md) — how cluster + chart compose
- [`./07-singletons-and-blast-radius.md`](./07-singletons-and-blast-radius.md) — `manifests/priorityclass/<cluster>/`
- [`../contour-nodeselector-tolerations-summary.md`](../contour-nodeselector-tolerations-summary.md)
+82
View File
@@ -0,0 +1,82 @@
> Per AI Blitz Plan §claude. Layer: 1. Repo: devops-infra-helm-charts.
# 03 — Chart inventory
`helm-templates/` carries about 74 chart directories. They fall into three categories by structure and one cross-cutting category by lifecycle.
## By structure
### 1. Vanilla upstream cache
Most charts are pulled verbatim via `helm pull <repo>/<chart>` and committed. The `templates/` are *not* edited. Editing them silently forks the chart and the edits get clobbered the next time someone refreshes the cache. The pre-commit hooks do not catch this — only PR review does.
If a fork is intentional, it must be documented in the chart's `README.md` and called out in the PR. See [`../docs/platform/procedures/fork-upstream-chart.md`](../docs/platform/procedures/fork-upstream-chart.md).
Background: [`../wiki/analyses/ADR-A1-cache-vs-upstream-charts.md`](../wiki/analyses/ADR-A1-cache-vs-upstream-charts.md).
### 2. Thin wrapper
`Chart.yaml` declares `dependencies:` pointing at one or more upstream charts. The local `templates/` is empty or carries only a thin glue manifest. Used so a single Argo Application can install a stack (e.g., kube-prometheus-stack carries Prometheus + Alertmanager + Grafana + node-exporter + kube-state-metrics together).
When bumping a wrapper, refresh `Chart.lock` with `helm dependency update helm-templates/<chart>`. See [`../docs/platform/procedures/update-chart-version.md`](../docs/platform/procedures/update-chart-version.md).
### 3. Intentional fork
A small number of charts have deliberate `templates/` edits — local CRD patches, label injection, removed sub-resources we don't want, etc. Each fork should be self-documenting in its `README.md`. If the rationale is missing, treat the fork as suspect and escalate per [`../docs/global/escalation-matrix.md`](../docs/global/escalation-matrix.md).
## By lifecycle — versioned siblings
A chart family often has two siblings live simultaneously to support blue-green migrations:
| Stable | Migration target | Used for |
|--------|------------------|----------|
| `argo-cd` | `argo-cd-green` | Green-deploy of the Argo CD control plane itself |
| `contour` | `contour-v1.33.3` | Pinned-version migration of the ingress data plane |
| `keda` | `keda-2.17.1` | Autoscaler version cutover |
| `opentelemetry-collector` | `opentelemetry-collector-latest` | OTel collector cutover |
| `victoria-metrics-cluster` | `victoria-metrics-cluster-latest` | VM cluster cutover |
| `victoria-metrics-agent` | `victoria-metrics-agent-latest` | VM agent cutover |
| `sonarqube` | (was forward; `sonarqube-old` retained) | SonarQube major cutover |
The `-green` / `-vX.Y.Z` / `-latest` / `-old` suffix names the **migration target** (or in `-old`'s case, the kept-around predecessor). Both can be live at once on different clusters or even on the same cluster (different Argo Applications). Deletion of a sibling requires confirming zero references in the sister repo. See [`../wiki/analyses/ADR-A2-blue-green-sibling-pattern.md`](../wiki/analyses/ADR-A2-blue-green-sibling-pattern.md) and [`../docs/platform/procedures/blue-green-chart-migration.md`](../docs/platform/procedures/blue-green-chart-migration.md).
## Multi-Contour pattern
Contour is unique in that a single cluster runs **multiple separate Contour Helm releases**, each pinned to its own node pool / compute class. The standard set:
- `contour-external` — public-facing ingress, primary
- `contour-external-1` — public-facing ingress, secondary (capacity / blue-green)
- `contour-internal-0`, `contour-internal-1` — internal mesh ingress, redundant pair
- `contour-internal-intra-0`, `contour-internal-intra-1` — intra-VPC ingress, redundant pair
Per-cluster matrix of which release goes on which node pool: repo-root `contour-nodeselector-tolerations-summary.md`. Each release has its own `helm-overrides/<cluster>/<contour-release>/custom-values.yaml`.
## Notable individual charts
| Chart | Notes |
|-------|-------|
| `argo-cd` / `argo-cd-green` | Self-managing — Argo CD installs itself. Sync policy must be careful. |
| `vault` | Stateful HA on Raft. Edits to seal config or HA storage require platform-team review. |
| `external-secrets` | Source of truth for secret materialization on each cluster. See [`./06-secrets-and-identity.md`](./06-secrets-and-identity.md). |
| `kyverno` | Cluster-policy enforcement. Edits change admission behaviour for all workloads. |
| `kube-prometheus-stack` | Bundles Prometheus + Alertmanager. Alert rules pages on-call — validate PromQL. See [`../docs/global/coding-guidelines/observability.md`](../docs/global/coding-guidelines/observability.md). |
| `external-dns` | Publishes DNS records to Cloud DNS. Often paired with sidecar `external-dns-services/*.yaml` raw manifests. |
| `cert-manager` | Issues TLS certs (Let's Encrypt + Vault). |
## Image registry convention
Production overrides pin images to Meesho's Artifact Registry mirror:
```
asia-southeast1-docker.pkg.dev/meesho-devops-admin-0622/admin/sre/<image>
```
…rather than Docker Hub directly. Mirroring decouples deploys from upstream registry availability and rate limits.
## See also
- [`./01-repo-structure.md`](./01-repo-structure.md)
- [`./02-cluster-fleet.md`](./02-cluster-fleet.md)
- [`./04-override-hierarchy.md`](./04-override-hierarchy.md)
- [`../docs/platform/procedures/update-chart-version.md`](../docs/platform/procedures/update-chart-version.md)
- [`../docs/platform/procedures/fork-upstream-chart.md`](../docs/platform/procedures/fork-upstream-chart.md)
+72
View File
@@ -0,0 +1,72 @@
> Per AI Blitz Plan §claude. Layer: 1. Repo: devops-infra-helm-charts.
# 04 — Override hierarchy
How the per-cluster override file, the chart's default values, and any raw-manifest sidecars compose at deploy time.
## The three layers
For a given Argo Application targeting `<cluster>` × `<app>`, the rendered manifests come from three sources:
1. **Chart defaults**`helm-templates/<chart>/values.yaml`. The upstream values, possibly customized in an intentional fork. This is the lowest precedence.
2. **Cluster override**`helm-overrides/<cluster>/<app>/custom-values.yaml`. Helm-merged on top of (1). This is what the agent edits day-to-day.
3. **Raw manifest sidecars**`helm-overrides/<cluster>/<app>/<extra>.yaml` (and optionally subdirectories like `computeclass/`, `external-dns-services/`). These are NOT consumed by Helm. Argo applies them directly to the cluster, in the same Application.
The Argo Application in the sister repo declares which `path:` (the override directory) and which `helm.valueFiles:` to use. Conventionally the Application points at the override directory and lists `custom-values.yaml`; raw sidecars in the same directory are picked up by Argo's manifest discovery.
## Helm merge semantics
Helm performs a **deep merge** of (2) over (1):
- Maps merge key-by-key.
- Lists are **replaced wholesale**, not merged. This is the most common surprise — to extend an upstream list (`tolerations`, `extraArgs`, `extraEnv`), copy the upstream list into the override and edit there. Don't write a list expecting it to append.
- `null` in the override deletes the key set in defaults.
If you need surgical list editing rather than wholesale replacement, you must fork the chart and rewrite the template — almost never the right call. See [`../docs/platform/procedures/fork-upstream-chart.md`](../docs/platform/procedures/fork-upstream-chart.md).
## Dry-running the merge
Always render before pushing. The command from the root `CLAUDE.md` Quick reference table:
```
helm template <release> helm-templates/<chart> \
-f helm-overrides/<cluster>/<app>/custom-values.yaml
```
For wrapper charts (`Chart.yaml` `dependencies:`), refresh subcharts first:
```
helm dependency update helm-templates/<chart>
```
For raw sidecars, validate separately:
```
kubectl apply --dry-run=client -f helm-overrides/<cluster>/<app>/<extra>.yaml
```
## Where each piece of config belongs
| Config | Goes in | Why |
|--------|---------|-----|
| Image tag pin (production registry) | `custom-values.yaml` | Per-cluster pinning is the whole point of the override layer. |
| `replicaCount`, resource requests | `custom-values.yaml` | Per-cluster capacity tuning. |
| `nodeSelector`, `tolerations`, `computeClass` | `custom-values.yaml` | Per-cluster node-pool topology. **Never copy-paste across clusters.** |
| `fullnameOverride` | `custom-values.yaml` | Pinned to keep Service DNS / PVC binding stable. **Never change** an existing one. |
| Helm-managed Service / Deployment / ConfigMap | chart's `templates/` (don't touch) | Owned by upstream chart. |
| External-DNS record bound to a Service the chart doesn't manage | `external-dns-services/*.yaml` raw sidecar | Not part of the chart's surface. |
| `ComputeClass` definition (Autopilot) | `computeclass/*-cc.yaml` raw sidecar | Cluster-scoped object the chart can't render. |
| StorageClass / PriorityClass | `manifests/storageclass/`, `manifests/priorityclass/<cluster>/` | Cluster-wide singleton, separate from any one Application. |
| Secret values | **External Secrets Operator** + GCP Secret Manager / Vault | Never in `custom-values.yaml`. See [`./06-secrets-and-identity.md`](./06-secrets-and-identity.md). |
## Schema details
- Override schema: [`../docs/platform/schemas/custom-values-schema.md`](../docs/platform/schemas/custom-values-schema.md)
- Raw-sidecar schema: [`../docs/platform/schemas/raw-manifest-sidecar-schema.md`](../docs/platform/schemas/raw-manifest-sidecar-schema.md)
- Singleton schema: [`../docs/platform/schemas/storageclass-priorityclass-schema.md`](../docs/platform/schemas/storageclass-priorityclass-schema.md)
## See also
- [`./00-overview.md`](./00-overview.md)
- [`./05-deploy-lifecycle.md`](./05-deploy-lifecycle.md)
- [`../docs/global/coding-guidelines/helm-values.md`](../docs/global/coding-guidelines/helm-values.md)
+103
View File
@@ -0,0 +1,103 @@
> Per AI Blitz Plan §claude. Layer: 1. Repo: devops-infra-helm-charts.
# 05 — Deploy lifecycle
End-to-end story of how a values change reaches a live cluster, where the safety gates are, and what happens when they fail.
## The path
```
edit override (branch) → commit (TruffleHog runs) → push → PR
→ reviewer approves → merge to main
→ Argo CD on cluster reconciles (auto-sync OR human Sync click)
→ manifests applied → workload changes
```
## Stage 1 — Branch and edit
- Branch off `main`. Never push to `main` directly.
- Edit one `helm-overrides/<cluster>/<app>/custom-values.yaml` (or its raw sidecars).
- No drive-by edits, no cross-cluster normalization in the same PR. See [`../docs/global/SANCTITY_RULES.md`](../docs/global/SANCTITY_RULES.md).
## Stage 2 — Local validation
- `helm template` against the override — confirms render succeeds.
- For wrappers: `helm dependency update` first.
- For raw sidecars: `kubectl apply --dry-run=client`.
If render fails locally, it will fail in Argo CD's `OutOfSync → SyncFailed`. Fix before pushing.
## Stage 3 — Commit
`git commit` triggers pre-commit hooks:
- **TruffleHog** — blocking. Real secrets bounce. Never `--no-verify`.
- **CAC, Yaak** — gated on paths this repo doesn't have, no-op.
Post-commit:
- **Cursor metric collector** — background, non-blocking. Pings `observe.meeshogcp.in` with commit telemetry. Failure here does not block.
Detail: [`./08-pre-commit-and-hooks.md`](./08-pre-commit-and-hooks.md).
## Stage 4 — PR + review (safety gate 1)
The reviewer's job:
1. Confirm the change touches only the cluster × app named in the PR.
2. Confirm any per-cluster scheduling fields were rewritten, not copy-pasted.
3. Confirm `fullnameOverride` is unchanged.
4. Confirm no secret materializes in the file.
5. Confirm chart `Chart.yaml` dep bumps came with `Chart.lock` refresh and a changelog reference.
6. Confirm versioned-sibling deletes have no sister-repo references.
If a chart fork is suspected, escalate per [`../docs/global/escalation-matrix.md`](../docs/global/escalation-matrix.md) row 1.
## Stage 5 — Merge to `main`
Merging is the deploy event. Argo CD on every cluster whose Application points at the changed path will move to `OutOfSync`.
## Stage 6 — Argo CD reconcile (safety gate 2)
Two reconciliation modes, set per Application in the sister repo:
- **Manual sync** (prod default for infra) — Argo waits for a human Sync click. Engineer reviews the diff in the Argo UI before applying.
- **Auto-sync** — Argo applies on its own. Reserved for low-risk leaves (`kube-state-metrics`, monitoring agents).
Background on the manual-sync default: [`../wiki/analyses/ADR-A5-manual-sync-default-for-infra.md`](../wiki/analyses/ADR-A5-manual-sync-default-for-infra.md).
The Argo Application also defines:
- `syncPolicy.automated.prune` — whether Argo deletes objects no longer in Git.
- `syncPolicy.automated.selfHeal` — whether Argo reverts manual cluster edits.
- `syncOptions``CreateNamespace`, `ServerSideApply`, `RespectIgnoreDifferences`, retry/backoff.
- Sync waves via annotations (in chart templates or sidecars).
These all live in the **sister repo**, not here. See [`../docs/global/coding-guidelines/argocd.md`](../docs/global/coding-guidelines/argocd.md).
## Failure modes
| Failure | Where it surfaces | Read |
|---------|------------------|------|
| Render error in `helm template` | Argo Application status `ComparisonError` | Re-render locally; fix values |
| `OutOfSync → SyncFailed` after Sync click | Argo UI events | [`../docs/platform/runbooks/argocd-sync-failure.md`](../docs/platform/runbooks/argocd-sync-failure.md) |
| Pods land but stay `Pending` | `kubectl get pods` on target cluster | [`../docs/platform/runbooks/pod-pending-scheduling.md`](../docs/platform/runbooks/pod-pending-scheduling.md) |
| Ingress 5xx after Contour change | `contour-external` envoy logs / synthetic probes | [`../docs/platform/runbooks/ingress-down.md`](../docs/platform/runbooks/ingress-down.md) |
| Drift reappears after `kubectl edit` | `selfHeal: true` doing its job | Edit Git, not the cluster |
## Sister-repo coupling
Almost every non-trivial change is a **paired PR**:
- New app on cluster: PR here (override) + PR in sister repo (Application).
- New cluster: PR here (cluster directory) + PR in sister repo (`ApplicationSet` cluster generator).
- Blue-green sibling cutover: PR here (sibling values) + PR in sister repo (Application `targetRevision` / chart path).
Procedures: [`../docs/platform/procedures/onboard-app-to-cluster.md`](../docs/platform/procedures/onboard-app-to-cluster.md), [`../docs/platform/procedures/onboard-new-cluster.md`](../docs/platform/procedures/onboard-new-cluster.md), [`../docs/platform/procedures/blue-green-chart-migration.md`](../docs/platform/procedures/blue-green-chart-migration.md), [`../docs/platform/procedures/deboard-app.md`](../docs/platform/procedures/deboard-app.md).
## See also
- [`./00-overview.md`](./00-overview.md)
- [`./04-override-hierarchy.md`](./04-override-hierarchy.md)
- [`../docs/architecture.md`](../docs/architecture.md)
- [`../docs/global/agent-operations-guide.md`](../docs/global/agent-operations-guide.md)
+70
View File
@@ -0,0 +1,70 @@
> Per AI Blitz Plan §claude. Layer: 1. Repo: devops-infra-helm-charts.
# 06 — Secrets and identity
This repo is **values + cached charts**, all of it world-readable from Git. No secret value should ever exist in a file here. The platform pattern is to express secrets as *references* and let the in-cluster machinery materialize them.
## The components
### External Secrets Operator (ESO)
Each cluster carries an `external-secrets/` override directory. ESO runs in the cluster, reads `ExternalSecret` CRs, fetches the secret value from a backend (GCP Secret Manager or Vault), and materializes a Kubernetes `Secret` for workloads to mount.
- The `ExternalSecret` CR refers to a backend by **name only** (e.g., `gcpsm/prod/<service>/api-token`). The CR is checked into Git; the value is not.
- The backend is configured per-cluster in `external-secrets/custom-values.yaml`.
### GCP Secret Manager
The default backend for most prod clusters. Secrets are project-scoped under the cluster's GCP project. Workload Identity binds the ESO service account to a Google service account that has `secretmanager.secretAccessor` on the relevant secrets.
### Vault
Used where additional capabilities are required — dynamic credentials, transit encryption, PKI. Vault runs in-cluster on Raft HA. Edits to Vault overrides (`helm-overrides/<cluster>/vault/custom-values.yaml`) — especially seal config, HA storage, autounseal — require platform-team review. Vault HA write-path failure is a paging incident. See [`../docs/global/escalation-matrix.md`](../docs/global/escalation-matrix.md) row 8.
### Workload Identity
GKE Workload Identity binds Kubernetes service accounts to Google service accounts via the `iam.gke.io/gcp-service-account` annotation. This is how pods authenticate to GCP APIs (Secret Manager, Cloud Storage, Pub/Sub) without long-lived keys.
The annotation is set in the chart's values (`serviceAccount.annotations`) — agent-editable. The IAM binding itself is set up out-of-band via Terraform in the platform IaC repo, not here.
## What never goes in this repo
- Plain-text passwords, API tokens, certificates, private keys.
- Base64-encoded secrets in `Secret` manifests.
- TLS keys / certs (use `cert-manager` issuers + ESO references instead).
- GCP service-account JSON keys (Workload Identity replaces them).
- OAuth client secrets (Secret Manager → ESO).
- Webhook URLs that contain a credential token in the path.
If the value would be useful to an attacker who clones this repo, it does not belong here.
## TruffleHog — last line of defense
The pre-commit hook scans staged content for high-entropy strings and known secret formats. **NEVER bypass.**
- `git commit --no-verify` is blocked by Sanctity rule.
- If the hook flags a real secret, rotate the credential first (the moment it touched a Git working tree it is already half-burned), then move it to ESO.
- If the hook flags a false positive, fix the regex in `pre-commit-scripts/` rather than excluding the file.
Detail: [`./08-pre-commit-and-hooks.md`](./08-pre-commit-and-hooks.md).
## The pre-commit hook telemetry exception
The post-commit Cursor metric collector POSTs to `observe.meeshogcp.in`. This is platform-managed automation, not agent-initiated, and is the only outbound call to a `*.meeshogcp.in` host the agent will ever observe in this repo. The agent must still refuse any *new* call to such hosts. See [`../docs/global/SANCTITY_RULES.md`](../docs/global/SANCTITY_RULES.md).
## Common patterns
| Pattern | Looks like |
|---------|-----------|
| Pod reads a Secret Manager value | `ExternalSecret` CR → ESO materializes `Secret` → pod mounts via `envFrom.secretRef` or `volumes.secret` |
| Pod calls a GCP API | KSA annotated with `iam.gke.io/gcp-service-account: <gsa>@<project>.iam.gserviceaccount.com` (Workload Identity) |
| TLS for an Ingress | `cert-manager` `Certificate` CR + Vault PKI or Let's Encrypt issuer |
| Vault dynamic DB credential | Vault DB secrets engine + ESO `VaultDynamicSecret` (or app-side Vault Agent sidecar) |
## See also
- [`./08-pre-commit-and-hooks.md`](./08-pre-commit-and-hooks.md)
- [`./07-singletons-and-blast-radius.md`](./07-singletons-and-blast-radius.md)
- [`../docs/global/SANCTITY_RULES.md`](../docs/global/SANCTITY_RULES.md)
- [`../docs/global/escalation-matrix.md`](../docs/global/escalation-matrix.md)
- [`../docs/global/coding-guidelines/helm-values.md`](../docs/global/coding-guidelines/helm-values.md)
+85
View File
@@ -0,0 +1,85 @@
> Per AI Blitz Plan §claude. Layer: 1. Repo: devops-infra-helm-charts.
# 07 — Singletons and blast radius
Most files in this repo affect one cluster × one application. A small number of files affect **everything** on a cluster (or every cluster). These are the singletons. They get a different review bar.
## `manifests/storageclass/*.yaml`
Cluster-wide `StorageClass` objects. Every PVC on the cluster either references one of these by name or relies on the default annotation (`storageclass.kubernetes.io/is-default-class: "true"`).
Wrong here means:
- New PVCs bind to a different disk type (cost, latency, IOPS change).
- `volumeBindingMode` change (Immediate ↔ WaitForFirstConsumer) changes scheduling semantics for every stateful workload.
- Default-class flip changes behaviour of every chart that doesn't pin a class explicitly.
**Layer-1 high risk.** Two reviewers, one of whom must be a cluster BU owner. Schema: [`../docs/platform/schemas/storageclass-priorityclass-schema.md`](../docs/platform/schemas/storageclass-priorityclass-schema.md).
## `manifests/priorityclass/<cluster>/*.yaml`
Cluster-wide `PriorityClass` objects, partitioned by cluster directory. Every pod that sets `spec.priorityClassName: <name>` resolves against this set.
Wrong here means:
- A `value:` change can swap which workloads preempt others under capacity pressure.
- A `globalDefault: true` flip changes behaviour of every pod that omits `priorityClassName`.
- Removing a `PriorityClass` referenced by a live workload causes admission failure on next pod create.
**Layer-1 high risk.** Same review policy as StorageClass. Schema: same file as above.
## `repository.yaml`
Owners, secondary owners, repo metadata. Owned by the **`registry-bootstrap` automation**, not by humans. Hand edits will be reverted on the next `registry-bootstrap` run.
**Layer-3 — refuse.** If asked to edit, redirect to `registry-bootstrap`. See [`../docs/global/escalation-matrix.md`](../docs/global/escalation-matrix.md) row 4.
## `manifests/{jenkins-filestore-caching,jenkins-gcs-caching,jfrog-filestore-data}/{dev,prd}/`
Per-env, one-shot PV / PVC manifests for stateful systems (Jenkins build cache, JFrog binary store). Bound to GCP Filestore or GCS. Once a PVC is bound to a PV with a real backend, you cannot move it without data migration.
**Layer-1 high risk.** Resize via `resources.requests.storage` only; do not recreate.
## Versioned-sibling chart deletion
Deleting a chart directory under `helm-templates/` (e.g., removing `argo-cd-green` after a successful migration) is irreversible from Argo CD's point of view — any cluster whose Application still points at it will fail to render.
**Layer-1 high risk.** Confirm zero references in [`Meesho/devops-infra-argo-config`](https://github.com/Meesho/devops-infra-argo-config) first. See [`../wiki/analyses/ADR-A2-blue-green-sibling-pattern.md`](../wiki/analyses/ADR-A2-blue-green-sibling-pattern.md) and [`../docs/global/escalation-matrix.md`](../docs/global/escalation-matrix.md) row 10.
## Chart `templates/` edits
Editing `helm-templates/<chart>/templates/` or `values.yaml` of a vanilla-pulled chart silently forks it. The next refresh clobbers the edit, but until then it ships to every cluster that consumes the chart.
**Layer-1 high risk.** Allowed only if the fork is intentional and documented in the chart's `README.md`. See [`../docs/platform/procedures/fork-upstream-chart.md`](../docs/platform/procedures/fork-upstream-chart.md).
## Kyverno cluster policies
`helm-overrides/<cluster>/kyverno/custom-values.yaml` configures admission policies. A new `enforce`-mode `ClusterPolicy` can block every pod admission on a cluster.
**Layer-1 high risk.** Roll out in `audit` mode first, observe `PolicyReport`s, then flip to `enforce`.
## Argo CD itself (`argo-cd` / `argo-cd-green`)
Argo CD self-manages — it deploys itself from this repo. A bad values change can break the control plane that would otherwise heal it. Recovery requires `kubectl` access to apply a hand-rendered manifest.
**Layer-1 high risk.** Always cut a green sibling first; never edit the live release directly.
## Decision summary
| Singleton | Layer | Review policy |
|-----------|-------|---------------|
| `manifests/storageclass/*.yaml` | 1 high-risk | Two reviewers, one cluster BU owner |
| `manifests/priorityclass/<cluster>/*.yaml` | 1 high-risk | Two reviewers, one cluster BU owner |
| `repository.yaml` | 3 | Refuse; redirect to `registry-bootstrap` |
| `manifests/{jenkins,jfrog}-…/{dev,prd}/` | 1 high-risk | Two reviewers; resize-only edits |
| Versioned-sibling chart deletion | 1 high-risk | Confirm sister-repo zero references |
| `helm-templates/<chart>/templates/` edits | 1 high-risk | README must document the fork |
| Kyverno enforce-mode policy | 1 high-risk | Audit-mode rollout first |
| Argo CD self-managed values | 1 high-risk | Cut a green sibling first |
## See also
- [`./01-repo-structure.md`](./01-repo-structure.md)
- [`../docs/platform/schemas/storageclass-priorityclass-schema.md`](../docs/platform/schemas/storageclass-priorityclass-schema.md)
- [`../docs/global/SANCTITY_RULES.md`](../docs/global/SANCTITY_RULES.md)
- [`../docs/global/escalation-matrix.md`](../docs/global/escalation-matrix.md)
+69
View File
@@ -0,0 +1,69 @@
> Per AI Blitz Plan §claude. Layer: 1. Repo: devops-infra-helm-charts.
# 08 — Pre-commit and hooks
What runs when you `git commit` here, what blocks, what doesn't, and why nothing should be bypassed.
## Hook installation
One-time, per clone:
```
pre-commit install \
--hook-type pre-commit \
--hook-type pre-push \
--hook-type post-commit
```
If the hooks aren't installed, the local commit will skip them — but PR review is the catch-net, and a missed scan in a feature branch can still catch the secret before merge.
## Active hooks
### TruffleHog (pre-commit, blocking)
Scans the staged content for high-entropy strings and known secret patterns (AWS keys, GCP service-account JSON, GitHub tokens, generic JWTs, etc.).
- **Blocks the commit** on any positive match.
- **NEVER bypass** with `git commit --no-verify` or `git commit -n`. This is on the don't-touch list — see [`../docs/global/SANCTITY_RULES.md`](../docs/global/SANCTITY_RULES.md).
- If the hook fires on a **real secret**: stop, rotate the credential immediately (any value that touched a Git working tree is half-burned), then move to External Secrets Operator. See [`./06-secrets-and-identity.md`](./06-secrets-and-identity.md).
- If the hook fires on a **false positive**: fix the regex in `pre-commit-scripts/` rather than skip-listing the file. The fix is reusable across the org.
### CAC and Yaak (pre-commit / pre-push, gated)
These hooks exist in the platform's standard `.pre-commit-config.yaml`, but they are gated on file paths this repo doesn't carry (CAC config files, Yaak collections). They no-op here. The same scripts run for real in service repos.
If a future change ever introduces matching paths, the hooks will start firing — read their messages and fix forward. Do not disable.
## Background hooks
### Cursor AI commit metric collector (post-commit, non-blocking)
Posts a metric ping to `observe.meeshogcp.in` describing the commit (author, files touched, AI tool used). Runs in the background, does not block, and silently drops on failure.
- This is **the only sanctioned outbound call to a `*.meeshogcp.in` host** the agent should ever observe in this repo. Agents must still refuse to *initiate* any such call themselves. See [`../docs/global/SANCTITY_RULES.md`](../docs/global/SANCTITY_RULES.md).
- If the post-commit script is failing, that's a platform issue — escalate per [`../docs/global/escalation-matrix.md`](../docs/global/escalation-matrix.md). Do not remove the script.
## Why never `--no-verify`
A bypassed pre-commit hook is invisible to the PR reviewer. Real secrets ship through merged PRs are very expensive to recover from:
- The credential itself must be rotated everywhere it's used.
- The Git history must be force-rewritten (and even then, the Git push may be cached on a mirror).
- Any system that ingested the secret value (CI logs, Slack quotes, downstream forks) is now compromised.
The 5 seconds saved bypassing the hook is a 5-day-or-more incident later.
## When the hook is wrong
Two kinds of false-positive:
1. **Pattern over-matches** — TruffleHog regex matches a non-secret high-entropy string (a hash, a UUID, a build label). Fix: tighten the regex in `pre-commit-scripts/`.
2. **Genuine fixture / test data** — a fake-looking string in a chart's example values or test fixture. Fix: same — tighten the pattern, or move the fixture to a path TruffleHog already excludes (chart `templates/` test fixtures usually qualify).
Either way, the fix is in the hook, not in the bypass.
## See also
- [`./06-secrets-and-identity.md`](./06-secrets-and-identity.md)
- [`../docs/global/SANCTITY_RULES.md`](../docs/global/SANCTITY_RULES.md)
- [`../docs/global/agent-operations-guide.md`](../docs/global/agent-operations-guide.md)
+67
View File
@@ -0,0 +1,67 @@
> Per AI Blitz Plan §claude. Layer: 1. Repo: devops-infra-helm-charts.
# 09 — Common tasks
Index of the procedures and skills checked into the repo. Pick the task, follow the link, run the playbook.
## Procedures (deeper, multi-step, often paired with sister-repo PR)
| Task | Read |
|------|------|
| Onboard a new app to an existing cluster | [`../docs/platform/procedures/onboard-app-to-cluster.md`](../docs/platform/procedures/onboard-app-to-cluster.md) |
| Onboard a new cluster | [`../docs/platform/procedures/onboard-new-cluster.md`](../docs/platform/procedures/onboard-new-cluster.md) |
| Deboard / remove an app from a cluster | [`../docs/platform/procedures/deboard-app.md`](../docs/platform/procedures/deboard-app.md) |
| Bump a chart version (Chart.yaml deps) | [`../docs/platform/procedures/update-chart-version.md`](../docs/platform/procedures/update-chart-version.md) |
| Cut a blue-green sibling and migrate to it | [`../docs/platform/procedures/blue-green-chart-migration.md`](../docs/platform/procedures/blue-green-chart-migration.md) |
| Intentionally fork an upstream chart | [`../docs/platform/procedures/fork-upstream-chart.md`](../docs/platform/procedures/fork-upstream-chart.md) |
## Skills (focused, single-task playbooks)
| Skill | Read |
|-------|------|
| Bump a chart version (concise checklist) | [`../skills/infra/bump-chart-version.md`](../skills/infra/bump-chart-version.md) |
| Diagnose pods stuck `Pending` (scheduling) | [`../skills/infra/diagnose-scheduling.md`](../skills/infra/diagnose-scheduling.md) |
| Onboard an app (concise checklist) | [`../skills/infra/onboard-app.md`](../skills/infra/onboard-app.md) |
## Runbooks (failure response)
| Symptom | Read |
|---------|------|
| Argo CD `OutOfSync → SyncFailed` | [`../docs/platform/runbooks/argocd-sync-failure.md`](../docs/platform/runbooks/argocd-sync-failure.md) |
| Pods stuck `Pending` | [`../docs/platform/runbooks/pod-pending-scheduling.md`](../docs/platform/runbooks/pod-pending-scheduling.md) |
| Ingress 5xx after a Contour change | [`../docs/platform/runbooks/ingress-down.md`](../docs/platform/runbooks/ingress-down.md) |
## Schemas (reference while editing)
| Surface | Read |
|---------|------|
| `helm-overrides/<cluster>/<app>/custom-values.yaml` | [`../docs/platform/schemas/custom-values-schema.md`](../docs/platform/schemas/custom-values-schema.md) |
| Raw `<extra>.yaml` sidecars in override dirs | [`../docs/platform/schemas/raw-manifest-sidecar-schema.md`](../docs/platform/schemas/raw-manifest-sidecar-schema.md) |
| Cluster-wide `StorageClass` / `PriorityClass` | [`../docs/platform/schemas/storageclass-priorityclass-schema.md`](../docs/platform/schemas/storageclass-priorityclass-schema.md) |
## Coding guidelines
| Domain | Read |
|--------|------|
| Helm values conventions | [`../docs/global/coding-guidelines/helm-values.md`](../docs/global/coding-guidelines/helm-values.md) |
| Argo CD interaction model | [`../docs/global/coding-guidelines/argocd.md`](../docs/global/coding-guidelines/argocd.md) |
| Observability stack | [`../docs/global/coding-guidelines/observability.md`](../docs/global/coding-guidelines/observability.md) |
## Operating discipline
| Topic | Read |
|-------|------|
| Pre-flight + authoring loop | [`../docs/global/agent-operations-guide.md`](../docs/global/agent-operations-guide.md) |
| Don't-touch list | [`../docs/global/SANCTITY_RULES.md`](../docs/global/SANCTITY_RULES.md) |
| Layer classification | [`../docs/global/AGENT_BOUNDARIES.md`](../docs/global/AGENT_BOUNDARIES.md) |
| Escalation table | [`../docs/global/escalation-matrix.md`](../docs/global/escalation-matrix.md) |
## ADRs (rationale, when you want to know *why*)
| ADR | Read |
|-----|------|
| Why cache charts here vs pull from upstream at deploy | [`../wiki/analyses/ADR-A1-cache-vs-upstream-charts.md`](../wiki/analyses/ADR-A1-cache-vs-upstream-charts.md) |
| Why versioned-sibling charts (`-green`, `-vX.Y.Z`, `-latest`) | [`../wiki/analyses/ADR-A2-blue-green-sibling-pattern.md`](../wiki/analyses/ADR-A2-blue-green-sibling-pattern.md) |
| Why per-cluster scheduling fields cannot be shared | [`../wiki/analyses/ADR-A3-per-cluster-scheduling.md`](../wiki/analyses/ADR-A3-per-cluster-scheduling.md) |
| Why raw manifest sidecars live next to overrides | [`../wiki/analyses/ADR-A4-raw-manifest-sidecars-in-helm-overrides.md`](../wiki/analyses/ADR-A4-raw-manifest-sidecars-in-helm-overrides.md) |
| Why manual Argo sync is the prod default | [`../wiki/analyses/ADR-A5-manual-sync-default-for-infra.md`](../wiki/analyses/ADR-A5-manual-sync-default-for-infra.md) |
+61
View File
@@ -0,0 +1,61 @@
> Per AI Blitz Plan §claude. Layer: 1. Repo: devops-infra-helm-charts.
# 10 — Glossary and references
Short definitions for the terms that recur in this repo's docs, and outbound links for deep dives.
## Glossary
**Argo CD** — GitOps continuous-delivery controller. Reconciles a cluster's actual state to a Git-declared desired state. Each cluster runs its own Argo CD instance; each Argo CD instance hosts a set of `Application` objects.
**Application (Argo)** — A single deployable unit. Points at a Git repo + path + revision + chart-and-values config, and a destination (cluster + namespace). In our setup, the source path is in **this** repo; the Application manifest itself is in the **sister repo**.
**ApplicationSet** — A controller-side template that fans out one Application per cluster (or per cluster × app). Used in the sister repo to express "deploy `victoria-metrics-agent` to every prod cluster" once instead of N times.
**BU (Business Unit)** — Meesho-internal grouping that owns a cluster. Encoded in the cluster name: `k8s-<bu>-prd-ase1[c]`. Examples: `central`, `supply`, `demand`, `dataengg`, `ml-platform`.
**Autopilot (GKE)** — Google's managed-node-pool flavour of GKE. Scheduling primitives are different from standard GKE — uses `cloud.google.com/compute-class` instead of `dedicated:` taints. The repo has three Autopilot clusters: `k8s-central-prd-ase1`, `k8s-dsgpu-prd-ase1`, `k8s-shared-int-ase1`. See [`./02-cluster-fleet.md`](./02-cluster-fleet.md).
**ESO (External Secrets Operator)** — In-cluster operator that reads `ExternalSecret` CRs and materializes Kubernetes `Secret` objects from a remote backend (GCP Secret Manager, Vault). The mechanism that keeps secret values out of this repo. See [`./06-secrets-and-identity.md`](./06-secrets-and-identity.md).
**ComputeClass** — A GKE Autopilot CR that describes a node-pool selection policy (machine family, accelerators, spot eligibility). Workloads target a ComputeClass via `nodeSelector."cloud.google.com/compute-class": <name>`. CRs live as raw sidecars in `helm-overrides/<cluster>/<app>/computeclass/`.
**fullnameOverride** — A Helm values key consumed by most charts to fix the resource name prefix. **Load-bearing** — Service DNS names, PVC bindings, ConfigMap references all key off it. Never change for a live release. See [`../docs/global/SANCTITY_RULES.md`](../docs/global/SANCTITY_RULES.md).
**Sister repo** — [`Meesho/devops-infra-argo-config`](https://github.com/Meesho/devops-infra-argo-config). Owns the Argo `Application` / `ApplicationSet` manifests that point at paths in this repo. See [`../docs/global/coding-guidelines/argocd.md`](../docs/global/coding-guidelines/argocd.md).
**External Secrets** — short for the External Secrets Operator (above), or the `ExternalSecret` CR it consumes.
**Blue-green sibling** — A second chart directory under `helm-templates/` (`-green`, `-vX.Y.Z`, `-latest`, `-old`) that exists alongside the stable chart to support a phased migration. Both can be live simultaneously. See [`../wiki/analyses/ADR-A2-blue-green-sibling-pattern.md`](../wiki/analyses/ADR-A2-blue-green-sibling-pattern.md).
**helm-overrides** — Top-level dir holding per-cluster × per-app values overlays (`<cluster>/<app>/custom-values.yaml`) and raw-manifest sidecars. The agent-edited surface.
**helm-templates** — Top-level dir holding cached / forked upstream charts. Mostly read-only. Edits silently fork unless intentional.
**Manual sync** — Argo `syncPolicy.automated` is unset; reconciliation requires a human Sync click in the Argo UI. The default for prod infra. See [`../wiki/analyses/ADR-A5-manual-sync-default-for-infra.md`](../wiki/analyses/ADR-A5-manual-sync-default-for-infra.md).
**Workload Identity** — GKE feature that binds a Kubernetes service account to a Google service account via the `iam.gke.io/gcp-service-account` annotation. Replaces long-lived JSON service-account keys.
**TruffleHog** — Pre-commit secret scanner. Active and blocking on this repo. Never bypass.
**Layer 1 / Layer 3** — Agent authority classification from the AI Blitz Plan. Layer 1 = agent-writable (this repo, mostly). Layer 3 = refuse and redirect (`repository.yaml` edits, production endpoint probes). See [`../docs/global/AGENT_BOUNDARIES.md`](../docs/global/AGENT_BOUNDARIES.md).
## References — internal
- Repo-root `CLAUDE.md` — authoritative facts list.
- [`../docs/architecture.md`](../docs/architecture.md) — full deploy lifecycle and gotchas.
- [`../wiki/entities/DevOps Infra Helm Charts.md`](../wiki/entities/DevOps%20Infra%20Helm%20Charts.md) — entity model.
- [`./09-common-tasks.md`](./09-common-tasks.md) — task index.
## References — external
- **Sister repo** (Argo Application manifests): [`github.com/Meesho/devops-infra-argo-config`](https://github.com/Meesho/devops-infra-argo-config)
- **AI Blitz Plan** — internal Confluence; ask the primary owner for the current link.
- **Argo CD** — [argo-cd.readthedocs.io](https://argo-cd.readthedocs.io/), chart at [github.com/argoproj/argo-helm](https://github.com/argoproj/argo-helm/tree/main/charts/argo-cd)
- **Contour** — [projectcontour.io](https://projectcontour.io/), chart at [github.com/bitnami/charts/tree/main/bitnami/contour](https://github.com/bitnami/charts/tree/main/bitnami/contour)
- **VictoriaMetrics** — [docs.victoriametrics.com](https://docs.victoriametrics.com/), charts at [github.com/VictoriaMetrics/helm-charts](https://github.com/VictoriaMetrics/helm-charts)
- **HashiCorp Vault** — [developer.hashicorp.com/vault](https://developer.hashicorp.com/vault), chart at [github.com/hashicorp/vault-helm](https://github.com/hashicorp/vault-helm)
- **KEDA** — [keda.sh](https://keda.sh/), chart at [github.com/kedacore/charts](https://github.com/kedacore/charts)
- **Kyverno** — [kyverno.io](https://kyverno.io/), chart at [github.com/kyverno/kyverno/tree/main/charts](https://github.com/kyverno/kyverno/tree/main/charts)
- **External Secrets Operator** — [external-secrets.io](https://external-secrets.io/)
- **GKE Autopilot ComputeClass** — [cloud.google.com/kubernetes-engine/docs/concepts/autopilot-compute-classes](https://cloud.google.com/kubernetes-engine/docs/concepts/autopilot-compute-classes)
@@ -0,0 +1,70 @@
# Contour NodeSelector and Tolerations Summary
## Summary by Cluster
### k8s-central-prd-ase1
| Contour | NodeSelector | Tolerations |
|---------|--------------|-------------|
| contour-external | `cloud.google.com/compute-class: contour-external-cc` | `cloud.google.com/compute-class: contour-external-cc, contour-shared-cc` |
| contour-external-1 | `dedicated: contour-external-1` | `dedicated: contour-external-1` |
| contour-internal-0 | `cloud.google.com/compute-class: contour-internal-0-cc` | `cloud.google.com/compute-class: contour-internal-0-cc, contour-shared-cc` |
| contour-internal-1 | `cloud.google.com/compute-class: contour-internal-1-cc` | `cloud.google.com/compute-class: contour-internal-1-cc, contour-shared-cc` |
| contour-internal-intra-0 | `cloud.google.com/compute-class: contour-intra-0-cc` | `cloud.google.com/compute-class: contour-intra-0-cc, contour-shared-cc` |
| contour-internal-intra-1 | `cloud.google.com/compute-class: contour-intra-1-cc` | `cloud.google.com/compute-class: contour-intra-1-cc, contour-shared-cc` |
### k8s-dataengg-prd-ase1
| Contour | NodeSelector | Tolerations |
|---------|--------------|-------------|
| contour-external | `dedicated: contour-external` | `dedicated: contour-external` |
| contour-internal-0 | `dedicated: contour-internal-0` | `dedicated: contour-internal-0` |
| contour-internal-1 | `dedicated: contour-internal-1` | `dedicated: contour-internal-1, contour-shared` |
| contour-internal-intra-0 | `dedicated: contour-internal-0` | `dedicated: contour-internal-0` |
| contour-internal-intra-1 | `dedicated: contour-intra-1` | `dedicated: contour-intra-1, contour-shared` |
### k8s-datascience-prd-ase1
| Contour | NodeSelector | Tolerations |
|---------|--------------|-------------|
| contour-internal-0 | `dedicated: contour-internal-0` | `dedicated: contour-internal-0` |
| contour-internal-1 | `dedicated: contour-internal-1-c4d` | `dedicated: contour-internal-1-c4d` |
| contour-internal-dataproc | `dedicated: contour-internal-1-c4d` | `dedicated: contour-internal-1-c4d` |
| contour-internal-intra-0 | `dedicated: contour-internal-0-c4d` | `dedicated: contour-internal-0-c4d` |
| contour-internal-intra-1 | `dedicated: contour-intra-1` | `dedicated: contour-intra-1, contour-shared` |
### k8s-demand-prd-ase1
| Contour | NodeSelector | Tolerations |
|---------|--------------|-------------|
| contour-external | `dedicated: contour-external` | `dedicated: contour-external` |
| contour-internal-0 | `dedicated: contour-internal-0` | `dedicated: contour-internal-0, contour-shared` |
| contour-internal-1 | `dedicated: contour-internal-1` | `dedicated: contour-internal-0, contour-internal-1` |
| contour-internal-intra-0 | `dedicated: contour-intra-0` | `dedicated: contour-internal-0, contour-intra-0` |
| contour-internal-intra-1 | `dedicated: contour-intra-1` | `dedicated: contour-internal-0, contour-intra-1` |
### k8s-farmiso-prd-ase1
| Contour | NodeSelector | Tolerations |
|---------|--------------|-------------|
| contour-external | `dedicated: contour-external` | `dedicated: contour-external` |
| contour-internal-0 | `dedicated: contour-internal-0` | `dedicated: contour-internal-0` |
| contour-internal-intra-0 | `dedicated: contour-internal-0` | `dedicated: contour-internal-0` |
### k8s-supply-prd-ase1
| Contour | NodeSelector | Tolerations |
|---------|--------------|-------------|
| contour-external | `dedicated: contour-external` | `dedicated: contour-external, contour-shared` |
| contour-internal-0 | `dedicated: contour-internal-0` | `dedicated: contour-internal-0, contour-shared` |
| contour-internal-1 | `dedicated: contour-internal-1` | `dedicated: contour-internal-1, contour-intra-0` |
| contour-internal-intra-0 | `dedicated: contour-intra-0` | `dedicated: contour-intra-0, contour-shared` |
| contour-internal-intra-1 | `dedicated: contour-intra-1` | `dedicated: contour-intra-1, contour-shared` |
## Key Patterns Observed
1. **Most clusters** use `dedicated` key for taints/tolerations with values matching the contour instance name
2. **GKE Autopilot clusters** (k8s-central-prd-ase1, k8s-dsgpu-prd-ase1, k8s-shared-int-ase1) use `cloud.google.com/compute-class`
3. **cert-checker** components use `<cluster-name>-devops` toleration values
4. **Some clusters** have multiple tolerations for migration/shared scheduling (e.g., `contour-shared`, `contour-internal-1-new`)
5. **k8s-aurva-prd-ase1** is the only cluster without any nodeSelector/tolerations for contour
+148
View File
@@ -0,0 +1,148 @@
# Architecture
This is a **GitOps Helm values repository**, not a service repo. There is no application code, no build, no tests — only declarative YAML (Helm charts, value overrides, Kubernetes manifests) and two git-hook shell scripts. Argo CD is the runtime; merging to `main` is the deployment.
## Section 1 — High-level design
### Repo purpose
Centralizes (1) cached/forked upstream Helm charts and (2) per-cluster value overrides for every infrastructure tool Meesho runs on its GKE fleet — observability (VictoriaMetrics, Mimir, Loki, Tempo, Grafana, OpenTelemetry, Pyroscope), ingress/edge (Contour/Envoy, ingress-nginx, cert-manager, external-dns, external-secrets), platform (Argo CD, Vault, Keda, Kyverno, Flagger, Jenkins, JFrog, Rancher, SonarQube), and data/AI (ClickHouse, Temporal, Superset, Deepgram, Aurva, Deepfence). It was carved out of `gcp-devops-admin` and is the source of truth for **what gets installed where, with what values**.
### System context
| Edge | Plays |
|------|-------|
| Sister repo `devops-infra-argo-config` | `github.com/Meesho/devops-infra-argo-config`. Holds the Argo CD `Application` / `ApplicationSet` manifests that point at this repo's `helm-overrides/<cluster>/<app>/` paths. Argo Application changes are PRs against that repo, not this one. |
| Argo CD instance(s) | Reconciles cluster state from this repo + the argo-config repo. One Argo CD per cluster (or per BU); each cluster has an `argocd/custom-values.yaml` here that configures *its own* Argo CD. |
| GKE cluster fleet | All consumers. Standard GKE clusters (`k8s-<bu>-prd-ase1`) plus auto-named dataplane clusters (`db-<numeric-id>-...`). Region: `asia-southeast1`. Project fleet: `meesho-admin-prd-0622`. |
| TruffleHog webhook | `https://observe.meeshogcp.in/api/webhook` — pre-commit hook reports verified secret findings. |
| CAC API | `https://observe.meeshogcp.in/api/cac/repos` — pre-commit allowlist; this repo isn't on the list, so the `cac validate` hook is a no-op. |
| Cursor metrics API | `https://cursor-server.meeshogcp.in/api/v1/...` — post-commit hook ships per-commit Cursor AI usage metrics. Local-only side effect. |
### Module boundaries
| Top-level dir | What it owns |
|---------------|--------------|
| `helm-templates/<chart>/` | Cached or forked upstream Helm chart. Touch only when a deliberate fork update is needed. Most are vanilla upstream — `Chart.yaml` + `templates/` + `values.yaml` (default upstream values). |
| `helm-templates/<chart>-<variant>/` | Versioned/blue-green sibling charts: `argo-cd` + `argo-cd-green`, `contour` + `contour-v1.33.3`, `keda` + `keda-2.17.1`, `opentelemetry-collector` + `-latest`, `victoria-metrics-cluster` + `-latest`, `victoria-metrics-agent` + `-latest`, `sonarqube` + `sonarqube-old`. The variant is the **target** of an in-flight chart upgrade — old version stays until the migration finishes. |
| `helm-overrides/<cluster>/<app>/custom-values.yaml` | Cluster × application override values. Argo CD's `helm.valueFiles` points here; values merge over the chart's own `values.yaml` (or the upstream subchart's defaults when the local chart is a thin wrapper). |
| `helm-overrides/<cluster>/<app>/<extra>.yaml` | Non-`custom-values` files: extra Kubernetes resources rendered by an Argo Application's `path:` (e.g., `computeclass/*-cc.yaml`, `elastic-cluster/argo-launch.yaml`, `mimir-distributed/alertmanager_config.yaml`, `external-dns-services/*.yaml`). These are not Helm values — they are raw manifests applied alongside the Helm release. |
| `manifests/` | One-shot, cluster-scoped resources applied outside the Helm flow: `storageclass/`, `priorityclass/<cluster>/`, `jenkins-filestore-caching/{dev,prd}/`, `jenkins-gcs-caching/`, `jfrog-filestore-data/{dev,prd}/`. These are singletons — wrong values affect every workload in the cluster. |
| `pre-commit-scripts/` | `runner.sh` (parallel exec), `trufflehog-hook.sh` (verified-secret scan + webhook), `cac-validate.sh` (no-op here — gated on `configs/` path), `yaakhook.sh` (no-op here — gated on `api-collections/` path). |
| `post-commit-scripts/` | `runner.sh` + `commit-metric.sh` — Cursor AI commit metric collector (forks to background; never blocks). |
| `repository.yaml` | Owners (auto-managed by registry-bootstrap). |
### Architecture philosophy
**Reliability-first, surgical edits.** A bad values change can take down ingress, observability, or an entire cluster. Two rules govern every change:
1. **Reliability-first** — production blast radius is huge; mirror the existing pattern of neighbor cluster overrides; never delete keys without checking what depends on them; preserve explicit limits and HPA bounds.
2. **Surgical** — touch only what was asked. Don't refactor surrounding values, don't "normalize" across clusters in the same PR, don't drive-by-edit other charts in the same cluster's directory.
### Data flow (deployment lifecycle)
```
edit helm-overrides/<cluster>/<app>/custom-values.yaml
git commit ──► pre-commit hooks (TruffleHog secrets scan)
git push ──► PR → review → merge to main
Argo CD on each cluster polls this repo + devops-infra-argo-config
Application sync: helm template <chart> -f <override> → apply to cluster
post-commit hook ships Cursor AI metrics (background, non-blocking)
```
Argo CD resolves `<chart>` from `helm-templates/` (when the Application uses `repoURL` of this repo with `path: helm-templates/<name>`) or pulls upstream by reading the local `Chart.yaml` dependencies (e.g., `argo-cd/Chart.yaml` declares `argo-cd 7.7.23` from `argoproj.github.io/argo-helm`).
### Cross-cutting concerns
- **Secret management** — TruffleHog pre-commit hook (`pre-commit-scripts/trufflehog-hook.sh`) blocks any verified secret. Reports go to the security webhook with content hash + commit + file/line metadata. NEVER bypass. Real secrets are externalised via `external-secrets` (per-cluster override exists in most clusters) backed by GCP Secret Manager / Vault.
- **Per-cluster scheduling** — every cluster has its own `nodeSelector` / `tolerations` / `computeclass` topology. The `contour-nodeselector-tolerations-summary.md` at the repo root documents the current matrix. GKE Autopilot clusters (`k8s-central-prd-ase1`, `k8s-dsgpu-prd-ase1`, `k8s-shared-int-ase1`) use `cloud.google.com/compute-class` keys; standard clusters use `dedicated:` keys. Copying values between clusters without rewriting these is a reliable way to schedule pods on the wrong nodes.
- **Versioned chart migrations** — when upgrading a chart, the new version lives as a sibling dir (`argo-cd-green`, `contour-v1.33.3`, `keda-2.17.1`) until cutover. Both directories may be referenced by Argo Applications during the transition. Don't delete the old sibling without confirming no Application still points at it.
- **Image registry** — most overrides pin images to `asia-southeast1-docker.pkg.dev/meesho-devops-admin-0622/admin/sre/<image>` (Meesho's internal Artifact Registry mirror), not upstream Docker Hub.
## Section 2 — Low-level details
### Cluster fleet (helm-overrides/)
Each top-level dir under `helm-overrides/` is one cluster. Two naming conventions:
| Convention | Example | Owner / type |
|------------|---------|--------------|
| `k8s-<bu>-prd-ase1` (and `-prd-ase1c`) | `k8s-central-prd-ase1`, `k8s-supply-prd-ase1`, `k8s-dataengg-prd-ase1` | Standard GKE cluster, BU-owned (central, supply, demand, dataengg, datascience, dengspark, dscispark, dsgpu, farmiso, ml-platform, admin, sec-admin, devops-admin, central-mqkafka). Project varies per BU (e.g., `meesho-supply-prd`, `meesho-datascience-prd`). All in `asia-southeast1`. |
| `k8s-shared-int-ase1` | (only) | Shared **integration** (pre-prod) cluster. The only non-prod cluster in this repo. |
| `k8s-aurva-prd-ase1` | (only) | Aurva integration. Limited override set (contour-internal, rancher only). |
| `db-<numeric-id>-...` | `db-2516183257845181-c-1204-195038-428` | Auto-named dataplane / data-tier clusters. Override sets are minimal (typically `kube-state-metrics` + `victoria-metrics-agent` only). `fullnameOverride` values use `dbc-<bu>-prd` form (e.g., `dbc-dsci-prd`). |
| `k8s-supply-dev-ase1` | (only) | Dev/sandbox supply cluster. |
Per-cluster READMEs (where present) say: "This folder contains the custom `values.yaml` files organized based on specific cluster names. Each subdirectory corresponds to a particular cluster and holds the configurations for the applications and tools deployed within that cluster."
### Application directory layout (per cluster)
Inside `helm-overrides/<cluster>/`, each subdirectory is an Argo CD Application. Common shapes:
| Layout | Meaning | Example |
|--------|---------|---------|
| `<app>/custom-values.yaml` | Single Helm release; values merged onto a chart from `helm-templates/<chart>` | `argocd/custom-values.yaml`, `etcd/custom-values.yaml`, `contour-internal-0/custom-values.yaml` |
| `<app>/<sub>.yaml` (no custom-values.yaml) | Argo Application's `path:` points here; raw manifests applied | `computeclass/contour-external-cc.yaml`, `elastic-cluster/argo-launch.yaml`, `mimir-distributed/alertmanager_config.yaml`, `external-dns-services/*.yaml` |
| Both | Helm release + sidecar raw manifests | rare; check the matching Application in `devops-infra-argo-config` |
Multiple Contour instances per cluster is the norm — `contour-external`, `contour-external-1`, `contour-internal-0`, `contour-internal-1`, `contour-internal-intra-0`, `contour-internal-intra-1`. Each maps to a different node pool / dedicated node taint or compute class. The mapping per cluster is recorded in `contour-nodeselector-tolerations-summary.md` at the repo root — read before adding/changing a Contour instance.
### Helm chart inventory
| Category | Charts in `helm-templates/` |
|----------|----------------------------|
| Argo / GitOps | `argo-cd`, `argo-cd-green` |
| Ingress / edge | `contour`, `contour-v1.33.3`, `contour-ca-issuer`, `contour-cert-checker`, `ingress-nginx`, `cert-manager`, `external-dns`, `external-secrets` |
| Observability — metrics | `prometheus-node-exporter`, `prometheus-stackdriver-exporter`, `kube-state-metrics`, `kube-events`, `victoria-metrics-{single,cluster,cluster-latest,agent,agent-latest,alert,alert-stateful,alerts-config,auth,mcp}`, `vm-alert-config`, `mimir-distributed`, `pmm`, `telegraf-operator` |
| Observability — logs/traces/profiles | `fluentd`, `loki-distributed`, `tempo-distributed`, `pyroscope`, `alloy`, `opentelemetry-collector`, `opentelemetry-collector-latest`, `opentelemetry-operator`, `elastalert2`, `coroot-node-agent`, `deepfence-console`, `deepfence-router` |
| UI / dashboards | `grafana`, `grafana-edge`, `grafana-mcp`, `kubernetes-dashboard`, `superset`, `uptime-kuma` |
| Workflow / CI/CD | `jenkins`, `jfrog`, `sonarqube`, `sonarqube-old`, `flagger`, `keda`, `keda-2.17.1`, `kyverno`, `loadtester`, `temporal`, `dind`, `canary-bot-gcp`, `paused-container` |
| Networking / DNS | `coredns`, `kube-dns`, `bifrost`, `conntrack-adjuster`, `node-thp-config` |
| Data / search / DB | `clickhouse`, `etcd`, `vault`, `elasticsearch-mcp`, `eck-operator`, `athens-proxy` |
| AI / 3rd-party | `aurva-dataplane`, `deepgram-onprem`, `rancher` |
74 charts total. Each has its own `Chart.yaml`. 19 also have a `Chart.lock` (charts with subchart dependencies that have been resolved with `helm dependency update`). Many of the local "charts" (e.g., `argo-cd/Chart.yaml`) are thin wrappers that declare the upstream chart as a dependency in `Chart.yaml` — the actual templates come from upstream. Others (e.g., `contour/`) carry a full vendored `templates/` tree.
### Manifests (singletons)
| Path | Scope | What it is |
|------|-------|------------|
| `manifests/storageclass/*.yaml` | Cluster-wide | StorageClasses: `pd-standard-retain-dr`, `sc-filestore-standard`, `sc-pd-ssd`, `sc-pd-standard`. Wrong change affects every PVC. |
| `manifests/priorityclass/<cluster>/*.yaml` | Per-cluster | `priorityclass-high.yaml`, `priorityclass-low.yaml` per BU cluster. Affects scheduling priority for every pod that references them. |
| `manifests/jenkins-filestore-caching/{dev,prd}/{pv,pvc}.yaml` | Per-env | Jenkins build cache PV/PVC backed by GCP Filestore. |
| `manifests/jenkins-gcs-caching/{pv,pvc,sc-gcs}.yaml` | Per-env | Jenkins GCS-backed cache. |
| `manifests/jfrog-filestore-data/{dev,prd}/` | Per-env | JFrog data PV/PVC. |
### Git hooks
| Hook | Path | Behavior |
|------|------|----------|
| pre-commit, pre-push | `pre-commit-scripts/runner.sh` | Forks every other `*.sh` in the same dir in parallel; fails the commit if any fails. |
| pre-commit, pre-push | `pre-commit-scripts/trufflehog-hook.sh` | Runs `trufflehog git file://. --since-commit HEAD --branch=$(git rev-parse --abbrev-ref HEAD) --json --results=verified`. On a verified hit: prints the finding and POSTs metadata (no raw secret) to `https://observe.meeshogcp.in/api/webhook`. Exit 1 blocks the commit. **Never bypass.** |
| pre-commit, pre-push | `pre-commit-scripts/cac-validate.sh` | Gated on `configs/` paths in the staged diff. This repo has no `configs/`, so it always early-exits. Documented for completeness. |
| pre-commit, pre-push | `pre-commit-scripts/yaakhook.sh` | Gated on `api-collections/` paths. This repo has none — early-exits. |
| post-commit | `post-commit-scripts/runner.sh``commit-metric.sh` | Two-phase: synchronous `start` writes a temp file with commit hash + repo info, spawns detached `continue` background process. `continue` polls the local Cursor SQLite DB up to 120 s for `aiCodeTracking.recentCommit.commitHash` to match HEAD, then POSTs the AI line-edit metrics to `https://cursor-server.meeshogcp.in/api/v1/add-commit-metrics`. Skips rebase/merge/cherry-pick commits. Always exits 0 — never blocks the hook. |
### Configuration touch points
There is no application config to touch. The only env-equivalent layer is `helm-overrides/<cluster>/<app>/custom-values.yaml` — every cluster × application pair is its own configuration unit. The CAC API at `https://observe.meeshogcp.in/api/cac/repos` would gate config schema validation, but this repo isn't on that allowlist.
### Critical invariants & gotchas
- **`helm-templates/` is mostly upstream code.** Most charts here are `helm pull`-ed copies of upstream charts (Bitnami, ArgoProj, VictoriaMetrics, Grafana). Editing a `templates/*.yaml` inside one of these is editing upstream — easy to forget on the next chart bump. Treat `helm-templates/<chart>/` as read-only unless you are explicitly forking; if you fork, document why in the chart's `README.md`.
- **Each cluster is unique on `nodeSelector` / `tolerations` / `computeClass`.** See `contour-nodeselector-tolerations-summary.md` at the repo root. GKE Autopilot clusters use `cloud.google.com/compute-class` keys; standard clusters use `dedicated:` keys. Copying a values block from one cluster to another without rewriting these schedules pods on the wrong nodes — or pending forever.
- **Versioned siblings are intentional, not duplicates.** `argo-cd` vs `argo-cd-green`, `contour` vs `contour-v1.33.3`, `keda` vs `keda-2.17.1`, `opentelemetry-collector` vs `-latest`, `sonarqube` vs `sonarqube-old`. Don't "consolidate" them. They support blue-green chart upgrades — both versions may be live during a migration.
- **`fullnameOverride` is load-bearing in dataplane overrides.** `db-*` cluster values use `fullnameOverride: <kind>-dbc-<bu>-prd` to keep release names stable across re-installs. Don't change these — Service DNS, PVC binding, and Argo Application names depend on them.
- **Argo CD reconciles from `main`.** A merge to `main` is a deploy. There is no staging branch — review the PR as if it ships to production, because it does.
- **`devops-infra-argo-config` is the routing layer.** A new chart in `helm-templates/` does nothing until an `Application` referencing it is added to the sister repo. A new cluster directory in `helm-overrides/` does nothing until an `ApplicationSet` covers it. Pair the two-repo change.
<!-- meesho-init: generated-at=2026-05-05T17:31:45Z base-sha=debd20fcc510e19bfe3123a08247dde39790643b+dirty -->
+123
View File
@@ -0,0 +1,123 @@
# AGENT_BOUNDARIES.md
> **Scope:** operations agents may perform on the `devops-infra-helm-charts` repo.
> **Companion docs:** [SANCTITY_RULES.md](SANCTITY_RULES.md) (hard rules), [coding-guidelines/helm-values.md](coding-guidelines/helm-values.md) (style).
This document classifies every operation in this repo into Layer 1 / 2 / 3 with explicit blast radius and approval requirements. **An agent operating in this repo MUST consult this file before any write.**
---
## The 3-Layer Model (recap)
| Layer | Agent action | Safety gate |
|-------|--------------|-------------|
| **Layer 1 — Agent-Writable** | Generate diff, open PR. Do **not** apply directly to clusters. | PR review + Argo CD UI Sync click. |
| **Layer 2 — Agent-Readable (Advisory)** | Research, analyse, recommend. Human executes. | Human review + manual execution. |
| **Layer 3 — Agent-Blocked** | Refuse the write. Explain why. Cite this doc. | None applicable. |
---
## Per-operation classification
### Layer 1 — Agent-Writable (this repo's normal operating range)
All edits land via PR. A merge to `main` is then reconciled by Argo CD per cluster — most infra Applications use manual sync ([ADR-A5](../../wiki/analyses/ADR-A5-manual-sync-default-for-infra.md)), so the workload deploy is a separate human Sync click.
| Operation | File(s) touched | Blast radius | Required approvers |
|-----------|-----------------|--------------|--------------------|
| Edit `custom-values.yaml` for one app on one cluster | `helm-overrides/<cluster>/<app>/custom-values.yaml` | One Helm release on one cluster | Service / app owner |
| Add a new app under an existing cluster | new dir + files in `helm-overrides/<cluster>/<app>/` | One new release | App owner + cluster owner; pair with Argo `Application` PR in sister repo |
| Add a sidecar raw manifest alongside an existing app | `helm-overrides/<cluster>/<app>/<extra>.yaml` | Adds Kubernetes resources rendered alongside the Helm release | App owner |
| Add a new override file under an existing app dir | new file in `helm-overrides/<cluster>/<app>/` | Layered into the same release if the Argo Application's `valueFiles` covers it | App owner |
| Append to an existing chart's `Chart.yaml` `dependencies[]` | `helm-templates/<chart>/Chart.yaml` + refresh `Chart.lock` via `helm dependency update` | Affects every consumer of that chart | Platform team |
| Bump a `dependencies[].version` in `Chart.yaml` | `helm-templates/<chart>/Chart.yaml` + `Chart.lock` | Same | Platform team — see [update-chart-version](../platform/procedures/update-chart-version.md) |
| Add a new chart sibling for blue-green migration | new dir `helm-templates/<chart>-<variant>/` | Migration target only; old sibling stays live | Platform team — see [blue-green-chart-migration](../platform/procedures/blue-green-chart-migration.md) |
| Edit the per-cluster Contour scheduling matrix | `contour-nodeselector-tolerations-summary.md` | Documentation; no runtime effect | Platform team |
### Layer 1 — HIGH RISK (write allowed, but require explicit approval and detailed rationale in PR)
| Operation | Why it's high risk |
|-----------|--------------------|
| Edit `helm-templates/<chart>/templates/` or `helm-templates/<chart>/values.yaml` | Most charts here are vanilla upstream pulled via `helm pull`. Edits silently fork the chart and get clobbered on the next upstream sync. **Only allowed if the fork is intentional and documented in that chart's `README.md` — see [fork-upstream-chart](../platform/procedures/fork-upstream-chart.md).** |
| Delete a versioned sibling chart (`<chart>-green`, `<chart>-vX.Y.Z`, `<chart>-latest`, `<chart>-old`) | The variant is a blue-green migration target. Both versions may be live simultaneously. **Confirm zero references in `github.com/Meesho/devops-infra-argo-config` before deleting.** |
| Edit `manifests/storageclass/*.yaml` | Cluster-wide singleton; affects every PVC. **Platform-team review required.** |
| Edit `manifests/priorityclass/<cluster>/*.yaml` | Affects scheduling priority for every pod that references the class. Platform-team review. |
| Edit `manifests/{jenkins-filestore-caching,jenkins-gcs-caching,jfrog-filestore-data}/{dev,prd}/` | Per-env stateful PV/PVCs; wrong reclaim policy can drop CI build caches or JFrog binary data. Platform-team review. |
| Add a new cluster directory under `helm-overrides/` | Creates a new deployment target. **Pair with the cluster's `ApplicationSet` change in the sister repo. Per-cluster `nodeSelector` / `tolerations` / `computeClass` MUST be written from scratch, not copied from another cluster ([SANCTITY_RULES R5](SANCTITY_RULES.md)).** |
| Change `fullnameOverride` in any `custom-values.yaml` | Service DNS, PVC binding, ConfigMap/Secret references, and downstream Argo Application names depend on it being stable. **Almost always wrong to touch.** |
| Bulk find-replace across cluster directories ("normalise" labels, image tags, etc.) | The whole point of per-cluster overrides is divergence. Cross-cluster cleanup is its own PR with its own scope ([SANCTITY_RULES R6](SANCTITY_RULES.md)). |
| Pin an image tag to a registry outside `asia-southeast1-docker.pkg.dev/meesho-devops-admin-0622/admin/sre/` | Production overrides go through Meesho's Artifact Registry mirror. Direct Docker Hub / Quay pulls are a supply-chain and rate-limit risk. |
### Layer 2 — Agent-Readable (advisory only)
Some operations a user might ask for touch systems an agent can analyse but not change.
| Operation | Why advisory |
|-----------|--------------|
| "Sync `<release>` now in Argo CD" | The Sync click is intentional human action. **Recommend the command (`argocd app sync <name>`) or the Argo CD UI path; do not execute.** |
| "Restart pods for `<release>`" | kubectl operation against a workload cluster. Recommend `kubectl rollout restart deploy/<name> -n <ns>`; do not execute. |
| "Why is this pod pending?" | Live cluster state. Recommend `kubectl describe pod` and walk [pod-pending-scheduling.md](../platform/runbooks/pod-pending-scheduling.md); do not infer. |
| "Why did the chart not render?" | Reproduce locally with `helm template`; recommend the fix. Do not push without PR. |
| "Add an alert rule for `<service>`" | Alert rules are in `victoria-metrics-alert*` chart values *here*, but routing/notifier config is elsewhere (Pulse / Slack webhook secrets). Recommend the right file; pair with the routing change. |
| "What's broken on the GKE cluster itself?" | Cluster-level GCP / GKE issues are out of scope for this repo. Recommend the Terraform repo or the platform team. |
| "Reconcile the Terraform drift for the cluster" | Out of scope — that's `terraform-gcp-infra`. Refuse + redirect. |
### Layer 3 — Agent-Blocked (refuse + explain)
| Operation | Why blocked | What would unblock |
|-----------|-------------|--------------------|
| Hand-edit `repository.yaml` | Owned by `registry-bootstrap` automation; manual edits are overwritten on the next bootstrap run. | Update the upstream registry that feeds registry-bootstrap. |
| Bypass pre-commit hooks (`--no-verify`, `git commit -n`, removing the hook) | TruffleHog is the last-line secret scan. ([SANCTITY_RULES R4](SANCTITY_RULES.md)) | If a hit is a known false positive, confirm with the platform/security team in writing first. |
| Push directly to `main` | Branch protection. ([SANCTITY_RULES R1](SANCTITY_RULES.md)) | (Never legitimate.) |
| Force-push to `main` | Same. | (Never legitimate.) |
| Run `helm install`, `helm upgrade`, or `kubectl apply` against any workload cluster | This is GitOps; in-cluster mutation creates drift Argo CD will reconcile away. | Use the Argo CD UI Sync flow, or the cluster's incident-response toolset. |
| Curl / probe / interact with `int.meesho.int`, `prd.meesho.int`, `int.mrouter.int`, `prd.mrouter.int`, or any workload-traffic `*.meeshogcp.in` host | Production traffic surfaces. ([SANCTITY_RULES R3](SANCTITY_RULES.md)) | (Pre-commit hook telemetry to `observe.meeshogcp.in` is automated; that is hook infrastructure, not agent action.) |
| Edit Argo `Application` / `ApplicationSet` manifests | They live in `github.com/Meesho/devops-infra-argo-config`. | Open a PR there. |
| Modify a chart whose `helm-templates/<chart>/` is vanilla upstream, without a documented fork rationale | An accidental fork is silently clobbered on the next sync. | Follow [fork-upstream-chart](../platform/procedures/fork-upstream-chart.md) and document the fork in the chart's `README.md`. |
| Copy a `custom-values.yaml` from one cluster to another verbatim | Per-cluster `nodeSelector` / `tolerations` / `computeClass` differ. ([SANCTITY_RULES R5](SANCTITY_RULES.md)) | Author the override from scratch using the per-cluster matrix in [contour-nodeselector-tolerations-summary.md](../../contour-nodeselector-tolerations-summary.md) and sibling files. |
---
## Cross-cuts: things to verify on **every** Layer 1 PR
Pre-commit hooks here are minimal — TruffleHog covers secrets; CAC and Yaak are no-ops because their gating paths don't exist in this repo. The agent is the next line of defence. On every PR, mentally run this checklist:
1. **Surgical scope.** The PR touches only the cluster × app the task asked for. No drive-by edits to neighbours.
2. **Per-cluster scheduling rewritten, not copied.** If the change involves `nodeSelector` / `tolerations` / `computeClass`, every cluster has its own topology. Copy-and-rename is the most common silent bug. ([contour-nodeselector-tolerations-summary.md](../../contour-nodeselector-tolerations-summary.md))
3. **`fullnameOverride` unchanged.** Unless the explicit headline of the PR is a release-name migration.
4. **Image tags pin to Meesho's GAR mirror** (`asia-southeast1-docker.pkg.dev/meesho-devops-admin-0622/admin/sre/<image>`), not Docker Hub.
5. **Versioned siblings preserved.** A delete or rename of a `<chart>-green` / `-latest` / `-vX.Y.Z` directory only proceeds after grepping `github.com/Meesho/devops-infra-argo-config` for references.
6. **Chart.yaml + Chart.lock move together.** A `dependencies[].version` bump without a refreshed lockfile is incomplete.
7. **Sister repo paired (where required).** A new app under a cluster needs a matching `Application` in the sister repo. A new cluster directory needs a matching `ApplicationSet` (or per-cluster Application set) in the sister repo. Note the pairing in the PR description.
8. **No `*` or `latest` image tags introduced.** Argo CD's manual-sync default does not rescue you from a pulled-out-from-under-you image.
9. **`manifests/` left alone unless the PR's headline says so.** `storageclass/` and `priorityclass/<cluster>/` are cluster-wide singletons.
10. **TruffleHog passed.** Never bypass.
---
## Approval requirements summary
| Change category | Reviewer required | CMR required? |
|-----------------|-------------------|---------------|
| Single-cluster `custom-values.yaml` edit (no scheduling, no `fullnameOverride`) | App owner | Per BU policy |
| Add a new app override under an existing cluster | App owner + cluster owner | **Yes** |
| Add a new cluster directory | Platform team | **Yes** |
| `Chart.yaml` `dependencies[].version` bump | Platform team | **Yes** for prod-fleet charts (Argo CD, Contour, VictoriaMetrics, ingress) |
| Intentional fork of `helm-templates/<chart>/templates/` | Platform team — multi-reviewer | **Yes** |
| Delete a versioned chart sibling | Platform team — confirm zero sister-repo references | **Yes** |
| Edit `manifests/storageclass/` or `priorityclass/<cluster>/` | Platform team | **Yes** |
| Pre/post-commit hook script change | Platform team + security (if hook scope changes) | Per CMR matrix |
| `fullnameOverride` change | Platform team — multi-reviewer | **Yes** — emergency-only |
CMR = Change Management Request. Per Meesho process; not enforced in-repo, applied at org level.
---
## Escalation
If a request falls outside this matrix or you can't classify it cleanly:
1. Refuse the write.
2. Cite this document + the row that matches (or explain why no row matches).
3. Suggest the human asks the platform team or files a CMR.
4. Do not improvise around the boundary.
+122
View File
@@ -0,0 +1,122 @@
# SANCTITY_RULES.md
> Non-negotiable rules for the `devops-infra-helm-charts` repo.
> Read alongside [AGENT_BOUNDARIES.md](AGENT_BOUNDARIES.md) (per-operation Layer map) and [coding-guidelines/helm-values.md](coding-guidelines/helm-values.md) (style).
These are the rules whose violation is a process incident, not a clever shortcut. Each one is the result of a real failure mode (or proximity to one).
---
## R1 — `main` is production
Argo CD on every cluster reconciles from `main`. There is no staging branch. A merge is a deploy event.
- **No experimentation on `main`.** Always work on a feature/fix branch and open a PR.
- **No force-push to `main`** (enforced at GitHub org level).
- **No "I'll just amend that" after merge.** A new PR is the only path forward.
## R2 — Sister repo is the routing layer; this repo is the values layer
`devops-infra-helm-charts` holds *what gets installed and with what values*. `github.com/Meesho/devops-infra-argo-config` holds *where it gets routed* (the Argo `Application` / `ApplicationSet` manifests).
- **A new chart in `helm-templates/` does nothing** until an `Application` referencing it lands in the sister repo.
- **A new cluster directory in `helm-overrides/` does nothing** until an `ApplicationSet` (or per-cluster Application set) covers it.
- **Pair the two-repo change.** Cite the sister-repo PR in the description here, and vice versa.
## R3 — Production traffic surfaces are off-limits
Agent-initiated requests to `int.meesho.int`, `prd.meesho.int`, `int.mrouter.int`, `prd.mrouter.int`, and workload `*.meeshogcp.in` services are forbidden. Any accidental call can affect live traffic or data.
- **Never `curl`, `WebFetch`, query, or otherwise probe** these endpoints.
- The pre-commit hook telemetry endpoints (`observe.meeshogcp.in/api/webhook`, `cursor-server.meeshogcp.in/api/v1/...`) are *automated hook infrastructure*, not agent-initiated traffic. They are not a precedent for agent calls.
## R4 — Pre-commit hooks must pass
`pre-commit-scripts/runner.sh` invokes TruffleHog (verified-secret scan with webhook telemetry). CAC and Yaak hooks exist but are no-ops here (their gating paths — `configs/` and `api-collections/` — don't exist in this repo). TruffleHog is the last-line secret scan.
- **Never bypass** with `--no-verify`, `git commit -n`, or by removing the hook.
- **Never weaken a hook to "just get this through"** — fix the upstream cause.
- A verified TruffleHog hit means a secret is staged. Real secrets belong in `external-secrets` (per-cluster), backed by GCP Secret Manager / Vault — not in `custom-values.yaml`.
## R5 — Per-cluster scheduling is bespoke; never copy across clusters
Each cluster has its own node-pool topology. Some clusters use GKE Autopilot's `cloud.google.com/compute-class:` keys (`k8s-central-prd-ase1`, `k8s-dsgpu-prd-ase1`, `k8s-shared-int-ase1`); standard clusters use `dedicated:` keys. Per-Contour-instance, per-cluster mappings are recorded in [contour-nodeselector-tolerations-summary.md](../../contour-nodeselector-tolerations-summary.md).
- **Never copy `nodeSelector` / `tolerations` / `computeClass` blocks between clusters** without rewriting them from scratch against the destination cluster's topology.
- **Always read the matrix** before editing any Contour values; cross-reference sibling cluster files for non-Contour scheduling.
- Wrong values strand pods on wrong nodes or leave them `Pending` indefinitely.
## R6 — Surgical edits only
The repo has ~30 cluster directories × dozens of apps each. The whole point of per-cluster overrides is divergence — accumulated, deliberate, often for tiered traffic or specialised hardware.
- **Never "normalise" values across clusters in the same PR as a feature change.** Cross-cluster clean-ups are their own PRs with their own scope and CMRs.
- **Never auto-update labels, image tags, or comments** on apps you weren't asked to touch.
- **One change-type per PR.** Reviewer cognition matters; rollback granularity matters.
## R7 — `helm-templates/<chart>/` is mostly upstream
Most charts here are vanilla upstream pulled via `helm pull`. The local `Chart.yaml` is often a thin wrapper that declares the upstream chart as a dependency. Editing a `templates/*.yaml` or the chart's own `values.yaml` silently forks the chart, and the fork is clobbered on the next upstream sync.
- **Never edit `helm-templates/<chart>/templates/` or `values.yaml` casually.** If a fork is intentional, follow [fork-upstream-chart](../platform/procedures/fork-upstream-chart.md) and document the reason in the chart's `README.md`.
- **Never bump `Chart.yaml` `dependencies[].version`** without (a) reading the upstream changelog, (b) running `helm dependency update` to refresh `Chart.lock`, and (c) calling out the bump in the PR description.
## R8 — Versioned chart siblings stay live during migrations
`<chart>``<chart>-green` (blue-green), `<chart>``<chart>-vX.Y.Z` (pinned upgrade target), `<chart>``<chart>-latest` (work-in-progress), `<chart>``<chart>-old` (retired but still referenced). Both directories may be referenced by Argo Applications during the migration window.
- **Never delete a versioned sibling** without confirming zero references in `github.com/Meesho/devops-infra-argo-config`.
- **Never "consolidate" siblings** into one chart in a maintenance PR. The split is intentional ([ADR-A2](../../wiki/analyses/ADR-A2-blue-green-sibling-pattern.md)).
## R9 — `fullnameOverride` is load-bearing
Helm's `fullnameOverride` controls the name of every released Service, Deployment, StatefulSet, ConfigMap, Secret, and PVC. Service DNS, PVC binding, ConfigMap references in other apps, and Argo Application names downstream all depend on it being stable.
- **Never change `fullnameOverride`** in any `custom-values.yaml`.
- A release-name migration is its own headline-of-the-PR change with platform-team approval, a documented before/after map, and an explicit reason.
## R10 — `manifests/` is cluster-wide singletons
`manifests/storageclass/*.yaml` is repo-global; a wrong StorageClass affects every PVC on every cluster that consumes it. `manifests/priorityclass/<cluster>/*.yaml` is per-cluster but cluster-wide; a wrong PriorityClass changes scheduling priority for every pod that references it.
- **Never edit `manifests/storageclass/`** or `manifests/priorityclass/<cluster>/` without platform-team review.
- **Never delete a StorageClass referenced by an existing PVC** — Kubernetes will not remove the StorageClass while bindings remain, but new PVCs will fail to provision.
## R11 — Image tags go through Meesho's Artifact Registry mirror
Production overrides pin images to `asia-southeast1-docker.pkg.dev/meesho-devops-admin-0622/admin/sre/<image>`, not upstream Docker Hub or Quay. The mirror exists for supply-chain control and rate-limit isolation.
- **Never introduce a Docker Hub / Quay / GCR / ECR upstream tag** in a production override.
- **Never use `:latest` or unpinned tags** in production overrides; an Argo CD reconcile is not the same as a controlled rollout.
## R12 — `repository.yaml` is automation-owned
Generated by `registry-bootstrap`. Hand edits will be silently overwritten on the next bootstrap run.
- **Never hand-edit `repository.yaml`.** If owner data is wrong, fix it in the upstream registry that feeds registry-bootstrap.
## R13 — Branch protection trumps everything
Direct push to `main` is blocked at the GitHub org level. PRs go through code review.
- **Never propose workflows that bypass branch protection.** If a hotfix is genuinely urgent, the path is "open a PR with a `hotfix/*` branch and request emergency review," not "force-push to main."
## R14 — Pre-existing schema/label drift is not yours to fix
Some clusters have inconsistencies in label values, indentation, key ordering, or comment style — accumulated technical-debt items. Some apps lack values keys their newer siblings have. Some clusters use long BU names (`supply`) while others use short (`supl`).
- **Never normalise label or BU values in unrelated PRs.** Cross-cutting clean-ups are their own PRs with their own scope and CMRs.
- **Never reformat a YAML file in passing.** Diffs full of indentation churn drown out the real change.
---
## What "non-negotiable" means
Each rule above has a documented reason and is the result of a real failure mode (or proximity to one). If you find yourself wanting to break a rule, the path is:
1. Write up the case in a doc (or PR description) explaining what would change and why.
2. Loop in the platform team for review.
3. If the rule should change, change *the rule first* in this file (with a PR to update it), then act.
4. If the rule should not change, find another way.
A merge that violates a rule here is a process incident, not a clever shortcut.
+82
View File
@@ -0,0 +1,82 @@
> Per AI Blitz Plan §global. Layer: 1. Repo: devops-infra-helm-charts.
# Agent Operations Guide
A meta-guide for any AI agent (or human contributor wearing the agent hat) doing work in this repo. Read this first; it tells you which other docs to load and in what order.
## Pre-flight (always, every task)
Before reading any task-specific file:
1. **Read the repo-root `CLAUDE.md`.** It is the authoritative source for the NEVER-DO list, cluster naming, versioned siblings, multi-Contour pattern, and the Layer constraint summary. Everything else in `docs/` derives from it.
2. **Read [AGENT_BOUNDARIES.md](./AGENT_BOUNDARIES.md)** to confirm which Layer the operation lives in.
3. **Read [SANCTITY_RULES.md](./SANCTITY_RULES.md)** to confirm the operation is not on the don't-touch list.
4. **Read [`wiki/entities/DevOps Infra Helm Charts.md`](../../wiki/entities/DevOps%20Infra%20Helm%20Charts.md)** for the conceptual model (this repo as values store; sister repo as routing layer).
5. **Skim [`docs/architecture.md`](../architecture.md)** if the task touches more than one chart or cluster.
If the task targets a specific chart family (Contour, Vault, Argo CD, observability stack), also load the relevant coding guideline before editing:
- [coding-guidelines/helm-values.md](./coding-guidelines/helm-values.md) — values-file conventions
- [coding-guidelines/argocd.md](./coding-guidelines/argocd.md) — Argo CD interaction model
- [coding-guidelines/observability.md](./coding-guidelines/observability.md) — VM / Mimir / Loki / Tempo / Grafana
## Authoring loop
The supported edit path for almost every task in this repo:
1. **Branch off `main`.** Never push to `main`. The branch name should describe the cluster × app being touched.
2. **Edit the single targeted file** under `helm-overrides/<cluster>/<app>/custom-values.yaml` (or sibling `<extra>.yaml`). No drive-by edits to other apps in the same directory. No cross-cluster "normalization" in the same PR.
3. **Dry-run with `helm template`** to confirm the values render. Use the command from the root `CLAUDE.md` Quick reference table:
```
helm template <release> helm-templates/<chart> -f helm-overrides/<cluster>/<app>/custom-values.yaml
```
4. **Commit.** The pre-commit hooks run automatically:
- **TruffleHog** — secret scan, blocking. NEVER bypass. See [claude/08-pre-commit-and-hooks.md](../../claude/08-pre-commit-and-hooks.md).
- CAC and Yaak hooks are gated/no-op on this repo.
5. **Open a PR.** Pair with a sister-repo PR if a new Argo Application is being introduced.
6. **Reviewer + Argo CD UI Sync are the safety gates.** Once the PR is merged to `main`, Argo CD on the target cluster reconciles. Per-cluster `syncPolicy` (auto vs manual) is set in the sister repo `Meesho/devops-infra-argo-config`, not here.
See [platform/procedures/onboard-app-to-cluster.md](../platform/procedures/onboard-app-to-cluster.md) and [platform/procedures/update-chart-version.md](../platform/procedures/update-chart-version.md) for two of the most common authoring loops.
## When to refuse
Refuse the operation outright if it falls into one of these categories. Cite [SANCTITY_RULES.md](./SANCTITY_RULES.md) in the refusal:
- Direct push to `main`, or any `--force` push.
- Bypassing the pre-commit hook (`--no-verify`, `git commit -n`).
- Curl / probe / query against any production endpoint (`*.meesho.int`, `*.mrouter.int`, `*.meeshogcp.in`).
- Edit to `repository.yaml` (owned by `registry-bootstrap`).
- Edit to an Argo `Application` / `ApplicationSet` manifest (lives in sister repo).
- Cross-cluster copy-paste of `nodeSelector` / `tolerations` / `computeClass` without rewrite.
- Deletion of a versioned-sibling chart without confirming zero sister-repo references.
## When to escalate
If the operation is potentially valid but exceeds Layer-1 authority — chart fork, dep bump with breaking changes, StorageClass/PriorityClass edit, Vault HA work — stop and escalate per [escalation-matrix.md](./escalation-matrix.md). The escalation matrix maps each situation to an owner and a channel.
## Tooling commands (cheat sheet)
The repo-root `CLAUDE.md` Quick reference table is the source of truth. Reproduced here for convenience:
| Task | Command |
|------|---------|
| Install pre-commit hooks | `pre-commit install --hook-type pre-commit --hook-type pre-push --hook-type post-commit` |
| Re-run pre-commit on staged changes | `pre-commit run` |
| Render a chart locally | `helm template <release> helm-templates/<chart> -f helm-overrides/<cluster>/<app>/custom-values.yaml` |
| Refresh subchart deps | `helm dependency update helm-templates/<chart>` |
| Diff against live release | `helm diff upgrade <release> helm-templates/<chart> -f helm-overrides/<cluster>/<app>/custom-values.yaml` |
| Lint a chart | `helm lint helm-templates/<chart>` |
| Find which clusters override an app | `find helm-overrides -maxdepth 2 -type d -name '<app>'` |
## Output discipline
- Generate diffs and PRs; do not apply directly to clusters. In-cluster mutation is incident response, not authoring.
- Surgical edits only. Touch the cluster × application asked for; leave the rest.
- Cross-link reasoning to ADRs in [`wiki/analyses/`](../../wiki/analyses/) where helpful.
## See also
- [AGENT_BOUNDARIES.md](./AGENT_BOUNDARIES.md)
- [SANCTITY_RULES.md](./SANCTITY_RULES.md)
- [escalation-matrix.md](./escalation-matrix.md)
- [coding-guidelines/helm-values.md](./coding-guidelines/helm-values.md)
- [../architecture.md](../architecture.md)
+67
View File
@@ -0,0 +1,67 @@
> Per AI Blitz Plan §global. Layer: 1. Repo: devops-infra-helm-charts.
# Coding Guideline — Argo CD interaction model
This repo holds **values** and **cached charts**. It does NOT own Argo CD `Application` or `ApplicationSet` manifests. Those live in the sister repo:
> [`github.com/Meesho/devops-infra-argo-config`](https://github.com/Meesho/devops-infra-argo-config)
A merge to `main` here is a deploy event for every cluster whose Argo Application points at a path in this repo. The Argo `Application` defines the routing (which path on which cluster, sync policy, retry, prune); we define what that path renders to.
## Hard separation
| Concern | Owns it |
|---------|---------|
| `helm-templates/<chart>/` (cached/forked chart) | this repo |
| `helm-overrides/<cluster>/<app>/custom-values.yaml` (per-cluster values) | this repo |
| `manifests/storageclass/`, `manifests/priorityclass/<cluster>/` (singletons) | this repo |
| Argo `Application` (cluster, path, repoURL, targetRevision, destination namespace) | **sister repo** |
| Argo `ApplicationSet` (cluster generators, templating fan-out) | **sister repo** |
| `syncPolicy.automated.{prune,selfHeal}` decision | **sister repo** |
| `syncPolicy.syncOptions` (CreateNamespace, ServerSideApply) | **sister repo** |
| Sync waves / hooks via `argocd.argoproj.io/sync-wave` annotations | this repo (when expressed inside chart templates or raw sidecar manifests) |
## What this means for the agent
- **Never** add or edit a file matching `Application*.yaml` / `ApplicationSet*.yaml` here. If the task asks for one, redirect to the sister repo. See [escalation-matrix.md](../escalation-matrix.md) row 5.
- When introducing a **new app** to a cluster, the change is a **paired PR**: (a) a PR here adding `helm-overrides/<cluster>/<newapp>/custom-values.yaml`, and (b) a PR in the sister repo adding the matching `Application` manifest. Both must merge before the app deploys.
- When introducing a **new cluster**, the paired PR in the sister repo updates the `ApplicationSet` cluster generator. See [../platform/procedures/onboard-new-cluster.md](../../platform/procedures/onboard-new-cluster.md).
- When **removing** an app, deboard the Argo Application first (sister repo), let Argo prune, then remove the override directory here. See [../platform/procedures/deboard-app.md](../../platform/procedures/deboard-app.md).
## Sync policy: where the decision lives
`syncPolicy.automated.prune` and `syncPolicy.automated.selfHeal` live in the sister repo's `Application` spec. Convention on the platform:
- **Manual sync default** for infra components on prod clusters. Sync is a deliberate human click after a merge. Rationale documented in [`wiki/analyses/ADR-A5-manual-sync-default-for-infra.md`](../../../wiki/analyses/ADR-A5-manual-sync-default-for-infra.md).
- Auto-sync is reserved for low-risk leaf components (e.g., `kube-state-metrics`, monitoring agents) where reconciliation drift is benign.
Agents editing values here should assume **the sync click is the safety gate**. A merged PR is not yet deployed.
## Validating values before merge
The agent's responsibility is that the values **render** correctly. Argo CD will materialize the rendered output via `helm template`-equivalent server-side. Use the same command locally:
```
helm template <release> helm-templates/<chart> \
-f helm-overrides/<cluster>/<app>/custom-values.yaml
```
If the chart has subchart dependencies (`Chart.yaml` `dependencies:`), run `helm dependency update helm-templates/<chart>` before templating, otherwise render will fail with `found in Chart.yaml, but missing in charts/ directory`.
For raw-manifest sidecars (`<extra>.yaml` files in the override dir), validate with `kubectl apply --dry-run=client -f <file>`. See [../platform/schemas/raw-manifest-sidecar-schema.md](../../platform/schemas/raw-manifest-sidecar-schema.md).
## Common failure modes
| Symptom | First read |
|---------|-----------|
| `Sync` button click results in `OutOfSync` that won't resolve | [../platform/runbooks/argocd-sync-failure.md](../../platform/runbooks/argocd-sync-failure.md) |
| Pods land but stay `Pending` | [../platform/runbooks/pod-pending-scheduling.md](../../platform/runbooks/pod-pending-scheduling.md) |
| Ingress 5xx after a Contour values change | [../platform/runbooks/ingress-down.md](../../platform/runbooks/ingress-down.md) |
## Cross-references
- Sister repo: [`Meesho/devops-infra-argo-config`](https://github.com/Meesho/devops-infra-argo-config)
- [helm-values.md](./helm-values.md)
- [observability.md](./observability.md)
- [../escalation-matrix.md](../escalation-matrix.md)
- [`wiki/analyses/ADR-A5-manual-sync-default-for-infra.md`](../../../wiki/analyses/ADR-A5-manual-sync-default-for-infra.md)
@@ -0,0 +1,167 @@
# Coding Guidelines — Helm values authoring
> The hard stops live in [../SANCTITY_RULES.md](../SANCTITY_RULES.md); the layer/scope rules in [../AGENT_BOUNDARIES.md](../AGENT_BOUNDARIES.md). This file is "how to write the values YAML well" — style, conventions, and the recurring footguns the linter doesn't catch.
---
## File-level conventions
### Where files go
| Path | Meaning |
|------|---------|
| `helm-overrides/<cluster>/<app>/custom-values.yaml` | The primary Helm values file Argo's `valueFiles` references. **Default name. Do not invent alternatives.** |
| `helm-overrides/<cluster>/<app>/<extra>.yaml` | Sidecar raw manifests applied alongside the Helm release. Common shapes: `computeclass/<x>-cc.yaml`, `external-dns-services/<svc>.yaml`, `elastic-cluster/argo-launch.yaml`, `mimir-distributed/alertmanager_config.yaml`. |
| `helm-templates/<chart>/Chart.yaml` | Chart manifest; usually a thin wrapper declaring an upstream dep. |
| `helm-templates/<chart>/values.yaml` | The chart's own defaults — rarely edited; treat as upstream. |
| `helm-templates/<chart>/templates/` | Manifest templates — vanilla upstream unless intentionally forked. **Don't edit casually.** |
### Cluster directory naming
The cluster directory's name is a contract — it must match the Kubernetes cluster name registered in Argo CD. Conventions:
| Pattern | Use |
|---------|-----|
| `k8s-<bu>-prd-ase1` | Standard GKE prod cluster, BU-owned (AWS-style naming retained). |
| `k8s-<bu>-prd-ase1c` | GCP zone-c twin. |
| `k8s-shared-int-ase1` | Shared int (pre-prod) cluster. The only non-prod cluster. |
| `k8s-aurva-prd-ase1` | Aurva integration. |
| `db-<numeric-id>-...` | Auto-named dataplane / data-tier clusters. Minimal override sets (typically `kube-state-metrics` + `victoria-metrics-agent`). |
| `k8s-supply-dev-ase1` | The lone dev/sandbox cluster. |
### App directory naming
Inside `helm-overrides/<cluster>/`, each subdirectory is one Argo Application = one Helm release.
- One Helm release per directory.
- Multiple Contour instances per cluster is the norm — `contour-external`, `contour-internal-0`, `contour-internal-1`, `contour-internal-intra-{0,1}`. Each maps to a different node pool / dedicated taint or compute class. **They are separate releases — don't merge them.**
- Versioned siblings (`argo-cd``argo-cd-green`, `keda``keda-2.17.1`) live as parallel directories under `helm-templates/`, but their per-cluster overrides typically live under one directory until the migration cuts over. See [blue-green-chart-migration](../../platform/procedures/blue-green-chart-migration.md).
---
## Field-level conventions (`custom-values.yaml`)
### Image references
- **Always pin images to Meesho's Artifact Registry mirror** for production:
```yaml
image:
registry: asia-southeast1-docker.pkg.dev
repository: meesho-devops-admin-0622/admin/sre/<image>
tag: <semver-or-sha>
```
- **Never use `:latest` or unpinned tags** in production overrides.
- **Never reference Docker Hub, Quay, GCR upstream, or ECR directly** in a production override. Mirror it via the platform team's image-pull workflow first.
### `fullnameOverride`
- **Set it once, never change it.** Service DNS, PVC binding, ConfigMap references, and downstream Argo Application names depend on stability. ([SANCTITY_RULES R9](../SANCTITY_RULES.md))
- For dataplane (`db-*`) clusters, the convention is `fullnameOverride: <kind>-dbc-<bu>-prd` (e.g. `kube-state-metrics-dbc-dsci-prd`).
- For BU clusters, omit `fullnameOverride` unless the chart's default name collides with another release in the same namespace.
### `nameOverride`
Almost never needed. Helm's `<release>-<chart>` naming is usually fine.
### Replica counts and HPA bounds
- Read the chart's defaults before specifying replicas. Some charts have HPA-managed replicas that conflict with `replicaCount`.
- For HPA-managed releases, set `minReplicas` and `maxReplicas` *and* leave `replicaCount` unset (or set to `null`).
- Don't lower `minReplicas` to zero unless the workload genuinely scales-from-zero.
### Resource requests and limits
- **Always set `resources.requests`** for production releases. Without requests, the scheduler treats the pod as best-effort.
- **Set `resources.limits`** unless the chart documentation explicitly recommends omitting them (some sidecars deliberately go limit-less).
- **Don't copy resources from another cluster.** Workload sizing is per-traffic-tier; the supply prd cluster's Contour requests are not the demand prd cluster's.
### `nodeSelector`, `tolerations`, `affinity`, `topologySpreadConstraints`
The single biggest source of silent mis-deploys. Per [SANCTITY_RULES R5](../SANCTITY_RULES.md):
| Cluster type | Key style | Example |
|--------------|-----------|---------|
| GKE Autopilot (`k8s-central-prd-ase1`, `k8s-dsgpu-prd-ase1`, `k8s-shared-int-ase1`) | `cloud.google.com/compute-class` | `nodeSelector: {cloud.google.com/compute-class: contour-internal-0-cc}` |
| Standard GKE | `dedicated:` | `nodeSelector: {dedicated: contour-internal-0}` |
| Most others | `dedicated:` | same |
Cross-reference [`contour-nodeselector-tolerations-summary.md`](../../../contour-nodeselector-tolerations-summary.md) for the per-cluster Contour matrix. For non-Contour apps, copy from a sibling app on the *same* cluster, not from the same app on a *different* cluster.
### Probes
- Always set `livenessProbe` and `readinessProbe` for any long-running container.
- For workloads that take >30 s to warm (Jenkins, JFrog, ClickHouse), bump `initialDelaySeconds` accordingly — not the timeout, not the period.
- A `startupProbe` is the right tool for slow-warm containers; don't fight it with a 600s `initialDelaySeconds` on `livenessProbe`.
### Persistence
- StorageClass references go through the cluster-wide singletons in `manifests/storageclass/`: `pd-standard-retain-dr`, `sc-filestore-standard`, `sc-pd-ssd`, `sc-pd-standard`. **Never reference a StorageClass that doesn't exist in `manifests/storageclass/`.**
- For stateful releases, set `persistence.size` explicitly. Default sizes are rarely right.
- Never enable `persistence.enabled: true` without confirming the StorageClass and its retention/reclaim policy.
### Secrets
- **Never inline secret values** in `custom-values.yaml`. ([SANCTITY_RULES R4](../SANCTITY_RULES.md))
- Reference secrets by name: `existingSecret: <secret-name>`, where the secret is materialised by the per-cluster `external-secrets` app from GCP Secret Manager / Vault.
- Most clusters have an `external-secrets/` override directory; if your release needs a secret, the corresponding `ExternalSecret` lives there.
### Annotations and labels
- **Add labels conservatively.** Most charts already emit sensible label sets (`app.kubernetes.io/name`, etc.).
- For ingress (`Ingress`, `HTTPProxy`, Contour `Service`), `external-dns` annotations and AWS/GCP load-balancer annotations are normal — copy from a sibling on the same cluster.
- **Don't invent label keys.** If you find yourself adding `meesho.com/<something>`, double-check whether the project already has a convention for it.
---
## Field-level conventions (raw sidecar manifests)
For `helm-overrides/<cluster>/<app>/<extra>.yaml` files (no Helm templating, applied as-is):
- One Kubernetes resource per file unless they are tightly coupled.
- Use `apiVersion: v1` etc. — pin the API version explicitly.
- Set `metadata.namespace` (don't rely on the Argo Application's `destination.namespace` for these).
- For `ComputeClass` / `NodeClass` / `BackendConfig` / GKE-specific resources, sample a sibling cluster's existing file before authoring.
- For `external-dns-services/*.yaml`, the `Service` resource carries `external-dns.alpha.kubernetes.io/hostname` annotations — match the cluster's existing DNS pattern.
---
## YAML style
- **2-space indent. No tabs.**
- **Use single quotes for `'*'`** and other glob-like strings; bare strings elsewhere where unambiguous.
- **Trailing newline at EOF.**
- **No `---` document separators** unless you genuinely need multi-document YAML (rare in this repo).
- **Don't comment out fields; remove them.** The repo doesn't use commented-out scaffolding.
- **Preserve key order from siblings.** A reordered file is a noisy diff that drowns the real change.
- **Don't reformat unrelated YAML in passing.** ([SANCTITY_RULES R14](../SANCTITY_RULES.md))
---
## Diff hygiene
When opening a PR:
- **One change-type per PR.** Adding a service should not also "normalise labels on three other apps."
- **Keep diffs minimal.** Don't reformat surrounding YAML.
- **Cite the procedure followed** (link to one of `docs/platform/procedures/*.md`) in the PR description.
- **Show the validation you ran** — `helm template`, `yamllint`, sibling-file diff, the kubectl context you ran a `helm diff` against.
- **Pair the sister-repo PR** (`devops-infra-argo-config`) when adding a new app or cluster — link both.
---
## Common mistakes the hooks do **not** catch
These are the recurring footguns that pre-commit hooks won't flag:
1. **`nodeSelector` / `tolerations` / `computeClass` copied from the wrong cluster.** Pods stay `Pending`, or schedule on the wrong node pool.
2. **`fullnameOverride` modified.** Downstream Service DNS resolves to nothing.
3. **`spec.source.path` in the sister repo's `Application` not updated** to point at the new chart sibling after a blue-green migration.
4. **Image tag pinned to Docker Hub** or Quay instead of the GAR mirror.
5. **`replicaCount` set on an HPA-managed release.** HPA fights the static count.
6. **`persistence.storageClass` referencing a class that doesn't exist** on this cluster — PVC stays `Pending` forever.
7. **`existingSecret` referencing a secret the per-cluster `external-secrets` app doesn't create.** Pods crashloop on missing env.
8. **`Chart.yaml` `dependencies[].version` bumped without `helm dependency update`.** Argo CD will use the lockfile and silently render the old version.
9. **Edits inside `helm-templates/<chart>/templates/`** — silently fork the chart; clobbered on next upstream sync.
10. **Sidecar raw-manifest namespace mismatch** with the Helm release's namespace — orphaned resources.
The agent's job is to be the second pair of eyes on every one of these.
@@ -0,0 +1,78 @@
> Per AI Blitz Plan §global. Layer: 1. Repo: devops-infra-helm-charts.
# Coding Guideline — Observability stack overrides
Conventions for editing values for the observability charts vendored in this repo:
- `victoria-metrics-cluster` and `victoria-metrics-cluster-latest`
- `victoria-metrics-agent` and `victoria-metrics-agent-latest`
- `vmalert`, `victoria-metrics-operator`
- `mimir-distributed`
- `loki`, `loki-distributed`
- `tempo`, `tempo-distributed`
- `grafana`
- `opentelemetry-collector` and `opentelemetry-collector-latest`
- `kube-state-metrics`, `node-exporter`, `metrics-server`
- `kube-prometheus-stack` (Prometheus alert rules)
The observability stack is the most rule-heavy domain in the repo: alert rules drive paging, retention drives storage cost, and label cardinality drives both. Treat values changes as *data-pipeline* changes, not static config.
## Versioned siblings
`*-latest` siblings exist alongside the stable chart for each VictoriaMetrics and OTel collector chart. Both can be live simultaneously during a blue-green migration. When editing, confirm which sibling the target Argo Application points at (sister repo). See [`wiki/analyses/ADR-A2-blue-green-sibling-pattern.md`](../../../wiki/analyses/ADR-A2-blue-green-sibling-pattern.md) and [../platform/procedures/blue-green-chart-migration.md](../../platform/procedures/blue-green-chart-migration.md).
## Cardinality discipline
Series cardinality on VictoriaMetrics / Mimir is the dominant cost driver. Before adding any of the following, ensure the new label is bounded:
- New `extraLabels` / `externalLabels` on `victoria-metrics-agent`.
- New `relabel_configs` that emit a label sourced from a high-cardinality metric source (pod name, request path, user id, request id).
- New scrape targets in `additionalScrapeConfigs`.
If a label can take more than ~few-hundred distinct values, drop it or aggregate before storage.
## PromQL / alert-rule validation
Alert rules live in `kube-prometheus-stack`, `vmalert`, and Mimir ruler config. Before merging:
1. Render with `helm template`:
```
helm template prom helm-templates/kube-prometheus-stack \
-f helm-overrides/<cluster>/kube-prometheus-stack/custom-values.yaml
```
2. Extract the `PrometheusRule` objects and validate PromQL with `promtool check rules <file.yaml>` (Prometheus tooling) or `vmalert -dryRun -rule=<file.yaml>` for vmalert-specific rules.
3. Confirm the rule's `for:` window and `severity` label match the cluster's PagerDuty routing — getting this wrong silently swaps which on-call gets paged.
## Retention and tenancy
- VictoriaMetrics `vmstorage.retentionPeriod` is per-cluster. Increasing it grows the PVC; never increase without confirming PVC headroom and matching PVC `resources.requests.storage`.
- Loki and Mimir multi-tenancy is keyed on the `X-Scope-OrgID` header. Tenant lists live in cluster-specific overrides; do not assume tenants match across clusters.
- Tempo trace retention is set via `compactor.compaction.block_retention`. Default is short (24h48h); long retention is opt-in per cluster.
## Grafana dashboards & datasources
- Datasources are declared in the cluster's `grafana/custom-values.yaml` under `datasources.datasources.yaml`. Pin URLs to in-cluster Service DNS, not external endpoints.
- Dashboards bundled via `dashboardProviders` reference ConfigMaps; uniqueness of `uid` matters for panel-image links and alert dashboards.
## Validation checklist (always)
Before raising a PR that touches an observability chart:
- [ ] `helm template` renders without error.
- [ ] PromQL in any new alert rule passes `promtool check rules`.
- [ ] No new high-cardinality label is added without a bound.
- [ ] Retention / PVC sizing has not been changed silently.
- [ ] If touching a `*-latest` sibling, the matching Argo Application points at it. See [argocd.md](./argocd.md).
## Schema references
- Per-cluster scheduling fields (must be rewritten, never copy-pasted): [../../platform/schemas/custom-values-schema.md](../../platform/schemas/custom-values-schema.md)
- Raw manifest sidecars (e.g., `external-dns-services/*.yaml` for Grafana ingress): [../../platform/schemas/raw-manifest-sidecar-schema.md](../../platform/schemas/raw-manifest-sidecar-schema.md)
- Storage backing for `vmstorage`, `loki` chunks, `tempo` blocks: [../../platform/schemas/storageclass-priorityclass-schema.md](../../platform/schemas/storageclass-priorityclass-schema.md)
## See also
- [helm-values.md](./helm-values.md) — values-file conventions
- [argocd.md](./argocd.md) — Argo CD interaction model
- [../escalation-matrix.md](../escalation-matrix.md)
- [../../platform/runbooks/argocd-sync-failure.md](../../platform/runbooks/argocd-sync-failure.md)
+39
View File
@@ -0,0 +1,39 @@
> Per AI Blitz Plan §global. Layer: 1. Repo: devops-infra-helm-charts.
# Escalation Matrix
Use this table when a task crosses a Sanctity/Boundary line, when blast radius exceeds the agent's authority, or when a request belongs in a different repo. Always escalate **before** writing the change, not after.
Primary owner: **siddharth.pal@meesho.com**
Secondary owner: **samarth.nag@meesho.com**
Owner data is sourced from the repo-root [`repository.yaml`](../../repository.yaml). If owners change, update that file via the `registry-bootstrap` flow; do not edit `repository.yaml` by hand. See [SANCTITY_RULES.md](./SANCTITY_RULES.md) for the don't-touch list and [AGENT_BOUNDARIES.md](./AGENT_BOUNDARIES.md) for layer classification.
## Situation → owner → channel
| # | Situation | Who | Channel | Notes |
|---|-----------|-----|---------|-------|
| 1 | Edit suspected to silently fork an upstream chart (touching `helm-templates/<chart>/templates/` or `values.yaml` of a vanilla-pulled chart) | siddharth.pal | Slack `#devops-infra` + PR review | Document the intentional fork in the chart's `README.md`. See [procedures/fork-upstream-chart.md](../platform/procedures/fork-upstream-chart.md). |
| 2 | Cross-cluster cleanup or "normalization" requested in the same PR as a feature change | siddharth.pal | Slack `#devops-infra` | Refuse in-PR; request a separate cleanup PR. See [SANCTITY_RULES.md](./SANCTITY_RULES.md) §surgical-edits. |
| 3 | TruffleHog flagged a real secret in a staged commit | siddharth.pal + secret owner (BU on-call) | Slack `#sec-incidents` (private) + revoke pipeline | NEVER bypass with `--no-verify`. Rotate the credential, then move it to External Secrets Operator. |
| 4 | Edit to `repository.yaml` requested | siddharth.pal | Slack `#devops-infra` | This file is owned by `registry-bootstrap` automation. Refuse and redirect to that pipeline. |
| 5 | Edit to an Argo CD `Application` / `ApplicationSet` manifest requested | siddharth.pal | PR against sister repo `Meesho/devops-infra-argo-config` | This repo does not own routing manifests. See [coding-guidelines/argocd.md](./coding-guidelines/argocd.md). |
| 6 | Schedule fields (`nodeSelector`, `tolerations`, `computeClass`) copy-pasted from one cluster's override to another without rewriting | siddharth.pal | PR review block | Re-derive from per-cluster node-pool topology. See [contour-nodeselector-tolerations-summary.md](../../contour-nodeselector-tolerations-summary.md) and [runbooks/pod-pending-scheduling.md](../platform/runbooks/pod-pending-scheduling.md). |
| 7 | Chart dep version bump where upstream changelog flags breaking template changes | siddharth.pal | Slack `#devops-infra` + PR review | Run `helm dependency update`, refresh `Chart.lock`, dry-run `helm template` against every consumer cluster. See [procedures/update-chart-version.md](../platform/procedures/update-chart-version.md). |
| 8 | Vault HA write-path failure (seal status, Raft peer loss, unsealed standby) | siddharth.pal + platform on-call | Slack `#sec-incidents` + PagerDuty | Production secret-store outage. Do not modify Vault overrides without on-call ack. |
| 9 | Edit to `manifests/storageclass/*.yaml` or `manifests/priorityclass/<cluster>/*.yaml` | siddharth.pal + cluster BU owner | PR review (two reviewers) | Cluster-wide singleton; affects every PVC / scheduling priority. See [schemas/storageclass-priorityclass-schema.md](../platform/schemas/storageclass-priorityclass-schema.md). |
| 10 | Deletion of a versioned-sibling chart (`-green`, `-vX.Y.Z`, `-latest`, `-old`) | siddharth.pal | Slack `#devops-infra` + grep sister repo | Confirm zero references in `Meesho/devops-infra-argo-config` before deletion. See [analyses/ADR-A2-blue-green-sibling-pattern.md](../../wiki/analyses/ADR-A2-blue-green-sibling-pattern.md). |
## Refusal language
When refusing, state:
1. The Sanctity rule or Layer constraint that's tripped.
2. Which owner to ping (from the table above).
3. The repo or pipeline the request actually belongs in (sister repo, `registry-bootstrap`, Vault on-call, etc.).
## See also
- [AGENT_BOUNDARIES.md](./AGENT_BOUNDARIES.md)
- [SANCTITY_RULES.md](./SANCTITY_RULES.md)
- [agent-operations-guide.md](./agent-operations-guide.md)
- Repo-root `CLAUDE.md` NEVER-DO list
@@ -0,0 +1,231 @@
> Per AI Blitz Plan §platform.procedures. Layer: 1. Repo: devops-infra-helm-charts.
# Procedure — Add or modify a Contour HTTPProxy route
> **Layer:** Layer 1 — values diff + PR.
> **Blast radius:** one Contour release × one cluster (a misrouted host can break ingress for the whole BU).
> **Approval:** consuming-app owner + cluster owner. Platform team if the change touches `contour-external*`.
This procedure covers HTTPProxy route changes that flow through one of the cluster's Contour releases. Most clusters run **multiple Contour instances** — read the [contour-nodeselector-tolerations-summary.md](../../../contour-nodeselector-tolerations-summary.md) (repo root) authoritative scheduling matrix before editing **any** Contour values.
---
## Multi-Contour topology
| Release name | Plane | Typical purpose |
|--------------|-------|-----------------|
| `contour-external` | North-south | Public / external traffic (terminates at GCP external LB) |
| `contour-external-1` | North-south | Second external Contour (blue-green or capacity split) |
| `contour-internal-0` | East-west | Internal traffic, plane 0 |
| `contour-internal-1` | East-west | Internal traffic, plane 1 |
| `contour-internal-intra-0` | Intra-cluster | Cluster-local east-west, plane 0 |
| `contour-internal-intra-1` | Intra-cluster | Cluster-local east-west, plane 1 |
Each is a separate Helm release, on a separate node pool, with its own `nodeSelector` / `tolerations` / `computeClass`. Picking the wrong release is the most common authoring mistake.
---
## When to use
- Adding a new HTTPProxy / route for a service.
- Changing TLS, retry, timeout, or rate-limit policy on an existing route.
- Re-pointing an HTTPProxy at a different upstream Service.
- Adding a new host to an existing route's `virtualhost.fqdn`.
Do **not** use this procedure for:
- Changing Contour itself (sizing, scheduling, image) — that's [modify-observability-config.md](modify-observability-config.md)-style infra editing on the Contour release.
- Bumping Contour's chart version — use [update-chart-version.md](update-chart-version.md) and consult the versioned sibling (`contour-v1.33.3`).
- Curling production hostnames to test — [SANCTITY_RULES R3](../../global/SANCTITY_RULES.md) forbids it. Test from inside the cluster with a `curl` Pod.
---
## Inputs
| Input | Example |
|-------|---------|
| Target cluster | `k8s-supply-prd-ase1` |
| Target Contour release | `contour-internal-0` |
| HTTPProxy host | `api-foo.internal.meeshogcp.in` |
| Upstream Service | `foo-svc.foo-ns:8080` |
| TLS source | `cert-manager` / `external-secret` / `none` |
| Path prefixes | `/v1`, `/health` |
| Approval ticket | CMR-… (if BU policy) |
---
## Pre-conditions
- [ ] You know which Contour release is the right one for this host (north-south = `external*`; east-west between BUs = `internal-{0,1}`; cluster-local = `internal-intra-{0,1}`). When in doubt, sample existing HTTPProxies in the same namespace.
- [ ] The upstream Service exists or will exist by the time of Sync.
- [ ] The DNS name follows the cluster's `external-dns` pattern.
- [ ] The TLS source (Secret, Issuer, etc.) exists on the cluster.
---
## Steps
### 1. Identify the right Contour release
```bash
ls helm-overrides/<cluster>/ | grep '^contour'
```
Pick the release whose plane matches the new route's traffic class. Cross-reference [contour-nodeselector-tolerations-summary.md](../../../contour-nodeselector-tolerations-summary.md). If unsure, look at existing HTTPProxies on the cluster:
```bash
# Read existing routes already shipped via this repo
yq e '.. | select(has("httpproxies"))' \
helm-overrides/<cluster>/contour-internal-0/custom-values.yaml
```
### 2. Decide where the HTTPProxy lives
Two patterns exist:
| Pattern | When | Where to author |
|---------|------|-----------------|
| **Inline in Contour values** | Routes shared by the cluster's infra layer (e.g. Grafana, Argo CD). | `helm-overrides/<cluster>/<contour-release>/custom-values.yaml` under `httpproxies:` (if the chart supports it) or as a sidecar manifest in the same dir. |
| **In the consuming app's repo** | Routes for a specific service. | The service's own deployment artifacts. **Out of scope for this repo.** |
If the route is service-owned, **redirect** to the consuming team's repo and stop. This procedure only covers infra-layer HTTPProxies.
### 3. Author the HTTPProxy
Skeleton (sidecar manifest pattern):
```yaml
apiVersion: projectcontour.io/v1
kind: HTTPProxy
metadata:
name: <name>
namespace: <ns>
spec:
virtualhost:
fqdn: <fqdn>
tls:
secretName: <tls-secret> # cert-manager-managed Secret
routes:
- conditions:
- prefix: /
services:
- name: <upstream-service>
port: <port>
timeoutPolicy:
response: 30s
retryPolicy:
count: 2
retryOn: 5xx
```
Drop into `helm-overrides/<cluster>/<contour-release>/httpproxies/<name>.yaml` (sidecar manifest) — see [../schemas/raw-manifest-sidecar-schema.md](../schemas/raw-manifest-sidecar-schema.md).
### 4. Lint the HTTPProxy
```bash
# Schema check (kubectl --dry-run against the cluster's CRD)
kubectl --context=<ctx> --dry-run=server -f helm-overrides/<cluster>/<contour-release>/httpproxies/<name>.yaml apply
# Or local: validate against the projectcontour CRD schema
kubeconform -schema-location default -schema-location \
'https://raw.githubusercontent.com/projectcontour/contour/main/examples/contour/01-crds.yaml' \
helm-overrides/<cluster>/<contour-release>/httpproxies/<name>.yaml
```
### 5. Render the chart
```bash
helm template <contour-release> helm-templates/<contour-chart> \
-f helm-overrides/<cluster>/<contour-release>/custom-values.yaml > /tmp/contour.yaml
```
The render must succeed; the HTTPProxy sidecar is applied alongside, not through Helm — but rendering catches values-side errors that would block sync of the same Argo Application.
### 6. Test from inside the cluster (post-merge, not pre-merge)
**Do not** curl `<fqdn>.meeshogcp.in` from your laptop / a build agent. Run a curl Pod on-cluster:
```bash
kubectl --context=<ctx> run -it --rm curl-test \
--image=curlimages/curl --restart=Never -- \
curl -v -H "Host: <fqdn>" http://<contour-svc>.projectcontour.svc.cluster.local
```
### 7. Open the PR
```bash
git checkout -b contour/<cluster>-<route-name>
git add helm-overrides/<cluster>/<contour-release>/
git commit -m "contour(<cluster>/<contour-release>): add route <name>"
git push origin contour/<cluster>-<route-name>
gh pr create --base main
```
### PR description template
```markdown
## Summary
Adds (or modifies) HTTPProxy `<name>` on `<cluster>` via `<contour-release>` for FQDN `<fqdn>`.
## Why
<1-2 sentences>
## Topology
- Cluster: `<cluster>`
- Contour release: `<contour-release>` (plane: external / internal / intra)
- FQDN: `<fqdn>`
- Upstream Service: `<svc>:<port>` in namespace `<ns>`
- TLS: cert-manager Secret `<tls-secret>`
## Validation
- [ ] HTTPProxy CRD schema validation passed (kubeconform / kubectl --dry-run)
- [ ] `helm template` rendered cleanly
- [ ] On-cluster curl from a curl Pod returns expected status
- [ ] DNS / external-dns plumbed (existing wildcard or new external-dns Service)
## Approvers
- App owner: <handle>
- Cluster owner: <handle>
- Platform (if `contour-external*`): <handle>
```
### 8. After merge — Sync
Open the cluster's Argo CD UI, find the Contour release's Application, **Sync**. Verify:
```bash
kubectl --context=<ctx> -n projectcontour get httpproxy <name>
kubectl --context=<ctx> -n projectcontour describe httpproxy <name> | grep -A5 'Status:'
```
A `Valid: true` status means Contour accepted the route. `Valid: false` with a reason → fix the values and re-PR.
If the HTTPProxy is `Valid` but traffic still 5xx → [../runbooks/ingress-down.md](../runbooks/ingress-down.md) §4.
---
## Anti-patterns
1. **Wrong Contour release.** A route mounted on `contour-internal-intra-0` is unreachable from outside the cluster. Cross-check the matrix.
2. **Curling the production FQDN** from a developer machine to "test." Forbidden — see [SANCTITY_RULES R3](../../global/SANCTITY_RULES.md).
3. **Hand-edited values for a single host across all Contour releases** — pick one release, justify it.
4. **`tls.passthrough` for plain HTTP services** — silent: TLS terminates upstream, doesn't.
5. **Wildcard hosts that overlap an existing HTTPProxy** — Contour status will mark one of them invalid; check before merging.
6. **Editing `helm-templates/contour*/`** to "tweak the chart." Layer 1 forbids casual chart edits — the chart is vanilla upstream.
---
## Rollback
- Revert the values PR.
- Sync the Contour Application — Argo will prune the HTTPProxy or restore the prior values.
---
## Related
- Reference (authoritative scheduling): [../../../contour-nodeselector-tolerations-summary.md](../../../contour-nodeselector-tolerations-summary.md).
- Runbook: [../runbooks/ingress-down.md](../runbooks/ingress-down.md).
- Schema: [../schemas/raw-manifest-sidecar-schema.md](../schemas/raw-manifest-sidecar-schema.md).
- Schema: [../schemas/custom-values-schema.md](../schemas/custom-values-schema.md).
- ADR: [../../../wiki/analyses/ADR-A3-per-cluster-scheduling.md](../../../wiki/analyses/ADR-A3-per-cluster-scheduling.md).
@@ -0,0 +1,206 @@
# Procedure — Blue-green chart migration (versioned siblings)
> **Layer:** Layer 1 — HIGH RISK.
> **Blast radius:** the chart upgrade ships in a new sibling directory; no cluster cuts over until its `Application` is repointed. Each cluster's cutover is its own decision.
> **Approval:** platform team — multi-reviewer.
This procedure handles the case where you can't safely bump a chart's pinned `dependencies[].version` in place — typically because of breaking template changes, immutable selector mismatches, or major-version semantics. The pattern is to keep both versions live as **sibling chart directories** until every consuming cluster has migrated.
The repo already shows this pattern at work:
| Original | Migration target |
|----------|------------------|
| `argo-cd` | `argo-cd-green` |
| `contour` | `contour-v1.33.3` |
| `keda` | `keda-2.17.1` |
| `opentelemetry-collector` | `opentelemetry-collector-latest` |
| `victoria-metrics-cluster` | `victoria-metrics-cluster-latest` |
| `victoria-metrics-agent` | `victoria-metrics-agent-latest` |
| `sonarqube` | `sonarqube-old` *(reverse — `sonarqube` is the new one; `-old` retained for rollback)* |
See [ADR-A2-blue-green-sibling-pattern.md](../../../wiki/analyses/ADR-A2-blue-green-sibling-pattern.md) for the rationale.
---
## When to use this procedure
- A major-version bump with breaking template changes.
- A bump with an immutable-field change (Deployment `spec.selector`, StatefulSet `volumeClaimTemplates`).
- A migration that needs cluster-by-cluster cutover with rollback windows.
This is **not** the right procedure for:
- A patch / minor bump that's a clean drop-in → use [update-chart-version.md](update-chart-version.md).
- Forking templates → use [fork-upstream-chart.md](fork-upstream-chart.md).
---
## Pre-conditions
- [ ] Platform team agrees a blue-green migration is required (not just a bump).
- [ ] You've identified the variant naming convention (`-green`, `-vX.Y.Z`, `-latest`, etc.).
- [ ] You've identified every consuming cluster: `grep -rl '<chart>' helm-overrides`.
- [ ] CMR open.
---
## Steps
### 1. Create the sibling chart directory
```bash
cp -R helm-templates/<chart> helm-templates/<chart>-<variant>
cd helm-templates/<chart>-<variant>
```
Update `Chart.yaml`:
```diff
apiVersion: v2
-name: <chart>
+name: <chart>-<variant>
dependencies:
- name: <sub>
- version: <old-version>
+ version: <new-version>
repository: <upstream-repo>
```
```bash
helm dependency update
```
### 2. Render against a representative cluster's overrides — old variant
The point of blue-green is *no surprises*. Render the **old** chart with each consuming cluster's override and capture the output.
```bash
for f in $(find helm-overrides -maxdepth 2 -name custom-values.yaml -path "*/<chart>/*"); do
cluster=$(echo "$f" | awk -F/ '{print $2}')
helm template <chart> helm-templates/<chart> -f "$f" > /tmp/old-${cluster}.yaml
done
```
### 3. Render against the same overrides — new sibling variant
```bash
for f in $(find helm-overrides -maxdepth 2 -name custom-values.yaml -path "*/<chart>/*"); do
cluster=$(echo "$f" | awk -F/ '{print $2}')
helm template <chart>-<variant> helm-templates/<chart>-<variant> -f "$f" > /tmp/new-${cluster}.yaml
done
```
### 4. Diff old → new per cluster
```bash
for cluster in $(ls /tmp/old-*.yaml | sed 's:/tmp/old-::; s:.yaml::'); do
echo "=== $cluster ==="
diff /tmp/old-${cluster}.yaml /tmp/new-${cluster}.yaml | head -30
done
```
For each cluster, decide:
- Is the diff what you expected?
- Will any value need updating to make the new chart render correctly? (If yes → that's a separate per-cluster PR after the sibling lands.)
- Is the cutover safe to do without the workload owner present? (If no → schedule.)
### 5. Open PR-1: introduce the sibling chart
```bash
git checkout -b migrate/<chart>-to-<variant>-introduce
git add helm-templates/<chart>-<variant>/
git commit
git push origin migrate/<chart>-to-<variant>-introduce
gh pr create --base main --title "migrate: introduce <chart>-<variant> sibling"
```
After merge, the new chart exists in the repo but **no cluster uses it yet** — the existing Argo `Application`s still point at `helm-templates/<chart>`.
### 6. Per-cluster cutover (one PR pair per cluster)
For each consuming cluster:
a. **Update the cluster's `custom-values.yaml`** if the new chart needs different values. Open as a values-side PR (this repo).
b. **Update the sister-repo `Application`** to repoint:
```diff
spec:
source:
repoURL: https://github.com/Meesho/devops-infra-helm-charts.git
targetRevision: main
- path: helm-templates/<chart>
+ path: helm-templates/<chart>-<variant>
```
c. **After both merge**, click Sync in the cluster's Argo CD UI.
d. **Soak** — leave it for the agreed soak period (often 2472 h) before moving to the next cluster.
### 7. Open PR-N: retire the old sibling
After every cluster has cut over and soaked:
```bash
git checkout -b migrate/<chart>-retire-old
git rm -r helm-templates/<chart>
# OR rename: git mv helm-templates/<chart> helm-templates/<chart>-old
git commit
git push origin migrate/<chart>-retire-old
gh pr create --base main --title "migrate: retire old <chart> sibling"
```
PR description:
- Confirmation every cluster has cut over (`grep -rl 'helm-templates/<chart>$' /path/to/devops-infra-argo-config` returns nothing).
- Confirmation soak period elapsed.
- Decision: delete vs rename to `-old` (kept for rollback).
---
## Why two PRs at the start, then per-cluster pairs, then a final retirement
| PR | Effect |
|----|--------|
| **PR-1: introduce sibling** | Adds the new chart. No cluster cuts over. Worst case: render errors caught before any cluster sees them. |
| **PR-2..N-1: per-cluster cutover (paired with sister repo)** | One cluster moves. Worst case: that cluster's release breaks; revert the sister-repo PR and Sync to the old chart. |
| **PR-N: retire old sibling** | Removes the old chart. Worst case: a cluster you missed becomes broken — but you grep'd, so this should be impossible. |
Bundling any of these violates the "rollback one cluster at a time" property that's the whole point of the blue-green pattern.
---
## Anti-patterns
1. **Cutting over multiple clusters in one PR.** Bundle = no per-cluster rollback.
2. **Deleting the old sibling before every cluster has cut over.** Cluster N+1 has its `Application` pointing at a path that no longer exists; sync fails immediately.
3. **Cutting over without rendering first.** Surprises after merge.
4. **Skipping the soak period.** "It looked fine in the first 5 minutes" is not soak.
5. **Renaming the *new* sibling to drop the suffix** (e.g. `argo-cd-green``argo-cd`) before the old chart is retired. The path collision will break Argo CD's caching.
---
## Rollback (per cluster)
If a cluster's cutover fails:
1. Revert the sister-repo PR for that cluster.
2. Click Sync in the cluster's Argo CD — the `Application` re-renders against `<chart>` (the old sibling). The rollback is one cluster only.
3. Investigate; iterate.
If the new sibling has a fundamental problem affecting every cluster:
1. Open PR-X: revert PR-1 (delete the sibling).
2. Any cluster that was already cutover gets reverted via its own per-cluster sister-repo revert.
3. Schedule a postmortem before re-attempting.
---
## Related
- Procedure: [update-chart-version.md](update-chart-version.md).
- Procedure: [fork-upstream-chart.md](fork-upstream-chart.md).
- ADR: [ADR-A2-blue-green-sibling-pattern.md](../../../wiki/analyses/ADR-A2-blue-green-sibling-pattern.md).
- [SANCTITY_RULES R8](../../global/SANCTITY_RULES.md).
+119
View File
@@ -0,0 +1,119 @@
# Procedure — Deboard a retired app from a cluster
> **Layer:** Layer 1 — HIGH RISK.
> **Blast radius:** the Helm release is removed from the cluster. If still in use, that's an outage.
> **Approval:** app owner + cluster owner. CMR mandatory.
This procedure removes an app's `helm-overrides/<cluster>/<app>/` directory. It does **not** delete the workload directly — but the matching sister-repo `Application` PR (which must be paired) tells Argo CD to stop tracking the release.
---
## Pre-conditions (block deboarding if any are FALSE)
- [ ] App is genuinely retired on this cluster — confirmed by app owner.
- [ ] No traffic / scrape job / dependency is still hitting it.
- [ ] All upstream consumers (alerts, dashboards, log collectors) have been migrated or notified.
- [ ] You have inventoried every cluster that runs the app and decided whether this is a single-cluster or fleet-wide deboard.
- [ ] CMR approved.
```bash
# Where does this app exist today?
find helm-overrides -maxdepth 2 -type d -name '<app>'
```
---
## Steps
### 1. Decide the scope
| Scope | Then |
|-------|------|
| Single cluster | Remove `helm-overrides/<cluster>/<app>/` only. Leave other clusters running. |
| Fleet-wide | Multiple PRs — one cluster per PR. Don't bundle. |
| App is being replaced (e.g. `victoria-metrics-cluster``victoria-metrics-cluster-latest`) | This is a **migration**, not a deboard — use [blue-green-chart-migration.md](blue-green-chart-migration.md). |
### 2. Open the sister-repo `Application` removal PR FIRST
In `github.com/Meesho/devops-infra-argo-config`:
- Remove (or scope out of) the `Application` / `ApplicationSet` entry that targets this cluster × app.
- Merge.
- The cluster's Argo CD will mark the `Application` for removal on next reconcile.
This step **must precede** the values-side removal. If you delete the values-side first, the `Application` will fail to render and the workload may go into an `Errored` state on the cluster.
### 3. Manually clean up the workload (if `automated.prune` was not set)
For most infra apps, the `Application` does not have `automated.prune: true` — so removing the `Application` does not delete the workload. Manually:
```bash
kubectl --context=<cluster> delete <kind>/<name> -n <ns>
# OR, if the whole namespace is dedicated to this release:
kubectl --context=<cluster> delete namespace <ns>
```
Coordinate with the app owner — wholesale namespace deletion is irreversible.
### 4. Open the values-side removal PR
```bash
git checkout -b deboard/<app>-from-<cluster>
git rm -r helm-overrides/<cluster>/<app>/
git commit
git push origin deboard/<app>-from-<cluster>
gh pr create --base main --title "deboard: <app> from <cluster>"
```
PR description:
- Procedure followed: this file.
- Confirmation pre-conditions are TRUE.
- Sister-repo PR (already merged).
- CMR ticket reference.
- Confirmation the workload was manually cleaned up (or scheduled).
### 5. (Optional) If this was the last cluster running the app
If `find helm-overrides -maxdepth 2 -type d -name '<app>'` now returns nothing, consider:
- **Should `helm-templates/<chart>/` also be removed?** Probably not — keeping the chart cached lets a future re-onboarding be cheap. But if it's a stale chart with security advisories you don't want to maintain, schedule a separate retirement PR for it (with platform-team review).
---
## "What if the app might come back?"
If retirement is provisional:
- **Do not** scale the workload to zero replicas via values "to deactivate it." Either it's running or it's not. Half-states are operational debt.
- **Do** keep the values directory in place but document a 30-day decision deadline in a TODO comment. If the deadline passes without a re-decision, deboard for real.
---
## Anti-patterns
1. **Deleting the values-side first** before the sister-repo `Application` is removed. The `Application` errors on next reconcile.
2. **Bulk-deleting multiple clusters in one PR.** One cluster per PR. Rollback granularity.
3. **Forgetting to clean up the workload manually.** The Helm release lingers on the cluster after the `Application` is removed (because most infra apps lack `automated.prune`).
4. **Forgetting `external-secrets` cleanup.** If the app referenced an `ExternalSecret`, the corresponding `ExternalSecret` resource (in the cluster's `external-secrets/` directory) often outlives the app. Either repurpose it or delete it in the same PR.
5. **Forgetting alert / dashboard cleanup.** Alerts firing on a workload that no longer exists cause noise; dashboards showing nothing cause confusion.
---
## Rollback
If you deboarded by mistake:
1. Revert the values-side PR (`git revert <merge-sha>`).
2. Revert the sister-repo PR.
3. Click Sync in the cluster's Argo CD UI.
4. The `Application` is recreated and renders the chart.
5. **However**, if you also manually deleted the workload (step 3), the Sync recreates it from scratch — make sure the underlying chart and values are still intact and any data PVCs were retained (see `manifests/storageclass/pd-standard-retain-dr.yaml`).
---
## Related
- Procedure: [onboard-app-to-cluster.md](onboard-app-to-cluster.md) — the inverse.
- Procedure: [blue-green-chart-migration.md](blue-green-chart-migration.md) — if "deboard" is actually a migration.
- ADR: [ADR-A5-manual-sync-default-for-infra.md](../../../wiki/analyses/ADR-A5-manual-sync-default-for-infra.md) — why the workload doesn't auto-delete.
@@ -0,0 +1,158 @@
# Procedure — Intentionally fork an upstream chart
> **Layer:** Layer 1 — HIGH RISK.
> **Blast radius:** every cluster that consumes this chart will render against the forked templates on next sync.
> **Approval:** platform team — multi-reviewer.
Most charts in `helm-templates/` are **vanilla upstream**, pulled via `helm pull`. The `Chart.yaml` is a thin wrapper declaring the upstream chart as a dependency; the actual templates come from the subchart in `charts/`. Editing a `templates/*.yaml` *under the wrapper* silently forks the chart, and the fork is clobbered the next time someone runs `helm dependency update`.
This procedure is the supported path when a fork is **intentional**.
---
## When to use this procedure
- Upstream chart lacks a feature you need (e.g. a values key that doesn't exist).
- Upstream behaviour conflicts with Meesho's environment (e.g. probe path doesn't work behind Contour).
- Upstream chart has a bug awaiting an upstream fix.
This is **not** the right procedure for:
- Adding a values knob — file a PR upstream, or override behaviour through existing knobs.
- Pinning to an old version — use [update-chart-version.md](update-chart-version.md) (or just don't bump).
- Style preferences — leave the upstream chart alone.
---
## Pre-conditions
- [ ] You've confirmed the desired behaviour cannot be achieved via the chart's existing values.
- [ ] You've checked whether an upstream PR / issue already covers this.
- [ ] Platform team agrees the fork is justified.
- [ ] The fork's rationale will be documented in the chart's `README.md`.
---
## Steps
### 1. Vendor the chart's templates
If the chart is currently a thin wrapper (templates come from a subchart in `charts/<sub>`), you must first promote the subchart's templates into the wrapper.
```bash
cd helm-templates/<chart>
ls charts/ # find the subchart .tgz
helm dependency update # ensure it's resolved
# Extract templates from the subchart .tgz
tar -xzf charts/<sub>-<ver>.tgz -C /tmp/
cp -R /tmp/<sub>/templates ./templates
cp -R /tmp/<sub>/values.yaml ./values.yaml.upstream
```
Now the wrapper has its own `templates/` — Helm will use those instead of the subchart's.
### 2. Edit `Chart.yaml` to reflect the fork
Remove the dependency (since the templates are now local), and bump `version:` (the chart's own version, not the subchart's):
```diff
apiVersion: v2
name: <chart>
-version: 0.1.0
+version: 0.1.0+fork.1
description: <description> — Meesho-forked from upstream <chart> <upstream-version>
-dependencies:
- - name: <sub>
- version: <upstream-version>
- repository: <upstream-repo>
```
### 3. Make the fork edits
Edit `templates/*.yaml` or `values.yaml` to apply the fix. Keep the diff minimal — every line away from upstream is technical debt.
### 4. Document the fork
Edit `helm-templates/<chart>/README.md` (create if missing). Use this template:
```markdown
# <chart>
**Forked from upstream <chart> <upstream-version>** at <date>.
## Why
<one-paragraph rationale — what behaviour the fork changes and why we couldn't achieve
it through values alone>
## What's changed
- `templates/<file>.yaml` — <one-line diff summary>
- `values.yaml` — <one-line diff summary>
## Upstream tracking
- Upstream PR: <link, if you've sent one>
- Upstream issue: <link>
- When upstream merges: revert this fork via [unfork procedure].
```
### 5. Render and diff
```bash
sibling=$(find helm-overrides -maxdepth 2 -type d -name '<chart>' | head -1)
helm template <chart> helm-templates/<chart> -f "$sibling/custom-values.yaml" | head -120
# Spot-check helm diff against a live cluster
helm diff upgrade <release> helm-templates/<chart> \
-f helm-overrides/<cluster>/<app>/custom-values.yaml --kube-context=<context>
```
### 6. Commit and open the PR
```bash
git checkout -b fork/<chart>-<purpose>
git add helm-templates/<chart>/
git commit
git push origin fork/<chart>-<purpose>
gh pr create --base main --title "fork: <chart> — <one-line purpose>"
```
PR description must include:
- Procedure followed: this file.
- Why the fork is necessary (link to upstream issue/PR if any).
- What templates / values are changed and why.
- Platform team approver(s).
- Plan for unforking when upstream lands the fix.
---
## Anti-patterns
1. **Editing `templates/` without first vendoring** (templates from a subchart). Your edits live in `helm-templates/<chart>/templates/` but Helm renders from `charts/<sub>/templates/` — the edits do nothing, then get clobbered.
2. **Forking a chart and not documenting why.** Six months later nobody remembers; the fork looks like accidental drift.
3. **Forking instead of overriding via values.** Always check the chart's existing values surface first.
4. **Forking and then bumping the upstream version.** A bump runs `helm dependency update`, which can clobber the fork. The fork must be re-applied or the bump must explicitly re-vendor.
5. **Sweeping cleanup of upstream code** alongside the fork edit. The diff should be exactly the change you intended; everything else is upstream.
---
## Rollback / unforking
When upstream lands the fix and you want to return to vanilla:
1. Restore `Chart.yaml` to declare the upstream as a dependency (with the new upstream version that includes the fix).
2. Delete the local `templates/` and `values.yaml` (or rename them as `.upstream` for reference).
3. Run `helm dependency update`.
4. Update `helm-templates/<chart>/README.md` to remove the "forked" status.
5. Render against a sibling override and confirm the resulting manifests match what the fork was producing.
---
## Related
- Procedure: [update-chart-version.md](update-chart-version.md).
- ADR: [ADR-A1-cache-vs-upstream-charts.md](../../../wiki/analyses/ADR-A1-cache-vs-upstream-charts.md).
- [SANCTITY_RULES R7](../../global/SANCTITY_RULES.md).
@@ -0,0 +1,227 @@
> Per AI Blitz Plan §platform.procedures. Layer: 1. Repo: devops-infra-helm-charts.
# Procedure — Modify Prometheus / VictoriaMetrics alert rules
> **Layer:** Layer 1 — values diff + PR.
> **Blast radius:** PagerDuty / on-call paging across the cluster's tenants. A wrong threshold pages everyone; a missing rule masks an outage.
> **Approval:** observability owner + on-call lead for the affected severity.
This procedure is the narrow alert-rule slice of [modify-observability-config.md](modify-observability-config.md). Use this when the entire intent of the PR is alert-rule editing — adding, removing, retuning thresholds, changing `for:` windows, or rewriting `expr:` PromQL.
---
## Where alert rules live
| File | Engine | Notes |
|------|--------|-------|
| `helm-overrides/<cluster>/vmalert/custom-values.yaml` | vmalert | Most clusters use vmalert against VM cluster as the primary alerting engine. Rules typically under `config.rules` or rendered as a `VMRule` CRD. |
| `helm-overrides/<cluster>/victoria-metrics-cluster/custom-values.yaml` | vmalert (bundled) / VM ruler | Some clusters carry rules in the cluster chart's `vmalert.config` block. |
| `helm-overrides/<cluster>/prometheus/custom-values.yaml` | Prometheus / `kube-prometheus-stack` | Rules under `additionalPrometheusRulesMap` or `serverFiles.alerting_rules.yml`. |
| `helm-overrides/<cluster>/kube-prometheus-stack/custom-values.yaml` | Prometheus | Same as above; older clusters use this chart name. |
| `helm-overrides/<cluster>/mimir/custom-values.yaml` | Mimir ruler | Rules go through the ruler API; YAML in `runtimeConfig` or via a sidecar `ConfigMap`. |
Confirm which cluster runs which engine before editing — sample existing rules in the override.
---
## When to use
- Adding/removing one or more alert rules in the cluster's primary alerting engine.
- Tuning `expr:` PromQL or `for:` windows on existing rules.
- Re-routing alerts (changing `severity`, `team`, or other routing labels).
- Adding/removing recording rules for downstream alert efficiency.
Do **not** use this procedure for:
- Touching scrape configs, retention, datasources, or sizing in the same PR — split it. See [modify-observability-config.md](modify-observability-config.md).
- Bumping the alerting chart's version — see [update-chart-version.md](update-chart-version.md).
- Writing app-specific alert rules that belong in the consuming service's own values — those go in the service's repo.
---
## Inputs
| Input | Example |
|-------|---------|
| Target cluster | `k8s-supply-prd-ase1` |
| Target chart | `vmalert` / `prometheus` / `kube-prometheus-stack` / `mimir` |
| Rule name(s) added/changed | `HighErrorRate`, `KafkaConsumerLag` |
| `expr:` PromQL | `sum(rate(http_requests_total{status=~"5.."}[5m])) by (service) > 0.05` |
| `for:` window | `5m` |
| Severity / routing labels | `severity: critical`, `team: supply-platform` |
| Approval ticket | CMR-… |
---
## Pre-conditions
- [ ] You have `promtool` and/or `vmalert` available locally.
- [ ] You know the cluster's Alertmanager / vmalert notifier routing (which `severity` / `team` label routes where).
- [ ] You have run the new PromQL expression against the cluster's VM/Prometheus to confirm it returns sensible values *before* writing the rule — open Grafana Explore.
- [ ] You have on-call sign-off if this rule pages on-call.
---
## Steps
### 1. Locate the rules block
```bash
yq e '.config.rules // .additionalPrometheusRulesMap // .serverFiles' \
helm-overrides/<cluster>/<chart>/custom-values.yaml
```
Identify the YAML path the engine expects:
- **vmalert**: `config.groups[].rules[]`.
- **kube-prometheus-stack**: `additionalPrometheusRulesMap.<group-name>.groups[].rules[]`.
- **prometheus**: `serverFiles.alerting_rules.yml.groups[].rules[]`.
- **mimir ruler**: per-tenant config — confirm the cluster's tenancy setup.
### 2. Author the rule
```yaml
- alert: <RuleName> # PascalCase, no spaces; surfaces in pages and dashboards
expr: |
<PromQL expression>
for: <duration> # e.g. 5m, 10m
labels:
severity: <warning|critical|info>
team: <owning-team> # routes to the right PagerDuty service
annotations:
summary: "<one-line>"
description: "<longer text, can reference $labels.* and $value>"
runbook_url: <link to runbook>
```
#### Threshold discipline
- Express thresholds as `rate(...) > 0.05` rather than `> 5%`. Ensure units in the expression match the units in `summary` / `description`.
- Avoid `for:` windows shorter than the scrape interval × 2. Sub-`1m` windows are flap factories.
- Avoid alerting on absolute counts (`sum(http_requests_total) > 1000`); prefer rates / ratios.
- For SLO-style alerts, use multi-window multi-burn-rate (Google SRE workbook). Single-window threshold alerts are a known anti-pattern.
#### Routing implications
Changing `severity` from `warning` to `critical` (or vice versa) **silently re-routes the page** — the rule may now wake on-call where it previously emailed (or vice versa). Same for `team:` — a typo here drops alerts into the wrong PagerDuty service. Cross-check the cluster's Alertmanager / vmalert routing config:
```bash
yq e '.config.route // .alertmanagerConfig' \
helm-overrides/<cluster>/<alertmanager-chart>/custom-values.yaml
```
### 3. Render the chart
```bash
helm template <release> helm-templates/<chart> \
-f helm-overrides/<cluster>/<chart>/custom-values.yaml > /tmp/rendered.yaml
```
### 4. Validate PromQL
For Prometheus / `kube-prometheus-stack`:
```bash
yq e 'select(.kind == "PrometheusRule")' /tmp/rendered.yaml > /tmp/rules.yaml
promtool check rules /tmp/rules.yaml
```
For vmalert:
```bash
yq e 'select(.kind == "VMRule" or .kind == "ConfigMap")' /tmp/rendered.yaml > /tmp/vmrules.yaml
vmalert -dryRun -rule=/tmp/vmrules.yaml
```
For Mimir ruler — `mimirtool rules check` against the rendered ruler config.
If validation fails: fix the PromQL. **Do not** merge a rule that fails parse.
### 5. Sanity-check expressions in Grafana Explore
In a non-production manner: open Grafana on the cluster, paste the `expr:` into Explore, run over the last 6h. Confirm:
- The series returned makes sense for the rule.
- The threshold isn't always-firing or never-firing in normal operation.
- Empty result is allowed (`absent_over_time(...)` style).
### 6. Open the PR
```bash
git checkout -b alerts/<cluster>-<rule-name>
git add helm-overrides/<cluster>/<chart>/custom-values.yaml
git commit -m "alerts(<cluster>/<chart>): <add|tune|remove> <RuleName>"
git push origin alerts/<cluster>-<rule-name>
gh pr create --base main
```
### PR description template
```markdown
## Summary
<add|tune|remove> alert rule(s) on `<cluster>` × `<chart>`.
## Rules touched
| Rule | Change | New expr | New `for:` | Severity | Team |
|------|--------|----------|-----------|----------|------|
| `<RuleName>` | added | `<expr>` | `5m` | `critical` | `supply-platform` |
## Validation
- [ ] `promtool check rules` / `vmalert -dryRun` passed
- [ ] PromQL sanity-checked in Grafana Explore over last 6h
- [ ] Threshold appropriate (no flap risk, no always-firing)
- [ ] Routing labels (`severity`, `team`) verified against Alertmanager/vmalert routes
- [ ] Runbook URL added (`annotations.runbook_url`)
## Approvers
- Observability owner: <handle>
- On-call lead (severity=<x>): <handle>
```
### 7. After merge — Sync and observe
Sync the Argo Application. Watch:
```bash
# vmalert
kubectl --context=<ctx> -n monitoring logs deploy/vmalert | grep -i "<RuleName>\|error"
# kube-prometheus-stack
kubectl --context=<ctx> -n monitoring logs prometheus-k8s-0 | grep -i "<RuleName>\|error"
```
Open the alerting engine's UI (vmalert UI / Prometheus `/alerts`) to confirm the rule loaded.
### Watch for false positives
Stay on the alert for at least one full `for:` window after sync. If the rule pages immediately and was not expected to → revert.
---
## Anti-patterns
1. **Sub-1m `for:` windows** — flap-prone.
2. **Alerting on absolute counts** instead of rates/ratios.
3. **`severity` flips without on-call sign-off** — silent re-route.
4. **Missing `runbook_url`** — pages without remediation steps waste on-call cycles.
5. **PromQL that uses `{job=~"foo.*"}` regex without anchors** — slow query, sometimes false matches.
6. **Inlining the rule body in the chart `templates/`** to "make it sticky" — that's a chart fork; see NEVER-DO.
7. **Adding the rule on every cluster in one PR** — surgical only.
---
## Rollback
- Revert the PR. Sync.
- vmalert/Prometheus reload picks up the previous ruleset within seconds.
- Any in-flight alerts resolve on next evaluation.
---
## Related
- Coding guideline: [../../global/coding-guidelines/observability.md](../../global/coding-guidelines/observability.md).
- Procedure: [modify-observability-config.md](modify-observability-config.md) — broader observability edits.
- Runbook: [../runbooks/metrics-gap.md](../runbooks/metrics-gap.md) — when an alert is silent because the metric is gone.
- Schema: [../schemas/custom-values-schema.md](../schemas/custom-values-schema.md).
- Escalation: [../../global/escalation-matrix.md](../../global/escalation-matrix.md).
@@ -0,0 +1,210 @@
> Per AI Blitz Plan §platform.procedures. Layer: 1. Repo: devops-infra-helm-charts.
# Procedure — Modify observability stack config
> **Layer:** Layer 1 — values diff + PR.
> **Blast radius:** one chart × one cluster (a metrics gap, retention change, or alert-rule edit can ripple to paging and dashboards across the BU).
> **Approval:** observability owner (`siddharth.pal@meesho.com`) + cluster owner.
This procedure covers edits to the cluster-by-cluster observability override files:
| Override path | What it controls |
|---------------|------------------|
| `helm-overrides/<cluster>/victoria-metrics-agent/custom-values.yaml` | Scrape targets, relabel rules, remote-write tenancy. |
| `helm-overrides/<cluster>/victoria-metrics-cluster/custom-values.yaml` | vmstorage retention, vmselect/vminsert sizing, ruler config. |
| `helm-overrides/<cluster>/mimir/custom-values.yaml` (also `mimir-distributed`) | Mimir distributor/ingester/ruler config and tenancy. |
| `helm-overrides/<cluster>/loki/custom-values.yaml` (also `loki-distributed`) | Loki retention, ingestion limits, multi-tenant config. |
| `helm-overrides/<cluster>/tempo/custom-values.yaml` (also `tempo-distributed`) | Tempo block retention, distributor sizing. |
| `helm-overrides/<cluster>/grafana/custom-values.yaml` | Datasources, dashboard providers, plugins. |
| `helm-overrides/<cluster>/vmalert/custom-values.yaml` | vmalert alerting rules and notifier config. |
| `helm-overrides/<cluster>/prometheus/custom-values.yaml` (or `kube-prometheus-stack`) | Prometheus alert rules, scrape config, retention. |
All of these are **versioned-sibling-aware** — confirm whether the cluster's Argo Application points at `victoria-metrics-cluster` or `victoria-metrics-cluster-latest`, etc., before editing. See [../../global/coding-guidelines/observability.md](../../global/coding-guidelines/observability.md) for stack conventions.
---
## When to use
- Adding/removing scrape targets, relabel rules, recording rules.
- Changing retention (`vmstorage.retentionPeriod`, Loki `retention_period`, Tempo `compaction.block_retention`).
- Adding/removing/tuning alert rules in `vmalert` or `kube-prometheus-stack`.
- Adding/removing Grafana datasources, dashboards, plugins.
- Tuning ingester/distributor sizing for Mimir/Loki/Tempo.
Do **not** use this procedure for:
- **Bumping the chart version** of an observability tool — use [update-chart-version.md](update-chart-version.md).
- **Onboarding a brand-new observability tool** to a cluster — use [onboard-app-to-cluster.md](onboard-app-to-cluster.md).
- **A blue-green migration** between sibling charts (`-latest`) — use [blue-green-chart-migration.md](blue-green-chart-migration.md).
---
## Inputs
| Input | Example |
|-------|---------|
| Target cluster | `k8s-supply-prd-ase1` |
| Target chart | `victoria-metrics-cluster` |
| Versioned-sibling target (if applicable) | `victoria-metrics-cluster-latest` |
| Change kind | `retention bump`, `new scrape target`, `new alert rule`, `dashboard add` |
| Promql expression(s) touched (if any) | `sum(rate(...)) by (job) > 0.05` |
| Approval ticket | CMR-1234 (if BU policy requires) |
---
## Pre-conditions
- [ ] The cluster directory and chart override exist.
- [ ] The cluster's Argo `Application` points at the chart you're editing (and not its sibling). Check `github.com/Meesho/devops-infra-argo-config`.
- [ ] You have the previous PR diff for context (most observability edits are touching a known knob).
- [ ] You have access to PromQL/promtool (or vmalert binary) locally for rule validation.
---
## Steps
### 1. Confirm which sibling the cluster runs
```bash
# In the sister repo
gh search code --repo Meesho/devops-infra-argo-config "<chart>" -- path:**/<cluster>*
```
Find the `Application` whose `spec.source.path` points at this repo. Note whether it's `victoria-metrics-cluster` or `victoria-metrics-cluster-latest`. **Editing the wrong one is silent** — the file diff merges, but no cluster picks it up.
### 2. Read the current values
```bash
yq e '.' helm-overrides/<cluster>/<chart>/custom-values.yaml | less
```
Note current retention, scrape targets, and any inline alert rules.
### 3. Author the change
Edit `helm-overrides/<cluster>/<chart>/custom-values.yaml`. Surgical — only the keys the task requires. Preserve YAML key order; preserve comments.
#### Cardinality discipline
If the change adds a label, scrape target, or `relabel_configs` rule, ask: can the new label exceed ~few-hundred distinct values? If yes, drop or aggregate. See [observability.md §Cardinality discipline](../../global/coding-guidelines/observability.md).
#### Retention changes
Increasing `vmstorage.retentionPeriod`, Loki `retention_period`, or Tempo `block_retention` grows the backing PVC. Confirm `persistence.size` (or `vmstorage.persistentVolume.size`) has been bumped to match — otherwise vmstorage runs out of disk silently.
#### Alert-rule edits
If the rule's `for:` window or `severity` label changes, the PagerDuty routing may swap. Cross-check the cluster's Alertmanager / vmalert notifier config before merging.
### 4. Render the chart locally
```bash
helm template <release> helm-templates/<chart> \
-f helm-overrides/<cluster>/<chart>/custom-values.yaml > /tmp/rendered.yaml
```
The render must succeed. If it errors, fix the values before continuing.
### 5. Validate any PromQL touched
For Prometheus/`kube-prometheus-stack`:
```bash
# Extract PrometheusRule objects from rendered output
yq e 'select(.kind == "PrometheusRule")' /tmp/rendered.yaml > /tmp/rules.yaml
# Validate
promtool check rules /tmp/rules.yaml
```
For vmalert:
```bash
# Extract VMRule (or ConfigMap with rules)
yq e 'select(.kind == "VMRule" or .kind == "ConfigMap")' /tmp/rendered.yaml > /tmp/vmrules.yaml
# vmalert dry-run
vmalert -dryRun -rule=/tmp/vmrules.yaml
```
If `promtool` / `vmalert` is unavailable locally, surface the rule expression in the PR description and request reviewer to validate.
### 6. (Grafana) Validate datasource URL is in-cluster
Datasources should point at in-cluster Service DNS (e.g. `http://victoria-metrics-cluster-vmselect:8481`), not external endpoints. **Never** pin a Grafana datasource at `*.meeshogcp.in`, `prd.meesho.int`, or any production hostname — that violates the NEVER-DO list and routes through external networking unnecessarily.
### 7. Open the PR
```bash
git checkout -b obs/<cluster>-<chart>-<short-desc>
git add helm-overrides/<cluster>/<chart>/custom-values.yaml
git commit -m "obs(<cluster>/<chart>): <short desc>"
git push origin obs/<cluster>-<chart>-<short-desc>
gh pr create --base main
```
### PR description template
```markdown
## Summary
<one-line: what changed and why>
## Cluster × chart
- Cluster: `<cluster>`
- Chart: `<chart>` (sibling: `<sibling-or-N/A>`)
- File: `helm-overrides/<cluster>/<chart>/custom-values.yaml`
## Validation
- [ ] `helm template` renders cleanly
- [ ] `promtool check rules` / `vmalert -dryRun` passed (PromQL expression: `<expr>`)
- [ ] Cardinality bounded (no unbounded label introduced)
- [ ] Retention/PVC headroom confirmed (if retention changed)
- [ ] PagerDuty routing unchanged (if alert rule changed)
## Approvers
- Observability owner: <handle>
- Cluster owner: <handle>
## Sister repo
- N/A (no Application change required)
```
### 8. After merge
Argo CD on the target cluster reconciles. Most observability charts use **manual sync** (see [observability.md](../../global/coding-guidelines/observability.md)) — open the cluster's Argo CD UI, find the Application, click **Sync**. Watch:
```bash
kubectl --context=<ctx> -n <observability-ns> get pods -w
kubectl --context=<ctx> -n <observability-ns> logs <chart>-pod | tail -50
```
If a metric goes missing post-sync → [../runbooks/metrics-gap.md](../runbooks/metrics-gap.md).
---
## Anti-patterns
1. **Editing the wrong sibling.** The Argo Application points at `*-latest`; you edit the stable chart's values. Diff merges, nothing applies.
2. **Adding `pod_name` / `request_id` / `user_id` as a label** without aggregation — explodes cardinality.
3. **Bumping retention without bumping PVC.** vmstorage runs out of disk; ingest fails silently.
4. **Silent PagerDuty re-route.** Changing `severity:` from `warning` to `critical` (or vice versa) without coordinating on-call.
5. **Inlining production hostnames** as Grafana datasource URLs — see [SANCTITY_RULES.md](../../global/SANCTITY_RULES.md) R3.
6. **Cross-cluster normalising** — touching every cluster's `custom-values.yaml` in one PR. Surgical only; one cluster per PR.
---
## Rollback
- Revert the values PR. Argo CD will re-render with the previous values; click Sync.
- For retention shrinks: data older than the new retention is dropped on next compaction. Reverting restores the *config* but not the *data*.
---
## Related
- Coding guideline: [../../global/coding-guidelines/observability.md](../../global/coding-guidelines/observability.md).
- Runbook: [../runbooks/metrics-gap.md](../runbooks/metrics-gap.md).
- Procedure: [modify-alert-rules.md](modify-alert-rules.md) — alert-only edits.
- Schema: [../schemas/custom-values-schema.md](../schemas/custom-values-schema.md).
- ADR: [../../../wiki/analyses/ADR-A2-blue-green-sibling-pattern.md](../../../wiki/analyses/ADR-A2-blue-green-sibling-pattern.md).
- Wiki: [../../../wiki/entities/DevOps%20Infra%20Helm%20Charts.md](../../../wiki/entities/DevOps%20Infra%20Helm%20Charts.md).
@@ -0,0 +1,204 @@
# Procedure — Onboard a new app to an existing cluster
> **Layer:** Layer 1 — Agent-Writable.
> **Blast radius:** one new Helm release on one cluster.
> **Approval:** app owner + cluster owner.
This procedure adds a new infrastructure-tooling Helm release to a cluster that already exists in `helm-overrides/`. It covers the slice owned by `devops-infra-helm-charts`. The matching Argo `Application` lives in `github.com/Meesho/devops-infra-argo-config` and must be paired.
---
## Inputs
| Input | Example |
|-------|---------|
| Chart name (must exist in `helm-templates/`) | `kube-state-metrics` |
| Target cluster directory | `k8s-supply-prd-ase1` |
| Release name | `kube-state-metrics` (matches chart name; may be different for variants) |
| Workload namespace | `monitoring` |
| Image tag | `v2.10.1` |
| Sized resources (CPU/memory requests + limits) | `250m / 512Mi` |
| Node-pool key (per cluster) | `dedicated: monitoring` |
| Whether this needs a sidecar `external-dns` Service | yes / no |
---
## Pre-conditions
- [ ] The chart exists in `helm-templates/<chart>/` with a current `Chart.yaml`.
- [ ] The cluster directory exists in `helm-overrides/<cluster>/`.
- [ ] The chart is appropriate for an *infra* release (services don't go here — they live in `devops-argo-config`).
- [ ] The matching sister-repo `Application` PR is drafted (or will be drafted in parallel).
- [ ] CMR ticket open if required by BU policy.
---
## Steps
### 1. Verify the chart renders with a sibling cluster's values
Pick a cluster that already runs this chart and use its values as a starting point:
```bash
sibling=$(find helm-overrides -maxdepth 2 -type d -name '<chart>' | head -1)
helm template <chart> helm-templates/<chart> -f "$sibling/custom-values.yaml" | head -60
```
If the render errors → the chart's dependencies may be unresolved. Run `helm dependency update helm-templates/<chart>` first.
### 2. Identify the cluster's scheduling profile
```bash
# Standard GKE: uses 'dedicated:' keys
grep -rh 'dedicated:' helm-overrides/<cluster>/*/custom-values.yaml | sort -u
# GKE Autopilot: uses 'cloud.google.com/compute-class' keys
grep -rh 'cloud.google.com/compute-class' helm-overrides/<cluster>/*/custom-values.yaml | sort -u
```
For Contour, cross-reference [contour-nodeselector-tolerations-summary.md](../../../contour-nodeselector-tolerations-summary.md). For others, copy from a sibling app on the **same** cluster — never from the same app on a different cluster ([SANCTITY_RULES R5](../../global/SANCTITY_RULES.md)).
### 3. Create the directory and `custom-values.yaml`
```bash
mkdir -p helm-overrides/<cluster>/<app>
$EDITOR helm-overrides/<cluster>/<app>/custom-values.yaml
```
Author from scratch using [custom-values-schema.md](../schemas/custom-values-schema.md) and the cluster's scheduling profile from step 2. Do **not** copy a sibling cluster's values verbatim.
Skeleton:
```yaml
image:
registry: asia-southeast1-docker.pkg.dev
repository: meesho-devops-admin-0622/admin/sre/<image>
tag: <tag>
replicaCount: <N>
resources:
requests: {cpu: <c>, memory: <m>}
limits: {cpu: <c>, memory: <m>}
nodeSelector:
<pool-key>: <pool-value>
tolerations:
- {key: <pool-key>, value: <pool-value>, effect: NoSchedule}
```
### 4. (If needed) Add sidecar raw manifests
If the app needs sidecar resources (e.g. `external-dns` `Service`, `ComputeClass`, `ExternalSecret`), drop them in the same directory under a subfolder:
```
helm-overrides/<cluster>/<app>/
custom-values.yaml
external-dns-services/<svc>.yaml
computeclass/<name>-cc.yaml
```
See [raw-manifest-sidecar-schema.md](../schemas/raw-manifest-sidecar-schema.md).
### 5. Validate locally
```bash
yamllint helm-overrides/<cluster>/<app>/custom-values.yaml
# Render
helm template <release> helm-templates/<chart> \
-f helm-overrides/<cluster>/<app>/custom-values.yaml | head -60
# Optional: dry-run diff against the live cluster (requires kubectl context + helm-diff plugin)
helm diff upgrade <release> helm-templates/<chart> \
-f helm-overrides/<cluster>/<app>/custom-values.yaml \
--kube-context=<context>
```
### 6. Open the sister-repo PR
In `github.com/Meesho/devops-infra-argo-config`, draft an `Application` (or add to an existing `ApplicationSet`):
```yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: <release>-<cluster>
spec:
destination:
name: <cluster>
namespace: <workload-namespace>
source:
repoURL: https://github.com/Meesho/devops-infra-helm-charts.git
targetRevision: main
path: helm-overrides/<cluster>/<app>
helm:
valueFiles: [custom-values.yaml]
syncPolicy:
syncOptions: [CreateNamespace=true]
# Most infra apps DO NOT use automated sync — see ADR-A5
```
### 7. Open the values-side PR (this repo)
```bash
git checkout -b onboard/<chart>-on-<cluster>
git add helm-overrides/<cluster>/<app>/
git commit
# pre-commit hook runs TruffleHog
git push origin onboard/<chart>-on-<cluster>
gh pr create --base main --title "Onboard <chart> to <cluster>"
```
PR description:
- Procedure followed: this file.
- App owner approver tag.
- Cluster owner approver tag.
- Sister-repo PR link (`devops-infra-argo-config#<n>`).
- CMR ticket reference (if applicable).
- Confirmation that the chart renders cleanly and `helm diff` (if run) showed only additions.
### 8. After both merge — sync in Argo CD
`devops-infra-argo-config`'s reconciler will create the `Application` resource on the cluster's Argo CD. Most infra apps are **manual sync** ([ADR-A5](../../../wiki/analyses/ADR-A5-manual-sync-default-for-infra.md)), so the workload deploy is a separate step:
1. Open the cluster's Argo CD UI.
2. Search for the new `Application`.
3. Verify the manifest renders (Diff view shows the chart's resources).
4. Click **Sync**.
5. Watch the rollout: `kubectl --context=<context> get pods -n <ns> -w`.
---
## Anti-patterns
1. **Copying the entire `helm-overrides/<sibling-cluster>/<app>/` directory** verbatim. Per-cluster scheduling differs.
2. **Bundling onboarding with a chart-version bump.** Two separate PRs.
3. **Skipping the sister-repo PR.** Without an `Application`, the values do nothing.
4. **Setting `automated.{prune,selfHeal}: true`** in the sister-repo `Application` "to make life easier." Manual sync is the default safety property.
5. **Inlining secrets** in `custom-values.yaml`. Use `ExternalSecret`.
---
## Rollback
If the merge causes a problem before Sync:
- Revert the values-side PR (and the sister-repo PR).
- Argo CD will prune the `Application` resource on next reconcile of the sister repo.
If Sync was clicked and the workload broke:
- Click **Rollback** in Argo CD UI to the previous synced revision (if there is one).
- Or revert both PRs and re-Sync — the previous state had no `Application`, so the workload is removed.
---
## Related
- Schema: [custom-values-schema.md](../schemas/custom-values-schema.md), [raw-manifest-sidecar-schema.md](../schemas/raw-manifest-sidecar-schema.md).
- Procedure: [update-chart-version.md](update-chart-version.md) for bumping after onboarding.
- Procedure: [deboard-app.md](deboard-app.md) for retirement.
- Skill: [skills/infra/onboard-app.md](../../../skills/infra/onboard-app.md) — agent-callable wrapper.
- ADR: [ADR-A3-per-cluster-scheduling.md](../../../wiki/analyses/ADR-A3-per-cluster-scheduling.md).
@@ -0,0 +1,140 @@
# Procedure — Onboard a new cluster's overrides
> **Layer:** Layer 1 — HIGH RISK.
> **Blast radius:** establishing a new deployment target. Mistakes here are repeated for every app subsequently onboarded.
> **Approval:** platform team + cluster owner. CMR mandatory.
When a new GKE cluster is provisioned (typically by `terraform-gcp-infra` or its successor), this repo gains a new `helm-overrides/<cluster>/` directory and the sister repo gains the `ApplicationSet` (or per-cluster Applications) that route to it. This procedure covers the slice owned by `devops-infra-helm-charts`.
---
## Pre-conditions
- [ ] The cluster exists in GCP — confirmed by the platform team.
- [ ] The cluster is registered in the relevant Argo CD instance(s).
- [ ] The cluster's `nodeSelector` / `tolerations` / `computeClass` topology is documented (node pool names + taints).
- [ ] The cluster has a `SecretStore` / `ClusterSecretStore` for `external-secrets` — or onboarding `external-secrets` is part of this PR.
- [ ] CMR open.
---
## Steps
### 1. Confirm the naming convention
| Pattern | Use |
|---------|-----|
| `k8s-<bu>-prd-ase1[c]` | Standard BU prod cluster (GCP zone-a or zone-c) |
| `k8s-shared-int-ase1` | Shared int |
| `k8s-aurva-prd-ase1` | Aurva |
| `k8s-supply-dev-ase1` | Dev/sandbox |
| `db-<numeric-id>-...` | Auto-named dataplane / data-tier |
The directory name is a **contract** — it must match the cluster name as registered in Argo CD. Deviating by a hyphen or case is a silent bind failure.
### 2. Determine the cluster's scheduling profile
| Cluster type | Scheduling key |
|--------------|----------------|
| GKE Autopilot | `cloud.google.com/compute-class` |
| Standard GKE | `dedicated:` |
Get the actual node-pool / compute-class names from the cluster owner. If GKE Autopilot, also collect the list of `ComputeClass` resources that need to land in `helm-overrides/<cluster>/<app>/computeclass/`.
### 3. Decide the minimal app set
Most clusters need at least:
- `external-secrets` — to materialise secrets from GCP Secret Manager
- `kube-state-metrics` — for fleet observability
- `victoria-metrics-agent` — to ship metrics to the central VM
- `fluentd` (or equivalent log shipper)
Plus per-cluster role:
- BU clusters: `contour-internal-0`, `contour-internal-1`, sometimes `contour-external` — see [contour-nodeselector-tolerations-summary.md](../../../contour-nodeselector-tolerations-summary.md) for the convention
- DSGPU / Spark clusters: GPU operators, `keda` for queue autoscaling
- Dataplane (`db-*`) clusters: minimal — `kube-state-metrics` + `victoria-metrics-agent` only
### 4. Create the directory and minimal apps
```bash
mkdir -p helm-overrides/<cluster>
cd helm-overrides/<cluster>
```
For each app in the minimal set, follow [onboard-app-to-cluster.md](onboard-app-to-cluster.md) (one app per sub-PR after this base PR lands, OR all in one base PR — see step 7).
### 5. Update the per-cluster Contour matrix
If the cluster runs Contour, add a section to [contour-nodeselector-tolerations-summary.md](../../../contour-nodeselector-tolerations-summary.md) with the per-instance scheduling. Without this, future Contour edits on the cluster have no reference.
### 6. (If GKE Autopilot) Add the `ComputeClass` resources
Each Autopilot Contour / pool needs a corresponding `ComputeClass`. Drop them in:
```
helm-overrides/<cluster>/<app>/computeclass/<name>-cc.yaml
```
Schema: [raw-manifest-sidecar-schema.md §ComputeClass](../schemas/raw-manifest-sidecar-schema.md). The `metadata.name` of each `ComputeClass` must equal the value the corresponding app's `nodeSelector: {cloud.google.com/compute-class: <name>}` references.
### 7. Open the base PR
```bash
git checkout -b cluster/<cluster>-base
git add helm-overrides/<cluster>/
git add contour-nodeselector-tolerations-summary.md # if updated
git commit
git push origin cluster/<cluster>-base
gh pr create --base main --title "Onboard <cluster> — base override set"
```
PR description must include:
- Cluster owner approver tag.
- Platform team approver tag.
- CMR ticket.
- Sister-repo PR for the `ApplicationSet` / per-cluster `Application` set.
- The minimal app set being shipped, with per-app rationale.
- The cluster's scheduling profile (key style + sample `nodeSelector`).
### 8. Pair the sister-repo PR
In `github.com/Meesho/devops-infra-argo-config`, draft the `ApplicationSet` (or per-cluster Application set) that walks `helm-overrides/<cluster>/`. The sister-repo PR depends on this PR being merged first (otherwise the paths it references don't exist).
### 9. Stage subsequent app additions
After the base PR merges:
- Each additional app (`contour-internal-0`, `flagger`, etc.) is its own PR via [onboard-app-to-cluster.md](onboard-app-to-cluster.md).
- Don't try to land the whole cluster in one PR — review surface explodes; rollback is all-or-nothing.
---
## Anti-patterns
1. **Naming the directory `<cluster-name>` slightly differently** from how Argo CD registered it. Silent bind failure.
2. **Cloning another cluster's directory verbatim.** Per-cluster scheduling differs; `external-secrets` `SecretStore` references differ; image-tag pinning differs.
3. **Onboarding 30 apps in the base PR.** Stage them — base + per-app.
4. **Forgetting the Contour matrix update.** Future Contour edits then have no reference and silently mis-schedule.
5. **Skipping the `ComputeClass` resources** on a GKE Autopilot cluster. `nodeSelector` references a class that doesn't exist; pods Pending.
---
## Rollback
If the cluster onboarding turns out to be premature:
- Revert the values-side PR.
- Revert the sister-repo `ApplicationSet` PR.
- The cluster reverts to "no Argo Applications" — workloads that were synced manually before revert remain (Argo CD doesn't `prune` what's not in its scope after the `Application` is removed); for a clean wipe, manually `kubectl delete ns` the affected namespaces.
---
## Related
- Procedure: [onboard-app-to-cluster.md](onboard-app-to-cluster.md) — for each app after the base PR.
- Schema: [raw-manifest-sidecar-schema.md](../schemas/raw-manifest-sidecar-schema.md) — for `ComputeClass` and `ExternalSecret` sidecars.
- Reference: [contour-nodeselector-tolerations-summary.md](../../../contour-nodeselector-tolerations-summary.md).
- ADR: [ADR-A3-per-cluster-scheduling.md](../../../wiki/analyses/ADR-A3-per-cluster-scheduling.md).
@@ -0,0 +1,176 @@
# Procedure — Update a chart's pinned dependency version
> **Layer:** Layer 1 — HIGH RISK (charts in `helm-templates/` are consumed by every cluster that runs them).
> **Blast radius:** every cluster that has an Argo `Application` referencing this chart will pick up the new version on next sync.
> **Approval:** platform team. CMR mandatory for prod-fleet charts.
In this repo, charts in `helm-templates/<chart>/` are typically thin wrappers — `Chart.yaml` declares an upstream chart as a dependency, and `Chart.lock` pins the resolved subchart. "Bumping the chart version" means:
1. Update `dependencies[].version` in `Chart.yaml`.
2. Run `helm dependency update` to refresh `Chart.lock` (and re-pull the subchart).
3. Test render with representative cluster overrides.
---
## When to use this procedure
- Upgrading a wrapper chart's pinned subchart version (e.g. `argo-cd 7.7.23``7.8.0`).
- Following a security advisory in an upstream chart.
This is **not** the right procedure for:
- A blue-green migration to a new major version → use [blue-green-chart-migration.md](blue-green-chart-migration.md).
- Editing chart templates → use [fork-upstream-chart.md](fork-upstream-chart.md).
- Changing values without a chart bump → that's per-cluster `custom-values.yaml` work, not this.
---
## Pre-conditions
- [ ] The new upstream version exists and has a published changelog.
- [ ] You have read the changelog for breaking template / values changes.
- [ ] The bump is the **explicit headline** of the PR (not a side-effect of another change).
- [ ] CMR open if this is a prod-fleet chart (Argo CD, Contour, VictoriaMetrics, ingress, cert-manager).
---
## Steps
### 1. Read the changelog
```bash
# For most upstream charts:
helm repo update
helm search repo <repo>/<chart> --versions | head -20
# Read the chart's CHANGELOG.md or release notes on GitHub.
```
Look specifically for:
- **Removed values keys** — would silently no-op overrides.
- **Renamed values keys** — same.
- **CRD changes** — might require manual `kubectl apply` of new CRDs.
- **Breaking template changes** (e.g. label selector immutability on Deployments).
- **Required Kubernetes version bumps**.
If any of these apply, this is not a simple version bump — escalate to a blue-green migration ([blue-green-chart-migration.md](blue-green-chart-migration.md)).
### 2. Update `Chart.yaml`
```bash
$EDITOR helm-templates/<chart>/Chart.yaml
```
Find the `dependencies[]` entry and bump `version:`. Example:
```diff
dependencies:
- name: argo-cd
- version: 7.7.23
+ version: 7.8.0
repository: https://argoproj.github.io/argo-helm
```
### 3. Refresh `Chart.lock`
```bash
helm dependency update helm-templates/<chart>
```
This:
- Verifies the new version resolves.
- Updates `Chart.lock` with the new digest.
- Re-pulls the subchart `.tgz` into `helm-templates/<chart>/charts/`.
The lockfile must be committed alongside `Chart.yaml`. A bump without a refreshed lockfile is incomplete.
### 4. Render against a representative cluster's overrides
Pick a cluster that runs this chart with a non-trivial override set:
```bash
sibling=$(find helm-overrides -maxdepth 2 -type d -name '<chart>' \
| grep -v '^helm-overrides/db-' | head -1)
helm template <chart> helm-templates/<chart> -f "$sibling/custom-values.yaml" | head -120
```
If the render errors → the chart bump introduced a values incompatibility. **Stop.** Either:
- Find the new values shape and update affected `custom-values.yaml` files in this PR, OR
- Defer the bump until those updates are scoped.
### 5. Spot-check `helm diff` against a live cluster (recommended)
```bash
helm diff upgrade <release> helm-templates/<chart> \
-f helm-overrides/<cluster>/<app>/custom-values.yaml \
--kube-context=<cluster-context>
```
What you want to see:
- Image tag bumps.
- Label updates (often `helm.sh/chart`).
- Possibly new CRDs or RBAC.
What's a red flag:
- `Deployment` selector changes (immutable; will fail to apply).
- `StatefulSet` `volumeClaimTemplates` changes.
- Resource removals you didn't expect.
### 6. Commit and open the PR
```bash
git checkout -b chart-bump/<chart>-<new-version>
git add helm-templates/<chart>/Chart.yaml helm-templates/<chart>/Chart.lock
git add helm-templates/<chart>/charts/ # if the .tgz was re-pulled
git commit
git push origin chart-bump/<chart>-<new-version>
gh pr create --base main --title "chart bump: <chart> <old> → <new>"
```
PR description:
- Procedure followed: this file.
- Old → new with a link to the upstream changelog.
- The list of clusters that consume this chart (`grep -rl '<chart>' helm-overrides | head`).
- The render(s) and diff(s) you ran.
- Whether any breaking-change fallout is bundled (preferably not — if so, scope to a separate PR).
### 7. After merge — Argo CD picks up the new chart on next sync
For each cluster running this chart:
- The cluster's Argo CD detects the chart hash change.
- The `Application` becomes `OutOfSync`.
- A human clicks **Sync** per [ADR-A5](../../../wiki/analyses/ADR-A5-manual-sync-default-for-infra.md).
- Watch rollout per cluster — don't sync 20 clusters simultaneously.
---
## Anti-patterns
1. **Bumping `Chart.yaml` without refreshing `Chart.lock`.** Argo CD uses the lockfile; the bump silently no-ops.
2. **Bundling a chart bump with values changes.** Two separate PRs — one for the bump, one for any values that need to change because of the bump.
3. **Bumping a major version (e.g. 7.x → 8.x) in place.** Use [blue-green-chart-migration.md](blue-green-chart-migration.md) — give yourself a sibling chart and migrate cluster-by-cluster.
4. **Syncing every cluster simultaneously after merge.** Stagger; one cluster at a time, with a soak between.
5. **Skipping the changelog read.** Surprises you'll regret.
---
## Rollback
Open a follow-up PR that reverts `Chart.yaml` and `Chart.lock` to the previous versions. After merge, each cluster's Argo CD shows `OutOfSync` against the old chart; click **Sync** to roll back per cluster.
If the chart bump landed CRDs that are now incompatible with the old version, the rollback may require manual CRD cleanup — coordinate with the platform team.
---
## Related
- Procedure: [blue-green-chart-migration.md](blue-green-chart-migration.md) — for major-version bumps.
- Procedure: [fork-upstream-chart.md](fork-upstream-chart.md) — when the bump requires template edits.
- Skill: [skills/infra/bump-chart-version.md](../../../skills/infra/bump-chart-version.md).
- ADR: [ADR-A1-cache-vs-upstream-charts.md](../../../wiki/analyses/ADR-A1-cache-vs-upstream-charts.md).
@@ -0,0 +1,231 @@
# Runbook — Argo CD Sync Failure (infra release)
> **Type:** Decision tree.
> **Entry symptom:** an Argo CD `Application` for an infra release is `OutOfSync`, errored, or stuck `Progressing`.
> **Layer:** mostly Layer 1 (read state, propose YAML diff). Some branches are Layer 2 (advisory).
This runbook handles sync failures for infra Applications routed by `github.com/Meesho/devops-infra-argo-config` and rendering against this repo's `helm-overrides/<cluster>/<app>/`.
---
## Entry — gather context
```bash
APP=<release> # e.g. argocd, contour-internal-0
CLUSTER=<cluster-name> # e.g. k8s-supply-prd-ase1
NS=$(argocd app get $APP -o json | jq -r '.spec.destination.namespace')
PROJECT=$(argocd app get $APP -o json | jq -r '.spec.project')
argocd app get $APP # headline
argocd app get $APP -o json | jq -r '.status.conditions[]?'
argocd app get $APP -o json | jq -r '.status.operationState.message // empty'
```
Note which Argo CD instance you're hitting — most infra Applications live in a per-cluster Argo CD install.
---
## Decision tree
```text
START
└── Is `argocd app get $APP` known to this Argo at all?
├── NO → §1 — Application not found
└── YES → What's the symptom?
├── Sync failed with an error message → §2 — Errored sync
├── Sync stuck `Progressing` for >5 min → §3 — Stuck progressing
├── App is `OutOfSync` but Sync hasn't run → §4 — OutOfSync only
└── `Synced`+`Healthy` but workload bad → §5 — Wrong workload (leave runbook)
```
---
## §1 — Application not found
| Sub-check | Action |
|-----------|--------|
| Are you on the right Argo CD instance? | Most v2 infra apps live in per-cluster Argo CDs. |
| Was the app deboarded recently? | `git -C <argo-config> log --diff-filter=D -- 'apps/<cluster>/<app>*'` and `git log --diff-filter=D -- 'helm-overrides/<cluster>/<app>/'`. |
| Did the values directory land on `main`? | `git log --all -- 'helm-overrides/<cluster>/<app>/'`. |
If the file *should* exist on `main` but the `Application` resource isn't created → **Layer 2** — escalate to the platform team. The cluster's Argo CD bootstrap (`ApplicationSet`) may not be picking up the path.
---
## §2 — Errored sync (read the error message)
### §2a — `repository not accessible / authentication required`
| Action |
|--------|
| Check `spec.source.repoURL` is `github.com/Meesho/devops-infra-helm-charts.git`. |
| If yes, the credentials in Argo CD's repo-list need refreshing. **Layer 2** — recommend platform team rotates credentials. |
### §2b — `path 'X' does not exist in repo Y`
```text
path 'helm-overrides/k8s-supply-prd-ase1/argocd' does not exist
```
| Action |
|--------|
| `ls helm-overrides/<cluster>/<app>/` on `main`. |
| If absent → either the values-side PR wasn't merged, or the path was typo'd in the sister-repo `Application`. **Layer 1** — open a fix PR (sister repo). |
| If a blue-green migration just landed: the `Application` may be pointing at the **old** chart path that was retired. **Layer 1** — repoint the `Application` to the new sibling path. |
### §2c — `Helm template error` / `values file not found`
```text
open helm-overrides/<cluster>/<app>/custom-values.yaml: no such file or directory
```
| Action |
|--------|
| Verify the file exists on `main`: `git ls-tree origin/main -- helm-overrides/<cluster>/<app>/custom-values.yaml`. |
| If absent → onboarding is incomplete. **Layer 1** — open the missing values-side PR. |
### §2d — `unable to render manifests` / `template error`
Helm template error inside the chart (missing required value, type mismatch).
| Action |
|--------|
| Reproduce locally: `helm template <app> helm-templates/<chart> -f helm-overrides/<cluster>/<app>/custom-values.yaml`. |
| Determine whether the fix is in this repo (rare — usually values shape changed) or `helm-templates/<chart>` (more common after a chart bump). **Layer 1**. |
| If the error is `Cannot use existing release: ...` — see §2h. |
### §2e — `cluster not found / dial tcp ... no route to host`
| Action |
|--------|
| **Layer 2** — escalate to platform team. Cluster API server unreachable, or cluster-secret stale in Argo CD. |
| Do **not** edit `spec.destination.{server,name}` to redirect; that masks the underlying cluster issue. |
### §2f — `forbidden: ...` / admission webhook deny
```text
admission webhook "validate.kyverno.svc-fail" denied the request
```
| Action |
|--------|
| Look at the rule that denied (Kyverno? PSP? OPA? GKE Autopilot policy?). |
| Often the chart's manifest violates a cluster policy (e.g. `runAsUser: 0`, missing `securityContext`). |
| **Layer 1** — fix in chart values; pair with the policy team if the policy is wrong. |
| GKE Autopilot specifically denies many privileged settings — read the deny message carefully. |
### §2g — `webhook errored: ... cert-manager / external-secrets / kyverno`
A webhook that should validate the new resource is itself unhealthy.
| Action |
|--------|
| `kubectl get pods -n cert-manager` (or the relevant operator's namespace) — is it running? |
| **Layer 2** — recommend recovering the webhook before re-syncing this app. |
### §2h — `cannot patch ... immutable field`
Most often: `Deployment.spec.selector` or `StatefulSet.volumeClaimTemplates`. A chart bump that changes labels.
| Action |
|--------|
| Read the upstream changelog to confirm. |
| **Layer 2** — recommend deleting the old `Deployment` / `StatefulSet` (with the workload owner) so the chart can recreate it. **Do not delete blindly** — for `StatefulSet`, the PVCs survive but the rollout is disruptive. |
| For systemic immutable-field changes across a chart bump, this is a sign the bump should have been a [blue-green migration](../procedures/blue-green-chart-migration.md). Roll back, plan the migration. |
### §2i — `dependent CRD ... not installed`
The chart needs a CRD that doesn't exist yet on the cluster.
| Action |
|--------|
| Check whether the chart includes the CRD in `templates/crds/` (most upstream charts ship CRDs). |
| If yes: the chart's `helm template` may not include CRDs by default — Argo CD has `IncludeCRDs` semantics; check the `Application`'s `helm.skipCrds` setting. |
| If the CRD is supposed to come from a different chart (`cert-manager`, `kube-prometheus-stack`): **Layer 2** — sync that chart first. |
---
## §3 — Stuck `Progressing` for > 5 minutes
The sync started but resources aren't reconciling.
| Sub-check | Action |
|-----------|--------|
| `argocd app get $APP --refresh` shows resource-level status. | Look for `Progressing` resources. |
| Is a Deployment failing to roll out? | `kubectl rollout status deploy/<name> -n $NS`. If yes → see [pod-pending-scheduling.md](pod-pending-scheduling.md) or [ingress-down.md](ingress-down.md). |
| Is a Job hung? | `kubectl describe job/<name> -n $NS`. Old `Job`s sometimes block syncs (Helm pre-/post-install hooks). |
| Is a `PreSync`/`PostSync` hook hanging? | `kubectl get pods -n $NS -l argocd.argoproj.io/hook=PostSync`. |
If the workload itself is the problem, leave this runbook.
---
## §4 — `OutOfSync` only (no error, sync hasn't run)
Argo CD sees a diff between git and the cluster. **Most infra apps are intentionally manual-sync** ([ADR-A5](../../../wiki/analyses/ADR-A5-manual-sync-default-for-infra.md)).
| Sub-check | Action |
|-----------|--------|
| Is this expected? (e.g. you just merged a PR.) | Click Sync. |
| Diff suspicious? (e.g. someone `kubectl edit`-ed.) | `argocd app diff $APP`. If out-of-band edit happened, the GitOps contract was violated; recommend reverting the manual change or capturing it in a PR. |
| Diff has sat for > 1 day? | Notify the app owner — manual-sync apps rot if no one clicks. |
---
## §5 — `Synced` and `Healthy` but workload misbehaving
Argo thinks all is fine; the workload is broken. Not a sync failure. **Leave this runbook.**
| Symptom | Where to go |
|---------|-------------|
| Pods crashlooping | [pod-pending-scheduling.md](pod-pending-scheduling.md) §3 |
| Ingress 5xx | [ingress-down.md](ingress-down.md) |
| Specific feature broken | App-team playbook |
---
## §6 — Special: blue-green migration in flight
If this app is in a `<chart>``<chart>-<variant>` migration:
- Confirm which variant the `Application` points at (check `spec.source.path`).
- The chart name may have changed in the new variant; release-name pinning via `fullnameOverride` may be required to keep the same Service DNS during cutover.
- A failed sync mid-migration is the trigger to roll back (`spec.source.path` ← old) and Sync, not to push forward.
- Read [blue-green-chart-migration.md](../procedures/blue-green-chart-migration.md) before deciding.
---
## Escalation matrix
| Symptom | Action | Escalate to |
|---------|--------|-------------|
| §1 + bootstrap looks healthy | Investigate further | App owner |
| §2a (repo auth) | Confirm allowed repoURL; rotate creds | Platform team |
| §2b (path missing) | Fix in this repo or sister repo | App owner |
| §2c, §2d (helm render) | Reproduce; fix values or chart | App owner / platform team |
| §2e (cluster unreachable) | Don't edit destination | Platform team |
| §2f (admission webhook) | Fix in chart values | App + policy team |
| §2g (webhook unhealthy) | Recover the webhook first | Platform team |
| §2h (immutable field) | Probably needs blue-green | Platform team |
| §3 (stuck > 30 min) | Check pod events; consider workload rollback | App owner |
---
## Done conditions
- `argocd app get $APP` shows `Synced` + `Healthy`.
- The PR or manual fix that resolved it is on `main`.
- If the failure was caused by a regression, a postmortem / RCA is scheduled.
---
## Related
- Runbook: [pod-pending-scheduling.md](pod-pending-scheduling.md).
- Runbook: [ingress-down.md](ingress-down.md).
- Schema: [custom-values-schema.md](../schemas/custom-values-schema.md).
- Boundaries: [AGENT_BOUNDARIES.md](../../global/AGENT_BOUNDARIES.md).
+197
View File
@@ -0,0 +1,197 @@
# Runbook — Ingress (Contour) is down on a cluster
> **Type:** Decision tree.
> **Entry symptom:** services on a cluster are returning 5xx, not reachable, or DNS doesn't resolve to working endpoints.
> **Layer:** mostly Layer 2 (advisory — recommend kubectl actions). Layer 1 only when the fix is a values diff in this repo.
Contour is the ingress for almost every BU cluster, and most clusters run **multiple Contour releases**`contour-external`, `contour-external-1`, `contour-internal-0`, `contour-internal-1`, `contour-internal-intra-{0,1}`. Each maps to a different node pool / dedicated taint or compute class. The matrix is in [contour-nodeselector-tolerations-summary.md](../../../contour-nodeselector-tolerations-summary.md). **Read it before editing any Contour values.**
---
## Entry — gather context
```bash
CLUSTER=<cluster>
CTX=<kubectl-context>
# Which Contour instances does this cluster run?
ls helm-overrides/$CLUSTER | grep '^contour'
# Pod state for each Contour
for c in $(ls helm-overrides/$CLUSTER | grep '^contour'); do
echo "=== $c ==="
kubectl --context=$CTX get pods -n projectcontour -l app.kubernetes.io/instance=$c -o wide 2>/dev/null \
|| kubectl --context=$CTX get pods --all-namespaces -l app.kubernetes.io/instance=$c -o wide
done
```
---
## Decision tree
```text
START
└── Which Contour instance is affected?
├── External (`contour-external*`) → §A — North-south traffic
├── Internal (`contour-internal-*`) → §B — East-west traffic
└── Both / unsure → §C — Cluster-wide (worst case)
```
For each branch:
```text
└── What's the failure shape?
├── Pods Pending → §1 — Scheduling failure
├── Pods CrashLooping → §2 — Contour boot failure
├── Pods Running but no endpoints → §3 — Service / load-balancer unhealthy
├── HTTPS responses are 5xx → §4 — Backend / cert / config error
└── DNS doesn't resolve → §5 — external-dns / DNS plumbing
```
---
## §1 — Contour pods Pending
This is almost always a scheduling-key mismatch. **The single most common Contour incident.**
```bash
kubectl --context=$CTX describe pod <contour-pod>
```
Read the `Events:` section. Common causes:
| Reason | Fix in |
|--------|--------|
| `0/N nodes available: 1 node(s) had untolerated taint <key>=<value>` | Tolerations in `helm-overrides/<cluster>/<contour-instance>/custom-values.yaml`. Cross-reference [contour-nodeselector-tolerations-summary.md](../../../contour-nodeselector-tolerations-summary.md). **Layer 1.** |
| `0/N nodes available: 1 node(s) didn't match Pod's node affinity/selector` | `nodeSelector` in the values. Same fix. **Layer 1.** |
| `0/N nodes available: 1 node(s) had no available compute class` (GKE Autopilot) | Either the `ComputeClass` resource is missing, or `nodeSelector: cloud.google.com/compute-class: <X>` references a class that doesn't exist. Check `helm-overrides/<cluster>/<contour-instance>/computeclass/*-cc.yaml`. **Layer 1.** |
| `0/N nodes available: insufficient cpu/memory` | Node-pool autoscaler is at max. **Layer 2** — escalate to cluster owner / platform team. |
The fix is always to bring the values' `nodeSelector` / `tolerations` into agreement with the cluster's actual node-pool topology. Never guess — read the matrix and the cluster's other apps.
---
## §2 — Contour pods CrashLooping
```bash
kubectl --context=$CTX logs <contour-pod> -c contour --previous
kubectl --context=$CTX logs <contour-pod> -c envoy --previous
```
| Pattern | Cause | Fix in |
|---------|-------|--------|
| `failed to load TLS certificates` | Missing `Secret`, expired cert, wrong key | `cert-manager` / `external-secrets`. **Layer 2.** |
| `error parsing config: invalid HTTPProxy` | A user `HTTPProxy` is malformed and Contour refuses to load | The user's namespace. **Layer 2** — recommend `kubectl get httpproxy -A` to find the offender, then fix in the consuming team's repo. |
| `bind: address already in use` | Two Contour pods on the same node fighting for the host port | Pod anti-affinity in values. **Layer 1.** |
| `error: ratelimit service ... unavailable` | `contour-rate-limit` sidecar / external service is down | Operator action. **Layer 2.** |
---
## §3 — Contour Running but no endpoints / LB unhealthy
The Contour pods are healthy, but downstream LB / DNS / Service routing is broken.
```bash
kubectl --context=$CTX get svc -n projectcontour
kubectl --context=$CTX get endpoints -n projectcontour
kubectl --context=$CTX describe svc <contour-svc> -n projectcontour
```
| Sub-check | Action |
|-----------|--------|
| `Service` of type `LoadBalancer` has no `EXTERNAL-IP` | GCP LB provisioning failed. Check the `Service` annotations match the cluster's LB pattern. **Layer 2** — escalate. |
| `Endpoints` empty | The Contour pods aren't matching the `Service` selector. Often a label drift between values and the chart's defaults. **Layer 1** — fix selectors. |
| `Service` annotations mention `cloud.google.com/load-balancer-type: Internal` but external traffic is expected | Wrong Contour instance / Service annotation. **Layer 1.** |
| `Health checks failing` on the GCP LB | Backend pods aren't ready. See §4. |
---
## §4 — HTTPS responses are 5xx
Don't curl the production endpoint yourself — that violates [SANCTITY_RULES R3](../../global/SANCTITY_RULES.md). Instead, recommend the user check from a controlled vantage:
```bash
# From inside the cluster
kubectl --context=$CTX run -it --rm curl-test --image=curlimages/curl --restart=Never -- \
curl -v https://<service>.<ns>.svc.cluster.local
# Contour access logs
kubectl --context=$CTX logs <envoy-pod> -c envoy | tail -50
```
| Pattern | Cause | Fix in |
|---------|-------|--------|
| `503 no_healthy_upstream` | Backend pods all unhealthy | App's pod readiness — see [pod-pending-scheduling.md](pod-pending-scheduling.md). **Layer 2.** |
| `502 upstream connect error` | Backend connection refused / TLS mismatch | App config / mTLS. **Layer 2.** |
| `404 route not found` | No matching `HTTPProxy`/`Ingress` | The user's `HTTPProxy` is missing or has the wrong host/path. **Layer 2.** |
| `500` from the app | Application error | App-team playbook. **Out of scope for this runbook.** |
---
## §5 — DNS doesn't resolve
| Sub-check | Action |
|-----------|--------|
| Is `external-dns` running on this cluster? | `kubectl --context=$CTX get pods -n external-dns`. |
| Are there `Service` resources with `external-dns.alpha.kubernetes.io/hostname` annotations? | `kubectl --context=$CTX get svc -A -o json \| jq '.items[] \| select(.metadata.annotations."external-dns.alpha.kubernetes.io/hostname")'`. |
| Did `external-dns` reconcile recently? | `kubectl --context=$CTX logs deploy/external-dns -n external-dns \| tail -30`. |
| Is the Cloud DNS zone wired up? | **Layer 2** — out of scope; escalate to platform team. |
---
## §C — Cluster-wide ingress outage
If both internal and external Contour are degraded simultaneously:
1. **Stop. Don't iterate values fixes.** This is incident-grade.
2. **Layer 2 — escalate to platform team immediately.**
3. Check whether a recent merge in this repo or the sister repo correlates: `git log --since='2 hours ago' -- helm-overrides/$CLUSTER/contour*` and the same in `devops-infra-argo-config`.
4. If a recent merge is implicated: revert it, click Sync to roll back to the previous state.
5. If no recent merge: cluster-level issue (node pool, network policy, GCP LB) — out of scope for this repo.
---
## When this repo *is* the right place to fix
A Contour outage traces back to `devops-infra-helm-charts` only when:
1. **`nodeSelector` / `tolerations` / `computeClass`** were copied from the wrong cluster.
2. **A chart bump** introduced an immutable-selector change or removed a values key.
3. **A blue-green migration** was cutover prematurely (Application points at `<contour>-vX.Y.Z` but values are still on the old shape).
4. **`fullnameOverride`** was changed (very rare, but catastrophic).
For 80%+ of ingress incidents, the fix is **outside** this repo (cluster issues, app-side issues, GCP LB, DNS).
---
## Escalation matrix
| Symptom | First responder | Escalate to |
|---------|-----------------|-------------|
| §1 (pending — scheduling) | Yourself with the values fix | Cluster owner if node pool full |
| §2 (CrashLoop — TLS) | cert-manager team | Security if cert source unknown |
| §2 (CrashLoop — invalid HTTPProxy) | Consuming team | Platform if Contour itself is broken |
| §3 (no endpoints / LB) | Cluster owner | Platform team |
| §4 (5xx) | App team | Platform team if Contour-side |
| §5 (DNS) | Platform team | — |
| §C (cluster-wide outage) | Platform team — pager | — |
---
## Done conditions
- `kubectl get pods -n projectcontour` shows N/N Ready for the affected instances.
- Synthetic probes from the app team return expected status codes.
- If the root cause was in this repo, the fix is on `main` and synced.
---
## Related
- Reference: [contour-nodeselector-tolerations-summary.md](../../../contour-nodeselector-tolerations-summary.md).
- Runbook: [pod-pending-scheduling.md](pod-pending-scheduling.md).
- Runbook: [argocd-sync-failure.md](argocd-sync-failure.md).
- ADR: [ADR-A3-per-cluster-scheduling.md](../../../wiki/analyses/ADR-A3-per-cluster-scheduling.md).
+233
View File
@@ -0,0 +1,233 @@
> Per AI Blitz Plan §platform.runbooks. Layer: 1. Repo: devops-infra-helm-charts.
# Runbook — Metrics gap on a cluster / namespace
> **Type:** Decision tree.
> **Entry symptom:** "Grafana panels are blank for `<cluster>` / `<namespace>` / `<service>`," or an alert that should be firing isn't, or VictoriaMetrics shows `no data`.
> **Layer:** mostly Layer 2 (advisory). Layer 1 only when the fix is a values diff in this repo.
The observability path on Meesho's GKE fleet is:
```
workload Pod (exposes /metrics)
└→ victoria-metrics-agent (vmagent) scrapes
└→ remote_write to victoria-metrics-cluster (vmstorage)
└→ vmselect ← Grafana / vmalert query
```
A metrics gap can be at any hop. Walk this tree top-down — the most common root cause is hop 1 (scrape config).
---
## Entry — gather context
```bash
CLUSTER=<cluster>
CTX=<kubectl-context>
NS=<workload-namespace-where-metric-is-missing>
METRIC=<metric-name-or-job-label>
# Confirm the cluster runs VM agent + cluster
ls helm-overrides/$CLUSTER | grep -E '^victoria-metrics-(agent|cluster)'
# Confirm pods are healthy
kubectl --context=$CTX -n monitoring get pods -l app.kubernetes.io/name=victoria-metrics-agent -o wide
kubectl --context=$CTX -n monitoring get pods -l app.kubernetes.io/name=vmstorage -o wide
```
If pods are missing/CrashLooping → that's the gap. Skip to §5.
---
## Decision tree
```text
START
├── Is the metric known to be emitted by the workload?
│ ├── No → §0 — Workload not emitting; out of scope (app team)
│ └── Yes →
├── §1 — Is vmagent scraping the workload?
│ ├── No → fix scrape config (Layer 1)
│ └── Yes →
├── §2 — Are scrape targets healthy (status=up)?
│ ├── Down → fix endpoint reachability (Layer 2 / Layer 1)
│ └── Up →
├── §3 — Are relabel rules dropping the metric?
│ ├── Yes → adjust relabel_configs (Layer 1)
│ └── No →
├── §4 — Is remote_write succeeding?
│ ├── No → vmagent → vmstorage path broken (Layer 2 / Layer 1)
│ └── Yes →
├── §5 — Is vmstorage healthy and ingesting?
│ ├── No → vmstorage outage (Layer 2)
│ └── Yes →
└── §6 — Is the Grafana datasource / tenant correct?
└── Misrouted query → fix datasource URL or tenant header (Layer 1)
```
---
## §0 — Workload not emitting
Out of scope for this repo. Confirm with:
```bash
# Port-forward and curl /metrics directly
kubectl --context=$CTX -n $NS port-forward <pod> 9090:<metrics-port> &
curl -s localhost:9090/metrics | grep -i "$METRIC"
```
If `/metrics` is empty or doesn't contain `$METRIC` → app team. Stop.
---
## §1 — Is vmagent scraping the workload?
```bash
# vmagent UI exposes /api/v1/targets
kubectl --context=$CTX -n monitoring port-forward svc/victoria-metrics-agent 8429:8429 &
curl -s localhost:8429/api/v1/targets | jq '.data.activeTargets[] | select(.labels.namespace=="'$NS'")'
```
If no targets for `$NS`:
- Look at `helm-overrides/$CLUSTER/victoria-metrics-agent/custom-values.yaml`.
- Check the `additionalScrapeConfigs` (or `config.scrape_configs`) for a job that matches the workload's labels / namespace selector.
- Common cause: a `kubernetes_sd_configs` `namespaces.names` filter excludes `$NS`.
- Common cause: a missing `Pod`/`Service`/`PodMonitor` annotation `prometheus.io/scrape: "true"` on the workload.
**Layer 1 fix** (if the gap is in the scrape config): edit `helm-overrides/$CLUSTER/victoria-metrics-agent/custom-values.yaml` per [../procedures/modify-observability-config.md](../procedures/modify-observability-config.md).
**Layer 2 fix** (if the gap is on the workload — missing annotation): hand off to app team.
---
## §2 — Targets healthy?
```bash
# In the same vmagent /targets output
curl -s localhost:8429/api/v1/targets | jq '.data.activeTargets[] | select(.health!="up") | {labels, lastError}'
```
If targets are `down`:
| `lastError` | Cause | Fix |
|-------------|-------|-----|
| `connection refused` | Workload not listening on declared port | App team — Layer 2. |
| `i/o timeout` | NetworkPolicy / firewall blocking vmagent → workload | Check `NetworkPolicy` in `$NS`. Often a NetworkPolicy allowing only intra-namespace traffic and not vmagent's namespace. **Layer 2** — recommend the workload team allow vmagent. |
| `x509: certificate signed by unknown authority` | mTLS misconfigured | App team — Layer 2. |
| `404 Not Found` | Wrong path (default `/metrics` vs custom) | Add `metrics_path:` in scrape config. **Layer 1.** |
---
## §3 — Relabel rules dropping the metric?
```bash
yq e '.config.scrape_configs[].metric_relabel_configs, .config.scrape_configs[].relabel_configs' \
helm-overrides/$CLUSTER/victoria-metrics-agent/custom-values.yaml
```
Look for:
- `action: drop` rules with regexes matching `$METRIC`.
- `action: keep` rules whose regex *excludes* `$METRIC`.
- `action: labeldrop` removing a label the query uses.
Test in vmagent's UI under the *Targets* tab — it shows the labels post-relabel.
**Layer 1 fix:** loosen the relabel rule. Re-PR per [../procedures/modify-observability-config.md](../procedures/modify-observability-config.md).
---
## §4 — Remote_write succeeding?
```bash
kubectl --context=$CTX -n monitoring logs deploy/victoria-metrics-agent | grep -i 'remote_write\|error\|failed' | tail -20
```
| Symptom | Cause | Fix |
|---------|-------|-----|
| `429 Too Many Requests` from vmstorage | vmstorage ingest saturated | Scale vmstorage / vminsert (Layer 1 — see [observability.md](../../global/coding-guidelines/observability.md)). |
| `connection refused` to vmstorage URL | vmstorage Service down or wrong URL | Verify `remoteWrite.url` in vmagent values matches the live `vmstorage` Service DNS. Layer 1. |
| `out of bounds timestamp` | Clock skew on vmagent's node | Layer 2 — node time sync. |
| `series limit exceeded` | Cardinality bomb on vmstorage tenant | Layer 1 — drop the offending label. See [observability.md §Cardinality](../../global/coding-guidelines/observability.md). |
---
## §5 — vmstorage healthy?
```bash
kubectl --context=$CTX -n monitoring get pods -l app.kubernetes.io/name=vmstorage -o wide
kubectl --context=$CTX -n monitoring describe pod vmstorage-0 | tail -30
kubectl --context=$CTX -n monitoring exec vmstorage-0 -- df -h /storage
```
Failure modes:
| Symptom | Layer | Fix |
|---------|-------|-----|
| Pod CrashLooping with `out of disk` | Layer 1 | Bump `persistence.size`. Note: PVC growth requires the StorageClass to support `allowVolumeExpansion: true`. See [../schemas/storageclass-priorityclass-schema.md](../schemas/storageclass-priorityclass-schema.md). |
| Pod CrashLooping with retention/index errors | Layer 2 | Escalate — may need data-side intervention. |
| Pod Pending | Layer 1 | Scheduling issue. See [pod-pending-scheduling.md](pod-pending-scheduling.md) and [../../../wiki/analyses/ADR-A3-per-cluster-scheduling.md](../../../wiki/analyses/ADR-A3-per-cluster-scheduling.md). |
| Pod Running but vmselect can't reach it | Layer 1 / 2 | Verify the headless Service and StatefulSet pod-DNS records. |
---
## §6 — Grafana datasource / tenant correct?
```bash
yq e '.datasources.datasources.yaml.datasources[] | select(.name == "*VictoriaMetrics*" or .type == "prometheus")' \
helm-overrides/$CLUSTER/grafana/custom-values.yaml
```
| Sub-check | Action |
|-----------|--------|
| `url:` points at the correct in-cluster vmselect Service DNS | If wrong, **Layer 1** — fix the values per [../procedures/modify-observability-config.md](../procedures/modify-observability-config.md). |
| `httpHeaderName1: X-Scope-OrgID` (multi-tenant clusters only) | If the cluster runs multi-tenant VM, the tenant header must be set. Layer 1 fix. |
| Datasource `url:` points at an external `*.meeshogcp.in` host | Forbidden — see [../../global/SANCTITY_RULES.md](../../global/SANCTITY_RULES.md) R3. Repoint at in-cluster Service DNS. |
---
## Remediation summary
| Hop | Likely fix | Layer | Procedure |
|-----|-----------|-------|-----------|
| §1 scrape | Add scrape config / fix selector | 1 | [../procedures/modify-observability-config.md](../procedures/modify-observability-config.md) |
| §2 endpoint | Workload-side / NetworkPolicy | 2 | Hand off to app team |
| §3 relabel | Loosen drop rule | 1 | [../procedures/modify-observability-config.md](../procedures/modify-observability-config.md) |
| §4 remote_write | Scale vmstorage / fix URL | 1/2 | [../procedures/modify-observability-config.md](../procedures/modify-observability-config.md) |
| §5 vmstorage | PVC grow / scheduling fix | 1/2 | [pod-pending-scheduling.md](pod-pending-scheduling.md) |
| §6 datasource | Fix Grafana datasource | 1 | [../procedures/modify-observability-config.md](../procedures/modify-observability-config.md) |
---
## Escalation triggers
- §5 vmstorage outage with no obvious values-side fix → platform team (observability owner).
- Multi-cluster simultaneous metrics gap → platform team — cluster-level / control-plane issue.
- Cardinality explosion impacting vmstorage stability → platform team + workload owner — joint fix.
---
## Done conditions
- The query that was returning `no data` returns the expected series in Grafana Explore.
- No remote_write errors in vmagent logs for at least 5 minutes post-fix.
- Alerts that depend on the metric have transitioned from `pending` / silent back to expected state.
---
## Related
- Procedure: [../procedures/modify-observability-config.md](../procedures/modify-observability-config.md).
- Procedure: [../procedures/modify-alert-rules.md](../procedures/modify-alert-rules.md) — if the gap is "alert silent" not "metric missing."
- Coding guideline: [../../global/coding-guidelines/observability.md](../../global/coding-guidelines/observability.md).
- Runbook: [pod-pending-scheduling.md](pod-pending-scheduling.md) — for §5 vmstorage scheduling failures.
- Runbook: [argocd-sync-failure.md](argocd-sync-failure.md) — if a sync didn't take.
@@ -0,0 +1,192 @@
# Runbook — Pod Pending / wrong-node scheduling
> **Type:** Decision tree.
> **Entry symptom:** an infra workload's pods are `Pending` indefinitely, or scheduling onto the wrong node pool.
> **Layer:** mostly Layer 2 (advisory — recommend kubectl). Layer 1 when the fix is a values edit here.
The single most common values-side bug in this repo is **`nodeSelector` / `tolerations` / `computeClass` copied from the wrong cluster**. ([SANCTITY_RULES R5](../../global/SANCTITY_RULES.md))
---
## Entry — gather context
```bash
APP=<release>
CLUSTER=<cluster>
CTX=<kubectl-context>
NS=<namespace>
kubectl --context=$CTX get pods -n $NS -o wide
kubectl --context=$CTX describe pod <pod> -n $NS | tail -40 # Events: section
```
---
## Decision tree
```text
START
└── What state are the pods in?
├── Pending — never scheduled → §1 — Pending pods
├── ContainerCreating long → §1 — Pending pods
├── Running but on the WRONG node pool → §2 — Wrong-pool scheduling
├── ImagePullBackOff / ErrImagePull → §3 — Image pull
├── CrashLoopBackOff → §4 — Crash loop
├── Running but PVC unbound → §5 — Storage
└── Running fine → leave runbook
```
---
## §1 — Pending pods
```bash
kubectl --context=$CTX describe pod <pod> -n $NS
```
Read the `Events:` section. Common patterns:
| Reason | Diagnosis | Fix in |
|--------|-----------|--------|
| `0/N nodes available: 1 node(s) had untolerated taint {key: dedicated, value: <X>, effect: NoSchedule}` | Pod has wrong toleration or no toleration. | `helm-overrides/<cluster>/<app>/custom-values.yaml` `tolerations:`. **Layer 1.** |
| `0/N nodes available: 1 node(s) didn't match Pod's node affinity/selector` | Pod's `nodeSelector` doesn't match any node label. | Values `nodeSelector:`. **Layer 1.** |
| `0/N nodes available: ... had no available compute class` (Autopilot) | `cloud.google.com/compute-class: <X>` references a `ComputeClass` that doesn't exist on the cluster. | (a) Add the `ComputeClass` resource under `helm-overrides/<cluster>/<app>/computeclass/`, or (b) use the right class name. **Layer 1.** |
| `0/N nodes available: insufficient cpu` / `insufficient memory` | Node-pool autoscaler at max, or pod's `requests` too high. | Either reduce `resources.requests`, or **Layer 2** — escalate to cluster owner to raise node-pool max. |
| `0/N nodes available: pod has unbound immediate PersistentVolumeClaims` | PVC is `Pending`. | See §5. |
| `0/N nodes available: didn't tolerate node-pressure taint` | Node has `node.kubernetes.io/disk-pressure` etc. | **Layer 2** — cluster-level issue. |
| `volume "X" not found` | PVC bound to a non-existent PV. | See §5. |
**The diagnostic for "wrong cluster's scheduling values":**
```bash
# What does the pod's nodeSelector say?
kubectl --context=$CTX get pod <pod> -n $NS -o yaml \
| yq e '.spec.nodeSelector'
# What labels do the cluster's nodes actually have?
kubectl --context=$CTX get nodes --show-labels | head -3
# Cross-reference: is the cluster's key style 'dedicated:' or 'cloud.google.com/compute-class'?
grep -h 'dedicated:\|cloud.google.com/compute-class' \
helm-overrides/$CLUSTER/*/custom-values.yaml | sort -u | head
```
If the values use `dedicated:` but the cluster only has `cloud.google.com/compute-class:` keys (or vice versa), the values were copied from a sibling cluster. **Author the values from scratch** using the cluster's own key style.
---
## §2 — Running but on the wrong node pool
The pod scheduled, but on a node it shouldn't be on (e.g. a Contour-internal pod landed on the Contour-external pool).
| Sub-check | Action |
|-----------|--------|
| What `nodeSelector` does the pod actually have? | `kubectl --context=$CTX get pod <pod> -o yaml \| yq e '.spec.nodeSelector'`. |
| Where is it running? | `kubectl --context=$CTX get pod <pod> -o wide` — note the `NODE`. Check that node's labels. |
| Is the values-side `nodeSelector` too permissive? | If the chart's default merges with your override, you may have inherited an unintended key. Render with `helm template` and inspect. |
The fix is to make the `nodeSelector` selective enough that only the intended pool matches. **Layer 1.**
---
## §3 — Image pull failing
```text
ErrImagePull / ImagePullBackOff
```
| Sub-check | Action |
|-----------|--------|
| Is the image pinned to Meesho's GAR mirror? | `kubectl get deploy <d> -n $NS -o jsonpath='{.spec.template.spec.containers[].image}'`. If it's Docker Hub / Quay / GCR upstream, that's [SANCTITY_RULES R11](../../global/SANCTITY_RULES.md) violation. **Layer 1** — fix the image reference. |
| Does the tag exist in the registry? | Out-of-band check (registry UI). |
| Is the registry-pull credential present on the cluster? | `kubectl get secret -n $NS \| grep gcr-pull`. **Layer 2** if missing. |
The image tag is set in `image.repository` / `image.tag` of `custom-values.yaml`. **Layer 1.**
---
## §4 — CrashLoopBackOff
```bash
kubectl --context=$CTX logs <pod> -n $NS --previous
kubectl --context=$CTX describe pod <pod> -n $NS
```
| Pattern | Likely cause | Fix in |
|---------|--------------|--------|
| Application stack trace, missing config | App expects an env var / file that isn't there | `custom-values.yaml` config section. **Layer 1.** |
| `connection refused` to a dependency | Dependency not up; or wrong DNS | Dependency team. **Layer 2.** |
| `exit code 137` | OOMKilled — `kubectl describe` confirms | Bump `resources.limits.memory` in values. **Layer 1.** |
| `permission denied` on a file | Volume mount / `securityContext` | Values. **Layer 1.** |
| `existing Secret <X> not found` | `existingSecret:` references a secret that doesn't exist | Either fix the name, or add the `ExternalSecret` to `helm-overrides/<cluster>/external-secrets/`. **Layer 1.** |
| Init container failed | Init logs explain | `kubectl --context=$CTX logs <pod> -c <init-container> -n $NS`. |
---
## §5 — Running but PVC unbound
```bash
kubectl --context=$CTX get pvc -n $NS
kubectl --context=$CTX describe pvc <pvc> -n $NS
```
| Sub-check | Action |
|-----------|--------|
| `Events: Failed to provision volume with StorageClass "<X>"` | The StorageClass doesn't exist on this cluster. | `ls manifests/storageclass/<X>.yaml`. If absent, fix `persistence.storageClass:` in values to a real class. **Layer 1.** |
| `Events: ProvisioningFailed: googleapi: Error 403` | CSI driver lacks IAM permission. **Layer 2.** | Platform / IAM team. |
| PVC `Pending` with no events | StorageClass has `volumeBindingMode: WaitForFirstConsumer` and the consuming pod hasn't been scheduled. | Schedule the pod (resolve §1 first). |
| PVC bound but pod can't mount | Often the access mode mismatch (`ReadWriteOnce` PVC referenced by a multi-replica `Deployment`). | Either set replicas to 1, or use a `StatefulSet` chart variant, or use a Filestore-backed `ReadWriteMany` class. **Layer 1.** |
---
## §6 — When this repo *is* the right place to fix
For these cases, the fix is a values diff in `helm-overrides/<cluster>/<app>/custom-values.yaml`:
1. Wrong-cluster `nodeSelector` / `tolerations` / `computeClass`.
2. Image tag pointing outside the GAR mirror.
3. `resources.requests` / `limits` mis-sized (OOMKill, throttling).
4. `persistence.storageClass` referencing a non-existent class.
5. `existingSecret:` referencing a non-existent secret.
6. `replicaCount` set on an HPA-managed release.
For these cases, the fix is **outside** this repo:
- Node pool full → cluster-owner / Terraform.
- Image not in GAR → image-mirror automation / build pipeline.
- CSI provisioning failures → platform / IAM team.
- App-internal crashes (config, dependencies) → app team.
---
## Escalation matrix
| Symptom | First responder | Escalate to |
|---------|-----------------|-------------|
| §1 — wrong scheduling values | Yourself with values fix | Cluster owner if topology is unclear |
| §1 — node pool full | Cluster owner | Platform team if quota raise needed |
| §3 — image pull (mirror miss) | Yourself with values fix | Platform if mirror push is missing |
| §4 — OOMKilled | Yourself with `resources.limits` bump | App team if root cause is leak |
| §4 — secret missing | Yourself with `ExternalSecret` add | Security if cluster-level `SecretStore` is missing |
| §5 — CSI provision failure | Platform team | — |
| §C — cluster-wide scheduling failure | Platform team — pager | — |
---
## Done conditions
- `kubectl rollout status deploy/<name> -n $NS` returns "successfully rolled out".
- `kubectl get pods -n $NS` shows N/N Ready for the expected replica count.
- Pods scheduled onto the **intended** node pool (verify `kubectl get pods -o wide` shows the right node names).
- If root cause was in this repo, the fix is on `main` and synced.
---
## Related
- Reference: [contour-nodeselector-tolerations-summary.md](../../../contour-nodeselector-tolerations-summary.md).
- Runbook: [argocd-sync-failure.md](argocd-sync-failure.md).
- Runbook: [ingress-down.md](ingress-down.md).
- Schema: [custom-values-schema.md](../schemas/custom-values-schema.md), [storageclass-priorityclass-schema.md](../schemas/storageclass-priorityclass-schema.md).
+251
View File
@@ -0,0 +1,251 @@
> Per AI Blitz Plan §platform.runbooks. Layer: 1. Repo: devops-infra-helm-charts.
# Runbook — Vault unavailable / External Secrets failing to render
> **Type:** Decision tree.
> **Entry symptom:** Pods are CrashLooping referencing a missing `Secret`, or `kubectl describe externalsecret` shows `SecretSyncedError`, or `kubectl get secrets <name>` returns NotFound for a name an `ExternalSecret` should be creating.
> **Layer:** mostly Layer 2 (advisory). Layer 1 only when the fix is a values diff in this repo.
>
> **Important Layer 3 boundary:** **Vault HA itself is Layer 3.** Vault runs in production-only with no lower environment, so the agent must NOT attempt server-side fixes (unsealing, leader-election toggling, raft config changes, restoring from snapshot). Those are platform-team / security-team operations. The agent's role here is *diagnose, narrow root cause, and escalate*.
---
## Architecture refresher
```
workload Pod (mounts Secret <name>)
↑ created by
External Secrets Operator (ESO) controller
└─ reads SecretStore / ClusterSecretStore
├─ kind: gcpsm → GCP Secret Manager
│ └─ auth via Workload Identity (KSA → GSA binding)
└─ kind: vault → Vault HA cluster
└─ auth via Kubernetes auth (KSA token review)
```
Most clusters in the fleet use **GCP Secret Manager** as the primary backend (via Workload Identity), with Vault HA as the secondary for legacy services. Some clusters use Vault as the primary. Confirm before troubleshooting:
```bash
ls helm-overrides/<cluster>/external-secrets/
yq e '.spec.provider' helm-overrides/<cluster>/external-secrets/*.yaml 2>/dev/null
```
---
## Entry — gather context
```bash
CLUSTER=<cluster>
CTX=<kubectl-context>
NS=<namespace-of-the-failing-workload>
ES=<external-secret-name>
# ESO controller status
kubectl --context=$CTX -n external-secrets get pods
kubectl --context=$CTX -n external-secrets logs deploy/external-secrets | tail -50
# The failing ExternalSecret
kubectl --context=$CTX -n $NS describe externalsecret $ES
kubectl --context=$CTX -n $NS get externalsecret $ES -o yaml | yq e '.status'
# The SecretStore / ClusterSecretStore it references
STORE=$(kubectl --context=$CTX -n $NS get externalsecret $ES -o jsonpath='{.spec.secretStoreRef.name}')
KIND=$(kubectl --context=$CTX -n $NS get externalsecret $ES -o jsonpath='{.spec.secretStoreRef.kind}')
kubectl --context=$CTX get $KIND $STORE -o yaml | yq e '.status, .spec.provider'
```
---
## Decision tree
```text
START
├── §1 — Is ESO controller running and healthy?
│ ├── No → §1a — ESO outage
│ └── Yes →
├── §2 — Is the SecretStore / ClusterSecretStore Ready?
│ ├── No → §2a — Store config / auth broken
│ └── Yes →
├── §3 — Does the ExternalSecret reference a real remote key?
│ ├── No → §3a — Bad spec.data[].remoteRef.key (Layer 1 likely)
│ └── Yes →
├── §4 — Is the auth path working? (WI binding or Vault K8s auth)
│ ├── No → §4a — Identity binding (Layer 2/3)
│ └── Yes →
└── §5 — Is the upstream backend healthy?
├── GCP Secret Manager 5xx → §5a — escalate to platform
└── Vault unsealed / leader OK? → §5b — Vault outage (Layer 3)
```
---
## §1 — ESO controller health
```bash
kubectl --context=$CTX -n external-secrets get pods
kubectl --context=$CTX -n external-secrets logs deploy/external-secrets --tail=100 | grep -iE 'error|failed|panic'
```
| Symptom | Cause | Layer | Action |
|---------|-------|-------|--------|
| Pods CrashLooping | Bad chart upgrade or RBAC misconfig | 1 | Check `helm-overrides/<cluster>/external-secrets/custom-values.yaml`. Last bump? Revert. |
| Pods Pending | Scheduling — wrong nodeSelector | 1 | See [pod-pending-scheduling.md](pod-pending-scheduling.md). |
| Pods Running, no logs about reconcile | Cluster-watch RBAC missing | 2 | Escalate. |
| `Forbidden` errors on CRD list | RBAC on the CRDs | 1 / 2 | Verify chart values' `rbac.create: true`. |
---
## §2 — SecretStore / ClusterSecretStore status
```bash
kubectl --context=$CTX get $KIND $STORE -o yaml | yq e '.status'
```
Look for `conditions[].status` and `conditions[].message`.
| Status / message | Cause | Layer | Action |
|------------------|-------|-------|--------|
| `Ready: False, ValidationFailed` | Store spec invalid | 1 | Fix the `SecretStore` YAML in `helm-overrides/<cluster>/external-secrets/`. |
| `Ready: False, InvalidProviderConfig` | Provider block malformed | 1 | Validate `spec.provider.gcpsm.projectID` / `spec.provider.vault.server`. |
| `Ready: False, AuthFailed` (gcpsm) | Workload Identity binding broken | 2/3 | §4 below. |
| `Ready: False, AuthFailed` (vault) | KSA token review fails | 2/3 | §4 below. |
| `Ready: True` | Store OK; problem is elsewhere | — | Continue to §3. |
---
## §3 — ExternalSecret spec validity
```bash
kubectl --context=$CTX -n $NS get externalsecret $ES -o yaml | yq e '.spec.data, .spec.dataFrom'
```
For each `remoteRef.key`:
- **GCP SM:** the key is the secret name in the project. Verify it exists:
```bash
gcloud secrets list --project=<gcp-project> --filter="name:<key>"
```
(Read-only — no write to GCP SM from the agent.)
- **Vault:** the key is the path under the engine. Cannot directly verify without Vault access; rely on the ESO controller's reconcile error message.
If the controller logs say `secret not found in backend` → the `remoteRef.key` is wrong. **Layer 1 fix:** correct the key in the `ExternalSecret` YAML.
---
## §4 — Auth path
### §4a — GCP Secret Manager (Workload Identity)
```bash
# The ServiceAccount the ESO controller (or this ExternalSecret's pod) runs as
kubectl --context=$CTX -n external-secrets get sa external-secrets -o yaml | yq e '.metadata.annotations'
# Should have:
# iam.gke.io/gcp-service-account: <gsa>@<project>.iam.gserviceaccount.com
```
| Sub-check | Layer | Action |
|-----------|-------|--------|
| KSA missing the `iam.gke.io/gcp-service-account` annotation | 1 | Add via `helm-overrides/<cluster>/external-secrets/custom-values.yaml` `serviceAccount.annotations`. |
| GSA exists but no IAM binding to KSA | 2 | Escalate to platform — IAM is out of repo. |
| GSA lacks `roles/secretmanager.secretAccessor` on the project | 2 | Escalate to platform. |
### §4b — Vault Kubernetes auth
| Sub-check | Layer | Action |
|-----------|-------|--------|
| `SecretStore.spec.provider.vault.auth.kubernetes.role` references a Vault role | — | Read-only; verify against existing working stores on the same cluster. |
| ESO logs say `permission denied` from Vault | 3 | The role/policy on the Vault server is wrong. **Cannot fix from this repo.** Escalate to security / Vault platform team. |
| ESO logs say `Vault is sealed` | 3 | **Vault HA outage. Do not attempt to unseal.** Escalate immediately. |
---
## §5 — Backend health
### §5a — GCP Secret Manager
GCP SM is a managed service. 5xx from it is rare and is a GCP-side incident. Action: escalate to platform; check GCP status dashboard. **No fix in this repo.**
### §5b — Vault HA
Vault HA on Meesho's fleet runs in production-only, no lower env. It is **Layer 3** — agent does not write to or operate Vault. Diagnostic *read* of pod state is OK; mutation is not.
```bash
# Diagnostic only
kubectl --context=$CTX -n vault get pods
kubectl --context=$CTX -n vault logs <vault-pod> | tail -50
# Look for: "core: Vault is sealed", "leader election", "raft", panic stacks
```
| Observed | Action |
|----------|--------|
| Some Vault pods sealed (HA quorum still up) | Escalate to security team. **Do not unseal.** |
| All Vault pods sealed (full outage) | Page security team. ESO will surface stale data only as long as the in-memory cache holds. |
| Leader-election thrashing | Escalate; could be a network/raft issue. |
| Vault pod Pending | Scheduling — see [pod-pending-scheduling.md](pod-pending-scheduling.md). Even here, restart of a Vault pod requires a security-team-led unseal afterwards. |
---
## Mitigations while Vault is down
If a workload's `ExternalSecret` is failing because Vault is unavailable, options are limited:
1. **Wait** — ESO caches the last-rendered Secret value. Pods that already mounted continue. New pod scheduling fails until Vault returns.
2. **Switch the `ExternalSecret` to GCP SM** if the same secret exists there (most do, with Vault as legacy). Layer 1 PR — change `secretStoreRef.name` to the GCP SM store. **Coordinate with security** before doing this in an outage.
3. **Hand-create the Secret as a temporary `kubectl apply`** — out of scope for the agent. This is incident response by a human operator.
The agent should **not** auto-cut option 2 without explicit human approval — switching the source of truth for a secret has security implications.
---
## Escalation matrix
| Symptom | First responder | Escalate to |
|---------|-----------------|-------------|
| §1 (ESO down) | DevOps on-call | Platform team |
| §2 (Store config) | DevOps on-call | Layer 1 PR + reviewer |
| §3 (Bad remoteRef) | DevOps on-call | Layer 1 PR + reviewer |
| §4a (WI binding) | Platform team | — |
| §4b (Vault role/policy) | Security team | — |
| §5a (GCP SM 5xx) | Platform team | GCP support |
| §5b (Vault outage) | **Security team — page** | — |
---
## Done conditions
- `ExternalSecret` `status.conditions[type=Ready].status == True`.
- The downstream `Secret` exists with expected keys.
- Workload pods consuming the Secret are Running.
- ESO logs are quiet for at least 5 minutes after the fix.
---
## What this repo can and cannot fix
| Fix kind | Layer | This repo? |
|----------|-------|-----------|
| `ExternalSecret` / `SecretStore` YAML edits | 1 | Yes — values PR. |
| ESO chart values (sizing, RBAC, metrics) | 1 | Yes. |
| Workload-Identity KSA annotation | 1 | Yes (in chart values' `serviceAccount.annotations`). |
| GSA IAM bindings on GCP | 2 | No — platform team. |
| Vault server-side role/policy | 3 | **Never** — security team. |
| Vault unseal / raft / leader | 3 | **Never** — security team. |
---
## Related
- Schema: [../schemas/raw-manifest-sidecar-schema.md §ExternalSecret](../schemas/raw-manifest-sidecar-schema.md).
- Runbook: [pod-pending-scheduling.md](pod-pending-scheduling.md) — if any of the above pods are Pending.
- Runbook: [argocd-sync-failure.md](argocd-sync-failure.md) — if the `ExternalSecret` itself didn't sync.
- Boundaries: [../../global/AGENT_BOUNDARIES.md](../../global/AGENT_BOUNDARIES.md), [../../global/SANCTITY_RULES.md](../../global/SANCTITY_RULES.md).
- Escalation: [../../global/escalation-matrix.md](../../global/escalation-matrix.md).
@@ -0,0 +1,379 @@
# Schema — `custom-values.yaml` (Helm override)
> Field-by-field annotation of the values file Argo CD's `valueFiles` references.
> Authoritative for `helm-overrides/<cluster>/<app>/custom-values.yaml`.
>
> Cross-reference: [coding-guidelines/helm-values.md](../../global/coding-guidelines/helm-values.md), [../../architecture.md](../../architecture.md).
---
## What this file is — and isn't
A `custom-values.yaml` is **not** a Helm chart. It is the *override* layer Argo CD merges over the chart's own `values.yaml` (or, for thin-wrapper charts, the upstream subchart's defaults).
- **Schema is owned by the chart, not by us.** Every key here must be a key the chart understands. Adding a key the chart doesn't read does nothing.
- **No multi-doc YAML.** One document per file.
- **No `apiVersion` / `kind`.** This file is values, not a Kubernetes manifest.
---
## Top-level shape (typical)
```yaml
# image registry / repository / tag
image:
registry: asia-southeast1-docker.pkg.dev
repository: meesho-devops-admin-0622/admin/sre/<image>
tag: <semver-or-sha>
pullPolicy: IfNotPresent
# release-name pinning (rarely changed once set)
fullnameOverride: <release>-<bu>-prd # e.g. kube-state-metrics-dbc-dsci-prd
# scaling
replicaCount: 3 # static, OR
autoscaling:
enabled: true
minReplicas: 3
maxReplicas: 10
targetCPUUtilizationPercentage: 70
# scheduling — bespoke per cluster
nodeSelector:
dedicated: <pool-key> # standard GKE
# cloud.google.com/compute-class: <cc> # GKE Autopilot
tolerations:
- key: dedicated
value: <pool-key>
effect: NoSchedule
# resources
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: 1
memory: 2Gi
# persistence (stateful charts only)
persistence:
enabled: true
storageClass: sc-pd-ssd # MUST exist in manifests/storageclass/
size: 100Gi
accessModes: [ReadWriteOnce]
# secrets — by reference, never inline
existingSecret: <name-managed-by-external-secrets>
# probes
livenessProbe:
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
initialDelaySeconds: 5
periodSeconds: 5
# ingress / Contour HTTPProxy (if applicable)
ingress:
enabled: false # most internal services
# chart-specific top-level keys
# (varies — read the chart's values.yaml for the full schema)
```
---
## §image
| Field | Required | Convention | Notes |
|-------|----------|------------|-------|
| `image.registry` | yes (production) | `asia-southeast1-docker.pkg.dev` | Meesho's Artifact Registry mirror. ([SANCTITY_RULES R11](../../global/SANCTITY_RULES.md)) |
| `image.repository` | yes | `meesho-devops-admin-0622/admin/sre/<image>` | Mirror path. |
| `image.tag` | yes (production) | semver, datestamp, or git SHA | Never `latest`. Never unpinned. |
| `image.pullPolicy` | no | `IfNotPresent` | `Always` only for development; pulls slow rollout. |
| `image.pullSecrets` | no | omit | Mirror is public to fleet; pull secrets are a lock-in trap. |
Note: chart authors disagree on the shape — some use `image: {repository, tag}` (no `registry`), some use a single `image: <fully-qualified>`, some split into `image.repository: <registry>/<repo>`. **Read the chart's own `values.yaml`** before structuring this block.
---
## §release identity
| Field | Required | Convention | Notes |
|-------|----------|------------|-------|
| `fullnameOverride` | varies | Set once at release creation; stable forever | Service DNS, PVC binding, ConfigMap refs depend on it. ([SANCTITY_RULES R9](../../global/SANCTITY_RULES.md)) |
| `nameOverride` | rare | Omit unless explicitly needed | |
| `commonLabels` / `commonAnnotations` | rare | Omit unless the chart documents the pattern | |
For dataplane (`db-*`) clusters: `fullnameOverride: <kind>-dbc-<bu>-prd` is the convention (e.g. `kube-state-metrics-dbc-dsci-prd`). For BU clusters, omit unless the chart's default name collides.
---
## §scaling
Charts diverge sharply here. Common shapes:
```yaml
# Pattern A — static replicas
replicaCount: 3
# Pattern B — chart-level autoscaling block
autoscaling:
enabled: true
minReplicas: 3
maxReplicas: 10
targetCPUUtilizationPercentage: 70
# Pattern C — separate HPA resource (KEDA / VictoriaMetrics)
hpa:
enabled: true
min: 3
max: 20
metrics:
- type: Resource
resource: {name: cpu, target: {type: Utilization, averageUtilization: 70}}
```
| Rule | Why |
|------|-----|
| **Don't set `replicaCount`** when `autoscaling.enabled: true`. | HPA and the chart's static deployment fight; replica count flaps. |
| **Set both `minReplicas` and `maxReplicas`** when autoscaling. | Without `min`, the HPA can scale to zero on a quiet hour. |
| **`minReplicas` ≥ 2** for any production-traffic-path workload. | Single-replica releases die on node drain. |
---
## §scheduling
The single biggest source of silent mis-deploys. Per [SANCTITY_RULES R5](../../global/SANCTITY_RULES.md):
| Cluster | Key style |
|---------|-----------|
| GKE Autopilot (`k8s-central-prd-ase1`, `k8s-dsgpu-prd-ase1`, `k8s-shared-int-ase1`) | `cloud.google.com/compute-class:` |
| Standard GKE | `dedicated:` |
```yaml
# Standard GKE — Contour internal-0 on most clusters
nodeSelector:
dedicated: contour-internal-0
tolerations:
- key: dedicated
value: contour-internal-0
effect: NoSchedule
# often a second toleration to allow scheduling onto shared nodes
- key: dedicated
value: contour-shared
effect: NoSchedule
# GKE Autopilot — same Contour internal-0 on k8s-central-prd-ase1
nodeSelector:
cloud.google.com/compute-class: contour-internal-0-cc
tolerations:
- key: cloud.google.com/compute-class
value: contour-internal-0-cc
effect: NoSchedule
- key: cloud.google.com/compute-class
value: contour-shared-cc
effect: NoSchedule
```
The full per-cluster Contour matrix lives in [`contour-nodeselector-tolerations-summary.md`](../../../contour-nodeselector-tolerations-summary.md). For non-Contour apps, copy from a sibling app on the **same** cluster.
| Field | Notes |
|-------|-------|
| `nodeSelector` | Hard requirement — no scheduling onto non-matching nodes. Use exactly one key (the cluster's pool key). |
| `tolerations` | Allow scheduling onto tainted nodes. May list multiple to allow shared nodes alongside dedicated. |
| `affinity.nodeAffinity` | Use sparingly; `nodeSelector` is sufficient for most cases here. |
| `topologySpreadConstraints` | Use for multi-zone resilience on chatty workloads (Contour, ingress-nginx). |
---
## §resources
```yaml
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: 1
memory: 2Gi
```
| Rule | Why |
|------|-----|
| **Always set `requests`** in production. | Without requests, pods are best-effort; first to evict on memory pressure. |
| **Set `limits` unless the chart explicitly recommends omitting them.** | Some sidecars (cert-manager, external-dns) deliberately skip `limits`. |
| **Don't copy resources from another cluster.** | Workload sizing is per-traffic-tier. Supply prd is not demand prd. |
| **CPU limits cause throttling**, not OOMKill. Memory limits cause OOMKill. Tune accordingly. |
---
## §persistence
```yaml
persistence:
enabled: true
storageClass: sc-pd-ssd
size: 100Gi
accessModes: [ReadWriteOnce]
```
Allowed `storageClass` values (must match a file under `manifests/storageclass/`):
| Class | Backend | Use case |
|-------|---------|----------|
| `pd-standard-retain-dr` | GCP Persistent Disk standard, retention-on-delete | DR-critical state |
| `sc-pd-ssd` | GCP PD SSD | Default for write-heavy workloads (etcd, ClickHouse) |
| `sc-pd-standard` | GCP PD standard | Default for read-heavy / archival |
| `sc-filestore-standard` | GCP Filestore | Shared volumes (Jenkins build cache, JFrog filestore) |
| Rule | Why |
|------|-----|
| **Never reference a `storageClass`** that doesn't exist in `manifests/storageclass/`. | PVC stays Pending forever. |
| **`size` must be set explicitly.** | Chart defaults are often wrong (8Gi for everything). |
| **`accessModes`** for `ReadWriteMany` requires Filestore. PD-backed classes are RWO. |
---
## §secrets
```yaml
# Chart-specific — read the chart's values.yaml
existingSecret: <name>
# OR
auth:
existingSecret: <name>
# OR
envFrom:
- secretRef: {name: <name>}
```
| Rule | Why |
|------|-----|
| **Never inline `password:`, `apiKey:`, etc.** | Pre-commit TruffleHog will catch many; it won't catch all. ([SANCTITY_RULES R4](../../global/SANCTITY_RULES.md)) |
| **The `Secret` resource is materialised** by the cluster's `external-secrets` app. If the secret name doesn't appear in `helm-overrides/<cluster>/external-secrets/`, it doesn't exist. |
| **Reference, don't author.** Adding the secret material to a Helm-rendered `Secret` template defeats the External Secrets pattern. |
---
## §probes
```yaml
livenessProbe:
httpGet: {path: /healthz, port: http}
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 3
failureThreshold: 3
readinessProbe:
httpGet: {path: /ready, port: http}
initialDelaySeconds: 5
periodSeconds: 5
# For slow-warm workloads (Jenkins, JFrog, ClickHouse)
startupProbe:
httpGet: {path: /healthz, port: http}
initialDelaySeconds: 60
periodSeconds: 10
failureThreshold: 60 # 10 minutes total runway
```
| Rule | Why |
|------|-----|
| **Always set `liveness` + `readiness`** for any long-running container. |
| **Use `startupProbe` for slow-warm workloads** instead of inflating `livenessProbe.initialDelaySeconds` to 600 s. |
| **Don't set the same probe to both `liveness` and `readiness`** — they have different purposes (kill vs gate). |
---
## §ingress (Contour `HTTPProxy` / `Ingress`)
For external-facing apps, ingress is via Contour `HTTPProxy`. Specifics depend on the cluster's Contour topology (multiple Contour instances per cluster — see [contour-nodeselector-tolerations-summary.md](../../../contour-nodeselector-tolerations-summary.md)).
- The `external-dns` annotation is the DNS-binding step — match the cluster's DNS pattern.
- TLS terminates at Contour with `cert-manager`-issued certs; reference the issuer by name.
- Internal services use `contour-internal-0` / `contour-internal-1`; external services use `contour-external` / `contour-external-1`. The class is set via the `Service` annotation, not the values file directly.
---
## End-to-end example — a typical observability-side override
`helm-overrides/k8s-supply-prd-ase1/kube-state-metrics/custom-values.yaml`:
```yaml
image:
registry: asia-southeast1-docker.pkg.dev
repository: meesho-devops-admin-0622/admin/sre/kube-state-metrics
tag: v2.10.1
replicaCount: 2
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: 500m
memory: 1Gi
nodeSelector:
dedicated: monitoring
tolerations:
- key: dedicated
value: monitoring
effect: NoSchedule
prometheus:
monitor:
enabled: true
honorLabels: true
```
---
## End-to-end example — a dataplane override
`helm-overrides/db-2516183257845181-c-1204-195038-428/victoria-metrics-agent/custom-values.yaml`:
```yaml
fullnameOverride: vmagent-dbc-supply-prd
image:
registry: asia-southeast1-docker.pkg.dev
repository: meesho-devops-admin-0622/admin/sre/victoria-metrics-agent
tag: v1.96.0
replicaCount: 1
resources:
requests:
cpu: 100m
memory: 256Mi
```
(Dataplane clusters intentionally have minimal overrides.)
---
## Validation
```bash
# Render the chart locally with this values file
helm template <release> helm-templates/<chart> \
-f helm-overrides/<cluster>/<app>/custom-values.yaml | head -80
# Dry-run diff against the live cluster (requires kubectl context + helm-diff plugin)
helm diff upgrade <release> helm-templates/<chart> \
-f helm-overrides/<cluster>/<app>/custom-values.yaml
# Lint
yamllint helm-overrides/<cluster>/<app>/custom-values.yaml
helm lint helm-templates/<chart>
# Sanity: storageClass referenced exists
yq e '.persistence.storageClass' helm-overrides/<cluster>/<app>/custom-values.yaml \
| xargs -I{} ls manifests/storageclass/{}.yaml 2>/dev/null \
|| echo "WARN: storageClass not in manifests/storageclass/"
```
@@ -0,0 +1,195 @@
> Per AI Blitz Plan §platform.schemas. Layer: 1. Repo: devops-infra-helm-charts.
# Schema — Incubator-tool values + sidecar contract
> **Scope:** the values-side contract for incubator (newly-vendored) infrastructure tools that live under `helm-overrides/<cluster>/<incubator-tool>/`.
>
> **Out of scope (explicit):** the Argo CD `Application` / `ApplicationSet` manifest that registers the incubator tool with a cluster's Argo. Those manifests live in the **sister repo** `github.com/Meesho/devops-infra-argo-config`, NOT here. This file documents only what `devops-infra-helm-charts` is responsible for: the values + raw sidecar manifests Argo CD reads from this repo.
This schema complements [custom-values-schema.md](custom-values-schema.md) (general values shape) and [raw-manifest-sidecar-schema.md](raw-manifest-sidecar-schema.md) (sidecar manifest shapes). Read both first.
---
## What "incubator" means here
A tool is **incubator** while it is being trialled on one or two clusters before fleet-wide rollout. In this repo that maps to:
- A new chart directory under `helm-templates/<incubator-tool>/` (often a thin wrapper `Chart.yaml` with an upstream dep).
- An override under `helm-overrides/<cluster>/<incubator-tool>/` for the trial cluster(s) only — typically `k8s-shared-int-ase1` (integration / pre-prod) first, sometimes one BU prod cluster as a canary.
- Possibly raw sidecar manifests alongside the values file.
Once the tool graduates from incubator status, the override pattern is identical to other infra tools — the "incubator" label is operational, not structural. This schema codifies the conventions that keep early-stage adoption sane.
---
## Directory layout
```
helm-overrides/<cluster>/<incubator-tool>/
├── custom-values.yaml # Helm values (required if chart is Helm-based)
├── computeclass/ # Optional — GKE Autopilot ComputeClass
│ └── <name>-cc.yaml
├── external-dns-services/ # Optional — Service for external-dns annotation
│ └── <fqdn>.yaml
├── external-secrets/ # Optional — ExternalSecret resources
│ └── <name>.yaml
└── <incubator-specific>.yaml # Tool-specific raw manifest (CRD, ConfigMap)
```
The Argo `Application` for this directory (sister repo) determines whether files are Helm-rendered, raw-applied, or layered (see [raw-manifest-sidecar-schema.md §Layered-with-Helm vs standalone](raw-manifest-sidecar-schema.md)).
---
## `custom-values.yaml` keys an incubator chart should expose
A chart promoted to incubator status MUST surface (i.e. let the override file set without forking templates) at minimum:
| Key | Why required |
|-----|--------------|
| `image.registry`, `image.repository`, `image.tag` | Production overrides pin to `asia-southeast1-docker.pkg.dev/meesho-devops-admin-0622/admin/sre/<image>` (Meesho Artifact Registry mirror, not Docker Hub). |
| `image.pullPolicy` | Default `IfNotPresent`. |
| `resources.requests.cpu`, `.memory` | No defaults assumed; Autopilot scheduling requires explicit requests. |
| `resources.limits.cpu`, `.memory` | Same. |
| `nodeSelector` | Per-cluster scheduling (see [custom-values-schema.md](custom-values-schema.md)). |
| `tolerations` | Per-cluster taints. |
| `affinity` (optional) | Pod anti-affinity for replicated tools. |
| `serviceAccount.create`, `.name`, `.annotations` | Workload Identity — `iam.gke.io/gcp-service-account` annotation goes here. |
| `replicaCount` (or `autoscaling.{enabled,minReplicas,maxReplicas}`) | Sizing. |
| `persistence.enabled`, `.storageClass`, `.size` | If stateful. `storageClass` MUST exist in `manifests/storageclass/`. See [storageclass-priorityclass-schema.md](storageclass-priorityclass-schema.md). |
| `priorityClassName` | If the tool needs preemption priority — must reference a class in `manifests/priorityclass/<cluster>/`. |
| `podLabels`, `podAnnotations` | For prometheus.io scrape annotations and team-attribution labels. |
| `extraEnv` (or `env`) | For environment-specific knobs the chart's templates don't already accept. |
If the upstream chart doesn't expose these — that's a chart-bug. **Do not** fork the chart in `helm-templates/` to add them ([NEVER-DO list](../../../CLAUDE.md)). Either upstream-PR the chart or wrap with a small Meesho-owned chart that re-exposes the keys.
---
## Values-file conventions for incubator tools
1. **Pin every image tag.** Never `latest`, never an unpinned SHA. This is the same rule as production overrides; incubator status does not relax it.
2. **Set explicit `nodeSelector` and `tolerations`** authored from scratch using sibling apps on the same cluster. Cross-cluster copying is forbidden — see [custom-values-schema.md](custom-values-schema.md).
3. **Use `fullnameOverride` deliberately or not at all.** Once set, do not change ([NEVER-DO list](../../../CLAUDE.md)). Incubator graduations to other clusters should reuse the same `fullnameOverride` string for portability.
4. **Don't enable `autoscaling`** in the first incubator deploy. Pin `replicaCount: 1` (or 2 for HA-mandatory) until you have a load profile.
5. **Don't expose the tool externally** in the incubator phase. No `external-dns-services/` until it's promoted to a cluster's stable inventory.
6. **Annotate the values file** with a top-of-file YAML comment: `# Incubator: cluster=<...>, owner=<...>, graduation-target=<date>`. Comment is plain text; not parsed; serves as reviewer signal.
7. **Confine secrets to `ExternalSecret`** under `external-secrets/`. No inline `existingSecret:` referencing a hand-applied Secret.
---
## Raw sidecar manifests in incubator directories
Concrete shapes already documented elsewhere; this section calls out which ones routinely appear with incubators.
### `computeclass/*-cc.yaml` (GKE Autopilot only)
Required when the override's `nodeSelector` uses `cloud.google.com/compute-class: <name>` and that class doesn't already exist on the cluster. The `metadata.name` MUST equal the value referenced. See [raw-manifest-sidecar-schema.md §ComputeClass](raw-manifest-sidecar-schema.md).
Example incubator pattern:
```yaml
apiVersion: autoscaling.gke.io/v1
kind: ComputeClass
metadata:
name: <incubator-tool>-cc
namespace: <ns>
spec:
priorities:
- machineFamily: c4d
minCores: 2
minMemory: 8Gi
nodePoolAutoCreation:
enabled: true
```
Per-cluster only — never copy between clusters.
### `external-dns-services/*.yaml`
Skip in the first incubator deploy. Only add once the tool has a stable internal-only DNS need. See [raw-manifest-sidecar-schema.md §Service for external-dns binding](raw-manifest-sidecar-schema.md).
### `external-secrets/*.yaml`
Always present if the tool needs secrets. Use the existing per-cluster `SecretStore` / `ClusterSecretStore`; do not author new stores in an incubator PR. See [raw-manifest-sidecar-schema.md §ExternalSecret](raw-manifest-sidecar-schema.md).
### `elastic-cluster/argo-launch.yaml`-style operator-managed CRD launches
If the incubator tool is an operator (e.g. ECK, Pyroscope), a sidecar CRD instance often lives alongside the operator's chart values:
```
helm-overrides/<cluster>/<incubator-operator>/
├── custom-values.yaml # operator chart values
└── <crd-instance>/
└── argo-launch.yaml # the actual workload CRD instance
```
Argo CD applies both in one Application (directory loader). The CRD instance must:
- Reference an `apiVersion` whose CRD the operator has already installed.
- Pin its own image / version explicitly.
- Avoid hand-rolling values that the operator templates would otherwise compute.
---
## Argo CD — sister repo contract (for cross-reference only)
The Application that points at this directory lives in `github.com/Meesho/devops-infra-argo-config`. For incubator tools the Application typically:
- Has `syncPolicy.automated` **disabled** (manual sync — incubator-grade safety; see [argocd.md](../../global/coding-guidelines/argocd.md)).
- Is named `<incubator-tool>-<cluster>` to be unambiguous.
- Lives in the cluster's namespace under `apps/<cluster>/`.
This file does NOT instruct on authoring the Application — that PR is in the sister repo. Cross-link the sister-repo PR in the values-side PR description.
---
## Validation
Same as any Helm override. Before opening a PR:
```bash
yamllint helm-overrides/<cluster>/<incubator-tool>/custom-values.yaml
helm template <release> helm-templates/<incubator-tool> \
-f helm-overrides/<cluster>/<incubator-tool>/custom-values.yaml > /tmp/render.yaml
# Validate any sidecar manifests against the cluster's CRDs
kubectl --context=<ctx> --dry-run=server \
-f helm-overrides/<cluster>/<incubator-tool>/<sidecar>.yaml apply
```
For tool-specific CRDs that aren't in vanilla Kubernetes, prefer `--dry-run=server` (the cluster validates against the registered CRD) over `--dry-run=client` (only client-side schema, often misses required fields).
---
## Graduation: incubator → stable
When the tool has been stable for some period (usually 24 weeks) and is ready to fleet-roll:
1. Remove the top-of-file `# Incubator:` comment.
2. Open new override directories in target clusters — author from scratch each time, do not copy.
3. Open the matching sister-repo `Application` PRs (one per new cluster) or extend the `ApplicationSet`.
4. If the chart was a thin wrapper, audit `Chart.yaml` `dependencies[].version` is current.
5. Promote the chart's documentation in `helm-templates/<incubator-tool>/README.md` (if a fork was needed) or note in PR description that no fork was needed.
---
## Anti-patterns
1. **Forking the chart in `helm-templates/<incubator-tool>/templates/`** to add a missing values key. Wrap or upstream-PR; don't fork. See NEVER-DO.
2. **Copying the entire incubator directory across clusters** for graduation. Per-cluster scheduling is bespoke.
3. **Enabling autoscaling on day one.** No load profile = thrashy autoscaler.
4. **Promoting from `k8s-shared-int-ase1` straight to a critical BU cluster.** Insert a low-traffic prod canary first.
5. **Inlining secrets** "just for the trial." TruffleHog will block; even if it didn't, the leak is real.
6. **Setting `fullnameOverride`** without a graduation plan. The string travels — bad ones travel forever.
---
## Related
- Schema: [custom-values-schema.md](custom-values-schema.md) — general values shape.
- Schema: [raw-manifest-sidecar-schema.md](raw-manifest-sidecar-schema.md) — sidecar shapes.
- Schema: [storageclass-priorityclass-schema.md](storageclass-priorityclass-schema.md) — cluster-singleton resources.
- Procedure: [../procedures/onboard-app-to-cluster.md](../procedures/onboard-app-to-cluster.md) — the procedure used to land an incubator override.
- Procedure: [../procedures/fork-upstream-chart.md](../procedures/fork-upstream-chart.md) — only when a fork is genuinely required.
- Coding guideline: [../../global/coding-guidelines/helm-values.md](../../global/coding-guidelines/helm-values.md).
- Coding guideline: [../../global/coding-guidelines/argocd.md](../../global/coding-guidelines/argocd.md) — sister-repo Application conventions.
@@ -0,0 +1,191 @@
# Schema — Raw-manifest sidecars in `helm-overrides/`
> Field-by-field guidance for `helm-overrides/<cluster>/<app>/<extra>.yaml` — Kubernetes manifests applied **alongside** a Helm release, not through it.
---
## What this is
Some Argo CD Applications point at a directory containing both a Helm `custom-values.yaml` *and* one or more raw Kubernetes manifests. The raw manifests are not Helm-rendered; Argo CD applies them as-is.
Common shapes seen in this repo:
| Path pattern | What it is |
|--------------|------------|
| `helm-overrides/<cluster>/<app>/computeclass/*-cc.yaml` | GKE Autopilot `ComputeClass` resource — declares a node-pool/compute-class profile referenced by `nodeSelector` in the Helm values. |
| `helm-overrides/<cluster>/<app>/external-dns-services/<svc>.yaml` | A `Service` that exists purely to carry an `external-dns.alpha.kubernetes.io/hostname` annotation, binding a DNS name to a workload. |
| `helm-overrides/<cluster>/elastic-cluster/argo-launch.yaml` | An `ElasticCluster` (ECK CRD) launched alongside the operator. |
| `helm-overrides/<cluster>/<app>/mimir-distributed/alertmanager_config.yaml` | Inlined Alertmanager config materialised as a `ConfigMap`. |
If the sister-repo `Application` for this directory has `path: helm-overrides/<cluster>/<app>/`, then **every YAML file in the directory is applied** — Argo CD's directory loader treats them as a single deployment unit.
---
## File-level conventions
| Rule | Why |
|------|-----|
| **One Kubernetes resource per file** unless they're tightly coupled (e.g. a `Service` + a `ServiceAccount` referenced by it). | Reviewer cognition; rollback granularity. |
| **Pin `apiVersion` explicitly.** | `extensions/v1beta1` and `networking.k8s.io/v1beta1` are real footguns — both are gone in current Kubernetes. |
| **Set `metadata.namespace` explicitly.** | Don't rely on the Argo `Application.spec.destination.namespace` carrying through — different cluster Argos behave differently here. |
| **Trailing newline at EOF.** |
| **No multi-doc (`---`) within one file** unless genuinely required. |
---
## Top-level shape
```yaml
apiVersion: <api-version> # e.g. v1, networking.k8s.io/v1, autoscaling.gke.io/v1
kind: <kind> # e.g. Service, ComputeClass, ConfigMap, ExternalSecret
metadata:
name: <name>
namespace: <namespace>
labels: {...} # optional
annotations: {...} # often the load-bearing field (DNS, LB)
spec:
... # kind-specific
```
---
## Common kinds in this repo
### `ComputeClass` (`autoscaling.gke.io/v1`)
GKE Autopilot uses `ComputeClass` resources to declare named node profiles. The Helm values reference them via `cloud.google.com/compute-class:` keys.
```yaml
apiVersion: autoscaling.gke.io/v1
kind: ComputeClass
metadata:
name: contour-internal-0-cc
namespace: projectcontour
spec:
priorities:
- machineFamily: c4d
minCores: 4
minMemory: 16Gi
nodePoolAutoCreation:
enabled: true
```
| Rule | Why |
|------|-----|
| **`metadata.name` MUST match the value referenced by `nodeSelector` in the Helm values.** | Otherwise pods stay `Pending`. |
| **Per-cluster.** A `ComputeClass` for `k8s-central-prd-ase1` does not exist on `k8s-supply-prd-ase1`. Don't share files. |
| **The matrix of which `ComputeClass` exists where** is recorded in [contour-nodeselector-tolerations-summary.md](../../../contour-nodeselector-tolerations-summary.md). |
### `Service` for `external-dns` binding
```yaml
apiVersion: v1
kind: Service
metadata:
name: <hostname>-dns
namespace: <ns>
annotations:
external-dns.alpha.kubernetes.io/hostname: <fqdn>.meeshogcp.in
cloud.google.com/load-balancer-type: Internal
spec:
type: ClusterIP
selector: {app.kubernetes.io/name: <app>}
ports:
- port: 80
targetPort: 8080
```
| Rule | Why |
|------|-----|
| **`metadata.annotations.external-dns.alpha.kubernetes.io/hostname`** is the contract. Check the cluster's existing DNS pattern before authoring. |
| **`selector` must match labels of an actual workload Pod** in the same namespace. |
| **Cloud-LB annotations** (`cloud.google.com/load-balancer-type`, etc.) — copy from a sibling on the same cluster. |
### `ExternalSecret` (per-cluster `external-secrets/`)
```yaml
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: <secret-name>
namespace: <ns>
spec:
refreshInterval: 1h
secretStoreRef:
name: gcp-sm-store # cluster-level SecretStore, defined elsewhere
kind: ClusterSecretStore
target:
name: <secret-name>
creationPolicy: Owner
data:
- secretKey: <env-key>
remoteRef:
key: <gcp-secret-name>
version: latest
```
| Rule | Why |
|------|-----|
| **`spec.target.name` is the `Secret` name** the workload's `existingSecret:` references. |
| **`spec.secretStoreRef.name`** must reference a `SecretStore` / `ClusterSecretStore` that already exists on the cluster. |
| **`creationPolicy: Owner`** is the default; `creationPolicy: Merge` is for the rare case where another tool also manages the same `Secret`. |
### `ConfigMap` for inlined config
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: <name>
namespace: <ns>
data:
<key>: |
<multi-line content>
```
| Rule | Why |
|------|-----|
| **Use `|` (literal block scalar)** for multi-line content with significant whitespace. |
| **Don't inline secrets** (TruffleHog will catch obvious ones; subtle ones slip through). |
| **Reference from the workload's chart values** via the `ConfigMap` name; don't duplicate config across files. |
### `ElasticCluster` / other CRDs
For ECK, Pyroscope, etc. — the schema is the operator's, not Kubernetes's. **Read the operator's CRD docs** before authoring; copy a sibling cluster's existing `argo-launch.yaml` first.
---
## Layered-with-Helm vs standalone
| Pattern | Argo Application points at |
|---------|----------------------------|
| Pure Helm | `path: helm-overrides/<cluster>/<app>/` with `helm.valueFiles: ['custom-values.yaml']` |
| Pure raw manifests | `path: helm-overrides/<cluster>/<app>/` with `directory.recurse: true`, no `helm:` block |
| Layered | `path: helm-overrides/<cluster>/<app>/` with `helm.valueFiles: ['custom-values.yaml']` AND extra files alongside |
Argo CD's behaviour for layered directories depends on its `directory.include` / `directory.exclude` settings — when in doubt, read the sister-repo `Application` to see exactly what gets picked up.
---
## Validation
```bash
# Validate the manifest against its API
kubectl --dry-run=client -f helm-overrides/<cluster>/<app>/<extra>.yaml apply
# Lint
yamllint helm-overrides/<cluster>/<app>/<extra>.yaml
# Confirm the Argo Application loads this path
# (read the matching file in github.com/Meesho/devops-infra-argo-config)
```
---
## Anti-patterns
1. **Inlining secrets** in a `ConfigMap` "to ship a hotfix." It's still a secret. Use `ExternalSecret`.
2. **Using `apiVersion: v1beta1`** of a CRD whose stable version exists. Pin to the highest stable.
3. **A `Service` whose `selector` doesn't match any Pod** — silent: the Service exists, DNS resolves, no endpoints.
4. **Cross-cluster cloning** of a `ComputeClass` or DNS `Service` without rewriting cluster-specific fields.
5. **Hand-rendered Helm output** dropped into a sidecar file (a release "freeze"). The chart bumps and your snapshot rots.
@@ -0,0 +1,158 @@
# Schema — `manifests/storageclass/` and `manifests/priorityclass/`
> Cluster-wide singletons. **High blast radius — every PVC / scheduling decision in the cluster is affected.**
>
> Cross-reference: [SANCTITY_RULES R10](../../global/SANCTITY_RULES.md), [coding-guidelines/helm-values.md §persistence](../../global/coding-guidelines/helm-values.md).
---
## §StorageClass (`manifests/storageclass/*.yaml`)
These are **repo-global** — one StorageClass file is applied to every cluster that consumes it. A wrong reclaim policy or volume-binding mode breaks every new PVC.
### Inventory
| File | Backend | Reclaim | Binding | Use case |
|------|---------|---------|---------|----------|
| `pd-standard-retain-dr.yaml` | GCP PD standard | `Retain` | `WaitForFirstConsumer` | DR-critical state — do not lose data on PVC delete |
| `sc-pd-ssd.yaml` | GCP PD SSD | `Delete` | `WaitForFirstConsumer` | Default for write-heavy (etcd, ClickHouse) |
| `sc-pd-standard.yaml` | GCP PD standard | `Delete` | `WaitForFirstConsumer` | Default for read-heavy / archival |
| `sc-filestore-standard.yaml` | GCP Filestore | varies | varies | Shared `ReadWriteMany` volumes (Jenkins build cache, JFrog filestore) |
### Schema
```yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: sc-pd-ssd # MUST match filename
annotations:
storageclass.kubernetes.io/is-default-class: "false" # exactly one default per cluster
provisioner: pd.csi.storage.gke.io
parameters:
type: pd-ssd
reclaimPolicy: Delete # Delete | Retain
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
```
| Field | Convention | Notes |
|-------|------------|-------|
| `metadata.name` | matches filename (without `.yaml`) | Helm values reference by name. |
| `metadata.annotations."storageclass.kubernetes.io/is-default-class"` | `"false"` for all of these | Exactly one StorageClass should be `"true"` per cluster (declared elsewhere, often by Terraform/cluster-bootstrap). |
| `provisioner` | `pd.csi.storage.gke.io` (PD) or `filestore.csi.storage.gke.io` (Filestore) | GCP CSI drivers. |
| `parameters.type` | `pd-ssd`, `pd-standard`, `pd-balanced` | Cost/perf trade-off. |
| `reclaimPolicy` | `Delete` (default) or `Retain` (DR) | **Changing this on an existing StorageClass does not retroactively change PVCs.** |
| `volumeBindingMode` | `WaitForFirstConsumer` | Avoids zone-mismatch on multi-zone clusters. `Immediate` only for `ReadWriteMany`. |
| `allowVolumeExpansion` | `true` | Required for online resizing. Default false on some classes — set explicitly. |
### Hard rules
1. **Never delete a StorageClass referenced by an existing PVC.** New PVCs against the deleted class fail; existing bound PVCs survive but lose the ability to expand.
2. **Never change `reclaimPolicy` from `Delete` → `Retain`** as a "safety improvement" without auditing every PVC. Existing bound PVs keep their old policy; new PVs get the new policy. Drift.
3. **Never change `provisioner`** — that's a delete-and-recreate, not an edit. Existing PVs become orphaned.
4. **Never make a new StorageClass the cluster default** without coordinating with the platform team. A wrong default class hijacks every PVC that doesn't pin a class explicitly.
5. **Validation:** every StorageClass referenced by any `helm-overrides/*/persistence.storageClass:` must have a corresponding file here.
```bash
# Find every PVC reference
grep -rE 'storageClass(Name)?:' helm-overrides | sort -u
# Find every StorageClass file
ls manifests/storageclass/*.yaml
```
---
## §PriorityClass (`manifests/priorityclass/<cluster>/*.yaml`)
**Per-cluster** but **cluster-wide** — affects scheduling priority for every pod that references the class.
### Inventory pattern
```
manifests/priorityclass/
k8s-central-prd-ase1/
priorityclass-high.yaml
priorityclass-low.yaml
k8s-supply-prd-ase1/
priorityclass-high.yaml
priorityclass-low.yaml
```
Most BU clusters get a `high` and a `low` class. Specialty clusters (`mqkafka`, `dsgpu`, dataplane `db-*`) sometimes have additional tiers.
### Schema
```yaml
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: high-priority
value: 1000000 # higher = more important
globalDefault: false # NEVER true on these — would clash with system defaults
description: "High-priority workloads — promoted ahead of general pods on resource pressure"
preemptionPolicy: PreemptLowerPriority # default; alternative is Never
```
| Field | Convention | Notes |
|-------|------------|-------|
| `metadata.name` | `high-priority`, `low-priority`, etc. | Workload pods reference by name. |
| `value` | High: 1,000,000 / Low: 100 / Critical (rare): >1,000,000,000 | Kubernetes system pods reserve `> 2,000,000,000`; don't conflict. |
| `globalDefault` | **always `false`** | A `true` here applies to every pod that doesn't pin a class — chaos. |
| `description` | one-line | For audit log. |
| `preemptionPolicy` | `PreemptLowerPriority` (default) or `Never` | `Never` for batch workloads that shouldn't kick others out. |
### Hard rules
1. **Never set `globalDefault: true`** on any PriorityClass here. The cluster's implicit default is what we want.
2. **Never raise `value`** of an existing class without auditing what gets preempted. A bump from 1,000,000 → 10,000,000 changes which pods get evicted under pressure.
3. **Never delete a PriorityClass** referenced by any workload — pods that referenced it become invalid.
4. **The same `name` must mean the same thing across clusters.** `high-priority` on supply ≠ `high-priority` on demand at the *value* level is an audit nightmare. Keep values consistent.
5. **Validation:** find every pod-spec reference:
```bash
grep -rE 'priorityClassName:' helm-overrides
```
---
## §The "PV/PVC singletons" — Jenkins / JFrog filestore
Beyond StorageClass and PriorityClass, `manifests/` also holds **per-env, one-shot** PV/PVC pairs:
```
manifests/jenkins-filestore-caching/
dev/{pv,pvc}.yaml
prd/{pv,pvc}.yaml
manifests/jenkins-gcs-caching/{pv,pvc,sc-gcs}.yaml
manifests/jfrog-filestore-data/
dev/...
prd/...
```
These are **already-created PVs being adopted** — typically because the underlying disk (Filestore mount, GCS bucket) was provisioned by Terraform or by hand. The PV file binds the existing disk to the cluster; the PVC file binds a workload to the PV.
| Rule | Why |
|------|-----|
| **Don't change `spec.csi.volumeHandle` / `spec.gcePersistentDisk.pdName`** without coordinating with Terraform. The handle is the disk identity. |
| **Don't change `spec.persistentVolumeReclaimPolicy`** from `Retain` to `Delete` on these. The disk has data on it. |
| **Don't move dev→prd or vice versa** — they reference different physical disks. |
| **Treat as platform-team review.** Any change here is a 1:1 disk operation. |
---
## Validation script
```bash
# StorageClass: every name in helm-overrides has a file here
for sc in $(grep -rhE 'storageClass(Name)?:' helm-overrides \
| sed -E 's/.*storageClass(Name)?:\s*//' \
| tr -d '"' | sort -u); do
[ -f "manifests/storageclass/${sc}.yaml" ] || echo "MISSING: $sc"
done
# PriorityClass: every name referenced has a file in the matching cluster
grep -rE 'priorityClassName:' helm-overrides
# (cross-reference manually against manifests/priorityclass/<cluster>/)
```
@@ -0,0 +1,478 @@
# Default values for kube-state-metrics.
prometheusScrape: true
image:
registry: asia-southeast1-docker.pkg.dev
repository: meesho-devops-admin-0622/admin/sre/kube-state-metrics
# If unset use v + .Charts.appVersion
tag: v2.9.2
sha: ""
pullPolicy: IfNotPresent
fullnameOverride: kube-state-metrics-dbc-dsci-prd
dedicatedValue: false
imagePullSecrets: []
# - name: "image-pull-secret"
ingress:
enabled: false
ingressClassName: internal
annotations:
nginx.ingress.kubernetes.io/force-ssl-redirect: "false"
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/ssl-redirect: "false"
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: 'true'
extraLabels: {}
hosts:
- name: clustermetrics-dbc-dsci-prd.meesho.com
path: /
port: http
tls: []
# - secretName: vmagent-ingress-tls
# hosts:
# - vmagent.local
# For Kubernetes >= 1.18 you should specify the ingress-controller via the field ingressClassName
# See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#specifying-the-class-of-an-ingress
# ingressClassName: nginx
# -- pathType is only for k8s >= 1.1=
pathType: Prefix
global:
# To help compatibility with other charts which use global.imagePullSecrets.
# Allow either an array of {name: pullSecret} maps (k8s-style), or an array of strings (more common helm-style).
# global:
# imagePullSecrets:
# - name: pullSecret1
# - name: pullSecret2
# or
# global:
# imagePullSecrets:
# - pullSecret1
# - pullSecret2
imagePullSecrets: []
#
# Allow parent charts to override registry hostname
imageRegistry: ""
# If set to true, this will deploy kube-state-metrics as a StatefulSet and the data
# will be automatically sharded across <.Values.replicas> pods using the built-in
# autodiscovery feature: https://github.com/kubernetes/kube-state-metrics#automated-sharding
# This is an experimental feature and there are no stability guarantees.
autosharding:
enabled: false
replicas: 2
# List of additional cli arguments to configure kube-state-metrics
# for example: --enable-gzip-encoding, --log-file, etc.
# all the possible args can be found here: https://github.com/kubernetes/kube-state-metrics/blob/master/docs/cli-arguments.md
extraArgs: []
service:
port: 8080
# Default to clusterIP for backward compatibility
type: ClusterIP
nodePort: 0
loadBalancerIP: ""
# Only allow access to the loadBalancerIP from these IPs
loadBalancerSourceRanges: []
clusterIP: ""
annotations: {}
## Additional labels to add to all resources
customLabels:
bu: "dbc-dsci"
team: "dbc-dsci-sre"
service: "kube-state-metrics-dbc-dsci-prd"
env: "prd"
priority: "p0"
type: "exporter"
# app: kube-state-metrics
## Override selector labels
selectorOverride: {}
## set to true to add the release label so scraping of the servicemonitor with kube-prometheus-stack works out of the box
releaseLabel: false
hostNetwork: false
rbac:
# If true, create & use RBAC resources
create: true
# Set to a rolename to use existing role - skipping role creating - but still doing serviceaccount and rolebinding to it, rolename set here.
# useExistingRole: your-existing-role
# If set to false - Run without Cluteradmin privs needed - ONLY works if namespace is also set (if useExistingRole is set this name is used as ClusterRole or Role to bind to)
useClusterRole: true
# Add permissions for CustomResources' apiGroups in Role/ClusterRole. Should be used in conjunction with Custom Resource State Metrics configuration
# Example:
# - apiGroups: ["monitoring.coreos.com"]
# resources: ["prometheuses"]
# verbs: ["list", "watch"]
extraRules: []
# Configure kube-rbac-proxy. When enabled, creates one kube-rbac-proxy container per exposed HTTP endpoint (metrics and telemetry if enabled).
# The requests are served through the same service but requests are then HTTPS.
kubeRBACProxy:
enabled: false
image:
registry: quay.io
repository: brancz/kube-rbac-proxy
tag: v0.14.0
sha: ""
pullPolicy: IfNotPresent
# List of additional cli arguments to configure kube-rbac-prxy
# for example: --tls-cipher-suites, --log-file, etc.
# all the possible args can be found here: https://github.com/brancz/kube-rbac-proxy#usage
extraArgs: []
## Specify security settings for a Container
## Allows overrides and additional options compared to (Pod) securityContext
## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container
containerSecurityContext: {}
resources: {}
# 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:'.
# limits:
# cpu: 100m
# memory: 64Mi
# requests:
# cpu: 10m
# memory: 32Mi
## volumeMounts enables mounting custom volumes in rbac-proxy containers
## Useful for TLS certificates and keys
volumeMounts: []
# - mountPath: /etc/tls
# name: kube-rbac-proxy-tls
# readOnly: true
serviceAccount:
# Specifies whether a ServiceAccount should be created, require rbac true
create: true
# The name of the ServiceAccount to use.
# If not set and create is true, a name is generated using the fullname template
name:
# Reference to one or more secrets to be used when pulling images
# ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
imagePullSecrets: []
# ServiceAccount annotations.
# Use case: AWS EKS IAM roles for service accounts
# ref: https://docs.aws.amazon.com/eks/latest/userguide/specify-service-account-role.html
annotations: {}
prometheus:
monitor:
enabled: false
annotations: {}
additionalLabels: {}
namespace: ""
jobLabel: ""
targetLabels: []
podTargetLabels: []
interval: ""
## SampleLimit defines per-scrape limit on number of scraped samples that will be accepted.
##
sampleLimit: 0
## TargetLimit defines a limit on the number of scraped targets that will be accepted.
##
targetLimit: 0
## Per-scrape limit on number of labels that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer.
##
labelLimit: 0
## Per-scrape limit on length of labels name that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer.
##
labelNameLengthLimit: 0
## Per-scrape limit on length of labels value that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer.
##
labelValueLengthLimit: 0
scrapeTimeout: ""
proxyUrl: ""
selectorOverride: {}
honorLabels: false
metricRelabelings: []
relabelings: []
scheme: ""
## File to read bearer token for scraping targets
bearerTokenFile: ""
## Secret to mount to read bearer token for scraping targets. The secret needs
## to be in the same namespace as the service monitor and accessible by the
## Prometheus Operator
bearerTokenSecret: {}
# name: secret-name
# key: key-name
tlsConfig: {}
## Specify if a Pod Security Policy for kube-state-metrics must be created
## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/
##
podSecurityPolicy:
enabled: false
annotations: {}
## Specify pod annotations
## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#apparmor
## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#seccomp
## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#sysctl
##
# seccomp.security.alpha.kubernetes.io/allowedProfileNames: '*'
# seccomp.security.alpha.kubernetes.io/defaultProfileName: 'docker/default'
# apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default'
additionalVolumes: []
## Configure network policy for kube-state-metrics
networkPolicy:
enabled: false
# networkPolicy.flavor -- Flavor of the network policy to use.
# Can be:
# * kubernetes for networking.k8s.io/v1/NetworkPolicy
# * cilium for cilium.io/v2/CiliumNetworkPolicy
flavor: kubernetes
## Configure the cilium network policy kube-apiserver selector
# cilium:
# kubeApiServerSelector:
# - toEntities:
# - kube-apiserver
# egress:
# - {}
# ingress:
# - {}
# podSelector:
# matchLabels:
# app.kubernetes.io/name: kube-state-metrics
securityContext:
enabled: true
runAsGroup: 65534
runAsUser: 65534
fsGroup: 65534
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
## Specify security settings for a Container
## Allows overrides and additional options compared to (Pod) securityContext
## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container
containerSecurityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
## Node labels for pod assignment
## Ref: https://kubernetes.io/docs/user-guide/node-selection/
nodeSelector:
dedicated: "devops"
## Affinity settings for pod assignment
## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/
affinity: {}
## Tolerations for pod assignment
## Ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/
tolerations:
- key: "dedicated"
operator: "Equal"
value: "devops"
effect: "NoSchedule"
## Topology spread constraints for pod assignment
## Ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
type: exporter
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
type: exporter
# Annotations to be added to the deployment/statefulset
annotations:
kubernetes.io/psp: eks.privileged
# Annotations to be added to the pod
podAnnotations: {}
## Assign a PriorityClassName to pods if set
# priorityClassName: ""
# Ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/
podDisruptionBudget: {}
# Comma-separated list of metrics to be exposed.
# This list comprises of exact metric names and/or regex patterns.
# The allowlist and denylist are mutually exclusive.
metricAllowlist: []
# Comma-separated list of metrics not to be enabled.
# This list comprises of exact metric names and/or regex patterns.
# The allowlist and denylist are mutually exclusive.
metricDenylist: []
# Comma-separated list of additional Kubernetes label keys that will be used in the resource's
# labels metric. By default the metric contains only name and namespace labels.
# To include additional labels, provide a list of resource names in their plural form and Kubernetes
# label keys you would like to allow for them (Example: '=namespaces=[k8s-label-1,k8s-label-n,...],pods=[app],...)'.
# A single '*' can be provided per resource instead to allow any labels, but that has
# severe performance implications (Example: '=pods=[*]').
metricLabelsAllowlist:
- pods=[*]
- nodes=[*]
- deployments=[*]
- statefulsets=[*]
- persistentvolumeclaims=[*]
- persistentvolumes=[*]
- ingresses=[*]
- namespaces=[*]
- horizontalpodautoscalers=[*]
# - namespaces=[k8s-label-1,k8s-label-n]
# Comma-separated list of Kubernetes annotations keys that will be used in the resource'
# labels metric. By default the metric contains only name and namespace labels.
# To include additional annotations provide a list of resource names in their plural form and Kubernetes
# annotation keys you would like to allow for them (Example: '=namespaces=[kubernetes.io/team,...],pods=[kubernetes.io/team],...)'.
# A single '*' can be provided per resource instead to allow any annotations, but that has
# severe performance implications (Example: '=pods=[*]').
metricAnnotationsAllowList: []
# - pods=[k8s-annotation-1,k8s-annotation-n]
# Available collectors for kube-state-metrics.
# By default, all available resources are enabled, comment out to disable.
collectors:
- certificatesigningrequests
- configmaps
- cronjobs
- daemonsets
- deployments
- endpoints
- horizontalpodautoscalers
- ingresses
- jobs
- leases
- limitranges
- mutatingwebhookconfigurations
- namespaces
- networkpolicies
- nodes
- persistentvolumeclaims
- persistentvolumes
- poddisruptionbudgets
- pods
- replicasets
- replicationcontrollers
- resourcequotas
- secrets
- services
- statefulsets
- storageclasses
- validatingwebhookconfigurations
- volumeattachments
# Enabling kubeconfig will pass the --kubeconfig argument to the container
kubeconfig:
enabled: false
# base64 encoded kube-config file
secret:
# Enabling support for customResourceState, will create a configMap including your config that will be read from kube-state-metrics
customResourceState:
enabled: false
# Add (Cluster)Role permissions to list/watch the customResources defined in the config to rbac.extraRules
config: {}
# Enable only the release namespace for collecting resources. By default all namespaces are collected.
# If releaseNamespace and namespaces are both set a merged list will be collected.
releaseNamespace: false
# Comma-separated list(string) or yaml list of namespaces to be enabled for collecting resources. By default all namespaces are collected.
namespaces: ""
# Comma-separated list of namespaces not to be enabled. If namespaces and namespaces-denylist are both set,
# only namespaces that are excluded in namespaces-denylist will be used.
namespacesDenylist: ""
## Override the deployment namespace
##
namespaceOverride: ""
resources:
# 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:'.
# limits:
# cpu: 100m
# memory: 64Mi
requests:
cpu: 10m
memory: 50Mi
## Provide a k8s version to define apiGroups for podSecurityPolicy Cluster Role.
## For example: kubeTargetVersionOverride: 1.14.9
##
kubeTargetVersionOverride: ""
# Enable self metrics configuration for service and Service Monitor
# Default values for telemetry configuration can be overridden
# If you set telemetryNodePort, you must also set service.type to NodePort
selfMonitor:
enabled: true
# telemetryHost: 0.0.0.0
telemetryPort: 8081
# telemetryNodePort: 0
# Enable vertical pod autoscaler support for kube-state-metrics
verticalPodAutoscaler:
enabled: false
# List of resources that the vertical pod autoscaler can control. Defaults to cpu and memory
controlledResources: []
# Define the max allowed resources for the pod
maxAllowed: {}
# cpu: 200m
# memory: 100Mi
# Define the min allowed resources for the pod
minAllowed: {}
# cpu: 200m
# memory: 100Mi
# updatePolicy:
# Specifies whether recommended updates are applied when a Pod is started and whether recommended updates
# are applied during the life of a Pod. Possible values are "Off", "Initial", "Recreate", and "Auto".
# updateMode: Auto
# volumeMounts are used to add custom volume mounts to deployment.
# See example below
volumeMounts: []
# - mountPath: /etc/config
# name: config-volume
# volumes are used to add custom volumes to deployment
# See example below
volumes: []
# - configMap:
# name: cm-for-volume
# name: config-volume
@@ -0,0 +1,296 @@
# Default values for victoria-metrics-agent.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 2
fullnameOverride: vmagent-dbc-dsci-prd
# vmagent scraping configuration:
# https://github.com/VictoriaMetrics/VictoriaMetrics/blob/master/docs/vmagent.md#how-to-collect-metrics-in-prometheus-format
# use existing configmap if specified
# otherwise .config values will be used
configMap: "vmagent-dbc-dsci-prd-config" # Use same name as in fullnameOverride-config
dedicatedValue: false
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: ScheduleAnyway
labelSelector:
matchLabels:
type: vmagent
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
type: vmagent
# ref: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/
deployment:
enabled: true
# vmagent pods will take almost 20-25 mins to work properly
minReadySeconds: 180
progressDeadlineSeconds: 300
# ref: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#strategy
strategy: {}
# rollingUpdate:
# maxSurge: 25%
# maxUnavailable: 25%
# type: RollingUpdate
# ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/
statefulset:
enabled: false
# -- create cluster of vmagents. See https://docs.victoriametrics.com/vmagent.html#scraping-big-number-of-targets
# available since 1.77.2 version https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.77.2
clusterMode: false
# -- replication factor for vmagent in cluster mode
replicationFactor: 1
# ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#update-strategies
updateStrategy: {}
# type: RollingUpdate
image:
repository: asia-southeast1-docker.pkg.dev/meesho-devops-admin-0622/admin/sre/vmagent
tag: v1.93.7-cluster # rewrites Chart.AppVersion
pullPolicy: IfNotPresent
imagePullSecrets: []
nameOverride: ""
containerWorkingDir: "/"
rbac:
create: true
# Note: The PSP will only be deployed, if Kubernetes (<1.25) supports the resource.
pspEnabled: true
annotations: {}
extraLabels: {}
# -- if true and `rbac.enabled`, will deploy a Role/Rolebinding instead of a ClusterRole/ClusterRoleBinding
namespaced: false
serviceAccount:
# Specifies whether a service account should be created
create: true
# Annotations to add to the service account
annotations: {
iam.gke.io/gcp-service-account: sa-dbc-desre-vmagent-prd@meesho-dbc-prd-0622.iam.gserviceaccount.com
}
# 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
## ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/
podDisruptionBudget:
enabled: false
# minAvailable: 1
# maxUnavailable: 1
labels: {}
# WARN: need to specify at least one remote write url or one multi tenant url
# remoteWriteUrls: []
remoteWriteUrls:
# - https://vminsert-prd-dbc.meeshogcp.in/insert/100/prometheus/api/v1/write
- http://vminsert-dbc-prd.meeshogcp.in/insert/100/prometheus/api/v1/write
# - http://prometheus:8480/insert/0/prometheus
multiTenantUrls: []
# multiTenantUrls:
# - http://vm-insert-az1:8480
# - http://vm-insert-az2:8480
extraArgs:
envflag.enable: "true"
envflag.prefix: VM_
loggerFormat: json
promscrape.config.strictParse: false
promscrape.maxScrapeSize: 1000000000
promscrape.minResponseSizeForStreamParse: 1000000
loggerTimezone: "Asia/Kolkata"
# Uncomment and specify the port if you want to support any of the protocols:
# https://victoriametrics.github.io/vmagent.html#features
# graphiteListenAddr: ":2003"
# influxListenAddr: ":8189"
# opentsdbHTTPListenAddr: ":4242"
# opentsdbListenAddr: ":4242"
# -- Additional environment variables (ex.: secret tokens, flags) https://github.com/VictoriaMetrics/VictoriaMetrics#environment-variables
env:
[]
# - name: VM_remoteWrite_basicAuth_password
# valueFrom:
# secretKeyRef:
# name: auth_secret
# key: password
# extra Labels for Pods, Deployment and Statefulset
extraLabels:
bu: "dbc-dsci"
team: "dbc-dsci-sre"
service: "vmagent-dbc-dsci-prd"
env: "prd"
priority: "p0"
type: "vmagent"
# extra Labels for Pods only
podLabels: {}
# 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
extraContainers: []
# - name: config-reloader
# image: reloader-image
podSecurityContext:
{}
# fsGroup: 2000
securityContext:
{}
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
service:
enabled: true
annotations: {}
# cloud.google.com/neg: '{"exposed_ports": {"8429":{"name": "vmagent-dbc-prd"}}}'
extraLabels: {}
clusterIP: ""
## Ref: https://kubernetes.io/docs/user-guide/services/#external-ips
##
externalIPs: []
loadBalancerIP: ""
loadBalancerSourceRanges: []
servicePort: 8429
# nodePort: 30000
type: ClusterIP
# Ref: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip
# externalTrafficPolicy: "local"
# healthCheckNodePort: 0
ingress:
enabled: true
ingressClassName: nginx-internal
annotations:
nginx.ingress.kubernetes.io/force-ssl-redirect: "false"
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/ssl-redirect: "false"
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: 'true'
extraLabels: {}
hosts:
- name: vmagent-dbc-dsci-prd.meeshogcp.in
path: /
port: http
tls: []
# - secretName: vmagent-ingress-tls
# hosts:
# - vmagent.local
# For Kubernetes >= 1.18 you should specify the ingress-controller via the field ingressClassName
# See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#specifying-the-class-of-an-ingress
# ingressClassName: nginx
# -- pathType is only for k8s >= 1.1=
pathType: Prefix
resources:
# 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:'.
# limits:
# cpu: 100m
# memory: 128Mi
requests:
cpu: 2
memory: 4Gi
# Annotations to be added to the deployment
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "8429"
# Annotations to be added to pod
podAnnotations:
prometheus.io/scrape: "true"
prometheus.io/port: "8429"
nodeSelector:
dedicated: "devops"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "devops"
effect: "NoSchedule"
affinity: {}
# -- priority class to be assigned to the pod(s)
priorityClassName: ""
serviceMonitor:
enabled: false
extraLabels: {}
annotations: {}
relabelings: []
# 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
persistence:
enabled: false
# storageClassName: default
accessModes:
- ReadWriteOnce
size: 10Gi
annotations: {}
extraLabels: {}
existingClaim: ""
# -- Bind Persistent Volume by labels. Must match all labels of targeted PV.
matchLabels: {}
# -- Extra scrape configs that will be appended to `config`
extraScrapeConfigs: []
# Add extra specs dynamically to this chart
extraObjects: []
@@ -0,0 +1,26 @@
ingress-nginx:
controller:
metrics:
enabled: true
podAnnotations:
prometheus.io/port: "10254"
prometheus.io/scrape: "true"
autoscaling:
enabled: true
minReplicas: 3
maxReplicas: 6
targetCPUUtilizationPercentage: 60
targetMemoryUtilizationPercentage: 60
ingressClassResource:
name: nginx-internal
service:
type: ClusterIP
annotations:
cloud.google.com/neg: '{"exposed_ports": {"80":{"name": "nginx-dbc-internal-prd"}}}'
nodeSelector:
dedicated: devops
tolerations:
- key: "dedicated"
operator: "Equal"
value: "devops"
effect: "NoSchedule"
@@ -0,0 +1,478 @@
# Default values for kube-state-metrics.
prometheusScrape: true
image:
registry: asia-southeast1-docker.pkg.dev
repository: meesho-devops-admin-0622/admin/sre/kube-state-metrics
# If unset use v + .Charts.appVersion
tag: v2.9.2
sha: ""
pullPolicy: IfNotPresent
fullnameOverride: kube-state-metrics-dbc-dengg-prd
dedicatedValue: false
imagePullSecrets: []
# - name: "image-pull-secret"
ingress:
enabled: false
ingressClassName: internal
annotations:
nginx.ingress.kubernetes.io/force-ssl-redirect: "false"
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/ssl-redirect: "false"
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: 'true'
extraLabels: {}
hosts:
- name: clustermetrics-dbc-dengg-prd.meesho.com
path: /
port: http
tls: []
# - secretName: vmagent-ingress-tls
# hosts:
# - vmagent.local
# For Kubernetes >= 1.18 you should specify the ingress-controller via the field ingressClassName
# See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#specifying-the-class-of-an-ingress
# ingressClassName: nginx
# -- pathType is only for k8s >= 1.1=
pathType: Prefix
global:
# To help compatibility with other charts which use global.imagePullSecrets.
# Allow either an array of {name: pullSecret} maps (k8s-style), or an array of strings (more common helm-style).
# global:
# imagePullSecrets:
# - name: pullSecret1
# - name: pullSecret2
# or
# global:
# imagePullSecrets:
# - pullSecret1
# - pullSecret2
imagePullSecrets: []
#
# Allow parent charts to override registry hostname
imageRegistry: ""
# If set to true, this will deploy kube-state-metrics as a StatefulSet and the data
# will be automatically sharded across <.Values.replicas> pods using the built-in
# autodiscovery feature: https://github.com/kubernetes/kube-state-metrics#automated-sharding
# This is an experimental feature and there are no stability guarantees.
autosharding:
enabled: false
replicas: 2
# List of additional cli arguments to configure kube-state-metrics
# for example: --enable-gzip-encoding, --log-file, etc.
# all the possible args can be found here: https://github.com/kubernetes/kube-state-metrics/blob/master/docs/cli-arguments.md
extraArgs: []
service:
port: 8080
# Default to clusterIP for backward compatibility
type: ClusterIP
nodePort: 0
loadBalancerIP: ""
# Only allow access to the loadBalancerIP from these IPs
loadBalancerSourceRanges: []
clusterIP: ""
annotations: {}
## Additional labels to add to all resources
customLabels:
bu: "dbc-dengg"
team: "dbc-dengg-sre"
service: "kube-state-metrics-dbc-dengg-prd"
env: "prd"
priority: "p0"
type: "exporter"
# app: kube-state-metrics
## Override selector labels
selectorOverride: {}
## set to true to add the release label so scraping of the servicemonitor with kube-prometheus-stack works out of the box
releaseLabel: false
hostNetwork: false
rbac:
# If true, create & use RBAC resources
create: true
# Set to a rolename to use existing role - skipping role creating - but still doing serviceaccount and rolebinding to it, rolename set here.
# useExistingRole: your-existing-role
# If set to false - Run without Cluteradmin privs needed - ONLY works if namespace is also set (if useExistingRole is set this name is used as ClusterRole or Role to bind to)
useClusterRole: true
# Add permissions for CustomResources' apiGroups in Role/ClusterRole. Should be used in conjunction with Custom Resource State Metrics configuration
# Example:
# - apiGroups: ["monitoring.coreos.com"]
# resources: ["prometheuses"]
# verbs: ["list", "watch"]
extraRules: []
# Configure kube-rbac-proxy. When enabled, creates one kube-rbac-proxy container per exposed HTTP endpoint (metrics and telemetry if enabled).
# The requests are served through the same service but requests are then HTTPS.
kubeRBACProxy:
enabled: false
image:
registry: quay.io
repository: brancz/kube-rbac-proxy
tag: v0.14.0
sha: ""
pullPolicy: IfNotPresent
# List of additional cli arguments to configure kube-rbac-prxy
# for example: --tls-cipher-suites, --log-file, etc.
# all the possible args can be found here: https://github.com/brancz/kube-rbac-proxy#usage
extraArgs: []
## Specify security settings for a Container
## Allows overrides and additional options compared to (Pod) securityContext
## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container
containerSecurityContext: {}
resources: {}
# 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:'.
# limits:
# cpu: 100m
# memory: 64Mi
# requests:
# cpu: 10m
# memory: 32Mi
## volumeMounts enables mounting custom volumes in rbac-proxy containers
## Useful for TLS certificates and keys
volumeMounts: []
# - mountPath: /etc/tls
# name: kube-rbac-proxy-tls
# readOnly: true
serviceAccount:
# Specifies whether a ServiceAccount should be created, require rbac true
create: true
# The name of the ServiceAccount to use.
# If not set and create is true, a name is generated using the fullname template
name:
# Reference to one or more secrets to be used when pulling images
# ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
imagePullSecrets: []
# ServiceAccount annotations.
# Use case: AWS EKS IAM roles for service accounts
# ref: https://docs.aws.amazon.com/eks/latest/userguide/specify-service-account-role.html
annotations: {}
prometheus:
monitor:
enabled: false
annotations: {}
additionalLabels: {}
namespace: ""
jobLabel: ""
targetLabels: []
podTargetLabels: []
interval: ""
## SampleLimit defines per-scrape limit on number of scraped samples that will be accepted.
##
sampleLimit: 0
## TargetLimit defines a limit on the number of scraped targets that will be accepted.
##
targetLimit: 0
## Per-scrape limit on number of labels that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer.
##
labelLimit: 0
## Per-scrape limit on length of labels name that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer.
##
labelNameLengthLimit: 0
## Per-scrape limit on length of labels value that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer.
##
labelValueLengthLimit: 0
scrapeTimeout: ""
proxyUrl: ""
selectorOverride: {}
honorLabels: false
metricRelabelings: []
relabelings: []
scheme: ""
## File to read bearer token for scraping targets
bearerTokenFile: ""
## Secret to mount to read bearer token for scraping targets. The secret needs
## to be in the same namespace as the service monitor and accessible by the
## Prometheus Operator
bearerTokenSecret: {}
# name: secret-name
# key: key-name
tlsConfig: {}
## Specify if a Pod Security Policy for kube-state-metrics must be created
## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/
##
podSecurityPolicy:
enabled: false
annotations: {}
## Specify pod annotations
## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#apparmor
## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#seccomp
## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#sysctl
##
# seccomp.security.alpha.kubernetes.io/allowedProfileNames: '*'
# seccomp.security.alpha.kubernetes.io/defaultProfileName: 'docker/default'
# apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default'
additionalVolumes: []
## Configure network policy for kube-state-metrics
networkPolicy:
enabled: false
# networkPolicy.flavor -- Flavor of the network policy to use.
# Can be:
# * kubernetes for networking.k8s.io/v1/NetworkPolicy
# * cilium for cilium.io/v2/CiliumNetworkPolicy
flavor: kubernetes
## Configure the cilium network policy kube-apiserver selector
# cilium:
# kubeApiServerSelector:
# - toEntities:
# - kube-apiserver
# egress:
# - {}
# ingress:
# - {}
# podSelector:
# matchLabels:
# app.kubernetes.io/name: kube-state-metrics
securityContext:
enabled: true
runAsGroup: 65534
runAsUser: 65534
fsGroup: 65534
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
## Specify security settings for a Container
## Allows overrides and additional options compared to (Pod) securityContext
## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container
containerSecurityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
## Node labels for pod assignment
## Ref: https://kubernetes.io/docs/user-guide/node-selection/
nodeSelector:
dedicated: "devops"
## Affinity settings for pod assignment
## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/
affinity: {}
## Tolerations for pod assignment
## Ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/
tolerations:
- key: "dedicated"
operator: "Equal"
value: "devops"
effect: "NoSchedule"
## Topology spread constraints for pod assignment
## Ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
type: exporter
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
type: exporter
# Annotations to be added to the deployment/statefulset
annotations:
kubernetes.io/psp: eks.privileged
# Annotations to be added to the pod
podAnnotations: {}
## Assign a PriorityClassName to pods if set
# priorityClassName: ""
# Ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/
podDisruptionBudget: {}
# Comma-separated list of metrics to be exposed.
# This list comprises of exact metric names and/or regex patterns.
# The allowlist and denylist are mutually exclusive.
metricAllowlist: []
# Comma-separated list of metrics not to be enabled.
# This list comprises of exact metric names and/or regex patterns.
# The allowlist and denylist are mutually exclusive.
metricDenylist: []
# Comma-separated list of additional Kubernetes label keys that will be used in the resource's
# labels metric. By default the metric contains only name and namespace labels.
# To include additional labels, provide a list of resource names in their plural form and Kubernetes
# label keys you would like to allow for them (Example: '=namespaces=[k8s-label-1,k8s-label-n,...],pods=[app],...)'.
# A single '*' can be provided per resource instead to allow any labels, but that has
# severe performance implications (Example: '=pods=[*]').
metricLabelsAllowlist:
- pods=[*]
- nodes=[*]
- deployments=[*]
- statefulsets=[*]
- persistentvolumeclaims=[*]
- persistentvolumes=[*]
- ingresses=[*]
- namespaces=[*]
- horizontalpodautoscalers=[*]
# - namespaces=[k8s-label-1,k8s-label-n]
# Comma-separated list of Kubernetes annotations keys that will be used in the resource'
# labels metric. By default the metric contains only name and namespace labels.
# To include additional annotations provide a list of resource names in their plural form and Kubernetes
# annotation keys you would like to allow for them (Example: '=namespaces=[kubernetes.io/team,...],pods=[kubernetes.io/team],...)'.
# A single '*' can be provided per resource instead to allow any annotations, but that has
# severe performance implications (Example: '=pods=[*]').
metricAnnotationsAllowList: []
# - pods=[k8s-annotation-1,k8s-annotation-n]
# Available collectors for kube-state-metrics.
# By default, all available resources are enabled, comment out to disable.
collectors:
- certificatesigningrequests
- configmaps
- cronjobs
- daemonsets
- deployments
- endpoints
- horizontalpodautoscalers
- ingresses
- jobs
- leases
- limitranges
- mutatingwebhookconfigurations
- namespaces
- networkpolicies
- nodes
- persistentvolumeclaims
- persistentvolumes
- poddisruptionbudgets
- pods
- replicasets
- replicationcontrollers
- resourcequotas
- secrets
- services
- statefulsets
- storageclasses
- validatingwebhookconfigurations
- volumeattachments
# Enabling kubeconfig will pass the --kubeconfig argument to the container
kubeconfig:
enabled: false
# base64 encoded kube-config file
secret:
# Enabling support for customResourceState, will create a configMap including your config that will be read from kube-state-metrics
customResourceState:
enabled: false
# Add (Cluster)Role permissions to list/watch the customResources defined in the config to rbac.extraRules
config: {}
# Enable only the release namespace for collecting resources. By default all namespaces are collected.
# If releaseNamespace and namespaces are both set a merged list will be collected.
releaseNamespace: false
# Comma-separated list(string) or yaml list of namespaces to be enabled for collecting resources. By default all namespaces are collected.
namespaces: ""
# Comma-separated list of namespaces not to be enabled. If namespaces and namespaces-denylist are both set,
# only namespaces that are excluded in namespaces-denylist will be used.
namespacesDenylist: ""
## Override the deployment namespace
##
namespaceOverride: ""
resources:
# 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:'.
# limits:
# cpu: 100m
# memory: 64Mi
requests:
cpu: 10m
memory: 50Mi
## Provide a k8s version to define apiGroups for podSecurityPolicy Cluster Role.
## For example: kubeTargetVersionOverride: 1.14.9
##
kubeTargetVersionOverride: ""
# Enable self metrics configuration for service and Service Monitor
# Default values for telemetry configuration can be overridden
# If you set telemetryNodePort, you must also set service.type to NodePort
selfMonitor:
enabled: true
# telemetryHost: 0.0.0.0
telemetryPort: 8081
# telemetryNodePort: 0
# Enable vertical pod autoscaler support for kube-state-metrics
verticalPodAutoscaler:
enabled: false
# List of resources that the vertical pod autoscaler can control. Defaults to cpu and memory
controlledResources: []
# Define the max allowed resources for the pod
maxAllowed: {}
# cpu: 200m
# memory: 100Mi
# Define the min allowed resources for the pod
minAllowed: {}
# cpu: 200m
# memory: 100Mi
# updatePolicy:
# Specifies whether recommended updates are applied when a Pod is started and whether recommended updates
# are applied during the life of a Pod. Possible values are "Off", "Initial", "Recreate", and "Auto".
# updateMode: Auto
# volumeMounts are used to add custom volume mounts to deployment.
# See example below
volumeMounts: []
# - mountPath: /etc/config
# name: config-volume
# volumes are used to add custom volumes to deployment
# See example below
volumes: []
# - configMap:
# name: cm-for-volume
# name: config-volume
@@ -0,0 +1,296 @@
# Default values for victoria-metrics-agent.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 2
fullnameOverride: vmagent-dbc-dengg-prd
# vmagent scraping configuration:
# https://github.com/VictoriaMetrics/VictoriaMetrics/blob/master/docs/vmagent.md#how-to-collect-metrics-in-prometheus-format
# use existing configmap if specified
# otherwise .config values will be used
configMap: "vmagent-dbc-dengg-prd-config" # Use same name as in fullnameOverride-config
dedicatedValue: false
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: ScheduleAnyway
labelSelector:
matchLabels:
type: vmagent
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
type: vmagent
# ref: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/
deployment:
enabled: true
# vmagent pods will take almost 20-25 mins to work properly
minReadySeconds: 180
progressDeadlineSeconds: 300
# ref: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#strategy
strategy: {}
# rollingUpdate:
# maxSurge: 25%
# maxUnavailable: 25%
# type: RollingUpdate
# ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/
statefulset:
enabled: false
# -- create cluster of vmagents. See https://docs.victoriametrics.com/vmagent.html#scraping-big-number-of-targets
# available since 1.77.2 version https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.77.2
clusterMode: false
# -- replication factor for vmagent in cluster mode
replicationFactor: 1
# ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#update-strategies
updateStrategy: {}
# type: RollingUpdate
image:
repository: asia-southeast1-docker.pkg.dev/meesho-devops-admin-0622/admin/sre/vmagent
tag: v1.93.7-cluster # rewrites Chart.AppVersion
pullPolicy: IfNotPresent
imagePullSecrets: []
nameOverride: ""
containerWorkingDir: "/"
rbac:
create: true
# Note: The PSP will only be deployed, if Kubernetes (<1.25) supports the resource.
pspEnabled: true
annotations: {}
extraLabels: {}
# -- if true and `rbac.enabled`, will deploy a Role/Rolebinding instead of a ClusterRole/ClusterRoleBinding
namespaced: false
serviceAccount:
# Specifies whether a service account should be created
create: true
# Annotations to add to the service account
annotations: {
iam.gke.io/gcp-service-account: sa-dbc-desre-vmagent-prd@meesho-dbc-prd-0622.iam.gserviceaccount.com
}
# 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
## ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/
podDisruptionBudget:
enabled: false
# minAvailable: 1
# maxUnavailable: 1
labels: {}
# WARN: need to specify at least one remote write url or one multi tenant url
# remoteWriteUrls: []
remoteWriteUrls:
# - https://vminsert-prd-dbc.meeshogcp.in/insert/100/prometheus/api/v1/write
- http://vminsert-dbc-prd.meeshogcp.in/insert/100/prometheus/api/v1/write
# - http://prometheus:8480/insert/0/prometheus
multiTenantUrls: []
# multiTenantUrls:
# - http://vm-insert-az1:8480
# - http://vm-insert-az2:8480
extraArgs:
envflag.enable: "true"
envflag.prefix: VM_
loggerFormat: json
promscrape.config.strictParse: false
promscrape.maxScrapeSize: 1000000000
promscrape.minResponseSizeForStreamParse: 1000000
loggerTimezone: "Asia/Kolkata"
# Uncomment and specify the port if you want to support any of the protocols:
# https://victoriametrics.github.io/vmagent.html#features
# graphiteListenAddr: ":2003"
# influxListenAddr: ":8189"
# opentsdbHTTPListenAddr: ":4242"
# opentsdbListenAddr: ":4242"
# -- Additional environment variables (ex.: secret tokens, flags) https://github.com/VictoriaMetrics/VictoriaMetrics#environment-variables
env:
[]
# - name: VM_remoteWrite_basicAuth_password
# valueFrom:
# secretKeyRef:
# name: auth_secret
# key: password
# extra Labels for Pods, Deployment and Statefulset
extraLabels:
bu: "dbc-dengg"
team: "dbc-dengg-sre"
service: "vmagent-dbc-dengg-prd"
env: "prd"
priority: "p0"
type: "vmagent"
# extra Labels for Pods only
podLabels: {}
# 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
extraContainers: []
# - name: config-reloader
# image: reloader-image
podSecurityContext:
{}
# fsGroup: 2000
securityContext:
{}
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
service:
enabled: true
annotations: {}
# cloud.google.com/neg: '{"exposed_ports": {"8429":{"name": "vmagent-dbc-prd"}}}'
extraLabels: {}
clusterIP: ""
## Ref: https://kubernetes.io/docs/user-guide/services/#external-ips
##
externalIPs: []
loadBalancerIP: ""
loadBalancerSourceRanges: []
servicePort: 8429
# nodePort: 30000
type: ClusterIP
# Ref: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip
# externalTrafficPolicy: "local"
# healthCheckNodePort: 0
ingress:
enabled: true
ingressClassName: nginx-internal
annotations:
nginx.ingress.kubernetes.io/force-ssl-redirect: "false"
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/ssl-redirect: "false"
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: 'true'
extraLabels: {}
hosts:
- name: vmagent-dbc-dengg-prd.meeshogcp.in
path: /
port: http
tls: []
# - secretName: vmagent-ingress-tls
# hosts:
# - vmagent.local
# For Kubernetes >= 1.18 you should specify the ingress-controller via the field ingressClassName
# See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#specifying-the-class-of-an-ingress
# ingressClassName: nginx
# -- pathType is only for k8s >= 1.1=
pathType: Prefix
resources:
# 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:'.
# limits:
# cpu: 100m
# memory: 128Mi
requests:
cpu: 2
memory: 4Gi
# Annotations to be added to the deployment
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "8429"
# Annotations to be added to pod
podAnnotations:
prometheus.io/scrape: "true"
prometheus.io/port: "8429"
nodeSelector:
dedicated: "devops"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "devops"
effect: "NoSchedule"
affinity: {}
# -- priority class to be assigned to the pod(s)
priorityClassName: ""
serviceMonitor:
enabled: false
extraLabels: {}
annotations: {}
relabelings: []
# 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
persistence:
enabled: false
# storageClassName: default
accessModes:
- ReadWriteOnce
size: 10Gi
annotations: {}
extraLabels: {}
existingClaim: ""
# -- Bind Persistent Volume by labels. Must match all labels of targeted PV.
matchLabels: {}
# -- Extra scrape configs that will be appended to `config`
extraScrapeConfigs: []
# Add extra specs dynamically to this chart
extraObjects: []
@@ -0,0 +1,234 @@
vmselect:
enabled: false
vmstorage:
enabled: false
fullnameOverride: vmstorage-dbc-prd
replicaCount: 5
dedicatedValue: false
# schedulerName: default-scheduler
vminsert:
# -- Enable deployment of vminsert component. Deployment is used
enabled: true
# -- vminsert container name
name: vminsert
strategy: {}
# rollingUpdate:
# maxSurge: 25%
# maxUnavailable: 25%
# type: RollingUpdate
image:
# -- Image repository
repository: asia-southeast1-docker.pkg.dev/meesho-devops-admin-0622/admin/sre/vminsert
# -- Image tag
tag: v1.93.7-cluster
# -- Image pull policy
pullPolicy: IfNotPresent
# -- Name of Priority Class
priorityClassName: ""
# -- Overrides the full name of vminsert component
fullnameOverride: vminsert-dbc-prd
# Extra command line arguments for vminsert component
extraArgs:
envflag.enable: "true"
envflag.prefix: VM_
loggerFormat: json
maxLabelsPerTimeseries: 40
replicationFactor: 1
loggerTimezone: "Asia/Kolkata"
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "8480"
extraLabels:
bu: "dbc"
team: "sre"
service: "vminsert-dbc-prd"
env: "prd"
priority: "p0"
type: "vminsert"
# arch: "arm64"
# runpod: "ondemand"
# -- Additional environment variables (ex.: secret tokens, flags) https://github.com/VictoriaMetrics/VictoriaMetrics#environment-variables
env: []
# -- Suppress rendering `--storageNode` FQDNs based on `vmstorage.replicaCount` value. If true suppress rendering `--storageNodes`, they can be re-defined in extraArgs
suppresStorageFQDNsRender: false
automountServiceAccountToken: true
# Readiness & Liveness probes
probe:
readiness:
initialDelaySeconds: 5
periodSeconds: 15
timeoutSeconds: 5
failureThreshold: 3
liveness:
initialDelaySeconds: 5
periodSeconds: 15
timeoutSeconds: 5
failureThreshold: 3
# Horizontal Pod Autoscaling
horizontalPodAutoscaler:
# -- Use HPA for vminsert component
enabled: true
# -- Maximum replicas for HPA to use to to scale the vminsert component
maxReplicas: 10
# -- Minimum replicas for HPA to use to scale the vminsert component
minReplicas: 2
# -- Metric for HPA to use to scale the vminsert component
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 40
# Extra Volumes for the pod
extraVolumes:
[]
# - name: example
# configMap:
# name: example
# Extra Volume Mounts for the container
extraVolumeMounts:
[]
# - name: example
# mountPath: /example
extraContainers:
[]
# - name: config-reloader
# image: reloader-image
initContainers:
[]
# - name: example
# image: example-image
podDisruptionBudget:
# -- See `kubectl explain poddisruptionbudget.spec` for more. Ref: [https://kubernetes.io/docs/tasks/run-application/configure-pdb/](https://kubernetes.io/docs/tasks/run-application/configure-pdb/)
enabled: false
# minAvailable: 1
# maxUnavailable: 1
labels: {}
# -- Array of tolerations object. Ref: [https://kubernetes.io/docs/concepts/configuration/assign-pod-node/](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/)
tolerations:
- key: "dedicated"
operator: "Equal"
value: "vmcommon"
effect: "NoSchedule"
# -- Pod's node selector. Ref: [https://kubernetes.io/docs/user-guide/node-selection/](https://kubernetes.io/docs/user-guide/node-selection/)
nodeSelector:
dedicated: "vmcommon"
# -- Pod affinity
affinity: {}
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: ScheduleAnyway
labelSelector:
matchLabels:
type: vminsert
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
type: vminsert
# -- Pod's annotations
podAnnotations:
prometheus.io/scrape: "true"
prometheus.io/port: "8480"
# -- Count of vminsert pods
replicaCount: 2
# -- Container workdir
containerWorkingDir: ""
# -- Resource object
resources:
# limits:
# cpu: 50m
# memory: 64Mi
requests:
cpu: 4
memory: 2Gi
# -- Pod's security context. Ref: [https://kubernetes.io/docs/tasks/configure-pod-container/security-context/](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/)
securityContext: {}
podSecurityContext: {}
service:
# -- Service annotations
annotations: {}
# -- Service labels
labels: {}
# -- Service ClusterIP
clusterIP: ""
# -- Service External IPs. Ref: [https://kubernetes.io/docs/user-guide/services/#external-ips]( https://kubernetes.io/docs/user-guide/services/#external-ips)
externalIPs: []
# -- Extra service ports
extraServicePorts: []
# -- Service load balancer IP
loadBalancerIP: ""
# -- Load balancer source range
loadBalancerSourceRanges: []
# -- Service port
servicePort: 8480
# -- Target port
targetPort: http
# -- Service type
type: ClusterIP
# -- Enable UDP port. used if you have "spec.opentsdbListenAddr" specified
# -- Make sure that service is not type "LoadBalancer", as it requires "MixedProtocolLBService" feature gate. ref: https://kubernetes.io/docs/reference/command-line-tools-reference/feature-gates/
udp: false
ingress:
# -- Enable deployment of ingress for vminsert component
enabled: true
# -- Ingress annotations
annotations:
nginx.ingress.kubernetes.io/force-ssl-redirect: "false"
nginx.ingress.kubernetes.io/ssl-redirect: "false"
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: 'true'
extraLabels: {}
# -- Array of host objects
hosts:
- name: vminsert-dbc-prd.meeshogcp.in
path: /
port: http
# -- Array of TLS objects
tls: []
# - secretName: vminsert-ingress-tls
# hosts:
# - vminsert.local
# For Kubernetes >= 1.18 you should specify the ingress-controller via the field ingressClassName
# See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#specifying-the-class-of-an-ingress
ingressClassName: nginx-internal
# -- pathType is only for k8s >= 1.1=
pathType: Prefix
serviceMonitor:
# -- Enable deployment of Service Monitor for vminsert component. This is Prometheus operator object
enabled: false
# -- Target namespace of ServiceMonitor manifest
namespace: ""
# -- Service Monitor labels
extraLabels: {}
# -- Service Monitor annotations
annotations: {}
# Commented. Prometheus scare interval for vminsert component
# interval: 15s
# Commented. Prometheus pre-scrape timeout for vminsert component
# scrapeTimeout: 5s
# -- Commented. HTTP scheme to use for scraping.
# scheme: https
# -- Commented. TLS configuration to use when scraping the endpoint
# tlsConfig:
# insecureSkipVerify: true
# -- Service Monitor relabelings
relabelings: []
@@ -0,0 +1,291 @@
vminsert:
enabled: false
vmstorage:
enabled: false
fullnameOverride: vmstorage-dbc-prd
replicaCount: 5
dedicatedValue: false
vmselect:
# -- Enable deployment of vmselect component. Can be deployed as Deployment(default) or StatefulSet
enabled: true
# -- Vmselect container name
name: vmselect
strategy: {}
# rollingUpdate:
# maxSurge: 25%
# maxUnavailable: 25%
# type: RollingUpdate
#extraVMSelects: []
image:
# -- Image repository
repository: asia-southeast1-docker.pkg.dev/meesho-devops-admin-0622/admin/sre/vmselect
# -- Image tag
tag: v1.93.7-cluster
# -- Image pull policy
pullPolicy: IfNotPresent
# -- Name of Priority Class
priorityClassName: ""
# -- Overrides the full name of vmselect component
fullnameOverride: vmselect-dbc-prd
# -- Suppress rendering `--storageNode` FQDNs based on `vmstorage.replicaCount` value. If true suppress rendering `--storageNodes`, they can be re-defined in extraArgs
suppresStorageFQDNsRender: false
automountServiceAccountToken: true
# Extra command line arguments for vmselect component
splitService: True
extraArgs:
envflag.enable: "true"
envflag.prefix: VM_
loggerFormat: json
clusternativeListenAddr: ":8401"
dedup.minScrapeInterval: 60s
search.maxSamplesPerQuery: "1000000000000"
search.maxQueryDuration: 180s
search.maxQueueDuration: 60s
search.maxSeries: "10000000000"
search.maxExportSeries: "1000000000"
search.maxUniqueTimeseries: "1000000000000"
search.maxQueryLen: "1000000"
loggerTimezone: "Asia/Kolkata"
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "8481"
extraLabels:
bu: "dbc"
team: "dbc-sre"
service: "vmselect-dbc-prd"
env: "prd"
priority: "p0"
type: "vmselect"
# arch: "arm64"
# runpod: "ondemand"
# -- Additional environment variables (ex.: secret tokens, flags) https://github.com/VictoriaMetrics/VictoriaMetrics#environment-variables
env: []
# Readiness & Liveness probes
probe:
readiness:
initialDelaySeconds: 5
periodSeconds: 15
timeoutSeconds: 5
failureThreshold: 3
liveness:
initialDelaySeconds: 5
periodSeconds: 15
timeoutSeconds: 5
failureThreshold: 3
horizontalPodAutoscaler:
# -- Use HPA for vmselect component
enabled: true
# -- Maximum replicas for HPA to use to to scale the vmselect component
maxReplicas: 15
# -- Minimum replicas for HPA to use to scale the vmselect component
minReplicas: 2
# -- Metric for HPA to use to scale the vmselect component
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 40
# 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
extraContainers:
[]
# - name: config-reloader
# image: reloader-image
initContainers:
[]
# - name: example
# image: example-image
podDisruptionBudget:
# -- See `kubectl explain poddisruptionbudget.spec` for more. Ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/
enabled: true
minAvailable: 1
# maxUnavailable: 1
labels: {}
tolerations:
- key: "dedicated"
operator: "Equal"
value: "vmselect"
effect: "NoSchedule"
nodeSelector:
dedicated: "vmselect"
# -- Pod affinity
affinity: {}
# -- Pod topologySpreadConstraints
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: ScheduleAnyway
labelSelector:
matchLabels:
type: vmselect
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: ScheduleAnyway
labelSelector:
matchLabels:
type: vmselect
# -- Pod's annotations
podAnnotations:
prometheus.io/scrape: "true"
prometheus.io/port: "8481"
# -- Count of vmselect pods
replicaCount: 2
# -- Container workdir
containerWorkingDir: ""
# -- Resource object
resources:
# limits:
# cpu: 50m
# memory: 64Mi
requests:
cpu: 5
memory: 6Gi
# -- Pod's security context. Ref: [https://kubernetes.io/docs/tasks/configure-pod-container/security-context/](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/
securityContext: {}
podSecurityContext: {}
# -- Cache root folder
cacheMountPath: /cache
service:
# -- Service annotations
annotations:
io.cilium/global-service: "true"
# -- Service labels
labels: {}
# -- Service ClusterIP
clusterIP: ""
# -- Service External IPs. Ref: [https://kubernetes.io/docs/user-guide/services/#external-ips](https://kubernetes.io/docs/user-guide/services/#external-ips)
externalIPs: []
# -- Extra service ports
extraServicePorts: []
# -- Service load balacner IP
loadBalancerIP: ""
# -- Load balancer source range
loadBalancerSourceRanges: []
# -- Service port
servicePort: 8481
# -- Target port
targetPort: http
# -- Service type
type: ClusterIP
ingress:
# -- Enable deployment of ingress for vmselect component
enabled: true
# -- Ingress annotations
annotations:
nginx.ingress.kubernetes.io/force-ssl-redirect: "false"
nginx.ingress.kubernetes.io/ssl-redirect: "false"
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: 'true'
ingressClassName: nginx-internal
extraLabels: {}
# -- Array of host objects
hosts:
- name: vmselect-dbc-prd.meeshogcp.in
path: /
port: http
# -- Array of TLS objects
tls: []
# - secretName: vmselect-ingress-tls
# hosts:
# - vmselect.local
# For Kubernetes >= 1.18 you should specify the ingress-controller via the field ingressClassName
# See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#specifying-the-class-of-an-ingress
# ingressClassName: nginx
# -- pathType is only for k8s >= 1.1=
pathType: Prefix
statefulSet:
# -- Deploy StatefulSet instead of Deployment for vmselect. Useful if you want to keep cache data.
enabled: false
# -- Deploy order policy for StatefulSet pods
podManagementPolicy: OrderedReady
## Headless service for statefulset
service:
# -- Headless service annotations
annotations: {}
# -- Headless service labels
labels: {}
# -- Headless service port
servicePort: 8481
persistentVolume:
# -- Create/use Persistent Volume Claim for vmselect component. Empty dir if false. If true, vmselect will create/use a Persistent Volume Claim
enabled: false
# -- Array of access mode. Must match those of existing PV or dynamic provisioner. Ref: [http://kubernetes.io/docs/user-guide/persistent-volumes/](http://kubernetes.io/docs/user-guide/persistent-volumes/)
accessModes:
- ReadWriteOnce
# -- Persistent volume annotations
annotations: {}
# -- Persistent volume labels
labels: {}
# -- Existing Claim name. Requires vmselect.persistentVolume.enabled: true. If defined, PVC must be created manually before volume will be bound
existingClaim: ""
## Vmselect data Persistent Volume mount root path
##
# -- Size of the volume. Better to set the same as resource limit memory property
size: 2Gi
# -- Mount subpath
subPath: ""
serviceMonitor:
# -- Enable deployment of Service Monitor for vmselect component. This is Prometheus operator object
enabled: false
# -- Target namespace of ServiceMonitor manifest
namespace: ""
# -- Service Monitor labels
extraLabels: {}
# -- Service Monitor annotations
annotations: {}
# Commented. Prometheus scare interval for vmselect component
# interval: 15s
# Commented. Prometheus pre-scrape timeout for vmselect component
# scrapeTimeout: 5s
# -- Commented. HTTP scheme to use for scraping.
# scheme: https
# -- Commented. TLS configuration to use when scraping the endpoint
# tlsConfig:
# insecureSkipVerify: true
# -- Service Monitor relabelings
relabelings: []
@@ -0,0 +1,316 @@
vminsert:
enabled: false
vmselect:
enabled: false
serviceAccount:
create: true
# name:
extraLabels: {}
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::847438129436:role/eks-s3-vmbackup-role
# mount API token to pod directly
automountToken: true
dedicatedValue: false
# schedulerName: default-scheduler
vmstorage:
# -- Enable deployment of vmstorage component. StatefulSet is used
enabled: true
# -- vmstorage container name
name: vmstorage
image:
# -- Image repository
repository: asia-southeast1-docker.pkg.dev/meesho-devops-admin-0622/admin/sre/vmstorage
# -- Image tag
tag: v1.93.7-cluster
# -- Image pull policy
pullPolicy: IfNotPresent
# -- Name of Priority Class
priorityClassName: ""
# -- Overrides the full name of vmstorage component
fullnameOverride: vmstorage-dbc-prd
automountServiceAccountToken: true
# -- Additional environment variables (ex.: secret tokens, flags) https://github.com/VictoriaMetrics/VictoriaMetrics#environment-variables
env: []
# -- Data retention period. Supported values 1w, 1d, number without measurement means month, e.g. 2 = 2month
retentionPeriod: 90d
# Additional vmstorage container arguments. Extra command line arguments for vmstorage component
extraArgs:
envflag.enable: "true"
envflag.prefix: VM_
loggerFormat: json
search.maxUniqueTimeseries: "30000000"
dedup.minScrapeInterval: 60s
loggerTimezone: "Asia/Kolkata"
# 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
extraContainers:
[]
# - name: config-reloader
# image: reloader-image
extraSecretMounts:
[]
# - name: secret
# mountPath: /etc/credentials
# subPath: ""
# readOnly: true
initContainers:
[]
# - name: vmrestore
# image: victoriametrics/vmrestore:latest
# volumeMounts:
# - mountPath: /storage
# name: vmstorage-volume
# - mountPath: /etc/vm/creds
# name: secret-remote-storage-keys
# readOnly: true
# args:
# - -storageDataPath=/storage
# - -src=s3://your_bucket/folder/latest
# - -credsFilePath=/etc/vm/creds/credentials
# -- See `kubectl explain poddisruptionbudget.spec` for more. Ref: [https://kubernetes.io/docs/tasks/run-application/configure-pdb/](https://kubernetes.io/docs/tasks/run-application/configure-pdb/)
podDisruptionBudget:
enabled: false
# minAvailable: 1
# maxUnavailable: 1
labels: {}
# -- Array of tolerations object. Node tolerations for server scheduling to nodes with taints. Ref: [https://kubernetes.io/docs/concepts/configuration/assign-pod-node/](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/)
##
tolerations:
- key: "dedicated"
operator: "Equal"
value: "vmstorage"
effect: "NoSchedule"
# -- Pod's node selector. Ref: [https://kubernetes.io/docs/user-guide/node-selection/](https://kubernetes.io/docs/user-guide/node-selection/)
nodeSelector:
dedicated: "vmstorage"
# -- Pod affinity
affinity: {}
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: ScheduleAnyway
labelSelector:
matchLabels:
type: vmstorage
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
type: vmstorage
## Use an alternate scheduler, e.g. "stork".
## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/
##
# schedulerName:
persistentVolume:
# -- Create/use Persistent Volume Claim for vmstorage component. Empty dir if false. If true, vmstorage will create/use a Persistent Volume Claim
enabled: true
# -- Array of access modes. Must match those of existing PV or dynamic provisioner. Ref: [http://kubernetes.io/docs/user-guide/persistent-volumes/](http://kubernetes.io/docs/user-guide/persistent-volumes/)
accessModes:
- ReadWriteOnce
# -- Persistent volume annotations
annotations: {}
# -- Persistent volume labels
labels: {}
# -- Storage class name. Will be empty if not setted
storageClass: sc-pd-ssd
# -- Existing Claim name. Requires vmstorage.persistentVolume.enabled: true. If defined, PVC must be created manually before volume will be bound
existingClaim: ""
# -- Data root path. Vmstorage data Persistent Volume mount root path
mountPath: /storage
# -- Size of the volume. Better to set the same as resource limit memory property
size: 300Gi
# -- Mount subpath
subPath: ""
# -- Pod's annotations
podAnnotations:
prometheus.io/port: "8482"
prometheus.io/scrape: "true"
annotations:
prometheus.io/port: "8482"
prometheus.io/scrape: "true"
extraLabels:
bu: "dbc"
team: "sre"
service: "vmstorage-dbc-prd"
env: "prd"
priority: "p0"
type: "vmstorage"
# arch: "arm64"
# runpod: "ondemand"
# -- Count of vmstorage pods
replicaCount: 5
# -- Container workdir
containerWorkingDir: ""
# -- Deploy order policy for StatefulSet pods
podManagementPolicy: OrderedReady
# -- Resource object. Ref: [https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/)
resources:
# limits:
# cpu: 500m
# memory: 512Mi
requests:
cpu: 5
memory: 40Gi
# -- Pod's security context. Ref: [https://kubernetes.io/docs/tasks/configure-pod-container/security-context/](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/)
securityContext: {}
podSecurityContext: {}
service:
# -- Service annotations
annotations: {}
# -- Service labels
labels: {}
# -- Service port
servicePort: 8482
# -- Port for accepting connections from vminsert
vminsertPort: 8400
# -- Port for accepting connections from vmstorage
vmstoragePort: 8401
# -- Extra service ports
extraServicePorts: []
# -- Pod's termination grace period in seconds
terminationGracePeriodSeconds: 60
probe:
readiness:
httpGet:
path: /health
port: http
initialDelaySeconds: 5
periodSeconds: 15
timeoutSeconds: 5
failureThreshold: 3
liveness:
tcpSocket:
port: http
initialDelaySeconds: 30
periodSeconds: 30
timeoutSeconds: 5
failureThreshold: 10
vmbackupmanager:
# -- enable automatic creation of backup via vmbackupmanager. vmbackupmanager is part of Enterprise packages
enable: false
# -- should be true and means that you have the legal right to run a backup manager
# that can either be a signed contract or an email with confirmation to run the service in a trial period
# # https://victoriametrics.com/legal/eula/
eula: true
image:
# -- vmbackupmanager image repository
repository: asia-southeast1-docker.pkg.dev/meesho-devops-admin-0622/admin/sre/vmbackupmanager
# -- vmbackupmanager image tag
tag: v1.93.7-cluster
# -- disable hourly backups
disableHourly: true
# -- disable daily backups
disableDaily: false
# -- disable weekly backups
disableWeekly: true
# -- disable monthly backups
disableMonthly: true
# -- backup destination at S3, GCS or local filesystem. Pod name will be included to path!
destination: "s3://prd-dbc-vmbackup"
# -- backups' retention settings
retention:
# -- keep last N hourly backups. 0 means delete all existing hourly backups. Specify -1 to turn off
keepLastHourly: 0
# -- keep last N daily backups. 0 means delete all existing daily backups. Specify -1 to turn off
keepLastDaily: 30
# -- keep last N weekly backups. 0 means delete all existing weekly backups. Specify -1 to turn off
keepLastWeekly: 0
# -- keep last N monthly backups. 0 means delete all existing monthly backups. Specify -1 to turn off
keepLastMonthly: 0
extraArgs:
envflag.enable: "true"
envflag.prefix: VM_
loggerFormat: json
concurrency: 15
loggerTimezone: "Asia/Kolkata"
# -- Allows to enable restore options for pod.
# Read more: https://docs.victoriametrics.com/vmbackupmanager.html#restore-commands
restore:
onStart:
enabled: false
resources: {}
# -- Additional environment variables (ex.: secret tokens, flags) https://github.com/VictoriaMetrics/VictoriaMetrics#environment-variables
env: []
readinessProbe:
httpGet:
path: /health
port: manager-http
initialDelaySeconds: 5
periodSeconds: 15
timeoutSeconds: 5
failureThreshold: 3
livenessProbe:
tcpSocket:
port: manager-http
initialDelaySeconds: 30
periodSeconds: 30
timeoutSeconds: 5
failureThreshold: 10
extraSecretMounts:
[]
# - name: secret
# mountPath: /etc/credentials
# subPath: ""
# readOnly: true
serviceMonitor:
# -- Enable deployment of Service Monitor for vmstorage component. This is Prometheus operator object
enabled: false
# -- Target namespace of ServiceMonitor manifest
namespace: ""
# -- Service Monitor labels
extraLabels: {}
# -- Service Monitor annotations
annotations: {}
# Commented. Prometheus scare interval for vmstorage component
# interval: 15s
# Commented. Prometheus pre-scrape timeout for vmstorage component
# scrapeTimeout: 5s
# -- Commented. HTTP scheme to use for scraping.
# scheme: https
# -- Commented. TLS configuration to use when scraping the endpoint
# tlsConfig:
# insecureSkipVerify: true
# -- Service Monitor relabelings
relabelings: []
@@ -0,0 +1,478 @@
# Default values for kube-state-metrics.
prometheusScrape: true
image:
registry: asia-southeast1-docker.pkg.dev
repository: meesho-devops-admin-0622/admin/sre/kube-state-metrics
# If unset use v + .Charts.appVersion
tag: v2.9.2
sha: ""
pullPolicy: IfNotPresent
fullnameOverride: kube-state-metrics-dbc-backend-prd
dedicatedValue: false
imagePullSecrets: []
# - name: "image-pull-secret"
ingress:
enabled: false
ingressClassName: internal
annotations:
nginx.ingress.kubernetes.io/force-ssl-redirect: "false"
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/ssl-redirect: "false"
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: 'true'
extraLabels: {}
hosts:
- name: clustermetrics-dbc-backend-prd.meesho.com
path: /
port: http
tls: []
# - secretName: vmagent-ingress-tls
# hosts:
# - vmagent.local
# For Kubernetes >= 1.18 you should specify the ingress-controller via the field ingressClassName
# See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#specifying-the-class-of-an-ingress
# ingressClassName: nginx
# -- pathType is only for k8s >= 1.1=
pathType: Prefix
global:
# To help compatibility with other charts which use global.imagePullSecrets.
# Allow either an array of {name: pullSecret} maps (k8s-style), or an array of strings (more common helm-style).
# global:
# imagePullSecrets:
# - name: pullSecret1
# - name: pullSecret2
# or
# global:
# imagePullSecrets:
# - pullSecret1
# - pullSecret2
imagePullSecrets: []
#
# Allow parent charts to override registry hostname
imageRegistry: ""
# If set to true, this will deploy kube-state-metrics as a StatefulSet and the data
# will be automatically sharded across <.Values.replicas> pods using the built-in
# autodiscovery feature: https://github.com/kubernetes/kube-state-metrics#automated-sharding
# This is an experimental feature and there are no stability guarantees.
autosharding:
enabled: false
replicas: 2
# List of additional cli arguments to configure kube-state-metrics
# for example: --enable-gzip-encoding, --log-file, etc.
# all the possible args can be found here: https://github.com/kubernetes/kube-state-metrics/blob/master/docs/cli-arguments.md
extraArgs: []
service:
port: 8080
# Default to clusterIP for backward compatibility
type: ClusterIP
nodePort: 0
loadBalancerIP: ""
# Only allow access to the loadBalancerIP from these IPs
loadBalancerSourceRanges: []
clusterIP: ""
annotations: {}
## Additional labels to add to all resources
customLabels:
bu: "dbc-backend"
team: "dbc-backend-sre"
service: "kube-state-metrics-dbc-backend-prd"
env: "prd"
priority: "p0"
type: "exporter"
# app: kube-state-metrics
## Override selector labels
selectorOverride: {}
## set to true to add the release label so scraping of the servicemonitor with kube-prometheus-stack works out of the box
releaseLabel: false
hostNetwork: false
rbac:
# If true, create & use RBAC resources
create: true
# Set to a rolename to use existing role - skipping role creating - but still doing serviceaccount and rolebinding to it, rolename set here.
# useExistingRole: your-existing-role
# If set to false - Run without Cluteradmin privs needed - ONLY works if namespace is also set (if useExistingRole is set this name is used as ClusterRole or Role to bind to)
useClusterRole: true
# Add permissions for CustomResources' apiGroups in Role/ClusterRole. Should be used in conjunction with Custom Resource State Metrics configuration
# Example:
# - apiGroups: ["monitoring.coreos.com"]
# resources: ["prometheuses"]
# verbs: ["list", "watch"]
extraRules: []
# Configure kube-rbac-proxy. When enabled, creates one kube-rbac-proxy container per exposed HTTP endpoint (metrics and telemetry if enabled).
# The requests are served through the same service but requests are then HTTPS.
kubeRBACProxy:
enabled: false
image:
registry: quay.io
repository: brancz/kube-rbac-proxy
tag: v0.14.0
sha: ""
pullPolicy: IfNotPresent
# List of additional cli arguments to configure kube-rbac-prxy
# for example: --tls-cipher-suites, --log-file, etc.
# all the possible args can be found here: https://github.com/brancz/kube-rbac-proxy#usage
extraArgs: []
## Specify security settings for a Container
## Allows overrides and additional options compared to (Pod) securityContext
## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container
containerSecurityContext: {}
resources: {}
# 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:'.
# limits:
# cpu: 100m
# memory: 64Mi
# requests:
# cpu: 10m
# memory: 32Mi
## volumeMounts enables mounting custom volumes in rbac-proxy containers
## Useful for TLS certificates and keys
volumeMounts: []
# - mountPath: /etc/tls
# name: kube-rbac-proxy-tls
# readOnly: true
serviceAccount:
# Specifies whether a ServiceAccount should be created, require rbac true
create: true
# The name of the ServiceAccount to use.
# If not set and create is true, a name is generated using the fullname template
name:
# Reference to one or more secrets to be used when pulling images
# ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
imagePullSecrets: []
# ServiceAccount annotations.
# Use case: AWS EKS IAM roles for service accounts
# ref: https://docs.aws.amazon.com/eks/latest/userguide/specify-service-account-role.html
annotations: {}
prometheus:
monitor:
enabled: false
annotations: {}
additionalLabels: {}
namespace: ""
jobLabel: ""
targetLabels: []
podTargetLabels: []
interval: ""
## SampleLimit defines per-scrape limit on number of scraped samples that will be accepted.
##
sampleLimit: 0
## TargetLimit defines a limit on the number of scraped targets that will be accepted.
##
targetLimit: 0
## Per-scrape limit on number of labels that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer.
##
labelLimit: 0
## Per-scrape limit on length of labels name that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer.
##
labelNameLengthLimit: 0
## Per-scrape limit on length of labels value that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer.
##
labelValueLengthLimit: 0
scrapeTimeout: ""
proxyUrl: ""
selectorOverride: {}
honorLabels: false
metricRelabelings: []
relabelings: []
scheme: ""
## File to read bearer token for scraping targets
bearerTokenFile: ""
## Secret to mount to read bearer token for scraping targets. The secret needs
## to be in the same namespace as the service monitor and accessible by the
## Prometheus Operator
bearerTokenSecret: {}
# name: secret-name
# key: key-name
tlsConfig: {}
## Specify if a Pod Security Policy for kube-state-metrics must be created
## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/
##
podSecurityPolicy:
enabled: false
annotations: {}
## Specify pod annotations
## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#apparmor
## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#seccomp
## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#sysctl
##
# seccomp.security.alpha.kubernetes.io/allowedProfileNames: '*'
# seccomp.security.alpha.kubernetes.io/defaultProfileName: 'docker/default'
# apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default'
additionalVolumes: []
## Configure network policy for kube-state-metrics
networkPolicy:
enabled: false
# networkPolicy.flavor -- Flavor of the network policy to use.
# Can be:
# * kubernetes for networking.k8s.io/v1/NetworkPolicy
# * cilium for cilium.io/v2/CiliumNetworkPolicy
flavor: kubernetes
## Configure the cilium network policy kube-apiserver selector
# cilium:
# kubeApiServerSelector:
# - toEntities:
# - kube-apiserver
# egress:
# - {}
# ingress:
# - {}
# podSelector:
# matchLabels:
# app.kubernetes.io/name: kube-state-metrics
securityContext:
enabled: true
runAsGroup: 65534
runAsUser: 65534
fsGroup: 65534
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
## Specify security settings for a Container
## Allows overrides and additional options compared to (Pod) securityContext
## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container
containerSecurityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
## Node labels for pod assignment
## Ref: https://kubernetes.io/docs/user-guide/node-selection/
nodeSelector:
dedicated: "devops"
## Affinity settings for pod assignment
## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/
affinity: {}
## Tolerations for pod assignment
## Ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/
tolerations:
- key: "dedicated"
operator: "Equal"
value: "devops"
effect: "NoSchedule"
## Topology spread constraints for pod assignment
## Ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
type: exporter
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
type: exporter
# Annotations to be added to the deployment/statefulset
annotations:
kubernetes.io/psp: eks.privileged
# Annotations to be added to the pod
podAnnotations: {}
## Assign a PriorityClassName to pods if set
# priorityClassName: ""
# Ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/
podDisruptionBudget: {}
# Comma-separated list of metrics to be exposed.
# This list comprises of exact metric names and/or regex patterns.
# The allowlist and denylist are mutually exclusive.
metricAllowlist: []
# Comma-separated list of metrics not to be enabled.
# This list comprises of exact metric names and/or regex patterns.
# The allowlist and denylist are mutually exclusive.
metricDenylist: []
# Comma-separated list of additional Kubernetes label keys that will be used in the resource's
# labels metric. By default the metric contains only name and namespace labels.
# To include additional labels, provide a list of resource names in their plural form and Kubernetes
# label keys you would like to allow for them (Example: '=namespaces=[k8s-label-1,k8s-label-n,...],pods=[app],...)'.
# A single '*' can be provided per resource instead to allow any labels, but that has
# severe performance implications (Example: '=pods=[*]').
metricLabelsAllowlist:
- pods=[*]
- nodes=[*]
- deployments=[*]
- statefulsets=[*]
- persistentvolumeclaims=[*]
- persistentvolumes=[*]
- ingresses=[*]
- namespaces=[*]
- horizontalpodautoscalers=[*]
# - namespaces=[k8s-label-1,k8s-label-n]
# Comma-separated list of Kubernetes annotations keys that will be used in the resource'
# labels metric. By default the metric contains only name and namespace labels.
# To include additional annotations provide a list of resource names in their plural form and Kubernetes
# annotation keys you would like to allow for them (Example: '=namespaces=[kubernetes.io/team,...],pods=[kubernetes.io/team],...)'.
# A single '*' can be provided per resource instead to allow any annotations, but that has
# severe performance implications (Example: '=pods=[*]').
metricAnnotationsAllowList: []
# - pods=[k8s-annotation-1,k8s-annotation-n]
# Available collectors for kube-state-metrics.
# By default, all available resources are enabled, comment out to disable.
collectors:
- certificatesigningrequests
- configmaps
- cronjobs
- daemonsets
- deployments
- endpoints
- horizontalpodautoscalers
- ingresses
- jobs
- leases
- limitranges
- mutatingwebhookconfigurations
- namespaces
- networkpolicies
- nodes
- persistentvolumeclaims
- persistentvolumes
- poddisruptionbudgets
- pods
- replicasets
- replicationcontrollers
- resourcequotas
- secrets
- services
- statefulsets
- storageclasses
- validatingwebhookconfigurations
- volumeattachments
# Enabling kubeconfig will pass the --kubeconfig argument to the container
kubeconfig:
enabled: false
# base64 encoded kube-config file
secret:
# Enabling support for customResourceState, will create a configMap including your config that will be read from kube-state-metrics
customResourceState:
enabled: false
# Add (Cluster)Role permissions to list/watch the customResources defined in the config to rbac.extraRules
config: {}
# Enable only the release namespace for collecting resources. By default all namespaces are collected.
# If releaseNamespace and namespaces are both set a merged list will be collected.
releaseNamespace: false
# Comma-separated list(string) or yaml list of namespaces to be enabled for collecting resources. By default all namespaces are collected.
namespaces: ""
# Comma-separated list of namespaces not to be enabled. If namespaces and namespaces-denylist are both set,
# only namespaces that are excluded in namespaces-denylist will be used.
namespacesDenylist: ""
## Override the deployment namespace
##
namespaceOverride: ""
resources:
# 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:'.
# limits:
# cpu: 100m
# memory: 64Mi
requests:
cpu: 10m
memory: 50Mi
## Provide a k8s version to define apiGroups for podSecurityPolicy Cluster Role.
## For example: kubeTargetVersionOverride: 1.14.9
##
kubeTargetVersionOverride: ""
# Enable self metrics configuration for service and Service Monitor
# Default values for telemetry configuration can be overridden
# If you set telemetryNodePort, you must also set service.type to NodePort
selfMonitor:
enabled: true
# telemetryHost: 0.0.0.0
telemetryPort: 8081
# telemetryNodePort: 0
# Enable vertical pod autoscaler support for kube-state-metrics
verticalPodAutoscaler:
enabled: false
# List of resources that the vertical pod autoscaler can control. Defaults to cpu and memory
controlledResources: []
# Define the max allowed resources for the pod
maxAllowed: {}
# cpu: 200m
# memory: 100Mi
# Define the min allowed resources for the pod
minAllowed: {}
# cpu: 200m
# memory: 100Mi
# updatePolicy:
# Specifies whether recommended updates are applied when a Pod is started and whether recommended updates
# are applied during the life of a Pod. Possible values are "Off", "Initial", "Recreate", and "Auto".
# updateMode: Auto
# volumeMounts are used to add custom volume mounts to deployment.
# See example below
volumeMounts: []
# - mountPath: /etc/config
# name: config-volume
# volumes are used to add custom volumes to deployment
# See example below
volumes: []
# - configMap:
# name: cm-for-volume
# name: config-volume
@@ -0,0 +1,296 @@
# Default values for victoria-metrics-agent.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 2
fullnameOverride: vmagent-dbc-backend-prd
# vmagent scraping configuration:
# https://github.com/VictoriaMetrics/VictoriaMetrics/blob/master/docs/vmagent.md#how-to-collect-metrics-in-prometheus-format
# use existing configmap if specified
# otherwise .config values will be used
configMap: "vmagent-dbc-backend-prd-config" # Use same name as in fullnameOverride-config
dedicatedValue: false
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: ScheduleAnyway
labelSelector:
matchLabels:
type: vmagent
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
type: vmagent
# ref: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/
deployment:
enabled: true
# vmagent pods will take almost 20-25 mins to work properly
minReadySeconds: 180
progressDeadlineSeconds: 300
# ref: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#strategy
strategy: {}
# rollingUpdate:
# maxSurge: 25%
# maxUnavailable: 25%
# type: RollingUpdate
# ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/
statefulset:
enabled: false
# -- create cluster of vmagents. See https://docs.victoriametrics.com/vmagent.html#scraping-big-number-of-targets
# available since 1.77.2 version https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.77.2
clusterMode: false
# -- replication factor for vmagent in cluster mode
replicationFactor: 1
# ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#update-strategies
updateStrategy: {}
# type: RollingUpdate
image:
repository: asia-southeast1-docker.pkg.dev/meesho-devops-admin-0622/admin/sre/vmagent
tag: v1.93.7-cluster # rewrites Chart.AppVersion
pullPolicy: IfNotPresent
imagePullSecrets: []
nameOverride: ""
containerWorkingDir: "/"
rbac:
create: true
# Note: The PSP will only be deployed, if Kubernetes (<1.25) supports the resource.
pspEnabled: true
annotations: {}
extraLabels: {}
# -- if true and `rbac.enabled`, will deploy a Role/Rolebinding instead of a ClusterRole/ClusterRoleBinding
namespaced: false
serviceAccount:
# Specifies whether a service account should be created
create: true
# Annotations to add to the service account
annotations: {
iam.gke.io/gcp-service-account: sa-dbc-desre-vmagent-prd@meesho-dbc-prd-0622.iam.gserviceaccount.com
}
# 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
## ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/
podDisruptionBudget:
enabled: false
# minAvailable: 1
# maxUnavailable: 1
labels: {}
# WARN: need to specify at least one remote write url or one multi tenant url
# remoteWriteUrls: []
remoteWriteUrls:
# - https://vminsert-prd-dbc.meeshogcp.in/insert/100/prometheus/api/v1/write
- http://vminsert-dbc-prd.meeshogcp.in/insert/100/prometheus/api/v1/write
# - http://prometheus:8480/insert/0/prometheus
multiTenantUrls: []
# multiTenantUrls:
# - http://vm-insert-az1:8480
# - http://vm-insert-az2:8480
extraArgs:
envflag.enable: "true"
envflag.prefix: VM_
loggerFormat: json
promscrape.config.strictParse: false
promscrape.maxScrapeSize: 1000000000
promscrape.minResponseSizeForStreamParse: 1000000
loggerTimezone: "Asia/Kolkata"
# Uncomment and specify the port if you want to support any of the protocols:
# https://victoriametrics.github.io/vmagent.html#features
# graphiteListenAddr: ":2003"
# influxListenAddr: ":8189"
# opentsdbHTTPListenAddr: ":4242"
# opentsdbListenAddr: ":4242"
# -- Additional environment variables (ex.: secret tokens, flags) https://github.com/VictoriaMetrics/VictoriaMetrics#environment-variables
env:
[]
# - name: VM_remoteWrite_basicAuth_password
# valueFrom:
# secretKeyRef:
# name: auth_secret
# key: password
# extra Labels for Pods, Deployment and Statefulset
extraLabels:
bu: "dbc-backend"
team: "dbc-backend-sre"
service: "vmagent-dbc-backend-prd"
env: "prd"
priority: "p0"
type: "vmagent"
# extra Labels for Pods only
podLabels: {}
# 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
extraContainers: []
# - name: config-reloader
# image: reloader-image
podSecurityContext:
{}
# fsGroup: 2000
securityContext:
{}
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
service:
enabled: true
annotations: {}
# cloud.google.com/neg: '{"exposed_ports": {"8429":{"name": "vmagent-dbc-prd"}}}'
extraLabels: {}
clusterIP: ""
## Ref: https://kubernetes.io/docs/user-guide/services/#external-ips
##
externalIPs: []
loadBalancerIP: ""
loadBalancerSourceRanges: []
servicePort: 8429
# nodePort: 30000
type: ClusterIP
# Ref: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip
# externalTrafficPolicy: "local"
# healthCheckNodePort: 0
ingress:
enabled: true
ingressClassName: nginx-internal
annotations:
nginx.ingress.kubernetes.io/force-ssl-redirect: "false"
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/ssl-redirect: "false"
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: 'true'
extraLabels: {}
hosts:
- name: vmagent-dbc-backend-prd.meeshogcp.in
path: /
port: http
tls: []
# - secretName: vmagent-ingress-tls
# hosts:
# - vmagent.local
# For Kubernetes >= 1.18 you should specify the ingress-controller via the field ingressClassName
# See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#specifying-the-class-of-an-ingress
# ingressClassName: nginx
# -- pathType is only for k8s >= 1.1=
pathType: Prefix
resources:
# 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:'.
# limits:
# cpu: 100m
# memory: 128Mi
requests:
cpu: 2
memory: 4Gi
# Annotations to be added to the deployment
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "8429"
# Annotations to be added to pod
podAnnotations:
prometheus.io/scrape: "true"
prometheus.io/port: "8429"
nodeSelector:
dedicated: "devops"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "devops"
effect: "NoSchedule"
affinity: {}
# -- priority class to be assigned to the pod(s)
priorityClassName: ""
serviceMonitor:
enabled: false
extraLabels: {}
annotations: {}
relabelings: []
# 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
persistence:
enabled: false
# storageClassName: default
accessModes:
- ReadWriteOnce
size: 10Gi
annotations: {}
extraLabels: {}
existingClaim: ""
# -- Bind Persistent Volume by labels. Must match all labels of targeted PV.
matchLabels: {}
# -- Extra scrape configs that will be appended to `config`
extraScrapeConfigs: []
# Add extra specs dynamically to this chart
extraObjects: []
@@ -0,0 +1,478 @@
# Default values for kube-state-metrics.
prometheusScrape: true
image:
registry: asia-southeast1-docker.pkg.dev
repository: meesho-devops-admin-0622/admin/sre/kube-state-metrics
# If unset use v + .Charts.appVersion
tag: v2.9.2
sha: ""
pullPolicy: IfNotPresent
fullnameOverride: kube-state-metrics-dbc-dping-prd
dedicatedValue: false
imagePullSecrets: []
# - name: "image-pull-secret"
ingress:
enabled: false
ingressClassName: internal
annotations:
nginx.ingress.kubernetes.io/force-ssl-redirect: "false"
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/ssl-redirect: "false"
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: 'true'
extraLabels: {}
hosts:
- name: clustermetrics-dbc-dping-prd.meesho.com
path: /
port: http
tls: []
# - secretName: vmagent-ingress-tls
# hosts:
# - vmagent.local
# For Kubernetes >= 1.18 you should specify the ingress-controller via the field ingressClassName
# See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#specifying-the-class-of-an-ingress
# ingressClassName: nginx
# -- pathType is only for k8s >= 1.1=
pathType: Prefix
global:
# To help compatibility with other charts which use global.imagePullSecrets.
# Allow either an array of {name: pullSecret} maps (k8s-style), or an array of strings (more common helm-style).
# global:
# imagePullSecrets:
# - name: pullSecret1
# - name: pullSecret2
# or
# global:
# imagePullSecrets:
# - pullSecret1
# - pullSecret2
imagePullSecrets: []
#
# Allow parent charts to override registry hostname
imageRegistry: ""
# If set to true, this will deploy kube-state-metrics as a StatefulSet and the data
# will be automatically sharded across <.Values.replicas> pods using the built-in
# autodiscovery feature: https://github.com/kubernetes/kube-state-metrics#automated-sharding
# This is an experimental feature and there are no stability guarantees.
autosharding:
enabled: false
replicas: 2
# List of additional cli arguments to configure kube-state-metrics
# for example: --enable-gzip-encoding, --log-file, etc.
# all the possible args can be found here: https://github.com/kubernetes/kube-state-metrics/blob/master/docs/cli-arguments.md
extraArgs: []
service:
port: 8080
# Default to clusterIP for backward compatibility
type: ClusterIP
nodePort: 0
loadBalancerIP: ""
# Only allow access to the loadBalancerIP from these IPs
loadBalancerSourceRanges: []
clusterIP: ""
annotations: {}
## Additional labels to add to all resources
customLabels:
bu: "dbc-dping"
team: "dbc-dping-sre"
service: "kube-state-metrics-dbc-dping-prd"
env: "prd"
priority: "p0"
type: "exporter"
# app: kube-state-metrics
## Override selector labels
selectorOverride: {}
## set to true to add the release label so scraping of the servicemonitor with kube-prometheus-stack works out of the box
releaseLabel: false
hostNetwork: false
rbac:
# If true, create & use RBAC resources
create: true
# Set to a rolename to use existing role - skipping role creating - but still doing serviceaccount and rolebinding to it, rolename set here.
# useExistingRole: your-existing-role
# If set to false - Run without Cluteradmin privs needed - ONLY works if namespace is also set (if useExistingRole is set this name is used as ClusterRole or Role to bind to)
useClusterRole: true
# Add permissions for CustomResources' apiGroups in Role/ClusterRole. Should be used in conjunction with Custom Resource State Metrics configuration
# Example:
# - apiGroups: ["monitoring.coreos.com"]
# resources: ["prometheuses"]
# verbs: ["list", "watch"]
extraRules: []
# Configure kube-rbac-proxy. When enabled, creates one kube-rbac-proxy container per exposed HTTP endpoint (metrics and telemetry if enabled).
# The requests are served through the same service but requests are then HTTPS.
kubeRBACProxy:
enabled: false
image:
registry: quay.io
repository: brancz/kube-rbac-proxy
tag: v0.14.0
sha: ""
pullPolicy: IfNotPresent
# List of additional cli arguments to configure kube-rbac-prxy
# for example: --tls-cipher-suites, --log-file, etc.
# all the possible args can be found here: https://github.com/brancz/kube-rbac-proxy#usage
extraArgs: []
## Specify security settings for a Container
## Allows overrides and additional options compared to (Pod) securityContext
## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container
containerSecurityContext: {}
resources: {}
# 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:'.
# limits:
# cpu: 100m
# memory: 64Mi
# requests:
# cpu: 10m
# memory: 32Mi
## volumeMounts enables mounting custom volumes in rbac-proxy containers
## Useful for TLS certificates and keys
volumeMounts: []
# - mountPath: /etc/tls
# name: kube-rbac-proxy-tls
# readOnly: true
serviceAccount:
# Specifies whether a ServiceAccount should be created, require rbac true
create: true
# The name of the ServiceAccount to use.
# If not set and create is true, a name is generated using the fullname template
name:
# Reference to one or more secrets to be used when pulling images
# ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
imagePullSecrets: []
# ServiceAccount annotations.
# Use case: AWS EKS IAM roles for service accounts
# ref: https://docs.aws.amazon.com/eks/latest/userguide/specify-service-account-role.html
annotations: {}
prometheus:
monitor:
enabled: false
annotations: {}
additionalLabels: {}
namespace: ""
jobLabel: ""
targetLabels: []
podTargetLabels: []
interval: ""
## SampleLimit defines per-scrape limit on number of scraped samples that will be accepted.
##
sampleLimit: 0
## TargetLimit defines a limit on the number of scraped targets that will be accepted.
##
targetLimit: 0
## Per-scrape limit on number of labels that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer.
##
labelLimit: 0
## Per-scrape limit on length of labels name that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer.
##
labelNameLengthLimit: 0
## Per-scrape limit on length of labels value that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer.
##
labelValueLengthLimit: 0
scrapeTimeout: ""
proxyUrl: ""
selectorOverride: {}
honorLabels: false
metricRelabelings: []
relabelings: []
scheme: ""
## File to read bearer token for scraping targets
bearerTokenFile: ""
## Secret to mount to read bearer token for scraping targets. The secret needs
## to be in the same namespace as the service monitor and accessible by the
## Prometheus Operator
bearerTokenSecret: {}
# name: secret-name
# key: key-name
tlsConfig: {}
## Specify if a Pod Security Policy for kube-state-metrics must be created
## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/
##
podSecurityPolicy:
enabled: false
annotations: {}
## Specify pod annotations
## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#apparmor
## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#seccomp
## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#sysctl
##
# seccomp.security.alpha.kubernetes.io/allowedProfileNames: '*'
# seccomp.security.alpha.kubernetes.io/defaultProfileName: 'docker/default'
# apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default'
additionalVolumes: []
## Configure network policy for kube-state-metrics
networkPolicy:
enabled: false
# networkPolicy.flavor -- Flavor of the network policy to use.
# Can be:
# * kubernetes for networking.k8s.io/v1/NetworkPolicy
# * cilium for cilium.io/v2/CiliumNetworkPolicy
flavor: kubernetes
## Configure the cilium network policy kube-apiserver selector
# cilium:
# kubeApiServerSelector:
# - toEntities:
# - kube-apiserver
# egress:
# - {}
# ingress:
# - {}
# podSelector:
# matchLabels:
# app.kubernetes.io/name: kube-state-metrics
securityContext:
enabled: true
runAsGroup: 65534
runAsUser: 65534
fsGroup: 65534
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
## Specify security settings for a Container
## Allows overrides and additional options compared to (Pod) securityContext
## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container
containerSecurityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
## Node labels for pod assignment
## Ref: https://kubernetes.io/docs/user-guide/node-selection/
nodeSelector:
dedicated: "devops"
## Affinity settings for pod assignment
## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/
affinity: {}
## Tolerations for pod assignment
## Ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/
tolerations:
- key: "dedicated"
operator: "Equal"
value: "devops"
effect: "NoSchedule"
## Topology spread constraints for pod assignment
## Ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
type: exporter
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
type: exporter
# Annotations to be added to the deployment/statefulset
annotations:
kubernetes.io/psp: eks.privileged
# Annotations to be added to the pod
podAnnotations: {}
## Assign a PriorityClassName to pods if set
# priorityClassName: ""
# Ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/
podDisruptionBudget: {}
# Comma-separated list of metrics to be exposed.
# This list comprises of exact metric names and/or regex patterns.
# The allowlist and denylist are mutually exclusive.
metricAllowlist: []
# Comma-separated list of metrics not to be enabled.
# This list comprises of exact metric names and/or regex patterns.
# The allowlist and denylist are mutually exclusive.
metricDenylist: []
# Comma-separated list of additional Kubernetes label keys that will be used in the resource's
# labels metric. By default the metric contains only name and namespace labels.
# To include additional labels, provide a list of resource names in their plural form and Kubernetes
# label keys you would like to allow for them (Example: '=namespaces=[k8s-label-1,k8s-label-n,...],pods=[app],...)'.
# A single '*' can be provided per resource instead to allow any labels, but that has
# severe performance implications (Example: '=pods=[*]').
metricLabelsAllowlist:
- pods=[*]
- nodes=[*]
- deployments=[*]
- statefulsets=[*]
- persistentvolumeclaims=[*]
- persistentvolumes=[*]
- ingresses=[*]
- namespaces=[*]
- horizontalpodautoscalers=[*]
# - namespaces=[k8s-label-1,k8s-label-n]
# Comma-separated list of Kubernetes annotations keys that will be used in the resource'
# labels metric. By default the metric contains only name and namespace labels.
# To include additional annotations provide a list of resource names in their plural form and Kubernetes
# annotation keys you would like to allow for them (Example: '=namespaces=[kubernetes.io/team,...],pods=[kubernetes.io/team],...)'.
# A single '*' can be provided per resource instead to allow any annotations, but that has
# severe performance implications (Example: '=pods=[*]').
metricAnnotationsAllowList: []
# - pods=[k8s-annotation-1,k8s-annotation-n]
# Available collectors for kube-state-metrics.
# By default, all available resources are enabled, comment out to disable.
collectors:
- certificatesigningrequests
- configmaps
- cronjobs
- daemonsets
- deployments
- endpoints
- horizontalpodautoscalers
- ingresses
- jobs
- leases
- limitranges
- mutatingwebhookconfigurations
- namespaces
- networkpolicies
- nodes
- persistentvolumeclaims
- persistentvolumes
- poddisruptionbudgets
- pods
- replicasets
- replicationcontrollers
- resourcequotas
- secrets
- services
- statefulsets
- storageclasses
- validatingwebhookconfigurations
- volumeattachments
# Enabling kubeconfig will pass the --kubeconfig argument to the container
kubeconfig:
enabled: false
# base64 encoded kube-config file
secret:
# Enabling support for customResourceState, will create a configMap including your config that will be read from kube-state-metrics
customResourceState:
enabled: false
# Add (Cluster)Role permissions to list/watch the customResources defined in the config to rbac.extraRules
config: {}
# Enable only the release namespace for collecting resources. By default all namespaces are collected.
# If releaseNamespace and namespaces are both set a merged list will be collected.
releaseNamespace: false
# Comma-separated list(string) or yaml list of namespaces to be enabled for collecting resources. By default all namespaces are collected.
namespaces: ""
# Comma-separated list of namespaces not to be enabled. If namespaces and namespaces-denylist are both set,
# only namespaces that are excluded in namespaces-denylist will be used.
namespacesDenylist: ""
## Override the deployment namespace
##
namespaceOverride: ""
resources:
# 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:'.
# limits:
# cpu: 100m
# memory: 64Mi
requests:
cpu: 10m
memory: 50Mi
## Provide a k8s version to define apiGroups for podSecurityPolicy Cluster Role.
## For example: kubeTargetVersionOverride: 1.14.9
##
kubeTargetVersionOverride: ""
# Enable self metrics configuration for service and Service Monitor
# Default values for telemetry configuration can be overridden
# If you set telemetryNodePort, you must also set service.type to NodePort
selfMonitor:
enabled: true
# telemetryHost: 0.0.0.0
telemetryPort: 8081
# telemetryNodePort: 0
# Enable vertical pod autoscaler support for kube-state-metrics
verticalPodAutoscaler:
enabled: false
# List of resources that the vertical pod autoscaler can control. Defaults to cpu and memory
controlledResources: []
# Define the max allowed resources for the pod
maxAllowed: {}
# cpu: 200m
# memory: 100Mi
# Define the min allowed resources for the pod
minAllowed: {}
# cpu: 200m
# memory: 100Mi
# updatePolicy:
# Specifies whether recommended updates are applied when a Pod is started and whether recommended updates
# are applied during the life of a Pod. Possible values are "Off", "Initial", "Recreate", and "Auto".
# updateMode: Auto
# volumeMounts are used to add custom volume mounts to deployment.
# See example below
volumeMounts: []
# - mountPath: /etc/config
# name: config-volume
# volumes are used to add custom volumes to deployment
# See example below
volumes: []
# - configMap:
# name: cm-for-volume
# name: config-volume
@@ -0,0 +1,296 @@
# Default values for victoria-metrics-agent.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 2
fullnameOverride: vmagent-dbc-dping-prd
# vmagent scraping configuration:
# https://github.com/VictoriaMetrics/VictoriaMetrics/blob/master/docs/vmagent.md#how-to-collect-metrics-in-prometheus-format
# use existing configmap if specified
# otherwise .config values will be used
configMap: "vmagent-dbc-dping-prd-config" # Use same name as in fullnameOverride-config
dedicatedValue: false
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: ScheduleAnyway
labelSelector:
matchLabels:
type: vmagent
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
type: vmagent
# ref: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/
deployment:
enabled: true
# vmagent pods will take almost 20-25 mins to work properly
minReadySeconds: 180
progressDeadlineSeconds: 300
# ref: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#strategy
strategy: {}
# rollingUpdate:
# maxSurge: 25%
# maxUnavailable: 25%
# type: RollingUpdate
# ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/
statefulset:
enabled: false
# -- create cluster of vmagents. See https://docs.victoriametrics.com/vmagent.html#scraping-big-number-of-targets
# available since 1.77.2 version https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.77.2
clusterMode: false
# -- replication factor for vmagent in cluster mode
replicationFactor: 1
# ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#update-strategies
updateStrategy: {}
# type: RollingUpdate
image:
repository: asia-southeast1-docker.pkg.dev/meesho-devops-admin-0622/admin/sre/vmagent
tag: v1.93.7-cluster # rewrites Chart.AppVersion
pullPolicy: IfNotPresent
imagePullSecrets: []
nameOverride: ""
containerWorkingDir: "/"
rbac:
create: true
# Note: The PSP will only be deployed, if Kubernetes (<1.25) supports the resource.
pspEnabled: true
annotations: {}
extraLabels: {}
# -- if true and `rbac.enabled`, will deploy a Role/Rolebinding instead of a ClusterRole/ClusterRoleBinding
namespaced: false
serviceAccount:
# Specifies whether a service account should be created
create: true
# Annotations to add to the service account
annotations: {
iam.gke.io/gcp-service-account: sa-dbc-desre-vmagent-prd@meesho-dbc-prd-0622.iam.gserviceaccount.com
}
# 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
## ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/
podDisruptionBudget:
enabled: false
# minAvailable: 1
# maxUnavailable: 1
labels: {}
# WARN: need to specify at least one remote write url or one multi tenant url
# remoteWriteUrls: []
remoteWriteUrls:
# - https://vminsert-prd-dbc.meeshogcp.in/insert/100/prometheus/api/v1/write
- http://vminsert-dbc-prd.meeshogcp.in/insert/100/prometheus/api/v1/write
# - http://prometheus:8480/insert/0/prometheus
multiTenantUrls: []
# multiTenantUrls:
# - http://vm-insert-az1:8480
# - http://vm-insert-az2:8480
extraArgs:
envflag.enable: "true"
envflag.prefix: VM_
loggerFormat: json
promscrape.config.strictParse: false
promscrape.maxScrapeSize: 1000000000
promscrape.minResponseSizeForStreamParse: 1000000
loggerTimezone: "Asia/Kolkata"
# Uncomment and specify the port if you want to support any of the protocols:
# https://victoriametrics.github.io/vmagent.html#features
# graphiteListenAddr: ":2003"
# influxListenAddr: ":8189"
# opentsdbHTTPListenAddr: ":4242"
# opentsdbListenAddr: ":4242"
# -- Additional environment variables (ex.: secret tokens, flags) https://github.com/VictoriaMetrics/VictoriaMetrics#environment-variables
env:
[]
# - name: VM_remoteWrite_basicAuth_password
# valueFrom:
# secretKeyRef:
# name: auth_secret
# key: password
# extra Labels for Pods, Deployment and Statefulset
extraLabels:
bu: "dbc-dping"
team: "dbc-dping-sre"
service: "vmagent-dbc-dping-prd"
env: "prd"
priority: "p0"
type: "vmagent"
# extra Labels for Pods only
podLabels: {}
# 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
extraContainers: []
# - name: config-reloader
# image: reloader-image
podSecurityContext:
{}
# fsGroup: 2000
securityContext:
{}
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
service:
enabled: true
annotations: {}
# cloud.google.com/neg: '{"exposed_ports": {"8429":{"name": "vmagent-dbc-prd"}}}'
extraLabels: {}
clusterIP: ""
## Ref: https://kubernetes.io/docs/user-guide/services/#external-ips
##
externalIPs: []
loadBalancerIP: ""
loadBalancerSourceRanges: []
servicePort: 8429
# nodePort: 30000
type: ClusterIP
# Ref: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip
# externalTrafficPolicy: "local"
# healthCheckNodePort: 0
ingress:
enabled: true
ingressClassName: nginx-internal
annotations:
nginx.ingress.kubernetes.io/force-ssl-redirect: "false"
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/ssl-redirect: "false"
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: 'true'
extraLabels: {}
hosts:
- name: vmagent-dbc-dping-prd.meeshogcp.in
path: /
port: http
tls: []
# - secretName: vmagent-ingress-tls
# hosts:
# - vmagent.local
# For Kubernetes >= 1.18 you should specify the ingress-controller via the field ingressClassName
# See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#specifying-the-class-of-an-ingress
# ingressClassName: nginx
# -- pathType is only for k8s >= 1.1=
pathType: Prefix
resources:
# 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:'.
# limits:
# cpu: 100m
# memory: 128Mi
requests:
cpu: 2
memory: 4Gi
# Annotations to be added to the deployment
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "8429"
# Annotations to be added to pod
podAnnotations:
prometheus.io/scrape: "true"
prometheus.io/port: "8429"
nodeSelector:
dedicated: "devops"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "devops"
effect: "NoSchedule"
affinity: {}
# -- priority class to be assigned to the pod(s)
priorityClassName: ""
serviceMonitor:
enabled: false
extraLabels: {}
annotations: {}
relabelings: []
# 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
persistence:
enabled: false
# storageClassName: default
accessModes:
- ReadWriteOnce
size: 10Gi
annotations: {}
extraLabels: {}
existingClaim: ""
# -- Bind Persistent Volume by labels. Must match all labels of targeted PV.
matchLabels: {}
# -- Extra scrape configs that will be appended to `config`
extraScrapeConfigs: []
# Add extra specs dynamically to this chart
extraObjects: []
@@ -0,0 +1,478 @@
# Default values for kube-state-metrics.
prometheusScrape: true
image:
registry: asia-southeast1-docker.pkg.dev
repository: meesho-devops-admin-0622/admin/sre/kube-state-metrics
# If unset use v + .Charts.appVersion
tag: v2.9.2
sha: ""
pullPolicy: IfNotPresent
fullnameOverride: kube-state-metrics-dbc-dpcon-prd
dedicatedValue: false
imagePullSecrets: []
# - name: "image-pull-secret"
ingress:
enabled: false
ingressClassName: internal
annotations:
nginx.ingress.kubernetes.io/force-ssl-redirect: "false"
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/ssl-redirect: "false"
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: 'true'
extraLabels: {}
hosts:
- name: clustermetrics-dbc-dpcon-prd.meesho.com
path: /
port: http
tls: []
# - secretName: vmagent-ingress-tls
# hosts:
# - vmagent.local
# For Kubernetes >= 1.18 you should specify the ingress-controller via the field ingressClassName
# See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#specifying-the-class-of-an-ingress
# ingressClassName: nginx
# -- pathType is only for k8s >= 1.1=
pathType: Prefix
global:
# To help compatibility with other charts which use global.imagePullSecrets.
# Allow either an array of {name: pullSecret} maps (k8s-style), or an array of strings (more common helm-style).
# global:
# imagePullSecrets:
# - name: pullSecret1
# - name: pullSecret2
# or
# global:
# imagePullSecrets:
# - pullSecret1
# - pullSecret2
imagePullSecrets: []
#
# Allow parent charts to override registry hostname
imageRegistry: ""
# If set to true, this will deploy kube-state-metrics as a StatefulSet and the data
# will be automatically sharded across <.Values.replicas> pods using the built-in
# autodiscovery feature: https://github.com/kubernetes/kube-state-metrics#automated-sharding
# This is an experimental feature and there are no stability guarantees.
autosharding:
enabled: false
replicas: 2
# List of additional cli arguments to configure kube-state-metrics
# for example: --enable-gzip-encoding, --log-file, etc.
# all the possible args can be found here: https://github.com/kubernetes/kube-state-metrics/blob/master/docs/cli-arguments.md
extraArgs: []
service:
port: 8080
# Default to clusterIP for backward compatibility
type: ClusterIP
nodePort: 0
loadBalancerIP: ""
# Only allow access to the loadBalancerIP from these IPs
loadBalancerSourceRanges: []
clusterIP: ""
annotations: {}
## Additional labels to add to all resources
customLabels:
bu: "dbc-dpcon"
team: "dbc-dpcon-sre"
service: "kube-state-metrics-dbc-dpcon-prd"
env: "prd"
priority: "p0"
type: "exporter"
# app: kube-state-metrics
## Override selector labels
selectorOverride: {}
## set to true to add the release label so scraping of the servicemonitor with kube-prometheus-stack works out of the box
releaseLabel: false
hostNetwork: false
rbac:
# If true, create & use RBAC resources
create: true
# Set to a rolename to use existing role - skipping role creating - but still doing serviceaccount and rolebinding to it, rolename set here.
# useExistingRole: your-existing-role
# If set to false - Run without Cluteradmin privs needed - ONLY works if namespace is also set (if useExistingRole is set this name is used as ClusterRole or Role to bind to)
useClusterRole: true
# Add permissions for CustomResources' apiGroups in Role/ClusterRole. Should be used in conjunction with Custom Resource State Metrics configuration
# Example:
# - apiGroups: ["monitoring.coreos.com"]
# resources: ["prometheuses"]
# verbs: ["list", "watch"]
extraRules: []
# Configure kube-rbac-proxy. When enabled, creates one kube-rbac-proxy container per exposed HTTP endpoint (metrics and telemetry if enabled).
# The requests are served through the same service but requests are then HTTPS.
kubeRBACProxy:
enabled: false
image:
registry: quay.io
repository: brancz/kube-rbac-proxy
tag: v0.14.0
sha: ""
pullPolicy: IfNotPresent
# List of additional cli arguments to configure kube-rbac-prxy
# for example: --tls-cipher-suites, --log-file, etc.
# all the possible args can be found here: https://github.com/brancz/kube-rbac-proxy#usage
extraArgs: []
## Specify security settings for a Container
## Allows overrides and additional options compared to (Pod) securityContext
## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container
containerSecurityContext: {}
resources: {}
# 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:'.
# limits:
# cpu: 100m
# memory: 64Mi
# requests:
# cpu: 10m
# memory: 32Mi
## volumeMounts enables mounting custom volumes in rbac-proxy containers
## Useful for TLS certificates and keys
volumeMounts: []
# - mountPath: /etc/tls
# name: kube-rbac-proxy-tls
# readOnly: true
serviceAccount:
# Specifies whether a ServiceAccount should be created, require rbac true
create: true
# The name of the ServiceAccount to use.
# If not set and create is true, a name is generated using the fullname template
name:
# Reference to one or more secrets to be used when pulling images
# ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
imagePullSecrets: []
# ServiceAccount annotations.
# Use case: AWS EKS IAM roles for service accounts
# ref: https://docs.aws.amazon.com/eks/latest/userguide/specify-service-account-role.html
annotations: {}
prometheus:
monitor:
enabled: false
annotations: {}
additionalLabels: {}
namespace: ""
jobLabel: ""
targetLabels: []
podTargetLabels: []
interval: ""
## SampleLimit defines per-scrape limit on number of scraped samples that will be accepted.
##
sampleLimit: 0
## TargetLimit defines a limit on the number of scraped targets that will be accepted.
##
targetLimit: 0
## Per-scrape limit on number of labels that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer.
##
labelLimit: 0
## Per-scrape limit on length of labels name that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer.
##
labelNameLengthLimit: 0
## Per-scrape limit on length of labels value that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer.
##
labelValueLengthLimit: 0
scrapeTimeout: ""
proxyUrl: ""
selectorOverride: {}
honorLabels: false
metricRelabelings: []
relabelings: []
scheme: ""
## File to read bearer token for scraping targets
bearerTokenFile: ""
## Secret to mount to read bearer token for scraping targets. The secret needs
## to be in the same namespace as the service monitor and accessible by the
## Prometheus Operator
bearerTokenSecret: {}
# name: secret-name
# key: key-name
tlsConfig: {}
## Specify if a Pod Security Policy for kube-state-metrics must be created
## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/
##
podSecurityPolicy:
enabled: false
annotations: {}
## Specify pod annotations
## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#apparmor
## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#seccomp
## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#sysctl
##
# seccomp.security.alpha.kubernetes.io/allowedProfileNames: '*'
# seccomp.security.alpha.kubernetes.io/defaultProfileName: 'docker/default'
# apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default'
additionalVolumes: []
## Configure network policy for kube-state-metrics
networkPolicy:
enabled: false
# networkPolicy.flavor -- Flavor of the network policy to use.
# Can be:
# * kubernetes for networking.k8s.io/v1/NetworkPolicy
# * cilium for cilium.io/v2/CiliumNetworkPolicy
flavor: kubernetes
## Configure the cilium network policy kube-apiserver selector
# cilium:
# kubeApiServerSelector:
# - toEntities:
# - kube-apiserver
# egress:
# - {}
# ingress:
# - {}
# podSelector:
# matchLabels:
# app.kubernetes.io/name: kube-state-metrics
securityContext:
enabled: true
runAsGroup: 65534
runAsUser: 65534
fsGroup: 65534
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
## Specify security settings for a Container
## Allows overrides and additional options compared to (Pod) securityContext
## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container
containerSecurityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
## Node labels for pod assignment
## Ref: https://kubernetes.io/docs/user-guide/node-selection/
nodeSelector:
dedicated: "devops"
## Affinity settings for pod assignment
## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/
affinity: {}
## Tolerations for pod assignment
## Ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/
tolerations:
- key: "dedicated"
operator: "Equal"
value: "devops"
effect: "NoSchedule"
## Topology spread constraints for pod assignment
## Ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
type: exporter
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
type: exporter
# Annotations to be added to the deployment/statefulset
annotations:
kubernetes.io/psp: eks.privileged
# Annotations to be added to the pod
podAnnotations: {}
## Assign a PriorityClassName to pods if set
# priorityClassName: ""
# Ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/
podDisruptionBudget: {}
# Comma-separated list of metrics to be exposed.
# This list comprises of exact metric names and/or regex patterns.
# The allowlist and denylist are mutually exclusive.
metricAllowlist: []
# Comma-separated list of metrics not to be enabled.
# This list comprises of exact metric names and/or regex patterns.
# The allowlist and denylist are mutually exclusive.
metricDenylist: []
# Comma-separated list of additional Kubernetes label keys that will be used in the resource's
# labels metric. By default the metric contains only name and namespace labels.
# To include additional labels, provide a list of resource names in their plural form and Kubernetes
# label keys you would like to allow for them (Example: '=namespaces=[k8s-label-1,k8s-label-n,...],pods=[app],...)'.
# A single '*' can be provided per resource instead to allow any labels, but that has
# severe performance implications (Example: '=pods=[*]').
metricLabelsAllowlist:
- pods=[*]
- nodes=[*]
- deployments=[*]
- statefulsets=[*]
- persistentvolumeclaims=[*]
- persistentvolumes=[*]
- ingresses=[*]
- namespaces=[*]
- horizontalpodautoscalers=[*]
# - namespaces=[k8s-label-1,k8s-label-n]
# Comma-separated list of Kubernetes annotations keys that will be used in the resource'
# labels metric. By default the metric contains only name and namespace labels.
# To include additional annotations provide a list of resource names in their plural form and Kubernetes
# annotation keys you would like to allow for them (Example: '=namespaces=[kubernetes.io/team,...],pods=[kubernetes.io/team],...)'.
# A single '*' can be provided per resource instead to allow any annotations, but that has
# severe performance implications (Example: '=pods=[*]').
metricAnnotationsAllowList: []
# - pods=[k8s-annotation-1,k8s-annotation-n]
# Available collectors for kube-state-metrics.
# By default, all available resources are enabled, comment out to disable.
collectors:
- certificatesigningrequests
- configmaps
- cronjobs
- daemonsets
- deployments
- endpoints
- horizontalpodautoscalers
- ingresses
- jobs
- leases
- limitranges
- mutatingwebhookconfigurations
- namespaces
- networkpolicies
- nodes
- persistentvolumeclaims
- persistentvolumes
- poddisruptionbudgets
- pods
- replicasets
- replicationcontrollers
- resourcequotas
- secrets
- services
- statefulsets
- storageclasses
- validatingwebhookconfigurations
- volumeattachments
# Enabling kubeconfig will pass the --kubeconfig argument to the container
kubeconfig:
enabled: false
# base64 encoded kube-config file
secret:
# Enabling support for customResourceState, will create a configMap including your config that will be read from kube-state-metrics
customResourceState:
enabled: false
# Add (Cluster)Role permissions to list/watch the customResources defined in the config to rbac.extraRules
config: {}
# Enable only the release namespace for collecting resources. By default all namespaces are collected.
# If releaseNamespace and namespaces are both set a merged list will be collected.
releaseNamespace: false
# Comma-separated list(string) or yaml list of namespaces to be enabled for collecting resources. By default all namespaces are collected.
namespaces: ""
# Comma-separated list of namespaces not to be enabled. If namespaces and namespaces-denylist are both set,
# only namespaces that are excluded in namespaces-denylist will be used.
namespacesDenylist: ""
## Override the deployment namespace
##
namespaceOverride: ""
resources:
# 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:'.
# limits:
# cpu: 100m
# memory: 64Mi
requests:
cpu: 10m
memory: 50Mi
## Provide a k8s version to define apiGroups for podSecurityPolicy Cluster Role.
## For example: kubeTargetVersionOverride: 1.14.9
##
kubeTargetVersionOverride: ""
# Enable self metrics configuration for service and Service Monitor
# Default values for telemetry configuration can be overridden
# If you set telemetryNodePort, you must also set service.type to NodePort
selfMonitor:
enabled: true
# telemetryHost: 0.0.0.0
telemetryPort: 8081
# telemetryNodePort: 0
# Enable vertical pod autoscaler support for kube-state-metrics
verticalPodAutoscaler:
enabled: false
# List of resources that the vertical pod autoscaler can control. Defaults to cpu and memory
controlledResources: []
# Define the max allowed resources for the pod
maxAllowed: {}
# cpu: 200m
# memory: 100Mi
# Define the min allowed resources for the pod
minAllowed: {}
# cpu: 200m
# memory: 100Mi
# updatePolicy:
# Specifies whether recommended updates are applied when a Pod is started and whether recommended updates
# are applied during the life of a Pod. Possible values are "Off", "Initial", "Recreate", and "Auto".
# updateMode: Auto
# volumeMounts are used to add custom volume mounts to deployment.
# See example below
volumeMounts: []
# - mountPath: /etc/config
# name: config-volume
# volumes are used to add custom volumes to deployment
# See example below
volumes: []
# - configMap:
# name: cm-for-volume
# name: config-volume
@@ -0,0 +1,296 @@
# Default values for victoria-metrics-agent.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 2
fullnameOverride: vmagent-dbc-dpcon-prd
# vmagent scraping configuration:
# https://github.com/VictoriaMetrics/VictoriaMetrics/blob/master/docs/vmagent.md#how-to-collect-metrics-in-prometheus-format
# use existing configmap if specified
# otherwise .config values will be used
configMap: "vmagent-dbc-dpcon-prd-config" # Use same name as in fullnameOverride-config
dedicatedValue: false
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: ScheduleAnyway
labelSelector:
matchLabels:
type: vmagent
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
type: vmagent
# ref: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/
deployment:
enabled: true
# vmagent pods will take almost 20-25 mins to work properly
minReadySeconds: 180
progressDeadlineSeconds: 300
# ref: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#strategy
strategy: {}
# rollingUpdate:
# maxSurge: 25%
# maxUnavailable: 25%
# type: RollingUpdate
# ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/
statefulset:
enabled: false
# -- create cluster of vmagents. See https://docs.victoriametrics.com/vmagent.html#scraping-big-number-of-targets
# available since 1.77.2 version https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.77.2
clusterMode: false
# -- replication factor for vmagent in cluster mode
replicationFactor: 1
# ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#update-strategies
updateStrategy: {}
# type: RollingUpdate
image:
repository: asia-southeast1-docker.pkg.dev/meesho-devops-admin-0622/admin/sre/vmagent
tag: v1.93.7-cluster # rewrites Chart.AppVersion
pullPolicy: IfNotPresent
imagePullSecrets: []
nameOverride: ""
containerWorkingDir: "/"
rbac:
create: true
# Note: The PSP will only be deployed, if Kubernetes (<1.25) supports the resource.
pspEnabled: true
annotations: {}
extraLabels: {}
# -- if true and `rbac.enabled`, will deploy a Role/Rolebinding instead of a ClusterRole/ClusterRoleBinding
namespaced: false
serviceAccount:
# Specifies whether a service account should be created
create: true
# Annotations to add to the service account
annotations: {
iam.gke.io/gcp-service-account: sa-dbc-desre-vmagent-prd@meesho-dbc-prd-0622.iam.gserviceaccount.com
}
# 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
## ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/
podDisruptionBudget:
enabled: false
# minAvailable: 1
# maxUnavailable: 1
labels: {}
# WARN: need to specify at least one remote write url or one multi tenant url
# remoteWriteUrls: []
remoteWriteUrls:
# - https://vminsert-prd-dbc.meeshogcp.in/insert/100/prometheus/api/v1/write
- http://vminsert-dbc-prd.meeshogcp.in/insert/100/prometheus/api/v1/write
# - http://prometheus:8480/insert/0/prometheus
multiTenantUrls: []
# multiTenantUrls:
# - http://vm-insert-az1:8480
# - http://vm-insert-az2:8480
extraArgs:
envflag.enable: "true"
envflag.prefix: VM_
loggerFormat: json
promscrape.config.strictParse: false
promscrape.maxScrapeSize: 1000000000
promscrape.minResponseSizeForStreamParse: 1000000
loggerTimezone: "Asia/Kolkata"
# Uncomment and specify the port if you want to support any of the protocols:
# https://victoriametrics.github.io/vmagent.html#features
# graphiteListenAddr: ":2003"
# influxListenAddr: ":8189"
# opentsdbHTTPListenAddr: ":4242"
# opentsdbListenAddr: ":4242"
# -- Additional environment variables (ex.: secret tokens, flags) https://github.com/VictoriaMetrics/VictoriaMetrics#environment-variables
env:
[]
# - name: VM_remoteWrite_basicAuth_password
# valueFrom:
# secretKeyRef:
# name: auth_secret
# key: password
# extra Labels for Pods, Deployment and Statefulset
extraLabels:
bu: "dbc-dpcon"
team: "dbc-dpcon-sre"
service: "vmagent-dbc-dpcon-prd"
env: "prd"
priority: "p0"
type: "vmagent"
# extra Labels for Pods only
podLabels: {}
# 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
extraContainers: []
# - name: config-reloader
# image: reloader-image
podSecurityContext:
{}
# fsGroup: 2000
securityContext:
{}
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
service:
enabled: true
annotations: {}
# cloud.google.com/neg: '{"exposed_ports": {"8429":{"name": "vmagent-dbc-prd"}}}'
extraLabels: {}
clusterIP: ""
## Ref: https://kubernetes.io/docs/user-guide/services/#external-ips
##
externalIPs: []
loadBalancerIP: ""
loadBalancerSourceRanges: []
servicePort: 8429
# nodePort: 30000
type: ClusterIP
# Ref: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip
# externalTrafficPolicy: "local"
# healthCheckNodePort: 0
ingress:
enabled: true
ingressClassName: nginx-internal
annotations:
nginx.ingress.kubernetes.io/force-ssl-redirect: "false"
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/ssl-redirect: "false"
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: 'true'
extraLabels: {}
hosts:
- name: vmagent-dbc-dpcon-prd.meeshogcp.in
path: /
port: http
tls: []
# - secretName: vmagent-ingress-tls
# hosts:
# - vmagent.local
# For Kubernetes >= 1.18 you should specify the ingress-controller via the field ingressClassName
# See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#specifying-the-class-of-an-ingress
# ingressClassName: nginx
# -- pathType is only for k8s >= 1.1=
pathType: Prefix
resources:
# 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:'.
# limits:
# cpu: 100m
# memory: 128Mi
requests:
cpu: 2
memory: 4Gi
# Annotations to be added to the deployment
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "8429"
# Annotations to be added to pod
podAnnotations:
prometheus.io/scrape: "true"
prometheus.io/port: "8429"
nodeSelector:
dedicated: "devops"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "devops"
effect: "NoSchedule"
affinity: {}
# -- priority class to be assigned to the pod(s)
priorityClassName: ""
serviceMonitor:
enabled: false
extraLabels: {}
annotations: {}
relabelings: []
# 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
persistence:
enabled: false
# storageClassName: default
accessModes:
- ReadWriteOnce
size: 10Gi
annotations: {}
extraLabels: {}
existingClaim: ""
# -- Bind Persistent Volume by labels. Must match all labels of targeted PV.
matchLabels: {}
# -- Extra scrape configs that will be appended to `config`
extraScrapeConfigs: []
# Add extra specs dynamically to this chart
extraObjects: []
@@ -0,0 +1,3 @@
# Cluster-based Custom Values
This folder contains the custom `values.yaml` files organized based on specific cluster names. Each subdirectory corresponds to a particular cluster and holds the configurations for the applications and tools deployed within that cluster.
@@ -0,0 +1,295 @@
# Custom values for Bifrost (ai-gateway-ext) - Meesho Production
# Usage: helm install bifrost ./helm-templates/bifrost-v1.5.12-latest/ -f ./helm-overrides/gke-central-prd-ase1a/ai-gateway-ext/custom-values.yaml -n prd-ai-gateway-ext
# -- Deployment Configuration --
replicaCount: 2
fullnameOverride: "prd-ai-gateway-ext"
image:
repository: docker.io/maximhq/bifrost
pullPolicy: IfNotPresent
tag: "v1.6.3"
# -- Service Account --
serviceAccount:
create: true
automount: true
annotations:
iam.gke.io/gcp-service-account: sa-dvops-ai-gateway@meesho-central-prd-0622.iam.gserviceaccount.com
name: "prd-ai-gateway-ext"
# -- Pod Metadata --
deploymentLabels:
bu: central
env: prod
team: devops
priority: p1
priority_v2: sp1
primary_owner: deep.shah
secondary_owner: anupam.satsangi
service: ai-gateway-ext
service_type: producer-httpstateless
podLabels:
bu: central
env: prod
team: devops
priority: p1
priority_v2: sp1
primary_owner: deep.shah
secondary_owner: anupam.satsangi
service: ai-gateway-ext
service_type: producer-httpstateless
podAnnotations:
prometheus.io/path: /metrics
prometheus.io/port: "8080"
prometheus.io/scrape: "true"
telegraf.influxdata.com/class: infra
# -- Security Context --
podSecurityContext:
fsGroup: 65534
runAsUser: 65534
runAsGroup: 65534
runAsNonRoot: true
securityContext:
capabilities:
drop:
- ALL
readOnlyRootFilesystem: false
runAsNonRoot: true
runAsUser: 65534
# -- Service --
service:
type: ClusterIP
port: 8080
# -- Contour HTTPProxy --
# ingress.enabled=false disables Bifrost's official K8s Ingress
# httpProxy.enabled=true enables the Meesho Contour HTTPProxy templates
# HTTPProxy templates read from ingress.* for hosts, class, etc.
httpProxy:
enabled: true
createContourGateway: true
namespace: prd-ai-gateway-ext
contourResponseTimeout: false
ingress:
enabled: false
ingressClassName: contour-external
servicePortNumber: 8080
enableWebsocket: false
hosts:
- host: ai-gateway-ext.meeshogcp.in
paths:
- path: /
pathType: ImplementationSpecific
slowStart:
enabled: false
aggression: 1
minPercent: 10
window: 120s
# -- Resources --
resources:
limits:
cpu: "5"
memory: 10Gi
requests:
cpu: "4"
memory: 8Gi
# -- Health Probes --
livenessProbe:
httpGet:
path: /health
port: http
scheme: HTTP
initialDelaySeconds: 15
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 5
successThreshold: 1
readinessProbe:
httpGet:
path: /health
port: http
scheme: HTTP
initialDelaySeconds: 15
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 5
successThreshold: 1
# -- HPA (disabled - using KEDA) --
autoscaling:
enabled: false
# -- Scheduling --
nodeSelector:
cloud.google.com/compute-class: megatetralite
tolerations:
- key: cloud.google.com/compute-class
operator: Equal
value: megatetralite
effect: NoSchedule
affinity: {}
# -- Lifecycle & Graceful Shutdown --
terminationGracePeriodSeconds: 300
lifecycle:
preStop:
exec:
command:
- /bin/bash
- "-c"
- "kill -SIGQUIT; /bin/sleep 120"
# -- Bifrost Application Config --
bifrost:
appDir: /app/data
port: 8080
host: 0.0.0.0
logLevel: warn
logStyle: json
# Auth configured via Bifrost UI (stored in DB), not in Helm values
# This avoids blocking /metrics scrape while still protecting the dashboard
client:
dropExcessRequests: false
initialPoolSize: 300
allowedOrigins:
- "*"
enableLogging: true
disableContentLogging: false
disableDbPingsInHealth: false
logRetentionDays: 365
enforceGovernanceHeader: false
allowDirectKeys: false
maxRequestBodySizeMb: 100
# Configure providers with env.VAR_NAME references for API keys
# providers:
# openai:
# - keys:
# - value: "env.OPENAI_API_KEY"
# models: ["gpt-4o", "gpt-4o-mini"]
# weight: 1.0
# -- Storage (External PostgreSQL) --
storage:
mode: postgres
configStore:
enabled: true
logsStore:
enabled: true
postgresql:
enabled: false
external:
enabled: true
host: "env.BIFROST_POSTGRES_HOST"
port: 5432
user: "env.BIFROST_POSTGRES_USER"
database: "env.BIFROST_POSTGRES_DATABASE"
sslMode: "disable"
existingSecret: "prd-ai-gateway-ext-vault"
passwordKey: "BIFROST_POSTGRES_PASSWORD"
# -- Vector Store (disabled) --
vectorStore:
enabled: false
type: none
# -- Meesho Standard Env Vars --
env:
- name: TZ
value: "Asia/Kolkata"
- name: BIFROST_POSTGRES_HOST
valueFrom:
secretKeyRef:
name: prd-ai-gateway-ext-vault
key: BIFROST_POSTGRES_HOST
- name: BIFROST_POSTGRES_USER
valueFrom:
secretKeyRef:
name: prd-ai-gateway-ext-vault
key: BIFROST_POSTGRES_USER
- name: BIFROST_POSTGRES_DATABASE
valueFrom:
secretKeyRef:
name: prd-ai-gateway-ext-vault
key: BIFROST_POSTGRES_DATABASE
- name: TELEGRAF_UDP_HOST
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: NODE_IP
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
# --- Meesho Infrastructure Extensions ---
# -- PodDisruptionBudget --
podDisruptionBudget:
enabled: true
maxUnavailable: "10%"
# -- ExternalSecret (Vault) --
# Creates K8s Secret "prd-ai-gateway-ext-vault" from Vault path
# This secret is referenced by postgresql.external.existingSecret above
externalSecret:
enabled: true
secretName: "prd-ai-gateway-ext-vault"
path: "prd/cntr/devop/ai-gateway-ext"
refreshInterval: "0"
secretStoreRef: "vault-backend"
# -- KEDA ScaledObject --
keda:
enabled: true
pollingInterval: 30
minReplicaCount: 2
maxReplicaCount: 200
scaledown:
stabilizationWindowSeconds: 1800
selectpolicy: Min
policies:
- type: Pods
value: 2
periodseconds: 15
scaleup:
stabilizationWindowSeconds: 120
selectpolicy: Max
policies:
- type: Pods
value: 2
periodseconds: 15
- type: Percent
value: 10
periodseconds: 15
triggers:
- type: cpu
metricType: Utilization
metadata:
value: "40"
@@ -0,0 +1,286 @@
# Custom values for Bifrost (ai-gateway) - Meesho Production
# Usage: helm install bifrost ./helm-templates/bifrost/ -f ./helm-templates/bifrost/custom-values.yaml -n prd-ai-gateway
# -- Deployment Configuration --
replicaCount: 2
fullnameOverride: "prd-ai-gateway"
image:
repository: docker.io/maximhq/bifrost
pullPolicy: IfNotPresent
tag: "v1.4.22"
# -- Service Account --
serviceAccount:
create: true
automount: true
annotations:
iam.gke.io/gcp-service-account: sa-dvops-ai-gateway@meesho-central-prd-0622.iam.gserviceaccount.com
name: "prd-ai-gateway"
# -- Pod Metadata --
deploymentLabels:
bu: central
env: prod
team: devops
priority: p1
priority_v2: sp1
primary_owner: deep.shah
secondary_owner: anupam.satsangi
service: ai-gateway
service_type: producer-httpstateless
podLabels:
bu: central
env: prod
team: devops
priority: p1
priority_v2: sp1
primary_owner: deep.shah
secondary_owner: anupam.satsangi
service: ai-gateway
service_type: producer-httpstateless
podAnnotations:
prometheus.io/path: /metrics
prometheus.io/port: "8080"
prometheus.io/scrape: "true"
telegraf.influxdata.com/class: infra
# -- Security Context --
podSecurityContext:
fsGroup: 65534
runAsUser: 65534
runAsGroup: 65534
runAsNonRoot: true
securityContext:
capabilities:
drop:
- ALL
readOnlyRootFilesystem: false
runAsNonRoot: true
runAsUser: 65534
# -- Service --
service:
type: ClusterIP
port: 8080
# -- Contour HTTPProxy --
# ingress.enabled=false disables Bifrost's official K8s Ingress
# httpProxy.enabled=true enables the Meesho Contour HTTPProxy templates
# HTTPProxy templates read from ingress.* for hosts, class, etc.
httpProxy:
enabled: true
createContourGateway: true
namespace: prd-ai-gateway
contourResponseTimeout: false
ingress:
enabled: false
ingressClassName: contour-internal-1
servicePortNumber: 8080
enableWebsocket: false
hosts:
- host: ai-gateway.prd.meesho.int
paths:
- path: /
pathType: ImplementationSpecific
- host: llm-gateway.prd.meesho.int
name: prd-llm-gateway-0
intraName: prd-llm-gateway-intra-0
paths:
- path: /
pathType: ImplementationSpecific
slowStart:
enabled: false
aggression: 1
minPercent: 10
window: 120s
# -- Resources --
resources:
limits:
cpu: "5"
memory: 25Gi
requests:
cpu: "4"
memory: 20Gi
# -- Health Probes --
livenessProbe:
httpGet:
path: /health
port: http
scheme: HTTP
initialDelaySeconds: 15
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 5
successThreshold: 1
readinessProbe:
httpGet:
path: /health
port: http
scheme: HTTP
initialDelaySeconds: 15
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 5
successThreshold: 1
# -- HPA (disabled - using KEDA) --
autoscaling:
enabled: false
# -- Scheduling --
nodeSelector:
cloud.google.com/compute-class: megatetralite
tolerations:
- key: cloud.google.com/compute-class
operator: Equal
value: megatetralite
effect: NoSchedule
affinity: {}
# -- Lifecycle & Graceful Shutdown --
terminationGracePeriodSeconds: 300
lifecycle:
preStop:
exec:
command:
- /bin/bash
- "-c"
- "kill -SIGQUIT; /bin/sleep 120"
# -- Bifrost Application Config --
bifrost:
appDir: /app/data
port: 8080
host: 0.0.0.0
logLevel: warn
logStyle: json
# Auth configured via Bifrost UI (stored in DB), not in Helm values
# This avoids blocking /metrics scrape while still protecting the dashboard
client:
dropExcessRequests: false
initialPoolSize: 300
allowedOrigins:
- "*"
enableLogging: true
disableContentLogging: false
disableDbPingsInHealth: false
logRetentionDays: 365
enforceGovernanceHeader: false
allowDirectKeys: false
maxRequestBodySizeMb: 100
# Configure providers with env.VAR_NAME references for API keys
# providers:
# openai:
# - keys:
# - value: "env.OPENAI_API_KEY"
# models: ["gpt-4o", "gpt-4o-mini"]
# weight: 1.0
# -- Storage (External PostgreSQL) --
storage:
mode: postgres
configStore:
enabled: true
logsStore:
enabled: true
postgresql:
enabled: false
external:
enabled: true
host: "10.147.2.236"
port: 5432
user: "app_user_bifrost"
database: "bifrost_db"
sslMode: "disable"
existingSecret: "prd-ai-gateway-vault"
passwordKey: "BIFROST_POSTGRES_PASSWORD"
# -- Vector Store (disabled) --
vectorStore:
enabled: false
type: none
# -- Meesho Standard Env Vars --
env:
- name: TZ
value: "Asia/Kolkata"
- name: TELEGRAF_UDP_HOST
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: NODE_IP
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
# --- Meesho Infrastructure Extensions ---
# -- PodDisruptionBudget --
podDisruptionBudget:
enabled: true
maxUnavailable: "10%"
# -- ExternalSecret (Vault) --
# Creates K8s Secret "prd-ai-gateway-vault" from Vault path
# This secret is referenced by postgresql.external.existingSecret above
externalSecret:
enabled: true
secretName: "prd-ai-gateway-vault"
path: "prd/cntr/devop/ai-gateway"
refreshInterval: "0"
secretStoreRef: "vault-backend"
# -- KEDA ScaledObject --
keda:
enabled: true
pollingInterval: 30
minReplicaCount: 2
maxReplicaCount: 200
scaledown:
stabilizationWindowSeconds: 1800
selectpolicy: Min
policies:
- type: Pods
value: 2
periodseconds: 15
scaleup:
stabilizationWindowSeconds: 120
selectpolicy: Max
policies:
- type: Pods
value: 2
periodseconds: 15
- type: Percent
value: 10
periodseconds: 15
triggers:
- type: cpu
metricType: Utilization
metadata:
value: "40"
@@ -0,0 +1,99 @@
# Akamai Observability MCP — grafana-mcp chart on gke-central-prd-ase1a
# Chart: helm-templates/grafana-mcp (v2.0.0+)
fullnameOverride: "akamai-observability-mcp"
replicas: 1
image:
registry: asia-southeast1-docker.pkg.dev
repository: meesho-devops-admin-0622/prd/devop/grafana-mcp
tag: "v2026-03-10"
pullPolicy: IfNotPresent
labels:
bu: central
team: devops
service: akamai-observability-mcp
env: prd
# -- Grafana connection.
# url: set this to the Akamai/observability Grafana endpoint reachable from
# gke-central-prd-ase1a (in-cluster DNS preferred; otherwise the prd FQDN).
# apiKeySecret: read GRAFANA_SERVICE_ACCOUNT_TOKEN from the K8s Secret produced
# by the ExternalSecret below.
grafana:
url: "" # TODO: set the Grafana base URL (e.g. https://grafana-akamai.prd.meesho.int)
apiKeySecret:
name: "akamai-observability-mcp-vault"
key: "GRAFANA_SERVICE_ACCOUNT_TOKEN"
# -- Vault-backed secret. Mint the Grafana service-account token in the Grafana
# UI, store it at the path below under key GRAFANA_SERVICE_ACCOUNT_TOKEN, then
# ESO syncs it into the K8s Secret referenced above.
externalSecret:
enabled: true
secretName: "akamai-observability-mcp-vault"
path: "prd/cntr/devop/akamai-observability-mcp" # TODO: confirm Vault path
refreshInterval: "0"
secretStoreRef: "vault-backend"
serviceAccount:
create: true
annotations: {}
# SSE transport is long-lived — keep Contour from cutting connections.
contourResponseTimeout: "1h"
createContourGateway: true
ingress:
enabled: true
ingressClassName: contour-internal-1
servicePortNumber: 8000
enableWebsocket: true
hosts:
- host: akamai-observability-mcp.prd.meesho.int
paths:
- path: /
pathType: Prefix
annotations: {}
slowStart:
enabled: false
window: "120s"
aggression: 1
minPercent: 10
resources:
requests:
cpu: 250m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
# Scheduling — dedicated MCP node pool on gke-central-prd-ase1a.
nodeSelector:
cloud.google.com/compute-class: "devops-mcp"
tolerations:
- key: "cloud.google.com/compute-class"
operator: "Equal"
value: "devops-mcp"
effect: NoSchedule
securityContext:
fsGroup: 1000
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
containerSecurityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
@@ -0,0 +1,689 @@
## Aurva Data Plane
## Ref: https://github.com/aurva-io/aurva-charts.git
postgresql:
enabled: true
fullnameOverride: "aurva-dataplane-database"
volumePermissions:
## @param volumePermissions.enabled Enable init container that changes the owner and group of the persistent volume
##
enabled: true
global:
storageClass: hyperdisk-balanced
postgresql:
auth:
postgresPassword: "aurva"
database: "controller"
# Add toleration to make sure where this postgres db pod should reside (Applicable for production workloads): For more detail ref: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/
primary:
extendedConfiguration: |
max_connections = 300
#PLACEHOLDER##
tolerations:
- effect: NoSchedule
key: cloud.google.com/compute-class
operator: Equal
value: central-devops
# -- Select nodes to deploy which matches the following labels
nodeSelector: ##PLACEHOLDER##
cloud.google.com/compute-class: central-devops
# -- Provide a name in place of `aurva`
# namespaceOverride: aurva-dataplane
##########################################################
# Global Configs
##########################################################
global:
aurva_controller:
enabled: true
aurva_fastdet:
enabled: false
aurva_pii_analyzer:
enabled: true
aurva_ocr:
enabled: true
aurva_collector:
enabled: true
deploymentAnnotations: {}
priorityClassName: ""
##########################################################
# Aurva Controller
##########################################################
aurva_controller:
# -- Additional labels for aurva-controller
additionalLabels:
bu: "central"
team: "central-devops"
service: "aurva-central-a-prd"
env: "prd"
priority: "p0"
type: "aurva_controller"
# -- Annotations on aurva-controller
annotations: {}
# "key": "value"
revisionHistoryLimit: 3
# -- no of replicas for aurva controller
replicas: 10
# -- Additional label added on pod which is used in Service's Label Selector
podLabels: {}
# -- Additional Pod Annotations added on pod created by this Deployment
additionalPodAnnotations: {}
# "key": "value"
# -- Secrets used to pull image
imagePullSecrets: ""
image:
# Image of the app container
repository: asia-south1-docker.pkg.dev/aurva-gcp/aurva-controller/aurva-controller
tag: "v3.20.3"
pullPolicy: IfNotPresent
# Environment variables to be passed to the app container
env: []
# -- If want to mount Envs from configmap or secret
envFrom:
- type: secret
name: aurva-controller-secrets
# - type: configmap
# name: proxy-datasource-config
# -- Resources to be defined for pod
resources:
limits:
memory: 2Gi
cpu: 2
requests:
memory: 1Gi
cpu: 1
aurvaFastdet:
image:
repository: asia-south1-docker.pkg.dev/aurva-gcp/aurva-fastdet/aurva-fastdet
tag: "v2.30.13"
pullPolicy: IfNotPresent
envFrom: []
env: []
resources:
limits:
cpu: 0.5
memory: 512Mi
requests:
cpu: 0.5
memory: 512Mi
nodeSelector: ##PLACEHOLDER##
cloud.google.com/compute-class: central-devops
# -- Taint tolerations for nodes
##PLACEHOLDER##
tolerations:
- effect: NoSchedule
key: cloud.google.com/compute-class
operator: Equal
value: central-devops
# -- Pod affinity and pod anti-affinity allow you to specify rules about how pods should be placed relative to other pods.
affinity:
# nodeAffinity:
# requiredDuringSchedulingIgnoredDuringExecution:
# nodeSelectorTerms:
# - matchExpressions:
# - key: disktype
# operator: In
# values:
# - ssd
# -- [DNS configuration]
dnsConfig: {}
# -- Alternative DNS policy for application controller pods
dnsPolicy: "ClusterFirst"
secret:
name: "aurva-controller-secrets"
# -- Additional Labels on secrets
additionalLabels:
# key: value
# -- Annotations on secrets
annotations:
# key: value
config:
#variables
COMPANY_ID: "65eeb832-67ba-40fb-b95a-30ca9eaa3409"
COMMAND_URL: "command.aurva-prd.meeshogcp.in:80"
DEPLOYMENT_TYPE: "kubernetes"
PG_USERNAME: "postgres"
PG_PASSWORD: "aurva"
PG_DBNAME: "controller"
FLUSHER_WORKER_POOL_SIZE: "1000"
FLUSHER_BATCH_SIZE: "30000"
UNIQUENESS_IDENTIFIER: "gke-central-prd-ase1a" #Recommendation: should be equal to cluster name
PROVIDER_ACCOUNT_ID: "meesho-central-prd-0622" # GCP PROJECT ID (not Number)
REGION: "asia-southeast1" #eg: asia-south1
ENVIRONMENT: "prod"
OCR_ENABLED: "true"
MONITORING_ENABLED: "false"
HYBRID_ONLY_MODE: "false"
FORCE_TLS: "false"
FASTDET_FLAG : "true"
AADHAAR_ENHANCER: "0"
WORKSPACE_EVENT_TRACKING_ENABLED: "false"
ACCESS_IQ_ENABLED: "true"
GRPC_ENFORCE_ALPN_ENABLED: "false"
ENABLE_FASTDET: "true"
FASTDET_MAX_BATCH_SIZE: "100"
HEARTBEAT_INTERVAL: "5m"
#pii data
PII_BUCKET_NAME: "gcs-infra-devop-aurva-central-prd"
PII_LOG_BUCKET_REGION: "asia-southeast1"
PII_LOG_CRON: "*/5 * * * *"
ENABLE_PII_LOG: "true"
PII_EVIDENCE_UPLOAD_MAX_BLOCKING_TASKS: "50000"
PII_EVIDENCE_UPLOAD_MAX_CONCURRENT_TASKS: "500"
PII_EVIDENCE_MAX_CACHE_WEIGHT: "100"
QUOTA_CLEANUP_CRON: "0 0 * * *"
ENABLE_PII_QUOTA: "true"
MAX_PII_EVIDENCES_PER_KEY_PER_WINDOW: "3"
PII_QUOTA_SYNC_CRON: "*/2 * * * *"
QUOTA_WINDOW_HOURS: "24"
#constants
SKIP_NAMESPACES: "contour-internal-1-central-prd,contour-internal-0-central-prd,contour-external-central-prd"
CLOUD_PROVIDER: "gcp"
LOG_ENV: "production"
RDS_SCANNER_AVAILABILITY : "false"
REDSHIFT_SCANNER_AVAILABILITY : "false"
S3_SCANNER_AVAILABILITY : "false"
DYNAMO_SCANNER_AVAILABILITY: "false"
DOCDB_SCANNER_AVAILABILITY: "false"
OPENSEARCH_SCANNER_AVAILABILITY: "false"
CLOUDSQL_SCANNER_AVAILABILITY: "true"
BIGQUERY_SCANNER_AVAILABILITY: "true"
AWS_SNAPSHOT_SCANNER_AVAILABILITY: "false"
CLOUDSTORAGE_SCANNER_AVAILABILITY: "true"
KEYSPACES_SCANNER_AVAILABILITY: "false"
ALLOYDB_SCANNER_AVAILABILITY: "true"
BIGTABLE_SCANNER_AVAILABILITY: "true"
GCP_BACKUP_AVAILABILITY: "true"
EGRESS_MODE_ONLY: "false"
SENTRY_DSN: "https://fd6738e1ee4a9a9c1f079d09953b43b1@sentry.aurva.io/4"
SCAN_UUID_ENABLED: "true"
serviceAccount:
# -- Create a service account for the aurva controller
create: true
# -- Service account name
name: aurva-controller-sa
# -- Annotations applied to created service account
annotations:
iam.gke.io/gcp-service-account: sa-central-prd-aurva-contr@meesho-central-prd-0622.iam.gserviceaccount.com
# eks.amazonaws.com/role-arn: arn:aws:iam::<account-id>:role/<role-name>
# -- Labels applied to created service account
labels: {}
autoscaling:
enabled: true
minReplicas: 10
maxReplicas: 15
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 70
##########################################################
# Aurva OCR
##########################################################
aurva_ocr:
# -- Additional labels for aurva-controller
additionalLabels:
bu: "central"
team: "central-devops"
service: "aurva-central-a-prd"
env: "prd"
priority: "p0"
type: "aurva_ocr"
# -- Annotations on aurva-controller
annotations: {}
# "key": "value"
revisionHistoryLimit: 3
# -- no of replicas for aurva controller
replicas: 1
# -- Additional label added on pod which is used in Service's Label Selector
podLabels: {}
# -- Additional Pod Annotations added on pod created by this Deployment
additionalPodAnnotations: {}
# "key": "value"
# -- Secrets used to pull image
imagePullSecrets: ""
# Image of the app container
image:
repository: asia-south1-docker.pkg.dev/aurva-gcp/aurva-ocr/aurva-ocr
tag: "v3.20.3"
pullPolicy: IfNotPresent
# Environment variables to be passed to the app container
env: []
# -- If want to mount Envs from configmap or secret
envFrom:
aurva-ocr:
type: secret
name: aurva-ocr-secrets
# -- Resources to be defined for pod
resources:
limits:
memory: 2Gi
cpu: 1
requests:
memory: 2Gi
cpu: 1
# -- Select nodes to deploy which matches the following labels
nodeSelector: ##PLACEHOLDER##
cloud.google.com/compute-class: central-devops
##PLACEHOLDER##
# -- Taint tolerations for nodes
tolerations:
- effect: NoSchedule
key: cloud.google.com/compute-class
operator: Equal
value: central-devops
# -- Pod affinity and pod anti-affinity allow you to specify rules about how pods should be placed relative to other pods.
affinity:
# nodeAffinity:
# requiredDuringSchedulingIgnoredDuringExecution:
# nodeSelectorTerms:
# - matchExpressions:
# - key: disktype
# operator: In
# values:
# - ssd
# -- [DNS configuration]
dnsConfig: {}
# -- Alternative DNS policy for application controller pods
dnsPolicy: "ClusterFirst"
secret:
name: "aurva-ocr-secrets"
# -- Additional Labels on secrets
additionalLabels:
# key: value
# -- Annotations on secrets
annotations:
# key: value
config:
PG_USERNAME: "postgres"
PG_PASSWORD: "aurva"
PG_DBNAME: "controller"
OCR_TIME_LIMIT: "1"
COMPANY_ID: "65eeb832-67ba-40fb-b95a-30ca9eaa3409"
UNIQUENESS_IDENTIFIER: "gke-central-prd-ase1a"
DEPLOYMENT_TYPE: "kubernetes"
serviceAccount:
# -- Create a service account for the aurva controller
create: true
# -- Service account name
name: aurva-ocr-sa
# -- Annotations applied to created service account
annotations:
# eks.amazonaws.com/role-arn: arn:aws:iam::<account-id>:role/<role-name>
# iam.gke.io/gcp-service-account: service-account@gcp.iam.gserviceaccount.com
# -- Labels applied to created service account
labels: {}
##########################################################
# Aurva Collector
##########################################################
aurva_collector:
# -- Additional labels for aurva-analyzer
additionalLabels:
bu: "central"
team: "central-devops"
service: "aurva-central-a-prd"
env: "prd"
priority: "p0"
type: "aurva_collector"
# -- Annotations on aurva-analyzer
annotations: {}
# "key": "value"
# -- Additional label added on pod which is used in Service's Label Selector
podLabels: {}
# -- Additional Pod Annotations added on pod created by this Deployment
additionalPodAnnotations: {}
# "key": "value"
# -- Secrets used to pull image
imagePullSecrets: ""
# Image of the app container
image:
repository: asia-south1-docker.pkg.dev/aurva-gcp/aurva-collector/aurva-collector
tag: "v3.20.3"
pullPolicy: IfNotPresent
# Environment variables to be passed to the app container
env: []
# -- If want to mount Envs from configmap or secret
envFrom:
aurva-controller:
type: secret
name: aurva-collector-secrets
resources:
limits:
cpu: 800m
memory: 800Mi
requests:
cpu: 200m
memory: 512Mi
podSecurityContext: {}
securityContext:
privileged: true
capabilities:
add:
# For kernel v5.8 and above we don't need CAP_SYS_ADMIN or CAP_SYS_RESOURCE
# we just need CAP_BPF and CAP_PERFMON. This has been tested on our EKS node
# which is on kernel v5.10.x
# When SSL Tracing is required we need CAP_SYS_ADMIN and CAP_SYS_PTRACE
# on top of the previous capabilities
# So finally these are the 4 possible combinations for capabilies
# 1. Newer Kernels without SSL
# - BPF
# - PERFMON
# 2. Newer Kernels with SSL
- SYS_ADMIN
- SYS_PTRACE
# 3. Older Kernels without SSL
# - SYS_ADMIN
# - SYS_RESOURCE
# 4. Older Kernels with SSL
# - SYS_ADMIN
# - SYS_RESOURCE
# - SYS_PTRACE
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
volumes:
- name: debugfs
mountPath: /sys/kernel/debug
hostPath: /sys/kernel/debug
- name: vmlinux
mountPath: /sys/kernel/btf/vmlinux
hostPath: /sys/kernel/btf/vmlinux
- name: procfs
mountPath: /host/proc
hostPath: /proc
- name: bpffs
mountPath: /sys/fs/bpf
hostPath: /sys/fs/bpf
# -- Taint tolerations for nodes
tolerations:
# - effect: NoSchedule
# key: dedicated
# operator: Equal
# value: megatetra
- operator: Exists
# -- Pod affinity and pod anti-affinity allow you to specify rules about how pods should be placed relative to other pods.
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: dedicated
operator: NotIn
values:
- vmstorage-n4d
- vmselect-mds
- vmagent-mds
- vminsert-mds
- contour-internal-0
- contour-internal-1
- contour-external
- contour-internal-intra-1
- contour-internal-intra-0
- contour-external-arm
- contour-external-cc
- contour-internal-0-arm
- contour-internal-0-cc
- contour-internal-1-arm
- contour-internal-1-cc
- contour-intra-0-arm
- contour-intra-0-cc
- contour-intra-1-arm
- contour-intra-1-cc
- contour-shared-arm
- contour-shared-cc
- alloy
- preprod-spot-16
dnsPolicy: "ClusterFirst"
secret:
name: "aurva-collector-secrets"
# -- Additional Labels on secrets
additionalLabels:
# key: value
# -- Annotations on secrets
annotations:
# key: value
config:
# variables
COMPANY_ID: "65eeb832-67ba-40fb-b95a-30ca9eaa3409"
UNIQUENESS_IDENTIFIER: "k8s-central-prd-ase1"
DEPLOYMENT_TYPE: "kubernetes"
TRACE_INTERNAL_SVC: "true"
TRACE_INTERNAL_SVC_HTTP: "true"
INTERNAL_SVC_SAMPLE_INTERVAL: "10m"
LOGS_TTL: "1h"
TRACE_HTTP2: "true"
TRACE_SSL: "false"
TRACE_PSQL: "false"
TRACE_SQLSERVER: "false"
TRACE_MYSQL: "false"
TRACE_EGRESS: "true"
TRACE_GO_TLS: "false"
TRACE_ML_SERVICES: "false"
# constants
LOG_ENV: production
SENTRY_DSN: "https://fd6738e1ee4a9a9c1f079d09953b43b1@sentry.aurva.io/4"
MONITORING_ENABLED: "false"
ENABLE_INGRESS_INFORMER: "false"
ENABLE_SERVICE_INFORMER: "false"
ENABLE_ISTIO_INFORMER: "false"
EXCLUDED_PII_REGEX_TYPES: "ip_address,us_bank_number,us_driver_license,us_itin,us_passport,us_routing,us_mbi,ssn"
AGGREGATOR_MAX_CONNECTIONS: "1000"
serviceAccount:
# -- Create a service account for the aurva controller
create: true
# -- Service account name
name: aurva-collector-sa
# -- Annotations applied to created service account
annotations:
# eks.amazonaws.com/role-arn: arn:aws:iam::<account-id>:role/<role-name>
# -- Labels applied to created service account
labels: {}
##########################################################
# Aurva PII Analyzer
##########################################################
aurva_pii_analyzer:
# -- Additional labels for aurva-controller
additionalLabels:
bu: "central"
team: "central-devops"
service: "aurva-central-a-prd"
env: "prd"
priority: "p0"
type: "aurva_pii_analyzer"
# -- Annotations on aurva-controller
annotations: {}
# "key": "value"
revisionHistoryLimit: 3
# -- no of replicas for aurva controller
replicas: 3
# -- Additional label added on pod which is used in Service's Label Selector
podLabels: {}
# -- Additional Pod Annotations added on pod created by this Deployment
additionalPodAnnotations: {}
# "key": "value"
# -- Secrets used to pull image
imagePullSecrets: ""
##PLACEHOLDER##
nodeSelector:
cloud.google.com/compute-class: central-devops
# Image of the app container
image:
repository: asia-south1-docker.pkg.dev/aurva-gcp/aurva-piianalyzer/aurva-piianalyzer
tag: "v3.20.3"
pullPolicy: IfNotPresent
# Environment variables to be passed to the app container
env: []
# -- If want to mount Envs from configmap or secret
envFrom:
aurva-pii-analyzer:
type: secret
name: aurva-pii-analyzer-secrets
# -- Resources to be defined for pod
resources:
limits:
memory: 4Gi
cpu: 4
requests:
memory: 2Gi
cpu: 2
nodeSelector: ##PLACEHOLDER##
cloud.google.com/compute-class: central-devops
##PLACEHOLDER##
# -- Taint tolerations for nodes
tolerations:
- effect: NoSchedule
key: cloud.google.com/compute-class
operator: Equal
value: central-devops
# -- Pod affinity and pod anti-affinity allow you to specify rules about how pods should be placed relative to other pods.
affinity:
# nodeAffinity:
# requiredDuringSchedulingIgnoredDuringExecution:
# nodeSelectorTerms:
# - matchExpressions:
# - key: disktype
# operator: In
# values:
# - ssd
# -- [DNS configuration]
dnsConfig: {}
# -- Alternative DNS policy for application controller pods
dnsPolicy: "ClusterFirst"
secret:
name: "aurva-pii-analyzer-secrets"
# -- Additional Labels on secrets
additionalLabels:
# key: value
# -- Annotations on secrets
annotations:
# key: value
config:
PG_USERNAME: "postgres"
PG_PASSWORD: "aurva"
PG_DBNAME: "controller"
SCHEDULER_TIME: "1"
SUPPORTED_REGION: "US"
COMPANY_ID: "65eeb832-67ba-40fb-b95a-30ca9eaa3409"
UNIQUENESS_IDENTIFIER: "gke-central-prd-ase1a"
DEPLOYMENT_TYPE: "kubernetes"
serviceAccount:
# -- Create a service account for the aurva controller
create: true
# -- Service account name
name: aurva-pii-analyzer-sa
# -- Annotations applied to created service account
annotations:
# eks.amazonaws.com/role-arn: arn:aws:iam::<account-id>:role/<role-name>
# -- Labels applied to created service account
labels: {}
autoscaling:
enabled: true
minReplicas: 2
maxReplicas: 3
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 70
@@ -0,0 +1,129 @@
global:
logLevel: 2
rbac:
create: true
priorityClassName: "high-priority"
installCRDs: false
crds:
enabled: true
keep: true
# Cert-manager Controller
replicaCount: 1
image:
repository: asia-southeast1-docker.pkg.dev/meesho-devops-admin-0622/admin/devops/cert-manager/cert-manager-controller
tag: v1.20.1
pullPolicy: IfNotPresent
nodeSelector:
cloud.google.com/compute-class: central-devops
tolerations:
- key: "cloud.google.com/compute-class"
operator: "Equal"
value: "central-devops"
effect: "NoSchedule"
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
# Webhook Configuration
webhook:
replicaCount: 1
image:
repository: asia-southeast1-docker.pkg.dev/meesho-devops-admin-0622/admin/devops/cert-manager/cert-manager-webhook
tag: v1.20.1
pullPolicy: IfNotPresent
nodeSelector:
cloud.google.com/compute-class: central-devops
tolerations:
- key: "cloud.google.com/compute-class"
operator: "Equal"
value: "central-devops"
effect: "NoSchedule"
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
cpu: 250m
memory: 256Mi
# CA Injector Configuration
cainjector:
enabled: true
replicaCount: 1
image:
repository: asia-southeast1-docker.pkg.dev/meesho-devops-admin-0622/admin/devops/cert-manager/cert-manager-cainjector
tag: v1.20.1
pullPolicy: IfNotPresent
nodeSelector:
cloud.google.com/compute-class: central-devops
tolerations:
- key: "cloud.google.com/compute-class"
operator: "Equal"
value: "central-devops"
effect: "NoSchedule"
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
cpu: 250m
memory: 256Mi
# ACME Solver Configuration
acmesolver:
image:
repository: asia-southeast1-docker.pkg.dev/meesho-devops-admin-0622/admin/devops/cert-manager/cert-manager-acmesolver
tag: v1.20.1
pullPolicy: IfNotPresent
# Startup API Check
startupapicheck:
enabled: true
timeout: 1m
backoffLimit: 4
image:
repository: asia-southeast1-docker.pkg.dev/meesho-devops-admin-0622/admin/devops/cert-manager/cert-manager-startupapicheck
tag: v1.20.1
pullPolicy: IfNotPresent
nodeSelector:
cloud.google.com/compute-class: central-devops
tolerations:
- key: "cloud.google.com/compute-class"
operator: "Equal"
value: "central-devops"
effect: "NoSchedule"
resources:
requests:
cpu: 10m
memory: 32Mi
limits:
cpu: 50m
memory: 64Mi
# Prometheus Monitoring
prometheus:
enabled: true
servicemonitor:
enabled: false
interval: 60s
scrapeTimeout: 30s
labels:
prometheus: cert-manager
@@ -0,0 +1,251 @@
# logHouse (central-prd) - overrides only.
# Google SSO via oauth2-proxy; ClickHouse ingress disabled.
oauth2Proxy:
enabled: true
# nginx audit proxy maps X-Forwarded-Email → X-ClickHouse-Setting-log_comment
# so system.query_log.log_comment shows the SSO email of who ran each query.
auditProxy:
enabled: true
replicas: 2
image: "nginx:1.27-alpine"
tolerations:
- key: "cloud.google.com/compute-class"
operator: "Equal"
value: "loghouse"
effect: "NoSchedule"
externalSecret:
enabled: true
path: meesho/prd/cntr/devop/loghouse
secretName: loghouse-oauth2-secret
annotations: {}
# --- Bitnami ClickHouse subchart ---
clickhouse:
replicaCount: 3
global:
security:
allowInsecureImages: true
image:
registry: asia-southeast1-docker.pkg.dev
repository: meesho-devops-admin-0622/prd/sis/clickhouse
tag: 25.6.2-debian-12-r0
auth:
username: default
password: ""
existingSecret: "loghouse-oauth2-secret"
existingSecretKey: "clickhouse-password"
# Enable sampling so Bitnami's 08-sampling.xml preserves query_log,
# text_log, metric_log etc. All queries are recorded in system.query_log.
sampling:
enabled: true
usersdFiles:
grant_all.xml: |
<yandex>
<users>
<default>
<access_management>1</access_management>
<named_collection_control>1</named_collection_control>
</default>
</users>
</yandex>
log_queries.xml: |
<clickhouse>
<profiles>
<default>
<log_queries>1</log_queries>
<log_query_threads>0</log_query_threads>
</default>
</profiles>
</clickhouse>
initContainers:
- name: copy-usersd-config
image: busybox:1.36
command:
- /bin/sh
- -ec
- cp -R /src/. /dst/
volumeMounts:
- name: usersd-configuration-configuration
mountPath: /src
readOnly: true
- name: clickhouse-users-d
mountPath: /dst
persistence:
storageClass: "hyperdisk-balanced"
size: 100Gi
mountPath: /var/lib/clickhouse
extraEnvVars:
- name: CLICKHOUSE_USER
value: "default"
- name: CLICKHOUSE_PASSWORD
valueFrom:
secretKeyRef:
name: loghouse-oauth2-secret
key: clickhouse-password
extraVolumes:
- name: clickhouse-users-d
emptyDir:
sizeLimit: 100Mi
- name: clickhouse-logs
emptyDir:
sizeLimit: 500Mi
- name: fluentbit-config
configMap:
name: loghouse-fluentbit-config
extraVolumeMounts:
- name: clickhouse-users-d
mountPath: /etc/clickhouse-server/users.d
- name: clickhouse-logs
mountPath: /var/log/clickhouse-server
sidecars:
- name: query-log-tailer
image: "asia-southeast1-docker.pkg.dev/meesho-devops-admin-0622/prd/sis/clickhouse:25.6.2-debian-12-r0"
command:
- /bin/sh
- -c
- |
while true; do
clickhouse-client --host 127.0.0.1 --port 9000 --user default --password "$CLICKHOUSE_PASSWORD" --query="SELECT event_time, user, query_id, query, client_hostname FROM system.query_log WHERE type = 'QueryFinish' AND event_time > now() - INTERVAL 10 SECOND FORMAT JSONEachRow" 2>/dev/null;
sleep 10;
done
env:
- name: CLICKHOUSE_PASSWORD
valueFrom:
secretKeyRef:
name: loghouse-oauth2-secret
key: clickhouse-password
volumeMounts:
- name: clickhouse-logs
mountPath: /var/log/clickhouse-server
readOnly: true
resources:
requests:
cpu: 10m
memory: 32Mi
limits:
cpu: 50m
memory: 64Mi
- name: fluentbit
image: fluent/fluent-bit:3.1
resources:
requests:
cpu: 25m
memory: 50Mi
limits:
cpu: 100m
memory: 100Mi
volumeMounts:
- name: clickhouse-logs
mountPath: /var/log/clickhouse-server
readOnly: true
- name: fluentbit-config
mountPath: /fluent-bit/etc
readOnly: true
defaultInitContainers:
volumePermissions:
enabled: false
image:
registry: asia-southeast1-docker.pkg.dev
repository: meesho-devops-admin-0622/prd/sis/os-shell
tag: 12-debian-12-r47
resourcesPreset: "none"
# Chart maps these inversely: values.requests -> pod limits, values.limits -> pod requests
resources:
requests:
cpu: "6"
memory: 40Gi
limits:
cpu: "6"
memory: 40Gi
tolerations:
- key: "cloud.google.com/compute-class"
operator: "Equal"
value: "loghouse"
effect: "NoSchedule"
# Disabled when oauth2Proxy.enabled is true (oauth2-proxy handles ingress)
ingress:
enabled: false
networkPolicy:
enabled: true
allowExternal: true
allowExternalEgress: true
keeper:
enabled: false
oauth2-proxy:
replicaCount: 3
config:
existingSecret: loghouse-oauth2-secret
requiredSecretKeys:
- client-id
- client-secret
- cookie-secret
extraArgs:
provider: google
redirect-url: "http://loghouse-central.prd.meesho.int/oauth2/callback"
upstream: "http://loghouse-central-a-prd-audit-proxy:8123"
email-domain: "meesho.com"
proxy-prefix: "/oauth2"
pass-host-header: "true"
proxy-websockets: "true"
real-client-ip-header: "X-Forwarded-For"
cookie-secure: "false"
cookie-expire: "0s"
custom-templates-dir: "/templates"
skip-jwt-bearer-tokens: "true"
oidc-issuer-url: "https://accounts.google.com"
extra-jwt-issuers: "https://accounts.google.com=32555940559.apps.googleusercontent.com"
pass-user-headers: "true"
set-xauthrequest: "true"
request-logging: "true"
auth-logging: "true"
standard-logging: "true"
extraVolumes:
- name: custom-templates
configMap:
name: '{{ .Release.Name }}-oauth2-proxy-templates'
extraVolumeMounts:
- name: custom-templates
mountPath: /templates
readOnly: true
service:
portNumber: 80
ingress:
enabled: true
className: contour-internal-1
path: /
pathType: Prefix
hosts:
- loghouse-central.prd.meesho.int
annotations: {}
tls: []
sessionStorage:
type: cookie
redis-ha:
enabled: false
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
cpu: 200m
memory: 128Mi
@@ -0,0 +1,45 @@
apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
name: azul
spec:
nodePoolConfig:
serviceAccount: sa-common-np-cntr-prd@meesho-central-prd-0622.iam.gserviceaccount.com
nodeLabels:
dedicated: azul
priorityDefaults:
location:
zones: ['asia-southeast1-a']
activeMigration:
optimizeRulePriority: true
nodePoolAutoCreation:
enabled: true
priorities:
- location:
zones:
- asia-southeast1-a
machineType: c2-standard-8
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-c
machineType: c2-standard-8
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-b
machineType: c2-standard-8
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
whenUnsatisfiable: DoNotScaleUp
@@ -0,0 +1,45 @@
apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
name: central-devops
spec:
nodePoolConfig:
serviceAccount: sa-common-np-cntr-prd@meesho-central-prd-0622.iam.gserviceaccount.com
nodeLabels:
dedicated: central-devops
priorityDefaults:
location:
zones: ['asia-southeast1-a']
activeMigration:
optimizeRulePriority: true
nodePoolAutoCreation:
enabled: true
priorities:
- location:
zones:
- asia-southeast1-a
machineType: e2-standard-4
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-c
machineType: e2-standard-4
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-b
machineType: e2-standard-4
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
whenUnsatisfiable: DoNotScaleUp
@@ -0,0 +1,45 @@
apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
name: central-kyverno
spec:
nodePoolConfig:
serviceAccount: sa-common-np-cntr-prd@meesho-central-prd-0622.iam.gserviceaccount.com
nodeLabels:
dedicated: central-kyverno
priorityDefaults:
location:
zones: ['asia-southeast1-a']
activeMigration:
optimizeRulePriority: true
nodePoolAutoCreation:
enabled: true
priorities:
- location:
zones:
- asia-southeast1-a
machineType: n2-standard-8
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-c
machineType: n2-standard-8
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-b
machineType: n2-standard-8
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
whenUnsatisfiable: DoNotScaleUp
@@ -0,0 +1,72 @@
apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
name: compactduo
spec:
nodePoolConfig:
serviceAccount: sa-common-np-cntr-prd@meesho-central-prd-0622.iam.gserviceaccount.com
nodeLabels:
dedicated: compactduo
priorityDefaults:
location:
zones: ['asia-southeast1-a']
activeMigration:
optimizeRulePriority: true
nodePoolAutoCreation:
enabled: true
priorities:
- location:
zones:
- asia-southeast1-a
machineType: c4-highcpu-8
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-a
machineType: c3-highcpu-8
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-c
machineType: c4-highcpu-8
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-c
machineType: c3-highcpu-8
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-b
machineType: c4-highcpu-8
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-b
machineType: c3-highcpu-8
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
whenUnsatisfiable: DoNotScaleUp
@@ -0,0 +1,45 @@
apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
name: compacttetra
spec:
nodePoolConfig:
serviceAccount: sa-common-np-cntr-prd@meesho-central-prd-0622.iam.gserviceaccount.com
nodeLabels:
dedicated: compacttetra
priorityDefaults:
location:
zones: ['asia-southeast1-a']
activeMigration:
optimizeRulePriority: true
nodePoolAutoCreation:
enabled: true
priorities:
- location:
zones:
- asia-southeast1-a
machineType: c3-standard-8
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-c
machineType: c3-standard-8
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-b
machineType: c3-standard-8
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
whenUnsatisfiable: DoNotScaleUp
@@ -0,0 +1,72 @@
apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
name: contour-external-arm
spec:
nodePoolConfig:
serviceAccount: sa-common-np-cntr-prd@meesho-central-prd-0622.iam.gserviceaccount.com
nodeLabels:
dedicated: contour-external-arm
priorityDefaults:
location:
zones: ['asia-southeast1-a']
activeMigration:
optimizeRulePriority: true
nodePoolAutoCreation:
enabled: true
priorities:
- location:
zones:
- asia-southeast1-a
machineType: n4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-a
machineType: c4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-c
machineType: n4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-c
machineType: c4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-b
machineType: n4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-b
machineType: c4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
whenUnsatisfiable: DoNotScaleUp
@@ -0,0 +1,72 @@
apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
name: contour-external-cc
spec:
nodePoolConfig:
serviceAccount: sa-common-np-cntr-prd@meesho-central-prd-0622.iam.gserviceaccount.com
nodeLabels:
dedicated: contour-external-cc
priorityDefaults:
location:
zones: ['asia-southeast1-a']
activeMigration:
optimizeRulePriority: true
nodePoolAutoCreation:
enabled: true
priorities:
- location:
zones:
- asia-southeast1-a
machineType: n4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-a
machineType: c4d-highcpu-8
spot: false
maxPodsPerNode: 16
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-a
machineType: n2d-highcpu-8
spot: false
maxPodsPerNode: 16
storage:
bootDiskSize: 30
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-c
machineType: n4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-c
machineType: c4d-highcpu-8
spot: false
maxPodsPerNode: 16
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-b
machineType: n4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
whenUnsatisfiable: DoNotScaleUp
@@ -0,0 +1,72 @@
apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
name: contour-internal-0-arm
spec:
nodePoolConfig:
serviceAccount: sa-common-np-cntr-prd@meesho-central-prd-0622.iam.gserviceaccount.com
nodeLabels:
dedicated: contour-internal-0-arm
priorityDefaults:
location:
zones: ['asia-southeast1-a']
activeMigration:
optimizeRulePriority: true
nodePoolAutoCreation:
enabled: true
priorities:
- location:
zones:
- asia-southeast1-a
machineType: n4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-a
machineType: c4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-c
machineType: n4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-c
machineType: c4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-b
machineType: n4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-b
machineType: c4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
whenUnsatisfiable: DoNotScaleUp
@@ -0,0 +1,45 @@
apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
name: contour-internal-0-cc
spec:
nodePoolConfig:
serviceAccount: sa-common-np-cntr-prd@meesho-central-prd-0622.iam.gserviceaccount.com
nodeLabels:
dedicated: contour-internal-0-cc
priorityDefaults:
location:
zones: ['asia-southeast1-a']
activeMigration:
optimizeRulePriority: true
nodePoolAutoCreation:
enabled: true
priorities:
- location:
zones:
- asia-southeast1-a
machineType: n4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-c
machineType: n4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-b
machineType: n4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
whenUnsatisfiable: DoNotScaleUp
@@ -0,0 +1,72 @@
apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
name: contour-internal-1-arm
spec:
nodePoolConfig:
serviceAccount: sa-common-np-cntr-prd@meesho-central-prd-0622.iam.gserviceaccount.com
nodeLabels:
dedicated: contour-internal-1-arm
priorityDefaults:
location:
zones: ['asia-southeast1-a']
activeMigration:
optimizeRulePriority: true
nodePoolAutoCreation:
enabled: true
priorities:
- location:
zones:
- asia-southeast1-a
machineType: n4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-a
machineType: c4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-c
machineType: n4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-c
machineType: c4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-b
machineType: n4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-b
machineType: c4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
whenUnsatisfiable: DoNotScaleUp
@@ -0,0 +1,72 @@
apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
name: contour-internal-1-cc
spec:
nodePoolConfig:
serviceAccount: sa-common-np-cntr-prd@meesho-central-prd-0622.iam.gserviceaccount.com
nodeLabels:
dedicated: contour-internal-1-cc
priorityDefaults:
location:
zones: ['asia-southeast1-a']
activeMigration:
optimizeRulePriority: true
nodePoolAutoCreation:
enabled: true
priorities:
- location:
zones:
- asia-southeast1-a
machineType: n4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-a
machineType: c4d-highcpu-8
spot: false
maxPodsPerNode: 16
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-a
machineType: n2d-highcpu-8
spot: false
maxPodsPerNode: 16
storage:
bootDiskSize: 30
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-c
machineType: n4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-c
machineType: c4d-highcpu-8
spot: false
maxPodsPerNode: 16
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-b
machineType: n4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
whenUnsatisfiable: DoNotScaleUp
@@ -0,0 +1,72 @@
apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
name: contour-intra-0-arm
spec:
nodePoolConfig:
serviceAccount: sa-common-np-cntr-prd@meesho-central-prd-0622.iam.gserviceaccount.com
nodeLabels:
dedicated: contour-intra-0-arm
priorityDefaults:
location:
zones: ['asia-southeast1-a']
activeMigration:
optimizeRulePriority: true
nodePoolAutoCreation:
enabled: true
priorities:
- location:
zones:
- asia-southeast1-a
machineType: n4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-a
machineType: c4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-c
machineType: n4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-c
machineType: c4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-b
machineType: n4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-b
machineType: c4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
whenUnsatisfiable: DoNotScaleUp
@@ -0,0 +1,72 @@
apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
name: contour-intra-0-cc
spec:
nodePoolConfig:
serviceAccount: sa-common-np-cntr-prd@meesho-central-prd-0622.iam.gserviceaccount.com
nodeLabels:
dedicated: contour-intra-0-cc
priorityDefaults:
location:
zones: ['asia-southeast1-a']
activeMigration:
optimizeRulePriority: true
nodePoolAutoCreation:
enabled: true
priorities:
- location:
zones:
- asia-southeast1-a
machineType: n4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-a
machineType: c4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-c
machineType: n4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-c
machineType: c4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-b
machineType: n4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-b
machineType: c4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
whenUnsatisfiable: DoNotScaleUp
@@ -0,0 +1,72 @@
apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
name: contour-intra-1-arm
spec:
nodePoolConfig:
serviceAccount: sa-common-np-cntr-prd@meesho-central-prd-0622.iam.gserviceaccount.com
nodeLabels:
dedicated: contour-intra-1-arm
priorityDefaults:
location:
zones: ['asia-southeast1-a']
activeMigration:
optimizeRulePriority: true
nodePoolAutoCreation:
enabled: true
priorities:
- location:
zones:
- asia-southeast1-a
machineType: n4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-a
machineType: c4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-c
machineType: n4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-c
machineType: c4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-b
machineType: n4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-b
machineType: c4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
whenUnsatisfiable: DoNotScaleUp
@@ -0,0 +1,45 @@
apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
name: contour-intra-1-cc
spec:
nodePoolConfig:
serviceAccount: sa-common-np-cntr-prd@meesho-central-prd-0622.iam.gserviceaccount.com
nodeLabels:
dedicated: contour-intra-1-cc
priorityDefaults:
location:
zones: ['asia-southeast1-a']
activeMigration:
optimizeRulePriority: true
nodePoolAutoCreation:
enabled: true
priorities:
- location:
zones:
- asia-southeast1-a
machineType: n4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-c
machineType: n4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-b
machineType: n4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
whenUnsatisfiable: DoNotScaleUp
@@ -0,0 +1,72 @@
apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
name: contour-shared-arm
spec:
nodePoolConfig:
serviceAccount: sa-common-np-cntr-prd@meesho-central-prd-0622.iam.gserviceaccount.com
nodeLabels:
dedicated: contour-shared-arm
priorityDefaults:
location:
zones: ['asia-southeast1-a']
activeMigration:
optimizeRulePriority: true
nodePoolAutoCreation:
enabled: true
priorities:
- location:
zones:
- asia-southeast1-a
machineType: n4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-a
machineType: c4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-c
machineType: n4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-c
machineType: c4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-b
machineType: n4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-b
machineType: c4d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: hyperdisk-balanced
whenUnsatisfiable: DoNotScaleUp
@@ -0,0 +1,45 @@
apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
name: contour-shared-cc
spec:
nodePoolConfig:
serviceAccount: sa-common-np-cntr-prd@meesho-central-prd-0622.iam.gserviceaccount.com
nodeLabels:
dedicated: contour-shared-cc
priorityDefaults:
location:
zones: ['asia-southeast1-a']
activeMigration:
optimizeRulePriority: true
nodePoolAutoCreation:
enabled: true
priorities:
- location:
zones:
- asia-southeast1-a
machineType: n2d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-c
machineType: n2d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-b
machineType: n2d-highcpu-8
maxPodsPerNode: 16
spot: false
storage:
bootDiskSize: 30
bootDiskType: pd-ssd
whenUnsatisfiable: DoNotScaleUp
@@ -0,0 +1,45 @@
apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
name: devops-mcp
spec:
nodePoolConfig:
serviceAccount: sa-common-np-cntr-prd@meesho-central-prd-0622.iam.gserviceaccount.com
nodeLabels:
dedicated: devops-mcp
priorityDefaults:
location:
zones: ['asia-southeast1-a']
activeMigration:
optimizeRulePriority: true
nodePoolAutoCreation:
enabled: true
priorities:
- location:
zones:
- asia-southeast1-a
machineType: n2d-highcpu-4
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-c
machineType: n2d-highcpu-4
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-b
machineType: n2d-highcpu-4
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
whenUnsatisfiable: DoNotScaleUp
@@ -0,0 +1,45 @@
apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
name: gatekeeper
spec:
nodePoolConfig:
serviceAccount: sa-common-np-cntr-prd@meesho-central-prd-0622.iam.gserviceaccount.com
nodeLabels:
dedicated: gatekeeper
priorityDefaults:
location:
zones: ['asia-southeast1-a']
activeMigration:
optimizeRulePriority: true
nodePoolAutoCreation:
enabled: true
priorities:
- location:
zones:
- asia-southeast1-a
machineType: c3-highcpu-22
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-c
machineType: c3-highcpu-22
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-b
machineType: c3-highcpu-22
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
whenUnsatisfiable: DoNotScaleUp
@@ -0,0 +1,45 @@
apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
name: loghouse
spec:
nodePoolConfig:
serviceAccount: sa-common-np-cntr-prd@meesho-central-prd-0622.iam.gserviceaccount.com
nodeLabels:
dedicated: loghouse
priorityDefaults:
location:
zones: ['asia-southeast1-a']
activeMigration:
optimizeRulePriority: true
nodePoolAutoCreation:
enabled: true
priorities:
- location:
zones:
- asia-southeast1-a
machineType: c3d-highmem-8
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-c
machineType: c3d-highmem-8
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-b
machineType: c3d-highmem-8
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
whenUnsatisfiable: DoNotScaleUp
@@ -0,0 +1,72 @@
apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
name: megaduo
spec:
nodePoolConfig:
serviceAccount: sa-common-np-cntr-prd@meesho-central-prd-0622.iam.gserviceaccount.com
nodeLabels:
dedicated: megaduo
priorityDefaults:
location:
zones: ['asia-southeast1-a']
activeMigration:
optimizeRulePriority: true
nodePoolAutoCreation:
enabled: true
priorities:
- location:
zones:
- asia-southeast1-a
machineType: c3-highcpu-22
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-a
machineType: c4-highcpu-24
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-c
machineType: c3-highcpu-22
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-c
machineType: c4-highcpu-24
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-b
machineType: c3-highcpu-22
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-b
machineType: c4-highcpu-24
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: hyperdisk-balanced
whenUnsatisfiable: DoNotScaleUp
@@ -0,0 +1,72 @@
apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
name: megaduolite
spec:
nodePoolConfig:
serviceAccount: sa-common-np-cntr-prd@meesho-central-prd-0622.iam.gserviceaccount.com
nodeLabels:
dedicated: megaduolite
priorityDefaults:
location:
zones: ['asia-southeast1-a']
activeMigration:
optimizeRulePriority: true
nodePoolAutoCreation:
enabled: true
priorities:
- location:
zones:
- asia-southeast1-a
machineType: n4-standard-16
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-a
machineType: n2-standard-16
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-c
machineType: n4-standard-16
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-c
machineType: n2-standard-16
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-b
machineType: n4-standard-16
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-b
machineType: n2-standard-16
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
whenUnsatisfiable: DoNotScaleUp
@@ -0,0 +1,45 @@
apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
name: megaoctalite
spec:
nodePoolConfig:
serviceAccount: sa-common-np-cntr-prd@meesho-central-prd-0622.iam.gserviceaccount.com
nodeLabels:
dedicated: megaoctalite
priorityDefaults:
location:
zones: ['asia-southeast1-a']
activeMigration:
optimizeRulePriority: true
nodePoolAutoCreation:
enabled: true
priorities:
- location:
zones:
- asia-southeast1-a
machineType: n2-highmem-16
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-c
machineType: n2-highmem-16
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-b
machineType: n2-highmem-16
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
whenUnsatisfiable: DoNotScaleUp
@@ -0,0 +1,72 @@
apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
name: megatetra
spec:
nodePoolConfig:
serviceAccount: sa-common-np-cntr-prd@meesho-central-prd-0622.iam.gserviceaccount.com
nodeLabels:
dedicated: megatetra
priorityDefaults:
location:
zones: ['asia-southeast1-a']
activeMigration:
optimizeRulePriority: true
nodePoolAutoCreation:
enabled: true
priorities:
- location:
zones:
- asia-southeast1-a
machineType: n2-standard-16
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-a
machineType: c3-standard-22
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-c
machineType: n2-standard-16
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-c
machineType: c3-standard-22
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-b
machineType: n2-standard-16
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-b
machineType: c3-standard-22
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
whenUnsatisfiable: DoNotScaleUp
@@ -0,0 +1,72 @@
apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
name: megatetralite
spec:
nodePoolConfig:
serviceAccount: sa-common-np-cntr-prd@meesho-central-prd-0622.iam.gserviceaccount.com
nodeLabels:
dedicated: megatetralite
priorityDefaults:
location:
zones: ['asia-southeast1-a']
activeMigration:
optimizeRulePriority: true
nodePoolAutoCreation:
enabled: true
priorities:
- location:
zones:
- asia-southeast1-a
machineType: n4-standard-16
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-a
machineType: n2-standard-16
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-c
machineType: n4-standard-16
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-c
machineType: n2-standard-16
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-b
machineType: n4-standard-16
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-b
machineType: n2-standard-16
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
whenUnsatisfiable: DoNotScaleUp
@@ -0,0 +1,45 @@
apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
name: megauno
spec:
nodePoolConfig:
serviceAccount: sa-common-np-cntr-prd@meesho-central-prd-0622.iam.gserviceaccount.com
nodeLabels:
dedicated: megauno
priorityDefaults:
location:
zones: ['asia-southeast1-a']
activeMigration:
optimizeRulePriority: true
nodePoolAutoCreation:
enabled: true
priorities:
- location:
zones:
- asia-southeast1-a
machineType: n2-highcpu-32
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-c
machineType: n2-highcpu-32
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-b
machineType: n2-highcpu-32
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
whenUnsatisfiable: DoNotScaleUp
@@ -0,0 +1,45 @@
apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
name: megaunolite
spec:
nodePoolConfig:
serviceAccount: sa-common-np-cntr-prd@meesho-central-prd-0622.iam.gserviceaccount.com
nodeLabels:
dedicated: megaunolite
priorityDefaults:
location:
zones: ['asia-southeast1-a']
activeMigration:
optimizeRulePriority: true
nodePoolAutoCreation:
enabled: true
priorities:
- location:
zones:
- asia-southeast1-a
machineType: n2-highcpu-48
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-c
machineType: n2-highcpu-48
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-b
machineType: n2-highcpu-48
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
whenUnsatisfiable: DoNotScaleUp
@@ -0,0 +1,45 @@
apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
name: mlp-g2-standard-8
spec:
nodePoolConfig:
serviceAccount: sa-common-np-cntr-prd@meesho-central-prd-0622.iam.gserviceaccount.com
nodeLabels:
dedicated: mlp-g2-standard-8
priorityDefaults:
location:
zones: ['asia-southeast1-a']
activeMigration:
optimizeRulePriority: true
nodePoolAutoCreation:
enabled: true
priorities:
- location:
zones:
- asia-southeast1-a
machineType: g2-standard-8
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-c
machineType: g2-standard-8
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-b
machineType: g2-standard-8
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
whenUnsatisfiable: DoNotScaleUp
@@ -0,0 +1,45 @@
apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
name: sale-rescue
spec:
nodePoolConfig:
serviceAccount: sa-common-np-cntr-prd@meesho-central-prd-0622.iam.gserviceaccount.com
nodeLabels:
dedicated: sale-rescue
priorityDefaults:
location:
zones: ['asia-southeast1-a']
activeMigration:
optimizeRulePriority: true
nodePoolAutoCreation:
enabled: true
priorities:
- location:
zones:
- asia-southeast1-a
machineType: c3-standard-22
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-c
machineType: c3-standard-22
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-b
machineType: c3-standard-22
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
whenUnsatisfiable: DoNotScaleUp
@@ -0,0 +1,72 @@
apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
name: session-mgr
spec:
nodePoolConfig:
serviceAccount: sa-common-np-cntr-prd@meesho-central-prd-0622.iam.gserviceaccount.com
nodeLabels:
dedicated: session-mgr
priorityDefaults:
location:
zones: ['asia-southeast1-a']
activeMigration:
optimizeRulePriority: true
nodePoolAutoCreation:
enabled: true
priorities:
- location:
zones:
- asia-southeast1-a
machineType: c3d-highcpu-60
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-a
machineType: c3d-standard-60
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-c
machineType: c3d-highcpu-60
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-c
machineType: c3d-standard-60
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-b
machineType: c3d-highcpu-60
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-b
machineType: c3d-standard-60
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
whenUnsatisfiable: DoNotScaleUp
@@ -0,0 +1,45 @@
apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
name: sumoduo-c4d
spec:
nodePoolConfig:
serviceAccount: sa-common-np-cntr-prd@meesho-central-prd-0622.iam.gserviceaccount.com
nodeLabels:
dedicated: sumoduo-c4d
priorityDefaults:
location:
zones: ['asia-southeast1-a']
activeMigration:
optimizeRulePriority: true
nodePoolAutoCreation:
enabled: true
priorities:
- location:
zones:
- asia-southeast1-a
machineType: c4d-highcpu-8
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-c
machineType: c4d-highcpu-8
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-b
machineType: c4d-highcpu-8
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: hyperdisk-balanced
whenUnsatisfiable: DoNotScaleUp
@@ -0,0 +1,72 @@
apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
name: sumoduo
spec:
nodePoolConfig:
serviceAccount: sa-common-np-cntr-prd@meesho-central-prd-0622.iam.gserviceaccount.com
nodeLabels:
dedicated: sumoduo
priorityDefaults:
location:
zones: ['asia-southeast1-a']
activeMigration:
optimizeRulePriority: true
nodePoolAutoCreation:
enabled: true
priorities:
- location:
zones:
- asia-southeast1-a
machineType: n2d-highcpu-32
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-a
machineType: n2d-standard-32
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-a
machineType: n4d-highcpu-32
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-c
machineType: n2d-highcpu-32
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-c
machineType: n2d-standard-32
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-b
machineType: n2d-highcpu-32
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
whenUnsatisfiable: DoNotScaleUp
@@ -0,0 +1,45 @@
apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
name: sumoduolite
spec:
nodePoolConfig:
serviceAccount: sa-common-np-cntr-prd@meesho-central-prd-0622.iam.gserviceaccount.com
nodeLabels:
dedicated: sumoduolite
priorityDefaults:
location:
zones: ['asia-southeast1-a']
activeMigration:
optimizeRulePriority: true
nodePoolAutoCreation:
enabled: true
priorities:
- location:
zones:
- asia-southeast1-a
machineType: n2-custom-32-65536
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-c
machineType: n2-custom-32-65536
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-b
machineType: n2-custom-32-65536
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
whenUnsatisfiable: DoNotScaleUp
@@ -0,0 +1,45 @@
apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
name: sumotetra
spec:
nodePoolConfig:
serviceAccount: sa-common-np-cntr-prd@meesho-central-prd-0622.iam.gserviceaccount.com
nodeLabels:
dedicated: sumotetra
priorityDefaults:
location:
zones: ['asia-southeast1-a']
activeMigration:
optimizeRulePriority: true
nodePoolAutoCreation:
enabled: true
priorities:
- location:
zones:
- asia-southeast1-a
machineType: n2-standard-32
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-c
machineType: n2-standard-32
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-b
machineType: n2-standard-32
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
whenUnsatisfiable: DoNotScaleUp
@@ -0,0 +1,45 @@
apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
name: sumouno
spec:
nodePoolConfig:
serviceAccount: sa-common-np-cntr-prd@meesho-central-prd-0622.iam.gserviceaccount.com
nodeLabels:
dedicated: sumouno
priorityDefaults:
location:
zones: ['asia-southeast1-a']
activeMigration:
optimizeRulePriority: true
nodePoolAutoCreation:
enabled: true
priorities:
- location:
zones:
- asia-southeast1-a
machineType: n2-highcpu-48
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-c
machineType: n2-highcpu-48
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-b
machineType: n2-highcpu-48
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
whenUnsatisfiable: DoNotScaleUp
@@ -0,0 +1,45 @@
apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
name: sumounolite
spec:
nodePoolConfig:
serviceAccount: sa-common-np-cntr-prd@meesho-central-prd-0622.iam.gserviceaccount.com
nodeLabels:
dedicated: sumounolite
priorityDefaults:
location:
zones: ['asia-southeast1-a']
activeMigration:
optimizeRulePriority: true
nodePoolAutoCreation:
enabled: true
priorities:
- location:
zones:
- asia-southeast1-a
machineType: n2-highcpu-48
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-c
machineType: n2-highcpu-48
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-b
machineType: n2-highcpu-48
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
whenUnsatisfiable: DoNotScaleUp
@@ -0,0 +1,45 @@
apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
name: vmagent
spec:
nodePoolConfig:
serviceAccount: sa-common-np-cntr-prd@meesho-central-prd-0622.iam.gserviceaccount.com
nodeLabels:
dedicated: vmagent
priorityDefaults:
location:
zones: ['asia-southeast1-a']
activeMigration:
optimizeRulePriority: true
nodePoolAutoCreation:
enabled: true
priorities:
- location:
zones:
- asia-southeast1-a
machineType: n2-highcpu-16
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-c
machineType: n2-highcpu-16
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-b
machineType: n2-highcpu-16
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
whenUnsatisfiable: DoNotScaleUp
@@ -0,0 +1,45 @@
apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
name: vmagent-dr
spec:
nodePoolConfig:
serviceAccount: sa-common-np-cntr-prd@meesho-central-prd-0622.iam.gserviceaccount.com
nodeLabels:
dedicated: vmagent-dr
priorityDefaults:
location:
zones: ['asia-southeast1-a']
activeMigration:
optimizeRulePriority: true
nodePoolAutoCreation:
enabled: true
priorities:
- location:
zones:
- asia-southeast1-a
machineType: n2-highcpu-16
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-c
machineType: n2-highcpu-16
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
- location:
zones:
- asia-southeast1-b
machineType: n2-highcpu-16
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: pd-ssd
whenUnsatisfiable: DoNotScaleUp
@@ -0,0 +1,72 @@
apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
name: vmagent-mds
spec:
nodePoolConfig:
serviceAccount: sa-common-np-cntr-prd@meesho-central-prd-0622.iam.gserviceaccount.com
nodeLabels:
dedicated: vmagent-mds
priorityDefaults:
location:
zones: ['asia-southeast1-a']
activeMigration:
optimizeRulePriority: true
nodePoolAutoCreation:
enabled: true
priorities:
- location:
zones:
- asia-southeast1-a
machineType: n4-highcpu-32
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-a
machineType: n4-highcpu-16
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-c
machineType: n4-highcpu-32
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-c
machineType: n4-highcpu-16
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-b
machineType: n4-highcpu-32
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: hyperdisk-balanced
- location:
zones:
- asia-southeast1-b
machineType: n4-highcpu-16
maxPodsPerNode: 32
spot: false
storage:
bootDiskSize: 100
bootDiskType: hyperdisk-balanced
whenUnsatisfiable: DoNotScaleUp

Some files were not shown because too many files have changed in this diff Show More