From 65b30af78ee7155695e7e7ae602963e9df98ac3f Mon Sep 17 00:00:00 2001 From: Bartosz Stebel Date: Fri, 18 Nov 2022 14:45:55 +0100 Subject: [PATCH] kube/postgres: add versioned library also use in mastodon-qa Change-Id: I628293fcfe9081c350087572ecda9e51ee18238f Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/1422 Reviewed-by: q3k --- app/mastodon/kube/mastodon.libsonnet | 18 ++++ kube/postgres_v.libsonnet | 155 +++++++++++++++++++++++++++ 2 files changed, 173 insertions(+) create mode 100644 kube/postgres_v.libsonnet diff --git a/app/mastodon/kube/mastodon.libsonnet b/app/mastodon/kube/mastodon.libsonnet index 383c3ae2..383e0818 100644 --- a/app/mastodon/kube/mastodon.libsonnet +++ b/app/mastodon/kube/mastodon.libsonnet @@ -1,5 +1,6 @@ local kube = import "../../../kube/kube.libsonnet"; local postgres = import "../../../kube/postgres.libsonnet"; +local postgres_v = import "../../../kube/postgres_v.libsonnet"; local redis = import "../../../kube/redis.libsonnet"; { @@ -126,6 +127,23 @@ local redis = import "../../../kube/redis.libsonnet"; password: kube.SecretKeyRef(app.config, "postgres-pass"), storageClassName: "waw-hdd-redundant-3", storageSize: "100Gi", + opts: { wal_level: "logical" }, + }, + }, + + #TODO(implr) remove above and replace with this post migration + postgresNew: postgres_v { + cfg+: { + version: "13.9", + namespace: cfg.namespace, + appName: "mastodon", + database: "mastodon", + username: "mastodon", + prefix: "waw3-", + password: kube.SecretKeyRef(app.config, "postgres-pass"), + storageClassName: "waw-hdd-redundant-3", + storageSize: "100Gi", + opts: { wal_level: "logical" }, }, }, diff --git a/kube/postgres_v.libsonnet b/kube/postgres_v.libsonnet new file mode 100644 index 00000000..1e156f4e --- /dev/null +++ b/kube/postgres_v.libsonnet @@ -0,0 +1,155 @@ +# PostgreSQL on Kubernetes, with versioned names + +local kube = import "kube.libsonnet"; + +{ + local postgres = self, + local cfg = postgres.cfg, + cfg:: { + namespace: error "namespace must be set", + appName: error "app name must be set", + storageClassName: "waw-hdd-paranoid-2", + prefix: "", # if set, should be 'foo-' + version: "10.4", # valid version tag for https://hub.docker.com/_/postgres/ + + image: "postgres:" + cfg.version, + database: error "database must be set", + username: error "username must be set", + # not literal, instead ref for env (like { secretKeyRef: ... }) + password: error "password must be set", + + storageSize: "30Gi", + + # This option can be used to customize initial database creation. For + # available options see: https://www.postgresql.org/docs/9.5/app-initdb.html + # Changing this option in already existing deployments will not affect + # existing database. + initdbArgs: null, + + # Extra postgres configuration options passed on startup. Accepts only + # string values. + # Example: { max_connections: "300" } + opts: {}, + }, + safeVersion:: std.strReplace(cfg.version, ".", "-"), + + makeName(suffix):: cfg.prefix + suffix + postgres.safeVersion, + + metadata:: { + namespace: cfg.namespace, + labels: { + "app.kubernetes.io/name": cfg.appName, + "app.kubernetes.io/managed-by": "kubecfg", + "app.kubernetes.io/component": "postgres_v", + "hswaw.net/postgres-version": postgres.safeVersion, + }, + }, + + volumeClaim: kube.PersistentVolumeClaim(postgres.makeName("postgres")) { + metadata+: postgres.metadata, + spec+: { + storageClassName: cfg.storageClassName, + accessModes: [ "ReadWriteOnce" ], + resources: { + requests: { + storage: cfg.storageSize, + }, + }, + }, + }, + deployment: kube.Deployment(postgres.makeName("postgres")) { + metadata+: postgres.metadata, + spec+: { + replicas: 1, + template+: { + spec+: { + volumes_: { + data: kube.PersistentVolumeClaimVolume(postgres.volumeClaim), + }, + containers_: { + postgres: kube.Container(postgres.makeName("postgres")) { + image: cfg.image, + ports_: { + client: { containerPort: 5432 }, + }, + env_: { + POSTGRES_DB: cfg.database, + POSTGRES_USER: cfg.username, + POSTGRES_PASSWORD: cfg.password, + PGDATA: "/var/lib/postgresql/data/pgdata", + } + if cfg.initdbArgs != null then { + POSTGRES_INITDB_ARGS: cfg.initdbArgs, + } else {}, + + args: std.flatMap( + function(k) ["-c", "%s=%s" % [k, cfg.opts[k]]], + std.objectFields(cfg.opts), + ), + + volumeMounts_: { + data: { mountPath: "/var/lib/postgresql/data" }, + }, + }, + }, + securityContext: { + runAsUser: 999, + }, + }, + }, + }, + }, + + svc: kube.Service(postgres.makeName("postgres")) { + metadata+: postgres.metadata, + target_pod:: postgres.deployment.spec.template, + spec+: { + ports: [ + { name: "client", port: 5432, targetPort: 5432, protocol: "TCP" }, + ], + type: "ClusterIP", + }, + }, + + bouncer: { + deployment: kube.Deployment(postgres.makeName("bouncer")) { + metadata+: postgres.metadata { + labels+: { + "app.kubernetes.io/component": "bouncer_v", + } + }, + spec+: { + replicas: 1, + template+: { + spec+: { + containers_: { + bouncer: kube.Container(postgres.makeName("bouncer")) { + image: "edoburu/pgbouncer:1.11.0", + ports_: { + client: { containerPort: 5432 }, + }, + env: [ + { name: "POSTGRES_PASSWORD", valueFrom: cfg.password }, + { name: "DATABASE_URL", value: "postgres://%s:$(POSTGRES_PASSWORD)@%s/%s" % [cfg.username, postgres.svc.host, cfg.database] }, + ], + }, + }, + }, + }, + }, + }, + svc: kube.Service(postgres.makeName("bouncer")) { + metadata+: postgres.metadata { + labels+: { + "app.kubernetes.io/component": "bouncer", + } + }, + target_pod:: postgres.bouncer.deployment.spec.template, + spec+: { + ports: [ + { name: "client", port: 5432, targetPort: 5432, protocol: "TCP" }, + ], + type: "ClusterIP", + }, + }, + }, +}