blob: a80c23606bddb2b6f787b1f29d47a3635666f078 [file] [log] [blame]
Sergiusz Bazanski5f2dc852019-04-02 02:36:22 +02001# PostgreSQL on Kubernetes.
2
3local kube = import "kube.libsonnet";
4
5{
6 local postgres = self,
7 local cfg = postgres.cfg,
8 cfg:: {
9 namespace: error "namespace must be set",
10 appName: error "app name must be set",
Sergiusz Bazanskid07861b2019-08-08 17:48:25 +020011 storageClassName: "waw-hdd-paranoid-2",
Sergiusz Bazanski5f2dc852019-04-02 02:36:22 +020012 prefix: "", # if set, should be 'foo-'
13
14 image: "postgres:10.4",
15 database: error "database must be set",
16 username: error "username must be set",
17 # not literal, instead ref for env (like { secretKeyRef: ... })
18 password: error "password must be set",
Serge Bazanskic0c037a2020-08-23 01:24:03 +000019
20 storageSize: "30Gi",
Piotr Dobrowolski1816f582021-01-30 11:53:38 +010021
22 # This option can be used to customize initial database creation. For
23 # available options see: https://www.postgresql.org/docs/9.5/app-initdb.html
24 # Changing this option in already existing deployments will not affect
25 # existing database.
26 initdbArgs: null,
Sergiusz Bazanski5f2dc852019-04-02 02:36:22 +020027 },
28
29 makeName(suffix):: cfg.prefix + suffix,
30
31 metadata:: {
32 namespace: cfg.namespace,
33 labels: {
34 "app.kubernetes.io/name": cfg.appName,
35 "app.kubernetes.io/managed-by": "kubecfg",
36 "app.kubernetes.io/component": "postgres",
37 },
38 },
39
40 volumeClaim: kube.PersistentVolumeClaim(postgres.makeName("postgres")) {
41 metadata+: postgres.metadata,
42 spec+: {
43 storageClassName: cfg.storageClassName,
44 accessModes: [ "ReadWriteOnce" ],
45 resources: {
46 requests: {
Serge Bazanskic0c037a2020-08-23 01:24:03 +000047 storage: cfg.storageSize,
Sergiusz Bazanski5f2dc852019-04-02 02:36:22 +020048 },
49 },
50 },
51 },
52 deployment: kube.Deployment(postgres.makeName("postgres")) {
53 metadata+: postgres.metadata,
54 spec+: {
55 replicas: 1,
56 template+: {
57 spec+: {
58 volumes_: {
59 data: kube.PersistentVolumeClaimVolume(postgres.volumeClaim),
60 },
61 containers_: {
62 postgres: kube.Container(postgres.makeName("postgres")) {
63 image: cfg.image,
64 ports_: {
65 client: { containerPort: 5432 },
66 },
67 env_: {
68 POSTGRES_DB: cfg.database,
69 POSTGRES_USER: cfg.username,
70 POSTGRES_PASSWORD: cfg.password,
71 PGDATA: "/var/lib/postgresql/data/pgdata",
Piotr Dobrowolski1816f582021-01-30 11:53:38 +010072 } + if cfg.initdbArgs != null then {
73 POSTGRES_INITDB_ARGS: cfg.initdbArgs,
74 } else {},
Sergiusz Bazanski5f2dc852019-04-02 02:36:22 +020075 volumeMounts_: {
76 data: { mountPath: "/var/lib/postgresql/data" },
77 },
78 },
79 },
Sergiusz Bazanskia2ee8652020-01-22 21:48:48 +010080 securityContext: {
81 runAsUser: 999,
82 },
Sergiusz Bazanski5f2dc852019-04-02 02:36:22 +020083 },
84 },
85 },
86 },
Serge Bazanskic0c037a2020-08-23 01:24:03 +000087
Sergiusz Bazanski5f2dc852019-04-02 02:36:22 +020088 svc: kube.Service(postgres.makeName("postgres")) {
89 metadata+: postgres.metadata,
90 target_pod:: postgres.deployment.spec.template,
91 spec+: {
92 ports: [
93 { name: "client", port: 5432, targetPort: 5432, protocol: "TCP" },
94 ],
95 type: "ClusterIP",
96 },
97 },
Sergiusz Bazanskic622a192020-02-15 12:39:14 +010098
99 bouncer: {
100 deployment: kube.Deployment(postgres.makeName("bouncer")) {
101 metadata+: postgres.metadata {
102 labels+: {
103 "app.kubernetes.io/component": "bouncer",
104 }
105 },
106 spec+: {
107 replicas: 1,
108 template+: {
109 spec+: {
110 containers_: {
111 bouncer: kube.Container(postgres.makeName("bouncer")) {
112 image: "edoburu/pgbouncer:1.11.0",
113 ports_: {
114 client: { containerPort: 5432 },
115 },
116 env: [
117 { name: "POSTGRES_PASSWORD", valueFrom: cfg.password },
118 { name: "DATABASE_URL", value: "postgres://%s:$(POSTGRES_PASSWORD)@%s/%s" % [cfg.username, postgres.svc.host, cfg.database] },
119 ],
120 },
121 },
122 },
123 },
124 },
125 },
126 svc: kube.Service(postgres.makeName("bouncer")) {
127 metadata+: postgres.metadata {
128 labels+: {
129 "app.kubernetes.io/component": "bouncer",
130 }
131 },
132 target_pod:: postgres.bouncer.deployment.spec.template,
133 spec+: {
134 ports: [
135 { name: "client", port: 5432, targetPort: 5432, protocol: "TCP" },
136 ],
137 type: "ClusterIP",
138 },
139 },
140 },
Sergiusz Bazanski5f2dc852019-04-02 02:36:22 +0200141}