Skip to content

Commit e3ff3f9

Browse files
committed
push pgbouncer chart
1 parent de69870 commit e3ff3f9

13 files changed

+811
-0
lines changed

pgbouncer/.helmignore

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Patterns to ignore when building packages.
2+
# This supports shell glob matching, relative path matching, and
3+
# negation (prefixed with !). Only one pattern per line.
4+
.DS_Store
5+
6+
# Common VCS dirs
7+
.git/
8+
.gitignore
9+
.bzr/
10+
.bzrignore
11+
.hg/
12+
.hgignore
13+
.svn/
14+
15+
# Common backup files
16+
*.swp
17+
*.bak
18+
*.tmp
19+
*~
20+
21+
# Various IDEs
22+
.project
23+
.idea/
24+
*.tmproj
25+
26+
# Builded charts
27+
values.*.yaml
28+
*.tgz

pgbouncer/Chart.yaml

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
apiVersion: v1
2+
appVersion: "1.0.0"
3+
description: A Helm chart installing pgbouncer in kubernetes
4+
name: pgbouncer
5+
version: 1.2.1

pgbouncer/README.md

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# PgBouncer custom chart
2+
3+
## Configure PgBouncer
4+
Everything will be done in the helm `values` file.
5+
6+
1. Add your virtual users (authentication) in the list in `config.userlist`.
7+
2. Configure the main destination PostgreSQL server in `.config.postgresql` (hostname and port).
8+
3. Configure (mount) the credentials for the databases through `extraVolumeMounts` and `extraVolumes`.
9+
The secret need to have this structure (common structure in C2C):
10+
```
11+
dbname: mydatabase
12+
host: thehost
13+
password: mypassword
14+
port: "5432"
15+
user: myuser
16+
```
17+
18+
## Fine tune the user permissions
19+
Please read here what is PostgreSQL HBA: https://www.postgresql.org/docs/current/auth-pg-hba-conf.html. In a nutshell, it allows you to configure advanced permissions for the users.
20+
21+
This will allow us to configure the permissions for our virtual PgBouncer users.
22+
23+
For that uncomment `config.hba` and configure the file based on the documentation linked above.

pgbouncer/templates/_helpers.tpl

