Compare commits

..
22 Commits
Author SHA1 Message Date
Mukul SharmaandClaude Opus 5 c83d535b6a Say how ArgoCD is really bootstrapped on GKE
The header claimed a manual helm install of argocd-admin-prd; Terraform
installs it, as release argo-cd, before the Application takes over.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fn2kUxyYNY4ApytbLiGWeY
2026-09-17 18:05:05 +05:30
Mukul SharmaandClaude Opus 5 fb7db5aee6 Point comments at paths that still exist after the homelab overrides were removed
References to helm-overrides/k8s-admin-prd-ase1 now either name the
homelab repo that still has that folder, or point at the GKE equivalent
under gke-toolshed-prd-usc1. Comments only; no rendered values change.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fn2kUxyYNY4ApytbLiGWeY
2026-09-17 18:02:01 +05:30
Mukul SharmaandClaude Opus 5 360fbdab55 Remove homelab k8s-admin-prd-ase1 overrides from the GCP repo
Nothing on GKE reads them: ArgoCD's valueFiles point only at
helm-overrides/gke-toolshed-prd-usc1.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fn2kUxyYNY4ApytbLiGWeY
2026-09-17 15:30:49 +05:30
Mukul SharmaandClaude Opus 5 61bc4af1a0 Serve every tool on deployshed.com instead of nip.io
Harbor, Gitea, Argo CD, Jenkins, Vault, Grafana and vmui now answer on
their deployshed.com names alone. Each was already serving both while the
move was proved out; this removes the nip.io half.

The dual-hostname workarounds go with it. Jenkins' secondaryingress existed
only because its chart's primary ingress takes one hostName and a
certificate could not span both names — the real domain moves onto the
primary with jenkins-tls, which it already holds. Argo CD gets extraTls
rather than ingress.tls, because the boolean hardcodes secretName
argocd-server-tls and would request a second certificate for a name that
already has a valid one in argocd-deployshed-tls.

Harbor also changes in two ways beyond the hostname:

  - externalURL moves to https://harbor.infra.deployshed.com. Harbor hands
    this to docker clients in its own API responses and builds the push
    commands shown in its UI from it, so a stale value is what makes a
    correctly-configured registry still advertise the old address.

  - updateStrategy is now Recreate. Its jobservice and registry volumes are
    standard-rwo (ReadWriteOnce), and a RollingUpdate starts the new pod
    before the old one releases the disk, so the replacement hangs forever
    on Multi-Attach. The cluster was sitting in exactly that state, old pods
    serving while new ones stayed in ContainerCreating. The chart's own
    comment on this value recommends Recreate when RWM is unavailable. The
    cost is a brief outage during upgrades, which beats a rollout that
    cannot complete.

The private registry CA is not removed yet. Apps deployed before this move
recorded nip.io image references that only change when each is rebuilt, so
the old hostname stays served by a standalone Ingress until then.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LEsTefWWifp4ikvhHF5s6N
2026-09-17 09:31:26 +05:30
Mukul SharmaandClaude Opus 5 df3e0a41af Keep three days of metrics rather than seven
Disk, not memory. The volume sits at 1.4G of 2.9G at seven days, and every
extra day is charged against the project's shared 250GB SSD quota. Three
days still spans a weekend, which is the window that matters for working
out what happened to something overnight.

Worth being explicit about what this does not do, since it followed an
OOM-kill and could easily be mistaken for the fix: retention has no
bearing on the memory this needs. That tracks active time series and cache
size, neither of which depends on how long data is kept — which is why the
limit had to be raised rather than this lowered when it started
OOM-killing on restart. Lowering this now would not let that be undone.

The lever for memory, if it is ever needed, is scrape cardinality. Several
targets here emit more than forty labels per series, which VictoriaMetrics
warns about in its own log; dropping labels there reduces series count
directly, and with it the memory.

Old partitions are removed on VictoriaMetrics' own cycle rather than at
startup, so the disk figure falls over the following hours, not
immediately.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LEsTefWWifp4ikvhHF5s6N
2026-09-17 08:40:19 +05:30
Mukul SharmaandClaude Opus 5 f6c659dd4b Give VictoriaMetrics enough memory to restart
It had run for weeks at 128Mi/512Mi and then OOM-killed in a loop the
first time anything restarted it — exit 137 about fifty seconds after a
clean start, repeatedly. Nothing about its configuration had changed. The
dataset had grown to 3.14 billion rows, and the memory needed to resume
ingestion no longer fit in the limit.

That failure mode is worth naming: a long-lived pod can sit comfortably
past the limit it would need in order to start again, so the problem stays
invisible until something restarts it — here, an unrelated sync adding a
hostname. The limit was not wrong when it was written; it was outgrown.

Memory tracks active time series rather than disk, so shortening
retentionPeriod would not have helped — the same targets are scraped
either way, and several carry more than forty labels.

Affordable: memory requests across the three nodes sit at 62%, 18% and
47%. CPU is what is scarce here, and this costs none.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LEsTefWWifp4ikvhHF5s6N
2026-09-17 08:32:11 +05:30
Mukul SharmaandClaude Opus 5 f703f0b55a Serve the infra tools on the real domain as well as nip.io
Each of these now answers on <name>.infra.deployshed.com alongside the
nip.io name it already had. Both are kept on purpose: nothing that
currently references the old name breaks, and the new one can be proved
before anything depends on it. Removing nip.io is a separate step, and a
larger one, because Harbor's name is embedded in every running app's image
reference.

TLS covers the real domain only. Let's Encrypt cannot issue for nip.io —
it is not on the public suffix list and every *.nip.io certificate shares
one rate limit — so a tls block naming both would request one certificate
spanning them and receive nothing for either. Each tls block therefore
lists exactly the one new hostname, which is why they are written out
rather than derived from the host list beside them.

The charts disagree about how to express a second host, so each is done
the way its own chart supports:

  gitea, grafana, vault, victoria-metrics-single take host lists, so the
  new name joins the existing one on a single Ingress.

  jenkins' primary ingress accepts exactly one hostName, so the new name
  goes on secondaryingress — a whole second Ingress object at the same
  backend. paths must be set explicitly there; left at the chart's default
  of [] it renders zero routes and the hostname answers nothing.

  argo-cd takes extraHosts natively, but its ingress.tls is a boolean bound
  to one fixed secret covering every host at once. Turning it on would
  request a certificate including nip.io and fail, and there is no extraTls
  to scope it. So ArgoCD gains the hostname now and its certificate when
  nip.io goes.

Harbor is untouched here. It has no multi-host mechanism at all, so its
second hostname needs a standalone Ingress, and its externalURL is what
docker clients are handed — both deserve their own change rather than
riding along with a hostname tidy-up.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LEsTefWWifp4ikvhHF5s6N
2026-09-17 02:14:30 +05:30
Mukul SharmaandClaude Opus 5 73ddfd8534 Let Gitea call toolshed's webhook endpoint
Gitea refused every push notification with "webhook can only call allowed
HTTP servers": toolshed builds an app's webhook target from the hostname
the dashboard was browsed on, so an app registered through the public URL
gets a public target, and this cluster's allowlist only permitted private
ranges.

Adding that one hostname rather than reverting to the homelab's "*". The
difference matters: "*" would also permit the node metadata server, which
is why it was narrowed in the first place. This permits exactly one host,
our own load balancer.

It is a stopgap and labelled as one in the file. The callback now hairpins
out to the load balancer and back in, which is precisely what the
cluster-DNS rule exists to avoid. The real fix is a configurable webhook
base URL in toolshed pointing at
toolshed-api.toolshed.svc.cluster.local:8080; this entry should be removed
when that lands.

Verified in the render: the value reaches Gitea's inline config, and
Recreate, standard-rwo, sqlite and disabled registration are untouched.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LEsTefWWifp4ikvhHF5s6N
2026-09-13 09:25:39 +05:30
Mukul SharmaandClaude Opus 5 41dd021d06 Upgrade Argo CD to chart 10.8.4 (v3.5.2)
Removes the cause of the diff failures that ServerSideDiff worked around:
v2.13.8 diffs against a Kubernetes schema compiled into its own binary,
and this cluster is newer than that schema.

Three things needed real changes, none of them mechanical:

- applicationSet.enabled no longer exists, and there is no replacement
  gate — unlike dex and notifications, the ApplicationSet controller's
  Deployment carries no conditional at all. Helm ignores unknown keys, so
  carrying the old value forward would have quietly started a controller
  nothing here uses. replicas: 0 is the only lever.

- The image tag pin is dropped rather than moved to v3.5.2. The chart's
  appVersion governs, so image and chart cannot drift; a pin outliving its
  chart is close to the failure being fixed here.

- server.insecure moved from server.extraArgs to configs.params, which is
  what the chart renders into argocd-cmd-params-cm. Caught by rendering:
  an earlier version of this commit deleted the extra arg on the strength
  of a comment claiming configs.params already set it, which it did not —
  Argo CD would have served its own TLS behind Contour and produced a
  redirect loop.

Verified in the rendered output: image v3.5.2 and no v2.13.8 anywhere,
server.insecure true, dex and notifications absent, ApplicationSet at zero
replicas, both HPAs intact with replicas omitted, ingress on Contour, repo
Secrets on cluster DNS.

Behaviour changes in v3 that apply here, none needing a values change:
logs RBAC is now enforced (jenkins-ci only syncs), update/delete no longer
inherit to sub-resources, and resource tracking moves from labels to
annotations, so the first sync re-stamps every managed resource.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LEsTefWWifp4ikvhHF5s6N
2026-09-12 15:24:49 +05:30
Mukul SharmaandClaude Opus 5 f83cedca65 GKE: values for the remaining homelab tools
Ports the rest of the homelab's stack: external-secrets, harbor, jenkins,
postgresql, redis, victoria-metrics-single, vmagent, node-exporter and
grafana. All nine verified with helm template.

Most are the homelab's values with storage moved from local-path to
standard-rwo and hostnames rebuilt on the reserved ingress IP. vmagent and
node-exporter are unchanged outright — everything in them is addressed by
cluster DNS, namespace or container port, none of which differs here.

Harbor is the substantial one. The homelab serves it over plain HTTP and
makes containerd accept that by hand-editing hosts.toml on the node; GKE
nodes are managed and replaced, so that edit cannot survive. Instead the
node pool was told at creation to trust a private CA for exactly this
hostname, and cert-manager now signs Harbor's certificate from that same
CA via an ingress-shim annotation. certSource is "secret" rather than the
chart's "auto", which would self-sign a certificate nothing trusts.
externalURL moves to https to match, since Harbor hands that URL to docker
clients and a mismatch surfaces as registry errors.

Jenkins drops secondaryingress, which exists in the homelab only to serve
its Tailscale hostname. Its plugin pins are carried over deliberately: each
fixes a failure whose symptom points somewhere else, above all the
kubernetes/kubernetes-client-api pairing, without which agents never come
online and builds hang at "Still waiting to schedule task".

Postgres and Redis keep the homelab's deliberately small memory settings.
Those were chosen for an 8GB node under pressure, and while this cluster
has room, a bigger cache buys nothing for a handful of small tools.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LEsTefWWifp4ikvhHF5s6N
2026-09-12 15:01:49 +05:30
Mukul SharmaandClaude Opus 5 63c243ce51 GKE: Vault values, auto-unsealing from Cloud KMS
Same chart (0.34.1) and same shape as the homelab — production mode,
file storage, standalone, no HA, injector off — with one substantial
difference: this Vault unseals itself.

The homelab unseals with 3 of 5 Shamir keys after every restart, which
was fine on an always-on VM. These nodes are spot and can be reclaimed
at any hour, and a sealed Vault means every secret in the cluster is
unavailable until someone notices. The trade is named rather than
buried: unsealing now depends on GCP IAM rather than on people holding
key shares.

The seal stanza's values come from terraform output vault_seal, so
Terraform and this file cannot disagree about which key is used, and no
credential appears in either: the pod authenticates to KMS as its
Workload Identity. That binding names exactly vault/vault, so
serviceAccount.name is pinned and the GSA annotation set — miss either
and Vault starts, fails to reach KMS, and stays sealed with an error
that never mentions Workload Identity.

Verified against the live project: the rendered seal block matches the
existing key ring and key, which grant encrypt/decrypt to that service
account and nothing else.

Storage is 10Gi on standard-rwo. The homelab's 5Gi exists only because
local-path cannot expand a bound volume; this class can.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LEsTefWWifp4ikvhHF5s6N
2026-09-12 14:23:17 +05:30
Mukul SharmaandClaude Opus 5 cdc6d9167c GKE: Contour values, exposed by LoadBalancer on the reserved IP
The homelab binds Envoy to node ports 80/443 with hostPort, because
VMware bridging over Wi-Fi never made a LoadBalancer IP reachable
(claude.md issue #6). Here it is a real cloud load balancer, and since
the nodes have no public IPs it is the single inbound path to the
cluster.

envoy.service.loadBalancerIP pins it to the address Terraform reserved,
which is what makes DNS work: every hostname here is
<name>.35.238.248.203.nip.io, so an unpinned Service would take a fresh
ephemeral address and point every hostname at nothing.

That field is deprecated upstream (Kubernetes 1.24). GKE's replacement
annotation is not a drop-in — it takes the address resource's name, and
on an external Service also requires spec.loadBalancerClass:
networking.gke.io/l4-regional-external, changing which controller
programs the load balancer. GKE still honours the field, so this is the
smaller change.

contour.ingressClass.name is pinned to "contour" because every Ingress
in this cluster names that class; the chart default derives a name from
the release instead. Envoy stays a DaemonSet, which is what makes the
chart's default externalTrafficPolicy: Local (real client IPs) correct.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LEsTefWWifp4ikvhHF5s6N
2026-09-12 13:43:27 +05:30
Mukul SharmaandClaude Opus 5 66c30cfaf4 GKE: values for gitea, argocd and cert-manager on gke-toolshed-prd-usc1
A new cluster directory rather than edits to k8s-admin-prd-ase1, so no
homelab value is ever reused for GCP by accident. Charts are the ones
already vendored here (gitea 12.7.0, argo-cd 7.7.23, cert-manager
v1.20.1); only the values are new. Verified with helm template.

What differs from the homelab, and why:

- gitea: storageClass standard-rwo, and Recreate for a different reason
  than the homelab's LevelDB lock — three nodes and a ReadWriteOnce disk
  mean a rolling update's new pod waits forever on Multi-Attach. The
  admin password comes from a Secret created at bootstrap instead of the
  chart's published default, which would otherwise be live on a public
  IP. Registration is disabled and webhooks are limited to private
  ranges, for the same reason.
- argocd: single ingress host (no Tailscale), and the homelab's Ingress
  health override is dropped, since Contour writes real load balancer
  status here. server and repoServer autoscale 1-3 on CPU; the chart
  omits replicas when autoscaling is on, so the HPA and ArgoCD's own
  self-management do not fight over the count. Memory is deliberately
  not a scaling metric: Go does not return memory promptly, so a memory
  target scales up and never back down.
- cert-manager: written fresh, not copied. The homelab file was never
  adapted from the fleet — it pulls from a private Meesho registry and
  pins pods to a node pool that does not exist here. The chart's own
  values.yaml carries that registry too, so imageRegistry and
  imageNamespace are overridden back to upstream's quay.io/jetstack.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LEsTefWWifp4ikvhHF5s6N
2026-09-12 13:16:11 +05:30
mukul 91550dd640 Merge pull request 'Add a Redis chart for toolshed's managed cache add-on' (#1) from add-redis-chart into main
Reviewed-on: http://gitea.100.90.248.118.nip.io/mukul/devops-infra-helm-charts/pulls/1
2026-09-09 07:30:04 +00:00
Mukul SharmaandClaude Opus 5 76b4ddd2de Add a Redis chart for toolshed's managed cache add-on
toolshed provisions a per-app Redis ACL user, scoped to its own key
prefix, on request (internal/dbprovision.EnsureRedisUser). Nothing in this
cluster ran Redis — Harbor's internal one is Harbor's and is not ACL
configured — so there was nowhere for that to point.

Hand-written rather than vendoring Bitnami's, same reasoning as the
sibling postgresql chart: Broadcom has been retiring and freezing images
behind that repo (infra issue #4, where it broke Contour twice), and Redis
publishes no official chart either.

The authentication design is the part worth reading before changing
anything. Redis is started with an ACL file and NO requirepass, and that
distinction is a security property rather than a style choice:

- toolshed persists provisioned users with ACL SAVE, which requires an
  aclfile. Without it every provisioned user is lost on the next restart.
- But ACL SAVE also serialises the default user. With requirepass, the
  saved entry comes back as `user default on nopass ~* &* +@all`, and
  after the next restart the ACL file wins — leaving Redis open to
  UNAUTHENTICATED access with full permissions. Verified directly: with
  requirepass, the restarted server answered an unauthenticated PING with
  PONG and served a key.

So the default user is defined in the ACL file instead, seeded once by an
init container that deliberately never overwrites an existing file —
overwriting would delete every user toolshed had provisioned into it,
reintroducing the same lockout from the other end. The documented
consequence is that rotating the admin password in Vault does not
propagate on its own; that needs ACL SETUSER default + ACL SAVE against
the running server.

Sized for a node at its ceiling: 32Mi requested, 96Mi limit, maxmemory
48mb. The limit sits above maxmemory on purpose, so Redis reaches its own
eviction policy rather than being OOM-killed, which would lose the whole
instance instead of the coldest keys. Snapshotting is off — what must
survive a restart is the ACL file, which ACL SAVE writes independently of
RDB, and cached values are by definition reconstructible.

allkeys-lru because this backs a connection kind called "cache" and
eviction under pressure is that contract; values.yaml says plainly that an
app using Redis as its only copy of something wants noeviction instead.

Verified: helm template, then a real deploy to a k3d cluster — provisioned
users through toolshed's own code, deleted the pod, and confirmed all five
came back with their key patterns intact, the init container declined to
overwrite, unauthenticated access got NOAUTH, and a user writing outside
its prefix got NOPERM.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wajog7nELA3i8JWTjxYGHF
2026-09-09 12:35:02 +05:30
Mukul SharmaandClaude Opus 5 0c68312765 Homelab Overview dashboard: envoy RPS, per-namespace CPU/mem, cluster utilization, totals
Provisioned rather than built by hand in Grafana's UI — same reasoning
as the datasource: survives a pod restart, and a git diff shows what
changed. Four rows: ingress (Envoy total RPS + connections + response
class breakdown), service level (CPU/memory by namespace, filterable
via a $namespace template variable, plus a current-usage table), cluster
utilization (used vs actual node capacity, not an assumed limit), and
total resources (cores/memory/pods/disk).

Two scrape gaps found and fixed to make this possible, both in vmagent:

- Contour's own ingress Envoy (projectcontour namespace — the actual
  data plane for everything routed through this homelab, hostPort
  80/443) was not being scraped at all. Confirmed live: Cilium's
  separate embedded Envoy (kube-system, its own L7 policy proxy) was
  already flowing, via the annotation-based kubernetes-pods job — which
  is what first showed envoy_* metrics existed in this cluster at all —
  but Contour's Envoy carries no such annotation. Added an explicit job
  targeting the projectcontour namespace by container port (8002, the
  official chart's fixed Envoy metrics port) rather than guessing at
  pod labels this cluster's auto-detected object names may not match.

- node-exporter, deployed two commits ago, was never actually being
  scraped either: confirmed live that kubernetes-service-endpoints
  (role: endpointslice, keyed on the Service's scrape annotation — where
  that chart puts it) finds nothing in this cluster at all, not merely
  down. Rather than chase why, added the same fix as Envoy: target the
  pod directly by its declared container port (9100).

Verified against the live deployment (queried through vmui) before
writing a single panel: envoy_http_downstream_rq_total,
envoy_http_downstream_rq_xx, container_cpu_usage_seconds_total,
container_memory_working_set_bytes, machine_cpu_cores and
machine_memory_bytes all confirmed present with real data. The one
exception is the "Disk free" panel, which depends on the node-exporter
scrape fix landing in this same change — noted in the values file's own
comment as unverified until it actually deploys.

Also verified with `helm template`: the dashboard JSON round-trips
through the YAML values file and the chart's own ConfigMap templating
intact (19 panels both times), and vmagent's scrape_configs list still
carries all 8 chart defaults plus both new jobs — nothing lost by using
extraScrapeConfigs instead of overriding the full list by hand.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wajog7nELA3i8JWTjxYGHF
2026-09-06 09:45:46 +05:30
Mukul SharmaandClaude Opus 5 baff705eee Add Grafana; expose VictoriaMetrics' own vmui UI
Grafana: real dashboards over VictoriaMetrics. Provisioned rather than
clicked through: a VictoriaMetrics datasource (type: prometheus — VM
speaks that query API, which is the whole point of it existing) is
baked into the chart's own datasource-provisioning config, so a fresh
install has it working with no manual setup. Admin credentials from
Vault via ExternalSecret (secretstores/grafana-admin-credentials.yaml
in devops-infra-argo-config), same pattern as every other admin
credential in this project — never plaintext in this repo. 1Gi
local-path PVC for dashboards/Grafana's own state (VictoriaMetrics
holds the actual metric data, not this). Dual LAN+Tailscale Ingress
hosts, same convention as everything externally reachable here.

Found and fixed while vendoring: helm-templates/grafana already held a
fully-vendored old Grafana chart (v6.58.7, appVersion 10.0.3) from the
original Meesho monorepo import (commit b8575bb) — generic production
config (fullnameOverride: grafana-infra-prd, GKE-shaped RBAC/PSP
defaults) unrelated to this homelab, same class of leftover as
victoria-metrics-single's collision two commits ago. Removed and
re-vendored fresh (10.5.15) as a thin wrapper, matching every other
official-chart component in this repo now.

vmui: VictoriaMetrics' own built-in UI (ad-hoc PromQL + graphs, no
saved dashboards — what Grafana is for) is served on the same
pod/port, so exposing it cost one ingress block on the
victoria-metrics-single values already committed. No new component,
no new RAM.

Verified with `helm template` against the real charts for both
components individually (Grafana: admin env vars correctly reference
the ExternalSecret's keys, datasource ConfigMap renders the intended
VictoriaMetrics URL, PVC/resources/ingress hosts all match; vmui:
ingress renders both hostnames pointing at the existing Service's named
http port) and again for the whole generic-argo-apps-chart appSpec
list — 12 Applications render, including grafana.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wajog7nELA3i8JWTjxYGHF
2026-09-06 08:57:22 +05:30
Mukul SharmaandClaude Opus 5 04e7ef2f82 Replace Prometheus with VictoriaMetrics (victoria-metrics-single + vmagent)
Lower RAM/disk for the same metric volume on an 8GB single node — VM's
own compression is the entire reason it exists as a project. Speaks
Prometheus's own query API (/api/v1/query), so nothing downstream
needed to change beyond the URL it points at: same PromQL, same
kubernetes-nodes-cadvisor-sourced container_cpu_usage_seconds_total /
container_memory_working_set_bytes toolshed's metrics work
(docs/PRODUCT-ARCHITECTURE.md step 5) already targets.

Three releases, matching the one-release-per-component convention
already used everywhere in this repo, since victoria-metrics-single has
no bundled scraper/exporter subcharts the way the Prometheus chart did:

- victoria-metrics-single: the TSDB + query engine. 3Gi/local-path,
  7-day retention, resources capped at 512Mi — same trim reasoning as
  the Prometheus server it replaces.
- vmagent: the scraper. Its default scrape_configs already includes
  kubernetes-nodes-cadvisor and kubernetes-service-endpoints (the
  chart's own comment says "COPY from Prometheus helm chart") — nothing
  to override there, only remoteWrite pointed at victoria-metrics-single
  and trimmed resources.
- node-exporter: pulled out of the removed Prometheus chart's bundled
  subchart into its own standalone release, since victoria-metrics-single
  has no equivalent. Same trim as before (32Mi/64Mi), same
  prometheus.io/scrape annotation vmagent's default scrape config
  already looks for.

Found and fixed while vendoring: helm-templates/victoria-metrics-single
already existed in this repo — a leftover GKE-targeted vendored copy
from the original Meesho monorepo import (commit b8575bb), with its own
templates/values.yaml for a different chart entirely. `mkdir -p` on an
already-existing directory silently did nothing, so the first vendoring
attempt left that old tree sitting alongside the new one and rendered
two ServiceAccounts/Services/StatefulSets with colliding names. Removed
outright rather than adapted, same reasoning as the ~35 charts
devops-helm-charts removed in its own prune — see this chart's own
Chart.yaml for the full note.

Verified with `helm template` against the real charts and these values
for all three releases individually, and again for the whole
generic-argo-apps-chart appSpec list (11 Applications render, including
the three new ones and nothing orphaned from the old prometheus entry).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wajog7nELA3i8JWTjxYGHF
2026-09-06 08:38:34 +05:30
Mukul SharmaandClaude Opus 5 6677c9e315 prometheus: turn on node-exporter for host-level metrics
The other three disabled subcharts (alertmanager/kube-state-metrics/
pushgateway) stay off — none of them do anything cAdvisor's per-container
metrics don't already cover for this deployment's actual purpose.
node-exporter is different: it's the one thing here that would report on
the node itself (disk, memory, load) rather than any particular
container, which matters on an 8GB single node already near its ceiling.

One DaemonSet pod, hostNetwork rather than a Service, resources capped
at 32Mi/64Mi — light enough that turning it on doesn't meaningfully
touch the budget the other three would have.

Verified with `helm template`: the DaemonSet renders with hostNetwork/
hostPID true and the trimmed resources, and its Service carries the
`prometheus.io/scrape: true` annotation the server's already-enabled
kubernetes-service-endpoints job picks up automatically — no separate
scrape config needed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wajog7nELA3i8JWTjxYGHF
2026-09-06 07:56:22 +05:30
Mukul SharmaandClaude Opus 5 6321533c47 Add Prometheus: server only, vendored official chart
Vendored prometheus-community/prometheus 29.27.1 the same way
Contour/ArgoCD/Vault/Gitea/Harbor/Jenkins already are here — a thin
Chart.yaml dependency plus a committed .tgz — rather than hand-written
like postgresql, which has no official chart to vendor.

Server only: alertmanager, kube-state-metrics, prometheus-node-exporter
and prometheus-pushgateway are all enabled by default in this chart and
all disabled here. None are needed for what actually consumes this —
toolshed's per-app CPU/memory metrics read straight from the chart's
built-in kubernetes-nodes-cadvisor scrape job (kubelet's own cAdvisor
endpoint) — and each is its own pod on a node that was already at its
8GB ceiling before this.

Trimmed for the same ceiling: 3Gi PVC on local-path (not the chart's
8Gi default), 7-day retention (not 15), resources capped at 512Mi.

nameOverride pinned to exactly "prometheus" matters more here than for
any other component pinning it: the chart's server Service renders as
"<release-name>-server", so this is what makes it "prometheus-server"
— the exact hostname toolshed's PROMETHEUS_URL was already seeded to
point at, before this existed, so the connection is already correct
the day this deploys.

Verified with `helm template` against the real chart and these values:
server-only object set (ClusterRole, ClusterRoleBinding, ConfigMap,
Deployment, PVC, Service, ServiceAccount — nothing from the four
disabled subcharts), and the rendered PVC/retention/resources/Service
name all match what's written above.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wajog7nELA3i8JWTjxYGHF
2026-09-06 07:30:32 +05:30
Mukul Sharma d4bb8985fb Add a hand-written PostgreSQL chart for toolshed
Not Bitnami's: that registry has been actively unstable here (it broke
Contour twice, infra issue #4) and PostgreSQL publishes no official chart.
A single StatefulSet, PVC and Service is small enough that owning it costs
less than depending on an unstable repackage.

Credentials come from an existing Secret rather than being generated by
the chart — a chart that generates its own password regenerates it on
every render and silently locks you out of the existing volume.

Details that matter and are easy to get wrong:
  - PGDATA is a subdirectory of the mount, not the mount itself. initdb
    refuses to run in a directory that already has contents.
  - Probes run through a shell. Kubernetes does not expand $(VAR) inside
    exec probe commands, only in command/args.
  - fsGroup 70 so the volume stays writable after the entrypoint drops
    from root to the postgres user on the Alpine variant.
  - shared_buffers cut to 32MB from PostgreSQL's 128MB default. The node
    has 8GB and was at its ceiling before this.

Verified with helm template.
2026-09-04 16:21:26 +05:30
Mukul Sharma 5d4d3d44e5 Scope jenkins-ci RBAC to the whole webapp project, not one app
Was hardcoded to webapp/demo-go-app — any future app added to this
project needed its own policy line. Wildcarding to webapp/* means any
app onboarded into that project (project: webapp in its Application
manifest) is automatically covered, no RBAC change needed per app.
Platform-level apps on the default project are unaffected.
2026-09-03 06:36:04 +05:30
222 changed files with 1865 additions and 33568 deletions
@@ -0,0 +1,165 @@
argo-cd:
# GKE counterpart of the homelab's argocd-admin-prd override
# (k8s-admin-prd-ase1, in the homelab devops-infra-helm-charts repo).
#
# Bootstrapped by Terraform, not by hand: toolshed-gke-infra's
# envs/prod/20-bootstrap/argocd.tf installs the upstream argo-cd chart
# directly (release "argo-cd", namespace "argocd") with its own inline
# values. After that, ArgoCD manages itself through the argocd Application
# in devops-infra-argo-config-gcp (nameOverride "argocd-admin-prd"), which
# renders this wrapper chart with the values in this file.
# Deliberately no image tag pin, unlike the homelab: the chart's own
# appVersion (v3.5.2) governs, so the image cannot drift from the chart.
# A pin that outlives its chart is close to the failure this upgrade
# fixes — software older than the cluster it manages.
#
# Upgraded from chart 7.7.23 / Argo CD v2.13.8. Three v3 behaviour changes
# apply to this deployment, none of which needs a values change today:
# - logs RBAC is now enforced, so an account that reads pod logs needs
# an explicit `logs, get` policy. jenkins-ci below only syncs.
# - update/delete no longer inherit to an application's sub-resources.
# - resource tracking moves from labels to annotations, so the first
# sync after the upgrade re-stamps every managed resource.
# SSO still deferred, same as the homelab.
dex:
enabled: false
controller:
replicas: 1
resources:
requests:
cpu: 200m
memory: 400Mi
limits:
cpu: 500m
memory: 768Mi
redis-ha:
enabled: false
redis:
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
memory: 128Mi
# repo-server does the manifest rendering (helm template per Application),
# so it is the component that actually saturates when many apps sync at
# once. Stateless, safe to run several behind its Service. With
# autoscaling on, the chart omits `replicas` from the Deployment, so the
# HPA and ArgoCD's own self-management do not fight over the count.
#
# CPU only. The chart's default also scales on memory, but a Go process
# does not hand memory back promptly after a spike, so a memory target
# scales up and then never scales down. Setting it to null removes it.
repoServer:
autoscaling:
enabled: true
minReplicas: 1
maxReplicas: 3
targetCPUUtilizationPercentage: 70
targetMemoryUtilizationPercentage: null
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: 300m
memory: 512Mi
# API/UI. Stateless, sessions live in Redis, so replicas are
# interchangeable. Same CPU-only reasoning as repoServer above.
server:
autoscaling:
enabled: true
minReplicas: 1
maxReplicas: 3
targetCPUUtilizationPercentage: 70
targetMemoryUtilizationPercentage: null
# --insecure is NOT set here as an extra arg: configs.params below
# carries server.insecure, which is the supported way to express it and
# is what the chart renders into argocd-cmd-params-cm. Setting both
# works but leaves two places to disagree.
ingress:
enabled: true
ingressClassName: contour
hostname: "argocd.infra.deployshed.com"
# TLS via extraTls rather than the `tls: true` boolean, deliberately.
#
# The boolean hardcodes `secretName: argocd-server-tls` (see the
# chart's argocd-server/ingress.yaml). This deployment already holds a
# valid, issued certificate for this exact hostname in
# argocd-deployshed-tls, created by the standalone Ingress that served
# the real domain while nip.io was still on `hostname`. Flipping the
# boolean would ignore that and request a second certificate for the
# same name — a needless issuance and a gap while it is obtained.
#
# extraTls takes an explicit secretName, so the existing certificate is
# adopted as-is and the standalone Ingress can simply be deleted.
extraTls:
- hosts:
- argocd.infra.deployshed.com
secretName: argocd-deployshed-tls
resources:
requests:
cpu: 50m
memory: 128Mi
limits:
cpu: 200m
memory: 256Mi
# applicationSet.enabled no longer exists in this chart, and there is no
# replacement: unlike dex and notifications below, the ApplicationSet
# controller's Deployment has no conditional at all. replicas: 0 is the
# only lever — the Deployment exists but runs nothing. Carrying the old
# `enabled: false` forward would have quietly started the controller,
# since Helm ignores unknown keys.
#
# Nothing here uses the ApplicationSet CRD; Applications are rendered by
# generic-argo-apps-chart instead.
applicationSet:
replicas: 0
notifications:
enabled: false
configs:
# Contour terminates TLS in front of Argo CD; leaving Argo CD's own TLS
# on as well produces a redirect loop. This renders into
# argocd-cmd-params-cm, which the server actually reads.
#
# This file previously expressed it as server.extraArgs: [--insecure],
# inherited from the homelab. Both work, but only one should exist, and
# the rendered ConfigMap is the thing to check when it looks wrong.
params:
server.insecure: true
cm:
# https now that the only hostname served carries a real certificate.
# This is what ArgoCD builds its own links from, so leaving it http
# would hand out plain-HTTP URLs for a TLS-only deployment.
url: "https://argocd.infra.deployshed.com"
timeout.reconciliation: 3m
timeout.reconciliation.jitter: 60s
# No Ingress health override, unlike the homelab: there Contour sat
# behind hostPort, so nothing ever wrote an Ingress's load balancer
# status. On GKE Envoy gets a real LoadBalancer Service and Contour
# writes that status, so ArgoCD's built-in check works as intended.
#
# Scoped account for Jenkins' syncArgoApp step — same as the homelab.
accounts.jenkins-ci: apiKey
accounts.jenkins-ci.enabled: "true"
rbac:
policy.csv: |
p, jenkins-ci, applications, sync, webapp/*, allow
p, jenkins-ci, applications, get, webapp/*, allow
# Reached over cluster DNS, never through Contour — which is what lets
# Contour itself be ArgoCD-managed. The repos are private on this
# public-facing Gitea, so ArgoCD reads them with a repo-creds Secret
# (created at bootstrap, covering everything under gitadmin/), not
# anonymously as in the homelab.
repositories:
devops-infra-helm-charts-gcp:
url: http://gitea-http.gitea.svc.cluster.local:3000/gitadmin/devops-infra-helm-charts-gcp.git
devops-infra-argo-config-gcp:
url: http://gitea-http.gitea.svc.cluster.local:3000/gitadmin/devops-infra-argo-config-gcp.git
@@ -0,0 +1,66 @@
# GKE values for the vendored cert-manager chart (helm-templates/cert-manager,
# v1.20.1). Written fresh rather than copied from the homelab's
# k8s-admin-prd-ase1 override, whose file was never adapted from the fleet: it pulls images from a private
# Meesho Artifact Registry and pins pods to a "dedicated: devops" node pool
# that does not exist here.
#
# Installed once by hand with `helm install cert-manager` (namespace
# "cert-manager"), then adopted by the cert-manager Application in
# devops-infra-argo-config-gcp.
#
# Its job here is Harbor's certificate, issued from the private registry CA
# that toolshed-gke-infra's 10-infra creates and the node pool trusts. The
# CA key pair reaches the cluster as the "registry-ca" Secret in this
# namespace (kubectl, from terraform output); the ClusterIssuer that uses it
# lives with Harbor's config, not here.
# The vendored chart's own values.yaml was edited in the fleet to pull every
# image from Meesho's private Artifact Registry, which these nodes cannot
# reach. Back to upstream's registry (quay.io/jetstack/cert-manager-*).
imageRegistry: quay.io
imageNamespace: jetstack
crds:
enabled: true
# A helm uninstall must not take every Certificate in the cluster with it.
keep: true
replicaCount: 1
resources:
requests:
cpu: 50m
memory: 96Mi
limits:
memory: 256Mi
webhook:
replicaCount: 1
resources:
requests:
cpu: 20m
memory: 48Mi
limits:
memory: 128Mi
cainjector:
enabled: true
replicaCount: 1
resources:
requests:
cpu: 20m
memory: 96Mi
limits:
memory: 256Mi
startupapicheck:
enabled: true
resources:
requests:
cpu: 10m
memory: 32Mi
limits:
memory: 64Mi
prometheus:
enabled: true
servicemonitor:
enabled: false
@@ -0,0 +1,70 @@
contour:
# GKE counterpart of the homelab's contour override (k8s-admin-prd-ase1,
# in the homelab devops-infra-helm-charts repo). Same official projectcontour chart (0.7.0, see helm-templates/contour), but
# exposed the opposite way.
#
# The homelab binds Envoy to node ports 80/443 with hostPort, because
# VMware bridging over Wi-Fi never made a LoadBalancer IP reachable
# (claude.md issue #6). None of that applies here: this is a real cloud
# load balancer on the reserved address, and it is the ONE inbound path
# into the cluster now that the nodes have no public IPs of their own.
contour:
replicaCount: 1
# Ingress objects across this cluster say `ingressClassName: contour`,
# so the class must be created under exactly that name. The chart's
# default is an empty string, which derives a name from the release.
ingressClass:
name: contour
create: true
default: true
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
memory: 192Mi
envoy:
# DaemonSet (the chart default): one Envoy per node, which pairs with
# externalTrafficPolicy: Local below — every node the load balancer can
# send to is running a proxy that can serve the request locally.
kind: daemonset
service:
type: LoadBalancer
# The reserved address from Terraform (module.network's
# google_compute_address). Every hostname in this deployment — the
# deployshed.com records, including the two wildcards — resolves here,
# so this pin is what makes DNS work at all: an unpinned Service takes
# a fresh ephemeral IP and every hostname points at nothing.
#
# More load-bearing now, not less, than when hostnames were
# <name>.35.238.248.203.nip.io. Those encoded the address, so a changed
# IP produced names that were merely wrong. Real DNS records point here
# until somebody edits them in Cloudflare, so a changed IP is an
# outage across every hostname at once.
#
# spec.loadBalancerIP is deprecated upstream (Kubernetes 1.24), and
# GKE's replacement is the annotation
# networking.gke.io/load-balancer-ip-addresses. That annotation is NOT
# a drop-in: it takes the address resource's NAME rather than the
# address, and on an external Service it also requires
# spec.loadBalancerClass: networking.gke.io/l4-regional-external,
# which changes which controller programs the load balancer. GKE still
# honours this field, so the deprecated-but-working one is the smaller
# change; revisit if a GKE upgrade ever stops honouring it.
loadBalancerIP: "35.238.248.203"
# Chart default, kept deliberately: preserves the real client IP
# instead of replacing it with a node's address. Valid here precisely
# because Envoy is a DaemonSet.
externalTrafficPolicy: Local
resources:
requests:
cpu: 50m
memory: 96Mi
limits:
memory: 256Mi
@@ -0,0 +1,42 @@
external-secrets:
# Same as the homelab's, which carries nothing cluster-specific: the
# controller is configured entirely by the ClusterSecretStore and
# ExternalSecret objects in devops-infra-argo-config-gcp, not by values.
#
# This is the piece every credential in the cluster hangs off — Harbor,
# Jenkins, Grafana and the pipeline all read their secrets from Vault
# through it, so it comes up before any of them.
#
# Two things must exist in Vault before the first ExternalSecret can sync,
# and neither is declarative: the KV v2 engine at secret/, and the
# Kubernetes auth method with a role bound to this controller's service
# account. Until then ExternalSecrets stay in a retry loop rather than
# failing outright.
#
# installCRDs defaults to true — kept, as on a fresh cluster there are no
# existing SecretStore/ExternalSecret CRs whose schema it could clobber.
#
# All three components default to unbounded resources; trimmed here for
# the same reason as everything else in this repo.
resources:
requests:
cpu: 25m
memory: 32Mi
limits:
memory: 128Mi
webhook:
resources:
requests:
cpu: 25m
memory: 32Mi
limits:
memory: 64Mi
certController:
resources:
requests:
cpu: 25m
memory: 32Mi
limits:
memory: 64Mi
@@ -0,0 +1,107 @@
gitea:
# GKE counterpart of the homelab's gitea override (k8s-admin-prd-ase1,
# in the homelab devops-infra-helm-charts repo) — same SQLite/no-cache
# shape, with what differs on GKE called out inline.
#
# Installed once by hand with `helm install gitea` (release "gitea",
# namespace "gitea"), then adopted by ArgoCD via the nameOverride in
# devops-infra-argo-config-gcp's values file. Gitea has to exist before
# ArgoCD can read anything, since both config repos live inside it.
# Recreate for a different reason than the homelab's LevelDB lock: on
# three nodes with a ReadWriteOnce persistent disk, the chart's default
# RollingUpdate (maxUnavailable: 0) starts the new pod first, and if it
# lands on another node it waits forever on Multi-Attach.
strategy:
type: Recreate
persistence:
size: 10Gi
# GKE's default class (pd-balanced), in place of the homelab's
# local-path. Counts against the project's 250GB SSD quota.
storageClass: standard-rwo
postgresql:
enabled: false
postgresql-ha:
enabled: false
valkey:
enabled: false
valkey-cluster:
enabled: false
resources:
requests:
cpu: 100m
memory: 300Mi
limits:
memory: 500Mi
gitea:
config:
database:
DB_TYPE: sqlite3
actions:
ENABLED: true
server:
ROOT_URL: https://gitea.infra.deployshed.com/
service:
# The homelab sat on a LAN; this Gitea is on a public IP. Open
# registration would let anyone on the internet create an account.
DISABLE_REGISTRATION: true
security:
# The homelab allowed "*" because every host was on a private LAN.
# Here "*" would also allow webhooks to the node metadata server, so
# this stays narrowed to private ranges — which covers every
# in-cluster Service (Jenkins included) reached over cluster DNS.
#
# The one public entry is toolshed's own dashboard host, and it is a
# STOPGAP. toolshed builds each app's webhook target from the
# hostname the dashboard was browsed on (internal/api/apps.go's
# queueRepo), with no override, so an app registered through the
# public URL gets a public webhook target and Gitea refuses to call
# it: "webhook can only call allowed HTTP servers".
#
# The cost is real but bounded: this permits exactly one hostname,
# which happens to be our own load balancer, so the callback
# hairpins out and back in rather than staying pod-to-pod. It does
# not re-expose the metadata server, which is why "*" was rejected.
#
# The proper fix is a configurable webhook base URL in toolshed
# pointing at toolshed-api.toolshed.svc.cluster.local:8080, after
# which this entry should be removed.
ALLOWED_HOST_LIST: private,console.deployshed.com
admin:
username: gitadmin
# Created by hand with kubectl at bootstrap, because Vault and ESO
# are not running yet. Same Secret name as the homelab so the
# ExternalSecret (secretstores/gitea-admin-credentials.yaml) can take
# it over unchanged once Vault is up.
existingSecret: gitea-admin-credentials
email: "admin@local.lab"
# Contour does not exist yet at bootstrap — the Ingress just sits unused
# until ArgoCD installs it.
#
# One host. The nip.io name was served alongside this one while the
# deployment moved onto its own domain, and came out once everything
# referencing it had been repointed: ROOT_URL above, the webhook allow-list
# above that, and any git remote anyone had configured.
ingress:
enabled: true
className: contour
annotations:
# Issues the certificate named in tls below. This could only ever cover
# the real domain: Let's Encrypt cannot issue for nip.io, so while both
# names were served, asking for one certificate spanning them returned
# nothing for either.
cert-manager.io/cluster-issuer: letsencrypt-prod
hosts:
- host: gitea.infra.deployshed.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: gitea-tls
hosts:
- gitea.infra.deployshed.com
@@ -0,0 +1,283 @@
grafana:
# From Vault via ExternalSecret (devops-infra-argo-config/secretstores/
# grafana-admin-credentials.yaml), same pattern as gitea/harbor/jenkins
# admin credentials elsewhere in this project — never a plaintext
# adminPassword in this file.
admin:
existingSecret: grafana-admin-credentials
userKey: username
passwordKey: password
persistence:
# 1Gi, not the chart's 10Gi default: this holds dashboards, folders and
# Grafana's own sqlite state, not metric data — VictoriaMetrics keeps
# that. Unlike the homelab's local-path, standard-rwo can be expanded
# later if that ever proves tight.
enabled: true
storageClassName: standard-rwo
size: 1Gi
resources:
requests:
cpu: 50m
memory: 128Mi
limits:
memory: 384Mi
# Provisioned at boot, not clicked through in the UI — the same reason
# every other credential/config in this project is committed rather
# than set by hand: it survives a pod restart and a fresh install gets
# it automatically. VictoriaMetrics speaks Prometheus's own query API,
# so `type: prometheus` here is correct even though the URL is VM's —
# see this repo's victoria-metrics-single chart for why.
datasources:
datasources.yaml:
apiVersion: 1
datasources:
- name: VictoriaMetrics
# Fixed uid, not left to auto-generate — the provisioned
# dashboard below references this datasource by uid, and an
# auto-generated one would only exist after Grafana's first
# boot, too late for a dashboard provisioned in the same boot.
uid: victoriametrics
type: prometheus
access: proxy
url: http://victoria-metrics-single-server.monitoring.svc.cluster.local:8428
isDefault: true
# Dashboard provisioning. Provisioned rather than built by hand in the
# UI for the same reason the datasource above is: it survives a pod
# restart (this deployment has no persistent Grafana database beyond
# the 1Gi PVC, and even with one, a fresh install should not start
# with an empty dashboard list) and a `git diff` shows what changed.
dashboardProviders:
dashboardproviders.yaml:
apiVersion: 1
providers:
- name: default
orgId: 1
folder: ""
type: file
disableDeletion: false
editable: true
options:
path: /var/lib/grafana/dashboards/default
# "Homelab Overview" — total Envoy/Contour RPS, per-namespace CPU and
# memory (the $namespace template variable filters every relevant
# panel), cluster-wide utilization against actual node capacity, and a
# total-resources row (cores/memory/pods/disk). Envoy and node-exporter
# metrics both required their own vmagent scrape job — see
# helm-overrides/.../vmagent/custom-values.yaml for why neither was
# reachable through the chart's own defaults in this cluster.
#
# Every panel except "Disk free" was run against the live deployment
# (vmui, over Tailscale) before being written in here — RPS, per-
# namespace CPU/memory, machine_cpu_cores/machine_memory_bytes all
# returned real data. "Disk free" depends on the node-exporter scrape
# job added alongside this same change, which had not been live yet to
# verify against — worth checking once this actually deploys, same as
# everything else in this repo that gets a `helm template` check but
# cannot get a live one before the first sync.
dashboards:
default:
homelab:
json: |
{
"title": "Homelab Overview",
"uid": "homelab-overview",
"schemaVersion": 39,
"editable": true,
"timezone": "browser",
"time": { "from": "now-1h", "to": "now" },
"refresh": "30s",
"templating": {
"list": [
{
"name": "namespace",
"type": "query",
"datasource": { "type": "prometheus", "uid": "victoriametrics" },
"query": "label_values(container_memory_working_set_bytes{container!=\"\", container!=\"POD\"}, namespace)",
"refresh": 2,
"multi": true,
"includeAll": true,
"current": { "selected": true, "text": "All", "value": "$__all" }
}
]
},
"panels": [
{ "type": "row", "title": "Ingress (Envoy / Contour)", "gridPos": { "h": 1, "w": 24, "x": 0, "y": 0 }, "id": 100 },
{
"type": "stat", "title": "Total RPS", "id": 1,
"gridPos": { "h": 6, "w": 6, "x": 0, "y": 1 },
"datasource": { "type": "prometheus", "uid": "victoriametrics" },
"targets": [{ "expr": "sum(rate(envoy_http_downstream_rq_total{namespace=\"projectcontour\"}[5m]))", "legendFormat": "rps" }],
"fieldConfig": { "defaults": { "unit": "reqps", "decimals": 2 }, "overrides": [] },
"options": { "reduceOptions": { "calcs": ["lastNotNull"] }, "graphMode": "area" }
},
{
"type": "stat", "title": "Active downstream connections", "id": 2,
"gridPos": { "h": 6, "w": 6, "x": 6, "y": 1 },
"datasource": { "type": "prometheus", "uid": "victoriametrics" },
"targets": [{ "expr": "sum(envoy_http_downstream_cx_active{namespace=\"projectcontour\"})", "legendFormat": "connections" }],
"fieldConfig": { "defaults": { "unit": "short" }, "overrides": [] }
},
{
"type": "timeseries", "title": "Requests by response class", "id": 3,
"gridPos": { "h": 6, "w": 12, "x": 12, "y": 1 },
"datasource": { "type": "prometheus", "uid": "victoriametrics" },
"targets": [{
"expr": "sum by (envoy_response_code_class) (rate(envoy_http_downstream_rq_xx{namespace=\"projectcontour\"}[5m]))",
"legendFormat": "{{envoy_response_code_class}}xx"
}],
"fieldConfig": { "defaults": { "unit": "reqps" }, "overrides": [] },
"options": { "legend": { "displayMode": "list", "placement": "bottom" } }
},
{ "type": "row", "title": "Service level (by namespace)", "gridPos": { "h": 1, "w": 24, "x": 0, "y": 7 }, "id": 101 },
{
"type": "timeseries", "title": "CPU usage by namespace", "id": 10,
"gridPos": { "h": 8, "w": 12, "x": 0, "y": 8 },
"datasource": { "type": "prometheus", "uid": "victoriametrics" },
"targets": [{
"expr": "sum by (namespace) (rate(container_cpu_usage_seconds_total{namespace=~\"$namespace\", container!=\"\", container!=\"POD\"}[5m]))",
"legendFormat": "{{namespace}}"
}],
"fieldConfig": { "defaults": { "unit": "short", "custom": { "fillOpacity": 10, "stacking": { "mode": "normal" } } }, "overrides": [] },
"options": { "legend": { "displayMode": "table", "placement": "right", "calcs": ["mean", "max"] } }
},
{
"type": "timeseries", "title": "Memory usage by namespace", "id": 11,
"gridPos": { "h": 8, "w": 12, "x": 12, "y": 8 },
"datasource": { "type": "prometheus", "uid": "victoriametrics" },
"targets": [{
"expr": "sum by (namespace) (container_memory_working_set_bytes{namespace=~\"$namespace\", container!=\"\", container!=\"POD\"})",
"legendFormat": "{{namespace}}"
}],
"fieldConfig": { "defaults": { "unit": "bytes", "custom": { "fillOpacity": 10, "stacking": { "mode": "normal" } } }, "overrides": [] },
"options": { "legend": { "displayMode": "table", "placement": "right", "calcs": ["mean", "max"] } }
},
{
"type": "table", "title": "Current usage per namespace", "id": 12,
"gridPos": { "h": 8, "w": 24, "x": 0, "y": 16 },
"datasource": { "type": "prometheus", "uid": "victoriametrics" },
"targets": [
{ "expr": "sum by (namespace) (rate(container_cpu_usage_seconds_total{namespace=~\"$namespace\", container!=\"\", container!=\"POD\"}[5m]))", "format": "table", "instant": true, "refId": "A" },
{ "expr": "sum by (namespace) (container_memory_working_set_bytes{namespace=~\"$namespace\", container!=\"\", container!=\"POD\"})", "format": "table", "instant": true, "refId": "B" },
{ "expr": "count by (namespace) (count by (namespace, pod) (container_memory_working_set_bytes{namespace=~\"$namespace\", container!=\"\", container!=\"POD\"}))", "format": "table", "instant": true, "refId": "C" }
],
"transformations": [
{ "id": "merge", "options": {} },
{ "id": "organize", "options": {
"excludeByName": { "Time": true, "Time 1": true, "Time 2": true, "Time 3": true },
"renameByName": { "Value #A": "CPU (cores)", "Value #B": "Memory", "Value #C": "Pods" }
} }
],
"fieldConfig": { "defaults": {}, "overrides": [
{ "matcher": { "id": "byName", "options": "Memory" }, "properties": [{ "id": "unit", "value": "bytes" }] },
{ "matcher": { "id": "byName", "options": "CPU (cores)" }, "properties": [{ "id": "unit", "value": "short" }, { "id": "decimals", "value": 3 }] }
] }
},
{ "type": "row", "title": "Cluster utilization", "gridPos": { "h": 1, "w": 24, "x": 0, "y": 24 }, "id": 102 },
{
"type": "gauge", "title": "CPU utilization", "id": 20,
"gridPos": { "h": 7, "w": 6, "x": 0, "y": 25 },
"datasource": { "type": "prometheus", "uid": "victoriametrics" },
"targets": [{ "expr": "100 * sum(rate(container_cpu_usage_seconds_total{container!=\"\", container!=\"POD\"}[5m])) / sum(machine_cpu_cores)" }],
"fieldConfig": { "defaults": { "unit": "percent", "min": 0, "max": 100,
"thresholds": { "mode": "absolute", "steps": [
{ "color": "green", "value": null }, { "color": "yellow", "value": 70 }, { "color": "red", "value": 90 }
] } }, "overrides": [] }
},
{
"type": "gauge", "title": "Memory utilization", "id": 21,
"gridPos": { "h": 7, "w": 6, "x": 6, "y": 25 },
"datasource": { "type": "prometheus", "uid": "victoriametrics" },
"targets": [{ "expr": "100 * sum(container_memory_working_set_bytes{container!=\"\", container!=\"POD\"}) / sum(machine_memory_bytes)" }],
"fieldConfig": { "defaults": { "unit": "percent", "min": 0, "max": 100,
"thresholds": { "mode": "absolute", "steps": [
{ "color": "green", "value": null }, { "color": "yellow", "value": 70 }, { "color": "red", "value": 90 }
] } }, "overrides": [] }
},
{
"type": "timeseries", "title": "Cluster CPU utilization over time", "id": 22,
"gridPos": { "h": 7, "w": 12, "x": 12, "y": 25 },
"datasource": { "type": "prometheus", "uid": "victoriametrics" },
"targets": [
{ "expr": "100 * sum(rate(container_cpu_usage_seconds_total{container!=\"\", container!=\"POD\"}[5m])) / sum(machine_cpu_cores)", "legendFormat": "CPU %" },
{ "expr": "100 * sum(container_memory_working_set_bytes{container!=\"\", container!=\"POD\"}) / sum(machine_memory_bytes)", "legendFormat": "Memory %" }
],
"fieldConfig": { "defaults": { "unit": "percent", "min": 0 }, "overrides": [] }
},
{ "type": "row", "title": "Total resources", "gridPos": { "h": 1, "w": 24, "x": 0, "y": 32 }, "id": 103 },
{
"type": "stat", "title": "Node CPU capacity", "id": 30,
"gridPos": { "h": 5, "w": 4, "x": 0, "y": 33 },
"datasource": { "type": "prometheus", "uid": "victoriametrics" },
"targets": [{ "expr": "max(machine_cpu_cores)" }],
"fieldConfig": { "defaults": { "unit": "short", "displayName": "cores" }, "overrides": [] }
},
{
"type": "stat", "title": "Node memory capacity", "id": 31,
"gridPos": { "h": 5, "w": 4, "x": 4, "y": 33 },
"datasource": { "type": "prometheus", "uid": "victoriametrics" },
"targets": [{ "expr": "max(machine_memory_bytes)" }],
"fieldConfig": { "defaults": { "unit": "bytes" }, "overrides": [] }
},
{
"type": "stat", "title": "CPU used (cluster)", "id": 32,
"gridPos": { "h": 5, "w": 4, "x": 8, "y": 33 },
"datasource": { "type": "prometheus", "uid": "victoriametrics" },
"targets": [{ "expr": "sum(rate(container_cpu_usage_seconds_total{container!=\"\", container!=\"POD\"}[5m]))" }],
"fieldConfig": { "defaults": { "unit": "short", "displayName": "cores", "decimals": 2 }, "overrides": [] }
},
{
"type": "stat", "title": "Memory used (cluster)", "id": 33,
"gridPos": { "h": 5, "w": 4, "x": 12, "y": 33 },
"datasource": { "type": "prometheus", "uid": "victoriametrics" },
"targets": [{ "expr": "sum(container_memory_working_set_bytes{container!=\"\", container!=\"POD\"})" }],
"fieldConfig": { "defaults": { "unit": "bytes" }, "overrides": [] }
},
{
"type": "stat", "title": "Running pods", "id": 34,
"gridPos": { "h": 5, "w": 4, "x": 16, "y": 33 },
"datasource": { "type": "prometheus", "uid": "victoriametrics" },
"targets": [{ "expr": "count(count by (namespace, pod) (container_memory_working_set_bytes{container!=\"\", container!=\"POD\"}))" }],
"fieldConfig": { "defaults": { "unit": "short" }, "overrides": [] }
},
{
"type": "stat", "title": "Disk free (root)", "id": 35,
"gridPos": { "h": 5, "w": 4, "x": 20, "y": 33 },
"datasource": { "type": "prometheus", "uid": "victoriametrics" },
"targets": [{ "expr": "node_filesystem_avail_bytes{mountpoint=\"/\"}" }],
"fieldConfig": { "defaults": { "unit": "bytes",
"thresholds": { "mode": "absolute", "steps": [
{ "color": "red", "value": null }, { "color": "yellow", "value": 5000000000 }, { "color": "green", "value": 15000000000 }
] } }, "overrides": [] }
}
]
}
ingress:
enabled: true
ingressClassName: contour
annotations:
# The real domain is now the only host, so this covers everything
# served. While nip.io was alongside it, only the real domain could
# appear in tls below — Let's Encrypt cannot issue for nip.io, and one
# certificate spanning both would have failed outright rather than
# covering the half it could serve.
cert-manager.io/cluster-issuer: letsencrypt-prod
path: /
hosts:
- grafana.infra.deployshed.com
tls:
- secretName: grafana-tls
hosts:
- grafana.infra.deployshed.com
@@ -0,0 +1,160 @@
harbor:
# GKE counterpart of the homelab's harbor override (k8s-admin-prd-ase1,
# in the homelab devops-infra-helm-charts repo), same chart (1.19.1), with one fundamental difference: this Harbor is served over
# real TLS, and it has to be.
#
# The homelab runs Harbor on plain HTTP and works around containerd's
# refusal to pull from an insecure registry by hand-editing
# /etc/containerd/certs.d/<host>/hosts.toml on the node. GKE nodes are
# managed and replaced, so that edit cannot survive.
#
# That used to mean a private CA: the registry was a nip.io name, Let's
# Encrypt cannot issue for one (not on the public suffix list, and every
# *.nip.io certificate shares a single rate limit), so Terraform generated
# a CA, the node pool was told at creation to trust it for exactly that
# hostname, and cert-manager signed Harbor from it. It worked for pulls,
# which is what mattered, but every browser warned on the Harbor UI and
# every docker client that was not a node needed the CA mounted by hand.
#
# Owning a domain removes all of it. harbor.infra.deployshed.com takes an
# ordinary Let's Encrypt certificate that everything already trusts — the
# nodes, dockerd in a build pod, a laptop, a browser. What retires with it:
# registry-ca-clusterissuer.yaml, registry-ca-configmap.yaml, the CA mount
# in every dind pod, and eventually the node pool's own
# private_registry_access_config block in Terraform.
#
# The nip.io name is still served, by a standalone Ingress alongside this
# one, and still signed by the private CA. It has to be: apps deployed
# before the move recorded their image as harbor.35.238.248.203.nip.io/...
# in toolshed's database, and that reference only changes when each app is
# rebuilt. Retiring the old name before then breaks their next image pull.
expose:
type: ingress
tls:
enabled: true
# secret, not the chart's "auto": auto generates its own self-signed
# certificate, which nothing has any reason to trust.
certSource: secret
secret:
secretName: harbor-deployshed-tls
ingress:
hosts:
core: "harbor.infra.deployshed.com"
className: contour
annotations:
# cert-manager's ingress-shim watches for this and creates the
# Certificate itself, writing the result into the secret named
# above. Nothing here ever touches a Certificate resource directly.
cert-manager.io/cluster-issuer: letsencrypt-prod
# The update strategy for the two deployments with persistent volumes,
# jobservice and registry. Recreate, not the chart's default RollingUpdate,
# because their volumes are standard-rwo — ReadWriteOnce — and a rolling
# update starts the replacement pod before the old one releases the disk.
# The new pod then waits on "Multi-Attach error for volume ... already used
# by pod" forever, and the rollout never converges: this cluster sat in
# exactly that state, old pods serving while new ones hung in
# ContainerCreating. The chart's own comment on this value says to set it
# this way when RWM volumes are unavailable.
#
# The cost is honest: Harbor is briefly down during an upgrade, because the
# old pod must stop before the new one starts. That beats an update that
# cannot complete at all.
updateStrategy:
type: Recreate
# https, matching the ingress above. Harbor hands this URL to docker
# clients in its own API responses, so a mismatch here breaks pushes in
# ways that look like registry errors rather than configuration — and it is
# what the "docker login / docker push" commands shown in Harbor's own UI
# are built from, which is where a stale value is noticed first.
externalURL: "https://harbor.infra.deployshed.com"
# From Vault through External Secrets — see
# secretstores/harbor-admin-credentials.yaml and Vault path
# secret/harbor/admin.
existingSecretAdminPassword: harbor-admin-credentials
existingSecretAdminPasswordKey: HARBOR_ADMIN_PASSWORD
# The one genuinely optional component. Harbor's database and redis are
# its own required internal state, not add-ons.
trivy:
enabled: false
persistence:
enabled: true
# Keeps the PVCs if the release is ever uninstalled: these hold the
# actual images.
resourcePolicy: "keep"
persistentVolumeClaim:
registry:
storageClass: standard-rwo
size: 5Gi
jobservice:
jobLog:
storageClass: standard-rwo
size: 1Gi
database:
storageClass: standard-rwo
size: 1Gi
redis:
storageClass: standard-rwo
size: 1Gi
portal:
resources:
requests:
cpu: 50m
memory: 128Mi
limits:
memory: 256Mi
core:
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
memory: 512Mi
jobservice:
resources:
requests:
cpu: 50m
memory: 128Mi
limits:
memory: 256Mi
registry:
registry:
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
memory: 256Mi
controller:
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
memory: 128Mi
database:
internal:
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
memory: 512Mi
redis:
internal:
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
memory: 128Mi
@@ -0,0 +1,94 @@
jenkins:
# GKE counterpart of the homelab's jenkins override (k8s-admin-prd-ase1,
# in the homelab devops-infra-helm-charts repo), same chart (5.8.58). Dynamic Kubernetes build agents, so idle cost is the
# controller alone.
#
# Every plugin pin below is carried over deliberately, not copied
# blindly — each one fixes a failure that is not obvious from its symptom.
# See the homelab file for the full history.
controller:
image:
# The chart's own default plugin list requires core >= 2.504.3, while
# its default image tag is 2.504.2. An upstream inconsistency in the
# chart, not our configuration: bumping core is the fix, since the
# plugins involved (kubernetes above all) are what dynamic agents
# depend on.
tag: "2.504.3-jdk21"
# Helm replaces lists wholesale rather than merging, so this is the
# chart's full default list with one version corrected, plus two
# additions — not a hand-picked subset.
installPlugins:
# Pinned as a pair. kubernetes needs kubernetes-client-api >=
# 7.3.1-256.v788a_0b_787114; left unpinned it resolves to an older
# version at image-build time and every agent launch dies with
# NoSuchMethodError while constructing the client. The pods start
# fine, so it presents as builds hanging forever at "Still waiting to
# schedule task" rather than as a plugin problem.
- kubernetes:4437.v3a_18554d3f32
- kubernetes-client-api:7.3.1-256.v788a_0b_787114
- workflow-aggregator:608.v67378e9d3db_1
- git:5.7.0
# kubernetes/git/credentials need this version, though the chart's
# own default list pins an older one. Same class of upstream
# inconsistency as the image tag.
- configuration-as-code:2006.v001a_2ca_6b_574
# Not in the chart's default list at all — provides readYaml, which
# the shared library's loadConfig stage uses to parse each repo's
# config.yaml.
- pipeline-utility-steps:3.810.va_7672d206740
resources:
requests:
cpu: 100m
memory: 512Mi
limits:
cpu: 500m
memory: 1Gi
admin:
# From Vault through External Secrets, never a plaintext password
# here. Requires secretstores/jenkins-admin-credentials.yaml to have
# synced, which in turn requires the Vault path secret/jenkins/admin.
existingSecret: jenkins-admin-credentials
userKey: jenkins-admin-user
passwordKey: jenkins-admin-password
# One hostname, on the primary ingress, with its certificate.
#
# This chart's primary ingress supports exactly one hostName — no
# extraHosts like argo-cd — so while nip.io was also served, the real
# domain lived in a whole second Ingress object (secondaryingress). That
# was the only way to keep the certificate clean, since a certificate
# covering both names is impossible: Let's Encrypt cannot issue for
# nip.io. With nip.io gone there is one name, so the second object is
# gone with it and the certificate moves onto the primary.
#
# controller.ingress.tls is a LIST here, not a boolean, taking an
# explicit secretName — so jenkins-tls, already issued for this exact
# hostname by the secondary ingress, is adopted rather than reissued.
ingress:
enabled: true
hostName: "jenkins.infra.deployshed.com"
ingressClassName: contour
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
tls:
- secretName: jenkins-tls
hosts:
- jenkins.infra.deployshed.com
agent:
resources:
requests:
cpu: 250m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
persistence:
enabled: true
storageClass: standard-rwo
size: 5Gi
@@ -0,0 +1,17 @@
prometheus-node-exporter:
# Unchanged from the homelab's — nothing here is cluster-specific. One
# DaemonSet pod per node on hostNetwork; three pods here rather than one.
#
# Host-level metrics are independent of which TSDB stores them, which is
# why this is its own release rather than a subchart of anything.
resources:
requests:
cpu: 20m
memory: 32Mi
limits:
memory: 64Mi
# The chart's Service carries prometheus.io/scrape by default. vmagent
# also targets these pods directly by container port, because that
# annotation-based path found nothing in the homelab — see the vmagent
# values for the detail.
@@ -0,0 +1,45 @@
# PostgreSQL for toolshed's control plane, on GKE.
#
# Its own namespace rather than toolshed's, so it is addressed over cluster
# DNS like any other platform component and outlives its first consumer:
#
# postgresql.postgres.svc.cluster.local:5432
#
# Hand-written chart, not Bitnami's: that registry has been unstable, and
# PostgreSQL ships no official chart.
#
# Credentials come from Vault through External Secrets — see
# secretstores/toolshed-postgres-credentials.yaml. The Secret must exist
# before this pod starts; without it the pod sits in
# CreateContainerConfigError, which does not explain itself.
fullnameOverride: postgresql
image:
repository: postgres
tag: "16-alpine"
pullPolicy: IfNotPresent
existingSecret: postgresql-credentials
database: toolshed
persistence:
enabled: true
storageClass: standard-rwo
size: 5Gi
config:
# Kept at the homelab's deliberately small values even though this
# cluster has room to spare: for a handful of control-plane tables it
# makes no measurable difference, and matching the homelab keeps one
# fewer variable between the two deployments. Raise it if a real query
# workload ever shows up here.
sharedBuffers: 32MB
maxConnections: "50"
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
memory: 256Mi
@@ -0,0 +1,45 @@
# Redis backing toolshed's managed cache add-on, on GKE.
#
# Its own namespace, same reasoning as postgresql:
#
# redis.redis.svc.cluster.local:6379
#
# Hand-written chart, not Bitnami's, for the same reason as postgresql.
#
# Read the chart's own values.yaml before changing anything about
# authentication. The absence of requirepass is deliberate and
# security-relevant, not an oversight: access is defined by an ACL file
# seeded from Vault through External Secrets
# (secretstores/toolshed-redis-credentials.yaml). The Secret must exist
# before this pod starts, or the init container cannot seed that file.
fullnameOverride: redis
image:
repository: redis
tag: "7-alpine"
pullPolicy: IfNotPresent
existingSecret: redis-credentials
persistence:
enabled: true
storageClass: standard-rwo
# Holds the ACL file and nothing else worth keeping, since snapshotting
# is off. 1Gi is already far more than needed.
size: 1Gi
config:
# Kept at the homelab's value. It was chosen there to fit an 8GB node
# under pressure, and while this cluster has room, a bigger cache buys
# nothing for a handful of small internal tools.
maxmemory: 48mb
maxmemoryPolicy: allkeys-lru
save: ""
resources:
requests:
cpu: 25m
memory: 32Mi
limits:
memory: 96Mi
@@ -0,0 +1,99 @@
vault:
# GKE counterpart of the homelab's vault override (k8s-admin-prd-ase1,
# in the homelab devops-infra-helm-charts repo), same chart (0.34.1) and same shape — production mode, file storage, standalone, no
# HA — with one substantial difference: this Vault unseals itself from
# Cloud KMS instead of by hand.
#
# The homelab unseals with 3 of 5 Shamir keys after every restart. That
# was fine on an always-on VM. Here the nodes are spot and can be
# reclaimed at any hour, and a sealed Vault means every secret in the
# cluster is unavailable until a human notices. The trade, stated plainly:
# unsealing now depends on GCP IAM rather than on people holding key
# shares.
#
# This is a fresh install, not an adoption. Init is still a one-off manual
# step (`vault operator init`), and with a KMS seal it returns RECOVERY
# keys plus a root token — recovery keys cannot unseal a running Vault,
# they exist to recover or rekey it. Keep them and the root token in a
# password manager; they belong in neither Git nor Vault itself.
injector:
enabled: false
server:
# The Workload Identity binding Terraform created names exactly
# vault/vault — this namespace and this service account name. The
# annotation is the other half of that pair. Miss either and Vault
# starts, fails to reach KMS, and stays sealed with a permission error
# that does not mention Workload Identity at all.
serviceAccount:
create: true
name: vault
annotations:
iam.gke.io/gcp-service-account: toolshed-vault@toolshed-testing-508208.iam.gserviceaccount.com
dataStorage:
enabled: true
# 10Gi rather than the homelab's 5Gi: that number exists only because
# local-path cannot expand a bound volume. standard-rwo can expand, so
# this is the chart default, not a constraint.
size: 10Gi
storageClass: standard-rwo
ha:
enabled: false
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
memory: 256Mi
standalone:
enabled: true
# `ui = true` here AND ui.enabled below are both required — the chart
# has two separate toggles for the same thing, and setting only one
# leaves the UI 404ing (claude.md issue #10).
#
# The seal stanza's values come from terraform output vault_seal, so
# Terraform and this file cannot disagree about which key Vault
# unseals with. No credentials appear here: the pod authenticates to
# KMS as its Workload Identity, so there is no key file to mount,
# rotate, or leak.
config: |
ui = true
listener "tcp" {
address = "[::]:8200"
cluster_address = "[::]:8201"
tls_disable = "true" # lab only - enable TLS for anything beyond local testing
}
storage "file" {
path = "/vault/data"
}
seal "gcpckms" {
project = "toolshed-testing-508208"
region = "us-central1"
key_ring = "toolshed-vault"
crypto_key = "unseal"
}
# Single host — no Tailscale here. Plain HTTP through Contour, matching
# tls_disable above.
ingress:
enabled: true
ingressClassName: contour
annotations:
# Certificate for the real domain, which is now the only one served.
# nip.io could never have had one.
cert-manager.io/cluster-issuer: letsencrypt-prod
hosts:
- host: "vault.infra.deployshed.com"
paths: []
tls:
- secretName: vault-tls
hosts:
- vault.infra.deployshed.com
ui:
enabled: true
@@ -0,0 +1,69 @@
victoria-metrics-single:
server:
# 3 days rather than the chart's month: this cluster exists to prove a
# pipeline, and every extra day is disk against the project's 250GB SSD
# quota, which every standard-rwo volume in the cluster shares. Three
# days still spans a weekend, which is the window that matters for
# working out what happened to something overnight.
#
# Down from 7d. Note what this does and does not do: it reclaims disk as
# old partitions are dropped, and shrinks the index a little, but it
# does NOT reduce the memory this needs to run. That tracks active time
# series and cache size, neither of which depends on how long data is
# kept — which is why the limit above had to be raised rather than this
# lowered when it started OOM-killing on restart. The lever for memory
# is scrape cardinality: several targets here carry more than forty
# labels per series (see the maxLabelsPerTimeseries warnings in its
# log), and dropping labels there would cut series count directly.
retentionPeriod: "3d"
persistentVolume:
storageClassName: standard-rwo
# VictoriaMetrics' compression is why it replaced Prometheus here;
# this cluster's metric volume at 7 days fits well inside 3Gi. Unlike
# the homelab's local-path, this class can be expanded later.
size: 3Gi
# Raised from 128Mi/512Mi, which this no longer fits inside.
#
# The pod ran for weeks at the old limit and then OOM-killed in a loop
# the first time it was restarted — exit 137 roughly fifty seconds after
# a clean start, every time. Nothing had changed about its configuration;
# the dataset had simply grown into 3.14 billion rows, and the memory a
# restart needs to resume ingestion no longer fit. A long-lived pod can
# sit well past the limit it would need to start again, so the failure
# only appears the next time something restarts it.
#
# Memory here tracks active time series rather than disk, which is why
# shortening retentionPeriod above would not have helped: the scrape
# targets are the same either way, and several of them carry 40+ labels
# (see the maxLabelsPerTimeseries warnings in its log).
#
# Affordable: memory requests across the three nodes sit at 62%, 18% and
# 47%, so there is room. CPU is the constrained resource on this cluster,
# and this costs none.
resources:
requests:
cpu: 50m
memory: 256Mi
limits:
memory: 1Gi
# vmui, VictoriaMetrics' built-in query UI, on the same pod and port —
# ad-hoc PromQL only, no saved dashboards; Grafana is the real UI. Free
# to expose, since it is not a separate component.
ingress:
enabled: true
ingressClassName: contour
annotations:
# Certificate for the real domain, now the only one served. nip.io
# could never have had one.
cert-manager.io/cluster-issuer: letsencrypt-prod
hosts:
- name: vm.infra.deployshed.com
path: ["/"]
port: http
tls:
- secretName: vm-tls
hosts:
- vm.infra.deployshed.com
@@ -0,0 +1,70 @@
victoria-metrics-agent:
# Unchanged from the homelab's, deliberately: everything here is
# addressed by cluster-internal Service DNS and namespace, none of which
# differs on GKE.
#
# The write path is what wires the two components together; the chart
# names do not imply it on their own.
remoteWrite:
- url: http://victoria-metrics-single-server.monitoring.svc.cluster.local:8428/api/v1/write
# config.scrape_configs stays at the chart's default, which already
# covers kubelet's cAdvisor endpoint and the prometheus.io/scrape
# annotation convention. extraScrapeConfigs is concatenated onto it
# rather than replacing it.
#
# Both jobs below exist because annotation-based discovery did not reach
# these targets in the homelab. Contour's Envoy carries no scrape
# annotation at all, and node-exporter's annotation sits on its Service,
# where the endpointslice discovery path found nothing. Targeting each by
# its fixed container port sidesteps both problems and is no less
# correct. Worth re-checking on this cluster rather than assuming the
# same gaps: if the defaults do find them here, these jobs are harmless
# duplicates, not errors.
extraScrapeConfigs:
- job_name: contour-envoy
kubernetes_sd_configs:
- role: pod
namespaces:
names: ["projectcontour"]
relabel_configs:
# 8002 is the official Contour chart's fixed metrics port for
# Envoy. /stats/prometheus is Envoy's own admin endpoint, not
# anything Contour-specific.
- action: keep
source_labels: [__meta_kubernetes_pod_container_port_number]
regex: "8002"
- target_label: __metrics_path__
replacement: /stats/prometheus
- action: labelmap
regex: __meta_kubernetes_pod_label_(.+)
- source_labels: [__meta_kubernetes_pod_name]
target_label: pod
- source_labels: [__meta_kubernetes_namespace]
target_label: namespace
- source_labels: [__meta_kubernetes_pod_node_name]
target_label: node
- job_name: node-exporter
kubernetes_sd_configs:
- role: pod
namespaces:
names: ["monitoring"]
relabel_configs:
- action: keep
source_labels: [__meta_kubernetes_pod_container_port_number]
regex: "9100"
- action: labelmap
regex: __meta_kubernetes_pod_label_(.+)
- source_labels: [__meta_kubernetes_pod_name]
target_label: pod
- source_labels: [__meta_kubernetes_namespace]
target_label: namespace
- source_labels: [__meta_kubernetes_pod_node_name]
target_label: node
resources:
requests:
cpu: 25m
memory: 64Mi
limits:
memory: 192Mi
@@ -1,3 +0,0 @@
# 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.
@@ -1,269 +0,0 @@
replicaCount: 5
image:
repository: quay.io/prometheus/alertmanager
pullPolicy: IfNotPresent
# Overrides the image tag whose default is the chart appVersion.
tag: ""
extraArgs:
log.level: debug
cluster.probe-timeout: 1s
cluster.probe-interval: 2s
## Additional Alertmanager Secret mounts
# Defines additional mounts with secrets. Secrets must be manually created in the namespace.
extraSecretMounts: []
# - name: secret-files
# mountPath: /etc/secrets
# subPath: ""
# secretName: alertmanager-secret-files
# readOnly: true
imagePullSecrets: []
nameOverride: ""
fullnameOverride: alertmanager-infra-prd
## namespaceOverride overrides the namespace which the resources will be deployed in
namespaceOverride: ""
configMap: alertmanager-infra-prd-config
labels:
bu: "infra"
team: "sre"
service: "alertmanager-infra-prd"
env: "prd"
priority: "p0"
type: "alertmanager"
automountServiceAccountToken: true
serviceAccount:
# Specifies whether a service account should be created
create: true
# Annotations to add to the service account
annotations: {}
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name: ""
# Sets priorityClassName in alertmanager pod
priorityClassName: ""
podSecurityContext:
fsGroup: 65534
dnsConfig: {}
# nameservers:
# - 1.2.3.4
# searches:
# - ns1.svc.cluster-domain.example
# - my.dns.search.suffix
# options:
# - name: ndots
# value: "2"
# - name: edns0
hostAliases: []
# - ip: "127.0.0.1"
# hostnames:
# - "foo.local"
# - "bar.local"
# - ip: "10.1.2.3"
# hostnames:
# - "foo.remote"
# - "bar.remote"
securityContext:
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
runAsUser: 65534
runAsNonRoot: true
runAsGroup: 65534
additionalPeers: []
## Additional InitContainers to initialize the pod
##
extraInitContainers: []
## Additional containers to add to the stateful set. This will allow to setup sidecarContainers like a proxy to integrate
## alertmanager with an external tool like teams that has not direct integration.
##
extraContainers: []
livenessProbe:
httpGet:
path: /
port: http
readinessProbe:
httpGet:
path: /
port: http
service:
annotations: {}
type: ClusterIP
port: 9093
clusterPort: 9094
loadBalancerIP: "" # Assign ext IP when Service type is LoadBalancer
loadBalancerSourceRanges: [] # Only allow access to loadBalancerIP from these IPs
# if you want to force a specific nodePort. Must be use with service.type=NodePort
# nodePort:
ingress:
enabled: true
className: nginx-internal
annotations: {}
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
hosts:
- host: alertmanager-infra-prd.meeshogcp.in
paths:
- path: /
pathType: ImplementationSpecific
tls: []
# - secretName: chart-example-tls
# hosts:
# - alertmanager.domain.com
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: 100m
memory: 150Mi
nodeSelector:
dedicated: "vmselect-temp"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "vmselect-temp"
effect: "NoSchedule"
affinity: {}
## Pod anti-affinity can prevent the scheduler from placing Alertmanager replicas on the same node.
## The default value "soft" means that the scheduler should *prefer* to not schedule two replica pods onto the same node but no guarantee is provided.
## The value "hard" means that the scheduler is *required* to not schedule two replica pods onto the same node.
## The value "" will disable pod anti-affinity so that no anti-affinity rules will be configured.
##
podAntiAffinity: ""
## If anti-affinity is enabled sets the topologyKey to use for anti-affinity.
## This can be changed to, for example, failure-domain.beta.kubernetes.io/zone
##
podAntiAffinityTopologyKey: kubernetes.io/hostname
## Topology spread constraints rely on node labels to identify the topology domain(s) that each Node is in.
## 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: alertmanager
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
type: alertmanager
statefulSet:
annotations: {}
podAnnotations: {}
podLabels: {}
# Ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/
podDisruptionBudget: {}
# maxUnavailable: 1
# minAvailable: 1
command: []
persistence:
enabled: true
## Persistent Volume Storage Class
## If defined, storageClassName: <storageClass>
## If set to "-", storageClassName: "", which disables dynamic provisioning
## If undefined (the default) or set to null, no storageClassName spec is
## set, choosing the default provisioner.
##
# storageClass: "-"
accessModes:
- ReadWriteOnce
size: 15Gi
configAnnotations: {}
## For example if you want to provide private data from a secret vault
## https://github.com/banzaicloud/bank-vaults/tree/main/charts/vault-secrets-webhook
## P.s.: Add option `configMapMutation: true` for vault-secrets-webhook
# vault.security.banzaicloud.io/vault-role: "admin"
# vault.security.banzaicloud.io/vault-addr: "https://vault.vault.svc.cluster.local:8200"
# vault.security.banzaicloud.io/vault-skip-verify: "true"
# vault.security.banzaicloud.io/vault-path: "kubernetes"
## Example for inject secret
# slack_api_url: '${vault:secret/data/slack-hook-alerts#URL}'
config: {}
## Monitors ConfigMap changes and POSTs to a URL
## Ref: https://github.com/jimmidyson/configmap-reload
##
configmapReload:
## If false, the configmap-reload container will not be deployed
##
enabled: true
## configmap-reload container name
##
name: configmap-reload
## configmap-reload container image
##
image:
repository: jimmidyson/configmap-reload
tag: v0.8.0
pullPolicy: IfNotPresent
# containerPort: 9533
## configmap-reload resource requests and limits
## Ref: http://kubernetes.io/docs/user-guide/compute-resources/
##
resources: {}
templates: {}
# alertmanager.tmpl: |-
## Optionally specify extra list of additional volumeMounts
extraVolumeMounts: []
# - name: extras
# mountPath: /usr/share/extras
# readOnly: true
## Optionally specify extra list of additional volumes
extraVolumes: []
# - name: extras
# emptyDir: {}
## Optionally specify extra environment variables to add to alertmanager container
extraEnv: []
# - name: FOO
# value: BAR
testFramework:
enabled: false
annotations:
"helm.sh/hook": test-success
# "helm.sh/hook-delete-policy": "before-hook-creation,hook-succeeded"
@@ -1,22 +0,0 @@
Here are the steps on how to migrate silenced alerts from an older Alertmanager to a newer Alertmanager machine:
1. Stop the old Alertmanager.
2. Export the silenced alerts from the old Alertmanager. You can use the following command:
amtool -o json --alertmanager.url=http://devops-p-alertmanager-01b.meeshoint.in:9093 silence > silenced_alerts.json
3. Copy the silenced_alerts.json file to the new Alertmanager machine.
k cp helm-overrides/prod-ops-cluster/alertmanager/silenced_alerts.json alertmanager/prd-infra-alertmanager-1:/home -c alertmanager
4. Exec into the new Alertmanager.
k exec -it prd-infra-alertmanager-1 -c alertmanager -- sh
5. Import the silenced alerts into the new Alertmanager. You can use the following command:
amtool --alertmanager.url=https://prd-infra-alertmanager.meesho.com silence import ../home/silenced_alerts.json
Note:
1. If you are running alertmanager on K8s as STS, then you only need to import in any 1 of the pods else duplicate silences will be created.
File diff suppressed because one or more lines are too long
@@ -1,49 +0,0 @@
fullnameOverride: "alloy-infra-prd"
alloy:
configMap:
configFile: admin.alloy
clustering:
enabled: true
extraPorts:
- name: "otlp-grpc"
port: 4317
targetPort: 4317
protocol: "TCP"
- name: "otlp-http"
port: 4318
targetPort: 4318
protocol: "TCP"
resources:
requests:
cpu: 3
memory: 12Gi
configReloader:
enabled: true
serviceAccount:
annotations: {
iam.gke.io/gcp-service-account: sa-infr-sre-obs-prd@meesho-admin-prd-0622.iam.gserviceaccount.com
}
controller:
# Must be one of 'daemonset', 'deployment', or 'statefulset'.
type: 'deployment'
nodeSelector:
dedicated: "alloy"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "alloy"
effect: "NoSchedule"
autoscaling:
enabled: true
minReplicas: 1
maxReplicas: 50
targetCPUUtilizationPercentage: 80
targetMemoryUtilizationPercentage: 80
@@ -1,118 +0,0 @@
argo-cd:
global:
image:
tag: "v2.13.8"
# Single-node homelab VM (8GB RAM / 6 cores, see claude.md) — no dedicated
# devops node pool here, so the GKE nodeSelector/toleration pair from the
# fleet's admin cluster doesn't apply. Every component below is trimmed to
# a single replica with small resource requests to fit the ~700MB total
# budget claude.md tracks for ArgoCD.
# SSO deferred per claude.md ("not yet implemented") — Dex stays off until
# that's picked back up. Revisit this file when it is.
dex:
enabled: false
controller:
replicas: 1
resources:
requests:
cpu: 200m
memory: 400Mi
limits:
cpu: 500m
memory: 768Mi
redis-ha:
enabled: false
redis:
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
memory: 128Mi
repoServer:
replicas: 1
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: 300m
memory: 512Mi
server:
replicas: 1
extraArgs:
- --insecure
ingress:
enabled: true
ingressClassName: contour
hostname: "argocd.192.168.1.7.nip.io"
# Tailscale nip.io variant, same dual-host pattern as Gitea — chart
# supports this natively via extraHosts (confirmed against the real
# values.yaml, not assumed).
extraHosts:
- name: "argocd.100.90.248.118.nip.io"
path: /
resources:
requests:
cpu: 50m
memory: 128Mi
limits:
cpu: 200m
memory: 256Mi
# Not used by this repo's Applications (plain Application manifests
# rendered by generic-argo-apps-chart, not the ApplicationSet CRD) and
# notifications has no configured trigger/service — both off to save RAM.
applicationSet:
enabled: false
notifications:
enabled: false
configs:
cm:
url: "https://argocd.192.168.1.7.nip.io"
timeout.reconciliation: 3m
timeout.reconciliation.jitter: 60s
# ArgoCD's built-in Ingress health check waits for
# status.loadBalancer.ingress to be populated — that only happens
# behind a Service type=LoadBalancer. Contour here is exposed via
# hostPort (MetalLB is installed but not load-bearing, see
# claude.md), so nothing ever writes that status field and every
# Ingress sits "Progressing" forever even though it's actually
# serving traffic fine. Override: an Ingress existing is enough.
resource.customizations.health.networking.k8s.io_Ingress: |
hs = {}
hs.status = "Healthy"
hs.message = "Ingress considered healthy on sight — this cluster's Contour has no LoadBalancer status to wait on (hostPort, not MetalLB)."
return hs
# Scoped account for Jenkins to trigger a sync as the last step of the
# CI/CD pipeline — devops-lib's real deployArgoCD.groovy always closes
# its 4-step ceremony with `argocd app sync --hard-refresh`; without
# this, our pipeline stops at the tag-bump commit and a human has to
# remember to click Sync. Uses apiKey auth (token-based), not the
# admin account — same least-privilege pattern as Harbor's robot
# account. Token itself is generated via CLI (not declarative — see
# bootstrap note in devops-lib's syncArgoApp.groovy) and stored in
# Vault like every other credential here.
accounts.jenkins-ci: apiKey
accounts.jenkins-ci.enabled: "true"
# No custom RBAC policy beyond the jenkins-ci account below: single-user
# homelab, the initial admin secret (kubectl -n argocd get secret
# argocd-initial-admin-secret) is enough for you. The fleet's
# role:admins / role:backend / GitHub-team policy.csv and real teammate
# emails from the source cluster are dropped here.
rbac:
policy.csv: |
p, jenkins-ci, applications, sync, webapp/demo-go-app, allow
p, jenkins-ci, applications, get, webapp/demo-go-app, allow
repositories:
devops-infra-helm-charts:
url: http://gitea.192.168.1.7.nip.io/mukul/devops-infra-helm-charts.git
devops-infra-argo-config:
url: http://gitea.192.168.1.7.nip.io/mukul/devops-infra-argo-config.git
@@ -1,348 +0,0 @@
image:
registry: docker.io
repository: gomods/athens
# Override the chart appVersion and use a specific tag
# tag: v0.12.0
# -- Specify a imagePullPolicy.
# see http://kubernetes.io/docs/user-guide/images/#pre-pulling-images
pullPolicy: IfNotPresent
# -- Specify secrets containing credentials for pulling images
pullSecrets: []
# - name: name-of-secret
# -- Determine if the image should run as `root` or user `athens`
runAsNonRoot: false
livenessProbe:
failureThreshold: 3
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
readinessProbe:
failureThreshold: 3
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
strategy:
# -- Using RollingUpdate requires a shared storage
type: Recreate
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
service:
# -- Add annotations to the service
annotations: {}
# -- Port as exposed by the service
servicePort: 80
# -- Type of service; valid values are "ClusterIP", "LoadBalancer", and
# "NodePort". "ClusterIP" is sufficient in the case when the Proxy will be used
# from within the cluster. To expose externally, consider a "NodePort" or "LoadBalancer" service or use an "Ingress".
type: ClusterIP
# Optional configuration if service is of type "NodePort"
# nodePort:
# -- Specify the nodePort in allowable range (e.g. 30000 - 32767 on minikube)
# port: 30080
ingress:
# -- Create an Ingress resource for athens
enabled: true
annotations: {}
className: nginx-internal
# -- Provide an array of values for the ingress host mapping
hosts:
- host: athens-prd.meeshogcp.in
paths:
- path: /
pathType: ImplementationSpecific
# Provide a base64 encoded cert for TLS use
tls: []
# - hosts:
# - athens-proxy.local
# secretName: athens-proxy.local-tls
storage:
# -- Storage type to use. For a single instance a PVC may be sufficient
type: disk
disk:
storageRoot: "/var/lib/athens"
persistence:
# -- Note if you use disk.persistence.enabled, replicaCount should be set to 1 unless your access mode is
# 'ReadWriteMany' and strategy type must be 'Recreate'
enabled: true
accessMode: ReadWriteOnce
storageClass: "premium-rwo"
size: 10Gi
mongo:
url: ""
s3:
# -- You must set s3 bucket and region when running 'helm install'
region: ""
bucket: ""
useDefaultConfiguration: false
forcePathStyle: false
accessKey: ""
secretKey: ""
sessionToken: ""
minio:
# -- All these variables needs to be set when configuring athens to run with minio backend
endpoint: ""
accessKey: ""
secretKey: ""
bucket: ""
gcp:
# -- For more information, see:
# https://docs.gomods.io/install/install-on-kubernetes/#google-cloud-storage
# you must set gcp projectID and bucket when running 'helm install'
projectID: "meesho-admin-prd-0622"
bucket: "gcs-infr-dvps-athens-prd"
# -- Set serviceAccount to a key which has read/write access to the GCS bucket.
# If you are running Athens inside GCP, you will most likely not need this
# as GCP figures out internal authentication between products for you.
serviceAccount: ""
singleFlight:
# -- SingleFlight type to use.
# Options are ["memory", "etcd", "redis", "redis-sentinel", "gcp", "azureblob"].
# see https://docs.gomods.io/configuration/storage/#running-multiple-athens-pointed-at-the-same-storage
type: ""
etcd:
endpoints: ""
redis:
endpoint: ""
password: ""
lockConfig: {}
# ttl: 900
# timeout: 15
# maxRetries: 10
redisSentinel:
endpoints: ""
masterName: ""
sentinelPassword: ""
redisUsername: ""
redisPassword: ""
lockConfig: {}
# ttl: 900
# timeout: 15
# maxRetries: 10
# -- Priority class for pod scheduling.
# see API reference: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/#priorityclass
priorityClassName: ""
# -- see API reference: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.31/#pod-v1-core.
# the default value is 30 seconds.
terminationGracePeriodSeconds: 30
# -- Container security context configuration.
# see API reference: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/#securitycontext-v1-core.
# This will override the `image.runAsNonRoot` settings in the specified container if `runAsUser` or `runAsGroup` are set
securityContext: {}
# allowPrivilegeEscalation: false
# runAsNonRoot: true
# -- Container lifecycle hooks configuration.
# see API reference: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/
lifecycle: {}
# -- Set environment variables to be passed to athens pods
configEnvVars:
- name: ATHENS_DOWNLOAD_MODE
value: sync
# -- Add extra annotations to the athens pods
annotations: {}
# -- Add extra labels to all resources
extraLabels: {}
# HTTP basic auth
basicAuth:
# -- If enabled, it expects to find the username and password in the named secret provided below
enabled: false
# -- Secret name, containing the 'passwordSecretKey' and 'usernameSecretKey'
secretName: athens-proxy-basic-auth
passwordSecretKey: password
usernameSecretKey: username
netrc:
# -- If enabled, it expects to find the content of a valid '.netrc' file in the named secret provided below
enabled: false
# -- Secret name, containing the '.netrc' file
existingSecret: netrcsecret
# gitconfig section provides a way to inject git config file to make athens able to fetch modules from private git repos
gitconfig:
# -- If enabled, it expects to find git configuration in the named secret provided below.
# By default, gitconfig is disabled
enabled: true
# -- Name of the kubernetes secret (in the same namespace as athens-proxy) that contains git config
secretName: athens-proxy-gitconfig
# -- Key in the kubernetes secret that contains git config data
secretKey: gitconfig
upstreamProxy:
# -- This is where you can set the URL for the upstream module repository.
# If 'enabled' is set to true, Athens will try to download modules from the upstream when it doesn't find them in its own storage.
# Here's a non-exhaustive list of options you can set here:
#
# - https://gocenter.io
# - https://proxy.golang.org
enabled: false
url: "https://proxy.golang.org"
jaeger:
# -- Deploy a jaeger "all-in-one" pod for tracing
enabled: false
annotations: {}
# -- Type of service; valid values are "ClusterIP", "LoadBalancer", and "NodePort".
type: ClusterIP
image:
repository: jaegertracing/all-in-one
tag: latest
# -- Specify the jaeger URL for the environment variable used by athens.
# With default settings, it uses the jaeger-collector-http port of the jaeger service.
url: ""
tracing:
# -- Set ATHENS_TRACE_EXPORTER* environment variables to point to a tracing deployment.
enabled: false
# -- Value of ATHENS_TRACE_EXPORTER_URL
url: ""
# -- Value of ATHENS_TRACE_EXPORTER, supported values are "jaeger", "datadog", and "stackdriver".
type: "jaeger"
# -- Configuration for private git servers that will provide ssh and git config to athens in a ConfigMap
sshGitServers: []
## Private git servers over ssh
## to enable uncomment lines with single hash below
## hostname of the git server
# - host: git.example.com
## https path, "/scm" for bitbucket
# path: ""
## ssh username
# user: git
## ssh private key for the user
# privateKey: |
# -----BEGIN RSA PRIVATE KEY-----
# -----END RSA PRIVATE KEY-----
## ssh port
# port: 22
## ssh private key from the existing secret (to be added separately in "Secret" Resource)
# existingSecret:
# name: ssh-keys
# subPath: secret.id_rsa
# -- sshGitServers init container security context configuration
initContainerSecurityContext: {}
# allowPrivilegeEscalation: false
# runAsNonRoot: true
# -- sshGitServers init container resources (deprecated naming, if initContainerResources is defined, that will be used in preference to this value)
intiContainerResources: {}
# limits:
# cpu: 100m
# memory: 64Mi
# requests:
# cpu: 100m
# memory: 64Mi
# -- sshGitServers init container resources
initContainerResources: {}
# limits:
# cpu: 100m
# memory: 64Mi
# requests:
# cpu: 100m
# memory: 64Mi
# -- Define extra init containers for athens-proxy
extraInitContainers: []
# - name: init
# image: busybox:1.28
# command: ['sh', '-c', "echo 'hello world'"]
# -- Specify the number of go workers
goGetWorkers: 16
metrics:
serviceMonitor:
# -- Create a ServiceMonitor for prometheus
enabled: false
# namespace: "monitoring"
# labels:
# prometheus: default
serviceScrape:
# -- Create a VMServiceScrape for victoria
enabled: false
# namespace: "monitoring"
serviceAccount:
# -- Create a ServiceAccount
create: true
annotations:
iam.gke.io/gcp-service-account: jenkins-prd-agent@meesho-devops-admin-0622.iam.gserviceaccount.com
name: "athens-proxy-admin-prd"
# -- see https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling
nodeSelector:
dedicated: dind
# -- see https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling
tolerations:
- key: "dedicated"
operator: "Equal"
value: "dind"
effect: "NoSchedule"
# -- see https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling
affinity: {}
# -- Add extra volumes to deployment pod
extraVolumes: {}
# -- Add extra volume mounts to deployment pod primary container
extraVolumeMounts: {}
# -- Define resources for athens pods.
# see https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#resources
resources:
limits:
cpu: '15'
memory: 8Gi
requests:
cpu: '12'
memory: 6Gi
# -- Set the number of athens-proxy replicas, unless autoscaling is enabled
replicaCount: 1
autoscaling:
# -- Enable Horizontal Pod Autoscaling
enabled: false
minReplicas: 1
maxReplicas: 3
targetCPUUtilizationPercentage: 80
targetMemoryUtilizationPercentage: 80
# -- Overwrite the API version used for HPA, uses 'autoscaling/v2' by default.
# see https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/horizontal-pod-autoscaler-v2/
apiVersionOverride: ""
# -- Define scaling behavior for HPA
behavior: {}
# scaleDown:
# stabilizationWindowSeconds: 300
# policies:
# - type: Pods
# value: 1
# periodSeconds: 180
# scaleUp:
# stabilizationWindowSeconds: 300
# policies:
# - type: Pods
# value: 2
# periodSeconds: 60
@@ -1,675 +0,0 @@
## 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: pd-standard-retain-dr
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: dedicated
operator: Equal
value: devops
# -- Select nodes to deploy which matches the following labels
nodeSelector: ##PLACEHOLDER##
dedicated: 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: false
deploymentAnnotations: {}
priorityClassName: ""
##########################################################
# Aurva Controller
##########################################################
aurva_controller:
# -- Additional labels for aurva-controller
additionalLabels:
bu: "admin"
team: "admin-devops"
service: "aurva-admin-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##
dedicated: devops
# -- Taint tolerations for nodes
##PLACEHOLDER##
tolerations:
- effect: NoSchedule
key: dedicated
operator: Equal
value: 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: "k8s-admin-prd-ase1" #Recommendation: should be equal to cluster name
PROVIDER_ACCOUNT_ID: "meesho-admin-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-admin-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: "argocd-central-ase1c-prd,argocd-central-prd,argocd-central-prd,argocd-dataengg-prd,argocd-datascience-prd,argocd-demand-prd,argocd-farmiso-prd,argocd-prd,argocd-shared-int,argocd-supply-prd,jenkins"
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-admin-prd-aurva-contr@meesho-admin-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: "admin"
team: "admin-devops"
service: "aurva-admin-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##
dedicated: devops
##PLACEHOLDER##
# -- Taint tolerations for nodes
tolerations:
- effect: NoSchedule
key: dedicated
operator: Equal
value: 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: "k8s-admin-prd-ase1"
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: "admin"
team: "admin-devops"
service: "aurva-admin-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
- vmselect
- vmagent
- vminsert
- contour-internal-0
- contour-internal-1
- contour-external
- 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-admin-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: "admin"
team: "admin-devops"
service: "aurva-admin-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:
dedicated: 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##
dedicated: devops
##PLACEHOLDER##
# -- Taint tolerations for nodes
tolerations:
- effect: NoSchedule
key: dedicated
operator: Equal
value: 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: "k8s-admin-prd-ase1"
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
@@ -1,25 +0,0 @@
replicaCount: 1
labels:
bu: central
team: devops
env: prd
service:
annotations:
cloud.google.com/neg: '{"exposed_ports": {"5000":{"name": "canary-bot-canary-bot-gcp"}}}'
type: ClusterIP
port: 5000
tolerations:
- key: "dedicated"
operator: "Equal"
value: "devops"
effect: "NoSchedule"
nodeSelector:
dedicated: devops
externalSecret:
path: prd/devops/canary-bot-secrets
secretRef: canary-bot-gcp
@@ -1,129 +0,0 @@
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:
dedicated: devops
tolerations:
- key: "dedicated"
operator: "Equal"
value: "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:
dedicated: devops
tolerations:
- key: "dedicated"
operator: "Equal"
value: "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:
dedicated: devops
tolerations:
- key: "dedicated"
operator: "Equal"
value: "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:
dedicated: devops
tolerations:
- key: "dedicated"
operator: "Equal"
value: "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
@@ -1,26 +0,0 @@
daemonSet:
namespace: prd-conntrack-adjuster
conntrack:
# Maximum number of conntrack entries
max: 2097152
# Hash size for conntrack
hashsize: 524288
# Sleep interval between adjustments (seconds)
sleepInterval: 30
# Enable additional matchExpressions
# addExtraMatchExpressions: true
# Additional matchExpressions to append
# additionalMatchExpressions:
# - key: node-role
# operator: In
# values:
# - "worker"
# - "ingress"
# - key: environment
# operator: In
# values:
# - "production"
# - "staging"
@@ -1,17 +0,0 @@
# ClusterIssuer override for k8s-admin-prd-ase1 (prd admin cluster, ase1a zone).
# ClusterIssuer is a cluster-scoped resource — this file pins the issuer
# identity for this cluster so the name is auditable per-cluster.
#
# Must match the `issuerRef.name` in consuming Certificate CRs (see
# devops-helm-charts/2.0.0/templates/proxyless-grpc-cert.yaml).
issuerName: contour-admin-prd-ca-issuer
rootCASecretName: contour-admin-ca
externalSecret:
enabled: true
vaultPath: admin/devops/contour/root-ca
refreshInterval: "0"
secretStoreRef:
name: vault-backend
namespace: cert-manager-admin-prd
@@ -1,28 +0,0 @@
cronJob:
image:
repository: asia-southeast1-docker.pkg.dev/meesho-devops-admin-0622/admin/contour-cert-checker
tag: v1.1
schedule: "0 12 * * *"
args: ["--cluster=k8s-admin-prd-ase1"]
resources:
requests:
memory: "50Mi"
cpu: "50m"
limits:
memory: "100Mi"
cpu: "100m"
nodeSelector:
dedicated: devops
tolerations:
- effect: NoSchedule
key: dedicated
operator: Equal
value: devops
backoffLimit: 3
historyLimit:
successfulJobs: 7
failedJobs: 7
rbac:
namespace: contour-cert-checker-ns
serviceAccountName: contour-cert-checker-sa
@@ -1,99 +0,0 @@
configInline:
enableExternalNameService: true
timeouts:
connection-idle-timeout: 305s
connection-shutdown-grace-period: 300s
max-connection-duration: 1200s
disablePermitInsecure: false
tls:
fallback-certificate: {}
accesslog-format: envoy
accesslog-level: disabled
contour:
enabled: true
replicaCount: 3
podLabels:
bu: admin
team: devops
env: prd
manageCRDs: true
resources:
requests:
cpu: 250m
memory: 1024Mi
tolerations:
- effect: NoSchedule
key: dedicated
operator: Equal
value: devops
nodeSelector:
dedicated: devops
service:
type: ClusterIP
ports:
xds: 8001
metrics: 8000
ingressClass:
name: "contour-internal-0"
create: true
debug: false
podAnnotations:
prometheus.io/path: /metrics
prometheus.io/port: '8000'
prometheus.io/scrape: 'true'
envoy:
enabled: true
podLabels:
bu: admin
team: devops
env: prd
kind: deployment
tolerations:
- effect: NoSchedule
key: dedicated
operator: Equal
value: devops
nodeSelector:
dedicated: devops
logLevel: error
autoscaling:
enabled: true
minReplicas: 2
maxReplicas: 250
targetCPU: "40"
targetMemory: "40"
podAnnotations:
prometheus.io/path: /stats/prometheus
prometheus.io/port: '8002'
prometheus.io/scrape: 'true'
extraArgs:
- '--concurrency 6'
resources:
requests:
cpu: 6
memory: 3Gi
limits:
cpu: 6
memory: 29Gi
service:
tcpLB: true
export:
enabled: true
targetPorts:
http: http
https: https
type: ClusterIP
annotations:
cloud.google.com/neg: '{"exposed_ports": {"80":{"name": "envoy-int0-admin-prd"}}}'
ports:
http: 80
https: 443
grpc: 8080
useHostPort: false
defaultBackend:
enabled: false
# Override the chart-default Vault path: the admin cluster stores the contour
# root CA under the admin/ prefix, not the meesho/ prefix used by other clusters.
certManager:
externalSecret:
vaultPath: admin/devops/contour/root-ca
@@ -1,69 +0,0 @@
contour:
# This is your live `helm get values contour -n projectcontour` output,
# verbatim. This is the ingress for everything else in this repo
# (Gitea, ArgoCD, Vault all route through it) — don't tune this without
# re-checking those still resolve afterward.
#
# hostPorts, not a Service type=LoadBalancer: claude.md issue #6 — MetalLB
# got a floating IP fine, but this VM's host (VMware Workstation, Bridged
# networking, over Wi-Fi) doesn't do true MAC-level bridging, so the IP
# was never reachable from outside the VM. hostPort on Envoy binds
# directly to the node's real NIC instead.
#
# Correction from an earlier version of this file: the keys below are
# NOT what `helm get values` showed as "user-supplied" on the live
# release (envoy.hostNetworking / envoy.hostPorts.enabled). Checked
# directly against this chart's own values.yaml — this version reads
# envoy.hostNetwork (singular) and envoy.useHostPort.http/https instead.
# Helm doesn't validate unknown keys, so the old ones were silent no-ops.
# hostPort on the live pods is actually coming from the raw `kubectl
# patch` in claude.md issue #7 ("the actual working solution" — that
# title is the tell), applied completely outside Helm. Getting the real
# keys into this file is what finally makes hostPort GitOps-managed
# instead of an unmanaged patch any future plain `helm upgrade` could
# silently wipe.
#
# This is also why ArgoCD's default Ingress health check needed
# overriding (see argocd-admin-prd/custom-values.yaml) — there's no
# Service type=LoadBalancer here to ever populate
# status.loadBalancer.ingress.
contour:
resources:
limits:
memory: 128Mi
requests:
cpu: 50m
memory: 64Mi
envoy:
dnsPolicy: ClusterFirstWithHostNet
# Mistake in an earlier version of this file: this was `true`. claude.md
# is explicit that hostPort was chosen specifically INSTEAD of
# hostNetwork ("not full hostNetwork, which is heavier-handed and
# affects pod DNS") — and hostNetwork: true also has a real API
# constraint that broke sync: it requires hostPort == containerPort on
# every port, which isn't the case here (containerPort 8080/8443 vs
# hostPort 80/443). `false` is both what was actually decided and what
# the API requires for this containerPort/hostPort combination.
hostNetwork: false
useHostPort:
http: true
https: true
# Already the chart default (80/443) — pinned explicitly anyway so a
# future chart bump changing its defaults can't silently change this.
hostPorts:
http: 80
https: 443
resources:
limits:
memory: 128Mi
requests:
cpu: 50m
memory: 64Mi
service:
type: ClusterIP
# Chart default (Local) pairs with the default type: LoadBalancer —
# only valid for LoadBalancer/NodePort services. Must be cleared for
# ClusterIP, which is what the sync error actually said.
externalTrafficPolicy: ""
@@ -1,27 +0,0 @@
replicaCount: 6
labels:
bu: admin
team: devops
env: prd
clusterIP: 10.137.32.2
resources:
limits:
cpu: 100m
memory: 128Mi
requests:
cpu: 100m
memory: 128Mi
tolerations:
- key: "dedicated"
operator: "Equal"
value: "devops"
effect: "NoSchedule"
nodeSelector:
dedicated: devops
kubernetes.io/os: linux
@@ -1,88 +0,0 @@
deploymentType: "StatefulSet"
fullNameOverride: "dind-int"
labels:
bu: infra
team: devops
service: dind-int
env: prd
priority: p0
type: dind
component: jenkins-agent
env:
- name: DOCKER_HOST
value: localhost
replicas: 1
image:
repository: docker
tag: 28-dind
imagePullPolicy: Always
podSecurityContext:
privileged: true
extraArgs:
mtu: 1460
tls: false
host: "tcp://0.0.0.0:2375"
max-concurrent-downloads: 20
max-concurrent-uploads: 20
# host: "unix:///var/run/docker.sock"
resources:
requests:
cpu: 12
memory: 36G
nodeSelector:
dedicated: dind
tolerations:
- key: dedicated
operator: Equal
value: dind
effect: NoSchedule
serviceAccountName: jenkins-prd-agent
persistentVolume:
enabled: true
storageClass: hyperdisk-balanced
accessModes:
- ReadWriteOnce
size: 1000Gi
mountPath: /var/lib/docker
existingClaim: ""
service:
port: 2375
type: ClusterIP
podDisruptionBudget:
enabled: true
minAvailable: 1
probe:
livenessProbe:
failureThreshold: 10
initialDelaySeconds: 30
periodSeconds: 30
successThreshold: 1
tcpSocket:
port: "{{ .Values.service.port }}"
timeoutSeconds: 5
readinessProbe:
failureThreshold: 3
httpGet:
path: /
port: "{{ .Values.service.port }}"
scheme: HTTP
initialDelaySeconds: 5
periodSeconds: 15
successThreshold: 1
timeoutSeconds: 5
@@ -1,88 +0,0 @@
deploymentType: "StatefulSet"
fullNameOverride: "dind-prd"
labels:
bu: infra
team: devops
service: dind-prd
env: prd
priority: p0
type: dind
component: jenkins-agent
env:
- name: DOCKER_HOST
value: localhost
replicas: 1
image:
repository: asia-southeast1-docker.pkg.dev/meesho-devops-admin-0622/admin/devops/docker
tag: 24-dind
imagePullPolicy: Always
podSecurityContext:
privileged: true
extraArgs:
mtu: 1460
tls: false
host: "tcp://0.0.0.0:2375"
max-concurrent-downloads: 20
max-concurrent-uploads: 20
# host: "unix:///var/run/docker.sock"
resources:
requests:
cpu: 12
memory: 36G
nodeSelector:
dedicated: dind
tolerations:
- key: dedicated
operator: Equal
value: dind
effect: NoSchedule
serviceAccountName: jenkins-prd-agent
persistentVolume:
enabled: true
storageClass: sc-pd-standard
accessModes:
- ReadWriteOnce
size: 600Gi
mountPath: /var/lib/docker
existingClaim: dind-prd-pvc-hd
service:
port: 2375
type: ClusterIP
podDisruptionBudget:
enabled: true
minAvailable: 1
probe:
livenessProbe:
failureThreshold: 10
initialDelaySeconds: 30
periodSeconds: 30
successThreshold: 1
tcpSocket:
port: "{{ .Values.service.port }}"
timeoutSeconds: 5
readinessProbe:
failureThreshold: 3
httpGet:
path: /
port: "{{ .Values.service.port }}"
scheme: HTTP
initialDelaySeconds: 5
periodSeconds: 15
successThreshold: 1
timeoutSeconds: 5
@@ -1,379 +0,0 @@
# nameOverride is the short name for the deployment. Leave empty to let Helm generate a name using chart values.
nameOverride: "elastic-operator"
# fullnameOverride is the full name for the deployment. Leave empty to let Helm generate a name using chart values.
fullnameOverride: "elastic-operator"
# managedNamespaces is the set of namespaces that the operator manages. Leave empty to manage all namespaces.
managedNamespaces: []
# installCRDs determines whether Custom Resource Definitions (CRD) are installed by the chart.
# Note that CRDs are global resources and require cluster admin privileges to install.
# If you are sharing a cluster with other users who may want to install ECK on their own namespaces, setting this to true can have unintended consequences.
# 1. Upgrades will overwrite the global CRDs and could disrupt the other users of ECK who may be running a different version.
# 2. Uninstalling the chart will delete the CRDs and potentially cause Elastic resources deployed by other users to be removed as well.
installCRDs: true
# replicaCount is the number of operator pods to run.
replicaCount: 1
image:
# repository is the container image prefixed by the registry name.
repository: docker.elastic.co/eck/eck-operator
# pullPolicy is the container image pull policy.
pullPolicy: IfNotPresent
# tag is the container image tag. If not defined, defaults to chart appVersion.
tag: null
# fips specifies whether the operator will use a FIPS compliant container image for its own StatefulSet image.
# This setting does not apply to Elastic Stack applications images.
# Can be combined with config.ubiOnly.
fips: false
# priorityClassName defines the PriorityClass to be used by the operator pods.
priorityClassName: ""
# imagePullSecrets defines the secrets to use when pulling the operator container image.
imagePullSecrets: []
# resources define the container resource limits for the operator.
resources:
requests:
cpu: 100m
memory: 150Mi
# statefulsetAnnotations define the annotations that should be added to the operator StatefulSet.
statefulsetAnnotations: {}
# statefulsetLabels define additional labels that should be added to the operator StatefulSet.
statefulsetLabels: {}
# podAnnotations define the annotations that should be added to the operator pod.
podAnnotations: {}
## podLabels define additional labels that should be added to the operator pod.
podLabels: {}
# podSecurityContext defines the pod security context for the operator pod.
podSecurityContext:
runAsNonRoot: true
# securityContext defines the security context of the operator container.
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
runAsNonRoot: true
# nodeSelector defines the node selector for the operator pod.
nodeSelector:
elastic: operator
# tolerations defines the node tolerations for the operator pod.
tolerations:
- key: elastic
operator: Equal
value: operator
effect: NoSchedule
# affinity defines the node affinity rules for the operator pod.
affinity: {}
# podDisruptionBudget configures the minimum or the maxium available pods for voluntary disruptions,
# set to either an integer (e.g. 1) or a percentage value (e.g. 25%).
podDisruptionBudget:
enabled: false
minAvailable: 1
# maxUnavailable: 3
# additional environment variables for the operator container.
env: []
# additional volume mounts for the operator container.
volumeMounts: []
# additional volumes to add to the operator pod.
volumes: []
# createClusterScopedResources determines whether cluster-scoped resources (ClusterRoles, ClusterRoleBindings) should be created.
createClusterScopedResources: true
# Automount API credentials for the Service Account into the pod.
automountServiceAccountToken: true
serviceAccount:
# create specifies whether a service account should be created for the operator.
create: true
# Specifies whether a service account should automount API credentials.
automountServiceAccountToken: true
# annotations to add to the service account
annotations: {}
# name of the service account to use. If not set and create is true, a name is generated using the fullname template.
name: ""
tracing:
# enabled specifies whether APM tracing is enabled for the operator.
enabled: false
# config is a map of APM Server configuration variables that should be set in the environment.
config:
ELASTIC_APM_SERVER_URL: http://localhost:8200
ELASTIC_APM_SERVER_TIMEOUT: 30s
refs:
# enforceRBAC specifies whether RBAC should be enforced for cross-namespace associations between resources.
enforceRBAC: false
webhook:
# enabled determines whether the webhook is installed.
enabled: true
# caBundle is the PEM-encoded CA trust bundle for the webhook certificate. Only required if manageCerts is false and certManagerCert is null.
caBundle: Cg==
# certManagerCert is the name of the cert-manager certificate to use with the webhook.
certManagerCert: null
# certsDir is the directory to mount the certificates.
certsDir: "/tmp/k8s-webhook-server/serving-certs"
# failurePolicy of the webhook.
failurePolicy: Ignore
# manageCerts determines whether the operator manages the webhook certificates automatically.
manageCerts: true
# namespaceSelector corresponds to the namespaceSelector property of the webhook.
# Setting this restricts the webhook to act only on objects submitted to namespaces that match the selector.
namespaceSelector: {}
# objectSelector corresponds to the objectSelector property of the webhook.
# Setting this restricts the webhook to act only on objects that match the selector.
objectSelector: {}
# port is the port that the validating webhook binds to.
port: 9443
# secret specifies the Kubernetes secret to be mounted into the path designated by the certsDir value to be used for webhook certificates.
certsSecret: ""
# hostNetwork allows a Pod to use the Node network namespace.
# This is required to allow for communication with the kube API when using some alternate CNIs in conjunction with webhook enabled.
# If hostNetwork is enabled, dnsPolicy defaults to ClusterFirstWithHostNet unless explicitly set.
# CAUTION: Proceed at your own risk. This setting has security concerns such as allowing malicious users to access workloads running on the host.
hostNetwork: false
# dnsPolicy defines the DNS policy for the operator pod.
# Check https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-s-dns-policy for more details.
dnsPolicy: ""
# dnsConfig defines the DNS configuration for the operator pod.
# Check https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-dns-config for more details.
# dnsConfig:
# nameservers:
# - 169.254.20.10
# searches:
# - svc.cluster.local
# options:
# - name: ndots
# value: "2"
dnsConfig: {}
softMultiTenancy:
# enabled determines whether the operator is installed with soft multi-tenancy extensions.
# This requires network policies to be enabled on the Kubernetes cluster.
enabled: false
# kubeAPIServerIP is required when softMultiTenancy is enabled.
kubeAPIServerIP: null
telemetry:
# disabled determines whether the operator periodically updates ECK telemetry data for Kibana to consume.
disabled: false
# distributionChannel denotes which distribution channel was used to install the operator.
distributionChannel: "helm"
# config values for the operator.
config:
# logVerbosity defines the logging level. Valid values are as follows:
# -2: Errors only
# -1: Errors and warnings
# 0: Errors, warnings, and information
# number greater than 0: Errors, warnings, information, and debug details.
logVerbosity: "0"
# (Deprecated: use metrics.port: will be removed in v2.14.0) metricsPort defines the port to expose operator metrics. Set to 0 to disable metrics reporting.
metricsPort: 0
metrics:
# port defines the port to expose operator metrics. Set to 0 to disable metrics reporting.
port: "0"
# secureMode contains the options for enabling and configuring RBAC and TLS/HTTPs for the metrics endpoint.
secureMode:
# secureMode.enabled specifies whether to enable RBAC and TLS/HTTPs for the metrics endpoint.
# * This option makes most sense when using a ServiceMonitor to scrape the metrics and is therefore mutually exclusive with the podMonitor.enabled option.
# * This option also requires using cluster scoped resources (ClusterRole, ClusterRoleBinding) to
# grant access to the /metrics endpoint. (createClusterScopedResources: true is required)
#
enabled: false
tls:
# certificateSecret is the name of the tls secret containing the custom TLS certificate and key for the secure metrics endpoint.
#
# * This is an optional setting and is only required if you are using a custom TLS certificate. A self-signed certificate will be generated by default.
# * TLS secret key must be named tls.crt.
# * TLS key's secret key must be named tls.key.
# * It is assumed to be in the same namespace as the ServiceMonitor.
#
# example: kubectl create secret tls eck-metrics-tls-certificate -n elastic-system \
# --cert=/path/to/tls.crt --key=/path/to/tls.key
certificateSecret: ""
# containerRegistry to use for pulling Elasticsearch and other application container images.
containerRegistry: docker.elastic.co
# containerRepository to use for pulling Elasticsearch and other application container images.
# containerRepository: ""
# containerSuffix suffix to be appended to container images by default. Cannot be combined with -ubiOnly flag
# containerSuffix: ""
# maxConcurrentReconciles is the number of concurrent reconciliation operations to perform per controller.
maxConcurrentReconciles: "3"
# caValidity defines the validity period of the CA certificates generated by the operator.
caValidity: 876000h
# caRotateBefore defines when to rotate a CA certificate that is due to expire.
caRotateBefore: 720h
# caDir defines the directory containing a CA certificate (tls.crt) and its associated private key (tls.key) to be used for all managed resources.
# Setting this makes caRotateBefore and caValidity values ineffective.
caDir: ""
# certificatesValidity defines the validity period of certificates generated by the operator.
certificatesValidity: 876000h
# certificatesRotateBefore defines when to rotate a certificate that is due to expire.
certificatesRotateBefore: 720h
# disableConfigWatch specifies whether the operator watches the configuration file for changes.
disableConfigWatch: false
# exposedNodeLabels is an array of regular expressions of node labels which are allowed to be copied as annotations on Elasticsearch Pods.
exposedNodeLabels:
["topology.kubernetes.io/.*", "failure-domain.beta.kubernetes.io/.*"]
# ipFamily specifies the IP family to use. Possible values: IPv4, IPv6 and "" (auto-detect)
ipFamily: ""
# setDefaultSecurityContext determines whether a default security context is set on application containers created by the operator.
# *note* that the default option now is "auto-detect" to attempt to set this properly automatically when both running
# in an openshift cluster, and a standard kubernetes cluster. Valid values are as follows:
# "auto-detect" : auto detect
# "true" : set pod security context when creating resources.
# "false" : do not set pod security context when creating resources.
setDefaultSecurityContext: "auto-detect"
# kubeClientTimeout sets the request timeout for Kubernetes API calls made by the operator.
kubeClientTimeout: 60s
# elasticsearchClientTimeout sets the request timeout for Elasticsearch API calls made by the operator.
elasticsearchClientTimeout: 180s
# policies contains policies for the operator, currently only password generation policies are supported.
policies: {}
# passwords:
# length: 24
# validateStorageClass specifies whether storage classes volume expansion support should be verified.
# Can be disabled if cluster-wide storage class RBAC access is not available.
validateStorageClass: true
# enableLeaderElection specifies whether leader election should be enabled
enableLeaderElection: true
# Interval between observations of Elasticsearch health, non-positive values disable asynchronous observation.
elasticsearchObservationInterval: 10s
# ubiOnly specifies whether the operator will use only UBI container images to deploy Elastic Stack applications as well as for its own StatefulSet image. UBI images are only available from 7.10.0 onward.
# Cannot be combined with the containerSuffix value.
ubiOnly: false
# Prometheus PodMonitor configuration
# Reference: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#podmonitor
podMonitor:
# enabled determines whether a podMonitor should deployed to scrape the eck metrics.
# This requires the prometheus operator and the config.metrics.port not to be 0
enabled: false
# labels adds additional labels to the podMonitor
labels: {}
# annotations adds additional annotations to the podMonitor
annotations: {}
# namespace determines in which namespace the podMonitor will be deployed.
# If not set the podMonitor will be created in the namespace where the Helm release is installed into
# namespace: monitoring
# interval specifies the interval at which metrics should be scraped
interval: 5m
# scrapeTimeout specifies the timeout after which the scrape is ended
scrapeTimeout: 30s
# podTargetLabels transfers labels on the Kubernetes Pod onto the target.
podTargetLabels: []
# podMetricsEndpointConfig allows to add an extended configuration to the podMonitor
podMetricsEndpointConfig: {}
# honorTimestamps: true
# Prometheus ServiceMonitor configuration
# Only used when config.enableSecureMetrics is true
# Reference: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#servicemonitor
serviceMonitor:
# This option requires the following settings within Prometheus to function:
# 1. RBAC settings for the Prometheus instance to access the metrics endpoint.
#
# - nonResourceURLs:
# - /metrics
# verbs:
# - get
#
# 2. If using the Prometheus Operator and your Prometheus instance is not in the same namespace as the operator you will need
# the Prometheus Operator configured with the following Helm values:
#
# prometheus:
# prometheusSpec:
# serviceMonitorNamespaceSelector: {}
# serviceMonitorSelectorNilUsesHelmValues: false
#
# allows to disable the serviceMonitor, enabled by default for backwards compatibility
enabled: true
# namespace determines in which namespace the serviceMonitor will be deployed.
# If not set the serviceMonitor will be created in the namespace where the Helm release is installed into
# namespace: monitoring
# caSecret is the name of the secret containing the custom CA certificate used to generate the custom TLS certificate for the secure metrics endpoint.
#
# * This *must* be the name of the secret containing the CA certificate used to sign the custom TLS certificate for the metrics endpoint.
# * This secret *must* be in the same namespace as the Prometheus instance that will scrape the metrics.
# * If using the Prometheus operator this secret must be within the `spec.secrets` field of the `Prometheus` custom resource such that it is mounted into the Prometheus pod at `caMountDirectory`, which defaults to /etc/prometheus/secrets/{secret-name}.
# * This is an optional setting and is only required if you are using a custom TLS certificate.
# * Key must be named ca.crt.
#
# example: kubectl create secret generic eck-metrics-tls-ca -n monitoring \
# --from-file=ca.crt=/path/to/ca.pem
caSecret: ""
# caMountDirectory is the directory at which the CA certificate is mounted within the Prometheus pod.
#
# * You should only need to adjust this if you are *not* using the Prometheus operator.
caMountDirectory: "/etc/prometheus/secrets/"
# insecureSkipVerify specifies whether to skip verification of the TLS certificate for the secure metrics endpoint.
#
# * If this setting is set to false, then the following settings are required:
# - certificateSecret
# - caSecret
insecureSkipVerify: true
# Globals meant for internal use only
global:
# manifestGen specifies whether the chart is running under manifest generator.
# This is used for tasks specific to generating the all-in-one.yaml file.
manifestGen: false
# createOperatorNamespace defines whether the operator namespace manifest should be generated when in manifestGen mode.
# Usually we do want that to happen (e.g. all-in-one.yaml) but, sometimes we don't (e.g. E2E tests).
createOperatorNamespace: true
# kubeVersion is the effective Kubernetes version we target when generating the all-in-one.yaml.
kubeVersion: 1.21.0
@@ -1,472 +0,0 @@
## Chart information
nameOverride: ""
fullnameOverride: ""
namespaceOverride: "elastalert-prd"
commonLabels: {}
commonAnnotations: {}
appKubernetesIoComponent: elastalert2
# Folder where Helm can find local rules prior to deployment to the k8s cluster. By default,
# 'rules' folder must be located in the root of the chart directory. Note that this setting
# will override the rules and secretRulesName values. Again, these rules are only read
# during the time of the chart deployment (installation) into the cluster.
# rootRulesFolder: "rules"
# enabledRules: ["deadman_slack", "deadman_pagerduty"]
# number of replicas to run
replicaCount: 1
# update strategy to use (default : RollingUpdate) but can be Recreate
updateStrategy:
type: RollingUpdate
rollingUpdate: {}
# number of helm release revisions to retain
revisionHistoryLimit: 5
# number of seconds for which a newly created Pod should be ready without any of its containers crashing, for it to be considered available.
minReadySeconds: 5
# Default internal between alert checks against the elasticsearch datasource, in minutes
runIntervalMins: 1
# Location of directory where rules reside
rulesFolder: "/opt/elastalert/rules"
# Enable/disabe subdirectory scanning for rules
scanSubdirectories: true
# Default rule buffer duration, in minutes
bufferTimeMins: 15
# Amount of time to retry and deliver failed alerts (1440 minutes per day)
alertRetryLimitMins: 2880
# Default time before realerting, in minutes
realertIntervalMins: ""
# For ES 5: The name of the index which stores elastalert 2 statuses, typically elastalert_status
# For ES 6: The prefix of the names of indices which store elastalert 2 statuses, typically elastalert
#
writebackIndex: elastalert
image:
# docker image
repository: jertel/elastalert2
# docker image tag
tag: 2.29.0
pullPolicy: IfNotPresent
pullSecret: ""
resources:
requests:
memory: 8Gi
cpu: "1"
limits:
memory: 10Gi
cpu: "3"
# Annotations to be added to deployment
deploymentAnnotations: {}
# Annotations to be added to pods
podAnnotations: {}
elasticsearch:
# ECK-managed ES service: <es-name>-es-http.<namespace>.svc.cluster.local
host: eck-observability-prd-es-http.eck-observability-prd.svc.cluster.local
# elasticsearch port
port: 9200
# whether or not to connect to es_host using TLS
# TLS is disabled on the ES HTTP layer (selfSignedCertificate.disabled: true in elasticsearch.yaml)
useSsl: "False"
# Username if authenticating to ES with basic auth
username: "elastic"
# Password if authenticating to ES with basic auth
# Get from: kubectl get secret eck-observability-stg-es-elastic-user -n eck-observability-stg -o jsonpath='{.data.elastic}' | base64 -d
password: "qT448rgRqJkIesBerfrcAXH2"
# Specifies an existing secret to be used for the ES username/password
credentialsSecret: ""
# The key in elasticsearch.credentialsSecret that stores the ES password
credentialsSecretUsernameKey: ""
# The key in elasticsearch.credentialsSecret that stores the ES username
credentialsSecretPasswordKey: ""
# whether or not to verify TLS certificates
# False because TLS is disabled on this cluster
verifyCerts: "False"
# Enable certificate based authentication
# path to a PEM certificate to use as the client certificate
# clientCert: "/certs/client.pem"
# path to a private key file to use as the client key
# clientKey: "/certs/client-key.pem"
# path to a CA cert bundle to use to verify SSL connections
# caCerts: "/certs/ca.pem"
# # certs volumes, required to mount ssl certificates when elasticsearch has tls enabled
# certsVolumes:
# - name: es-certs
# secret:
# defaultMode: 420
# secretName: es-certs
# # mount certs volumes, required to mount ssl certificates when elasticsearch has tls enabled
# certsVolumeMounts:
# - name: es-certs
# mountPath: /certs
# readOnly: true
# Optional env variables for the pod
optEnv: []
## Specify optional additional containers to run alongside the Elastalert2 container.
extraContainers: []
## Specify optional additional initContainers to run prior to the Elastalert2 container.
extraInitContainers: []
extraConfigOptions: {}
# # Options to propagate to all rules, e.g. a common slack_webhook_url or kibana_url
# # Please note at the time of implementing this value, it will not work for required_locals
# # Which MUST be set at the rule level, these are: ['alert', 'type', 'name', 'index']
# kibana_url: https://kibana.yourdomain.com
# slack_webhook_url: dummy
# To load ElastAlert 2 config via secret, uncomment the line below
# secretConfigName: elastalert-config-secret
# Example of a secret config
#apiVersion: v1
#kind: Secret
#metadata:
# name: elastalert-config-secret
#type: Opaque
#stringData:
# elastalert_config: |-
# rules_folder: /opt/elastalert/rules
# scan_subdirectories: false
# run_every:
# minutes: 1
# buffer_time:
# minutes: 15
# es_host: elasticsearch
# es_port: 9200
# writeback_index: elastalert
# use_ssl: False
# verify_certs: True
# alert_time_limit:
# minutes: 2880
# slack_webhook_url: https://hooks.slack.com/services/xxxx
# slack_channel_override: '#alerts'
# To load ElastAlert's rules via secret, uncomment the line below
#secretRulesName: elastalert-rules-secret
# Additionally, you must specificy which rules to load from the secret
#secretRulesList: [ "rule_1", "rule_2" ]
# Example of secret rules
#apiVersion: v1
#kind: Secret
#metadata:
# name: elastalert-rules-secret
# namespace: elastic-system
#type: Opaque
#stringData:
# rule_1: |-
# name: Rule 1
# type: frequency
# index: index1-*
# num_events: 3
# timeframe:
# minutes: 1
# alert:
# - "slack"
# rule_2: |-
# name: Rule 2
# type: frequency
# index: index2-*
# num_events: 5
# timeframe:
# minutes: 10
# alert:
# - "slack"
# Command and args override for container e.g. (https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/)
# command: ["YOUR_CUSTOM_COMMAND"]
# args: ["YOUR", "CUSTOM", "ARGS"]
# specifies the rules volume to be used
rulesVolumeName: "rules"
# additional rule configurations e.g. (http://elastalert2.readthedocs.io/en/latest/)
rules:
multi_index_doc_count_threshold: |-
---
name: "High Doc Count Alert - GCP and GKE Indices"
type: frequency
# 1. Target Index Selection: Combines all indices with these prefixes
index: "gcp-prd-*,gcp-kubeevents-*,gke-mcs-*"
# 2. Threshold: Total count across all matched indices
num_events: 950000000
timeframe:
hours: 1
# 3. Optimization: Essential for Basic Tier and high doc counts
use_count_query: true
doc_type: "_doc"
# 4. Filter: Count everything in those indices
filter:
- query:
match_all: {}
# 5. PagerDuty Action (Configured per your requirements)
alert:
- "pagerduty"
# Routing and Severity
pagerduty_service_key: "63386d7276d24c08d0b795122bfea0b1"
pagerduty_severity: "critical"
# Client and Description
pagerduty_client_name: "high doc alert"
pagerduty_description: "High Document Count Alert: Total count across gcp-prd, gcp-kubeevents, and gke-mcs has exceeded 950,000,000."
# Deduplication Key (to avoid multiple pages for the same spike)
pagerduty_incident_key: "high-doc-count-gcp"
# deadman_slack: |-
# ---
# name: Deadman Switch Slack
# type: frequency
# index: containers-*
# num_events: 3
# timeframe:
# minutes: 3
# filter:
# - term:
# message: "deadmanslack"
# alert:
# - "slack"
# slack:
# slack_webhook_url: dummy
# deadman_pagerduty: |-
# ---
# name: Deadman Switch PagerDuty
# type: frequency
# index: containers-*
# num_events: 3
# timeframe:
# minutes: 3
# filter:
# - term:
# message: "deadmanpd"
# alert:
# - "pagerduty"
# pagerduty:
# pagerduty_service_key: dummy
# pagerduty_client_name: ElastAlert Deadman Switch
# Probes configuration
livenessProbe:
enabled: false
readinessProbe:
enabled: false
serviceAccount:
# Specifies whether a service account should be created
create: true
# Annotations to add to the service account
annotations: {}
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name:
# Enable pod security policy
# https://kubernetes.io/docs/concepts/policy/pod-security-policy/
# DEPRECATED in Kubernetes 1.21 (https://kubernetes.io/blog/2021/04/06/podsecuritypolicy-deprecation-past-present-and-future/)
podSecurityPolicy:
create: false
securityContext:
runAsNonRoot: true
runAsUser: 1000
podSecurityContext:
fsGroup: 1000
runAsUser: 1000
runAsGroup: 1000
# Support using node selectors and tolerations
nodeSelector:
cloud.google.com/gke-nodepool: np-admin-default-v131-prd-ase1
team: shared
# Specify node affinity or anti-affinity specifications
affinity: {}
# Autoscaling configuration
autoscaling:
enabled: true
minReplicas: 2
maxReplicas: 5
targetCPUUtilizationPercentage: 80
targetMemoryUtilizationPercentage: 80
# Optional automatic SMTP mail server credential management.
# smtp_auth:
# username: ""
# password: ""
extraVolumes: []
# - name: smtp-auth
# secret:
# secretName: elastalert-smtp-auth
# items:
# - key: smtp_auth.yaml
# path: smtp_auth.yaml
# mode: 0400
extraVolumeMounts: []
# - name: smtp-auth
# mountPath: /opt/elastalert/config-smtp/smtp_auth.yaml
# subPath: smtp_auth.yaml
# readOnly: true
## @section Metrics parameters
## Prometheus metrics
##
metrics:
## @param metrics.enabled Enable the export of Prometheus metrics
##
enabled: false
prometheusPort: 8080
prometheusPortName: http-alt
# Prometheus Exporter defined by port:
prometheusScrapeAnnotations:
prometheus.io/scrape: "true"
prometheus.io/path: "/"
service:
type: ClusterIP
# clusterIP: ""
# externalTrafficPolicy: Cluster
# loadBalancerIP: ""
# loadBalancerSourceRanges: {}
# nodePorts: ""
## Prometheus Operator ServiceMonitor configuration
##
serviceMonitor:
## @param metrics.serviceMonitor.enabled Specify if a ServiceMonitor will be deployed for Prometheus Operator
##
enabled: false
## @param metrics.serviceMonitor.namespace Namespace in which Prometheus is running
##
namespace: ""
## @param metrics.serviceMonitor.labels Extra labels for the ServiceMonitor
## Normally used for prometheus operator to detect the servicemonitor if deployed to different namespace
## labels:
## release: prometheus-operator
labels: {}
## @param metrics.serviceMonitor.jobLabel The name of the label on the target service to use as the job name in Prometheus
##
jobLabel: ""
## @param metrics.serviceMonitor.interval How frequently to scrape metrics
## e.g:
## interval: 10s
##
interval: ""
## @param metrics.serviceMonitor.scrapeTimeout Timeout after which the scrape is ended
## e.g:
## scrapeTimeout: 10s
##
scrapeTimeout: ""
## @param metrics.serviceMonitor.metricRelabelings [array] Specify additional relabeling of metrics
## metricRelabelings:
## # Drop GO metrics
## - sourceLabels: [__name__]
## regex: go_.*
## action: drop
## # Drop python_gc metrics
## - sourceLabels: [__name__]
## regex: python_gc.*
## action: drop
## # Normalise POD names
## - sourceLabels: [pod]
## regex: (.+elastalert2)\-([\w\d]+)\-([\w\d]+)
## replacement: $1
## targetLabel: pod
metricRelabelings: []
## @param metrics.serviceMonitor.relabelings [array] Specify general relabeling
##
relabelings: []
## @param metrics.serviceMonitor.selector Prometheus instance selector labels
## ref: https://github.com/bitnami/charts/tree/master/bitnami/prometheus-operator#prometheus-configuration
##
selector: {}
## PrometheusRule CRD configuration
##
prometheusRule:
## @param metrics.prometheusRule.enabled If `true`, creates a Prometheus Operator PrometheusRule (also requires `metrics.enabled` to be `true`)
##
enabled: false
## @param metrics.prometheusRule.namespace Namespace in which the PrometheusRule CRD is created
##
namespace: ""
## @param metrics.prometheusRule.additionalLabels Additional labels for the prometheusRule
## to be detected by prometheus-operator
## additionalLabels:
## release: prometheus-operator
additionalLabels: {}
## @param metrics.prometheusRule.rules Prometheus Rules for ElastAlert 2.
## These are just examples rules, please adapt them to your needs.
## rules: |-
## groups:
## - name: elastalert
## rules:
## - alert: elastalert Pod down
## annotations:
## description: Prometheus is unable to scrape metrics service. Check pod logs for details
## summary: elastalert POD is down
## expr: up{service="{{ template "common.names.servicename" . }}",container="elastalert"} == 0
## for: 5m
## labels:
## severity: critical
## production: 'True'
## - alert: elastalert file descriptors use
## annotations:
## description: Elastalert pod nearly exhausting file descriptors
## summary: too many file descriptors used
## expr: |-
## process_open_fds{service="{{ template "common.names.servicename" . }}",container="elastalert"}
## /
## process_max_fds{service="{{ template "common.names.servicename" . }}",container="elastalert"}
## > 0.9
## for: 3m
## labels:
## severity: critical
## production: 'True'
## - alert: elastalert scrapes failing
## annotations:
## description: Elastalert is not scraping for a rule {{ "{{" }} $labels.rule_name {{ "}}" }}
## summary: scrapes for rule stalled {{ "{{" }} $labels.rule_name {{ "}}" }}
## expr: |-
## rate(elastalert_scrapes_total{service="{{ template "common.names.servicename" . }}",container="elastalert"}[1m]) == 0
## for: 5m
## labels:
## severity: critical
## production: 'True'
rules: []
@@ -1,38 +0,0 @@
# Argo CD Application: dedicated monitoring ES + Kibana for Stack Monitoring (metrics store).
# Deploy after ECK operator; same namespace as main observability (eck-observability-prd)
---
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: eck-observability-monitoring-k8s-admin-prd-ase1
namespace: argocd-prd
finalizers:
- resources-finalizer.argocd.argoproj.io
labels:
bu: infra
team: devops
env: prd
cluster: k8s-admin-prd-ase1
spec:
project: default
source:
repoURL: https://github.com/Meesho/devops-infra-helm-charts
path: helm-overrides/k8s-admin-prd-ase1/elastic-cluster/eck-observability-monitoring
targetRevision: main
directory:
recurse: false
include: "*.yaml"
destination:
server: ""
name: k8s-admin-prd-ase1
namespace: eck-observability-prd
syncPolicy:
syncOptions:
- CreateNamespace=true
- ServerSideApply=true
retry:
limit: 5
backoff:
duration: 5s
factor: 2
maxDuration: 3m
@@ -1,45 +0,0 @@
# Argo CD Application: ECK observability manifests (Elasticsearch, Kibana, APM, HTTPProxy, SA, Namespace).
# Deploys to cluster: k8s-admin-prd-ase1
#
# Apply:
# kubectl apply -f argo-launch.yaml -n argocd
#
# (ECK operator Helm chart is separate — install elastic-system operator before this app syncs.)
---
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: eck-observability-k8s-admin-prd-ase1
namespace: argocd-prd
finalizers:
- resources-finalizer.argocd.argoproj.io
labels:
bu: infra
team: devops
env: prd
cluster: k8s-admin-prd-ase1
spec:
project: default
source:
repoURL: https://github.com/Meesho/devops-infra-helm-charts
path: helm-overrides/k8s-admin-prd-ase1/elastic-cluster/eck-observability
targetRevision: main
directory:
recurse: false
include: "*.yaml"
# Example secret is not applied from git; create the real Secret separately
exclude: "*example.yaml"
destination:
server: ""
name: k8s-admin-prd-ase1
namespace: eck-observability-prd
syncPolicy:
syncOptions:
- CreateNamespace=true
- ServerSideApply=true
retry:
limit: 5
backoff:
duration: 5s
factor: 2
maxDuration: 3m
@@ -1,63 +0,0 @@
# Dedicated monitoring Elasticsearch for Stack Monitoring metrics (ECK observability workload).
# Namespace: prd-eck-observability (same as main observability stack).
# Pattern mirrors eck-monitoring (single nodeSet); 3 nodes × 90Gi SSD (gke-pd-ssd).
# Align nodeSelector/tolerations with your GKE pool (same as prd-eck-observability by default).
apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
name: eck-observability-monitoring-prd
namespace: eck-observability-prd
spec:
version: 9.3.1
nodeSets:
- name: default
count: 3
volumeClaimTemplates:
- metadata:
name: elasticsearch-data
spec:
storageClassName: gke-pd-ssd
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 500Gi
podTemplate:
metadata:
labels:
elasticsearch.k8s.elastic.co/service-account: eck-observability-monitoring-es-sa-prd
app: elasticsearch-monitoring
tier: monitoring
annotations:
cluster-autoscaler.kubernetes.io/safe-to-evict: "false"
spec:
serviceAccountName: eck-observability-monitoring-es-sa-prd
tolerations:
- effect: NoSchedule
key: elastic-observability-monitoring-nodes
operator: Equal
value: "true"
nodeSelector:
elastic-observability-monitoring-nodes: "true"
initContainers:
- name: sysctl
securityContext:
privileged: true
runAsUser: 0
command: ["sh", "-c", "sysctl -w vm.max_map_count=262144"]
containers:
- name: elasticsearch
env:
- name: ES_JAVA_OPTS
value: "-Xms22g -Xmx22g"
resources:
requests:
memory: 107Gi
cpu: "20"
limits:
memory: 107Gi
cpu: "25"
http:
tls:
selfSignedCertificate:
disabled: true
@@ -1,24 +0,0 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: es-prd-observability-monitoring-nginx
namespace: eck-observability-prd
annotations:
kubernetes.io/ingress.class: nginx-internal
nginx.ingress.kubernetes.io/ssl-redirect: "false"
nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
nginx.ingress.kubernetes.io/proxy-send-timeout: "300"
nginx.ingress.kubernetes.io/proxy-body-size: "0"
spec:
ingressClassName: nginx-internal
rules:
- host: es-prd-observability-monitoring.prd.meesho.int
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: eck-observability-monitoring-prd-es-http
port:
number: 9200
@@ -1,24 +0,0 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: kibana-prd-observability-monitoring-nginx
namespace: eck-observability-prd
annotations:
kubernetes.io/ingress.class: nginx-internal
nginx.ingress.kubernetes.io/ssl-redirect: "false"
nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
nginx.ingress.kubernetes.io/proxy-send-timeout: "300"
nginx.ingress.kubernetes.io/proxy-body-size: "0"
spec:
ingressClassName: nginx-internal
rules:
- host: kibana-prd-observability-monitoring.prd.meesho.int
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: kibana-observability-monitoring-prd-kb-http
port:
number: 5601
@@ -1,38 +0,0 @@
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: kibana-observability-monitoring-prd-hpa
namespace: eck-observability-prd
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: kibana-observability-monitoring-prd-kb
minReplicas: 1
maxReplicas: 5
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 50
periodSeconds: 60
scaleUp:
stabilizationWindowSeconds: 30
policies:
- type: Percent
value: 100
periodSeconds: 30
@@ -1,47 +0,0 @@
# Kibana for the monitoring cluster (Stack Monitoring UI / metrics exploration).
apiVersion: kibana.k8s.elastic.co/v1
kind: Kibana
metadata:
name: kibana-observability-monitoring-prd
namespace: eck-observability-prd
spec:
version: 9.3.1
config:
server.publicBaseUrl: http://kibana-prd-observability-monitoring.prd.meesho.int
monitoring.ui.ccs.enabled: false
count: 1
elasticsearchRef:
name: eck-observability-monitoring-prd
podTemplate:
metadata:
annotations:
cluster-autoscaler.kubernetes.io/safe-to-evict: "false"
spec:
tolerations:
- effect: NoSchedule
key: elastic-observability-monitoring-common
operator: Equal
value: "true"
nodeSelector:
elastic-observability-monitoring-common: "true"
containers:
- name: kibana
readinessProbe:
httpGet:
path: /api/status
port: 5601
initialDelaySeconds: 30
periodSeconds: 10
failureThreshold: 3
resources:
requests:
memory: 40Gi
cpu: "9"
limits:
memory: 40Gi
cpu: "12"
http:
tls:
selfSignedCertificate:
disabled: true
@@ -1,14 +0,0 @@
# pd-ssd - SSD-class block storage on GKE (pd.csi.storage.gke.io).
# Apply once per cluster before Elasticsearch PVCs.
# See: https://cloud.google.com/kubernetes-engine/docs/concepts/persistent-volumes
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: gke-pd-ssd
provisioner: pd.csi.storage.gke.io
parameters:
type: pd-ssd
replication-type: none
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
reclaimPolicy: Retain
@@ -1,5 +0,0 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: eck-observability-monitoring-es-sa-prd
namespace: eck-observability-prd
@@ -1,38 +0,0 @@
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: apm-eck-observability-prd-hpa
namespace: eck-observability-prd
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: apm-eck-observability-prd-apm-server
minReplicas: 3
maxReplicas: 5
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 50
periodSeconds: 60
scaleUp:
stabilizationWindowSeconds: 30
policies:
- type: Percent
value: 100
periodSeconds: 30
@@ -1,23 +0,0 @@
# APM Server (HTTP + OTLP/gRPC on 8200) — Contour HTTPProxy.
# For OTLP gRPC, uses protocol h2c (HTTP/2 Cleartext); works with both gRPC and HTTP agents.
apiVersion: projectcontour.io/v1
kind: HTTPProxy
metadata:
name: apm-prd-observability
namespace: eck-observability-prd
annotations:
projectcontour.io/ingress.class: contour-internal
spec:
ingressClassName: contour-internal
virtualhost:
fqdn: apm-eck-observability.prd.meesho.int
routes:
- conditions:
- prefix: /
services:
- name: apm-eck-observability-prd-apm-http
port: 8200
protocol: h2c
timeoutPolicy:
response: "300s"
idle: "300s"
@@ -1,40 +0,0 @@
# APM Server for eck-observability-prd: traces and APM data land in this Elasticsearch cluster.
apiVersion: apm.k8s.elastic.co/v1
kind: ApmServer
metadata:
name: apm-eck-observability-prd
namespace: eck-observability-prd
spec:
version: 9.3.1
count: 3
elasticsearchRef:
name: eck-observability-prd
namespace: eck-observability-prd
kibanaRef:
name: kibana-eck-observability-prd
namespace: eck-observability-prd
podTemplate:
metadata:
annotations:
cluster-autoscaler.kubernetes.io/safe-to-evict: "false"
spec:
nodeSelector:
elastic-observability-common-nodes: "true"
tolerations:
- effect: NoSchedule
key: elastic-observability-common-nodes
operator: Equal
value: "true"
containers:
- name: apm-server
resources:
requests:
memory: 50Gi
cpu: 26
limits:
memory: 50Gi
cpu: 29
http:
tls:
selfSignedCertificate:
disabled: true
@@ -1,181 +0,0 @@
# Elasticsearch for observability: logs, traces (via APM), hot/warm tiers.
# Stack monitoring: metrics + logs ship to eck-observability-monitoring-prd (ECK-managed ref).
# Topology: 3× (master + data_hot + ingest), 2× (data_warm + ingest), 6g heap, 500Gi disk per node.
# Tolerations: align with your GKE node pool taint (key/value below).
# ILM: configure index templates to route hot → warm (data_hot / data_warm) in Kibana / API.
# SSO: Google login is handled at nginx + oauth2-proxy (ingress), not Elasticsearch OIDC (Platinum).
apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
name: eck-observability-prd
namespace: eck-observability-prd
spec:
version: 9.3.1
monitoring:
metrics:
elasticsearchRefs:
- name: eck-observability-monitoring-prd
namespace: eck-observability-prd
logs:
elasticsearchRefs:
- name: eck-observability-monitoring-prd
namespace: eck-observability-prd
nodeSets:
# 3 nodes: master-eligible + data_hot + ingest (schedule on tainted pool)
- name: hot
count: 9
config:
node.roles: ["data_hot", "ingest", "data_content", "transform"]
volumeClaimTemplates:
- metadata:
name: elasticsearch-data
spec:
storageClassName: gke-hyperdisk-balanced-35k
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 4Ti
podTemplate:
metadata:
labels:
elasticsearch.k8s.elastic.co/service-account: eck-observability-es-sa-prd
elasticsearch.k8s.elastic.co/nodeset: hot
elasticsearch.k8s.elastic.co/tier: hot-warm-data
elasticsearch.k8s.elastic.co/tier22: hot-warm-data-22
annotations:
cluster-autoscaler.kubernetes.io/safe-to-evict: "false"
spec:
serviceAccountName: eck-observability-es-sa-prd
# Tolerations for dedicated ES node pool (edit key/value to match your taint)
tolerations:
- effect: NoSchedule
key: elastic-observability-hot-nodes
operator: Equal
value: "true"
nodeSelector:
elastic-observability-hot-nodes: "true"
initContainers:
- name: sysctl
securityContext:
privileged: true
runAsUser: 0
command: ['sh', '-c', 'sysctl -w vm.max_map_count=262144']
containers:
- name: elasticsearch
env:
- name: ES_JAVA_OPTS
value: "-Xms31g -Xmx31g"
resources:
requests:
memory: 110Gi
cpu: "26"
limits:
memory: 110Gi
cpu: "28"
# 2 nodes: data_warm + ingest (schedule on tainted pool)
- name: warm
count: 6
config:
node.roles: ["data_warm", "ingest", "data_content"]
volumeClaimTemplates:
- metadata:
name: elasticsearch-data
spec:
storageClassName: gke-hyperdisk-ssd
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 6.5Ti
podTemplate:
metadata:
labels:
elasticsearch.k8s.elastic.co/service-account: eck-observability-es-sa-prd
elasticsearch.k8s.elastic.co/nodeset: warm
elasticsearch.k8s.elastic.co/tier: hot-warm-data
annotations:
cluster-autoscaler.kubernetes.io/safe-to-evict: "false"
spec:
serviceAccountName: eck-observability-es-sa-prd
tolerations:
- effect: NoSchedule
key: elastic-observability-warm-nodes
operator: Equal
value: "true"
nodeSelector:
elastic-observability-warm-nodes: "true"
initContainers:
- name: sysctl
securityContext:
privileged: true
runAsUser: 0
command: ['sh', '-c', 'sysctl -w vm.max_map_count=262144']
containers:
- name: elasticsearch
env:
- name: ES_JAVA_OPTS
value: "-Xms31g -Xmx31g"
resources:
requests:
memory: 107Gi
cpu: "24"
limits:
memory: 107Gi
cpu: "26"
# 3 nodes: master-only (dedicated cluster state management)
- name: master
count: 3
config:
node.roles: ["master"]
volumeClaimTemplates:
- metadata:
name: elasticsearch-data
spec:
storageClassName: gke-hyperdisk-ssd
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 200Gi
podTemplate:
metadata:
labels:
elasticsearch.k8s.elastic.co/service-account: eck-observability-es-sa-prd
elasticsearch.k8s.elastic.co/nodeset: master
annotations:
cluster-autoscaler.kubernetes.io/safe-to-evict: "false"
spec:
serviceAccountName: eck-observability-es-sa-prd
tolerations:
- effect: NoSchedule
key: elastic-observability-master-nodes
operator: Equal
value: "true"
nodeSelector:
elastic-observability-master-nodes: "true"
initContainers:
- name: sysctl
securityContext:
privileged: true
runAsUser: 0
command: ['sh', '-c', 'sysctl -w vm.max_map_count=262144']
containers:
- name: elasticsearch
env:
- name: ES_JAVA_OPTS
value: "-Xms5g -Xmx5g"
resources:
requests:
memory: 10Gi
cpu: "5"
limits:
memory: 10Gi
cpu: "6"
http:
tls:
selfSignedCertificate:
disabled: true
@@ -1,19 +0,0 @@
apiVersion: v1
kind: Service
metadata:
name: eck-observability-prd-es-hot-warm
namespace: eck-observability-prd
labels:
app: elasticsearch
elasticsearch.k8s.elastic.co/cluster-name: eck-observability-prd
elasticsearch.k8s.elastic.co/tier: hot-warm-data
spec:
type: ClusterIP
ports:
- port: 9200
targetPort: 9200
protocol: TCP
name: http
selector:
elasticsearch.k8s.elastic.co/cluster-name: eck-observability-prd
elasticsearch.k8s.elastic.co/tier: hot-warm-data
@@ -1,21 +0,0 @@
apiVersion: projectcontour.io/v1
kind: HTTPProxy
metadata:
name: es-prd-observability
namespace: eck-observability-prd
annotations:
projectcontour.io/ingress.class: contour-internal
spec:
ingressClassName: contour-internal
virtualhost:
fqdn: es-prd-observability.prd.meesho.int
routes:
- conditions:
- prefix: /
services:
# Unified ES HTTP service (no dedicated coordinating/client node set)
- name: eck-observability-prd-es-http
port: 9200
timeoutPolicy:
response: "300s"
idle: "300s"
@@ -1,35 +0,0 @@
# HTTPProxy for Kibana + OAuth2-proxy
# Routes /oauth2/* to oauth2-proxy (auth endpoints)
# Routes all other paths to Kibana
apiVersion: projectcontour.io/v1
kind: HTTPProxy
metadata:
name: kibana-prd-observability-oauth
namespace: eck-observability-prd
annotations:
projectcontour.io/ingress.class: contour-internal
spec:
ingressClassName: contour-internal
virtualhost:
fqdn: kibana-prd-observability.prd.meesho.int
routes:
# Route 1: OAuth2-proxy auth endpoints (/oauth2/auth, /oauth2/start, /oauth2/callback)
- conditions:
- prefix: /oauth2
services:
- name: oauth2-proxy-kibana
port: 4180
timeoutPolicy:
response: "30s"
idle: "30s"
# Route 2: All other routes go to Kibana
- conditions:
- prefix: /
services:
- name: kibana-eck-observability-prd-kb-http
port: 5601
timeoutPolicy:
response: "300s"
idle: "300s"
@@ -1,20 +0,0 @@
apiVersion: projectcontour.io/v1
kind: HTTPProxy
metadata:
name: kibana-prd-observability
namespace: eck-observability-prd
annotations:
projectcontour.io/ingress.class: contour-internal
spec:
ingressClassName: contour-internal
virtualhost:
fqdn: kibana-prd-observability.prd.meesho.int
routes:
- conditions:
- prefix: /
services:
- name: kibana-eck-observability-prd-kb-http
port: 5601
timeoutPolicy:
response: "300s"
idle: "300s"
@@ -1,27 +0,0 @@
# APM Server (HTTP + OTLP/gRPC on 8200) — nginx-internal (alternative to Contour HTTPProxy).
# For OTLP gRPC, nginx ingress may require backend-protocol GRPC; tune if agents use HTTP only.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: apm-prd-observability-nginx
namespace: eck-observability-prd
annotations:
kubernetes.io/ingress.class: nginx-internal
nginx.ingress.kubernetes.io/ssl-redirect: "false"
nginx.ingress.kubernetes.io/backend-protocol: "GRPC"
nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
nginx.ingress.kubernetes.io/proxy-send-timeout: "300"
nginx.ingress.kubernetes.io/proxy-body-size: "0"
spec:
ingressClassName: nginx-internal
rules:
- host: apm-eck-observability.prd.meesho.int
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: apm-eck-observability-prd-apm-http
port:
number: 8200
@@ -1,25 +0,0 @@
# Elasticsearch HTTP API — nginx-internal (alternative to Contour HTTPProxy).
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: es-prd-observability-nginx
namespace: eck-observability-prd
annotations:
kubernetes.io/ingress.class: nginx-internal
nginx.ingress.kubernetes.io/ssl-redirect: "false"
nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
nginx.ingress.kubernetes.io/proxy-send-timeout: "300"
nginx.ingress.kubernetes.io/proxy-body-size: "0"
spec:
ingressClassName: nginx-internal
rules:
- host: es-prd-observability.prd.meesho.int
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: eck-observability-prd-es-http
port:
number: 9200
@@ -1,50 +0,0 @@
# Kibana — nginx-internal with Google OAuth via oauth2-proxy.
# Ref: https://medium.com/@hrlimaye/google-oauth2-with-kubernetes-nginx-controller-d7a0a3e62e1b
#
# nginx auth_request flow:
# 1. Request hits this ingress for path /
# 2. nginx makes internal subrequest to auth-url (cluster-internal DNS, always resolvable from nginx pod)
# 3. oauth2-proxy returns 202 (valid cookie) -> request passes to Kibana
# oauth2-proxy returns 401 (no/bad cookie) -> nginx redirects browser to auth-signin
# 4. auth-signin uses $host (browser redirect, not internal subrequest - $host is fine here)
# -> oauth2-proxy starts Google login flow -> /oauth2/callback -> sets cookie -> back to Kibana
#
# Why auth-url uses cluster DNS (not $host):
# auth-url is an nginx internal subrequest - nginx tries to resolve it from inside the pod.
# External hostnames like prd.meesho.int may not resolve from within the nginx controller pod.
# auth-signin is a browser redirect, so $host works fine there.
#
# Requires:
# - Secret oauth2-proxy-google applied (oauth2-proxy-secret.example.yaml)
# - oauth2-proxy Deployment + Service (oauth2-proxy.yaml)
# - /oauth2 Ingress on same host (ingress-oauth2-proxy.yaml)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: kibana-prd-observability-nginx
namespace: eck-observability-prd
annotations:
kubernetes.io/ingress.class: nginx-internal
nginx.ingress.kubernetes.io/ssl-redirect: "false"
nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
nginx.ingress.kubernetes.io/proxy-send-timeout: "300"
nginx.ingress.kubernetes.io/proxy-body-size: "0"
nginx.ingress.kubernetes.io/proxy-buffer-size: "16k"
# auth-url: cluster-internal DNS so nginx can always reach oauth2-proxy for the subrequest.
nginx.ingress.kubernetes.io/auth-url: "http://oauth2-proxy-kibana.eck-observability-prd.svc.cluster.local:4180/oauth2/auth"
# auth-signin: browser redirect — $host resolves to the request Host header in the browser.
nginx.ingress.kubernetes.io/auth-signin: "http://$host/oauth2/start?rd=$escaped_request_uri"
nginx.ingress.kubernetes.io/auth-response-headers: "X-Auth-Request-Email, X-Auth-Request-User"
spec:
ingressClassName: nginx-internal
rules:
- host: kibana-prd-observability.prd.meesho.int
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: kibana-eck-observability-prd-kb-http
port:
number: 5601
@@ -1,25 +0,0 @@
# oauth2-proxy routes (/oauth2/*) on the same host as Kibana.
# No auth_request on this Ingress — otherwise the /oauth2/start and /oauth2/callback
# paths would loop trying to authenticate themselves.
# Ref: https://medium.com/@hrlimaye/google-oauth2-with-kubernetes-nginx-controller-d7a0a3e62e1b
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: oauth2-proxy-kibana-nginx
namespace: eck-observability-prd
annotations:
kubernetes.io/ingress.class: nginx-internal
nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
ingressClassName: nginx-internal
rules:
- host: kibana-prd-observability.prd.meesho.int
http:
paths:
- path: /oauth2
pathType: Prefix
backend:
service:
name: oauth2-proxy-kibana
port:
number: 4180
@@ -1,38 +0,0 @@
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: kibana-eck-observability-prd-hpa
namespace: eck-observability-prd
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: kibana-eck-observability-prd-kb
minReplicas: 1
maxReplicas: 5
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 50
periodSeconds: 60
scaleUp:
stabilizationWindowSeconds: 30
policies:
- type: Percent
value: 100
periodSeconds: 30
@@ -1,61 +0,0 @@
# Anonymous auth: Kibana logs into ES as credentials.username using the password from Secret
# kibana-anonymous-sso (required; anonymous cannot work without it). Must match that ES user.
# Google SSO is only at the ingress (oauth2-proxy). See kibana-anonymous-sso.example.yaml.
apiVersion: kibana.k8s.elastic.co/v1
kind: Kibana
metadata:
name: kibana-eck-observability-prd
namespace: eck-observability-prd
spec:
version: 9.3.1
secureSettings:
- secretName: kibana-anonymous-sso
config:
server.publicBaseUrl: http://kibana-prd-observability.prd.meesho.int
monitoring.ui.ccs.enabled: false
xpack.security.authc.providers:
anonymous.anonymous1:
order: 0
credentials:
username: kibana-anonymous-viewer
password: "${xpack.security.authc.providers.anonymous.anonymous1.credentials.password}"
basic.basic1:
order: 1
count: 1
elasticsearchRef:
name: eck-observability-prd
podTemplate:
metadata:
annotations:
cluster-autoscaler.kubernetes.io/safe-to-evict: "false"
spec:
tolerations:
- effect: NoSchedule
key: elastic-observability-common-nodes
operator: Equal
value: "true"
nodeSelector:
elastic-observability-common-nodes: "true"
containers:
- name: kibana
# Override ECK's default readiness probe (/login → 404 when anonymous auth is enabled).
# /api/status returns 200 whenever Kibana is healthy, regardless of auth config.
readinessProbe:
httpGet:
path: /api/status
port: 5601
initialDelaySeconds: 30
periodSeconds: 10
failureThreshold: 3
resources:
requests:
memory: 25Gi
cpu: 10
limits:
memory: 25Gi
cpu: 13
http:
tls:
selfSignedCertificate:
disabled: true
@@ -1,6 +0,0 @@
# apiVersion: v1
# kind: Namespace
# metadata:
# name: eck-observability-prd
# annotations:
# argocd.argoproj.io/sync-wave: "-1"
@@ -1,147 +0,0 @@
# oauth2-proxy: Google OAuth at the nginx ingress layer.
# Ref: https://medium.com/@hrlimaye/google-oauth2-with-kubernetes-nginx-controller-d7a0a3e62e1b
#
# Flow:
# 1. Request hits nginx ingress for Kibana (ingress-kibana.yaml).
# 2. nginx calls auth-url -> oauth2-proxy /oauth2/auth (200 = pass, 401 = redirect to signin).
# 3. On 401, nginx redirects to auth-signin (oauth2-proxy /oauth2/start) -> Google login.
# 4. Google redirects back to /oauth2/callback (served by ingress-oauth2-proxy.yaml).
# 5. Authenticated request proceeds to Kibana.
#
# Requires Secret "oauth2-proxy-google" (see oauth2-proxy-secret.example.yaml).
# Google OAuth app: Authorized redirect URI must be set to:
# http://kibana-prd-observability.prd.meesho.int/oauth2/callback
apiVersion: v1
kind: Service
metadata:
name: oauth2-proxy-kibana
namespace: eck-observability-prd
labels:
app: oauth2-proxy-kibana
spec:
type: ClusterIP
ports:
- name: http
port: 4180
targetPort: 4180
selector:
app: oauth2-proxy-kibana
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: oauth2-proxy-kibana
namespace: eck-observability-prd
labels:
app: oauth2-proxy-kibana
spec:
replicas: 1
selector:
matchLabels:
app: oauth2-proxy-kibana
template:
metadata:
labels:
app: oauth2-proxy-kibana
annotations:
cluster-autoscaler.kubernetes.io/safe-to-evict: "false"
spec:
tolerations:
- effect: NoSchedule
key: elastic-observability-common-nodes
operator: Equal
value: "true"
nodeSelector:
elastic-observability-common-nodes: "true"
containers:
- name: oauth2-proxy
image: quay.io/oauth2-proxy/oauth2-proxy:v7.6.0
args:
- --provider=google
- --http-address=0.0.0.0:4180
# upstream=static://200 means oauth2-proxy only handles /oauth2/* paths;
# actual proxying to Kibana is done by nginx, not oauth2-proxy.
- --upstream=static://200
- --skip-provider-button=true
# Allow any Google-authenticated user; restrict by setting --email-domain=meesho.com
- --email-domain=*
- --cookie-secure=false
- --set-xauthrequest=true
- --pass-access-token=false
- --redirect-url=http://kibana-prd-observability.prd.meesho.int/oauth2/callback
envFrom:
- secretRef:
name: oauth2-proxy-google
ports:
- name: http
containerPort: 4180
readinessProbe:
httpGet:
path: /ping
port: 4180
initialDelaySeconds: 5
periodSeconds: 10
resources:
requests:
cpu: 9
memory: 25Gi
limits:
cpu: 13
memory: 25Gi
---
# HorizontalPodAutoscaler for oauth2-proxy-kibana Deployment
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: oauth2-proxy-kibana-hpa
namespace: eck-observability-prd
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: oauth2-proxy-kibana
minReplicas: 1
maxReplicas: 10
metrics:
# CPU-based scaling: target 70% CPU utilization
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
# Memory-based scaling: target 80% memory utilization
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 50
periodSeconds: 60
scaleUp:
stabilizationWindowSeconds: 30
policies:
- type: Percent
value: 100
periodSeconds: 30
- type: Pods
value: 2
periodSeconds: 60
# kubectl exec -it eck-observability-prd-es-hot-0 -n eck-observability-prd \
# -- curl -s -u "elastic:$(kubectl get secret eck-observability-prd-es-elastic-user -n eck-observability-prd -o jsonpath='{.data.elastic}' | base64 -d)" \
# -X POST "http://localhost:9200/_security/user/kibana-anonymous-viewer" \
# -H "Content-Type: application/json" \
# -d '{
# "password": "ViewerPass@2026",
# "roles": ["viewer"],
# "full_name": "Kibana Anonymous Viewer",
# "enabled": true
# }'
@@ -1,15 +0,0 @@
# Hyperdisk Balanced with 35k IOPS — High performance SSD on GKE (pd.csi.storage.gke.io).
# Apply once per cluster before Elasticsearch PVCs. Requires GKE version that supports Hyperdisk.
# See: https://cloud.google.com/kubernetes-engine/docs/how-to/persistent-volumes/hyperdisk
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: gke-hyperdisk-balanced-35k
provisioner: pd.csi.storage.gke.io
parameters:
type: hyperdisk-balanced
provisioned-throughput-on-create: "2000Mi"
provisioned-iops-on-create: "35000"
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
reclaimPolicy: Retain
@@ -1,14 +0,0 @@
# Hyperdisk Balanced — SSD-class block storage on GKE (pd.csi.storage.gke.io).
# Apply once per cluster before Elasticsearch PVCs. Requires GKE version that supports Hyperdisk.
# See: https://cloud.google.com/kubernetes-engine/docs/how-to/persistent-volumes/hyperdisk
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: gke-hyperdisk-ssd
provisioner: pd.csi.storage.gke.io
parameters:
type: hyperdisk-balanced
replication-type: none
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
reclaimPolicy: Retain
@@ -1,9 +0,0 @@
apiVersion: net.gke.io/v1
kind: ServiceExport
metadata:
name: apm-eck-observability-prd-apm-http
namespace: eck-observability-prd
#apm-eck-observability-prd-apm-http.eck-observability-prd.svc.clusterset.local
#eck-observability-prd-es-hot-warm.eck-observability-prd.svc.clusterset.local
@@ -1,5 +0,0 @@
apiVersion: net.gke.io/v1
kind: ServiceExport
metadata:
name: eck-observability-prd-es-hot-warm
namespace: eck-observability-prd
@@ -1,5 +0,0 @@
apiVersion: net.gke.io/v1
kind: ServiceExport
metadata:
name: eck-observability-prd-es-http
namespace: eck-observability-prd
@@ -1,7 +0,0 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: eck-observability-es-sa-prd
namespace: eck-observability-prd
annotations:
iam.gke.io/gcp-service-account: eck-prd@meesho-admin-dev-0622.iam.gserviceaccount.com
@@ -1,37 +0,0 @@
external-secrets:
# Fresh install — nothing runs this today, so no adoption gotchas here
# (unlike gitea/vault/contour). Replaces the Vault Agent Injector as the
# path for getting secrets into pods (see the injector.enabled: false
# note in ../vault/custom-values.yaml) — nothing is wired to a
# SecretStore/ClusterSecretStore backend yet, that's a separate step
# once this controller itself is up and healthy.
#
# installCRDs defaults to true — leaving it, this is a fresh cluster
# with no existing SecretStore/ExternalSecret CRs whose schema this
# could clobber.
#
# All three components (controller, webhook, cert-controller) default
# to unbounded resources — every other app in this repo gets trimmed
# requests/limits for the same reason, staying consistent here.
resources:
requests:
cpu: 25m
memory: 32Mi
limits:
memory: 128Mi
webhook:
resources:
requests:
cpu: 25m
memory: 32Mi
limits:
memory: 64Mi
certController:
resources:
requests:
cpu: 25m
memory: 32Mi
limits:
memory: 64Mi
@@ -1,55 +0,0 @@
# Default values for flagger.
image:
repository: asia-southeast1-docker.pkg.dev/meesho-devops-admin-0622/admin/flagger
tag: hpa-changes-26
# accepted values are debug, info, warning, error (defaults to info)
logLevel: info
podAnnotations:
prometheus.io/scrape: "true"
prometheus.io/port: "8080"
appmesh.k8s.aws/sidecarInjectorWebhook: disabled
crd:
# crd.create: `true` if custom resource definitions should be created
create: false
resources:
limits:
memory: "1024Mi"
cpu: "2"
requests:
memory: "512Mi"
cpu: "500m"
nodeSelector:
dedicated: devops
tolerations:
- effect: NoSchedule
key: dedicated
operator: Equal
value: devops
prometheus:
install: false
image: docker.io/prom/prometheus:v2.39.1
pullSecret:
retention: 2h
securityContext:
enabled: false
context:
readOnlyRootFilesystem: true
runAsUser: 10001
podDisruptionBudget:
enabled: false
minAvailable: 1
podLabels:
env: prd
team: devops
bu: infra
@@ -1,679 +0,0 @@
nameOverride: ""
fullnameOverride: ""
# DaemonSet, Deployment or StatefulSet
kind: "DaemonSet"
# azureblob, cloudwatch, elasticsearch7, elasticsearch8, gcs, graylog , kafka, kafka2, kinesis, opensearch
variant: gcs
# # Only applicable for Deployment or StatefulSet
# replicaCount: 1
image:
repository: "asia-southeast1-docker.pkg.dev/meesho-devops-admin-0622/admin/sre/fluentd-v2"
pullPolicy: "Always"
tag: "edge-debian"
## Optional array of imagePullSecrets containing private registry credentials
## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
imagePullSecrets: []
serviceAccount:
create: true
annotations: {
iam.gke.io/gcp-service-account: sa-admn-adsre-fluentd-prd@meesho-admin-prd-0622.iam.gserviceaccount.com
}
name: null
rbac:
create: true
# from Kubernetes 1.25, PSP is deprecated
# See: https://kubernetes.io/blog/2022/08/23/kubernetes-v1-25-release/#pod-security-changes
# We automatically disable PSP if Kubernetes version is 1.25 or higher
podSecurityPolicy:
enabled: true
annotations: {}
## Security Context policies for controller pods
## See https://kubernetes.io/docs/tasks/administer-cluster/sysctl-cluster/ for
## notes on enabling and using sysctls
##
podSecurityContext: {}
# seLinuxOptions:
# type: "spc_t"
securityContext: {}
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
# Configure the livecycle
# Ref: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/
lifecycle: {}
# preStop:
# exec:
# command: ["/bin/sh", "-c", "sleep 20"]
# Configure the livenessProbe
# Ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/
#livenessProbe:
# httpGet:
# path: /metrics
# port: metrics
# initialDelaySeconds: 0
# periodSeconds: 10
# timeoutSeconds: 1
# successThreshold: 1
# failureThreshold: 3
# Configure the readinessProbe
# Ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/
#readinessProbe:
# httpGet:
# path: /metrics
# port: metrics
# initialDelaySeconds: 0
# periodSeconds: 10
# timeoutSeconds: 1
# successThreshold: 1
# failureThreshold: 3
resources:
requests:
cpu: 100m
memory: 50Mi
limits:
memory: 2000Mi
cpu: 2000m
## only available if kind is Deployment
autoscaling:
enabled: false
minReplicas: 1
maxReplicas: 100
targetCPUUtilizationPercentage: 80
# targetMemoryUtilizationPercentage: 80
## see https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/#autoscaling-on-multiple-metrics-and-custom-metrics
customRules: []
# - type: Pods
# pods:
# metric:
# name: packets-per-second
# target:
# type: AverageValue
# averageValue: 1k
## see https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/#support-for-configurable-scaling-behavior
# behavior:
# scaleDown:
# policies:
# - type: Pods
# value: 4
# periodSeconds: 60
# - type: Percent
# value: 10
# periodSeconds: 60
priorityClassName: "system-node-critical"
nodeSelector: {}
## Node tolerations for server scheduling to nodes with taints
## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/
##
tolerations:
- operator: Exists
## Affinity and anti-affinity
## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity
##
affinity: {}
## Annotations to be added to fluentd DaemonSet/Deployment
##
annotations: {}
## Labels to be added to fluentd DaemonSet/Deployment
##
labels:
bu: admin
team: sre
type: fluentd
service: fluentd-admin-prd
priority: p0
env: prd
## Annotations to be added to fluentd pods
##
podAnnotations: {}
## Labels to be added to fluentd pods
##
podLabels:
bu: admin
team: sre
type: fluentd
service: fluentd-admin-prd
priority: p0
env: prd
## How long (in seconds) a pods needs to be stable before progressing the deployment
##
minReadySeconds:
## How long (in seconds) a pod may take to exit (useful with lifecycle hooks to ensure lb deregistration is done)
##
terminationGracePeriodSeconds:
## Deployment strategy / DaemonSet updateStrategy
##
updateStrategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 25%
maxSurge: 0
## Additional environment variables to set for fluentd pods
## Additional environment variables to set for fluentd pods
env:
- name: APP_NAME
value: namespace_name
- name: SUB_SYSTEM
value: container_name
# - name: FLUENTD_CONF
# value: "../../etc/fluent/fluent.conf"
- name: APP_NAME_SYSTEMD
value: systemd
- name: SUB_SYSTEM_SYSTEMD
value: kubelet.service
- name: ENDPOINT
value: ingress.coralogixsg.com
- name: LOG_LEVEL
value: error
- name: TZ
value: "Asia/Kolkata"
- name: K8S_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
externalSecret:
secretStoreRef:
name: vault-backend
path: prd/admin/coralogix-keys
# externalSecret:
# enabled: true
# key: dev/devops/coralogix
# secretStoreRef:
# name: vault-backend
envFrom:
- secretRef:
name: integrations-privatekey
- secretRef:
name: es-password
initContainers: []
## Name of the configMap containing a custom fluentd.conf configuration file to use instead of the default.
# mainConfigMapNameOverride: ""
## Name of the configMap containing files to be placed under /etc/fluent/config.d/
## NOTE: This will replace ALL default files in the aforementioned path!
# extraFilesConfigMapNameOverride: ""
mountVarLogDirectory: true
mountDockerContainersDirectory: true
volumes: []
# - name: varlog
# hostPath:
# path: /var/log
# - name: varlibdockercontainers
# hostPath:
# path: /var/lib/docker/containers
# - name: etcfluentd-main
# configMap:
# name: fluentd-main
# defaultMode: 0777
# - name: etcfluentd-config
# configMap:
# name: fluentd-config
# defaultMode: 0777
volumeMounts: []
# - name: varlog
# mountPath: /var/log
# - name: varlibdockercontainers
# mountPath: /var/lib/docker/containers
# readOnly: true
# - name: etcfluentd-main
# mountPath: /etc/fluent
# - name: etcfluentd-config
# mountPath: /etc/fluent/config.d/
## Only available if kind is StatefulSet
## Fluentd persistence
##
persistence:
enabled: false
storageClass: ""
accessMode: ReadWriteOnce
size: 10Gi
## Fluentd service
##
service:
enabled: true
type: "ClusterIP"
annotations: {}
# loadBalancerIP:
# externalTrafficPolicy: Local
ports: []
# - name: "forwarder"
# protocol: TCP
# containerPort: 24224
## Prometheus Monitoring
##
metrics:
serviceMonitor:
enabled: false
additionalLabels:
release: prometheus-operator
namespace: ""
namespaceSelector: {}
## metric relabel configs to apply to samples before ingestion.
##
metricRelabelings: []
# - sourceLabels: [__name__]
# separator: ;
# regex: ^fluentd_output_status_buffer_(oldest|newest)_.+
# replacement: $1
# action: drop
## relabel configs to apply to samples after ingestion.
##
relabelings: []
# - sourceLabels: [__meta_kubernetes_pod_node_name]
# separator: ;
# regex: ^(.*)$
# targetLabel: nodename
# replacement: $1
# action: replace
## Additional serviceMonitor config
##
# jobLabel: fluentd
# scrapeInterval: 30s
# scrapeTimeout: 5s
# honorLabels: true
prometheusRule:
enabled: false
additionalLabels: {}
namespace: ""
rules: []
# - alert: FluentdDown
# expr: up{job="fluentd"} == 0
# for: 5m
# labels:
# context: fluentd
# severity: warning
# annotations:
# summary: "Fluentd Down"
# description: "{{ $labels.pod }} on {{ $labels.nodename }} is down"
# - alert: FluentdScrapeMissing
# expr: absent(up{job="fluentd"} == 1)
# for: 15m
# labels:
# context: fluentd
# severity: warning
# annotations:
# summary: "Fluentd Scrape Missing"
# description: "Fluentd instance has disappeared from Prometheus target discovery"
## Grafana Monitoring Dashboard
##
dashboards:
enabled: "true"
namespace: ""
labels:
grafana_dashboard: '"1"'
## Fluentd list of plugins to install
##
plugins: []
# - fluent-plugin-out-http
## Add fluentd config files from K8s configMaps
##
configMapConfigs: []
# - fluentd-prometheus-conf
# - fluentd-systemd-conf
## Fluentd configurations:
##
fileConfigs:
01_sources.conf: |-
<source>
@type systemd
path /var/log/journal
tag sys-log
read_from_head true
</source>
<source>
@id fluentd-containers.log
@type tail
encoding utf-8
path /var/log/containers/*.log
pos_file /var/log/containers.log.pos
exclude_path ["/var/log/containers/*telegraf*.log"]
path_key filename
tag raw.containers.*
read_from_head true
<parse>
@type multi_format
<pattern>
format json
time_key time
time_format %Y-%m-%dT%H:%M:%S.%NZ
keep_time_key true
</pattern>
<pattern>
format /^(?<time>.+) (?<stream>stdout|stderr) [^ ]* (?<log>.*)$/
time_format %Y-%m-%dT%H:%M:%S.%N%:z
keep_time_key true
</pattern>
<pattern>
format /^(?<log>fsp\s+.+)$/
ignorecase false
multiline false
</pattern>
</parse>
</source>
<match raw.containers.**>
@id raw.containers
@type detect_exceptions
remove_tag_prefix raw
message log
stream stream
multiline_flush_interval 5
max_bytes 500000
max_lines 1000
</match>
<filter containers.**>
@type kubernetes_metadata
</filter>
<filter containers.**>
@type record_transformer
enable_ruby true
<record>
container_id ${record.dig("docker", "container_id")}
</record>
</filter>
<match containers.**>
@type rewrite_tag_filter
<rule>
key $.kubernetes.namespace_name
pattern ^(.+)$
tag $1.${tag}
</rule>
</match>
02_filters.conf: |-
03_dispatch.conf: |-
<match {kube**,**coredns**,**external-secrets**,**keda**,**gke-mcs**,sys-log,**victoriametrics**,**grafana**,**sonarqube**}>
@type "relabel"
@label @NOCONCATDISPATCH
</match>
<match {**prd**,**int**} >
@type "relabel"
@label @CONCATDISPATCH
</match>
<label @CONCATDISPATCH>
<filter {**prd**,**int**}>
@type concat
key log
stream_identity_key container_id
multiline_start_regexp /^.+\d{2}\:\d{2}\:\d{2}\.\d{3}/
separator "\n"
flush_interval 30
timeout_label @DISPATCH
</filter>
<match **>
@type "relabel"
@label @DISPATCH
</match>
</label>
<label @DISPATCH>
<match {vault-admin-prd.**} >
@type "gcs"
bucket "perf-infr-test-orders-tiered-stanpshot"
path "admin/${tag[0]}/dt=%d.%m.%Y/hr=%H/${tag[5]}"
time_slice_format %Y%m%d%H
object_key_format "%{path}/%{time_slice}_%{index}.%{file_extension}"
store_as "gzip"
<format>
@type "json"
localtime true
</format>
<buffer tag,time>
timekey 30m
@type "file"
path "/tmp/td-agent/vault-buffer/"
flush_thread_count 2
timekey_wait 10m
chunk_limit_size 50m
flush_at_shutdown true
</buffer>
</match>
<match {**prd**} >
@type copy
<store>
@type "gcs"
bucket "gcs-infr-dvps-meesho-logs-prd"
path "admin/${tag[0]}/dt=%d.%m.%Y/hr=%H/${tag[5]}"
time_slice_format %Y%m%d%H
object_key_format "%{path}/%{time_slice}_%{index}.%{file_extension}"
store_as "gzip"
<format>
@type "json"
localtime true
</format>
<buffer tag,time>
timekey 30m
@type "file"
path "/tmp/td-agent/buffer/"
flush_thread_count 2
timekey_wait 10m
chunk_limit_size 50m
flush_at_shutdown true
</buffer>
</store>
<store>
@type "relabel"
@label @PRD
</store>
</match>
<match {**int**} >
@type copy
<store>
@type "relabel"
@label @PREPROD
</store>
</match>
</label>
<label @PRD>
<filter {**prd**}>
@type grep
<regexp>
key log
pattern /ERROR|WARN|error|warn/
</regexp>
</filter>
<filter **>
@type record_transformer
enable_ruby true
auto_typecast true
renew_record true
<record>
application_name ${record.dig("kubernetes", "namespace_name")}
service_name ${record.dig("kubernetes", "container_name")}
host ${record.dig("kubernetes", "host")}
pod_name ${record.dig("kubernetes", "pod_name")}
pod_ip ${record.dig("kubernetes", "pod_ip")}
text ${record.dig("log")}
</record>
</filter>
<match {**prd**}>
@type elasticsearch
host eck-observability-prd-es-hot-warm.eck-observability-prd.svc.cluster.local
port 9200
scheme http
compression_level best_speed
ssl_verify false
emit_error_for_missing_id true
id_key request_id
user elastic
index_name gcp-prd
password "#{ENV['ECK_ES_PASSWORD']}"
reload_on_failure true
reconnect_on_error true
include_timestamp true
request_timeout 60s
</match>
</label>
<label @NOCONCATDISPATCH>
<filter sys-log >
@type record_transformer
enable_ruby true
auto_typecast true
renew_record true
renew_time_key ${record.dig("SYSLOG_TIMESTAMP")}
<record>
cluster_name "admin-prd"
application_name "systemd"
node_name ${record.dig("_HOSTNAME")}
text ${record.to_json}
</record>
</filter>
<filter {kube**,**coredns**,**external-secrets**,**keda**,**gke-mcs**,**victoriametrics**,**grafana**,**sonarqube**}>
@type record_transformer
enable_ruby true
auto_typecast true
renew_record true
<record>
application_name ${record.dig("kubernetes", "namespace_name")}
service_name ${record.dig("kubernetes", "container_name")}
host ${record.dig("kubernetes", "host")}
pod_name ${record.dig("kubernetes", "pod_name")}
pod_ip ${record.dig("kubernetes", "pod_ip")}
text ${record.dig("log")}
</record>
</filter>
<match {**kube-events**,**kube-system**,**external-secrets**,**keda**,sys-log,**victoriametrics**,**grafana**,**sonarqube**}>
@type elasticsearch
host eck-observability-prd-es-hot-warm.eck-observability-prd.svc.cluster.local
port 9200
scheme http
compression_level best_speed
ssl_verify false
emit_error_for_missing_id true
id_key request_id
user elastic
index_name gcp-kubeevents
password "#{ENV['ECK_ES_PASSWORD']}"
reload_on_failure true
reconnect_on_error true
include_timestamp true
request_timeout 60s
</match>
<match {**gke-mcs**}>
@type elasticsearch
host eck-observability-prd-es-hot-warm.eck-observability-prd.svc.cluster.local
port 9200
scheme http
compression_level best_speed
ssl_verify false
emit_error_for_missing_id true
id_key request_id
user elastic
index_name gke-mcs
password "#{ENV['ECK_ES_PASSWORD']}"
reload_on_failure true
reconnect_on_error true
include_timestamp true
request_timeout 60s
</match>
<match **>
@type elasticsearch
host eck-observability-prd-es-hot-warm.eck-observability-prd.svc.cluster.local
port 9200
scheme http
compression_level best_speed
ssl_verify false
emit_error_for_missing_id true
id_key request_id
user elastic
index_name gcp-prd
password "#{ENV['ECK_ES_PASSWORD']}"
reload_on_failure true
reconnect_on_error true
include_timestamp true
request_timeout 60s
</match>
</label>
<label @PREPROD>
<filter {**int**}>
@type grep
<regexp>
key log
pattern /INFO|ERROR|WARN|info|error|warn/
</regexp>
</filter>
<filter **>
@type record_transformer
enable_ruby true
auto_typecast true
renew_record true
<record>
application_name ${record.dig("kubernetes", "namespace_name")}
service_name ${record.dig("kubernetes", "container_name")}
host ${record.dig("kubernetes", "host")}
pod_name ${record.dig("kubernetes", "pod_name")}
pod_ip ${record.dig("kubernetes", "pod_ip")}
text ${record.dig("log")}
</record>
</filter>
<match {**int**}>
@type elasticsearch
host eck-observability-prd-es-hot-warm.eck-observability-prd.svc.cluster.local
port 9200
scheme http
compression_level best_speed
ssl_verify false
emit_error_for_missing_id true
id_key request_id
user elastic
index_name gcp-int
password "#{ENV['ECK_ES_PASSWORD']}"
reload_on_failure true
reconnect_on_error true
include_timestamp true
request_timeout 60s
</match>
</label>
04_outputs.conf: |-
@@ -1,108 +0,0 @@
gitea:
# Adopting the standalone install from localvm-kubernetes-setup's
# deploy_gitea.sh (helm release "gitea", namespace "gitea") — same
# config, translated to values so it's GitOps-managed from here on.
# See devops-infra-argo-config values/admin/incubator-infra-k8s-admin-prd-ase1-values.yaml
# for the nameOverride that makes Argo's render match the existing
# release/object names instead of creating a second Gitea.
#
# sqlite + valkey/postgres disabled: sqlite is enough for a lab, and
# the valkey-cluster pod was stuck Pending until the StorageClass was
# fixed (claude.md issue #2/#3) — disabling it avoids that dependency.
# persistence.size must stay 10Gi to match the already-bound PVC —
# local-path-provisioner doesn't support volume expansion.
# Chart default is RollingUpdate with maxUnavailable: 0 — the new pod
# always comes up before the old one terminates. On a real multi-node
# cluster with real RWO block storage that's fine (the new pod just
# can't mount until the old one releases). On this single-node cluster,
# local-path-provisioner's hostPath-style volume doesn't block a second
# same-node mount, so old+new pods briefly run concurrently against the
# same /data — and Gitea's LevelDB-backed queue holds an exclusive file
# lock, so the new pod crashes with "unable to lock level db ...
# resource temporarily unavailable". Recreate forces the old pod to
# fully terminate (and release the lock) before the new one starts.
strategy:
type: Recreate
# Scopes Replace=true to ONLY the Deployment (not the whole Application —
# see the note in devops-infra-argo-config's values file for why that
# broke the PVC). The `configure-gitea` init container's
# GITEA_ADMIN_USERNAME/PASSWORD env vars still carry plaintext `value`
# fields on the live object from the original imperative install; ours
# switch those to `valueFrom: secretKeyRef` (below), and a patch can't
# clear the old field while adding the new one. A full PUT of just this
# one resource sidesteps that. Safe to remove once the live Deployment
# no longer carries the old `value` fields — after that first successful
# sync, plain patching is fine again.
deployment:
annotations:
argocd.argoproj.io/sync-options: Replace=true
persistence:
size: 10Gi
postgresql:
enabled: false
postgresql-ha:
enabled: false
valkey:
enabled: false
valkey-cluster:
enabled: false
resources:
requests:
cpu: 100m
memory: 300Mi
limits:
memory: 500Mi
gitea:
config:
database:
DB_TYPE: sqlite3
actions:
ENABLED: true
security:
# Gitea's own SSRF protection blocks outbound webhook calls to
# private/internal IPs by default — hit this trying to fire a
# webhook at jenkins.192.168.1.7.nip.io ("webhook can only call
# allowed HTTP servers"). Everything on this homelab lives on a
# private LAN, so a narrow allowlist would just mean editing
# this every time a new *.192.168.1.7.nip.io/*.100.90.248.118.nip.io
# host needs webhook access — matches the lightweight security
# posture already used elsewhere here (ArgoCD --insecure, plain
# HTTP throughout).
ALLOWED_HOST_LIST: "*"
admin:
username: gitadmin
# The running install set this via a plaintext --set-string flag at
# install time. Correction from an earlier version of this comment:
# this is NOT install-time only — the `configure-gitea` init
# container re-runs GITEA_ADMIN_PASSWORD_MODE: keepUpdated on every
# pod (re)start, actively syncing the admin password from whatever
# this env var resolves to. That's what caused the value->valueFrom
# migration conflict fixed above — this Secret must exist and be
# correct before the Deployment syncs.
#
# As of the Vault + External Secrets Operator migration, this Secret
# is no longer manually kubectl-created — it's managed by the
# ExternalSecret at devops-infra-argo-config/secretstores/gitea-admin-credentials.yaml,
# sourced from Vault path secret/gitea/admin. Rotate the password via
# `vault kv put secret/gitea/admin ...`, not kubectl, from here on.
existingSecret: gitea-admin-credentials
email: "admin@local.lab"
ingress:
enabled: true
className: contour
hosts:
- host: gitea.192.168.1.7.nip.io
paths:
- path: /
pathType: Prefix
- host: gitea.100.90.248.118.nip.io
paths:
- path: /
pathType: Prefix
@@ -1,68 +0,0 @@
fullnameOverride: grafana-edge-infra-prd
replicas: 1
image:
tag: "11.3.1"
ingress:
enabled: true
ingressClassName: nginx-internal
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "false"
nginx.ingress.kubernetes.io/force-ssl-redirect: "false"
nginx.ingress.kubernetes.io/client_header_buffer_size: "512k"
nginx.ingress.kubernetes.io/large_client_header_buffers: "4 512k"
nginx.ingress.kubernetes.io/proxy-body-size: "0"
path: /
pathType: Prefix
hosts:
- grafana-edge-prd.meeshogcp.in
resources:
limits:
cpu: 7
memory: 6Gi
requests:
cpu: 3.5
memory: 3Gi
nodeSelector:
dedicated: "grafana"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "grafana"
effect: "NoSchedule"
adminUser: admin
externalSecrets:
refreshInterval: "150s"
secretStoreRef:
name: vault-backend
kind: ClusterSecretStore
dataFrom:
secretKey: "admin/common-infra/grafana-edge-infra-prd"
envFromSecrets:
- name: grafana-edge-infra-prd-secret
optional: false
grafana.ini:
server:
root_url: "https://{{ if (and .Values.ingress.enabled .Values.ingress.hosts) }}{{ .Values.ingress.hosts | first }}{{ else }}''{{ end }}"
enable_gzip: true
users:
auto_assign_org_role: "Editor"
auth.proxy:
enabled: true
header_name: "X-WEBAUTH-USER"
header_property: "username"
metrics:
enabled: true
disable_total_stats: false
plugins:
- yesoreyeram-infinity-datasource
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -1,112 +0,0 @@
harbor:
# Fresh install (helm list -n harbor came back empty — claude.md's "Just
# installed this session" note was stale). Minimal footprint by request:
# Trivy disabled (Notary/ChartMuseum aren't even in this chart anymore —
# dropped upstream, not something to disable), database/redis are
# Harbor's own required internal state (not optional the way Trivy is,
# despite what I initially suggested), everything else trimmed.
#
# Plain HTTP, matching every other app here (Vault tls_disable, ArgoCD
# --insecure, etc.) — avoids cert-manager entirely for this homelab.
# Note: this only affects the ingress. Jenkins pushing images should go
# through Harbor's internal cluster-DNS service (harbor-core.harbor.svc.cluster.local)
# instead, per claude.md's own plan — pod-to-pod traffic never touches
# the ingress, so no client-side insecure-registry config needed for CI.
# Pulling/pushing from outside the cluster (e.g. your laptop) through the
# ingress WOULD need Docker configured to treat this host as an insecure
# registry, since there's no TLS here.
expose:
type: ingress
tls:
enabled: false
ingress:
hosts:
core: "harbor.192.168.1.7.nip.io"
className: contour
externalURL: "http://harbor.192.168.1.7.nip.io"
# Vault-backed from the start, same pattern as jenkins-admin-credentials.
# See devops-infra-argo-config/secretstores/harbor-admin-credentials.yaml
# and vault kv path secret/harbor/admin.
existingSecretAdminPassword: harbor-admin-credentials
existingSecretAdminPasswordKey: HARBOR_ADMIN_PASSWORD
trivy:
enabled: false
persistence:
enabled: true
resourcePolicy: "keep"
persistentVolumeClaim:
registry:
storageClass: local-path
size: 5Gi
jobservice:
jobLog:
storageClass: local-path
size: 1Gi
database:
storageClass: local-path
size: 1Gi
redis:
storageClass: local-path
size: 1Gi
portal:
resources:
requests:
cpu: 50m
memory: 128Mi
limits:
memory: 256Mi
core:
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
memory: 512Mi
jobservice:
resources:
requests:
cpu: 50m
memory: 128Mi
limits:
memory: 256Mi
registry:
registry:
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
memory: 256Mi
controller:
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
memory: 128Mi
database:
internal:
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
memory: 512Mi
redis:
internal:
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
memory: 128Mi
@@ -1,34 +0,0 @@
ingress-nginx:
controller:
metrics:
enabled: true
podAnnotations:
prometheus.io/port: "10254"
prometheus.io/scrape: "true"
resources:
requests:
cpu: 200m
memory: 512Mi
autoscaling:
enabled: true
minReplicas: 4
maxReplicas: 30
targetCPUUtilizationPercentage: 60
targetMemoryUtilizationPercentage: 60
ingressClass: nginx-external
ingressClassByName: true
watchIngressWithoutClass: false
ingressClassResource:
controllerValue: k8s.io/ingress-nginx-external
name: nginx-external
service:
type: ClusterIP
annotations:
cloud.google.com/neg: '{"exposed_ports": {"80":{"name": "nginx-ext-admin-prd"}}}'
nodeSelector:
dedicated: devops
tolerations:
- key: "dedicated"
operator: "Equal"
value: "devops"
effect: "NoSchedule"
@@ -1,32 +0,0 @@
ingress-nginx:
controller:
config:
proxy-body-size: "50g"
metrics:
enabled: true
podAnnotations:
prometheus.io/port: "10254"
prometheus.io/scrape: "true"
resources:
requests:
cpu: 200m
memory: 512Mi
autoscaling:
enabled: true
minReplicas: 4
maxReplicas: 30
targetCPUUtilizationPercentage: 60
targetMemoryUtilizationPercentage: 60
ingressClassResource:
name: nginx-internal
service:
type: ClusterIP
annotations:
cloud.google.com/neg: '{"exposed_ports": {"80":{"name": "nginx-admin-prd"}}}'
nodeSelector:
dedicated: devops
tolerations:
- key: "dedicated"
operator: "Equal"
value: "devops"
effect: "NoSchedule"
@@ -1,98 +0,0 @@
jenkins:
# Fresh install. Dynamic Kubernetes build agents come from agent.enabled
# (chart default, not overridden here) — agent pods only exist during
# builds, matching claude.md's "idle cost is just the controller" note.
# Trimmed agent pod resources below anyway, since they still compete for
# the same 8GB box while a build is running.
controller:
image:
# Chart's default (unset here) falls back to appVersion 2.504.2 —
# but the chart's own bundled default plugin list (kubernetes,
# credentials, workflow-*, git, etc.) requires Jenkins core
# >= 2.504.3. Upstream inconsistency between the chart's pinned
# image tag and its own default plugins.txt, not our config —
# bumping the core image is the fix, not trimming plugins (several
# of them, especially `kubernetes`, are what dynamic build agents
# actually depend on).
tag: "2.504.3-jdk21"
# Chart default installPlugins list pins configuration-as-code at
# 1971.vf9280461ea_89, but kubernetes/git/credentials — also in that
# same default list — need 2006.v001a_2ca_6b_574. Another upstream
# chart-defaults inconsistency, same category as the image tag one
# above. Lists replace wholesale in Helm, not merge, so this is the
# chart's full default list with just that one version corrected —
# not a hand-picked subset.
#
# kubernetes-client-api added explicitly (not part of the chart's
# default list) — kubernetes originally pinned at 4353.vb_47977da_9417
# required kubernetes-client-api >= 7.3.1-256.v788a_0b_787114
# (confirmed via https://plugins.jenkins.io/kubernetes/dependencies/),
# but left unpinned it resolved to an older version at image-build
# time, producing `NoSuchMethodError:
# ConfigBuilder.withMasterUrl(String)` on every agent launch attempt
# — pods provisioned fine but the controller crashed trying to
# actually connect the agent (Reaper.preLaunch -> KubernetesCloud.connect
# -> KubernetesFactoryAdapter.createClient), so builds hung forever at
# "Still waiting to schedule task". kubernetes itself later bumped to
# 4437.v3a_18554d3f32 (updated via the Jenkins UI, then pinned here
# to match so a future restart doesn't silently revert it) — same
# kubernetes-client-api floor, and this exact pairing is what got a
# real build through checkout successfully.
installPlugins:
- kubernetes:4437.v3a_18554d3f32
- kubernetes-client-api:7.3.1-256.v788a_0b_787114
- workflow-aggregator:608.v67378e9d3db_1
- git:5.7.0
- configuration-as-code:2006.v001a_2ca_6b_574
# readYaml (loadConfig.groovy's config.yaml parsing) and any future
# writeYaml/readJSON-type usage — not part of the chart's default
# list at all, missing entirely rather than version-mismatched like
# kubernetes-client-api above.
- pipeline-utility-steps:3.810.va_7672d206740
resources:
requests:
cpu: 100m
memory: 512Mi
limits:
cpu: 500m
memory: 1Gi
admin:
# Vault-backed from the start (unlike gitea, which started as a
# plain kubectl secret and got migrated later) — see
# devops-infra-argo-config/secretstores/jenkins-admin-credentials.yaml
# and vault kv path secret/jenkins/admin.
existingSecret: jenkins-admin-credentials
userKey: jenkins-admin-user
passwordKey: jenkins-admin-password
ingress:
enabled: true
hostName: "jenkins.192.168.1.7.nip.io"
ingressClassName: contour
# This chart's primary ingress only supports one hostName — no
# extraHosts like argo-cd. secondaryingress renders a whole second
# Ingress object at the same backend (confirmed against the actual
# template, not assumed) — that's the supported way to get a second
# hostname here. paths must be set explicitly: the template just
# renders zero routes if left at the chart's own default `[]`, unlike
# the primary ingress.
secondaryingress:
enabled: true
hostName: "jenkins.100.90.248.118.nip.io"
ingressClassName: contour
paths:
- /
agent:
resources:
requests:
cpu: 250m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
persistence:
enabled: true
storageClass: local-path
size: 5Gi
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -1,26 +0,0 @@
keda:
operator:
replicaCount: 2
metricsServer:
replicaCount: 2
nodeSelector:
dedicated: devops
tolerations:
- key: "dedicated"
operator: "Equal"
value: "devops"
effect: "NoSchedule"
podLabels:
bu: "infra"
team: "devops"
metricsAdapter:
bu: "infra"
team: "devops"
resources:
webhooks:
limits:
cpu: 50m
memory: 150Mi
requests:
cpu: 10m
memory: 25Mi
@@ -1,2 +0,0 @@
stubDomains: >-
{"clusterset.local":["169.254.169.254"]}
@@ -1,149 +0,0 @@
fullnameOverride: kube-events-infra-prd
operator:
enabled: true
image:
repository: kubesphere/kube-events-operator
tag: "" # If unset use v+ .Chart.appVersion
pullPolicy: IfNotPresent
configReloader:
image: jimmidyson/configmap-reload:v0.7.1
affinity: {}
nodeSelector:
dedicated: "sre-shared-tmp"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "sre-shared-tmp"
effect: "NoSchedule"
resources:
limits:
cpu: 200m
memory: 200Mi
requests:
cpu: 20m
memory: 20Mi
# Additional volumes on the Deployment definition.
volumes: []
# Additional volumeMounts on the Deployment definition.
volumeMounts: []
serviceAccount:
create: true
name: ""
# If true, just clean up cr but not crd
cleanupAllCustomResources: false
kubectlImage: docker.io/bitnami/kubectl:1.14.1
exporter:
enabled: true
image:
repository: kubesphere/kube-events-exporter
tag: "" # If unset use v+ .Chart.appVersion
pullPolicy: IfNotPresent
affinity: {}
nodeSelector:
dedicated: "sre-shared-tmp"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "sre-shared-tmp"
effect: "NoSchedule"
resources:
limits:
cpu: 200m
memory: 500Mi
requests:
cpu: 20m
memory: 50Mi
# Additional volumes on the output Deployment definition.
volumes: []
# Additional volumeMounts on the output Deployment definition.
volumeMounts: []
sinks:
stdout:
enabled: true
additionalWebhooks: []
# - url:
# service:
# namespace:
# name:
# port:
# path:
# Configure fluentbit(operated by https://github.com/fluent/fluent-operator) to collect events logs of exporter.
# These will be applied only when exporter.stdout.enabled=true and fluentbit.enabled=true.
fluentbit:
enabled: false
# Set this to containerd or crio if you want fluentbit to collect CRI format logs.
# If not set, it will be auto detected.
containerRuntime: ""
input:
enabled: true
tail:
refreshIntervalSeconds: 10
memBufLimit: 5MB
skipLongLines: true
dbSync: Normal
filter:
enabled: true
additionalFilters: []
output:
enabled: true
opensearch:
host: opensearch-cluster-data.kubesphere-logging-system.svc
port: 9200
logstashPrefix: ks-whizard-events
suppressTypeName: true
logstashFormat: true
generateID: true
ruler:
enabled: false
replicas: 2
image:
repository: kubesphere/kube-events-ruler
tag: "" # If unset use v+ .Chart.appVersion
pullPolicy: IfNotPresent
affinity: {}
nodeSelector:
dedicated: "sre-shared-tmp"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "sre-shared-tmp"
effect: "NoSchedule"
resources:
limits:
cpu: 500m
memory: 500Mi
requests:
cpu: 50m
memory: 50Mi
# Additional volumes on the output Deployment definition.
volumes: []
# Additional volumeMounts on the output Deployment definition.
volumeMounts: []
ruleNamespaceSelector: {}
ruleSelector: {}
sinks:
alertmanagers:
- namespace: kubesphere-monitoring-system
name: alertmanager-operated
# webhooks:
# - type:
# url:
# service:
# namespace:
# name:
# port:
# path:
## 'stdout' sink type can be either 'notification' or 'alert'
# stdout:
# type: notification
rule:
createDefaults: true
overrideDefaults: false
# Set timezone env variable to be set in containers
timezone: "Asia/Kolkata"
@@ -1,478 +0,0 @@
# 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-infra-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-infra-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: "infra"
team: "sre"
service: "kube-state-metrics-infra-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: "sre-shared-tmp"
## 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: "sre-shared-tmp"
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: 40m
memory: 200Mi
## 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
@@ -1,128 +0,0 @@
fullnameOverride: "kubectl-mcp-server"
replicas: 1
image:
# In-house hardened build (helm-templates/kubectl-mcp-server/docker/) —
# NOT the upstream Docker Hub image. 266→18 HIGH/CRIT vulns, non-root,
# multi-stage slim base, kubectl v1.33.12 / helm v3.21.0.
repository: asia-southeast1-docker.pkg.dev/meesho-devops-admin-0622/prd/devop/kubectl-mcp-server
tag: "v2"
pullPolicy: IfNotPresent
labels:
bu: infra
team: devops
service: kubectl-mcp-server
env: prd
serviceAccount:
create: true
annotations: {}
rbac:
create: true
podAnnotations: {}
podSecurityContext: {}
securityContext:
runAsNonRoot: true
runAsUser: 1000
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
priorityClassName: ""
# Admin cluster has no `admin-devops` pool — the general devops nodepool
# is labelled/tainted `dedicated=devops` (verified on k8s-admin-prd-ase1).
nodeSelector:
dedicated: "devops"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "devops"
effect: NoSchedule
affinity: {}
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: 1000m
memory: 1Gi
mcp:
mode: single
transport: http
host: "0.0.0.0"
port: 8000
auth:
allowAnonymous: false
externalSecrets:
enabled: true
refreshInterval: "150s"
secretStoreRef:
name: vault-backend
kind: ClusterSecretStore
dataFrom:
secretKey: "meesho/prd/cntr/devop/kubectl-mcp-server-admin"
# tcpSocket on purpose — streamable-http transport exposes only /mcp,
# there is no /health route (see chart values.yaml note).
livenessProbe:
tcpSocket:
port: 8000
initialDelaySeconds: 30
periodSeconds: 30
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
tcpSocket:
port: 8000
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
service:
port: 8000
type: ClusterIP
# admin prd has no Contour — only nginx-external / nginx-internal ingress
# classes. Use the networking.k8s.io Ingress path (nginx-internal), not
# the HTTPProxy/Contour gateway. Verified on k8s-admin-prd-ase1.
createContourGateway: false
ingress:
enabled: true
ingressClassName: nginx-internal
servicePortNumber: 8000
hosts:
- host: kubectl-mcp-server-admin.prd.meesho.int
paths:
- path: /
pathType: Prefix
annotations:
kubernetes.io/ingress.class: nginx-internal
nginx.ingress.kubernetes.io/ssl-redirect: "false"
nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
nginx.ingress.kubernetes.io/proxy-send-timeout: "300"
nginx.ingress.kubernetes.io/proxy-body-size: "10m"
nginx.ingress.kubernetes.io/proxy-buffer-size: "16k"
nginx.ingress.kubernetes.io/limit-rps: "10"
nginx.ingress.kubernetes.io/limit-connections: "20"
slowStart:
enabled: false
window: "120s"
aggression: 1
minPercent: 10
@@ -1,272 +0,0 @@
fullnameOverride: "loki"
serviceAccount:
annotations: {
iam.gke.io/gcp-service-account: sa-infr-sre-obs-prd@meesho-admin-prd-0622.iam.gserviceaccount.com
}
loki:
auth_enabled: false
server:
grpc_server_max_recv_msg_size: 104857600
grpc_server_max_send_msg_size: 104857600
http_server_read_timeout: 60s
http_server_write_timeout: 60s
ingester_client:
remote_timeout: 60s
limits_config:
allow_structured_metadata: true
retention_period: 744h
max_line_size: 0
ingestion_rate_mb: 512
ingestion_burst_size_mb: 1024
per_stream_rate_limit: 512M
per_stream_rate_limit_burst: 1024M
schemaConfig:
configs:
- from: 2024-04-01
store: tsdb
object_store: gcs
schema: v13
index:
prefix: index_
period: 24h
storage_config:
tsdb_shipper:
active_index_directory: /var/loki/index
cache_location: /var/loki/index_cache
cache_ttl: 48h
gcs:
bucket_name: "loki_data"
object_prefix: "chunks"
storage:
type: gcs
bucketNames:
chunks: loki_data
compactor:
working_directory: /var/loki/compactor
tracing:
enabled: false
deploymentMode: Distributed
distributor:
replicas: 1
maxUnavailable: 1
resources:
limits:
cpu: 32
memory: 30Gi
requests:
cpu: 30
memory: 27Gi
nodeSelector:
dedicated: "loki-highcpu"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "loki-highcpu"
effect: "NoSchedule"
affinity: {}
ingester:
replicas: 2
persistence:
enabled: true
claims:
- name: data
size: 500Gi
storageClass: "premium-rwo"
resources:
limits:
cpu: 47
memory: 180Gi
requests:
cpu: 45
memory: 175Gi
nodeSelector:
dedicated: "loki-standard"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "loki-standard"
effect: "NoSchedule"
zoneAwareReplication:
enabled: false
queryFrontend:
replicas: 2
maxUnavailable: 1
resources:
limits:
cpu: 1
memory: 1Gi
requests:
cpu: 1
memory: 1Gi
nodeSelector:
dedicated: "loki-highcpu-s"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "loki-highcpu-s"
effect: "NoSchedule"
affinity: {}
queryScheduler:
replicas: 1
resources:
limits:
cpu: 1
memory: 1Gi
requests:
cpu: 1
memory: 1Gi
nodeSelector:
dedicated: "loki-highcpu-s"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "loki-highcpu-s"
effect: "NoSchedule"
affinity: {}
querier:
replicas: 1
maxUnavailable: 1
resources:
limits:
cpu: 31
memory: 30Gi
requests:
cpu: 30
memory: 27Gi
nodeSelector:
dedicated: "loki-highcpu"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "loki-highcpu"
effect: "NoSchedule"
affinity: {}
indexGateway:
replicas: 2
maxUnavailable: 1
persistence:
enabled: true
size: 10Gi
storageClass: "premium-rwo"
resources:
limits:
cpu: 1
memory: 1Gi
requests:
cpu: 1
memory: 1Gi
nodeSelector:
dedicated: "loki-highcpu-s"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "loki-highcpu-s"
effect: "NoSchedule"
affinity: {}
compactor:
replicas: 1
persistence:
enabled: true
claims:
- name: data
size: 10Gi
storageClass: "sc-pd-standard"
resources:
limits:
cpu: 3
memory: 10Gi
requests:
cpu: 2
memory: 8Gi
nodeSelector:
dedicated: "loki-highmem"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "loki-highmem"
effect: "NoSchedule"
resultsCache:
replicas: 2
allocatedMemory: 2048
nodeSelector:
dedicated: "loki-highmem"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "loki-highmem"
effect: "NoSchedule"
chunksCache:
replicas: 2
allocatedMemory: 32768
nodeSelector:
dedicated: "loki-highmem"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "loki-highmem"
effect: "NoSchedule"
lokiCanary:
enabled: true
nodeSelector:
dedicated: "loki-highcpu-s"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "loki-highcpu-s"
effect: "NoSchedule"
gateway:
enabled: true
replicas: 2
nodeSelector:
dedicated: "loki-highcpu-s"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "loki-highcpu-s"
effect: "NoSchedule"
affinity: {}
# unused components
ruler:
enabled: false
test:
enabled: false
# Experimental - could be helpful in the future for faster queries
bloomPlanner:
replicas: 0
bloomBuilder:
replicas: 0
bloomGateway:
replicas: 0
# Zero out replica counts of other deployment modes
backend:
replicas: 0
read:
replicas: 0
write:
replicas: 0
singleBinary:
replicas: 0
@@ -1,21 +0,0 @@
route:
receiver: mimir-alerts
repeat_interval: 60m
group_by: ['alertname']
receivers:
- name: mimir-alerts
slack_configs:
- api_url: "https://hooks.slack.com/services/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"
channel: "#mimir-alerts"
send_resolved: true
title: '[{{ .Status | toUpper }} {{ .Alerts.Firing | len }}] {{ .GroupLabels.alertname }}'
text: |
{{ range .Alerts }}
*Alert:* {{ .Annotations.summary }} - `{{ .Labels.severity }}`
*Status:* `{{ .Status | toUpper }}`
*Details:*
{{ range .Labels.SortedPairs }}
• *{{ .Name }}:* `{{ .Value }}`
{{ end }}
{{ end }}
@@ -1,406 +0,0 @@
fullnameOverride: "mimir"
image:
repository: asia-southeast1-docker.pkg.dev/meesho-devops-admin-0622/admin/sre/mimir
tag: 2.13.0
serviceAccount:
annotations: {
iam.gke.io/gcp-service-account: sa-infr-sre-obs-prd@meesho-admin-prd-0622.iam.gserviceaccount.com
}
runtimeConfig:
overrides:
anonymous:
out_of_order_time_window: 10m
# ingester_limits:
# max_inflight_push_requests: 0
mimir:
multitenancy_enabled: false
structuredConfig:
limits:
max_global_exemplars_per_user: 1000000000 # 0
out_of_order_time_window: 2m # 0s
compactor_blocks_retention_period: 90d # 0s
max_global_series_per_user: 0 # 150000
max_label_names_per_series: 100 # 30
ingestion_rate: 100000000 # 10000
ingestion_burst_size: 100000000 # 200000
ruler_max_rules_per_rule_group: 0 # 20
ruler_max_rule_groups_per_tenant: 0 # 70
max_fetched_chunks_per_query: 0 # 2000000
compactor_split_and_merge_shards: 36 # 0
compactor_split_groups: 36 # 1
ingester:
# read_path_cpu_utilization_limit: 31.5
# read_path_memory_utilization_limit: 131941395200
ring:
replication_factor: 3 # 3
instance_limits:
max_inflight_push_requests: 0 # 2000
compactor:
meta_sync_concurrency: 200 # 4
block_sync_concurrency: 50 # 1
max_compaction_time: 12h
common:
storage:
backend: gcs
server:
log_level: "info"
blocks_storage:
backend: gcs
gcs:
bucket_name: "mimir_data"
storage_prefix: "blocks"
alertmanager_storage:
backend: gcs
gcs:
bucket_name: "mimir_data"
storage_prefix: "alertmanager"
ruler_storage:
backend: gcs
gcs:
bucket_name: "mimir_data"
storage_prefix: "ruler"
distributor:
replicas: 1
resources:
limits:
cpu: 62
memory: 60Gi
requests:
cpu: 60
memory: 54Gi
nodeSelector:
dedicated: "mimir-highcpu"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "mimir-highcpu"
effect: "NoSchedule"
ingester:
replicas: 6
persistentVolume:
enabled: true
size: 250Gi
storageClass: "premium-rwo"
resources:
limits:
cpu: 47
memory: 180Gi
requests:
cpu: 45
memory: 175Gi
nodeSelector:
dedicated: "mimir-standard"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "mimir-standard"
effect: "NoSchedule"
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app.kubernetes.io/component
operator: In
values:
- ingester
topologyKey: 'kubernetes.io/hostname'
zoneAwareReplication:
enabled: false
query_frontend:
replicas: 2
resources:
limits:
cpu: 1
memory: 1Gi
requests:
cpu: 1
memory: 1Gi
nodeSelector:
dedicated: "mimir-highcpu-s"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "mimir-highcpu-s"
effect: "NoSchedule"
query_scheduler:
enabled: true
replicas: 2
resources:
limits:
cpu: 1
memory: 1Gi
requests:
cpu: 1
memory: 1Gi
nodeSelector:
dedicated: "mimir-highcpu-s"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "mimir-highcpu-s"
effect: "NoSchedule"
querier:
replicas: 2
resources:
limits:
cpu: 31
memory: 30Gi
requests:
cpu: 30
memory: 27Gi
nodeSelector:
dedicated: "mimir-highcpu"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "mimir-highcpu"
effect: "NoSchedule"
store_gateway:
replicas: 6
persistentVolume:
enabled: true
size: 500Gi
storageClass: "premium-rwo"
resources:
limits:
cpu: 20
memory: 20Gi
requests:
cpu: 20
memory: 18Gi
nodeSelector:
dedicated: "mimir-highcpu"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "mimir-highcpu"
effect: "NoSchedule"
affinity: {}
# podAntiAffinity:
# requiredDuringSchedulingIgnoredDuringExecution:
# - labelSelector:
# matchExpressions:
# - key: app.kubernetes.io/component
# operator: In
# values:
# - store-gateway
# topologyKey: 'kubernetes.io/hostname'
zoneAwareReplication:
enabled: false
compactor:
replicas: 16
persistentVolume:
enabled: true
size: 100Gi
storageClass: "premium-rwo"
resources:
limits:
cpu: 3
memory: 10Gi
requests:
cpu: 2
memory: 8Gi
nodeSelector:
dedicated: "mimir-highmem"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "mimir-highmem"
effect: "NoSchedule"
chunks-cache:
enabled: true
replicas: 2
allocatedMemory: 32768
nodeSelector:
dedicated: "mimir-highmem"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "mimir-highmem"
effect: "NoSchedule"
index-cache:
enabled: true
replicas: 2
allocatedMemory: 8192
nodeSelector:
dedicated: "mimir-highmem"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "mimir-highmem"
effect: "NoSchedule"
metadata-cache:
enabled: true
replicas: 2
allocatedMemory: 2048
nodeSelector:
dedicated: "mimir-highmem"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "mimir-highmem"
effect: "NoSchedule"
results-cache:
enabled: true
replicas: 2
allocatedMemory: 2048
nodeSelector:
dedicated: "mimir-highmem"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "mimir-highmem"
effect: "NoSchedule"
ruler:
enabled: true
replicas: 1
resources:
limits:
cpu: 11
memory: 12Gi
requests:
cpu: 10
memory: 10Gi
nodeSelector:
dedicated: "mimir-highcpu-s"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "mimir-highcpu-s"
effect: "NoSchedule"
remoteEvaluationDedicatedQueryPath: true
ruler_query_frontend:
replicas: 2
resources:
limits:
cpu: 1
memory: 1Gi
requests:
cpu: 1
memory: 1Gi
nodeSelector:
dedicated: "mimir-highcpu-s"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "mimir-highcpu-s"
effect: "NoSchedule"
ruler_query_scheduler:
replicas: 2
resources:
limits:
cpu: 1
memory: 1Gi
requests:
cpu: 1
memory: 1Gi
nodeSelector:
dedicated: "mimir-highcpu-s"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "mimir-highcpu-s"
effect: "NoSchedule"
ruler_querier:
replicas: 1
resources:
limits:
cpu: 31
memory: 30Gi
requests:
cpu: 30
memory: 27Gi
nodeSelector:
dedicated: "mimir-highcpu"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "mimir-highcpu"
effect: "NoSchedule"
alertmanager:
replicas: 2
persistentVolume:
enabled: false
resources:
limits:
cpu: 1
memory: 1Gi
requests:
cpu: 1
memory: 1Gi
nodeSelector:
dedicated: "mimir-highcpu-s"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "mimir-highcpu-s"
effect: "NoSchedule"
overrides_exporter:
replicas: 1
resources:
limits:
cpu: 200m
memory: 128Mi
requests:
cpu: 100m
memory: 128Mi
nodeSelector:
dedicated: "mimir-highcpu-s"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "mimir-highcpu-s"
effect: "NoSchedule"
ingress:
enabled: true
ingressClassName: nginx-internal
hosts:
- mimir.meeshogcp.in
nginx:
enabled: true
replicas: 2
nodeSelector:
dedicated: "mimir-highcpu-s"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "mimir-highcpu-s"
effect: "NoSchedule"
rollout_operator:
enabled: false
minio:
enabled: false
@@ -1,659 +0,0 @@
# Default values for opentelemetry-collector.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
nameOverride: ""
fullnameOverride: "opentelemetry-admin-prd"
dedicatedValue: false
schedulerName: default-scheduler
labels:
bu: "infra"
team: "sre"
service: "opentelemetry-admin-prd"
env: "prd"
priority: "p0"
type: "opentelemetry"
arch: "any"
runpod: "ondemand"
externalSecret:
enabled: true
key: prd/admin/coralogix-keys
secretStoreRef:
name: vault-backend
# Valid values are "daemonset", "deployment", and "statefulset".
mode: "deployment"
# Specify which namespace should be used to deploy the resources into
namespaceOverride: ""
# Handles basic configuration of components that
# also require k8s modifications to work correctly.
# .Values.config can be used to modify/add to a preset
# component configuration, but CANNOT be used to remove
# preset configuration. If you require removal of any
# sections of a preset configuration, you cannot use
# the preset. Instead, configure the component manually in
# .Values.config and use the other fields supplied in the
# values.yaml to configure k8s as necessary.
presets:
# Configures the collector to collect logs.
# Adds the filelog receiver to the logs pipeline
# and adds the necessary volumes and volume mounts.
# Best used with mode = daemonset.
# See https://opentelemetry.io/docs/kubernetes/collector/components/#filelog-receiver for details on the receiver.
logsCollection:
enabled: false
includeCollectorLogs: false
# Enabling this writes checkpoints in /var/lib/otelcol/ host directory.
# Note this changes collector's user to root, so that it can write to host directory.
storeCheckpoints: false
# The maximum bytes size of the recombined field.
# Once the size exceeds the limit, all received entries of the source will be combined and flushed.
maxRecombineLogSize: 102400
# Configures the collector to collect host metrics.
# Adds the hostmetrics receiver to the metrics pipeline
# and adds the necessary volumes and volume mounts.
# Best used with mode = daemonset.
# See https://opentelemetry.io/docs/kubernetes/collector/components/#host-metrics-receiver for details on the receiver.
hostMetrics:
enabled: false
# Configures the Kubernetes Processor to add Kubernetes metadata.
# Adds the k8sattributes processor to all the pipelines
# and adds the necessary rules to ClusteRole.
# Best used with mode = daemonset.
# See https://opentelemetry.io/docs/kubernetes/collector/components/#kubernetes-attributes-processor for details on the receiver.
kubernetesAttributes:
enabled: false
# When enabled the processor will extra all labels for an associated pod and add them as resource attributes.
# The label's exact name will be the key.
extractAllPodLabels: false
# When enabled the processor will extra all annotations for an associated pod and add them as resource attributes.
# The annotation's exact name will be the key.
extractAllPodAnnotations: false
# Configures the collector to collect node, pod, and container metrics from the API server on a kubelet..
# Adds the kubeletstats receiver to the metrics pipeline
# and adds the necessary rules to ClusteRole.
# Best used with mode = daemonset.
# See https://opentelemetry.io/docs/kubernetes/collector/components/#kubeletstats-receiver for details on the receiver.
kubeletMetrics:
enabled: false
# Configures the collector to collect kubernetes events.
# Adds the k8sobject receiver to the logs pipeline
# and collects kubernetes events by default.
# Best used with mode = deployment or statefulset.
# See https://opentelemetry.io/docs/kubernetes/collector/components/#kubernetes-objects-receiver for details on the receiver.
kubernetesEvents:
enabled: false
# Configures the Kubernetes Cluster Receiver to collect cluster-level metrics.
# Adds the k8s_cluster receiver to the metrics pipeline
# and adds the necessary rules to ClusteRole.
# Best used with mode = deployment or statefulset.
# See https://opentelemetry.io/docs/kubernetes/collector/components/#kubernetes-cluster-receiver for details on the receiver.
clusterMetrics:
enabled: false
configMap:
# Specifies whether a configMap should be created (true by default)
create: true
# Base collector configuration.
# Supports templating. To escape existing instances of {{ }}, use {{` <original content> `}}.
# For example, {{ REDACTED_EMAIL }} becomes {{` {{ REDACTED_EMAIL }} `}}.
config:
receivers:
otlp:
protocols:
grpc:
endpoint: ${env:MY_POD_IP}:4317
max_recv_msg_size_mib: 7
http:
endpoint: ${env:MY_POD_IP}:4318
processors:
batch:
send_batch_size: 1024
timeout: 5s
# If set to null, will be overridden with values based on k8s resource limits
memory_limiter: null
attributes/shipper:
actions:
- key: shipper
action: insert
value: '${MY_POD_IP}'
- key: cloud
action: insert
value: 'gcp'
tail_sampling:
decision_wait: 30s
num_traces: 300000
expected_new_traces_per_sec: 100000
policies:
[
{
name: errors-policy,
type: status_code,
status_code: {status_codes: [ERROR]}
},
{
name: probablistic-policy,
type: probabilistic,
probabilistic: {sampling_percentage: 1}
}
]
# filter/include:
# spans:
# include:
# match_type: regexp
# services:
# - order-service
exporters:
logging: {}
coralogix:
domain: "coralogixsg.com"
private_key: "${CORALOGIX_PRIVATE_KEY}"
application_name: "default"
subsystem_name: "nodes"
application_name_attributes:
- "applicationName"
- "service.namespace"
- "k8s.namespace.name"
subsystem_name_attributes:
- "service.name"
- "k8s.deployment.name"
- "k8s.statefulset.name"
- "k8s.daemonset.name"
- "k8s.cronjob.name"
- "k8s.job.name"
- "k8s.container.name"
timeout: 30s
otlp/elastic:
endpoint: "946ece6f7b344005aa1e5c273b1a886f.apm.psc.asia-southeast1.gcp.elastic-cloud.com:443"
headers:
Authorization: "Bearer ehllv9fQQ7GGMOjE79"
timeout: 10s
extensions:
# The health_check extension is mandatory for this chart.
# Without the health_check extension the collector will fail the readiness and liveliness probes.
# The health_check extension can be modified, but should never be removed.
health_check: {}
# memory_ballast: {}
connectors:
spanmetrics:
histogram:
explicit:
buckets: [100us, 1ms, 2ms, 6ms, 10ms, 100ms, 250ms]
dimensions_cache_size: 1000
aggregation_temporality: "AGGREGATION_TEMPORALITY_CUMULATIVE"
metrics_flush_interval: 15s
service:
telemetry:
metrics:
address: ${env:MY_POD_IP}:8888
extensions:
- health_check
# - memory_ballast
pipelines:
# traces:
# receivers:
# - otlp
# processors:
# - tail_sampling
# - attributes/shipper
# - batch
# exporters:
# - coralogix
# - spanmetrics
traces:
receivers:
- otlp
processors:
- tail_sampling
- attributes/shipper
# - filter/include
- batch
exporters:
- otlp/elastic
# - spanmetrics
metrics: null
logs: null
image:
# If you want to use the core image `otel/opentelemetry-collector`, you also need to change `command.name` value to `otelcol`.
#repository: 847438129436.dkr.ecr.ap-southeast-1.amazonaws.com/otel/opentelemetry-collector-contrib
repository: asia-southeast1-docker.pkg.dev/meesho-devops-admin-0622/admin/sre/opentelemetry-collector-contrib
# repository: otel/opentelemetry-collector-contrib
pullPolicy: IfNotPresent
# Overrides the image tag whose default is the chart appVersion.
tag: "0.87.0"
# When digest is set to a non-empty value, images will be pulled by digest (regardless of tag value).
digest: ""
imagePullSecrets: []
# OpenTelemetry Collector executable
command:
name: otelcol-contrib
extraArgs: []
serviceAccount:
# Specifies whether a service account should be created
create: true
# Annotations to add to the service account
annotations: {}
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name: ""
clusterRole:
# Specifies whether a clusterRole should be created
# Some presets also trigger the creation of a cluster role and cluster role binding.
# If using one of those presets, this field is no-op.
create: false
# Annotations to add to the clusterRole
# Can be used in combination with presets that create a cluster role.
annotations: {}
# The name of the clusterRole to use.
# If not set a name is generated using the fullname template
# Can be used in combination with presets that create a cluster role.
name: ""
# A set of rules as documented here : https://kubernetes.io/docs/reference/access-authn-authz/rbac/
# Can be used in combination with presets that create a cluster role to add additional rules.
rules: []
# - apiGroups:
# - ''
# resources:
# - 'pods'
# - 'nodes'
# verbs:
# - 'get'
# - 'list'
# - 'watch'
clusterRoleBinding:
# Annotations to add to the clusterRoleBinding
# Can be used in combination with presets that create a cluster role binding.
annotations: {}
# The name of the clusterRoleBinding to use.
# If not set a name is generated using the fullname template
# Can be used in combination with presets that create a cluster role binding.
name: ""
podSecurityContext: {}
securityContext: {}
# nodeSelector: []
# tolerations: {}
nodeSelector:
dedicated: "opentelemetry"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "opentelemetry"
effect: "NoSchedule"
affinity: {}
topologySpreadConstraints: []
# Allows for pod scheduler prioritisation
priorityClassName: ""
#extraEnvs: []
extraEnvs:
- name: OTEL_RESOURCE_ATTRIBUTES
value: "k8s.node.name=$(K8S_NODE_NAME)"
- name: KUBE_NODE_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: spec.nodeName
extraEnvsFrom: []
extraVolumes: []
extraVolumeMounts: []
# Configuration for ports
# nodePort is also allowed
ports:
otlp:
enabled: true
containerPort: 4317
servicePort: 4317
# hostPort: 4317
protocol: TCP
# nodePort: 30317
appProtocol: grpc
otlp-http:
enabled: true
containerPort: 4318
servicePort: 4318
# hostPort: 4318
protocol: TCP
jaeger-compact:
enabled: false
containerPort: 6831
servicePort: 6831
# hostPort: 6831
protocol: UDP
jaeger-thrift:
enabled: false
containerPort: 14268
servicePort: 14268
# hostPort: 14268
protocol: TCP
jaeger-grpc:
enabled: false
containerPort: 14250
servicePort: 14250
# hostPort: 14250
protocol: TCP
zipkin:
enabled: false
containerPort: 9411
servicePort: 9411
# hostPort: 9411
protocol: TCP
metrics:
# The metrics port is disabled by default. However you need to enable the port
# in order to use the ServiceMonitor (serviceMonitor.enabled) or PodMonitor (podMonitor.enabled).
enabled: false
containerPort: 8888
servicePort: 8888
protocol: TCP
# Resource limits & requests. Update according to your own use case as these values might be too low for a typical deployment.
#resources: {}
resources:
requests:
cpu: 25
memory: 25Gi
limits:
cpu: 30
memory: 30Gi
# Annotations to be added to pod
podAnnotations:
otel.io/path: /metrics
otel.io/port: '8888'
otel.io/scrape: 'true'
podLabels: {}
# Host networking requested for this pod. Use the host's network namespace.
hostNetwork: false
# Pod DNS policy ClusterFirst, ClusterFirstWithHostNet, None, Default, None
dnsPolicy: "ClusterFirstWithHostNet"
# Custom DNS config. Required when DNS policy is None.
dnsConfig: {}
# only used with deployment mode
replicaCount: 1
# only used with deployment mode
revisionHistoryLimit: 100
annotations: {}
# prometheus.io/path: "/metrics"
# prometheus.io/scrape: "true"
# prometheus.io/port: "8888"
# List of extra sidecars to add
extraContainers: []
# extraContainers:
# - name: test
# command:
# - cp
# args:
# - /bin/sleep
# - /test/sleep
# image: busybox:latest
# volumeMounts:
# - name: test
# mountPath: /test
# List of init container specs, e.g. for copying a binary to be executed as a lifecycle hook.
# Another usage of init containers is e.g. initializing filesystem permissions to the OTLP Collector user `10001` in case you are using persistence and the volume is producing a permission denied error for the OTLP Collector container.
initContainers: []
# initContainers:
# - name: test
# image: busybox:latest
# command:
# - cp
# args:
# - /bin/sleep
# - /test/sleep
# volumeMounts:
# - name: test
# mountPath: /test
# - name: init-fs
# image: busybox:latest
# command:
# - sh
# - '-c'
# - 'chown -R 10001: /var/lib/storage/otc' # use the path given as per `extensions.file_storage.directory` & `extraVolumeMounts[x].mountPath`
# volumeMounts:
# - name: opentelemetry-collector-data # use the name of the volume used for persistence
# mountPath: /var/lib/storage/otc # use the path given as per `extensions.file_storage.directory` & `extraVolumeMounts[x].mountPath`
# Pod lifecycle policies.
lifecycleHooks: {}
# lifecycleHooks:
# preStop:
# exec:
# command:
# - /test/sleep
# - "5"
# liveness probe configuration
# Ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/
##
livenessProbe:
# Number of seconds after the container has started before startup, liveness or readiness probes are initiated.
# initialDelaySeconds: 1
# How often in seconds to perform the probe.
# periodSeconds: 10
# Number of seconds after which the probe times out.
# timeoutSeconds: 1
# Minimum consecutive failures for the probe to be considered failed after having succeeded.
# failureThreshold: 1
# Duration in seconds the pod needs to terminate gracefully upon probe failure.
# terminationGracePeriodSeconds: 10
httpGet:
port: 13133
path: /
# readiness probe configuration
# Ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/
##
readinessProbe:
# Number of seconds after the container has started before startup, liveness or readiness probes are initiated.
# initialDelaySeconds: 1
# How often (in seconds) to perform the probe.
# periodSeconds: 10
# Number of seconds after which the probe times out.
# timeoutSeconds: 1
# Minimum consecutive successes for the probe to be considered successful after having failed.
# successThreshold: 1
# Minimum consecutive failures for the probe to be considered failed after having succeeded.
# failureThreshold: 1
httpGet:
port: 13133
path: /
service:
# Enable the creation of a Service.
# By default, it's enabled on mode != daemonset.
# However, to enable it on mode = daemonset, its creation must be explicitly enabled
# enabled: true
type: ClusterIP
# type: LoadBalancer
# loadBalancerIP: 1.2.3.4
# loadBalancerSourceRanges: []
# By default, Service of type 'LoadBalancer' will be created setting 'externalTrafficPolicy: Cluster'
# unless other value is explicitly set.
# Possible values are Cluster or Local (https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip)
# externalTrafficPolicy: Cluster
annotations:
io.cilium/global-service: "true"
# By default, Service will be created setting 'internalTrafficPolicy: Local' on mode = daemonset
# unless other value is explicitly set.
# Setting 'internalTrafficPolicy: Cluster' on a daemonset is not recommended
# internalTrafficPolicy: Cluster
ingress:
enabled: false
# annotations: {}
# ingressClassName: nginx
# hosts:
# - host: collector.example.com
# paths:
# - path: /
# pathType: Prefix
# port: 4318
# tls:
# - secretName: collector-tls
# hosts:
# - collector.example.com
# Additional ingresses - only created if ingress.enabled is true
# Useful for when differently annotated ingress services are required
# Each additional ingress needs key "name" set to something unique
additionalIngresses: []
# - name: cloudwatch
# ingressClassName: nginx
# annotations: {}
# hosts:
# - host: collector.example.com
# paths:
# - path: /
# pathType: Prefix
# port: 4318
# tls:
# - secretName: collector-tls
# hosts:
# - collector.example.com
podMonitor:
# The pod monitor by default scrapes the metrics port.
# The metrics port needs to be enabled as well.
enabled: false
metricsEndpoints:
- port: metrics
# interval: 15s
# additional labels for the PodMonitor
extraLabels: {}
# release: kube-prometheus-stack
serviceMonitor:
# The service monitor by default scrapes the metrics port.
# The metrics port needs to be enabled as well.
enabled: false
metricsEndpoints:
- port: metrics
# interval: 15s
# additional labels for the ServiceMonitor
extraLabels: {}
# release: kube-prometheus-stack
# PodDisruptionBudget is used only if deployment enabled
podDisruptionBudget:
enabled: false
# minAvailable: 2
maxUnavailable: 1
# autoscaling is used only if deployment enabled
autoscaling:
enabled: true
minReplicas: 5
maxReplicas: 300
behavior: {}
targetCPUUtilizationPercentage: 80
targetMemoryUtilizationPercentage: 80
rollout:
# When 'mode: daemonset', maxSurge cannot be used when hostPort is set for any of the ports
rollingUpdate:
# maxSurge: 10%
maxUnavailable: 5
strategy: RollingUpdate
prometheusRule:
enabled: false
groups: []
# Create default rules for monitoring the collector
defaultRules:
enabled: false
# additional labels for the PrometheusRule
extraLabels: {}
statefulset:
# volumeClaimTemplates for a statefulset
volumeClaimTemplates: []
podManagementPolicy: "Parallel"
networkPolicy:
enabled: false
# Annotations to add to the NetworkPolicy
annotations: {}
# Configure the 'from' clause of the NetworkPolicy.
# By default this will restrict traffic to ports enabled for the Collector. If
# you wish to further restrict traffic to other hosts or specific namespaces,
# see the standard NetworkPolicy 'spec.ingress.from' definition for more info:
# https://kubernetes.io/docs/reference/kubernetes-api/policy-resources/network-policy-v1/
allowIngressFrom: []
# # Allow traffic from any pod in any namespace, but not external hosts
# - namespaceSelector: {}
# # Allow external access from a specific cidr block
# - ipBlock:
# cidr: 192.168.1.64/32
# # Allow access from pods in specific namespaces
# - namespaceSelector:
# matchExpressions:
# - key: kubernetes.io/metadata.name
# operator: In
# values:
# - "cats"
# - "dogs"
# Add additional ingress rules to specific ports
# Useful to allow external hosts/services to access specific ports
# An example is allowing an external prometheus server to scrape metrics
#
# See the standard NetworkPolicy 'spec.ingress' definition for more info:
# https://kubernetes.io/docs/reference/kubernetes-api/policy-resources/network-policy-v1/
extraIngressRules: []
# - ports:
# - port: metrics
# protocol: TCP
# from:
# - ipBlock:
# cidr: 192.168.1.64/32
# Restrict egress traffic from the OpenTelemetry collector pod
# See the standard NetworkPolicy 'spec.egress' definition for more info:
# https://kubernetes.io/docs/reference/kubernetes-api/policy-resources/network-policy-v1/
egressRules: []
# - to:
# - namespaceSelector: {}
# - ipBlock:
# cidr: 192.168.10.10/24
# ports:
# - port: 1234
# protocol: TCP
@@ -1,111 +0,0 @@
config:
receivers:
otlp:
protocols:
grpc:
endpoint: ${env:MY_POD_IP}:4317
max_recv_msg_size_mib: 50
processors:
batch:
send_batch_size: 256
timeout: 200ms
send_batch_max_size: 512
filter/drop-noisy-services:
error_mode: ignore
traces:
span:
- IsMatch(resource.attributes["service.name"], ".*consumer.*|.*scheduler.*|.*cron.*|.*worker.*|.*inhouse-ingestion.*|.*.messaging-api-internal*|.*cis.*")
tail_sampling:
decision_wait: 10s # avg latency across services
num_traces: 25000000 # expected_new_traces_per_sec * decision_wait + some buffer
expected_new_traces_per_sec: 1500000 # combined span rate across all business units
decision_cache:
sampled_cache_size: 6000000 # sampling rate * num_traces + some buffer
policies:
[
{
name: errors-policy,
type: status_code,
status_code: {status_codes: [ERROR]}
},
# {
# name: latency-policy,
# type: latency,
# latency: {threshold_ms: 1000}
# },
{
name: probablistic-policy,
type: probabilistic,
probabilistic: {sampling_percentage: 1}
}
]
exporters:
otlp/elastic:
endpoint: "946ece6f7b344005aa1e5c273b1a886f.apm.psc.asia-southeast1.gcp.elastic-cloud.com:443"
timeout: 15s
sending_queue:
num_consumers: 50
queue_size: 10000
headers:
Authorization: "Bearer ehllv9fQQ7GGMOjE79"
service:
telemetry:
metrics:
level: detailed
readers:
- pull:
exporter:
prometheus:
host: '0.0.0.0'
port: 8888
extensions:
- health_check
pipelines:
traces:
receivers: [otlp]
processors: [filter/drop-noisy-services, tail_sampling, batch]
exporters: [otlp/elastic]
metrics: null
logs: null
fullnameOverride: "opentelemetry-admin-prd"
mode: "deployment"
podAnnotations:
otel.io/path: '/metrics'
otel.io/port: '8888'
otel.io/scrape: 'true'
image:
repository: asia-southeast1-docker.pkg.dev/meesho-devops-admin-0622/admin/sre/opentelemetry-collector-contrib
pullPolicy: IfNotPresent
tag: "0.114.0"
nodeSelector:
dedicated: "opentelemetry-std"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "opentelemetry-std"
effect: "NoSchedule"
resources:
requests:
cpu: '45'
memory: 175Gi
limits:
cpu: '45'
memory: 175Gi
autoscaling:
enabled: true
minReplicas: 15
maxReplicas: 50
targetCPUUtilizationPercentage: 75
targetMemoryUtilizationPercentage: 75
@@ -1,73 +0,0 @@
# Default values for hello-world.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
deployments:
- nodepool: vminsert
bu: infra
cpuRequest: 1
memoryRequest: 1Gi
replicaCount: 3
priorityClass:
name: "ultralow-priority"
image:
repository: nginx
tag: "1.14.2"
pullPolicy: IfNotPresent
# Overrides the image tag whose default is the chart appVersion.
nameOverride: ""
fullnameOverride: "paused-container-infra-prd"
extraLabels:
team: "devops"
bu: "infra"
env: "prd"
service: "paused-container-infra-prd"
priority: "p3"
type: "tools"
topologySpreadConstraints: []
# - labelSelector:
# matchLabels:
# dedicated: vminsert
# maxSkew: 1
# topologyKey: topology.kubernetes.io/hostname
# whenUnsatisfiable: DoNotSchedule
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: run
operator: In
values:
- paused-container-infra-prd
topologyKey: topology.kubernetes.io/zone
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: run
operator: In
values:
- paused-container-infra-prd
topologyKey: kubernetes.io/hostname
namespaceSelector: {}
serviceAccount:
# Specifies whether a service account should be created
create: true
# Annotations to add to the service account
annotations: {}
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name: ""
service:
type: ClusterIP
port: 80
@@ -1,279 +0,0 @@
## @section Percona Monitoring and Management (PMM) parameters
## Default values for PMM.
## This is a YAML-formatted file.
## Declare variables to be passed into your templates.
## PMM image version
## ref: https://hub.docker.com/r/percona/pmm-server/tags
## @param image.repository PMM image repository
## @param image.pullPolicy PMM image pull policy
## @param image.tag PMM image tag (immutable tags are recommended)
## @param image.imagePullSecrets Global Docker registry secret names as an array
##
image:
repository: percona/pmm-server
pullPolicy: IfNotPresent
# Overrides the image tag whose default is the chart appVersion.
tag: "2.41.0"
imagePullSecrets: []
## PMM environment variables
## ref: https://docs.percona.com/percona-monitoring-and-management/setting-up/server/docker.html#environment-variables
##
pmmEnv:
## @param pmmEnv.DISABLE_UPDATES Disables a periodic check for new PMM versions as well as ability to apply upgrades using the UI (need to be disabled in k8s environment as updates rolled with helm/container update)
##
DISABLE_UPDATES: "1"
# optional variables to integrate Grafana with internal iDP, see also secret part
# GF_AUTH_GENERIC_OAUTH_ENABLED: 'true'
# GF_AUTH_GENERIC_OAUTH_SCOPES: ''
# GF_AUTH_GENERIC_OAUTH_AUTH_URL: ''
# GF_AUTH_GENERIC_OAUTH_TOKEN_URL: ''
# GF_AUTH_GENERIC_OAUTH_API_URL: ''
# GF_AUTH_GENERIC_OAUTH_ALLOWED_DOMAINS: ''
## @param pmmResources optional [Resources](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/) requested for [PMM container](https://docs.percona.com/percona-monitoring-and-management/setting-up/server/index.html#set-up-pmm-server)
# pmmResources:
# requests:
# memory: "32Gi"
# cpu: "8"
# limits:
# memory: "64Gi"
# cpu: "32"
pmmResources:
requests:
memory: "14Gi"
cpu: "4"
limits:
memory: "16Gi"
cpu: "6"
## Readiness probe Config
## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#configure-probes
## @param readyProbeConf.initialDelaySeconds Number of seconds after the container has started before readiness probes is initiated
## @param readyProbeConf.periodSeconds How often (in seconds) to perform the probe
## @param readyProbeConf.failureThreshold When a probe fails, Kubernetes will try failureThreshold times before giving up
##
readyProbeConf:
initialDelaySeconds: 1
periodSeconds: 5
failureThreshold: 6
## @section PMM secrets
##
secret:
## @param secret.name Defines the name of the k8s secret that holds passwords and other secrets
##
name: pmm-secret
## @param secret.create If true then secret will be generated by Helm chart. Otherwise it is expected to be created by user.
##
create: false
## @param secret.pmm_password Initial PMM password - it changes only on the first deployment, ignored if PMM was already provisioned and just restarted. If PMM admin password is not set, it will be generated.
## E.g.
## pmm_password: admin
##
## To get password execute `kubectl get secret pmm-secret -o jsonpath='{.data.PMM_ADMIN_PASSWORD}' | base64 --decode`
##
pmm_password: ""
##
# GF_AUTH_GENERIC_OAUTH_CLIENT_ID optional client ID to integrate Grafana with internal iDP, requires other env defined as well under pmmEnv
# GF_AUTH_GENERIC_OAUTH_CLIENT_ID:
# GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET optional secret to integrate Grafana with internal iDP, requires other env defined as well under pmmEnv
# GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET:
## @param certs Optional certificates, if not provided PMM would use generated self-signed certificates,
## please provide your own signed ssl certificates like this in base 64 format:
## certs:
## name: pmm-certs
## files:
## certificate.crt:
## certificate.key:
## ca-certs.pem:
## dhparam.pem:
## certificate.conf:
certs: {}
## @section PMM network configuration
## Service configuration
##
service:
## @param service.name Service name that is dns name monitoring services would send data to. `monitoring-service` used by default by pmm-client in Percona operators.
##
name: monitoring-service
## @param service.type Kubernetes Service type
##
type: ClusterIP
## Ports 443 and/or 80
##
ports:
## @param service.ports[0].port https port number
- port: 443
## @param service.ports[0].targetPort target port to map for statefulset and ingress
targetPort: https
## @param service.ports[0].protocol protocol for https
protocol: TCP
## @param service.ports[0].name port name
name: https
## @param service.ports[1].port http port number
- port: 80
## @param service.ports[1].targetPort target port to map for statefulset and ingress
targetPort: http
## @param service.ports[1].protocol protocol for http
protocol: TCP
## @param service.ports[1].name port name
name: http
## Ingress controller configuration
##
ingress:
## @param ingress.enabled -- Enable ingress controller resource
enabled: true
## @param ingress.nginxInc -- Using ingress controller from NGINX Inc
nginxInc: false
## @param ingress.annotations -- Ingress annotations configuration
annotations: {}
## kubernetes.io/ingress.class: nginx
## kubernetes.io/tls-acme: "true"
### nginx proxy to https
## nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
## @param ingress.community.annotations -- Ingress annotations configuration for community managed ingress (nginxInc = false)
community:
annotations: {}
## kubernetes.io/ingress.class: nginx
## kubernetes.io/tls-acme: "true"
## @param ingress.ingressClassName -- Sets the ingress controller class name to use.
ingressClassName: "nginx-internal"
## Ingress resource hostnames and path mappings
hosts:
## @param ingress.hosts[0].host hostname
- host: pmmmongo-admin-prd.meeshogcp.in
## @param ingress.hosts[0].paths path mapping
paths: [/]
## @param ingress.pathType -- How ingress paths should be treated.
pathType: Prefix
## @param ingress.tls -- Ingress TLS configuration
tls: []
## - secretName: chart-example-tls
## hosts:
## - chart-example.local
## @section PMM storage configuration
## Claiming storage for PMM using Persistent Volume Claims (PVC)
## ref: https://kubernetes.io/docs/user-guide/persistent-volumes/
##
storage:
## @param storage.name name of PVC
name: pmmmongo-storage
## @param storage.storageClassName optional PMM data Persistent Volume Storage Class
## If defined, storageClassName: <storageClass>
## If set to "-", storageClassName: "", which disables dynamic provisioning
## If undefined (the default) or set to null, no storageClassName spec is
## set, choosing the default provisioner. (gp2 on AWS, standard on
## GKE, AWS & OpenStack)
##
storageClassName: "pd-balanced"
##
## @param storage.size size of storage [depends](https://docs.percona.com/percona-monitoring-and-management/setting-up/server/index.html#set-up-pmm-server) on number of monitored services and data retention
##
size: 300Gi
##
## @param storage.dataSource VolumeSnapshot to start from
##
dataSource: {}
## name: before-vX.Y.Z-upgrade
## kind: VolumeSnapshot
## apiGroup: snapshot.storage.k8s.io
##
## @param storage.selector select existing PersistentVolume
##
selector: {}
## matchLabels:
## release: "stable"
## matchExpressions:
## - key: environment
## operator: In
## values:
## - dev
## @section PMM kubernetes configurations
## @param nameOverride String to partially override common.names.fullname template with a string (will prepend the release name)
##
nameOverride: ""
## @param extraLabels Labels to add to all deployed objects
##
extraLabels:
priority: p0
env: prod
team: dbe
bu: infra
## Pods Service Account
## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/
## @param serviceAccount.create Specifies whether a ServiceAccount should be created
## @param serviceAccount.annotations Annotations for service account. Evaluated as a template. Only used if `create` is `true`.
## @param serviceAccount.name Name of the service account to use. If not set and create is true, a name is generated using the fullname template.
##
serviceAccount:
create: true
annotations: {}
name: "pmmmongo-service-account"
## @param podAnnotations Pod annotations
## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/
##
podAnnotations: {}
## @param podSecurityContext Configure Pods Security Context
## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod
## E.g
## podSecurityContext:
## fsGroup: 2000
##
podSecurityContext: {}
## @param securityContext Configure Container Security Context
## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod
## securityContext.capabilities The capabilities to add/drop when running containers
## securityContext.runAsUser Set pmm containers' Security Context runAsUser
## securityContext.runAsNonRoot Set pmm container's Security Context runAsNonRoot
## E.g.
## securityContext:
## capabilities:
## drop:
## - ALL
## readOnlyRootFilesystem: true
## runAsNonRoot: true
## runAsUser: 1000
securityContext: {}
## @param nodeSelector Node labels for pod assignment
## Ref: https://kubernetes.io/docs/user-guide/node-selection/
##
nodeSelector: {}
## @param tolerations Tolerations for pod assignment
## Ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/
##
tolerations:
- effect: NoSchedule
key: dedicated
operator: Equal
value: devops
## @param affinity Affinity for pod assignment
## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity
##
affinity: {}
## @param extraVolumeMounts Optionally specify extra list of additional volumeMounts
##
extraVolumeMounts: []
## @param extraVolumes Optionally specify extra list of additional volumes
##
extraVolumes: []
@@ -1,496 +0,0 @@
# Default values for prometheus-node-exporter.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
image:
registry: quay.io
repository: prometheus/node-exporter
# Overrides the image tag whose default is {{ printf "v%s" .Chart.AppVersion }}
tag: ""
pullPolicy: IfNotPresent
digest: ""
imagePullSecrets: []
# - name: "image-pull-secret"
nameOverride: ""
fullnameOverride: ""
# Number of old history to retain to allow rollback
# Default Kubernetes value is set to 10
revisionHistoryLimit: 10
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: ""
# Configure kube-rbac-proxy. When enabled, creates a kube-rbac-proxy to protect the node-exporter http endpoint.
# The requests are served through the same service but requests are 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
service:
enabled: true
type: ClusterIP
port: 9200
targetPort: 9200
nodePort:
portName: metrics
listenOnAllInterfaces: true
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "9200"
prometheus.io/path: "/metrics"
ipDualStack:
enabled: false
ipFamilies: ["IPv6", "IPv4"]
ipFamilyPolicy: "PreferDualStack"
# Set a NetworkPolicy with:
# ingress only on service.port
# no egress permitted
networkPolicy:
enabled: false
# Additional environment variables that will be passed to the daemonset
env: {}
## env:
## VARIABLE: value
prometheus:
monitor:
enabled: false
additionalLabels: {}
namespace: ""
jobLabel: ""
# List of pod labels to add to node exporter metrics
# https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#servicemonitor
podTargetLabels: []
scheme: http
basicAuth: {}
bearerTokenFile:
tlsConfig: {}
## proxyUrl: URL of a proxy that should be used for scraping.
##
proxyUrl: ""
## Override serviceMonitor selector
##
selectorOverride: {}
## Attach node metadata to discovered targets. Requires Prometheus v2.35.0 and above.
##
attachMetadata:
node: false
relabelings: []
metricRelabelings: []
interval: ""
scrapeTimeout: 10s
## prometheus.monitor.apiVersion ApiVersion for the serviceMonitor Resource(defaults to "monitoring.coreos.com/v1")
apiVersion: ""
## 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
# PodMonitor defines monitoring for a set of pods.
# ref. https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#monitoring.coreos.com/v1.PodMonitor
# Using a PodMonitor may be preferred in some environments where there is very large number
# of Node Exporter endpoints (1000+) behind a single service.
# The PodMonitor is disabled by default. When switching from ServiceMonitor to PodMonitor,
# the time series resulting from the configuration through PodMonitor may have different labels.
# For instance, there will not be the service label any longer which might
# affect PromQL queries selecting that label.
podMonitor:
enabled: false
# Namespace in which to deploy the pod monitor. Defaults to the release namespace.
namespace: ""
# Additional labels, e.g. setting a label for pod monitor selector as set in prometheus
additionalLabels: {}
# release: kube-prometheus-stack
# PodTargetLabels transfers labels of the Kubernetes Pod onto the target.
podTargetLabels: []
# apiVersion defaults to monitoring.coreos.com/v1.
apiVersion: ""
# Override pod selector to select pod objects.
selectorOverride: {}
# Attach node metadata to discovered targets. Requires Prometheus v2.35.0 and above.
attachMetadata:
node: false
# The label to use to retrieve the job name from. Defaults to label app.kubernetes.io/name.
jobLabel: ""
# Scheme/protocol to use for scraping.
scheme: "http"
# Path to scrape metrics at.
path: "/metrics"
# BasicAuth allow an endpoint to authenticate over basic authentication.
# More info: https://prometheus.io/docs/operating/configuration/#endpoint
basicAuth: {}
# Secret to mount to read bearer token for scraping targets.
# The secret needs to be in the same namespace as the pod monitor and accessible by the Prometheus Operator.
# https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#secretkeyselector-v1-core
bearerTokenSecret: {}
# TLS configuration to use when scraping the endpoint.
tlsConfig: {}
# Authorization section for this endpoint.
# https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#monitoring.coreos.com/v1.SafeAuthorization
authorization: {}
# OAuth2 for the URL. Only valid in Prometheus versions 2.27.0 and newer.
# https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#monitoring.coreos.com/v1.OAuth2
oauth2: {}
# ProxyURL eg http://proxyserver:2195. Directs scrapes through proxy to this endpoint.
proxyUrl: ""
# Interval at which endpoints should be scraped. If not specified Prometheus global scrape interval is used.
interval: ""
# Timeout after which the scrape is ended. If not specified, the Prometheus global scrape interval is used.
scrapeTimeout: ""
# HonorTimestamps controls whether Prometheus respects the timestamps present in scraped data.
honorTimestamps: true
# HonorLabels chooses the metrics labels on collisions with target labels.
honorLabels: true
# Whether to enable HTTP2. Default false.
enableHttp2: ""
# Drop pods that are not running. (Failed, Succeeded).
# Enabled by default. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase
filterRunning: ""
# FollowRedirects configures whether scrape requests follow HTTP 3xx redirects. Default false.
followRedirects: ""
# Optional HTTP URL parameters
params: {}
# RelabelConfigs to apply to samples before scraping. Prometheus Operator automatically adds
# relabelings for a few standard Kubernetes fields. The original scrape jobs name
# is available via the __tmp_prometheus_job_name label.
# More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config
relabelings: []
# MetricRelabelConfigs to apply to samples before ingestion.
metricRelabelings: []
# 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
## Customize the updateStrategy if set
updateStrategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
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: 200m
memory: 50Mi
requests:
cpu: 100m
memory: 30Mi
serviceAccount:
# Specifies whether a ServiceAccount should be created
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:
annotations: {}
# annotations: {
# iam.gke.io/gcp-service-account: node-exporter-admin-prd@meesho-admin-prd-0622.iam.gserviceaccount.com
# }
imagePullSecrets: []
automountServiceAccountToken: false
securityContext:
fsGroup: 65534
runAsGroup: 65534
runAsNonRoot: true
runAsUser: 65534
containerSecurityContext:
readOnlyRootFilesystem: true
# capabilities:
# add:
# - SYS_TIME
rbac:
## If true, create & use RBAC resources
##
create: true
## If true, create & use Pod Security Policy resources
## https://kubernetes.io/docs/concepts/policy/pod-security-policy/
pspEnabled: true
pspAnnotations: {}
# for deployments that have node_exporter deployed outside of the cluster, list
# their addresses here
endpoints: []
# Expose the service to the host network
hostNetwork: true
# Share the host process ID namespace
hostPID: true
# Mount the node's root file system (/) at /host/root in the container
hostRootFsMount:
enabled: true
# Defines how new mounts in existing mounts on the node or in the container
# are propagated to the container or node, respectively. Possible values are
# None, HostToContainer, and Bidirectional. If this field is omitted, then
# None is used. More information on:
# https://kubernetes.io/docs/concepts/storage/volumes/#mount-propagation
mountPropagation: HostToContainer
## Assign a group of affinity scheduling rules
##
affinity: {}
# nodeAffinity:
# requiredDuringSchedulingIgnoredDuringExecution:
# nodeSelectorTerms:
# - matchFields:
# - key: metadata.name
# operator: In
# values:
# - target-host-name
# Annotations to be added to node exporter pods
podAnnotations:
# Fix for very slow GKE cluster upgrades
cluster-autoscaler.kubernetes.io/safe-to-evict: "true"
prometheus.io/scrape: "true"
prometheus.io/port: "9200"
prometheus.io/path: "/metrics"
# Extra labels to be added to node exporter pods
podLabels:
bu: "infra"
team: "infra-sre"
service: "node-exporter-infra-prd"
env: "prd"
priority: "p0"
type: "exporter"
# Annotations to be added to node exporter daemonset
daemonsetAnnotations:
prometheus.io/scrape: "true"
prometheus.io/port: "9200"
prometheus.io/path: "/metrics"
## set to true to add the release label so scraping of the servicemonitor with kube-prometheus-stack works out of the box
releaseLabel: false
# Custom DNS configuration to be added to prometheus-node-exporter pods
dnsConfig: {}
# nameservers:
# - 1.2.3.4
# searches:
# - ns1.svc.cluster-domain.example
# - my.dns.search.suffix
# options:
# - name: ndots
# value: "2"
# - name: edns0
## Assign a nodeSelector if operating a hybrid cluster
##
nodeSelector: {}
# kubernetes.io/os: linux
# kubernetes.io/arch: amd64
tolerations:
- operator: Exists
## Assign a PriorityClassName to pods if set
priorityClassName: "system-node-critical"
## Additional container arguments
##
extraArgs: []
# - --collector.diskstats.ignored-devices=^(ram|loop|fd|(h|s|v)d[a-z]|nvme\\d+n\\d+p)\\d+$
# - --collector.textfile.directory=/run/prometheus
## Additional mounts from the host to node-exporter container
##
extraHostVolumeMounts: []
# - name: <mountName>
# hostPath: <hostPath>
# mountPath: <mountPath>
# readOnly: true|false
# mountPropagation: None|HostToContainer|Bidirectional
## Additional configmaps to be mounted.
##
configmaps: []
# - name: <configMapName>
# mountPath: <mountPath>
secrets: []
# - name: <secretName>
# mountPath: <mountPatch>
## Override the deployment namespace
##
namespaceOverride: "monitoring"
## Additional containers for export metrics to text file
##
sidecars: []
## - name: nvidia-dcgm-exporter
## image: nvidia/dcgm-exporter:1.4.3
## Volume for sidecar containers
##
sidecarVolumeMount: []
## - name: collector-textfiles
## mountPath: /run/prometheus
## readOnly: false
## Additional mounts from the host to sidecar containers
##
sidecarHostVolumeMounts: []
# - name: <mountName>
# hostPath: <hostPath>
# mountPath: <mountPath>
# readOnly: true|false
# mountPropagation: None|HostToContainer|Bidirectional
## Additional InitContainers to initialize the pod
##
extraInitContainers: []
## Liveness probe
##
livenessProbe:
failureThreshold: 3
httpGet:
httpHeaders: []
scheme: http
initialDelaySeconds: 0
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
## Readiness probe
##
readinessProbe:
failureThreshold: 3
httpGet:
httpHeaders: []
scheme: http
initialDelaySeconds: 0
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
# Enable vertical pod autoscaler support for prometheus-node-exporter
verticalPodAutoscaler:
enabled: false
# Recommender responsible for generating recommendation for the object.
# List should be empty (then the default recommender will generate the recommendation)
# or contain exactly one recommender.
# recommenders:
# - name: custom-recommender-performance
# List of resources that the vertical pod autoscaler can control. Defaults to cpu and memory
controlledResources: []
# Specifies which resource values should be controlled: RequestsOnly or RequestsAndLimits.
# controlledValues: RequestsAndLimits
# 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 minimal number of replicas which need to be alive for VPA Updater to attempt pod eviction
# minReplicas: 1
# 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
# Extra manifests to deploy as an array
extraManifests: []
# - |
# apiVersion: v1
# kind: ConfigMap
# metadata:
# name: prometheus-extra
# data:
# extra-data: "value"
@@ -1,170 +0,0 @@
# Provide a name in place of prometheus-stackdriver-exporter for `app:` labels
nameOverride: "stackdriver-exporter-infra-prd"
# Provide a name to substitute for the full names of resources
fullnameOverride: "stackdriver-exporter-infra-prd"
# Number of exporters to run
replicaCount: 1
# Restart policy for container
restartPolicy: Always
image:
repository: prometheuscommunity/stackdriver-exporter
# if not set appVersion field from Chart.yaml is used
tag: "v0.16.0"
pullPolicy: IfNotPresent
## Optionally specify an array of imagePullSecrets.
## Secrets must be manually created in the namespace.
## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
##
# pullSecrets:
# - myDockerConfigJsonSecretName
resources:
requests:
cpu: 500m
memory: 512Mi
# limits:
# cpu: 100m
# memory: 128Mi
securityContext: {}
containerSecurityContext: {}
service:
type: ClusterIP
httpPort: 9255
annotations: {}
## Additional labels to add to all resources
customLabels:
bu: "infra"
team: "infra-sre"
service: "stackdriver-exporter-infra-prd"
env: "prd"
priority: "p0"
type: "exporter"
# app: prometheus-stackdriver-exporter
secret:
labels: {}
stackdriver:
# The Google Project ID to gather metrics for
projectId: "meesho-admin-prd-0622"
# An existing secret which contains credentials.json
serviceAccountSecret: ""
# Provide custom key for the existing secret to load credentials.json from
serviceAccountSecretKey: ""
# A service account key JSON file. Must be provided when no existing secret is used, in this case a new secret will be created holding this service account
serviceAccountKey: ""
# Max number of retries that should be attempted on 503 errors from Stackdriver
maxRetries: 0
# How long should Stackdriver_exporter wait for a result from the Stackdriver API
httpTimeout: 10s
# Max time between each request in an exp backoff scenario
maxBackoff: 5s
# The amount of jitter to introduce in an exp backoff scenario
backoffJitter: 1s
# The HTTP statuses that should trigger a retry
retryStatuses: 503
# Drop metrics from attached projects and fetch `project_id` only
dropDelegatedProjects: true
metrics:
# The prefixes to gather metrics for, we default to just CPU metrics.
typePrefixes: 'compute.googleapis.com/instance,cloudsql.googleapis.com/database,logging.googleapis.com/user/node_drain_metric,compute.googleapis.com/guest/system/uptime'
# The filters to refine the metrics query by using Filter objects that Google provides.
# Filter objects: project, group.id, resource.type, resource.labels.[KEY], metric.type, metric.labels.[KEY]
# https://cloud.google.com/monitoring/api/v3/filters
filters: []
# - 'pubsub.googleapis.com/subscription:resource.labels.subscription_id=monitoring.regex.full_match("us-west4.*my-team.*")'
# The frequency to request
interval: '5m'
# How far into the past to offset
offset: '0s'
# Offset for the Google Stackdriver Monitoring Metrics interval into the past by the ingest delay from the metric's metadata.
ingestDelay: false
# If enabled will treat all DELTA metrics as an in-memory counter instead of a gauge.
aggregateDeltas: false
# How long should a delta metric continue to be exported after GCP stops producing a metric
aggregateDeltasTTL: '30m'
web:
# Port to listen on
listenAddress: ':9255'
# Path under which to expose metrics.
path: /metrics
## Pod affinity
##
affinity: {}
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "9255"
prometheus.io/path: "/metrics"
## Pod extra arguments
##
extraArgs: {}
## Node labels for stackdriver-exporter pod assignment
## Ref: https://kubernetes.io/docs/user-guide/node-selection/
##
nodeSelector:
dedicated: "sre-shared-tmp"
## Node tolerations for stackdriver-exporter scheduling to nodes with taints
## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/
##
tolerations:
- key: "dedicated"
operator: "Equal"
value: "sre-shared-tmp"
effect: "NoSchedule"
## Service Account
##
serviceAccount:
# Specifies whether a ServiceAccount should be created
create: true
# The name of the ServiceAccount to use.
# If not set and create is false, 'default' is used
# If not set and create is true, a name is generated using the fullname template
name:
annotations: {
iam.gke.io/gcp-service-account: sa-stackdriver-exp-infra-prd@meesho-admin-prd-0622.iam.gserviceaccount.com
}
# Enable this if you're using https://github.com/coreos/prometheus-operator
serviceMonitor:
enabled: false
namespace: monitoring
# additionalLabels is the set of additional labels to add to the ServiceMonitor
additionalLabels: {}
# How long until a scrape request times out.
scrapeTimeout: '10s'
# fallback to the prometheus default unless specified
interval: 10s
# Defaults to what's used if you follow CoreOS [Prometheus Install Instructions](https://github.com/helm/charts/tree/master/stable/prometheus-operator#tldr)
honorLabels: true
# Whether Prometheus should use the timestamps of the metrics exposed by stackdriver-exporter
honorTimestamps: true
# MetricRelabelConfigs to apply to samples before ingestion https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#relabelconfig
metricRelabelings: []
# RelabelConfigs to apply to samples before scraping. https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#relabelconfig
relabelings: []
## Custom PrometheusRules to be defined
## ref: https://github.com/coreos/prometheus-operator#customresourcedefinitions
prometheusRule:
enabled: false
additionalLabels: {}
namespace: ""
rules: []
@@ -1,62 +0,0 @@
alloy:
enabled: false
agent:
enabled: false
minio:
enabled: false
pyroscope:
fullnameOverride: prd-pyroscope
image:
repository: grafana/pyroscope
pullPolicy: IfNotPresent
tag: ""
extraLabels:
bu: "infra"
team: "devops"
service: "prd-pyroscope"
env: "prd"
priority: "p1"
type: "pyroscope"
resources:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: "2"
memory: 4Gi
persistence:
enabled: true
accessModes:
- ReadWriteOnce
size: 50Gi
storageClassName: pd-balanced
nodeSelector:
dedicated: devops
tolerations:
- key: "dedicated"
operator: "Equal"
value: "devops"
effect: "NoSchedule"
podDisruptionBudget:
enabled: false
serviceAccount:
create: true
ingress:
enabled: true
className: nginx-internal
annotations: {}
hosts:
- pyroscope.meeshogcp.in
tls: []
@@ -1,652 +0,0 @@
# Default values for sonarqube.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
# If the deployment Type is set to Deployment sonarqube is deployed as a replica set.
deploymentType: "StatefulSet"
labels:
bu: "infra"
team: "devops"
service: "sonarqube-public-prd"
env: "prd"
priority: "p0"
type: "sonarqube"
# There should not be more than 1 sonarqube instance connected to the same database. Please set this value to 1 or 0 (in case you need to scale down programmatically).
replicaCount: 1
# How many revisions to retain (Deployment ReplicaSets or StatefulSets)
revisionHistoryLimit: 10
# This will use the default deployment strategy unless it is overriden
deploymentStrategy: {}
# Uncomment this to scheduler pods on priority
# priorityClassName: "high-priority"
## Use an alternate scheduler, e.g. "stork".
## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/
##
# schedulerName:
## Is this deployment for OpenShift? If so, we help with SCCs
OpenShift:
enabled: false
createSCC: true
edition: "community"
image:
repository: asia-southeast1-docker.pkg.dev/meesho-devops-admin-0622/admin/devops/sonarqube
tag: 10.4.0-{{ .Values.edition }}
pullPolicy: Always
# If using a private repository, the imagePullSecrets to use
# pullSecrets:
# - name: my-repo-secret
# Set security context for sonarqube pod
securityContext:
fsGroup: 0
# Set security context for sonarqube container
containerSecurityContext:
# Sonarqube dockerfile creates sonarqube user as UID and GID 1000
# Those default are used to match pod security standard restricted as least privileged approach
allowPrivilegeEscalation: false
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
seccompProfile:
type: RuntimeDefault
# capabilities:
# drop: ["ALL"]
# Settings to configure elasticsearch host requirements
elasticsearch:
# DEPRECATED: Use initSysctl.enabled instead
configureNode: false
bootstrapChecks: false
service:
type: ClusterIP
externalPort: 9000
internalPort: 9000
labels:
annotations: {}
# May be used in example for internal load balancing in GCP:
# cloud.google.com/load-balancer-type: Internal
# loadBalancerSourceRanges:
# - 0.0.0.0/0
# loadBalancerIP: 1.2.3.4
# Optionally create Network Policies
networkPolicy:
enabled: false
# If you plan on using the jmx exporter, you need to define where the traffic is coming from
prometheusNamespace: "monitoring"
# If you are using a external database and enable network Policies to be created
# you will need to explicitly allow egress traffic to your database
# expects https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.21/#networkpolicyspec-v1-networking-k8s-io
# additionalNetworkPolicys:
# will be used as default for ingress path and probes path, will be injected in .Values.env as SONAR_WEB_CONTEXT
# if .Values.env.SONAR_WEB_CONTEXT is set, this value will be ignored
sonarWebContext: ""
# also install the nginx ingress helm chart
nginx:
enabled: false
ingress:
enabled: true
# Used to create an Ingress record.
hosts:
- name: sonarqube-public-prd.infr-h1.meeshogcp.in
#sonarProperties:
# sonar.auth.saml.enabled: true
# sonar.auth.saml.applicationId: sonarqube
# sonar.auth.saml.providerName: <ProviderNameFromOkta>
# sonar.auth.saml.providerId: http://okta.url/<providerID>
# sonar.auth.saml.loginUrl: https://okta.url/sso/saml
# sonar.auth.saml.user.login: login
# sonar.auth.saml.user.name: name
# sonar.auth.saml.user.email: email
# sonar.auth.saml.group.name: groups
# sonar.auth.saml.certificate.secured: <CERT>
# sonar.core.serverBaseURL: https://sonar.url
# Different clouds or configurations might need /* as the default path
# path: /
# For additional control over serviceName and servicePort
# serviceName: someService
# servicePort: somePort
# the pathType can be one of the following values: Exact|Prefix|ImplementationSpecific(default)
# pathType: ImplementationSpecific
annotations:
kubernetes.io/ingress.class: nginx-external
nginx.ingress.kubernetes.io/proxy-body-size: "20M"
# kubernetes.io/tls-acme: "true"
# Set the ingressClassName on the ingress record
ingressClassName: nginx-external
# Additional labels for Ingress manifest file
# labels:
# traffic-type: external
# traffic-type: internal
tls: []
# Secrets must be manually created in the namespace. To generate a self-signed certificate (and private key) and then create the secret in the cluster please refer to official documentation available at https://kubernetes.github.io/ingress-nginx/user-guide/tls/#tls-secrets
# - secretName: chart-example-tls
# hosts:
# - chart-example.local
route:
enabled: false
host: ""
# Add tls section to secure traffic. TODO: extend this section with other secure route settings
# Comment this out if you want plain http route created.
tls:
termination: edge
annotations: {}
# See Openshift/OKD route annotation
# https://docs.openshift.com/container-platform/4.10/networking/routes/route-configuration.html#nw-route-specific-annotations_route-configuration
# haproxy.router.openshift.io/timeout: 1m
# Additional labels for Route manifest file
# labels:
# external: 'true'
# Affinity for pod assignment
# Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity
affinity: {}
# Tolerations for pod assignment
# Ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/
# taint a node with the following command to mark it as not schedulable for new pods
# kubectl taint nodes <node> sonarqube=true:NoSchedule
# The following statement will tolerate this taint and as such reverse a node for sonarqube
tolerations:
- key: "dedicated"
operator: "Equal"
value: "jenkins"
effect: "NoSchedule"
# Node labels for pod assignment
# Ref: https://kubernetes.io/docs/user-guide/node-selection/
# add a label to a node with the following command
# kubectl label node <node> sonarqube=true
nodeSelector:
dedicated: "jenkins"
# hostAliases allows the modification of the hosts file inside a container
hostAliases: []
# - ip: "192.168.1.10"
# hostnames:
# - "example.com"
# - "www.example.com"
readinessProbe:
initialDelaySeconds: 90
periodSeconds: 30
failureThreshold: 6
# Note that timeoutSeconds was not respected before Kubernetes 1.20 for exec probes
timeoutSeconds: 1
# If an ingress *path* other than the root (/) is defined, it should be reflected here
# A trailing "/" must be included
# deprecated please use sonarWebContext at the value top level
# sonarWebContext: /
livenessProbe:
initialDelaySeconds: 90
periodSeconds: 30
failureThreshold: 6
# Note that timeoutSeconds was not respected before Kubernetes 1.20 for exec probes
timeoutSeconds: 1
# If an ingress *path* other than the root (/) is defined, it should be reflected here
# A trailing "/" must be included
# deprecated please use sonarWebContext at the value top level
# sonarWebContext: /
startupProbe:
initialDelaySeconds: 180
periodSeconds: 10
failureThreshold: 24
# Note that timeoutSeconds was not respected before Kubernetes 1.20 for exec probes
timeoutSeconds: 1
# If an ingress *path* other than the root (/) is defined, it should be reflected here
# A trailing "/" must be included
# deprecated please use sonarWebContext at the value top level
# sonarWebContext: /
initContainers:
# image: busybox:1.36
# We allow the init containers to have a separate security context declaration because
# the initContainer may not require the same as SonarQube.
# Those default are used to match pod security standard restricted as least privileged approach
securityContext:
allowPrivilegeEscalation: false
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
seccompProfile:
type: RuntimeDefault
capabilities:
drop: ["ALL"]
# We allow the init containers to have a separate resources declaration because
# the initContainer does not take as much resources.
resources: {}
# Extra init containers to e.g. download required artifacts
extraInitContainers: {}
## Array of extra containers to run alongside the sonarqube container
##
## Example:
## - name: myapp-container
## image: busybox
## command: ['sh', '-c', 'echo Hello && sleep 3600']
##
extraContainers: []
## Provide a secret containing one or more certificate files in the keys that will be added to cacerts
## The cacerts file will be set via SONARQUBE_WEB_JVM_OPTS and SONAR_CE_JAVAOPTS
##
caCerts:
enabled: false
image: adoptopenjdk/openjdk11:alpine
secret: your-secret
initSysctl:
enabled: false
vmMaxMapCount: 524288
fsFileMax: 131072
nofile: 131072
nproc: 8192
# image: busybox:1.36
securityContext:
# Compatible with podSecurity standard privileged
privileged: true
# resources: {}
# This should not be required anymore, used to chown/chmod folder created by faulty CSI driver that are not applying properly POSIX fsgroup.
initFs:
enabled: false
# Image: busybox:1.36
# Compatible with podSecurity standard baseline.
securityContext:
privileged: false
runAsNonRoot: false
runAsUser: 0
runAsGroup: 0
seccompProfile:
type: RuntimeDefault
capabilities:
drop: ["ALL"]
add: ["CHOWN"]
prometheusExporter:
enabled: false
# jmx_prometheus_javaagent version to download from Maven Central
version: "0.17.2"
# Alternative full download URL for the jmx_prometheus_javaagent.jar (overrides prometheusExporter.version)
# downloadURL: ""
# if you need to ignore TLS certificates for whatever reason enable the following flag
noCheckCertificate: false
# Ports for the jmx prometheus agent to export metrics at
webBeanPort: 8000
ceBeanPort: 8001
config:
rules:
- pattern: ".*"
# Overrides config for the CE process Prometheus exporter (by default, the same rules are used for both the Web and CE processes).
# ceConfig:
# rules:
# - pattern: ".*"
# image: curlimages/curl:8.2.1
# For use behind a corporate proxy when downloading prometheus
# httpProxy: ""
# httpsProxy: ""
# noProxy: ""
# Reuse default initcontainers.securityContext that match restricted pod security standard
# securityContext: {}
prometheusMonitoring:
# Generate a Prometheus Pod Monitor (https://github.com/coreos/prometheus-operator)
#
podMonitor:
# Create PodMonitor Resource for Prometheus scraping
enabled: false
# Specify a custom namespace where the PodMonitor will be created
namespace: "sonarqube"
# Specify the interval how often metrics should be scraped
interval: 30s
# Specify the timeout after a scrape is ended
# scrapeTimeout: ""
# Name of the label on target services that prometheus uses as job name
# jobLabel: ""
# List of plugins to install.
# For example:
# plugins:
# install:
# - "https://github.com/AmadeusITGroup/sonar-stash/releases/download/1.3.0/sonar-stash-plugin-1.3.0.jar"
# - "https://github.com/SonarSource/sonar-ldap/releases/download/2.2-RC3/sonar-ldap-plugin-2.2.0.601.jar"
#
plugins:
image: curlimages/curl:8.2.1
install:
- https://github.com/iSergio/sonarqube-community-branch-plugin/releases/download/1.16.1/sonarqube-community-branch-plugin-1.16.1-SNAPSHOT.jar
- https://github.com/insideapp-oss/sonar-apple/releases/download/0.4.0/sonar-apple-plugin-0.4.0.jar
noCheckCertificate: false
env:
- name: TZ
value: Asia/Kolkata
- name: SONAR_WEB_JAVAOPTS
value: "-javaagent:/opt/sonarqube/extensions/plugins/sonarqube-community-branch-plugin-1.16.1-SNAPSHOT.jar=web"
- name: SONAR_CE_JAVAOPTS
value: "-javaagent:/opt/sonarqube/extensions/plugins/sonarqube-community-branch-plugin-1.16.1-SNAPSHOT.jar=ce"
# For use behind a corporate proxy when downloading plugins
# httpProxy: ""
# httpsProxy: ""
# noProxy: ""
# resources: {}
# .netrc secret file with a key "netrc" to use basic auth while downloading plugins
# netrcCreds: ""
# Set to true to not validate the server's certificate to download plugin
# Reuse default initcontainers.securityContext that match restricted pod security standard
# securityContext: {}
## (DEPRECATED) The following value sets SONAR_WEB_JAVAOPTS (e.g., jvmOpts: "-Djava.net.preferIPv4Stack=true"). However, this is deprecated, please set SONAR_WEB_JAVAOPTS or sonar.web.javaOpts directly instead.
jvmOpts: ""
## (DEPRECATED) The following value sets SONAR_CE_JAVAOPTS. However, this is deprecated, please set SONAR_CE_JAVAOPTS or sonar.ce.javaOpts directly instead.
jvmCeOpts: ""
## a monitoring passcode needs to be defined in order to get reasonable probe results
# not setting the monitoring passcode will result in a deployment that will never be ready
monitoringPasscode: "define_it"
# Alternatively, you can define the passcode loading it from an existing secret specifying the right key
# monitoringPasscodeSecretName: "pass-secret-name"
# monitoringPasscodeSecretKey: "pass-key"
## Environment variables to attach to the pods
##
# env:
# # If you use a different ingress path from /, you have to add it here as the value of SONAR_WEB_CONTEXT
# - name: SONAR_WEB_CONTEXT
# value: /sonarqube
# - name: VARIABLE
# value: my-value
# Set annotations for pods
annotations: {}
## We usually don't make specific ressource recommandations, as they are heavily dependend on
## The usage of SonarQube and the surrounding infrastructure.
## Adjust these values to your needs, but make sure that the memory limit is never under 4 GB
resources:
limits:
cpu: 800m
memory: 4Gi
requests:
cpu: 400m
memory: 2Gi
persistence:
enabled: true
## Set annotations on pvc
annotations: {}
## Specify an existing volume claim instead of creating a new one.
## When using this option all following options like storageClass, accessMode and size are ignored.
# existingClaim:
## If defined, storageClassName: <storageClass>
## If set to "-", storageClassName: "", which disables dynamic provisioning
## If undefined (the default) or set to null, no storageClassName spec is
## set, choosing the default provisioner. (gp2 on AWS, standard on
## GKE, AWS & OpenStack)
##
storageClass:
accessMode: ReadWriteOnce
size: 5Gi
uid: 1000
guid: 0
## Specify extra volumes. Refer to ".spec.volumes" specification : https://kubernetes.io/fr/docs/concepts/storage/volumes/
volumes: []
## Specify extra mounts. Refer to ".spec.containers.volumeMounts" specification : https://kubernetes.io/fr/docs/concepts/storage/volumes/
mounts: []
# In case you want to specify different resources for emptyDir than {}
emptyDir: {}
# Example of resouces that might be used:
# medium: Memory
# sizeLimit: 16Mi
# A custom sonar.properties file can be provided via dictionary.
# For example:
# sonarProperties:
# sonar.forceAuthentication: true
# sonar.security.realm: LDAP
# ldap.url: ldaps://organization.com
# Additional sonar properties to load from a secret with a key "secret.properties" (must be a string)
# sonarSecretProperties:
# Kubernetes secret that contains the encryption key for the sonarqube instance.
# The secret must contain the key 'sonar-secret.txt'.
# The 'sonar.secretKeyPath' property will be set automatically.
# sonarSecretKey: "settings-encryption-secret"
## Override JDBC values
## for external Databases
jdbcOverwrite:
# If enable the JDBC Overwrite, make sure to set `postgresql.enabled=false`
enable: false
# The JDBC url of the external DB
jdbcUrl: "jdbc:postgresql://myPostgress/myDatabase?socketTimeout=1500"
# The DB user that should be used for the JDBC connection
jdbcUsername: "sonarUser"
# Use this if you don't mind the DB password getting stored in plain text within the values file
jdbcPassword: "sonarPass"
## Alternatively, use a pre-existing k8s secret containing the DB password
# jdbcSecretName: "sonarqube-jdbc"
## and the secretValueKey of the password found within that secret
# jdbcSecretPasswordKey: "jdbc-password"
## (DEPRECATED) Configuration values for postgresql dependency
## ref: https://github.com/bitnami/charts/blob/master/bitnami/postgresql/README.md
postgresql:
# Enable to deploy the bitnami PostgreSQL chart
enabled: true
primary:
tolerations:
- key: "dedicated"
operator: "Equal"
value: "jenkins"
effect: "NoSchedule"
nodeSelector:
dedicated: "jenkins"
labels:
bu: "infra"
team: "devops"
service: "sonarqube-prd"
env: "prd"
priority: "p0"
type: "sonarqube-psql-master"
podLabels:
bu: "infra"
team: "devops"
service: "sonarqube-prd"
env: "prd"
priority: "p0"
type: "sonarqube-psql-master"
readReplicas:
tolerations:
- key: "dedicated"
operator: "Equal"
value: "jenkins"
effect: "NoSchedule"
nodeSelector:
dedicated: "jenkins"
labels:
bu: "infra"
team: "devops"
service: "sonarqube-prd"
env: "prd"
priority: "p0"
type: "sonarqube-psql-slave"
podLabels:
bu: "infra"
team: "devops"
service: "sonarqube-prd"
env: "prd"
priority: "p0"
type: "sonarqube-psql-slave"
## postgresql Chart global settings
# global:
# imageRegistry: ''
# imagePullSecrets: ''
## bitnami/postgres image tag
# image:
# tag: 11.7.0-debian-10-r9
# existingSecret Name of existing secret to use for PostgreSQL passwords
# The secret has to contain the keys postgresql-password which is the password for postgresqlUsername when it is
# different of postgres, postgresql-postgres-password which will override postgresqlPassword,
# postgresql-replication-password which will override replication.password and postgresql-ldap-password which will be
# used to authenticate on LDAP. The value is evaluated as a template.
# existingSecret: ""
#
# The bitnami chart enforces the key to be "postgresql-password". This value is only here for historic purposes
# existingSecretPasswordKey: "postgresql-password"
postgresqlUsername: "sonarUser"
postgresqlPassword: "sonarPass"
postgresqlDatabase: "sonarDB"
# Specify the TCP port that PostgreSQL should use
service:
port: 5432
resources:
limits:
cpu: 2
memory: 2Gi
requests:
cpu: 100m
memory: 200Mi
persistence:
enabled: true
accessMode: ReadWriteOnce
size: 2Gi
storageClass:
securityContext:
# For standard Kubernetes deployment, set enabled=true
# If using OpenShift, enabled=false for restricted SCC and enabled=true for anyuid/nonroot SCC
enabled: true
# fsGroup specification below are not applied if enabled=false. enabled=false is the required setting for OpenShift "restricted SCC" to work successfully.
# postgresql dockerfile sets user as 1001
fsGroup: 1001
containerSecurityContext:
# For standard Kubernetes deployment, set enabled=true
# If using OpenShift, enabled=false for restricted SCC and enabled=true for anyuid/nonroot SCC
enabled: true
# runAsUser specification below are not applied if enabled=false. enabled=false is the required setting for OpenShift "restricted SCC" to work successfully.
# postgresql dockerfile sets user as 1001, the rest aim at making it compatible with restricted pod security standard.
runAsUser: 1001
allowPrivilegeEscalation: false
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
capabilities:
drop: ["ALL"]
volumePermissions:
# For standard Kubernetes deployment, set enabled=false
# For OpenShift, set enabled=true and ensure to set volumepermissions.securitycontext.runAsUser below.
enabled: false
# if using restricted SCC set runAsUser: "auto" and if running under anyuid/nonroot SCC - runAsUser needs to match runAsUser above
securityContext:
runAsUser: 0
shmVolume:
chmod:
enabled: false
serviceAccount:
## If enabled = true, and name is not set, postgreSQL will create a serviceAccount
enabled: false
# name:
# Additional labels to add to the pods:
# podLabels:
# key: value
podLabels: {}
# For compatibility with 8.0 replace by "/opt/sq"
# For compatibility with 8.2, leave the default. They changed it back to /opt/sonarqube
sonarqubeFolder: /opt/sonarqube
tests:
image: ""
enabled: true
resources: {}
# For OpenShift set create=true to ensure service account is created.
serviceAccount:
create: false
# name:
# automountToken: false # default
## Annotations for the Service Account
annotations: {}
# extraConfig is used to load Environment Variables from Secrets and ConfigMaps
# which may have been written by other tools, such as external orchestrators.
#
# These Secrets/ConfigMaps are expected to contain Key/Value pairs, such as:
#
# apiVersion: v1
# kind: ConfigMap
# metadata:
# name: external-sonarqube-opts
# data:
# SONARQUBE_JDBC_USERNAME: foo
# SONARQUBE_JDBC_URL: jdbc:postgresql://db.example.com:5432/sonar
#
# These vars can then be injected into the environment by uncommenting the following:
#
# extraConfig:
# configmaps:
# - external-sonarqube-opts
extraConfig:
secrets: []
configmaps: []
# account:
# The values can be set to define the current and the (new) custom admin passwords at the startup (the username will remain "admin")
# adminPassword: admin
# currentAdminPassword: admin
# The above values can be also provided by a secret that contains "password" and "currentPassword" as keys. You can generate such a secret in your cluster
# using "kubectl create secret generic admin-password-secret-name --from-literal=password=admin --from-literal=currentPassword=admin"
# adminPasswordSecretName: ""
# # Reuse default initcontainers.securityContext that match restricted pod security standard
# # securityContext: {}
# resources:
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
# curlContainerImage: curlimages/curl:8.2.1
# adminJobAnnotations: {}
# deprecated please use sonarWebContext at the value top level
# sonarWebContext: /
terminationGracePeriodSeconds: 60
@@ -1,650 +0,0 @@
# Default values for sonarqube.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
# If the deployment Type is set to Deployment sonarqube is deployed as a replica set.
deploymentType: "StatefulSet"
labels:
bu: "infra"
team: "devops"
service: "sonarqube-prd"
env: "prd"
priority: "p0"
type: "sonarqube"
# There should not be more than 1 sonarqube instance connected to the same database. Please set this value to 1 or 0 (in case you need to scale down programmatically).
replicaCount: 1
# How many revisions to retain (Deployment ReplicaSets or StatefulSets)
revisionHistoryLimit: 10
# This will use the default deployment strategy unless it is overriden
deploymentStrategy: {}
# Uncomment this to scheduler pods on priority
# priorityClassName: "high-priority"
## Use an alternate scheduler, e.g. "stork".
## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/
##
# schedulerName:
## Is this deployment for OpenShift? If so, we help with SCCs
OpenShift:
enabled: false
createSCC: true
edition: "community"
image:
repository: asia-southeast1-docker.pkg.dev/meesho-devops-admin-0622/admin/devops/sonarqube
tag: 10.4.1-{{ .Values.edition }}
pullPolicy: Always
# If using a private repository, the imagePullSecrets to use
# pullSecrets:
# - name: my-repo-secret
# Set security context for sonarqube pod
securityContext:
fsGroup: 0
# Set security context for sonarqube container
containerSecurityContext:
# Sonarqube dockerfile creates sonarqube user as UID and GID 1000
# Those default are used to match pod security standard restricted as least privileged approach
allowPrivilegeEscalation: false
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
seccompProfile:
type: RuntimeDefault
# capabilities:
# drop: ["ALL"]
# Settings to configure elasticsearch host requirements
elasticsearch:
# DEPRECATED: Use initSysctl.enabled instead
configureNode: false
bootstrapChecks: false
service:
type: ClusterIP
externalPort: 9000
internalPort: 9000
labels:
annotations: {}
# May be used in example for internal load balancing in GCP:
# cloud.google.com/load-balancer-type: Internal
# loadBalancerSourceRanges:
# - 0.0.0.0/0
# loadBalancerIP: 1.2.3.4
# Optionally create Network Policies
networkPolicy:
enabled: false
# If you plan on using the jmx exporter, you need to define where the traffic is coming from
prometheusNamespace: "monitoring"
# If you are using a external database and enable network Policies to be created
# you will need to explicitly allow egress traffic to your database
# expects https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.21/#networkpolicyspec-v1-networking-k8s-io
# additionalNetworkPolicys:
# will be used as default for ingress path and probes path, will be injected in .Values.env as SONAR_WEB_CONTEXT
# if .Values.env.SONAR_WEB_CONTEXT is set, this value will be ignored
sonarWebContext: ""
# also install the nginx ingress helm chart
nginx:
enabled: false
ingress:
enabled: true
# Used to create an Ingress record.
hosts:
- name: sonarqube-prd.meeshogcp.in
#sonarProperties:
# sonar.auth.saml.enabled: true
# sonar.auth.saml.applicationId: sonarqube
# sonar.auth.saml.providerName: <ProviderNameFromOkta>
# sonar.auth.saml.providerId: http://okta.url/<providerID>
# sonar.auth.saml.loginUrl: https://okta.url/sso/saml
# sonar.auth.saml.user.login: login
# sonar.auth.saml.user.name: name
# sonar.auth.saml.user.email: email
# sonar.auth.saml.group.name: groups
# sonar.auth.saml.certificate.secured: <CERT>
# sonar.core.serverBaseURL: https://sonar.url
# Different clouds or configurations might need /* as the default path
# path: /
# For additional control over serviceName and servicePort
# serviceName: someService
# servicePort: somePort
# the pathType can be one of the following values: Exact|Prefix|ImplementationSpecific(default)
# pathType: ImplementationSpecific
annotations:
nginx.ingress.kubernetes.io/proxy-body-size: "20M"
# kubernetes.io/tls-acme: "true"
# Set the ingressClassName on the ingress record
ingressClassName: nginx-internal
# Additional labels for Ingress manifest file
# labels:
# traffic-type: external
# traffic-type: internal
tls: []
# Secrets must be manually created in the namespace. To generate a self-signed certificate (and private key) and then create the secret in the cluster please refer to official documentation available at https://kubernetes.github.io/ingress-nginx/user-guide/tls/#tls-secrets
# - secretName: chart-example-tls
# hosts:
# - chart-example.local
route:
enabled: false
host: ""
# Add tls section to secure traffic. TODO: extend this section with other secure route settings
# Comment this out if you want plain http route created.
tls:
termination: edge
annotations: {}
# See Openshift/OKD route annotation
# https://docs.openshift.com/container-platform/4.10/networking/routes/route-configuration.html#nw-route-specific-annotations_route-configuration
# haproxy.router.openshift.io/timeout: 1m
# Additional labels for Route manifest file
# labels:
# external: 'true'
# Affinity for pod assignment
# Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity
affinity: {}
# Tolerations for pod assignment
# Ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/
# taint a node with the following command to mark it as not schedulable for new pods
# kubectl taint nodes <node> sonarqube=true:NoSchedule
# The following statement will tolerate this taint and as such reverse a node for sonarqube
tolerations:
- key: "dedicated"
operator: "Equal"
value: "jenkins"
effect: "NoSchedule"
# Node labels for pod assignment
# Ref: https://kubernetes.io/docs/user-guide/node-selection/
# add a label to a node with the following command
# kubectl label node <node> sonarqube=true
nodeSelector:
dedicated: "jenkins"
# hostAliases allows the modification of the hosts file inside a container
hostAliases: []
# - ip: "192.168.1.10"
# hostnames:
# - "example.com"
# - "www.example.com"
readinessProbe:
initialDelaySeconds: 90
periodSeconds: 30
failureThreshold: 6
# Note that timeoutSeconds was not respected before Kubernetes 1.20 for exec probes
timeoutSeconds: 1
# If an ingress *path* other than the root (/) is defined, it should be reflected here
# A trailing "/" must be included
# deprecated please use sonarWebContext at the value top level
# sonarWebContext: /
livenessProbe:
initialDelaySeconds: 90
periodSeconds: 30
failureThreshold: 6
# Note that timeoutSeconds was not respected before Kubernetes 1.20 for exec probes
timeoutSeconds: 1
# If an ingress *path* other than the root (/) is defined, it should be reflected here
# A trailing "/" must be included
# deprecated please use sonarWebContext at the value top level
# sonarWebContext: /
startupProbe:
initialDelaySeconds: 180
periodSeconds: 10
failureThreshold: 24
# Note that timeoutSeconds was not respected before Kubernetes 1.20 for exec probes
timeoutSeconds: 1
# If an ingress *path* other than the root (/) is defined, it should be reflected here
# A trailing "/" must be included
# deprecated please use sonarWebContext at the value top level
# sonarWebContext: /
initContainers:
# image: busybox:1.36
# We allow the init containers to have a separate security context declaration because
# the initContainer may not require the same as SonarQube.
# Those default are used to match pod security standard restricted as least privileged approach
securityContext:
allowPrivilegeEscalation: false
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
seccompProfile:
type: RuntimeDefault
capabilities:
drop: ["ALL"]
# We allow the init containers to have a separate resources declaration because
# the initContainer does not take as much resources.
resources: {}
# Extra init containers to e.g. download required artifacts
extraInitContainers: {}
## Array of extra containers to run alongside the sonarqube container
##
## Example:
## - name: myapp-container
## image: busybox
## command: ['sh', '-c', 'echo Hello && sleep 3600']
##
extraContainers: []
## Provide a secret containing one or more certificate files in the keys that will be added to cacerts
## The cacerts file will be set via SONARQUBE_WEB_JVM_OPTS and SONAR_CE_JAVAOPTS
##
caCerts:
enabled: false
image: adoptopenjdk/openjdk11:alpine
secret: your-secret
initSysctl:
enabled: false
vmMaxMapCount: 524288
fsFileMax: 131072
nofile: 131072
nproc: 8192
# image: busybox:1.36
securityContext:
# Compatible with podSecurity standard privileged
privileged: true
# resources: {}
# This should not be required anymore, used to chown/chmod folder created by faulty CSI driver that are not applying properly POSIX fsgroup.
initFs:
enabled: false
# Image: busybox:1.36
# Compatible with podSecurity standard baseline.
securityContext:
privileged: false
runAsNonRoot: false
runAsUser: 0
runAsGroup: 0
seccompProfile:
type: RuntimeDefault
capabilities:
drop: ["ALL"]
add: ["CHOWN"]
prometheusExporter:
enabled: false
# jmx_prometheus_javaagent version to download from Maven Central
version: "0.17.2"
# Alternative full download URL for the jmx_prometheus_javaagent.jar (overrides prometheusExporter.version)
# downloadURL: ""
# if you need to ignore TLS certificates for whatever reason enable the following flag
noCheckCertificate: false
# Ports for the jmx prometheus agent to export metrics at
webBeanPort: 8000
ceBeanPort: 8001
config:
rules:
- pattern: ".*"
# Overrides config for the CE process Prometheus exporter (by default, the same rules are used for both the Web and CE processes).
# ceConfig:
# rules:
# - pattern: ".*"
# image: curlimages/curl:8.2.1
# For use behind a corporate proxy when downloading prometheus
# httpProxy: ""
# httpsProxy: ""
# noProxy: ""
# Reuse default initcontainers.securityContext that match restricted pod security standard
# securityContext: {}
prometheusMonitoring:
# Generate a Prometheus Pod Monitor (https://github.com/coreos/prometheus-operator)
#
podMonitor:
# Create PodMonitor Resource for Prometheus scraping
enabled: false
# Specify a custom namespace where the PodMonitor will be created
namespace: "sonarqube"
# Specify the interval how often metrics should be scraped
interval: 30s
# Specify the timeout after a scrape is ended
# scrapeTimeout: ""
# Name of the label on target services that prometheus uses as job name
# jobLabel: ""
# List of plugins to install.
# For example:
# plugins:
# install:
# - "https://github.com/AmadeusITGroup/sonar-stash/releases/download/1.3.0/sonar-stash-plugin-1.3.0.jar"
# - "https://github.com/SonarSource/sonar-ldap/releases/download/2.2-RC3/sonar-ldap-plugin-2.2.0.601.jar"
#
plugins:
image: curlimages/curl:8.2.1
install:
- https://github.com/mc1arke/sonarqube-community-branch-plugin/releases/download/1.17.1/sonarqube-community-branch-plugin-1.17.1.jar
noCheckCertificate: false
env:
- name: TZ
value: Asia/Kolkata
- name: SONAR_WEB_JAVAOPTS
value: "-javaagent:/opt/sonarqube/extensions/plugins/sonarqube-community-branch-plugin-1.17.1.jar=web"
- name: SONAR_CE_JAVAOPTS
value: "-javaagent:/opt/sonarqube/extensions/plugins/sonarqube-community-branch-plugin-1.17.1.jar=ce"
# For use behind a corporate proxy when downloading plugins
# httpProxy: ""
# httpsProxy: ""
# noProxy: ""
# resources: {}
# .netrc secret file with a key "netrc" to use basic auth while downloading plugins
# netrcCreds: ""
# Set to true to not validate the server's certificate to download plugin
# Reuse default initcontainers.securityContext that match restricted pod security standard
# securityContext: {}
## (DEPRECATED) The following value sets SONAR_WEB_JAVAOPTS (e.g., jvmOpts: "-Djava.net.preferIPv4Stack=true"). However, this is deprecated, please set SONAR_WEB_JAVAOPTS or sonar.web.javaOpts directly instead.
jvmOpts: ""
## (DEPRECATED) The following value sets SONAR_CE_JAVAOPTS. However, this is deprecated, please set SONAR_CE_JAVAOPTS or sonar.ce.javaOpts directly instead.
jvmCeOpts: ""
## a monitoring passcode needs to be defined in order to get reasonable probe results
# not setting the monitoring passcode will result in a deployment that will never be ready
monitoringPasscode: "define_it"
# Alternatively, you can define the passcode loading it from an existing secret specifying the right key
# monitoringPasscodeSecretName: "pass-secret-name"
# monitoringPasscodeSecretKey: "pass-key"
## Environment variables to attach to the pods
##
# env:
# # If you use a different ingress path from /, you have to add it here as the value of SONAR_WEB_CONTEXT
# - name: SONAR_WEB_CONTEXT
# value: /sonarqube
# - name: VARIABLE
# value: my-value
# Set annotations for pods
annotations: {}
## We usually don't make specific ressource recommandations, as they are heavily dependend on
## The usage of SonarQube and the surrounding infrastructure.
## Adjust these values to your needs, but make sure that the memory limit is never under 4 GB
resources:
limits:
cpu: 4
memory: 10Gi
requests:
cpu: 3
memory: 8Gi
persistence:
enabled: true
## Set annotations on pvc
annotations: {}
## Specify an existing volume claim instead of creating a new one.
## When using this option all following options like storageClass, accessMode and size are ignored.
# existingClaim:
## If defined, storageClassName: <storageClass>
## If set to "-", storageClassName: "", which disables dynamic provisioning
## If undefined (the default) or set to null, no storageClassName spec is
## set, choosing the default provisioner. (gp2 on AWS, standard on
## GKE, AWS & OpenStack)
##
storageClass:
accessMode: ReadWriteOnce
size: 5Gi
uid: 1000
guid: 0
## Specify extra volumes. Refer to ".spec.volumes" specification : https://kubernetes.io/fr/docs/concepts/storage/volumes/
volumes: []
## Specify extra mounts. Refer to ".spec.containers.volumeMounts" specification : https://kubernetes.io/fr/docs/concepts/storage/volumes/
mounts: []
# In case you want to specify different resources for emptyDir than {}
emptyDir: {}
# Example of resouces that might be used:
# medium: Memory
# sizeLimit: 16Mi
# A custom sonar.properties file can be provided via dictionary.
# For example:
# sonarProperties:
# sonar.forceAuthentication: true
# sonar.security.realm: LDAP
# ldap.url: ldaps://organization.com
# Additional sonar properties to load from a secret with a key "secret.properties" (must be a string)
# sonarSecretProperties:
# Kubernetes secret that contains the encryption key for the sonarqube instance.
# The secret must contain the key 'sonar-secret.txt'.
# The 'sonar.secretKeyPath' property will be set automatically.
# sonarSecretKey: "settings-encryption-secret"
## Override JDBC values
## for external Databases
jdbcOverwrite:
# If enable the JDBC Overwrite, make sure to set `postgresql.enabled=false`
enable: false
# The JDBC url of the external DB
jdbcUrl: "jdbc:postgresql://myPostgress/myDatabase?socketTimeout=1500"
# The DB user that should be used for the JDBC connection
jdbcUsername: "sonarUser"
# Use this if you don't mind the DB password getting stored in plain text within the values file
jdbcPassword: "sonarPass"
## Alternatively, use a pre-existing k8s secret containing the DB password
# jdbcSecretName: "sonarqube-jdbc"
## and the secretValueKey of the password found within that secret
# jdbcSecretPasswordKey: "jdbc-password"
## (DEPRECATED) Configuration values for postgresql dependency
## ref: https://github.com/bitnami/charts/blob/master/bitnami/postgresql/README.md
postgresql:
# Enable to deploy the bitnami PostgreSQL chart
enabled: true
primary:
# tolerations:
# - key: "dedicated"
# operator: "Equal"
# value: "jenkins"
# effect: "NoSchedule"
# nodeSelector:
# dedicated: "jenkins"
labels:
bu: "infra"
team: "devops"
service: "sonarqube-prd"
env: "prd"
priority: "p0"
type: "sonarqube-psql-master"
podLabels:
bu: "infra"
team: "devops"
service: "sonarqube-prd"
env: "prd"
priority: "p0"
type: "sonarqube-psql-master"
readReplicas:
# tolerations:
# - key: "dedicated"
# operator: "Equal"
# value: "jenkins"
# effect: "NoSchedule"
# nodeSelector:
# dedicated: "jenkins"
labels:
bu: "infra"
team: "devops"
service: "sonarqube-prd"
env: "prd"
priority: "p0"
type: "sonarqube-psql-slave"
podLabels:
bu: "infra"
team: "devops"
service: "sonarqube-prd"
env: "prd"
priority: "p0"
type: "sonarqube-psql-slave"
## postgresql Chart global settings
# global:
# imageRegistry: ''
# imagePullSecrets: ''
## bitnami/postgres image tag
# image:
# tag: 11.7.0-debian-10-r9
# existingSecret Name of existing secret to use for PostgreSQL passwords
# The secret has to contain the keys postgresql-password which is the password for postgresqlUsername when it is
# different of postgres, postgresql-postgres-password which will override postgresqlPassword,
# postgresql-replication-password which will override replication.password and postgresql-ldap-password which will be
# used to authenticate on LDAP. The value is evaluated as a template.
# existingSecret: ""
#
# The bitnami chart enforces the key to be "postgresql-password". This value is only here for historic purposes
# existingSecretPasswordKey: "postgresql-password"
postgresqlUsername: "sonarUser"
postgresqlPassword: "sonarPass"
postgresqlDatabase: "sonarDB"
# Specify the TCP port that PostgreSQL should use
service:
port: 5432
resources:
limits:
cpu: "2"
memory: 6Gi
requests:
cpu: "2"
memory: 4Gi
persistence:
enabled: true
accessMode: ReadWriteOnce
size: 2Gi
storageClass:
securityContext:
# For standard Kubernetes deployment, set enabled=true
# If using OpenShift, enabled=false for restricted SCC and enabled=true for anyuid/nonroot SCC
enabled: true
# fsGroup specification below are not applied if enabled=false. enabled=false is the required setting for OpenShift "restricted SCC" to work successfully.
# postgresql dockerfile sets user as 1001
fsGroup: 1001
containerSecurityContext:
# For standard Kubernetes deployment, set enabled=true
# If using OpenShift, enabled=false for restricted SCC and enabled=true for anyuid/nonroot SCC
enabled: true
# runAsUser specification below are not applied if enabled=false. enabled=false is the required setting for OpenShift "restricted SCC" to work successfully.
# postgresql dockerfile sets user as 1001, the rest aim at making it compatible with restricted pod security standard.
runAsUser: 1001
allowPrivilegeEscalation: false
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
capabilities:
drop: ["ALL"]
volumePermissions:
# For standard Kubernetes deployment, set enabled=false
# For OpenShift, set enabled=true and ensure to set volumepermissions.securitycontext.runAsUser below.
enabled: false
# if using restricted SCC set runAsUser: "auto" and if running under anyuid/nonroot SCC - runAsUser needs to match runAsUser above
securityContext:
runAsUser: 0
shmVolume:
chmod:
enabled: false
serviceAccount:
## If enabled = true, and name is not set, postgreSQL will create a serviceAccount
enabled: false
# name:
# Additional labels to add to the pods:
# podLabels:
# key: value
podLabels: {}
# For compatibility with 8.0 replace by "/opt/sq"
# For compatibility with 8.2, leave the default. They changed it back to /opt/sonarqube
sonarqubeFolder: /opt/sonarqube
tests:
image: ""
enabled: true
resources: {}
# For OpenShift set create=true to ensure service account is created.
serviceAccount:
create: false
# name:
# automountToken: false # default
## Annotations for the Service Account
annotations: {}
# extraConfig is used to load Environment Variables from Secrets and ConfigMaps
# which may have been written by other tools, such as external orchestrators.
#
# These Secrets/ConfigMaps are expected to contain Key/Value pairs, such as:
#
# apiVersion: v1
# kind: ConfigMap
# metadata:
# name: external-sonarqube-opts
# data:
# SONARQUBE_JDBC_USERNAME: foo
# SONARQUBE_JDBC_URL: jdbc:postgresql://db.example.com:5432/sonar
#
# These vars can then be injected into the environment by uncommenting the following:
#
# extraConfig:
# configmaps:
# - external-sonarqube-opts
extraConfig:
secrets: []
configmaps: []
# account:
# The values can be set to define the current and the (new) custom admin passwords at the startup (the username will remain "admin")
# adminPassword: admin
# currentAdminPassword: admin
# The above values can be also provided by a secret that contains "password" and "currentPassword" as keys. You can generate such a secret in your cluster
# using "kubectl create secret generic admin-password-secret-name --from-literal=password=admin --from-literal=currentPassword=admin"
# adminPasswordSecretName: ""
# # Reuse default initcontainers.securityContext that match restricted pod security standard
# # securityContext: {}
# resources:
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
# curlContainerImage: curlimages/curl:8.2.1
# adminJobAnnotations: {}
# deprecated please use sonarWebContext at the value top level
# sonarWebContext: /
terminationGracePeriodSeconds: 60
@@ -1,245 +0,0 @@
bootstrapScript: |
#!/bin/bash
apt-get update && apt-get install -y python3-dev default-libmysqlclient-dev
rm -rf /var/lib/apt/lists/*
pip install --upgrade pip
pip install \
sqlalchemy-bigquery \
cachelib \
redis \
authlib \
packaging==23.2 \
clickhouse-connect \
sqlalchemy==1.4.36 && \
if [ ! -f ~/bootstrap ]; then echo "Running Superset with uid {{ .Values.runAsUser }}" > ~/bootstrap; fi
extraEnv:
GUNICORN_TIMEOUT: 900
SERVER_WORKER_AMOUNT: 4
WORKER_MAX_REQUESTS: 0
WORKER_MAX_REQUESTS_JITTER: 0
SERVER_THREADS_AMOUNT: 20
GUNICORN_KEEPALIVE: 2
SERVER_LIMIT_REQUEST_LINE: 0
SERVER_LIMIT_REQUEST_FIELD_SIZE: 0
configOverrides:
sql_query_settings: |
SQL_MAX_ROW = 1000000
SQLLAB_CTAS_NO_LIMIT = True
FEATURE_FLAGS = {"ALLOW_FULL_CSV_EXPORT": True, "DRUID_JOINS": True, "ALERT_REPORTS": True, "ALLOW_ADHOC_SUBQUERY": True, "DASHBOARD_VIRTUALIZATION": True, "DYNAMIC_PLUGINS": True, "DRILL_TO_DETAIL": True, "DRILL_BY": True, "ENABLE_TEMPLATE_PROCESSING": True, "DASHBOARD_NATIVE_FILTERS": True, "DASHBOARD_CROSS_FILTERS": True, "EMBEDDED_SUPERSET": True, "DASHBOARD_RBAC": False}
metatda_db_settings:
SQLALCHEMY_DATABASE_URI = f"mysql+mysqldb://{env('DB_USER')}:{env('DB_PASS')}@{env('DB_HOST')}:{env('DB_PORT')}/{env('DB_NAME')}"
superset_config.py: |
import logging
import os
from datetime import timedelta
from typing import Optional
from cachelib.file import FileSystemCache
from celery.schedules import crontab
REDIS_HOST = os.environ.get("REDIS_HOST"),
REDIS_PORT = "6379"
REDIS_CELERY_DB = "0"
REDIS_RESULTS_DB = "1"
CACHE_CONFIG = {
"CACHE_TYPE": "RedisCache",
"CACHE_DEFAULT_TIMEOUT": 86400,
"CACHE_KEY_PREFIX": "superset_",
"CACHE_REDIS_HOST": REDIS_HOST,
"CACHE_REDIS_PORT": REDIS_PORT,
"CACHE_REDIS_DB": REDIS_RESULTS_DB,
}
DATA_CACHE_CONFIG = CACHE_CONFIG
class CeleryConfig:
broker_url = "redis://superset-infra-admin-prd-redis-master.prd-superset-infra.svc.cluster.local:6379/0"
imports = ('superset.sql_lab', "superset.tasks", "superset.tasks.thumbnails",)
result_backend = "redis://superset-infra-admin-prd-redis-master.prd-superset-infra.svc.cluster.local:6379/1"
CELERYD_LOG_LEVEL = "DEBUG"
worker_prefetch_multiplier = 10
task_acks_late = True
task_annotations = {
'sql_lab.get_sql_results': {
'rate_limit': '100/s',
},
'email_reports.send': {
'rate_limit': '1/s',
'time_limit': 600,
'soft_time_limit': 600,
'ignore_result': True,
},
}
CELERY_CONFIG = CeleryConfig
extend_timeout: |
# Extend timeout to allow long running queries.
SQLLAB_TIMEOUT = 300
SQLLAB_ASYNC_TIME_LIMIT_SEC = 900
SUPERSET_WEBSERVER_TIMEOUT = 300
enable_oauth: |
import os
from flask_appbuilder.security.manager import AUTH_OID, AUTH_REMOTE_USER, AUTH_DB, AUTH_LDAP, AUTH_OAUTH
basedir = os.path.abspath(os.path.dirname(__file__))
ENABLE_PROXY_FIX = True
AUTH_TYPE = AUTH_OAUTH
PREFERRED_URL_SCHEME = "https"
OAUTH_HOME_DOMAIN = "meesho.com"
CSRF_ENABLED = True
OAUTH_PROVIDERS = [
{
"name": "google",
"whitelist": [ "@meesho.com" ],
"icon": "fa-google",
"token_key": "access_token",
"remote_app": {
"client_id": os.environ.get("GOOGLE_KEY"),
"client_secret": os.environ.get("GOOGLE_SECRET"),
"api_base_url": "https://www.googleapis.com/oauth2/v2/",
"client_kwargs": {"scope": "email profile"},
"request_token_url": None,
"access_token_url": "https://accounts.google.com/o/oauth2/token",
"authorize_url": "https://accounts.google.com/o/oauth2/auth",
"authorize_params": {"hd": "meesho.com"}
}
}
]
# Map Authlib roles to superset roles
AUTH_ROLE_ADMIN = 'Admin'
AUTH_ROLE_PUBLIC = 'Public'
# Will allow user self registration, allowing to create Flask users from Authorized User
AUTH_USER_REGISTRATION = True
# The default user self registration role
AUTH_USER_REGISTRATION_ROLE = "read_user_basic"
cors: |
ENABLE_CORS = True
CORS_OPTIONS = {
'supports_credentials': True,
'allow_headers': [
'*',
],
'resources': [
'*'
],
'origins': ['*'],
}
WTF_CSRF_ENABLED = False
TALISMAN_ENABLED = False
ENABLE_PROXY_FIX = True
extend_timeout: |
SUPERSET_WEBSERVER_TIMEOUT = 300
secret: |
SECRET_KEY = os.getenv("SECRET_KEY")
ingress:
enabled: true
ingressClassName: nginx-external
annotations:
nginx.ingress.kubernetes.io/force-ssl-redirect: "false"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/proxy-connect-timeout: "300"
nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
nginx.ingress.kubernetes.io/proxy-send-timeout: "300"
path: /
pathType: Prefix
hosts:
- superset-infra-prd.meeshogcp.in
labels:
priority: p1
env: prd
team: devops
bu: infra
service: superset-infra
resources:
limits:
cpu: 1000m
memory: 1000Mi
requests:
cpu: 1000m
memory: 1000Mi
supersetNode:
replicas:
replicaCount: 2
connections:
redis_host: 'superset-infra-admin-prd-redis-master.prd-superset-infra.svc.cluster.local'
redis_port: "6379"
affinity: {}
resources:
limits:
cpu: 3
memory: 8000Mi
requests:
cpu: 2000m
memory: 4000Mi
supersetWorker:
replicas:
replicaCount: 2
resources:
limits:
cpu: 2000m
memory: 6000Mi
requests:
cpu: 1000m
memory: 3000Mi
init:
enabled: true
loadExamples: false
createAdmin: true
adminUser:
username: admin
firstname: Superset
lastname: Admin
email: devops@meesho.com
password: superset
celery:
enabled: true
broker_url: 'redis://superset-infra-admin-prd-redis-master.prd-superset-infra.svc.cluster.local:6379/0'
result_backend: 'redis://superset-infra-admin-prd-redis-master.prd-superset-infra.svc.cluster.local:6379/1'
worker:
replicas: 1 # Number of Celery workers
resources:
limits:
cpu: 500m
memory: 2000Mi
requests:
cpu: 100m
memory: 1000Mi
postgresql:
enabled: false
redis:
enabled: true
image:
registry: asia-southeast1-docker.pkg.dev
repository: meesho-devops-admin-0622/admin/devops/bitnami/redis
tag: "7.0.10-debian-11-r4"
pullPolicy: IfNotPresent
architecture: standalone
auth:
enabled: false
master:
resources:
limits:
cpu: 2
memory: 8000Mi
requests:
cpu: 1
memory: 4000Mi
tolerations:
- key: dedicated
operator: "Equal"
value: devops
effect: "NoSchedule"
@@ -1,209 +0,0 @@
fullnameOverride: "tempo"
serviceAccount:
annotations: {
iam.gke.io/gcp-service-account: sa-infr-sre-obs-prd@meesho-admin-prd-0622.iam.gserviceaccount.com
}
traces:
otlp:
http:
enabled: true
grpc:
enabled: true
receiverConfig:
max_recv_msg_size_mib: 50
storage:
trace:
backend: gcs
gcs:
bucket_name: "tempo_data"
prefix: "trace"
pool:
max_workers: 300
queue_depth: 100000
global_overrides:
defaults:
global:
max_bytes_per_trace: 0
# metrics_generator:
# processors: [span-metrics,service-graphs]
ingestion:
max_traces_per_user: 0
burst_size_bytes: 1000000000
rate_limit_bytes: 1000000000
server:
grpc_server_max_recv_msg_size: 500000000
grpc_server_max_send_msg_size: 500000000
http_server_read_timeout: 2m
http_server_write_timeout: 2m
distributor:
replicas: 1
resources:
limits:
cpu: 31
memory: 30Gi
requests:
cpu: 30
memory: 27Gi
nodeSelector:
dedicated: "tempo-highcpu"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "tempo-highcpu"
effect: "NoSchedule"
ingester:
replicas: 2
persistence:
enabled: true
size: 500Gi
storageClass: "premium-rwo"
resources:
limits:
cpu: 31
memory: 235Gi
requests:
cpu: 28
memory: 230Gi
nodeSelector:
dedicated: "tempo-highmem-h"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "tempo-highmem-h"
effect: "NoSchedule"
queryFrontend:
config:
max_outstanding_per_tenant: 8000
max_batch_size: 5
search:
concurrent_jobs: 8000
replicas: 1
resources:
limits:
cpu: 1
memory: 1Gi
requests:
cpu: 1
memory: 1Gi
nodeSelector:
dedicated: "tempo-standard-s"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "tempo-standard-s"
effect: "NoSchedule"
querier:
config:
trace_by_id:
query_timeout: 120s
search:
query_timeout: 300s
max_concurrent_queries: 100
frontend_worker:
grpc_client_config:
max_send_msg_size: 100000000
replicas: 1
resources:
limits:
cpu: 31
memory: 30Gi
requests:
cpu: 30
memory: 27Gi
nodeSelector:
dedicated: "tempo-highcpu"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "tempo-highcpu"
effect: "NoSchedule"
compactor:
config:
compaction:
block_retention: 72h
replicas: 6
resources:
limits:
cpu: 3
memory: 10Gi
requests:
cpu: 2
memory: 8Gi
nodeSelector:
dedicated: "tempo-standard-s"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "tempo-standard-s"
effect: "NoSchedule"
memcached:
replicas: 1
allocatedMemory: 51200
resources:
limits:
memory: 56320Mi
requests:
cpu: 500m
memory: 56320Mi
nodeSelector:
dedicated: "tempo-highmem"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "tempo-highmem"
effect: "NoSchedule"
metricsGenerator:
config:
storage:
remote_write:
- url: "http://mimir-nginx.mimir-distributed.svc.clusterset.local/api/v1/push"
send_exemplars: true
headers:
X-Scope-OrgID: anonymous
enabled: false
replicas: 1
resources:
limits:
cpu: 11
memory: 22Gi
requests:
cpu: 10
memory: 20Gi
nodeSelector:
dedicated: "tempo-standard-s"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "tempo-standard-s"
effect: "NoSchedule"
gateway:
enabled: true
ingress:
enabled: true
ingressClassName: nginx-internal
hosts:
- host: tempo.meeshogcp.in
paths:
- path: /
pathType: Prefix
tls: []
nodeSelector:
dedicated: "tempo-standard-s"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "tempo-standard-s"
effect: "NoSchedule"
@@ -1,168 +0,0 @@
# Default values for uptime-kuma.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
image:
repository: louislam/uptime-kuma
pullPolicy: IfNotPresent
# Overrides the image tag whose default is the chart appVersion.
tag: "1.21.3-debian"
dedicatedValue: true
imagePullSecrets: []
nameOverride: ""
fullnameOverride: prd-infra-uptime-kuma
labels:
bu: "infra"
team: "sre"
service: "prd-infra-uptime-kuma"
env: "prd"
priority: "p0"
type: "uptime-kuma"
arch: "amd64"
runpod: "ondemand"
# If this option is set to false a StateFulset instead of a Deployment is used
useDeploy: true
serviceAccount:
# Specifies whether a service account should be created
create: false
# Annotations to add to the service account
annotations: {}
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name: ""
podAnnotations: {}
podLabels: {}
# app: uptime-kuma
podEnv:
# a default port must be set. required by container
- name: "UPTIME_KUMA_PORT"
value: "3001"
podSecurityContext: {}
# fsGroup: 2000
securityContext: {}
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
service:
type: ClusterIP
port: 3001
nodePort:
annotations: {}
ingress:
enabled: true
className: nginx-internal
extraLabels: {}
# vhost: uptime-kuma.company.corp
annotations:
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
nginx.ingress.kubernetes.io/server-snippets: |
location / {
proxy_set_header Upgrade $http_upgrade;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_set_header Connection "upgrade";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_cache_bypass $http_upgrade;
}
hosts:
- host: prd-infra-uptime-kuma.meeshogcp.in
paths:
- path: /
pathType: ImplementationSpecific
tls:
[]
# - secretName: chart-example-tls
# hosts:
# - chart-example.local
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: 100m
memory: 128Mi
nodeSelector:
dedicated: "vmselect-temp"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "vmselect-temp"
effect: "NoSchedule"
affinity: {}
livenessProbe:
enabled: true
timeoutSeconds: 2
initialDelaySeconds: 15
readinessProbe:
enabled: true
initialDelaySeconds: 5
volume:
enabled: true
accessMode: ReadWriteOnce
size: 13Gi
# If you want to use a storage class other than the default, uncomment this
# line and define the storage class name
# storageClassName: meesho-gp3
# Reuse your own pre-existing PVC.
existingClaim: ""
strategy:
type: Recreate
# Prometheus ServiceMonitor configuration
serviceMonitor:
enabled: false
# -- Scrape interval. If not set, the Prometheus default scrape interval is used.
interval: 60s
# -- Timeout if metrics can't be retrieved in given time interval
scrapeTimeout: 10s
# -- Scheme to use when scraping, e.g. http (default) or https.
scheme: ~
# -- TLS configuration to use when scraping, only applicable for scheme https.
tlsConfig: {}
# -- Prometheus [RelabelConfigs] to apply to samples before scraping
relabelings: []
# -- Prometheus [MetricRelabelConfigs] to apply to samples before ingestion
metricRelabelings: []
# -- Prometheus ServiceMonitor selector, only select Prometheus's with these
# labels (if not set, select any Prometheus)
selector: {}
# -- Namespace where the ServiceMonitor resource should be created, default is
# the same as the release namespace
namespace: ~
# -- Additional labels to add to the ServiceMonitor
additionalLabels: {}
# -- Additional annotations to add to the ServiceMonitor
annotations: {}
@@ -1,67 +0,0 @@
vault:
# This started as your live `helm get values vault -n vault` output,
# verbatim. One deliberate deviation from that since: injector.enabled
# is now false, not true. Secret delivery into pods is going through
# External Secrets Operator instead of Vault Agent Injector sidecars —
# nothing currently depends on the injector (claude.md's "Pending / not
# yet built" list has "Vault Agent Injector annotations for pulling
# secrets at pod start" — never actually wired up to any workload), so
# this removes an unused webhook rather than breaking anything live.
#
# Production mode (file storage, not dev), standalone (no HA/raft).
# Init/unseal are still NEVER in Git or scripted: run by hand and keep
# the unseal keys / root token in a password manager, same as claude.md
# says. This adoption only manages Vault's own Deployment config, not
# its data or seal state.
#
# `ui = true` in the HCL block AND top-level ui.enabled: true are BOTH
# required — this is claude.md issue #10 (Vault UI 404'd until both were
# set; the chart has two separate toggles for the same thing).
injector:
enabled: false
server:
dataStorage:
enabled: true
# Must stay 5Gi to match the already-bound PVC — local-path-provisioner
# doesn't support volume expansion, same constraint as Gitea's PVC.
size: 5Gi
ha:
enabled: false
resources:
limits:
memory: 256Mi
requests:
cpu: 100m
memory: 128Mi
standalone:
enabled: true
config: |
ui = true
listener "tcp" {
address = "[::]:8200"
cluster_address = "[::]:8201"
tls_disable = "true" # lab only - enable TLS for anything beyond local testing
}
storage "file" {
path = "/vault/data"
}
# No ingress config existed here before — access was via two raw,
# unmanaged Ingress objects (vault-ingress, vault-ingress-tailscale)
# that don't match anything Helm would generate, so this creates new
# GitOps-managed ones alongside them rather than adopting. Once these
# are confirmed working, the two raw ones should be deleted by hand
# (kubectl -n vault delete ingress vault-ingress vault-ingress-tailscale)
# — do that only after confirming, not before, so there's no access gap.
ingress:
enabled: true
ingressClassName: contour
hosts:
- host: "vault.192.168.1.7.nip.io"
paths: []
- host: "vault.100.90.248.118.nip.io"
paths: []
ui:
enabled: true
@@ -1,296 +0,0 @@
# Default values for victoria-metrics-agent.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 2
fullnameOverride: vmagent-infra-prd-dr
# 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-infra-prd-dr-config" # Use same name as in fullnameOverride-config
dedicatedValue: false
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: ScheduleAnyway
labelSelector:
matchLabels:
type: vmagent-dr
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
type: vmagent-dr
# 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-infr-sre-vmagent-prd@meesho-admin-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-infra.meeshogcp.in/insert/100/prometheus/api/v1/write
- http://vminsert-infra-prd-dr.victoriametrics.svc.cluster.local:8480/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: "infra"
team: "sre"
service: "vmagent-infra-prd"
env: "prd"
priority: "p0"
type: "vmagent-dr"
# 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-infra-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-infra-prd-dr.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: 5
memory: 5Gi
# 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: "vmagent-dr"
tolerations:
- key: "dedicated"
operator: "Equal"
value: "vmagent-dr"
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: []

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