Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/workflows/render.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ jobs:
-e COOKIE_SECRET=test-cookie-secret \
-e INCIDENT_IO_API_KEY=inc_test \
-e RAFT_TOKEN=test-raft-token \
-e REDIS_URL=redis://redis.example.com:6379 \
-v /tmp/control.toml:/tmp/control.toml:ro \
"$CONTROL2_IMAGE" \
/usr/local/bin/control2 configcheck --config /tmp/control.toml
Expand Down
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Changelog

## 0.4.0

### Breaking changes

The redis service has been removed from the chart since control plane no longer needs it.

### Upgrading from 0.3.x

- Do `helm upgrade` to delete the `<release>-redis` resources.
- Remove `redis.*` and `control.config.redis.*` from your values file. Helm ignores these keys and does not show an error.
- If you use an external Redis, the control plane stops using it after the upgrade. You can remove the `redis-url` key from your Secret.
- If you pin `image.tag`, use a control image that accepts a `control.toml` without a `[redis]` section (strictly newer than `v2026-11-03`).
2 changes: 1 addition & 1 deletion Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ apiVersion: v2
name: pgdog-control
description: PgDog Control
type: application
version: 0.3.5
version: 0.4.0
appVersion: "main-ent"
81 changes: 5 additions & 76 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ The three somewhat complex steps are:

## Chart summary

This chart installs the PgDog control plane and, by default, a Redis instance.
This chart installs the PgDog control plane.

The PgDog deployment contains the following components:

