diff --git a/charts/console-api/Chart.yaml b/charts/console-api/Chart.yaml index d24df689..bb84d537 100644 --- a/charts/console-api/Chart.yaml +++ b/charts/console-api/Chart.yaml @@ -14,7 +14,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.11.2 +version: 0.12.0 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. diff --git a/charts/console-api/templates/pgbouncer-configmap.yaml b/charts/console-api/templates/pgbouncer-configmap.yaml new file mode 100644 index 00000000..7c84e608 --- /dev/null +++ b/charts/console-api/templates/pgbouncer-configmap.yaml @@ -0,0 +1,24 @@ +{{- if .Values.pgbouncer.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Chart.Name }}-{{ .Values.chain }}-pgbouncer-config + namespace: {{ .Release.Namespace }} +data: + pgbouncer.ini: | + [databases] + * = host={{ .Values.pgbouncer.upstream.host }} port={{ .Values.pgbouncer.upstream.port }} + + [pgbouncer] + listen_addr = 0.0.0.0 + listen_port = 5432 + auth_type = scram-sha-256 + auth_file = /etc/pgbouncer/auth/userlist.txt + pool_mode = transaction + max_prepared_statements = 200 + default_pool_size = {{ .Values.pgbouncer.defaultPoolSize }} + max_client_conn = {{ .Values.pgbouncer.maxClientConn }} + ignore_startup_parameters = extra_float_digits + log_connections = 0 + log_disconnections = 0 +{{- end }} diff --git a/charts/console-api/templates/pgbouncer-deployment.yaml b/charts/console-api/templates/pgbouncer-deployment.yaml new file mode 100644 index 00000000..1c2f316a --- /dev/null +++ b/charts/console-api/templates/pgbouncer-deployment.yaml @@ -0,0 +1,68 @@ +{{- if .Values.pgbouncer.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Chart.Name }}-{{ .Values.chain }}-pgbouncer + namespace: {{ .Release.Namespace }} + labels: + app: {{ .Chart.Name }}-{{ .Values.chain }}-pgbouncer + annotations: + secrets.doppler.com/reload: 'true' +spec: + replicas: {{ .Values.pgbouncer.replicas }} + selector: + matchLabels: + app: {{ .Chart.Name }}-{{ .Values.chain }}-pgbouncer + template: + metadata: + labels: + app: {{ .Chart.Name }}-{{ .Values.chain }}-pgbouncer + annotations: + checksum/config: {{ include (print $.Template.BasePath "/pgbouncer-configmap.yaml") . | sha256sum }} + spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + topologyKey: kubernetes.io/hostname + labelSelector: + matchLabels: + app: {{ .Chart.Name }}-{{ .Values.chain }}-pgbouncer + containers: + - name: pgbouncer + image: {{ .Values.pgbouncer.image }} + command: ["/usr/bin/pgbouncer", "/etc/pgbouncer/conf/pgbouncer.ini"] + ports: + - containerPort: 5432 + name: pgbouncer + protocol: TCP + volumeMounts: + - name: config + mountPath: /etc/pgbouncer/conf + readOnly: true + - name: userlist + mountPath: /etc/pgbouncer/auth + readOnly: true + resources: + {{- toYaml .Values.pgbouncer.resources | nindent 12 }} + readinessProbe: + tcpSocket: + port: pgbouncer + periodSeconds: 10 + livenessProbe: + tcpSocket: + port: pgbouncer + periodSeconds: 10 + failureThreshold: 6 + volumes: + - name: config + configMap: + name: {{ .Chart.Name }}-{{ .Values.chain }}-pgbouncer-config + - name: userlist + secret: + secretName: {{ .Chart.Name }}-{{ .Values.chain }}-secret + items: + - key: PGBOUNCER_USERLIST + path: userlist.txt +{{- end }} diff --git a/charts/console-api/templates/pgbouncer-pdb.yaml b/charts/console-api/templates/pgbouncer-pdb.yaml new file mode 100644 index 00000000..489cb902 --- /dev/null +++ b/charts/console-api/templates/pgbouncer-pdb.yaml @@ -0,0 +1,12 @@ +{{- if .Values.pgbouncer.enabled }} +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ .Chart.Name }}-{{ .Values.chain }}-pgbouncer + namespace: {{ .Release.Namespace }} +spec: + maxUnavailable: 1 + selector: + matchLabels: + app: {{ .Chart.Name }}-{{ .Values.chain }}-pgbouncer +{{- end }} diff --git a/charts/console-api/templates/pgbouncer-service.yaml b/charts/console-api/templates/pgbouncer-service.yaml new file mode 100644 index 00000000..c6e6aa54 --- /dev/null +++ b/charts/console-api/templates/pgbouncer-service.yaml @@ -0,0 +1,16 @@ +{{- if .Values.pgbouncer.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ .Chart.Name }}-{{ .Values.chain }}-pgbouncer + namespace: {{ .Release.Namespace }} +spec: + selector: + app: {{ .Chart.Name }}-{{ .Values.chain }}-pgbouncer + ports: + - protocol: TCP + port: 5432 + targetPort: pgbouncer + name: pgbouncer + type: ClusterIP +{{- end }} diff --git a/charts/console-api/values.yaml b/charts/console-api/values.yaml index a19ebb6c..1ddab95f 100644 --- a/charts/console-api/values.yaml +++ b/charts/console-api/values.yaml @@ -59,3 +59,22 @@ jobDefaults: cpu: 50m ephemeral-storage: 1Gi memory: 256Mi + +# Transaction-mode pooler in front of the database. Needs a PGBOUNCER_USERLIST key in the release's Doppler secret, one `"user" "password"` line per database user. +pgbouncer: + enabled: false + replicas: 2 + image: edoburu/pgbouncer:v1.26.1-p0 + upstream: + host: cloudsql-proxy-console-api + port: 5432 + # Server connections per database and user, on each replica. + defaultPoolSize: 20 + maxClientConn: 2000 + resources: + limits: + cpu: 1 + memory: 256Mi + requests: + cpu: 50m + memory: 64Mi