+139
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
{{/* vim: set filetype=mustache: */}}
2+
{{/*
3+
Expand the name of the chart.
4+
*/}}
5+
{{- define "pgbouncer.name" -}}
6+
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
7+
{{- end -}}
8+
9+
{{/*
10+
Create a default fully qualified app name.
11+
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
12+
If release name contains chart name it will be used as a full name.
13+
*/}}
14+
{{- define "pgbouncer.fullname" -}}
15+
{{- if .Values.fullnameOverride -}}
16+
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
17+
{{- else -}}
18+
{{- $name := default .Chart.Name .Values.nameOverride -}}
19+
{{- if contains $name .Release.Name -}}
20+
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
21+
{{- else -}}
22+
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
23+
{{- end -}}
24+
{{- end -}}
25+
{{- end -}}
26+
27+
{{/*
28+
Create chart name and version as used by the chart label.
29+
*/}}
30+
{{- define "pgbouncer.chart" -}}
31+
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
32+
{{- end -}}
33+
34+
{{/*
35+
Create content for userlist.txt secret
36+
*/}}
37+
{{- define "pgbouncer.secret.userlist" }}
38+
{{- if .Values.config.adminUser }}
39+
"{{ .Values.config.adminUser }}" "{{ required "A valid .Values.config.adminPassword entry required!" .Values.config.adminPassword }}"
40+
{{- end }}
41+
{{- if .Values.config.authUser }}
42+
"{{ .Values.config.authUser }}" "{{ required "A valid .Values.config.authPassword entry required!" .Values.config.authPassword }}"
43+
{{- end }}
44+
{{- range $key, $val := .Values.config.userlist }}
45+
"{{ $key }}" "{{ $val }}"
46+
{{- end }}
47+
{{- end }}
48+
49+
{{/*
50+
Create the name of the service account to use
51+
*/}}
52+
{{- define "pgbouncer.serviceAccountName" -}}
53+
{{- if not .Values.serviceAccount.name -}}
54+
{{ template "pgbouncer.fullname" . }}
55+
{{- else -}}
56+
{{- .Values.serviceAccount.name | trunc 63 | trimSuffix "-" -}}
57+
{{- end -}}
58+
{{- end -}}
59+
60+
{{/*
61+
Contruct and return the image to use
62+
*/}}
63+
{{- define "pgbouncer.image" -}}
64+
{{- if not .Values.image.registry -}}
65+
{{ printf "%s:%s" .Values.image.repository .Values.image.tag }}
66+
{{- else -}}
67+
{{ printf "%s/%s:%s" .Values.image.registry .Values.image.repository .Values.image.tag }}
68+
{{- end -}}
69+
{{- end -}}
70+
71+
{{/*
72+
Contruct and return the exporter image to use
73+
*/}}
74+
{{- define "pgbouncer.exporterImage" -}}
75+
{{- if not .Values.pgbouncerExporter.image.registry -}}
76+
{{ printf "%s:%s" .Values.pgbouncerExporter.image.repository .Values.pgbouncerExporter.image.tag }}
77+
{{- else -}}
78+
{{ printf "%s/%s:%s" .Values.pgbouncerExporter.image.registry .Values.pgbouncerExporter.image.repository .Values.pgbouncerExporter.image.tag }}
79+
{{- end -}}
80+
{{- end -}}
81+
82+
{{/*
83+
Return the appropriate apiVersion for deployment.
84+
*/}}
85+
{{- define "deployment.apiVersion" -}}
86+
{{- print "apps/v1" -}}
87+
{{- end -}}
88+
89+
{{/*
90+
Return the appropriate apiVersion for PodSecurityPolicy kind of objects.
91+
*/}}
92+
{{- define "podSecurityPolicy.apiVersion" -}}
93+
{{- if .Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy" -}}
94+
{{- print "policy/v1beta1" -}}
95+
{{- else -}}
96+
{{- print "extensions/v1beta1" -}}
97+
{{- end -}}
98+
{{- end -}}
99+
100+
{{/*
101+
Return the appropriate apiVersion for PodDisruptionBudget kind of objects.
102+
*/}}
103+
{{- define "podDisruptionBudget.apiVersion" -}}
104+
{{- if .Capabilities.APIVersions.Has "policy/v1/PodDisruptionBudget" -}}
105+
{{- print "policy/v1" -}}
106+
{{- else -}}
107+
{{- print "policy/v1beta1" -}}
108+
{{- end -}}
109+
{{- end -}}
110+
111+
{{/*
112+
Return the appropriate apiVersion for Role kind of objects.
113+
*/}}
114+
{{- define "role.apiVersion" -}}
115+
{{- if .Capabilities.APIVersions.Has "rbac.authorization.k8s.io/v1/Role" -}}
116+
{{- print "rbac.authorization.k8s.io/v1" -}}
117+
{{- else -}}
118+
{{- if .Capabilities.APIVersions.Has "rbac.authorization.k8s.io/v1beta1/Role" -}}
119+
{{- print "rbac.authorization.k8s.io/v1beta1" -}}
120+
{{- else -}}
121+
{{- print "rbac.authorization.k8s.io/v1alpha1" -}}
122+
{{- end -}}
123+
{{- end -}}
124+
{{- end -}}
125+
126+
{{/*
127+
Return the appropriate apiVersion for RoleBinding kind of objects.
128+
*/}}
129+
{{- define "roleBinding.apiVersion" -}}
130+
{{- if .Capabilities.APIVersions.Has "rbac.authorization.k8s.io/v1/RoleBinding" -}}
131+
{{- print "rbac.authorization.k8s.io/v1" -}}
132+
{{- else -}}
133+
{{- if .Capabilities.APIVersions.Has "rbac.authorization.k8s.io/v1beta1/RoleBinding" -}}
134+
{{- print "rbac.authorization.k8s.io/v1beta1" -}}
135+
{{- else -}}
136+
{{- print "rbac.authorization.k8s.io/v1alpha1" -}}
137+
{{- end -}}
138+
{{- end -}}
139+
{{- end -}}

pgbouncer/templates/configmap.yaml

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
apiVersion: v1
2+
kind: ConfigMap
3+
metadata:
4+
name: {{ include "pgbouncer.fullname" . }}-configmap
5+
labels:
6+
app.kubernetes.io/name: {{ include "pgbouncer.name" . }}
7+
helm.sh/chart: {{ include "pgbouncer.chart" . }}
8+
app.kubernetes.io/instance: {{ .Release.Name }}
9+
app.kubernetes.io/managed-by: {{ .Release.Service }}
10+
data:
11+
pgbouncer.ini: |
12+
[databases]
13+
%include /opt/bitnami/pgbouncer/conf/databases.txt
14+
15+
[pgbouncer]
16+
listen_addr = *
17+
listen_port = 5432
18+
auth_file = /etc/userlist/userlist.txt
19+
admin_users = {{ .Values.config.adminUser }}
20+
{{- if .Values.config.authUser }}
21+
auth_user = {{ .Values.config.authUser }}
22+
{{- end }}
23+
{{- range $key, $val := .Values.config.pgbouncer }}
24+
{{ $key }} = {{ $val }}
25+
{{- end }}
26+
{{- if .Values.config.hba }}
27+
hba.txt: |
28+
{{ .Values.config.hba | nindent 4 }}
29+
{{- end }}
30+
databases.txt: |
31+
{{ .Values.config.databases | nindent 4 }}

pgbouncer/templates/deployment.yaml

+165
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
apiVersion: {{ template "deployment.apiVersion" . }}
2+
kind: Deployment
3+
metadata:
4+
name: {{ include "pgbouncer.fullname" . }}
5+
labels:
6+
app.kubernetes.io/name: {{ template "pgbouncer.name" . }}
7+
helm.sh/chart: {{ template "pgbouncer.chart" . }}
8+
app.kubernetes.io/instance: {{ .Release.Name }}
9+
app.kubernetes.io/managed-by: {{ .Release.Service }}
10+
spec:
11+
replicas: {{ .Values.replicaCount }}
12+
revisionHistoryLimit: {{ .Values.revisionHistoryLimit }}
13+
{{ if .Values.updateStrategy -}}
14+
strategy: {{ .Values.updateStrategy | toYaml | trimSuffix "\n" | nindent 4 }}
15+
{{ end -}}
16+
{{ if .Values.minReadySeconds -}}
17+
minReadySeconds: {{ .Values.minReadySeconds }}
18+
{{ end -}}
19+
selector:
20+
matchLabels:
21+
app.kubernetes.io/name: {{ template "pgbouncer.name" . }}
22+
app.kubernetes.io/instance: {{ .Release.Name }}
23+
template:
24+
metadata:
25+
labels:
26+
app.kubernetes.io/name: {{ template "pgbouncer.name" . }}
27+
app.kubernetes.io/instance: {{ .Release.Name }}
28+
{{- if .Values.podLabels }}
29+
{{ range $key, $value := .Values.podLabels -}}
30+
{{ $key }}: {{ $value | quote }}
31+
{{- end -}}
32+
{{- end }}
33+
annotations:
34+
checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
35+
{{- if .Values.pgbouncerExporter.enabled }}
36+
prometheus.io/scrape: "true"
37+
prometheus.io/port: "{{ .Values.pgbouncerExporter.port }}"
38+
prometheus.io/path: "/metrics"
39+
{{- end }}
40+
{{ range $key, $value := .Values.podAnnotations -}}
41+
{{ $key }}: {{ $value | quote }}
42+
{{- end }}
43+
spec:
44+
serviceAccountName: {{ template "pgbouncer.serviceAccountName" . }}
45+
terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }}
46+
{{ if .Values.nodeSelector -}}
47+
nodeSelector: {{ toYaml .Values.nodeSelector | trimSuffix "\n" | nindent 8 }}
48+
{{ end -}}
49+
{{ if .Values.tolerations -}}
50+
tolerations: {{ toYaml .Values.tolerations | trimSuffix "\n" | nindent 6 }}
51+
{{ end -}}
52+
{{ if .Values.affinity -}}
53+
affinity: {{ toYaml .Values.affinity | trimSuffix "\n" | nindent 8 }}
54+
{{ end -}}
55+
{{ if .Values.priorityClassName -}}
56+
priorityClassName: {{ .Values.priorityClassName }}
57+
{{ end -}}
58+
{{ if .Values.runtimeClassName -}}
59+
runtimeClassName: {{ .Values.runtimeClassName }}
60+
{{ end -}}
61+
{{ if len .Values.imagePullSecrets -}}
62+
imagePullSecrets: {{ toYaml .Values.imagePullSecrets | trimSuffix "\n" | nindent 6 }}
63+
{{ end -}}
64+
{{ if .Values.extraInitContainers -}}
65+
initContainers: {{ toYaml .Values.extraInitContainers | trimSuffix "\n" | nindent 6 }}
66+
{{ end -}}
67+
containers:
68+
- name: pgbouncer
69+
image: {{ template "pgbouncer.image" . }}
70+
imagePullPolicy: {{ .Values.image.pullPolicy }}
71+
lifecycle:
72+
postStart:
73+
exec:
74+
command:
75+
- '/bin/sh'
76+
- '-c'
77+
- >
78+
until pids=$(pidof pgbouncer); do
79+
sleep 1
80+
done;
81+
for db_name in /etc/secrets-db/*; do
82+
cd $db_name
83+
echo "$(cat dbname) = host={{ .Values.config.postgresql.host }} port={{ .Values.config.postgresql.port }} dbname=$(cat dbname) user=$(cat user) password=$(cat password)" >> /opt/bitnami/pgbouncer/conf/databases.txt
84+
done;
85+
kill -1 1
86+
env:
87+
- name: POSTGRESQL_HOST
88+
value: "{{ .Values.config.postgresql.host }}"
89+
- name: POSTGRESQL_PORT
90+
value: "{{ .Values.config.postgresql.port }}"
91+
- name: PGBOUNCER_PORT
92+
value: "{{ .Values.config.postgresql.port }}"
93+
- name: POSTGRESQL_PASSWORD
94+
value: "0"
95+
{{- if .Values.extraEnvs }}
96+
{{ toYaml .Values.extraEnvs | trimSuffix "\n" | nindent 10 }}
97+
{{- end }}
98+
ports:
99+
- name: psql
100+
containerPort: 5432
101+
protocol: TCP
102+
readinessProbe:
103+
tcpSocket:
104+
port: 5432
105+
initialDelaySeconds: 10
106+
periodSeconds: 5
107+
livenessProbe:
108+
tcpSocket:
109+
port: 5432
110+
initialDelaySeconds: 60
111+
periodSeconds: 10
112+
{{- if .Values.resources }}
113+
resources: {{ toYaml .Values.resources | trimSuffix "\n" | nindent 10 }}
114+
{{- end }}
115+
volumeMounts:
116+
- name: config
117+
mountPath: /bitnami/pgbouncer/conf/
118+
- name: userlist
119+
mountPath: /etc/userlist/
120+
{{- if .Values.extraVolumeMounts -}}
121+
{{ toYaml .Values.extraVolumeMounts | trimSuffix "\n" | nindent 8 }}
122+
{{- end }}
123+
{{- if .Values.pgbouncerExporter.enabled }}
124+
- name: exporter
125+
image: {{ template "pgbouncer.exporterImage" . }}
126+
imagePullPolicy: {{ .Values.pgbouncerExporter.image.pullPolicy }}
127+
args:
128+
- --web.listen-address=:{{ .Values.pgbouncerExporter.port }}
129+
- --web.telemetry-path=/metrics
130+
- --log.level={{ .Values.pgbouncerExporter.log.level }}
131+
- --log.format={{ .Values.pgbouncerExporter.log.format }}
132+
- --pgBouncer.connectionString=postgres://$(PGBOUNCER_USER):$(PGBOUNCER_PASS)@127.0.0.1:5432/pgbouncer?sslmode=disable&connect_timeout=10
133+
env:
134+
- name: PGBOUNCER_USER
135+
valueFrom:
136+
secretKeyRef:
137+
name: {{ template "pgbouncer.fullname" . }}-secret
138+
key: adminUser
139+
- name: PGBOUNCER_PASS
140+
valueFrom:
141+
secretKeyRef:
142+
name: {{ template "pgbouncer.fullname" . }}-secret
143+
key: adminPassword
144+
{{- if .Values.pgbouncerExporter.resources }}
145+
resources: {{ toYaml .Values.pgbouncerExporter.resources | trimSuffix "\n" | nindent 10 }}
146+
{{- end }}
147+
ports:
148+
- name: exporter
149+
containerPort: {{ .Values.pgbouncerExporter.port }}
150+
protocol: TCP
151+
{{- end }}
152+
{{ if .Values.extraContainers -}}
153+
{{ toYaml .Values.extraContainers | trimSuffix "\n" | indent 6 | trimPrefix " " }}
154+
{{ end -}}
155+
volumes:
156+
- name: config
157+
configMap:
158+
defaultMode: 0777
159+
name: {{ template "pgbouncer.fullname" . }}-configmap
160+
- name: userlist
161+
secret:
162+
secretName: {{ template "pgbouncer.fullname" . }}-userlist-secret
163+
{{- if .Values.extraVolumes -}}
164+
{{ toYaml .Values.extraVolumes | trimSuffix "\n" | nindent 6 }}
165+
{{ end -}}

0 commit comments

Comments
 (0)