Expand All @@ -50,44 +50,6 @@ The PgDog deployment contains the following components:
| Service account, Cluster role, Cluster role bindings | Service account with RBAC to access select Kube APIs. See [RBAC](#rbac) for more details. |
| NetworkPolicy | Optional; restricts ingress/egress traffic. See [NetworkPolicy](#networkpolicy) for more details. |

By default, the chart also deploys a single-replica Redis instance. The control plane uses Redis for storing metrics. Set `redis.enabled: false` and provide `redis.url` to use an external Redis instead. The chart-managed Redis has the following components:

| Components | Description |
| ---------- | ---------------------------------------------------------------------------------------- |
| Deployment | Redis deployment with one replica. |
| Service | Redis service pointing to the deployment, with selector labels configured automatically. |

```yaml
redis:
enabled: true
url: "" # defaults to redis://<release>-redis.<namespace>.svc.cluster.local:6379
image:
repository: redis
tag: "7-alpine"
pullPolicy: IfNotPresent
pullSecrets: []
```

| Option | Description |
| ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| `redis.enabled` | Deploy the chart-managed Redis resources (bool, default `true`). |
| `redis.pdb.enabled` | Create the Redis PodDisruptionBudget with `minAvailable: 1` (bool, default `true`). |
| `redis.url` | Redis connection string written to `[redis].url` in `control.toml`. When empty, defaults to the chart-managed Redis Service (string, default `""`). |
| `redis.image.repository` | Redis image repository (string, default `redis`). |
| `redis.image.tag` | Redis image tag (string, default `7-alpine`). |
| `redis.image.pullPolicy` | Redis image pull policy (string, default `IfNotPresent`). |
| `redis.image.pullSecrets` | Image pull secrets attached to the Redis pod (list, default `[]`). |

The Redis PodDisruptionBudget blocks voluntary evictions of the single Redis replica, including during node drains and managed node upgrades. Set `redis.pdb.enabled: false` to allow these evictions while keeping Redis deployed:

```yaml
redis:
pdb:
enabled: false
```

Redis will be unavailable while its pod is replaced. The pod retains its `cluster-autoscaler.kubernetes.io/safe-to-evict: "false"` annotation.

### Raft

Enable Raft with a top-level setting:
Expand Down Expand Up @@ -363,11 +325,10 @@ If your cluster manages RBAC out-of-band (a platform team's controller, GitOps,

## NetworkPolicy

When `networkPolicy.enabled` is `true`, the chart renders a `NetworkPolicy` for the control pod and, when `redis.enabled` is true, one for Redis, restricting traffic to what the control plane actually needs:
When `networkPolicy.enabled` is `true`, the chart renders a `NetworkPolicy` for the control pod, restricting traffic to what the control plane actually needs:

- Ingress on `control.port` from the `ingress-nginx` namespace only.
- Egress to Redis on port 6379, to `kube-system` for DNS, and to the public internet on 5432 (Postgres) and 443 (HTTPS, e.g. the AWS/CloudWatch/RDS APIs), excluding RFC1918 private ranges. When chart-managed Redis is enabled, the Redis rule is restricted to its pods; otherwise it permits egress to any destination on port 6379 so the external Redis can be reached.
- Chart-managed Redis accepts ingress only from the control pod and allows no egress.
- Egress to `kube-system` for DNS, and to the public internet on 5432 (Postgres) and 443 (HTTPS, e.g. the AWS/CloudWatch/RDS APIs), excluding RFC1918 private ranges.

In clusters that deny pod-to-pod traffic by default, the built-in ingress-nginx rule alone often isn't enough — for example, PgDog pods calling the control plane's API need their own rule. Use `networkPolicy.extraIngress` to add any number of additional ingress rules to the control `NetworkPolicy`:

Expand All @@ -389,7 +350,7 @@ networkPolicy:

| Option | Description |
| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `networkPolicy.enabled` | Render the control and, when enabled, Redis `NetworkPolicy` resources (bool, default `false`). |
| `networkPolicy.enabled` | Render the control `NetworkPolicy` (bool, default `false`). |
| `networkPolicy.extraIngress` | Additional ingress rules appended to the control `NetworkPolicy`, on top of the built-in ingress-nginx rule. Each entry follows the standard `NetworkPolicyIngressRule` schema (`from`/`ports`) and is passed through verbatim (list, default `[]`). |

## AWS access (EKS / IRSA)
Expand Down Expand Up @@ -644,7 +605,6 @@ Secrets are injected as environment variables. Leave corresponding inline values
| `COOKIE_SECRET` | Key used to sign session and CSRF cookies. |
| `INCIDENT_IO_API_KEY` | incident.io API key for creating incidents. |
| `RAFT_TOKEN` | Shared token authenticating Raft peers. |
| `REDIS_URL` | Redis connection URL, including credentials if required. |

Create `secrets.yaml` separately from the Helm release, replacing the example values:

Expand All @@ -663,7 +623,6 @@ stringData:
cookie-secret: "replace-with-a-random-key-of-at-least-32-bytes"
incident-io-api-key: "inc_your-api-key"
raft-token: "replace-with-a-shared-random-token"
redis-url: "redis://user:password@redis.example.com:6379"
```

Apply it in the release namespace with `kubectl apply -n <release-namespace> -f secrets.yaml`, then reference its keys in `values.yaml`:
Expand Down Expand Up @@ -696,14 +655,9 @@ raft:
secret:
name: control-secrets
tokenKey: raft-token
redis:
enabled: false
secret:
name: control-secrets
urlKey: redis-url
```

Cookie and Raft references disable their generated Secrets. A Redis reference omits the default URL; set `redis.enabled: false` for external Redis. Raft requires `raft.enabled: true`. The last four variables require a control image containing commit `80895477` or later.
Cookie and Raft references disable their generated Secrets. Raft requires `raft.enabled: true`. The last three variables require a control image containing commit `80895477` or later.

After rotating a Secret, run `kubectl rollout restart deployment/<release>-control` (use `statefulset` when Raft is enabled).

Expand Down Expand Up @@ -838,31 +792,6 @@ control:
| `bot_token` | Slack bot token with `chat:write` permission (string, optional). |
| `channel` | Slack channel ID or name for status updates (string, optional). |

### Redis persistence

`control.config.redis` controls how often the in-memory store is snapshotted to Redis between process restarts. The chart provisions an in-cluster Redis (`<release>-redis`) by default and writes its connection string to `[redis].url` in `control.toml`.

```yaml
control:
config:
redis:
save_interval_secs: 60
```

| Option | Description |
| -------------------- | ------------------------------------------------------------------------------- |
| `save_interval_secs` | How often the background task snapshots the store to Redis (int, default `60`). |

To use an external Redis, disable all chart-managed Redis resources and set its URL:

```yaml
redis:
enabled: false
url: redis://my-redis.cache:6379
```

For backwards compatibility, `control.config.redis.url` is still accepted, but `redis.url` is preferred.

## Examples

```sh
Expand Down
30 changes: 0 additions & 30 deletions templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,6 @@ the same cluster don't collide.
{{- printf "%s-%s-control" .Release.Name .Release.Namespace | trunc 63 | trimSuffix "-" }}
{{- end }}

{{- define "pgdog-control.redis.fullname" -}}
{{- printf "%s-redis" .Release.Name | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/* Stable DNS service and token Secret for the Raft members. */}}
{{- define "pgdog-control.raft.fullname" -}}
{{- printf "%s-raft" .Release.Name | trunc 63 | trimSuffix "-" -}}
Expand Down Expand Up @@ -80,16 +76,6 @@ render context so the Secret, ConfigMap, and pod checksum all agree.
{{- end -}}
{{- end }}

{{/*
Redis URL used by the control plane. redis.url is the public chart setting;
control.config.redis.url remains supported for backwards compatibility.
*/}}
{{- define "pgdog-control.redis.url" -}}
{{- $config := .Values.control.config | default dict -}}
{{- $redisConfig := $config.redis | default dict -}}
{{- .Values.redis.url | default $redisConfig.url | default (printf "redis://%s.%s.svc.cluster.local:6379" (include "pgdog-control.redis.fullname" .) .Release.Namespace) -}}
{{- end }}

{{/*
ServiceAccount name for the control component. Falls back to the
control fullname when not explicitly set in values.
Expand Down Expand Up @@ -131,19 +117,3 @@ app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/component: control
{{- end }}

{{/*
Labels for the redis component.
*/}}
{{- define "pgdog-control.redis.labels" -}}
{{ include "pgdog-control.commonLabels" . }}
{{ include "pgdog-control.redis.selectorLabels" . }}
{{- end }}

{{/*
Selector labels for the redis component.
*/}}
{{- define "pgdog-control.redis.selectorLabels" -}}
app.kubernetes.io/name: {{ include "pgdog-control.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/component: redis
{{- end }}
10 changes: 0 additions & 10 deletions templates/configmap.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -247,13 +247,3 @@ data:
channel = {{ .channel | quote }}
{{- end }}
{{- end }}

{{- $redis := $config.redis | default dict }}

[redis]
{{- if or .Values.redis.url $redis.url (not ((.Values.redis.secret | default dict).urlKey)) }}
url = {{ include "pgdog-control.redis.url" . | quote }}
{{- end }}
{{- with $redis.save_interval_secs }}
save_interval_secs = {{ . }}
{{- end }}
9 changes: 0 additions & 9 deletions templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -189,15 +189,6 @@ spec:
{{- end }}
{{- end }}
{{- end }}
{{- with .Values.redis.secret }}
{{- if .urlKey }}
- name: REDIS_URL
valueFrom:
secretKeyRef:
name: {{ required "redis.secret.name is required when urlKey is set" .name | quote }}
key: {{ .urlKey | quote }}
{{- end }}
{{- end }}
{{- with $auth.github }}
{{- with .secret }}
# OAuth credentials sourced from an existing Secret. The control
Expand Down
38 changes: 0 additions & 38 deletions templates/networkpolicy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,19 +42,6 @@ spec:
- protocol: TCP
port: {{ .Values.control.port }}
{{- end }}
{{- if .Values.redis.enabled }}
- to:
- podSelector:
matchLabels:
{{- include "pgdog-control.redis.selectorLabels" . | nindent 10 }}
ports:
- protocol: TCP
port: 6379
{{- else }}
- ports:
- protocol: TCP
port: 6379
{{- end }}
- to:
- ipBlock:
cidr: 0.0.0.0/0
Expand Down Expand Up @@ -84,29 +71,4 @@ spec:
port: 53
- protocol: TCP
port: 53
{{- if .Values.redis.enabled }}
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: {{ include "pgdog-control.redis.fullname" . }}
labels:
{{- include "pgdog-control.redis.labels" . | nindent 4 }}
spec:
podSelector:
matchLabels:
{{- include "pgdog-control.redis.selectorLabels" . | nindent 6 }}
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
{{- include "pgdog-control.selectorLabels" . | nindent 10 }}
ports:
- protocol: TCP
port: 6379
egress: []
{{- end }}
{{- end }}
55 changes: 0 additions & 55 deletions templates/redis-deployment.yaml

This file was deleted.

13 changes: 0 additions & 13 deletions templates/redis-pdb.yaml

This file was deleted.

17 changes: 0 additions & 17 deletions templates/redis-service.yaml

This file was deleted.

Loading
Loading