feat: add basic pgo

This commit is contained in:
Kasper Juul Hermansen 2023-04-06 02:21:56 +02:00
commit ebd0fcf700
Signed by: kjuulh
GPG Key ID: 57B6E1465221F912
128 changed files with 61656 additions and 0 deletions

1
pgo/.helmignore Normal file
View File

@ -0,0 +1 @@
.git*

6
pgo/Chart.yaml Normal file
View File

@ -0,0 +1,6 @@
apiVersion: v2
appVersion: 5.3.1
description: Installer for PGO, the open source Postgres Operator from Crunchy Data
name: pgo
type: application
version: 5.3.1

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

31
pgo/templates/NOTES.txt Normal file
View File

@ -0,0 +1,31 @@
Thank you for deploying PGO v{{ .Chart.AppVersion }}!
((((((((((((((((((((((
(((((((((((((%%%%%%%(((((((((((((((
(((((((((((%%% %%%%((((((((((((
(((((((((((%%( (((( ( %%%(((((((((((
(((((((((((((%% (( ,(( %%%(((((((((((
(((((((((((((((%% *%%/ %%%%%%%((((((((((
(((((((((((((((((((%%(( %%%%%%%%%%#(((((%%%%%%%%%%#((((((((((((
((((((((((((((((((%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%((((((((((((((
*((((((((((((((((((((%%%%%% /%%%%%%%%%%%%%%%%%%%((((((((((((((((
(((((((((((((((((((((((%%%/ .%, %%%((((((((((((((((((,
((((((((((((((((((((((% %#(((((((((((((((((
(((((((((((((((%%%%%% #%(((((((((((((((((
((((((((((((((%% %%(((((((((((((((,
((((((((((((%%%#% % %%(((((((((((((((
((((((((((((%. % % #((((((((((((((
(((((((((((%% % %%* %(((((((((((((
#(###(###(#%% %%% %% %%% #%%#(###(###(#
###########%%%%% /%%%%%%%%%%%%% %% %%%%% ,%%#######
###############%% %%%%%% %%% %%%%%%%% %%#####
################%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %%##
################%% %%%%%%%%%%%%%%%%% %%%% %
##############%# %% (%%%%%%% %%%%%%
#############% %%%%% %%%%%%%%%%%
###########% %%%%%%%%%%% %%%%%%%%%
#########%% %% %%%%%%%%%%%%%%%#
########%% %% %%%%%%%%%
######%% %% %%%%%%
####%%% %%%%% %
%% %%%%

View File

@ -0,0 +1,94 @@
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "install.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Crunchy labels
*/}}
{{- define "install.clusterLabels" -}}
postgres-operator.crunchydata.com/control-plane: {{ .Chart.Name }}
{{- end }}
{{- define "install.upgradeLabels" -}}
postgres-operator.crunchydata.com/control-plane: {{ .Chart.Name }}-upgrade
{{- end }}
{{/*
Common labels
*/}}
{{- define "install.labels" -}}
helm.sh/chart: {{ include "install.chart" . }}
app.kubernetes.io/name: {{ .Chart.Name }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Create the name of the service account to use
*/}}
{{- define "install.serviceAccountName" -}}
{{ .Chart.Name }}
{{- end }}
{{/*
Create the name of the Role/ClusterRole to use
*/}}
{{- define "install.roleName" -}}
{{ .Chart.Name }}
{{- end }}
{{/*
Create the name of the RoleBinding/ClusterRoleBinding to use
*/}}
{{- define "install.roleBindingName" -}}
{{ .Chart.Name }}
{{- end }}
{{/*
Create the kind for rolebindings. Will be RoleBinding in single
namespace mode or ClusterRoleBinding by default.
*/}}
{{- define "install.roleBindingKind" -}}
{{- if .Values.singleNamespace -}}
RoleBinding
{{- else -}}
ClusterRoleBinding
{{- end }}
{{- end }}
{{/*
Create the kind for role. Will be Role in single
namespace mode or ClusterRole by default.
*/}}
{{- define "install.roleKind" -}}
{{- if .Values.singleNamespace -}}
Role
{{- else -}}
ClusterRole
{{- end }}
{{- end }}
{{- define "install.imagePullSecrets" -}}
{{/* Earlier versions required the full structure of PodSpec.ImagePullSecrets */}}
{{- if .Values.imagePullSecrets }}
imagePullSecrets:
{{ toYaml .Values.imagePullSecrets }}
{{- else if .Values.imagePullSecretNames }}
imagePullSecrets:
{{- range .Values.imagePullSecretNames }}
- name: {{ . | quote }}
{{- end }}{{/* range */}}
{{- end }}{{/* if */}}
{{- end }}{{/* define */}}
{{- define "install.relatedImages" -}}
{{- range $id, $object := .Values.relatedImages }}
- name: RELATED_IMAGE_{{ $id | upper }}
value: {{ $object.image | quote }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,45 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Chart.Name }}-upgrade
labels:
{{- include "install.labels" . | nindent 4 }}
{{- include "install.upgradeLabels" . | nindent 4 }}
spec:
replicas: 1
strategy: { type: Recreate }
selector:
matchLabels:
{{- include "install.upgradeLabels" . | nindent 6 }}
template:
metadata:
labels:
{{- include "install.upgradeLabels" . | nindent 8 }}
spec:
{{- include "install.imagePullSecrets" . | indent 6 }}
serviceAccountName: {{ include "install.serviceAccountName" . }}-upgrade
containers:
- name: operator
image: {{ required ".Values.controllerImages.upgrade is required" .Values.controllerImages.upgrade | quote }}
env:
- name: CRUNCHY_DEBUG
value: {{ .Values.debug | ne false | quote }}
{{- if .Values.singleNamespace }}
- name: PGO_TARGET_NAMESPACE
valueFrom: { fieldRef: { apiVersion: v1, fieldPath: metadata.namespace } }
{{- end }}
{{- if .Values.workers }}
- name: PGO_WORKERS
value: {{ .Values.workers | quote }}
{{- end }}
{{- include "install.relatedImages" . | indent 8 }}
{{- if .Values.resources.upgrade }}
resources:
{{- toYaml .Values.resources.upgrade | nindent 10 }}
{{- end }}
securityContext:
allowPrivilegeEscalation: false
capabilities: { drop: [ALL] }
readOnlyRootFilesystem: true
runAsNonRoot: true

View File

@ -0,0 +1,51 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Chart.Name }}
labels:
{{- include "install.labels" . | nindent 4 }}
{{- include "install.clusterLabels" . | nindent 4 }}
spec:
replicas: 1
strategy: { type: Recreate }
selector:
matchLabels:
{{- include "install.clusterLabels" . | nindent 6 }}
template:
metadata:
labels:
{{- include "install.clusterLabels" . | nindent 8 }}
spec:
{{- include "install.imagePullSecrets" . | indent 6 }}
serviceAccountName: {{ include "install.serviceAccountName" . }}
containers:
- name: operator
image: {{ required ".Values.controllerImages.cluster is required" .Values.controllerImages.cluster | quote }}
env:
- name: CRUNCHY_DEBUG
value: {{ .Values.debug | ne false | quote }}
- name: PGO_NAMESPACE
valueFrom: { fieldRef: { apiVersion: v1, fieldPath: metadata.namespace } }
{{- if .Values.singleNamespace }}
- name: PGO_TARGET_NAMESPACE
valueFrom: { fieldRef: { apiVersion: v1, fieldPath: metadata.namespace } }
{{- end }}
{{- if .Values.workers }}
- name: PGO_WORKERS
value: {{ .Values.workers | quote }}
{{- end }}
{{- include "install.relatedImages" . | indent 8 }}
{{- if .Values.disable_check_for_upgrades }}
- name: CHECK_FOR_UPGRADES
value: "false"
{{- end }}
{{- if .Values.resources.controller }}
resources:
{{- toYaml .Values.resources.controller | nindent 10 }}
{{- end }}
securityContext:
allowPrivilegeEscalation: false
capabilities: { drop: [ALL] }
readOnlyRootFilesystem: true
runAsNonRoot: true

View File

@ -0,0 +1,71 @@
---
apiVersion: rbac.authorization.k8s.io/v1
kind: {{ include "install.roleKind" . }}
metadata:
name: {{ include "install.roleName" . }}-upgrade
labels:
{{- include "install.labels" . | nindent 4 }}
{{- include "install.upgradeLabels" . | nindent 4 }}
rules:
- apiGroups:
- ""
resources:
- endpoints
verbs:
- delete
- get
- list
- watch
- apiGroups:
- apps
resources:
- statefulsets
verbs:
- list
- watch
- apiGroups:
- batch
resources:
- jobs
verbs:
- create
- delete
- list
- patch
- watch
- apiGroups:
- postgres-operator.crunchydata.com
resources:
- pgupgrades
verbs:
- get
- list
- watch
- apiGroups:
- postgres-operator.crunchydata.com
resources:
- pgupgrades/finalizers
verbs:
- patch
- update
- apiGroups:
- postgres-operator.crunchydata.com
resources:
- pgupgrades/status
verbs:
- get
- patch
- apiGroups:
- postgres-operator.crunchydata.com
resources:
- postgresclusters
verbs:
- get
- list
- watch
- apiGroups:
- postgres-operator.crunchydata.com
resources:
- postgresclusters/status
verbs:
- patch

136
pgo/templates/role.yaml Normal file
View File

@ -0,0 +1,136 @@
---
apiVersion: rbac.authorization.k8s.io/v1
kind: {{ include "install.roleKind" . }}
metadata:
name: {{ include "install.roleName" . }}
labels:
{{- include "install.labels" . | nindent 4 }}
{{- include "install.clusterLabels" . | nindent 4 }}
rules:
- apiGroups:
- ''
resources:
- configmaps
- persistentvolumeclaims
- secrets
- services
verbs:
- create
- delete
- get
- list
- patch
- watch
- apiGroups:
- ''
resources:
- endpoints
verbs:
- create
- delete
- deletecollection
- get
- list
- patch
- watch
- apiGroups:
- ''
resources:
- endpoints/restricted
- pods/exec
verbs:
- create
- apiGroups:
- ''
resources:
- events
verbs:
- create
- patch
- apiGroups:
- ''
resources:
- pods
verbs:
- delete
- get
- list
- patch
- watch
- apiGroups:
- ''
resources:
- serviceaccounts
verbs:
- create
- get
- list
- patch
- watch
- apiGroups:
- apps
resources:
- deployments
- statefulsets
verbs:
- create
- delete
- get
- list
- patch
- watch
- apiGroups:
- batch
resources:
- cronjobs
- jobs
verbs:
- create
- delete
- get
- list
- patch
- watch
- apiGroups:
- policy
resources:
- poddisruptionbudgets
verbs:
- create
- delete
- get
- list
- patch
- watch
- apiGroups:
- postgres-operator.crunchydata.com
resources:
- postgresclusters
verbs:
- get
- list
- patch
- watch
- apiGroups:
- postgres-operator.crunchydata.com
resources:
- postgresclusters/finalizers
verbs:
- update
- apiGroups:
- postgres-operator.crunchydata.com
resources:
- postgresclusters/status
verbs:
- patch
- apiGroups:
- rbac.authorization.k8s.io
resources:
- rolebindings
- roles
verbs:
- create
- get
- list
- patch
- watch

View File

@ -0,0 +1,32 @@
---
apiVersion: rbac.authorization.k8s.io/v1
kind: {{ include "install.roleBindingKind" . }}
metadata:
name: {{ include "install.roleBindingName" . }}
labels:
{{- include "install.labels" . | nindent 4 }}
{{- include "install.clusterLabels" . | nindent 4 }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: {{ include "install.roleKind" . }}
name: {{ include "install.roleName" . }}
subjects:
- kind: ServiceAccount
name: {{ include "install.serviceAccountName" . }}
namespace: {{ .Release.Namespace }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: {{ include "install.roleBindingKind" . }}
metadata:
name: {{ include "install.roleBindingName" . }}-upgrade
labels:
{{- include "install.labels" . | nindent 4 }}
{{- include "install.upgradeLabels" . | nindent 4 }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: {{ include "install.roleKind" . }}
name: {{ include "install.roleName" . }}-upgrade
subjects:
- kind: ServiceAccount
name: {{ include "install.serviceAccountName" . }}-upgrade
namespace: {{ .Release.Namespace }}

View File

@ -0,0 +1,16 @@
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "install.serviceAccountName" . }}
labels:
{{- include "install.labels" . | nindent 4 }}
{{- include "install.clusterLabels" . | nindent 4 }}
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "install.serviceAccountName" . }}-upgrade
labels:
{{- include "install.labels" . | nindent 4 }}
{{- include "install.upgradeLabels" . | nindent 4 }}

47
pgo/values.yaml Normal file
View File

@ -0,0 +1,47 @@
# controllerImages are used to run the PostgresCluster and PGUpgrade controllers.
controllerImages:
cluster: registry.developers.crunchydata.com/crunchydata/postgres-operator:ubi8-5.3.1-0
upgrade: registry.developers.crunchydata.com/crunchydata/postgres-operator-upgrade:ubi8-5.3.1-0
# relatedImages are used when an image is omitted from PostgresCluster or PGUpgrade specs.
relatedImages:
postgres_15:
image: registry.developers.crunchydata.com/crunchydata/crunchy-postgres:ubi8-15.2-0
postgres_15_gis_3.3:
image: registry.developers.crunchydata.com/crunchydata/crunchy-postgres-gis:ubi8-15.2-3.3-0
postgres_14:
image: registry.developers.crunchydata.com/crunchydata/crunchy-postgres:ubi8-14.7-0
postgres_14_gis_3.1:
image: registry.developers.crunchydata.com/crunchydata/crunchy-postgres-gis:ubi8-14.7-3.1-0
postgres_14_gis_3.2:
image: registry.developers.crunchydata.com/crunchydata/crunchy-postgres-gis:ubi8-14.7-3.2-0
postgres_14_gis_3.3:
image: registry.developers.crunchydata.com/crunchydata/crunchy-postgres-gis:ubi8-14.7-3.3-0
postgres_13:
image: registry.developers.crunchydata.com/crunchydata/crunchy-postgres:ubi8-13.10-0
postgres_13_gis_3.0:
image: registry.developers.crunchydata.com/crunchydata/crunchy-postgres-gis:ubi8-13.10-3.0-0
postgres_13_gis_3.1:
image: registry.developers.crunchydata.com/crunchydata/crunchy-postgres-gis:ubi8-13.10-3.1-0
pgadmin:
image: registry.developers.crunchydata.com/crunchydata/crunchy-pgadmin4:ubi8-4.30-10
pgbackrest:
image: registry.developers.crunchydata.com/crunchydata/crunchy-pgbackrest:ubi8-2.41-4
pgbouncer:
image: registry.developers.crunchydata.com/crunchydata/crunchy-pgbouncer:ubi8-1.18-0
pgexporter:
image: registry.developers.crunchydata.com/crunchydata/crunchy-postgres-exporter:ubi8-5.3.1-0
pgupgrade:
image: registry.developers.crunchydata.com/crunchydata/crunchy-upgrade:ubi8-5.3.1-0
# singleNamespace controls where PGO watches for PostgresClusters. When false,
# PGO watches for and responds to PostgresClusters in all namespaces. When true,
# PGO watches only the namespace in which it is installed.
singleNamespace: false
# debug allows you to enable or disable the "debug" level of logging.
debug: true
# imagePullSecretNames is a list of secret names to use for pulling controller images.
# More info: https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod
imagePullSecretNames: []
# Resource configuration of the PostgresCluster and PGUpgrade controllers.
resources:
controller: {}
upgrade: {}

View File

@ -0,0 +1,8 @@
---
name: Open an Issue for PGO Examples
about: Open an issue specific to the "postgres-operator-examples" repository. For all other issues please visit https://github.com/CrunchyData/postgres-operator
---
Please report any bugs or feature requests specific to the PGO Examples that are in this repository. This includes anything around the examples for Kustomize and Helm.
For any bugs or feature request related to PGO itself, please visit https://github.com/CrunchyData/postgres-operator

View File

@ -0,0 +1,190 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
Copyright 2017 - 2023 Crunchy Data Solutions, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -0,0 +1,17 @@
# [PGO](https://github.com/CrunchyData/postgres-operator), Crunchy [Postgres Operator](https://github.com/CrunchyData/postgres-operator) Examples
This repository contains examples for deploying PGO, the Postgres Operator from Crunchy Data, using a variety of examples.
The examples are grouped by various tools that can be used to deploy them.
The best way to get started is to fork this repository and experiment with the examples.
Each of the examples has its own README that guides you through the process of deploying it.
You can find the full [PGO documentation](https://access.crunchydata.com/documentation/postgres-operator/v5/) for the project here:
[https://access.crunchydata.com/documentation/postgres-operator/v5/](https://access.crunchydata.com/documentation/postgres-operator/v5/)
You can find out more information about [PGO](https://github.com/CrunchyData/postgres-operator), the [Postgres Operator](https://github.com/CrunchyData/postgres-operator) from [Crunchy Data](https://www.crunchydata.com) at the project page:
[https://github.com/CrunchyData/postgres-operator](https://github.com/CrunchyData/postgres-operator)

View File

@ -0,0 +1,3 @@
# https://github.com/github/linguist/issues/4905
# https://github.com/github/linguist/issues/5092#issuecomment-730262298
/templates/*.tpl linguist-language=handlebars

View File

@ -0,0 +1 @@
.git*

View File

@ -0,0 +1,8 @@
apiVersion: v2
name: pgo
description: Installer for PGO, the open source Postgres Operator from Crunchy Data
type: application
# The version below should match the version on the PostgresCluster CRD
version: 5.3.1
appVersion: 5.3.1

View File

@ -0,0 +1,31 @@
Thank you for deploying PGO v{{ .Chart.AppVersion }}!
((((((((((((((((((((((
(((((((((((((%%%%%%%(((((((((((((((
(((((((((((%%% %%%%((((((((((((
(((((((((((%%( (((( ( %%%(((((((((((
(((((((((((((%% (( ,(( %%%(((((((((((
(((((((((((((((%% *%%/ %%%%%%%((((((((((
(((((((((((((((((((%%(( %%%%%%%%%%#(((((%%%%%%%%%%#((((((((((((
((((((((((((((((((%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%((((((((((((((
*((((((((((((((((((((%%%%%% /%%%%%%%%%%%%%%%%%%%((((((((((((((((
(((((((((((((((((((((((%%%/ .%, %%%((((((((((((((((((,
((((((((((((((((((((((% %#(((((((((((((((((
(((((((((((((((%%%%%% #%(((((((((((((((((
((((((((((((((%% %%(((((((((((((((,
((((((((((((%%%#% % %%(((((((((((((((
((((((((((((%. % % #((((((((((((((
(((((((((((%% % %%* %(((((((((((((
#(###(###(#%% %%% %% %%% #%%#(###(###(#
###########%%%%% /%%%%%%%%%%%%% %% %%%%% ,%%#######
###############%% %%%%%% %%% %%%%%%%% %%#####
################%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %%##
################%% %%%%%%%%%%%%%%%%% %%%% %
##############%# %% (%%%%%%% %%%%%%
#############% %%%%% %%%%%%%%%%%
###########% %%%%%%%%%%% %%%%%%%%%
#########%% %% %%%%%%%%%%%%%%%#
########%% %% %%%%%%%%%
######%% %% %%%%%%
####%%% %%%%% %
%% %%%%

View File

@ -0,0 +1,94 @@
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "install.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Crunchy labels
*/}}
{{- define "install.clusterLabels" -}}
postgres-operator.crunchydata.com/control-plane: {{ .Chart.Name }}
{{- end }}
{{- define "install.upgradeLabels" -}}
postgres-operator.crunchydata.com/control-plane: {{ .Chart.Name }}-upgrade
{{- end }}
{{/*
Common labels
*/}}
{{- define "install.labels" -}}
helm.sh/chart: {{ include "install.chart" . }}
app.kubernetes.io/name: {{ .Chart.Name }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Create the name of the service account to use
*/}}
{{- define "install.serviceAccountName" -}}
{{ .Chart.Name }}
{{- end }}
{{/*
Create the name of the Role/ClusterRole to use
*/}}
{{- define "install.roleName" -}}
{{ .Chart.Name }}
{{- end }}
{{/*
Create the name of the RoleBinding/ClusterRoleBinding to use
*/}}
{{- define "install.roleBindingName" -}}
{{ .Chart.Name }}
{{- end }}
{{/*
Create the kind for rolebindings. Will be RoleBinding in single
namespace mode or ClusterRoleBinding by default.
*/}}
{{- define "install.roleBindingKind" -}}
{{- if .Values.singleNamespace -}}
RoleBinding
{{- else -}}
ClusterRoleBinding
{{- end }}
{{- end }}
{{/*
Create the kind for role. Will be Role in single
namespace mode or ClusterRole by default.
*/}}
{{- define "install.roleKind" -}}
{{- if .Values.singleNamespace -}}
Role
{{- else -}}
ClusterRole
{{- end }}
{{- end }}
{{- define "install.imagePullSecrets" -}}
{{/* Earlier versions required the full structure of PodSpec.ImagePullSecrets */}}
{{- if .Values.imagePullSecrets }}
imagePullSecrets:
{{ toYaml .Values.imagePullSecrets }}
{{- else if .Values.imagePullSecretNames }}
imagePullSecrets:
{{- range .Values.imagePullSecretNames }}
- name: {{ . | quote }}
{{- end }}{{/* range */}}
{{- end }}{{/* if */}}
{{- end }}{{/* define */}}
{{- define "install.relatedImages" -}}
{{- range $id, $object := .Values.relatedImages }}
- name: RELATED_IMAGE_{{ $id | upper }}
value: {{ $object.image | quote }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,45 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Chart.Name }}-upgrade
labels:
{{- include "install.labels" . | nindent 4 }}
{{- include "install.upgradeLabels" . | nindent 4 }}
spec:
replicas: 1
strategy: { type: Recreate }
selector:
matchLabels:
{{- include "install.upgradeLabels" . | nindent 6 }}
template:
metadata:
labels:
{{- include "install.upgradeLabels" . | nindent 8 }}
spec:
{{- include "install.imagePullSecrets" . | indent 6 }}
serviceAccountName: {{ include "install.serviceAccountName" . }}-upgrade
containers:
- name: operator
image: {{ required ".Values.controllerImages.upgrade is required" .Values.controllerImages.upgrade | quote }}
env:
- name: CRUNCHY_DEBUG
value: {{ .Values.debug | ne false | quote }}
{{- if .Values.singleNamespace }}
- name: PGO_TARGET_NAMESPACE
valueFrom: { fieldRef: { apiVersion: v1, fieldPath: metadata.namespace } }
{{- end }}
{{- if .Values.workers }}
- name: PGO_WORKERS
value: {{ .Values.workers | quote }}
{{- end }}
{{- include "install.relatedImages" . | indent 8 }}
{{- if .Values.resources.upgrade }}
resources:
{{- toYaml .Values.resources.upgrade | nindent 10 }}
{{- end }}
securityContext:
allowPrivilegeEscalation: false
capabilities: { drop: [ALL] }
readOnlyRootFilesystem: true
runAsNonRoot: true

View File

@ -0,0 +1,51 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Chart.Name }}
labels:
{{- include "install.labels" . | nindent 4 }}
{{- include "install.clusterLabels" . | nindent 4 }}
spec:
replicas: 1
strategy: { type: Recreate }
selector:
matchLabels:
{{- include "install.clusterLabels" . | nindent 6 }}
template:
metadata:
labels:
{{- include "install.clusterLabels" . | nindent 8 }}
spec:
{{- include "install.imagePullSecrets" . | indent 6 }}
serviceAccountName: {{ include "install.serviceAccountName" . }}
containers:
- name: operator
image: {{ required ".Values.controllerImages.cluster is required" .Values.controllerImages.cluster | quote }}
env:
- name: CRUNCHY_DEBUG
value: {{ .Values.debug | ne false | quote }}
- name: PGO_NAMESPACE
valueFrom: { fieldRef: { apiVersion: v1, fieldPath: metadata.namespace } }
{{- if .Values.singleNamespace }}
- name: PGO_TARGET_NAMESPACE
valueFrom: { fieldRef: { apiVersion: v1, fieldPath: metadata.namespace } }
{{- end }}
{{- if .Values.workers }}
- name: PGO_WORKERS
value: {{ .Values.workers | quote }}
{{- end }}
{{- include "install.relatedImages" . | indent 8 }}
{{- if .Values.disable_check_for_upgrades }}
- name: CHECK_FOR_UPGRADES
value: "false"
{{- end }}
{{- if .Values.resources.controller }}
resources:
{{- toYaml .Values.resources.controller | nindent 10 }}
{{- end }}
securityContext:
allowPrivilegeEscalation: false
capabilities: { drop: [ALL] }
readOnlyRootFilesystem: true
runAsNonRoot: true

View File

@ -0,0 +1,71 @@
---
apiVersion: rbac.authorization.k8s.io/v1
kind: {{ include "install.roleKind" . }}
metadata:
name: {{ include "install.roleName" . }}-upgrade
labels:
{{- include "install.labels" . | nindent 4 }}
{{- include "install.upgradeLabels" . | nindent 4 }}
rules:
- apiGroups:
- ""
resources:
- endpoints
verbs:
- delete
- get
- list
- watch
- apiGroups:
- apps
resources:
- statefulsets
verbs:
- list
- watch
- apiGroups:
- batch
resources:
- jobs
verbs:
- create
- delete
- list
- patch
- watch
- apiGroups:
- postgres-operator.crunchydata.com
resources:
- pgupgrades
verbs:
- get
- list
- watch
- apiGroups:
- postgres-operator.crunchydata.com
resources:
- pgupgrades/finalizers
verbs:
- patch
- update
- apiGroups:
- postgres-operator.crunchydata.com
resources:
- pgupgrades/status
verbs:
- get
- patch
- apiGroups:
- postgres-operator.crunchydata.com
resources:
- postgresclusters
verbs:
- get
- list
- watch
- apiGroups:
- postgres-operator.crunchydata.com
resources:
- postgresclusters/status
verbs:
- patch

View File

@ -0,0 +1,136 @@
---
apiVersion: rbac.authorization.k8s.io/v1
kind: {{ include "install.roleKind" . }}
metadata:
name: {{ include "install.roleName" . }}
labels:
{{- include "install.labels" . | nindent 4 }}
{{- include "install.clusterLabels" . | nindent 4 }}
rules:
- apiGroups:
- ''
resources:
- configmaps
- persistentvolumeclaims
- secrets
- services
verbs:
- create
- delete
- get
- list
- patch
- watch
- apiGroups:
- ''
resources:
- endpoints
verbs:
- create
- delete
- deletecollection
- get
- list
- patch
- watch
- apiGroups:
- ''
resources:
- endpoints/restricted
- pods/exec
verbs:
- create
- apiGroups:
- ''
resources:
- events
verbs:
- create
- patch
- apiGroups:
- ''
resources:
- pods
verbs:
- delete
- get
- list
- patch
- watch
- apiGroups:
- ''
resources:
- serviceaccounts
verbs:
- create
- get
- list
- patch
- watch
- apiGroups:
- apps
resources:
- deployments
- statefulsets
verbs:
- create
- delete
- get
- list
- patch
- watch
- apiGroups:
- batch
resources:
- cronjobs
- jobs
verbs:
- create
- delete
- get
- list
- patch
- watch
- apiGroups:
- policy
resources:
- poddisruptionbudgets
verbs:
- create
- delete
- get
- list
- patch
- watch
- apiGroups:
- postgres-operator.crunchydata.com
resources:
- postgresclusters
verbs:
- get
- list
- patch
- watch
- apiGroups:
- postgres-operator.crunchydata.com
resources:
- postgresclusters/finalizers
verbs:
- update
- apiGroups:
- postgres-operator.crunchydata.com
resources:
- postgresclusters/status
verbs:
- patch
- apiGroups:
- rbac.authorization.k8s.io
resources:
- rolebindings
- roles
verbs:
- create
- get
- list
- patch
- watch

View File

@ -0,0 +1,32 @@
---
apiVersion: rbac.authorization.k8s.io/v1
kind: {{ include "install.roleBindingKind" . }}
metadata:
name: {{ include "install.roleBindingName" . }}
labels:
{{- include "install.labels" . | nindent 4 }}
{{- include "install.clusterLabels" . | nindent 4 }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: {{ include "install.roleKind" . }}
name: {{ include "install.roleName" . }}
subjects:
- kind: ServiceAccount
name: {{ include "install.serviceAccountName" . }}
namespace: {{ .Release.Namespace }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: {{ include "install.roleBindingKind" . }}
metadata:
name: {{ include "install.roleBindingName" . }}-upgrade
labels:
{{- include "install.labels" . | nindent 4 }}
{{- include "install.upgradeLabels" . | nindent 4 }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: {{ include "install.roleKind" . }}
name: {{ include "install.roleName" . }}-upgrade
subjects:
- kind: ServiceAccount
name: {{ include "install.serviceAccountName" . }}-upgrade
namespace: {{ .Release.Namespace }}

View File

@ -0,0 +1,16 @@
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "install.serviceAccountName" . }}
labels:
{{- include "install.labels" . | nindent 4 }}
{{- include "install.clusterLabels" . | nindent 4 }}
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "install.serviceAccountName" . }}-upgrade
labels:
{{- include "install.labels" . | nindent 4 }}
{{- include "install.upgradeLabels" . | nindent 4 }}

View File

@ -0,0 +1,47 @@
---
# controllerImages are used to run the PostgresCluster and PGUpgrade controllers.
controllerImages:
cluster: registry.developers.crunchydata.com/crunchydata/postgres-operator:ubi8-5.3.1-0
upgrade: registry.developers.crunchydata.com/crunchydata/postgres-operator-upgrade:ubi8-5.3.1-0
# relatedImages are used when an image is omitted from PostgresCluster or PGUpgrade specs.
relatedImages:
postgres_15:
image: registry.developers.crunchydata.com/crunchydata/crunchy-postgres:ubi8-15.2-0
postgres_15_gis_3.3:
image: registry.developers.crunchydata.com/crunchydata/crunchy-postgres-gis:ubi8-15.2-3.3-0
postgres_14:
image: registry.developers.crunchydata.com/crunchydata/crunchy-postgres:ubi8-14.7-0
postgres_14_gis_3.1:
image: registry.developers.crunchydata.com/crunchydata/crunchy-postgres-gis:ubi8-14.7-3.1-0
postgres_14_gis_3.2:
image: registry.developers.crunchydata.com/crunchydata/crunchy-postgres-gis:ubi8-14.7-3.2-0
postgres_14_gis_3.3:
image: registry.developers.crunchydata.com/crunchydata/crunchy-postgres-gis:ubi8-14.7-3.3-0
pgadmin:
image: registry.developers.crunchydata.com/crunchydata/crunchy-pgadmin4:ubi8-4.30-10
pgbackrest:
image: registry.developers.crunchydata.com/crunchydata/crunchy-pgbackrest:ubi8-2.41-4
pgbouncer:
image: registry.developers.crunchydata.com/crunchydata/crunchy-pgbouncer:ubi8-1.18-0
pgexporter:
image: registry.developers.crunchydata.com/crunchydata/crunchy-postgres-exporter:ubi8-5.3.1-0
pgupgrade:
image: registry.developers.crunchydata.com/crunchydata/crunchy-upgrade:ubi8-5.3.1-0
# singleNamespace controls where PGO watches for PostgresClusters. When false,
# PGO watches for and responds to PostgresClusters in all namespaces. When true,
# PGO watches only the namespace in which it is installed.
singleNamespace: false
# debug allows you to enable or disable the "debug" level of logging.
debug: true
# imagePullSecretNames is a list of secret names to use for pulling controller images.
# More info: https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod
imagePullSecretNames: []
# Resource configuration of the PostgresCluster and PGUpgrade controllers.
resources:
controller: {}
upgrade: {}

View File

@ -0,0 +1,7 @@
apiVersion: v2
name: postgrescluster
description: A Helm chart for Kubernetes
type: application
# The version below should match the version on the PostgresCluster CRD
version: 5.3.1
appVersion: 5.3.1

View File

@ -0,0 +1,31 @@
Thank you for deploying a Crunchy PostgreSQL cluster!
((((((((((((((((((((((
(((((((((((((%%%%%%%(((((((((((((((
(((((((((((%%% %%%%((((((((((((
(((((((((((%%( (((( ( %%%(((((((((((
(((((((((((((%% (( ,(( %%%(((((((((((
(((((((((((((((%% *%%/ %%%%%%%((((((((((
(((((((((((((((((((%%(( %%%%%%%%%%#(((((%%%%%%%%%%#((((((((((((
((((((((((((((((((%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%((((((((((((((
*((((((((((((((((((((%%%%%% /%%%%%%%%%%%%%%%%%%%((((((((((((((((
(((((((((((((((((((((((%%%/ .%, %%%((((((((((((((((((,
((((((((((((((((((((((% %#(((((((((((((((((
(((((((((((((((%%%%%% #%(((((((((((((((((
((((((((((((((%% %%(((((((((((((((,
((((((((((((%%%#% % %%(((((((((((((((
((((((((((((%. % % #((((((((((((((
(((((((((((%% % %%* %(((((((((((((
#(###(###(#%% %%% %% %%% #%%#(###(###(#
###########%%%%% /%%%%%%%%%%%%% %% %%%%% ,%%#######
###############%% %%%%%% %%% %%%%%%%% %%#####
################%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %%##
################%% %%%%%%%%%%%%%%%%% %%%% %
##############%# %% (%%%%%%% %%%%%%
#############% %%%%% %%%%%%%%%%%
###########% %%%%%%%%%%% %%%%%%%%%
#########%% %% %%%%%%%%%%%%%%%#
########%% %% %%%%%%%%%
######%% %% %%%%%%
####%%% %%%%% %
%% %%%%

View File

@ -0,0 +1,12 @@
{{/* Allow for Azure secret information to be stored in a Secret */}}
{{- define "postgres.azure" }}
[global]
{{- if .azure }}
{{- if .azure.account }}
repo{{ add .index 1 }}-azure-account={{ .azure.account }}
{{- end }}
{{- if .azure.key }}
repo{{ add .index 1 }}-azure-key={{ .azure.key }}
{{- end }}
{{- end }}
{{ end }}

View File

@ -0,0 +1,7 @@
{{/* Allow for GCS secret information to be stored in a Secret */}}
{{- define "postgres.gcs" }}
[global]
{{- if .gcs }}
repo{{ add .index 1 }}-gcs-key=/etc/pgbackrest/conf.d/gcs-key.json
{{- end }}
{{ end }}

View File

@ -0,0 +1,18 @@
{{/* Allow for S3 secret information to be stored in a Secret */}}
{{- define "postgres.s3" }}
[global]
{{- if .s3 }}
{{- if .s3.key }}
repo{{ add .index 1 }}-s3-key={{ .s3.key }}
{{- end }}
{{- if .s3.keySecret }}
repo{{ add .index 1 }}-s3-key-secret={{ .s3.keySecret }}
{{- end }}
{{- if .s3.keyType }}
repo{{ add .index 1 }}-s3-key-type={{ .s3.keyType }}
{{- end }}
{{- if .s3.encryptionPassphrase }}
repo{{ add .index 1 }}-cipher-pass={{ .s3.encryptionPassphrase }}
{{- end }}
{{- end }}
{{ end }}

View File

@ -0,0 +1,41 @@
{{- if or .Values.multiBackupRepos .Values.s3 .Values.gcs .Values.azure }}
apiVersion: v1
kind: Secret
metadata:
name: {{ default .Release.Name .Values.name }}-pgbackrest-secret
type: Opaque
data:
{{- if .Values.multiBackupRepos }}
{{- range $index, $repo := .Values.multiBackupRepos }}
{{- if $repo.s3 }}
{{- $args := dict "s3" $repo.s3 "index" $index }}
s3.conf: |-
{{ include "postgres.s3" $args | b64enc }}
{{- else if $repo.gcs }}
{{- $args := dict "gcs" $repo.gcs "index" $index }}
gcs.conf: |-
{{ include "postgres.gcs" $args | b64enc }}
gcs-key.json: |-
{{ $repo.gcs.key | b64enc }}
{{- else if $repo.azure }}
{{- $args := dict "azure" $repo.azure "index" $index }}
azure.conf: |-
{{ include "postgres.azure" $args | b64enc }}
{{- end }}
{{- end }}
{{- else if .Values.s3 }}
{{- $args := dict "s3" .Values.s3 "index" 0 }}
s3.conf: |-
{{ include "postgres.s3" $args | b64enc }}
{{- else if .Values.gcs }}
{{- $args := dict "gcs" .Values.gcs "index" 0 }}
gcs.conf: |-
{{ include "postgres.gcs" $args | b64enc }}
gcs-key.json: |-
{{ .Values.gcs.key | b64enc }}
{{- else if .Values.azure }}
{{- $args := dict "azure" .Values.azure "index" 0 }}
azure.conf: |-
{{ include "postgres.azure" $args | b64enc }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,214 @@
apiVersion: postgres-operator.crunchydata.com/v1beta1
kind: PostgresCluster
metadata:
name: {{ default .Release.Name .Values.name }}
spec:
postgresVersion: {{ required "You must set the version of Postgres to deploy." .Values.postgresVersion }}
{{- if .Values.postGISVersion }}
postGISVersion: {{ quote .Values.postGISVersion }}
{{- end }}
{{- if .Values.imagePostgres }}
image: {{ .Values.imagePostgres | quote }}
{{- end }}
{{- if .Values.port }}
port: {{ .Values.port }}
{{- end }}
{{- if .Values.instances }}
instances:
{{ toYaml .Values.instances | indent 4 }}
{{- else }}
instances:
- name: {{ default "instance1" .Values.instanceName | quote }}
replicas: {{ default 1 .Values.instanceReplicas }}
dataVolumeClaimSpec:
{{- if .Values.instanceStorageClassName }}
storageClassName: {{ .Values.instanceStorageClassName | quote }}
{{- end }}
accessModes:
- "ReadWriteOnce"
resources:
requests:
storage: {{ default "1Gi" .Values.instanceSize | quote }}
{{- if or .Values.instanceMemory .Values.instanceCPU }}
resources:
limits:
cpu: {{ default "" .Values.instanceCPU | quote }}
memory: {{ default "" .Values.instanceMemory | quote }}
{{- end }}
{{- end }}
backups:
pgbackrest:
{{- if .Values.imagePgBackRest }}
image: {{ .Values.imagePgBackRest | quote }}
{{- end }}
{{- if .Values.pgBackRestConfig }}
{{ toYaml .Values.pgBackRestConfig | indent 6 }}
{{- else if .Values.multiBackupRepos }}
configuration:
- secret:
name: {{ default .Release.Name .Values.name }}-pgbackrest-secret
global:
{{- range $index, $repo := .Values.multiBackupRepos }}
{{- if or $repo.s3 $repo.gcs $repo.azure }}
repo{{ add $index 1 }}-path: /pgbackrest/{{ $.Release.Namespace }}/{{ default $.Release.Name $.Values.name }}/repo{{ add $index 1 }}
{{- end }}
{{- end }}
repos:
{{- range $index, $repo := .Values.multiBackupRepos }}
- name: repo{{ add $index 1 }}
{{- if $repo.volume }}
volume:
volumeClaimSpec:
{{- if $repo.volume.backupsStorageClassName }}
storageClassName: {{ .Values.backupsStorageClassName | quote }}
{{- end }}
accessModes:
- "ReadWriteOnce"
resources:
requests:
storage: {{ default "1Gi" $repo.volume.backupsSize | quote }}
{{- else if $repo.s3 }}
s3:
bucket: {{ $repo.s3.bucket | quote }}
endpoint: {{ $repo.s3.endpoint | quote }}
region: {{ $repo.s3.region | quote }}
{{- else if $repo.gcs }}
gcs:
bucket: {{ $repo.gcs.bucket | quote }}
{{- else if $repo.azure }}
azure:
container: {{ $repo.azure.container | quote }}
{{- end }}
{{- end }}
{{- else if .Values.s3 }}
configuration:
- secret:
name: {{ default .Release.Name .Values.name }}-pgbackrest-secret
global:
repo1-path: /pgbackrest/{{ .Release.Namespace }}/{{ default .Release.Name .Values.name }}/repo1
{{- if .Values.s3.encryptionPassphrase }}
repo1-cipher-type: aes-256-cbc
{{- end }}
repos:
- name: repo1
s3:
bucket: {{ .Values.s3.bucket | quote }}
endpoint: {{ .Values.s3.endpoint | quote }}
region: {{ .Values.s3.region | quote }}
{{- else if .Values.gcs }}
configuration:
- secret:
name: {{ default .Release.Name .Values.name }}-pgbackrest-secret
global:
repo1-path: /pgbackrest/{{ .Release.Namespace }}/{{ default .Release.Name .Values.name }}/repo1
repos:
- name: repo1
gcs:
bucket: {{ .Values.gcs.bucket | quote }}
{{- else if .Values.azure }}
configuration:
- secret:
name: {{ default .Release.Name .Values.name }}-pgbackrest-secret
global:
repo1-path: /pgbackrest/{{ .Release.Namespace }}/{{ default .Release.Name .Values.name }}/repo1
repos:
- name: repo1
azure:
container: {{ .Values.azure.container | quote }}
{{- else }}
repos:
- name: repo1
volume:
volumeClaimSpec:
{{- if .Values.backupsStorageClassName }}
storageClassName: {{ .Values.backupsStorageClassName | quote }}
{{- end }}
accessModes:
- "ReadWriteOnce"
resources:
requests:
storage: {{ default "1Gi" .Values.backupsSize | quote }}
{{- end }}
{{- if or .Values.pgBouncerReplicas .Values.pgBouncerConfig }}
proxy:
pgBouncer:
{{- if .Values.imagePgBouncer }}
image: {{ .Values.imagePgBouncer | quote }}
{{- end }}
{{- if .Values.pgBouncerConfig }}
{{ toYaml .Values.pgBouncerConfig | indent 6 }}
{{- else }}
replicas: {{ .Values.pgBouncerReplicas }}
{{- end }}
{{- end }}
{{- if .Values.patroni }}
patroni:
{{ toYaml .Values.patroni | indent 4 }}
{{- end }}
{{- if .Values.users }}
users:
{{ toYaml .Values.users | indent 4 }}
{{- end }}
{{- if .Values.service }}
service:
{{ toYaml .Values.service | indent 4 }}
{{- end }}
{{- if .Values.dataSource }}
dataSource:
{{ toYaml .Values.dataSource | indent 4 }}
{{- end }}
{{- if .Values.databaseInitSQL }}
databaseInitSQL:
name: {{ required "A ConfigMap name is required for running bootstrap SQL." .Values.databaseInitSQL.name | quote }}
key: {{ required "A key in a ConfigMap containing any bootstrap SQL is required." .Values.databaseInitSQL.key | quote }}
{{- end }}
{{- if .Values.imagePullPolicy }}
imagePullPolicy: {{ .Values.imagePullPolicy | quote }}
{{- end }}
{{- if .Values.imagePullSecrets }}
imagePullSecrets:
{{ toYaml .Values.imagePullSecrets | indent 4 }}
{{- end }}
{{- if .Values.disableDefaultPodScheduling }}
disableDefaultPodScheduling: true
{{- end }}
{{- if .Values.metadata }}
metadata:
{{ toYaml .Values.metadata | indent 4 }}
{{- end }}
{{- if .Values.monitoring }}
monitoring:
pgmonitor:
exporter:
image: {{ default "" .Values.imageExporter | quote }}
{{- if .Values.monitoringConfig }}
{{ toYaml .Values.monitoringConfig | indent 8 }}
{{- end }}
{{- end }}
{{- if .Values.shutdown }}
shutdown: true
{{- end }}
{{- if .Values.standby }}
standby:
enabled: {{ .Values.standby.enabled }}
repoName: {{ .Values.standby.repoName }}
host: {{ .Values.standby.host }}
port: {{ .Values.standby.port }}
{{- end }}
{{- if .Values.supplementalGroups }}
supplementalGroups:
{{ toYaml .Values.supplementalGroups | indent 4 }}
{{- end }}
{{- if .Values.openshift }}
openshift: true
{{- else if eq .Values.openshift false }}
openshift: false
{{- end }}
{{- if .Values.customTLSSecret }}
customTLSSecret:
{{ toYaml .Values.customTLSSecret | indent 4 }}
{{- end }}
{{- if .Values.customReplicationTLSSecret }}
customReplicationTLSSecret:
{{ toYaml .Values.customReplicationTLSSecret | indent 4 }}
{{- end }}

View File

@ -0,0 +1,312 @@
# For a full explanation of how to set up the custom resource, please refer to
# the documentation:
# https://access.crunchydata.com/documentation/postgres-operator/v5/
###########
# General #
###########
# name is the name of the cluster. This defaults to the name of the Helm
# release.
name: clank
# postgresVersion sets the version to deploy. This version number needs to be
# available as one of the "RELATED_IMAGE_POSTGRES_..." images as part of the PGO
# installation if you want to deploy the image without setting the "postgres"
# image variable. This value is required.
postgresVersion: 15
# postGISVersion if sets and coupled with a PostGIS enabled container, enables
# PostGIS. This version number needs to be available as one of the
# "RELATED_IMAGE_POSTGRES_..." images as part of the PGO installation if you
# want to deploy the image without setting the "postgres" image variable.
# postGISVersion: 3.1
# NOTE: pgBackRest is enabled by default. It must be set in
# "RELATED_IMAGE_PGBACKREST" on the PGO deployment, otherwise you will need to
# override the "pgBackRest" image.
# pgBouncerReplicas sets the number of pgBouncer instances to deploy. The
# default is 0. You need to set this to at least 1 to deploy pgBouncer or set
# "pgBouncerConfig". Setting "pgBouncerConfig" will override the value of
# pgBouncerReplicas. The "RELATED_IMAGE_PGBOUNCER" in the PGO deployment must be
# set if you want to enable this without explicitly setting "pgBouncer".
# pgBouncerReplicas: 1
# monitoring enables the ability to monitor the Postgres cluster through a
# metrics exporter than can be scraped by Prometheus. This defaults to the value
# below.
monitoring: true
###################
# Image Overrides #
###################
# imagePostgres can be a Postgres or GIS-enabled Postgres image. This defaults to the
# below value. "postgresVersion" needs to match the version of Postgres that is
# used here. If using the GIS-enabled Postgres image, you need to ensure
# "postGISVersion" matches the version of PostGIS used.
# imagePostgres: registry.developers.crunchydata.com/crunchydata/crunchy-postgres:ubi8-14.7-0
# imagePgBackRest is the pgBackRest backup utility image. This defaults to the
# below value.
# imagePgBackRest: registry.developers.crunchydata.com/crunchydata/crunchy-pgbackrest:ubi8-2.41-4
# imagePgBouncer is the image for the PgBouncer connection pooler. This defaults
# to the below value.
# imagePgBouncer: registry.developers.crunchydata.com/crunchydata/crunchy-pgbouncer:ubi8-1.18-0
# imageExporter is the image name for the exporter used as a part of monitoring.
# This defaults to the value below.
# imageExporter: registry.developers.crunchydata.com/crunchydata/crunchy-postgres-exporter:ubi8-5.3.1-0
###########################
# Basic Postgres Settings #
###########################
# instanceName lets you set the name of your instances. This defaults to
# the value below. Setting "instances" overrides this value.
# instanceName: instance1
# instanceSize sets the size of the volume that contains the data. This defaults
# to the value below. Settings "instances" overrides this value.
# instanceSize: 1Gi
# instanceStorageClassName sets the storage class for the volume that contains the data.
# This defaults to the "default" storage class defined in the cluster.
# See: 'kubectl get storageclasses.storage.k8s.io | grep default'
# Settings "instances" overrides this value.
# instanceStorageClassName: "hostpath"
# instanceMemory sets the memory limit for the Postgres instances. This defaults
# to no limit being set, but an example value is set below. Settings "instances"
# overrides this value.
# instanceMemory: 2Gi
# instanceCPU sets the CPU limit for the Postgres instances. This defaults to
# no limit being set, but an example value is set below. Setting "instances"
# overrides this value.
# instanceCPU: 1000m
# instanceReplicas lets you set the total number of Postgres replicas. This
# defaults to the value below. More than on replica enables high availability
# (HA). Settings "instances" overrides this value.
# instanceReplicas: 1
##############################
# Advanced Postgres Settings #
##############################
# instances allows you to define one or more Postgres instance sets. By default,
# PGO will only deploy a single instance. Each instance set has similar
# characteristics to the other instances in the set, e.g. storage size, resource
# etc. You can have multiple replicas within an instance set.
#
# This allows you to fully customize the topology of your Postgres instances.
#
# For example, to set up an instance set with HA (due to the default pod
# topology spread constraints)
#
# instances:
# - name: pgha1
# replicas: 2
# dataVolumeClaimSpec:
# accessModes:
# - "ReadWriteOnce"
# resources:
# requests:
# storage: 1Gi
# instances: {}
# port sets the port that Postgres listens on. Defaults to 5432.
# port: 5432
# patroni lets you set the Patroni configuration for the Postgres cluster.
# for example, to set up synchronous replication:
# patroni:
# dynamicConfiguration:
# synchronous_mode: true
# postgresql:
# parameters:
# synchronous_commit: "on"
# patroni: {}
# users sets any custom Postgres users and databases that they have access to
# as well as any permissions assoicated with the user account.
# users: {}
# dataSource specifies a data source for bootstrapping a Postgres cluster.
# dataSource: {}
# customTLSSecret references a Secret that contains the relevant information for
# bringing external TLS artifacts to a PostgreSQL cluster. This provides the
# TLS for the cluster itself.
# customTLSSecret: {}
# customReplicationTLSSecret references a Secret that contains the relevant
# information for bringing external TLS artifacts to a PostgreSQL cluster. This
# provides the information for the replication user.
# customReplicationTLSSecret: {}
# databaseInitSQL referencs a ConfigMap that contains a SQL file that should be
# run a cluster bootstrap.
# databaseInitSQL:
# name: bootstrap-sql
# key: bootstrap.sql
# standby sets whether or not to run this as a standby cluster. Setting "enabled" to
# "true" eunables the standby cluster while "repoName" points to a pgBackRest
# archive to replay WAL files from, and "host" and "port" point to a primary
# cluster from which to stream data.
# standby:
# enabled: false
# repoName: repo1
# host: "192.0.2.2"
# port: 5432
# shutdown when set scales the entire workload to zero. By default this is not
# set.
# shutdown: true
#################################
# Backups / pgBackRest Settings #
#################################
# backupsSize sets the storage size of the backups to a volume in Kubernetes.
# can be overridden by "pgBackRestConfig", if set. Defaults to the value below.
# backupsSize: 1Gi
# backupsStorageClassName sets the storage class to a class existing in Kubernetes.
# Defaults to the "default" storage class defined in the cluster.
# Can be overridden by "pgBackRestConfig", if set.
# backupsStorageClassName: "hostpath"
# s3 allows for AWS S3 or an S3 compatible storage system to be used for
# backups. This allows for a quick setup with S3; if you need more advanced
# setup, use pgBackRestConfig.
# s3:
# # bucket specifies the S3 bucket to use,
# bucket: ""
# # endpoint specifies the S3 endpoint to use.
# endpoint: ""
# # region specifies the S3 region to use. If your S3 storage system does not
# # use "region", fill this in with a random vaule.
# region: ""
# # key is the S3 key. This is stored in a Secret.
# key: ""
# # keySecret is the S3 key secret. This is stored in a Secret.
# keySecret: ""
# # keyType can be configured to enable IAM integration via AssumeRole
# keyType: ""
# # encryptionPassphrase is an optional parameter to enable encrypted backups
# # with pgBackRest. This is encrypted by pgBackRest and does not use S3's
# # built-in encrpytion system.
# encryptionPassphrase: ""
# gcs allows for Google Cloud Storage (GCS) to be used for backups. This allows
# for a quick setup with GCS; if you need a more advanced setup, use
# "pgBackRestConfig".
# gcs:
# # bucket is the name of the GCS bucket that the backups will be stored in.
# bucket: ""
# # key is a multi-line string that contains the GCS key, which is a JSON
# # structure.
# key: |
# {}
# azure allows for Azure Blob Storage to be used for backups. This allows
# for a quick setup with Azure Blob Storage; if you need a more advanced setup,
# use "pgBackRestConfig".
# azure:
# # account is the name of the Azure account to be used.
# account: ""
# # key is the Secret key used associated with the Azure acount.
# key: ""
# # container is the Azure container that the backups will be stored in.
# container: ""
# multiBackupRepos allows for backing up to multiple repositories. This is
# effectively uses the "quickstarts" for each of the backup types (volume, s3,
# gcs, azure). You can have any permutation of these types. You can set up to 4.
# can be overwritten by "pgBackRestConfig".
#
# You can't set "multiBackupRepos" and any of the individual quickstarts at the
# same time. "multiBackupRepos" will take precedence.
#
# Below is an example that enables one of each backup type. Note all of the
# available quickstart options are presented below; please see the backup types
# if you want to see how each option works.
# multiBackupRepos:
# - volume:
# backupsSize: 1Gi
# - s3:
# bucket: ""
# endpoint: ""
# region: ""
# key: ""
# keySecret: ""
# keyType: ""
# - gcs:
# bucket: ""
# key: |
# {}
# - azure:
# account: ""
# key: ""
# container: ""
# pgBackRestConfig allows for the configuration of every pgBackRest option
# except for "image", which is set by "pgBackRest".
# pgBackRestConfig: {}
################################
# Pooling / pgBouncer Settings #
################################
# pgBouncerConfig sets all of the pgBouncer portion of the spec except for
# image. To set image, you need to set the "pgBouncer" setting.
# pgBouncerConfig: {}
#######################
# Monitoring Settings #
#######################
# monitoringConfig sets all of the monitoring portion of the spec except for the
# image. To set the image, which also enables monitoring, you need to set the
# "monitoring" setting.
# monitoringConfig: {}
#######################
# Kubernetes Settings #
#######################
# metadata contains any metadata that should be applied to all PGO managed
# objects in this Postgres cluster. This includes "annotations" and "labels" as
# subkeys.
# metadata: {}
# service customizes the Service that exposes the Postgres primary.
# service: {}
# imagePullPolicy sets the pull policy for all the images. This defaults to
# the Kubernetes heuristic:
# https://kubernetes.io/docs/concepts/containers/images/#imagepullpolicy-defaulting
# imagePullPolicy: IfNotPresent
# imagePullSecrets references Secrets that credentials for pulling image from
# private repositories
# imagePullSecrets: []
# supplementalGroups sets any group IDs that should be assigned to
# Pods, particularly around file system contraints within a system
# supplementalGroups: []
# disableDefaultPodScheduling if set to true, will disable any of the default
# scheduling constraints for Pods, such as the default Pod Topology Spread
# Constraints. If set to false or unset, the default scheduling constraints will
# be used in addition to any customizations that are added in.
# disableDefaultPodScheduling: false
# openshift can set explicitly if this is an OpenShift cluster, or a cluster
# that uses a SecurityContextConstraint. This usually does not need to be set,
# but you may want to explicitly set it to "false" when using a SCC like
# "anyuid"
# openshift: false

View File

@ -0,0 +1 @@
azure.conf

View File

@ -0,0 +1,3 @@
[global]
repo1-azure-account=<YOUR_AZURE_ACCOUNT>
repo1-azure-key=<YOUR_AZURE_KEY>

View File

@ -0,0 +1,12 @@
namespace: postgres-operator
secretGenerator:
- name: pgo-azure-creds
files:
- azure.conf
generatorOptions:
disableNameSuffixHash: true
resources:
- postgres.yaml

View File

@ -0,0 +1,26 @@
apiVersion: postgres-operator.crunchydata.com/v1beta1
kind: PostgresCluster
metadata:
name: hippo-azure
spec:
image: registry.developers.crunchydata.com/crunchydata/crunchy-postgres:ubi8-14.7-0
postgresVersion: 14
instances:
- dataVolumeClaimSpec:
accessModes:
- "ReadWriteOnce"
resources:
requests:
storage: 1Gi
backups:
pgbackrest:
image: registry.developers.crunchydata.com/crunchydata/crunchy-pgbackrest:ubi8-2.41-4
configuration:
- secret:
name: pgo-azure-creds
global:
repo1-path: /pgbackrest/postgres-operator/hippo-azure/repo1
repos:
- name: repo1
azure:
container: "<YOUR_AZURE_CONTAINER>"

View File

@ -0,0 +1,49 @@
# Using Cert-Manager with Postgres Operator 5.x
## Introduction
Starting with version 5.0 of PGO, the Postgres Operator from Crunchy Data, TLS is on by default to secure all communication to/from the postgres cluster. By default, the Operator will generate the necessary certificates for the Postgres cluster and components. It is possible to provide custom certificates by storing the certificates in a Kubernetes Secret and pointing the Operator to those secrets in the Postgres manifest.
Cert-Manager can be used to dynamically generate and manage certificates in Kubernetes. Cert-Manager can generate self-signed certificates or certificates from several certificate authorities.
This example shows how to use custom self-signed certificates generated by Cert-Manager.
## Cert-Manager Installation
The first step is to deploy Cert-Manager to the Kubernetes cluster. To do this, follow the instructions on the Cert-Manager website (https://cert-manager.io/docs/installation/).
## Setup Certificate Issuer
After Cert-Manager has been deployed, the next step used in this example is to setup a Certificate Issuer. The Certificate Issuer can be configured to be local to a namespace or cluster wide. In the examples provided here, a cluster wide issuer is created.
### Configure Issuer
```
kubectl apply -k certman
```
This Kustomize deployment performs the following actions:
* Creates a cluster wide (ClusterIssuer) self-signed certificate issuer.
* Generates a common CA certificate.
* Creates a cluster wide (ClusterIssuer) CA certificate issuer using the generated CA certificate.
By default the issues are created in the cert-manager namespace which is the default namespace for Cert-Manager.
The CA certificate issuer is important as the Postgres components require that the ca.crt be the same for the certificates generated to support Postgres.
## Deploy Postgres with Custom Certificates
With the cluster wide certificate issuer in place, the next step is to generate certificates and then instruct the Operator to use these certicates.
Two certificates will be generated by the Kustomize deployment. The first certificate secret is named <cluster>-tls (hippo-tls in this example) and the second certificate <cluster>-repl-tls (hippo-repl-tls). The critical different between the two certificates is the Common Name (CN). For the replication certificate (<cluster>-repl-tls), the Common Name must be _crunchyrepl. If the Common Name is not set properly then the replicas will fail doing bootstrap process.
In the Postgres manifest, two entries are added to point to the newly created Secrets. The customTLSSecret key references the <cluster>-tls secret while the customReplicationTLSSecret references the <cluster>-repl-tls secret.
### Deploy Postgres
```shell
kubectl apply -k postgres
```
The following process takes place during the deployment:
* Custom certificate is generated for Postgres using the CA ClusterIssuer created in the previous steps.
* Custom certificate is generated for Postgres replication using the CA ClusterIssuer.
* Postgres cluster deployed using the custom certificates.

View File

@ -0,0 +1,17 @@
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: selfsigned-ca
namespace: cert-manager
spec:
isCA: true
commonName: postgres-operator
secretName: root-secret
privateKey:
algorithm: ECDSA
size: 256
issuerRef:
name: selfsigned-cluster-issuer
kind: ClusterIssuer
group: cert-manager.io

View File

@ -0,0 +1,9 @@
---
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: ca-issuer
namespace: cert-manager
spec:
ca:
secretName: root-secret

View File

@ -0,0 +1,4 @@
resources:
- selfsigned-clusterissuer.yaml
- ca-cert.yaml
- ca-issuer.yaml

View File

@ -0,0 +1,8 @@
---
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: selfsigned-cluster-issuer
namespace: cert-manager
spec:
selfSigned: {}

View File

@ -0,0 +1,7 @@
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: selfsigned-issuer
spec:
selfSigned: {}

View File

@ -0,0 +1,33 @@
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: hippo-repl-certmanager
spec:
# Secret names are always required.
secretName: hippo-repl-tls
duration: 2160h # 90d
renewBefore: 360h # 15d
subject:
organizations:
- hippo-org
# The use of the common name field has been deprecated since 2000 and is
# discouraged from being used.
commonName: _crunchyrepl
isCA: false
privateKey:
algorithm: ECDSA
size: 256
usages:
- digital signature
- key encipherment
# At least one of a DNS Name, URI, or IP address is required.
dnsNames:
- _crunchyrepl
issuerRef:
name: ca-issuer
# We can reference ClusterIssuers by changing the kind here.
# The default value is Issuer (i.e. a locally namespaced Issuer)
kind: ClusterIssuer
# This is optional since cert-manager will default to this value however
# if you are using an external issuer, change this to that issuer group.
group: cert-manager.io

View File

@ -0,0 +1,36 @@
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: hippo-certmanager
spec:
# Secret names are always required.
secretName: hippo-tls
duration: 2160h # 90d
renewBefore: 360h # 15d
subject:
organizations:
- hippo-org
# The use of the common name field has been deprecated since 2000 and is
# discouraged from being used.
commonName: hippo-primary
isCA: false
privateKey:
algorithm: ECDSA
size: 256
usages:
- digital signature
- key encipherment
# At least one of a DNS Name, URI, or IP address is required.
dnsNames:
- hippo-primary
- hippo-primary.postgres-operator
- hippo-primary.postgres-operator.svc
- hippo-primary.postgres-operator.svc.cluster.local
issuerRef:
name: ca-issuer
# We can reference ClusterIssuers by changing the kind here.
# The default value is Issuer (i.e. a locally namespaced Issuer)
kind: ClusterIssuer
# This is optional since cert-manager will default to this value however
# if you are using an external issuer, change this to that issuer group.
group: cert-manager.io

View File

@ -0,0 +1,6 @@
namespace: postgres-operator
resources:
- cert.yaml
- cert-repl.yaml
- postgres.yaml

View File

@ -0,0 +1,31 @@
apiVersion: postgres-operator.crunchydata.com/v1beta1
kind: PostgresCluster
metadata:
name: hippo
spec:
image: registry.developers.crunchydata.com/crunchydata/crunchy-postgres:ubi8-14.7-0
postgresVersion: 14
customReplicationTLSSecret:
name: hippo-repl-tls
customTLSSecret:
name: hippo-tls
instances:
- replicas: 2
dataVolumeClaimSpec:
accessModes:
- "ReadWriteOnce"
resources:
requests:
storage: 1Gi
backups:
pgbackrest:
image: registry.developers.crunchydata.com/crunchydata/crunchy-pgbackrest:ubi8-2.41-4
repos:
- name: repo1
volume:
volumeClaimSpec:
accessModes:
- "ReadWriteOnce"
resources:
requests:
storage: 1Gi

View File

@ -0,0 +1 @@
gcs-key.json

View File

@ -0,0 +1,2 @@
[global]
repo1-gcs-key=/etc/pgbackrest/conf.d/gcs-key.json

View File

@ -0,0 +1,13 @@
namespace: postgres-operator
secretGenerator:
- name: pgo-gcs-creds
files:
- gcs.conf
- gcs-key.json
generatorOptions:
disableNameSuffixHash: true
resources:
- postgres.yaml

View File

@ -0,0 +1,26 @@
apiVersion: postgres-operator.crunchydata.com/v1beta1
kind: PostgresCluster
metadata:
name: hippo-gcs
spec:
image: registry.developers.crunchydata.com/crunchydata/crunchy-postgres:ubi8-14.7-0
postgresVersion: 14
instances:
- dataVolumeClaimSpec:
accessModes:
- "ReadWriteOnce"
resources:
requests:
storage: 1Gi
backups:
pgbackrest:
image: registry.developers.crunchydata.com/crunchydata/crunchy-pgbackrest:ubi8-2.41-4
configuration:
- secret:
name: pgo-gcs-creds
global:
repo1-path: /pgbackrest/postgres-operator/hippo-gcs/repo1
repos:
- name: repo1
gcs:
bucket: "<YOUR_GCS_BUCKET_NAME>"

View File

@ -0,0 +1,52 @@
apiVersion: postgres-operator.crunchydata.com/v1beta1
kind: PostgresCluster
metadata:
name: hippo-ha
spec:
image: registry.developers.crunchydata.com/crunchydata/crunchy-postgres:ubi8-14.7-0
postgresVersion: 14
instances:
- name: pgha1
replicas: 2
dataVolumeClaimSpec:
accessModes:
- "ReadWriteOnce"
resources:
requests:
storage: 1Gi
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
podAffinityTerm:
topologyKey: kubernetes.io/hostname
labelSelector:
matchLabels:
postgres-operator.crunchydata.com/cluster: hippo-ha
postgres-operator.crunchydata.com/instance-set: pgha1
backups:
pgbackrest:
image: registry.developers.crunchydata.com/crunchydata/crunchy-pgbackrest:ubi8-2.41-4
repos:
- name: repo1
volume:
volumeClaimSpec:
accessModes:
- "ReadWriteOnce"
resources:
requests:
storage: 1Gi
proxy:
pgBouncer:
image: registry.developers.crunchydata.com/crunchydata/crunchy-pgbouncer:ubi8-1.18-0
replicas: 2
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
podAffinityTerm:
topologyKey: kubernetes.io/hostname
labelSelector:
matchLabels:
postgres-operator.crunchydata.com/cluster: hippo-ha
postgres-operator.crunchydata.com/role: pgbouncer

View File

@ -0,0 +1,4 @@
namespace: postgres-operator
resources:
- ha-postgres.yaml

View File

@ -0,0 +1,3 @@
resources:
- bases/postgres-operator.crunchydata.com_postgresclusters.yaml
- bases/postgres-operator.crunchydata.com_pgupgrades.yaml

View File

@ -0,0 +1,25 @@
namespace: postgres-operator
commonLabels:
app.kubernetes.io/name: pgo
# The version below should match the version on the PostgresCluster CRD
app.kubernetes.io/version: 5.3.1
bases:
- ../crd
- ../rbac/cluster
- ../manager
images:
- name: postgres-operator
newName: registry.developers.crunchydata.com/crunchydata/postgres-operator
newTag: ubi8-5.3.1-0
- name: postgres-operator-upgrade
newName: registry.developers.crunchydata.com/crunchydata/postgres-operator-upgrade
newTag: ubi8-5.3.1-0
patchesJson6902:
- target: { group: apps, version: v1, kind: Deployment, name: pgo }
path: selectors.yaml
- target: { group: apps, version: v1, kind: Deployment, name: pgo-upgrade }
path: selectors.yaml

View File

@ -0,0 +1,8 @@
# We add the app version as a "commonLabel" and change it with each release.
# Remove it from selectors until we use "labels" of Kustomize v4.1.
# See: https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/commonlabels/
# See: https://github.com/kubernetes-sigs/kustomize/releases/tag/kustomize%2Fv4.1.0
- op: remove
path: /spec/selector/matchLabels/app.kubernetes.io~1name
- op: remove
path: /spec/selector/matchLabels/app.kubernetes.io~1version

View File

@ -0,0 +1,3 @@
resources:
- manager.yaml
- manager-upgrade.yaml

View File

@ -0,0 +1,36 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: pgo-upgrade
labels:
postgres-operator.crunchydata.com/control-plane: postgres-operator-upgrade
spec:
replicas: 1
strategy: { type: Recreate }
selector:
matchLabels:
postgres-operator.crunchydata.com/control-plane: postgres-operator-upgrade
template:
metadata:
labels:
postgres-operator.crunchydata.com/control-plane: postgres-operator-upgrade
spec:
containers:
- name: operator
image: postgres-operator-upgrade
env:
- name: PGO_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: CRUNCHY_DEBUG
value: "true"
- name: RELATED_IMAGE_PGUPGRADE
value: "registry.developers.crunchydata.com/crunchydata/crunchy-upgrade:ubi8-5.3.1-0"
securityContext:
allowPrivilegeEscalation: false
capabilities: { drop: [ALL] }
readOnlyRootFilesystem: true
runAsNonRoot: true
serviceAccountName: postgres-operator-upgrade

View File

@ -0,0 +1,54 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: pgo
labels:
postgres-operator.crunchydata.com/control-plane: postgres-operator
spec:
replicas: 1
strategy: { type: Recreate }
selector:
matchLabels:
postgres-operator.crunchydata.com/control-plane: postgres-operator
template:
metadata:
labels:
postgres-operator.crunchydata.com/control-plane: postgres-operator
spec:
containers:
- name: operator
image: postgres-operator
env:
- name: PGO_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: CRUNCHY_DEBUG
value: "true"
- name: RELATED_IMAGE_POSTGRES_14
value: "registry.developers.crunchydata.com/crunchydata/crunchy-postgres:ubi8-14.7-0"
- name: RELATED_IMAGE_POSTGRES_14_GIS_3.1
value: "registry.developers.crunchydata.com/crunchydata/crunchy-postgres-gis:ubi8-14.7-3.1-0"
- name: RELATED_IMAGE_POSTGRES_14_GIS_3.2
value: "registry.developers.crunchydata.com/crunchydata/crunchy-postgres-gis:ubi8-14.7-3.2-0"
- name: RELATED_IMAGE_POSTGRES_14_GIS_3.3
value: "registry.developers.crunchydata.com/crunchydata/crunchy-postgres-gis:ubi8-14.7-3.3-0"
- name: RELATED_IMAGE_POSTGRES_15
value: "registry.developers.crunchydata.com/crunchydata/crunchy-postgres:ubi8-15.2-0"
- name: RELATED_IMAGE_POSTGRES_15_GIS_3.3
value: "registry.developers.crunchydata.com/crunchydata/crunchy-postgres-gis:ubi8-15.2-3.3-0"
- name: RELATED_IMAGE_PGADMIN
value: "registry.developers.crunchydata.com/crunchydata/crunchy-pgadmin4:ubi8-4.30-10"
- name: RELATED_IMAGE_PGBACKREST
value: "registry.developers.crunchydata.com/crunchydata/crunchy-pgbackrest:ubi8-2.41-4"
- name: RELATED_IMAGE_PGBOUNCER
value: "registry.developers.crunchydata.com/crunchydata/crunchy-pgbouncer:ubi8-1.18-0"
- name: RELATED_IMAGE_PGEXPORTER
value: "registry.developers.crunchydata.com/crunchydata/crunchy-postgres-exporter:ubi8-5.3.1-0"
securityContext:
allowPrivilegeEscalation: false
capabilities: { drop: [ALL] }
readOnlyRootFilesystem: true
runAsNonRoot: true
serviceAccountName: pgo

View File

@ -0,0 +1,2 @@
resources:
- namespace.yaml

View File

@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: postgres-operator

View File

@ -0,0 +1,7 @@
resources:
- service_account.yaml
- role.yaml
- role_binding.yaml
- service_account-upgrade.yaml
- role-upgrade.yaml
- role_binding-upgrade.yaml

View File

@ -0,0 +1,71 @@
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
creationTimestamp: null
name: postgres-operator-upgrade
labels:
postgres-operator.crunchydata.com/control-plane: postgres-operator-upgrade
rules:
- apiGroups:
- ""
resources:
- endpoints
verbs:
- delete
- get
- list
- watch
- apiGroups:
- apps
resources:
- statefulsets
verbs:
- list
- watch
- apiGroups:
- batch
resources:
- jobs
verbs:
- create
- delete
- list
- patch
- watch
- apiGroups:
- postgres-operator.crunchydata.com
resources:
- pgupgrades
verbs:
- get
- list
- watch
- apiGroups:
- postgres-operator.crunchydata.com
resources:
- pgupgrades/finalizers
verbs:
- patch
- update
- apiGroups:
- postgres-operator.crunchydata.com
resources:
- pgupgrades/status
verbs:
- get
- patch
- apiGroups:
- postgres-operator.crunchydata.com
resources:
- postgresclusters
verbs:
- get
- list
- watch
- apiGroups:
- postgres-operator.crunchydata.com
resources:
- postgresclusters/status
verbs:
- patch

View File

@ -0,0 +1,135 @@
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: postgres-operator
labels:
postgres-operator.crunchydata.com/control-plane: postgres-operator
rules:
- apiGroups:
- ''
resources:
- configmaps
- persistentvolumeclaims
- secrets
- services
verbs:
- create
- delete
- get
- list
- patch
- watch
- apiGroups:
- ''
resources:
- endpoints
verbs:
- create
- delete
- deletecollection
- get
- list
- patch
- watch
- apiGroups:
- ''
resources:
- endpoints/restricted
- pods/exec
verbs:
- create
- apiGroups:
- ''
resources:
- events
verbs:
- create
- patch
- apiGroups:
- ''
resources:
- pods
verbs:
- delete
- get
- list
- patch
- watch
- apiGroups:
- ''
resources:
- serviceaccounts
verbs:
- create
- get
- list
- patch
- watch
- apiGroups:
- apps
resources:
- deployments
- statefulsets
verbs:
- create
- delete
- get
- list
- patch
- watch
- apiGroups:
- batch
resources:
- cronjobs
- jobs
verbs:
- create
- delete
- get
- list
- patch
- watch
- apiGroups:
- policy
resources:
- poddisruptionbudgets
verbs:
- create
- delete
- get
- list
- patch
- watch
- apiGroups:
- postgres-operator.crunchydata.com
resources:
- postgresclusters
verbs:
- get
- list
- patch
- watch
- apiGroups:
- postgres-operator.crunchydata.com
resources:
- postgresclusters/finalizers
verbs:
- update
- apiGroups:
- postgres-operator.crunchydata.com
resources:
- postgresclusters/status
verbs:
- patch
- apiGroups:
- rbac.authorization.k8s.io
resources:
- rolebindings
- roles
verbs:
- create
- get
- list
- patch
- watch

View File

@ -0,0 +1,14 @@
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: postgres-operator-upgrade
labels:
postgres-operator.crunchydata.com/control-plane: postgres-operator-upgrade
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: postgres-operator-upgrade
subjects:
- kind: ServiceAccount
name: postgres-operator-upgrade

View File

@ -0,0 +1,14 @@
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: postgres-operator
labels:
postgres-operator.crunchydata.com/control-plane: postgres-operator
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: postgres-operator
subjects:
- kind: ServiceAccount
name: pgo

View File

@ -0,0 +1,7 @@
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: postgres-operator-upgrade
labels:
postgres-operator.crunchydata.com/control-plane: postgres-operator-upgrade

View File

@ -0,0 +1,7 @@
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: pgo
labels:
postgres-operator.crunchydata.com/control-plane: postgres-operator

View File

@ -0,0 +1,7 @@
resources:
- service_account.yaml
- role.yaml
- role_binding.yaml
- service_account-upgrade.yaml
- role-upgrade.yaml
- role_binding-upgrade.yaml

View File

@ -0,0 +1,71 @@
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
creationTimestamp: null
name: postgres-operator-upgrade
labels:
postgres-operator.crunchydata.com/control-plane: postgres-operator-upgrade
rules:
- apiGroups:
- ""
resources:
- endpoints
verbs:
- delete
- get
- list
- watch
- apiGroups:
- apps
resources:
- statefulsets
verbs:
- list
- watch
- apiGroups:
- batch
resources:
- jobs
verbs:
- create
- delete
- list
- patch
- watch
- apiGroups:
- postgres-operator.crunchydata.com
resources:
- pgupgrades
verbs:
- get
- list
- watch
- apiGroups:
- postgres-operator.crunchydata.com
resources:
- pgupgrades/finalizers
verbs:
- patch
- update
- apiGroups:
- postgres-operator.crunchydata.com
resources:
- pgupgrades/status
verbs:
- get
- patch
- apiGroups:
- postgres-operator.crunchydata.com
resources:
- postgresclusters
verbs:
- get
- list
- watch
- apiGroups:
- postgres-operator.crunchydata.com
resources:
- postgresclusters/status
verbs:
- patch

View File

@ -0,0 +1,135 @@
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: postgres-operator
labels:
postgres-operator.crunchydata.com/control-plane: postgres-operator
rules:
- apiGroups:
- ''
resources:
- configmaps
- persistentvolumeclaims
- secrets
- services
verbs:
- create
- delete
- get
- list
- patch
- watch
- apiGroups:
- ''
resources:
- endpoints
verbs:
- create
- delete
- deletecollection
- get
- list
- patch
- watch
- apiGroups:
- ''
resources:
- endpoints/restricted
- pods/exec
verbs:
- create
- apiGroups:
- ''
resources:
- events
verbs:
- create
- patch
- apiGroups:
- ''
resources:
- pods
verbs:
- delete
- get
- list
- patch
- watch
- apiGroups:
- ''
resources:
- serviceaccounts
verbs:
- create
- get
- list
- patch
- watch
- apiGroups:
- apps
resources:
- deployments
- statefulsets
verbs:
- create
- delete
- get
- list
- patch
- watch
- apiGroups:
- batch
resources:
- cronjobs
- jobs
verbs:
- create
- delete
- get
- list
- patch
- watch
- apiGroups:
- policy
resources:
- poddisruptionbudgets
verbs:
- create
- delete
- get
- list
- patch
- watch
- apiGroups:
- postgres-operator.crunchydata.com
resources:
- postgresclusters
verbs:
- get
- list
- patch
- watch
- apiGroups:
- postgres-operator.crunchydata.com
resources:
- postgresclusters/finalizers
verbs:
- update
- apiGroups:
- postgres-operator.crunchydata.com
resources:
- postgresclusters/status
verbs:
- patch
- apiGroups:
- rbac.authorization.k8s.io
resources:
- rolebindings
- roles
verbs:
- create
- get
- list
- patch
- watch

View File

@ -0,0 +1,14 @@
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: postgres-operator-upgrade
labels:
postgres-operator.crunchydata.com/control-plane: postgres-operator-upgrade
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: postgres-operator-upgrade
subjects:
- kind: ServiceAccount
name: postgres-operator-upgrade

View File

@ -0,0 +1,14 @@
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: postgres-operator
labels:
postgres-operator.crunchydata.com/control-plane: postgres-operator
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: postgres-operator
subjects:
- kind: ServiceAccount
name: pgo

View File

@ -0,0 +1,7 @@
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: postgres-operator-upgrade
labels:
postgres-operator.crunchydata.com/control-plane: postgres-operator-upgrade

View File

@ -0,0 +1,7 @@
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: pgo
labels:
postgres-operator.crunchydata.com/control-plane: postgres-operator

View File

@ -0,0 +1,29 @@
namespace: postgres-operator
commonLabels:
app.kubernetes.io/name: pgo
# The version below should match the version on the PostgresCluster CRD
app.kubernetes.io/version: 5.3.1
bases:
- ../crd
- ../rbac/namespace
- ../manager
images:
- name: postgres-operator
newName: registry.developers.crunchydata.com/crunchydata/postgres-operator
newTag: ubi8-5.3.1-0
- name: postgres-operator-upgrade
newName: registry.developers.crunchydata.com/crunchydata/postgres-operator-upgrade
newTag: ubi8-5.3.1-0
patchesJson6902:
- target: { group: apps, version: v1, kind: Deployment, name: pgo }
path: selectors.yaml
- target: { group: apps, version: v1, kind: Deployment, name: pgo-upgrade }
path: selectors.yaml
patchesStrategicMerge:
- manager-target.yaml
- manager-target-upgrade.yaml

View File

@ -0,0 +1,13 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: pgo-upgrade
spec:
template:
spec:
containers:
- name: operator
env:
- name: PGO_TARGET_NAMESPACE
valueFrom: { fieldRef: { apiVersion: v1, fieldPath: metadata.namespace } }

View File

@ -0,0 +1,13 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: pgo
spec:
template:
spec:
containers:
- name: operator
env:
- name: PGO_TARGET_NAMESPACE
valueFrom: { fieldRef: { apiVersion: v1, fieldPath: metadata.namespace } }

View File

@ -0,0 +1,8 @@
# We add the app version as a "commonLabel" and change it with each release.
# Remove it from selectors until we use "labels" of Kustomize v4.1.
# See: https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/commonlabels/
# See: https://github.com/kubernetes-sigs/kustomize/releases/tag/kustomize%2Fv4.1.0
- op: remove
path: /spec/selector/matchLabels/app.kubernetes.io~1name
- op: remove
path: /spec/selector/matchLabels/app.kubernetes.io~1version

View File

@ -0,0 +1,48 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: keycloak
namespace: postgres-operator
labels:
app.kubernetes.io/name: keycloak
spec:
selector:
matchLabels:
app.kubernetes.io/name: keycloak
template:
metadata:
labels:
app.kubernetes.io/name: keycloak
spec:
containers:
- image: quay.io/keycloak/keycloak:latest
name: keycloak
env:
- name: DB_VENDOR
value: "postgres"
- name: DB_ADDR
valueFrom: { secretKeyRef: { name: keycloakdb-pguser-keycloakdb, key: host } }
- name: DB_PORT
valueFrom: { secretKeyRef: { name: keycloakdb-pguser-keycloakdb, key: port } }
- name: DB_DATABASE
valueFrom: { secretKeyRef: { name: keycloakdb-pguser-keycloakdb, key: dbname } }
- name: DB_USER
valueFrom: { secretKeyRef: { name: keycloakdb-pguser-keycloakdb, key: user } }
- name: DB_PASSWORD
valueFrom: { secretKeyRef: { name: keycloakdb-pguser-keycloakdb, key: password } }
- name: KEYCLOAK_USER
value: "admin"
- name: KEYCLOAK_PASSWORD
value: "admin"
- name: PROXY_ADDRESS_FORWARDING
value: "true"
ports:
- name: http
containerPort: 8080
- name: https
containerPort: 8443
readinessProbe:
httpGet:
path: /auth/realms/master
port: 8080
restartPolicy: Always

View File

@ -0,0 +1,5 @@
namespace: postgres-operator
resources:
- postgres.yaml
- keycloak.yaml

View File

@ -0,0 +1,37 @@
apiVersion: postgres-operator.crunchydata.com/v1beta1
kind: PostgresCluster
metadata:
name: keycloakdb
spec:
image: registry.developers.crunchydata.com/crunchydata/crunchy-postgres:ubi8-14.7-0
postgresVersion: 14
instances:
- replicas: 2
dataVolumeClaimSpec:
accessModes:
- "ReadWriteOnce"
resources:
requests:
storage: 1Gi
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
podAffinityTerm:
topologyKey: kubernetes.io/hostname
labelSelector:
matchLabels:
postgres-operator.crunchydata.com/cluster: keycloakdb
postgres-operator.crunchydata.com/instance-set: "00"
backups:
pgbackrest:
image: registry.developers.crunchydata.com/crunchydata/crunchy-pgbackrest:ubi8-2.41-4
repos:
- name: repo1
volume:
volumeClaimSpec:
accessModes:
- "ReadWriteOnce"
resources:
requests:
storage: 1Gi

View File

@ -0,0 +1,5 @@
To deploy monitoring,
1. verify the namespace is correct in kustomization.yaml
2. If you are deploying in openshift, edit deploy*.yaml and comment out fsGroup line under securityContext
3. kubectl apply -k .

View File

@ -0,0 +1,87 @@
apiVersion: v1
data:
alertmanager.yml: |
###
#
# Copyright © 2017-2023 Crunchy Data Solutions, Inc. All Rights Reserved.
#
###
# Based on upstream example file found here: https://github.com/prometheus/alertmanager/blob/master/doc/examples/simple.yml
global:
smtp_smarthost: 'localhost: 25'
smtp_require_tls: false
smtp_from: 'Alertmanager <abc@yahoo.com>'
# smtp_smarthost: 'smtp.example.com:587'
# smtp_from: 'Alertmanager <abc@yahoo.com>'
# smtp_auth_username: '<username>'
# smtp_auth_password: '<password>'
# templates:
# - '/etc/alertmanager/template/*.tmpl'
inhibit_rules:
# Apply inhibition of warning if the alertname for the same system and service is already critical
- source_match:
severity: 'critical'
target_match:
severity: 'warning'
equal: ['alertname', 'job', 'service']
receivers:
- name: 'default-receiver'
email_configs:
- to: 'example@crunchydata.com'
send_resolved: true
## Examples of alternative alert receivers. See documentation for more info on how to configure these fully
#- name: 'pagerduty-dba'
# pagerduty_configs:
# - service_key: <RANDOMKEYSTUFF>
#- name: 'pagerduty-sre'
# pagerduty_configs:
# - service_key: <RANDOMKEYSTUFF>
#- name: 'dba-team'
# email_configs:
# - to: 'example-dba-team@crunchydata.com'
# send_resolved: true
#- name: 'sre-team'
# email_configs:
# - to: 'example-sre-team@crunchydata.com'
# send_resolved: true
route:
receiver: default-receiver
group_by: [severity, service, job, alertname]
group_wait: 30s
group_interval: 5m
repeat_interval: 24h
## Example routes to show how to route outgoing alerts based on the content of that alert
# routes:
# - match_re:
# service: ^(postgresql|mysql|oracle)$
# receiver: dba-team
# # sub route to send critical dba alerts to pagerduty
# routes:
# - match:
# severity: critical
# receiver: pagerduty-dba
#
# - match:
# service: system
# receiver: sre-team
# # sub route to send critical sre alerts to pagerduty
# routes:
# - match:
# severity: critical
# receiver: pagerduty-sre
kind: ConfigMap
metadata:
labels:
app.kubernetes.io/name: postgres-operator-monitoring
vendor: crunchydata
name: alertmanager-config

View File

@ -0,0 +1,428 @@
apiVersion: v1
data:
crunchy-alert-rules-pg.yml: |
###
#
# Copyright 2017-2023 Crunchy Data Solutions, Inc. All Rights Reserved.
#
###
groups:
- name: alert-rules
rules:
########## EXPORTER RULES ##########
- alert: PGExporterScrapeError
expr: pg_exporter_last_scrape_error > 0
for: 60s
labels:
service: postgresql
severity: critical
severity_num: 300
annotations:
summary: 'Postgres Exporter running on {{ $labels.job }} (instance: {{ $labels.instance }}) is encountering scrape errors processing queries. Error count: ( {{ $value }} )'
########## SYSTEM RULES ##########
- alert: ExporterDown
expr: avg_over_time(up[5m]) < 0.5
for: 10s
labels:
service: system
severity: critical
severity_num: 300
annotations:
description: 'Metrics exporter service for {{ $labels.job }} running on {{ $labels.instance }} has been down at least 50% of the time for the last 5 minutes. Service may be flapping or down.'
summary: 'Prometheus Exporter Service Down'
########## POSTGRESQL RULES ##########
- alert: PGIsUp
expr: pg_up < 1
for: 60s
labels:
service: postgresql
severity: critical
severity_num: 300
annotations:
summary: 'postgres_exporter running on {{ $labels.job }} is unable to communicate with the configured database'
# Example to check for current version of PostgreSQL. Metric returns the version that the exporter is running on, so you can set a rule to check for the minimum version you'd like all systems to be on. Number returned is the 6 digit integer representation contained in the setting "server_version_num".
#
# - alert: PGMinimumVersion
# expr: ccp_postgresql_version_current < 110005
# for: 60s
# labels:
# service: postgresql
# severity: critical
# severity_num: 300
# annotations:
# summary: '{{ $labels.job }} is not running at least version 11.5 of PostgreSQL'
# Whether a system switches from primary to replica or vice versa must be configured per named job.
# No way to tell what value a system is supposed to be without a rule expression for that specific system
# 2 to 1 means it changed from primary to replica. 1 to 2 means it changed from replica to primary
# Set this alert for each system that you want to monitor a recovery status change
# Below is an example for a target job called "Replica" and watches for the value to change above 1 which means it's no longer a replica
#
# - alert: PGRecoveryStatusSwitch_Replica
# expr: ccp_is_in_recovery_status{job="Replica"} > 1
# for: 60s
# labels:
# service: postgresql
# severity: critical
# severity_num: 300
# annotations:
# summary: '{{ $labels.job }} has changed from replica to primary'
# Absence alerts must be configured per named job, otherwise there's no way to know which job is down
# Below is an example for a target job called "Prod"
# - alert: PGConnectionAbsent_Prod
# expr: absent(ccp_connection_stats_max_connections{job="Prod"})
# for: 10s
# labels:
# service: postgresql
# severity: critical
# severity_num: 300
# annotations:
# description: 'Connection metric is absent from target (Prod). Check that postgres_exporter can connect to PostgreSQL.'
# Optional monitor for changes to pg_settings (postgresql.conf) system catalog.
# A similar metric is available for monitoring pg_hba.conf. See ccp_hba_settings_checksum().
# If metric returns 0, then NO settings have changed for either pg_settings since last known valid state
# If metric returns 1, then pg_settings have changed since last known valid state
# To see what may have changed, check the monitor.pg_settings_checksum table for a history of config state.
# - alert: PGSettingsChecksum
# expr: ccp_pg_settings_checksum > 0
# for 60s
# labels:
# service: postgresql
# severity: critical
# severity_num: 300
# annotations:
# description: 'Configuration settings on {{ $labels.job }} have changed from previously known valid state. To reset current config to a valid state after alert fires, run monitor.pg_settings_checksum_set_valid().'
# summary: 'PGSQL Instance settings checksum'
# Monitor for data block checksum failures. Only works in PG12+
# - alert: PGDataChecksum
# expr: ccp_data_checksum_failure > 0
# for 60s
# labels:
# service: postgresql
# severity: critical
# severity_num: 300
# annotations:
# description: '{{ $labels.job }} has at least one data checksum failure in database {{ $labels.dbname }}. See pg_stat_database system catalog for more information.'
# summary: 'PGSQL Data Checksum failure'
- alert: PGIdleTxn
expr: ccp_connection_stats_max_idle_in_txn_time > 300
for: 60s
labels:
service: postgresql
severity: warning
severity_num: 200
annotations:
description: '{{ $labels.job }} has at least one session idle in transaction for over 5 minutes.'
summary: 'PGSQL Instance idle transactions'
- alert: PGIdleTxn
expr: ccp_connection_stats_max_idle_in_txn_time > 900
for: 60s
labels:
service: postgresql
severity: critical
severity_num: 300
annotations:
description: '{{ $labels.job }} has at least one session idle in transaction for over 15 minutes.'
summary: 'PGSQL Instance idle transactions'
- alert: PGQueryTime
expr: ccp_connection_stats_max_query_time > 43200
for: 60s
labels:
service: postgresql
severity: warning
severity_num: 200
annotations:
description: '{{ $labels.job }} has at least one query running for over 12 hours.'
summary: 'PGSQL Max Query Runtime'
- alert: PGQueryTime
expr: ccp_connection_stats_max_query_time > 86400
for: 60s
labels:
service: postgresql
severity: critical
severity_num: 300
annotations:
description: '{{ $labels.job }} has at least one query running for over 1 day.'
summary: 'PGSQL Max Query Runtime'
- alert: PGConnPerc
expr: 100 * (ccp_connection_stats_total / ccp_connection_stats_max_connections) > 75
for: 60s
labels:
service: postgresql
severity: warning
severity_num: 200
annotations:
description: '{{ $labels.job }} is using 75% or more of available connections ({{ $value }}%)'
summary: 'PGSQL Instance connections'
- alert: PGConnPerc
expr: 100 * (ccp_connection_stats_total / ccp_connection_stats_max_connections) > 90
for: 60s
labels:
service: postgresql
severity: critical
severity_num: 300
annotations:
description: '{{ $labels.job }} is using 90% or more of available connections ({{ $value }}%)'
summary: 'PGSQL Instance connections'
- alert: DiskFillPredict
expr: predict_linear(ccp_nodemx_data_disk_available_bytes{mount_point!~"tmpfs"}[1h], 24 * 3600) < 0 and 100 * ((ccp_nodemx_data_disk_total_bytes - ccp_nodemx_data_disk_available_bytes) / ccp_nodemx_data_disk_total_bytes) > 70
for: 5m
labels:
service: postgresql
severity: warning
severity_num: 200
annotations:
summary: 'Disk predicted to be full in 24 hours'
description: 'Disk on {{ $labels.pg_cluster }}:{{ $labels.kubernetes_pod_name }} is predicted to fill in 24 hrs based on current usage'
- alert: PGClusterRoleChange
expr: count by (pg_cluster) (ccp_is_in_recovery_status != ignoring(instance,ip,pod,role) (ccp_is_in_recovery_status offset 5m)) >= 1
for: 60s
labels:
service: postgresql
severity: critical
severity_num: 300
annotations:
summary: '{{ $labels.pg_cluster }} has had a switchover/failover event. Please check this cluster for more details'
- alert: PGDiskSize
expr: 100 * ((ccp_nodemx_data_disk_total_bytes - ccp_nodemx_data_disk_available_bytes) / ccp_nodemx_data_disk_total_bytes) > 75
for: 60s
labels:
service: postgresql
severity: warning
severity_num: 200
annotations:
description: 'PGSQL Instance {{ $labels.deployment }} over 75% disk usage at mount point "{{ $labels.mount_point }}": {{ $value }}%'
summary: PGSQL Instance usage warning
- alert: PGDiskSize
expr: 100 * ((ccp_nodemx_data_disk_total_bytes - ccp_nodemx_data_disk_available_bytes) / ccp_nodemx_data_disk_total_bytes) > 90
for: 60s
labels:
service: postgresql
severity: critical
severity_num: 300
annotations:
description: 'PGSQL Instance {{ $labels.deployment }} over 90% disk usage at mount point "{{ $labels.mount_point }}": {{ $value }}%'
summary: 'PGSQL Instance size critical'
- alert: PGReplicationByteLag
expr: ccp_replication_lag_size_bytes > 5.24288e+07
for: 60s
labels:
service: postgresql
severity: warning
severity_num: 200
annotations:
description: 'PGSQL Instance {{ $labels.job }} has at least one replica lagging over 50MB behind.'
summary: 'PGSQL Instance replica lag warning'
- alert: PGReplicationByteLag
expr: ccp_replication_lag_size_bytes > 1.048576e+08
for: 60s
labels:
service: postgresql
severity: critical
severity_num: 300
annotations:
description: 'PGSQL Instance {{ $labels.job }} has at least one replica lagging over 100MB behind.'
summary: 'PGSQL Instance replica lag warning'
- alert: PGReplicationSlotsInactive
expr: ccp_replication_slots_active == 0
for: 60s
labels:
service: postgresql
severity: critical
severity_num: 300
annotations:
description: 'PGSQL Instance {{ $labels.job }} has one or more inactive replication slots'
summary: 'PGSQL Instance inactive replication slot'
- alert: PGXIDWraparound
expr: ccp_transaction_wraparound_percent_towards_wraparound > 50
for: 60s
labels:
service: postgresql
severity: warning
severity_num: 200
annotations:
description: 'PGSQL Instance {{ $labels.job }} is over 50% towards transaction id wraparound.'
summary: 'PGSQL Instance {{ $labels.job }} transaction id wraparound imminent'
- alert: PGXIDWraparound
expr: ccp_transaction_wraparound_percent_towards_wraparound > 75
for: 60s
labels:
service: postgresql
severity: critical
severity_num: 300
annotations:
description: 'PGSQL Instance {{ $labels.job }} is over 75% towards transaction id wraparound.'
summary: 'PGSQL Instance transaction id wraparound imminent'
- alert: PGEmergencyVacuum
expr: ccp_transaction_wraparound_percent_towards_emergency_autovac > 110
for: 60s
labels:
service: postgresql
severity: warning
severity_num: 200
annotations:
description: 'PGSQL Instance {{ $labels.job }} is over 110% beyond autovacuum_freeze_max_age value. Autovacuum may need tuning to better keep up.'
summary: 'PGSQL Instance emergency vacuum imminent'
- alert: PGEmergencyVacuum
expr: ccp_transaction_wraparound_percent_towards_emergency_autovac > 125
for: 60s
labels:
service: postgresql
severity: critical
severity_num: 300
annotations:
description: 'PGSQL Instance {{ $labels.job }} is over 125% beyond autovacuum_freeze_max_age value. Autovacuum needs tuning to better keep up.'
summary: 'PGSQL Instance emergency vacuum imminent'
- alert: PGArchiveCommandStatus
expr: ccp_archive_command_status_seconds_since_last_fail > 300
for: 60s
labels:
service: postgresql
severity: critical
severity_num: 300
annotations:
description: 'PGSQL Instance {{ $labels.job }} has a recent failing archive command'
summary: 'Seconds since the last recorded failure of the archive_command'
- alert: PGSequenceExhaustion
expr: ccp_sequence_exhaustion_count > 0
for: 60s
labels:
service: postgresql
severity: critical
severity_num: 300
annotations:
description: 'Count of sequences on instance {{ $labels.job }} at over 75% usage: {{ $value }}. Run following query to see full sequence status: SELECT * FROM monitor.sequence_status() WHERE percent >= 75'
- alert: PGSettingsPendingRestart
expr: ccp_settings_pending_restart_count > 0
for: 60s
labels:
service: postgresql
severity: critical
severity_num: 300
annotations:
description: 'One or more settings in the pg_settings system catalog on system {{ $labels.job }} are in a pending_restart state. Check the system catalog for which settings are pending and review postgresql.conf for changes.'
########## PGBACKREST RULES ##########
#
# Uncomment and customize one or more of these rules to monitor your pgbackrest backups.
# Full backups are considered the equivalent of both differentials and incrementals since both are based on the last full
# And differentials are considered incrementals since incrementals will be based off the last diff if one exists
# This avoid false alerts, for example when you don't run diff/incr backups on the days that you run a full
# Stanza should also be set if different intervals are expected for each stanza.
# Otherwise rule will be applied to all stanzas returned on target system if not set.
#
# Relevant metric names are:
# ccp_backrest_last_full_backup_time_since_completion_seconds
# ccp_backrest_last_incr_backup_time_since_completion_seconds
# ccp_backrest_last_diff_backup_time_since_completion_seconds
#
# To avoid false positives on backup time alerts, 12 hours are added onto each threshold to allow a buffer if the backup runtime varies from day to day.
# Further adjustment may be needed depending on your backup runtimes/schedule.
#
# - alert: PGBackRestLastCompletedFull_main
# expr: ccp_backrest_last_full_backup_time_since_completion_seconds{stanza="main"} > 648000
# for: 60s
# labels:
# service: postgresql
# severity: critical
# severity_num: 300
# annotations:
# summary: 'Full backup for stanza [main] on system {{ $labels.job }} has not completed in the last week.'
#
# - alert: PGBackRestLastCompletedIncr_main
# expr: ccp_backrest_last_incr_backup_time_since_completion_seconds{stanza="main"} > 129600
# for: 60s
# labels:
# service: postgresql
# severity: critical
# severity_num: 300
# annotations:
# summary: 'Incremental backup for stanza [main] on system {{ $labels.job }} has not completed in the last 24 hours.'
#
#
# Runtime monitoring is handled with a single metric:
#
# ccp_backrest_last_info_backup_runtime_seconds
#
# Runtime monitoring should have the "backup_type" label set.
# Otherwise the rule will apply to the last run of all backup types returned (full, diff, incr)
# Stanza should also be set if runtimes per stanza have different expected times
#
# - alert: PGBackRestLastRuntimeFull_main
# expr: ccp_backrest_last_info_backup_runtime_seconds{backup_type="full", stanza="main"} > 14400
# for: 60s
# labels:
# service: postgresql
# severity: critical
# severity_num: 300
# annotations:
# summary: 'Expected runtime of full backup for stanza [main] has exceeded 4 hours'
#
# - alert: PGBackRestLastRuntimeDiff_main
# expr: ccp_backrest_last_info_backup_runtime_seconds{backup_type="diff", stanza="main"} > 3600
# for: 60s
# labels:
# service: postgresql
# severity: critical
# severity_num: 300
# annotations:
# summary: 'Expected runtime of diff backup for stanza [main] has exceeded 1 hour'
##
#
## If the pgbackrest command fails to run, the metric disappears from the exporter output and the alert never fires.
## An absence alert must be configured explicitly for each target (job) that backups are being monitored.
## Checking for absence of just the full backup type should be sufficient (no need for diff/incr).
## Note that while the backrest check command failing will likely also cause a scrape error alert, the addition of this
## check gives a clearer answer as to what is causing it and that something is wrong with the backups.
#
# - alert: PGBackrestAbsentFull_Prod
# expr: absent(ccp_backrest_last_full_backup_time_since_completion_seconds{job="Prod"})
# for: 10s
# labels:
# service: postgresql
# severity: critical
# severity_num: 300
# annotations:
# description: 'Backup Full status missing for Prod. Check that pgbackrest info command is working on target system.'
kind: ConfigMap
metadata:
labels:
app.kubernetes.io/name: postgres-operator-monitoring
vendor: crunchydata
name: alertmanager-rules-config

View File

@ -0,0 +1,16 @@
###
#
# Copyright © 2017-2023 Crunchy Data Solutions, Inc. All Rights Reserved.
#
###
apiVersion: 1
providers:
- name: 'crunchy_dashboards'
orgId: 1
folder: ''
type: file
disableDeletion: false
updateIntervalSeconds: 3 #how often Grafana will scan for changed dashboards
options:
path: /etc/grafana/provisioning/dashboards

View File

@ -0,0 +1,331 @@
{
"__inputs": [
{
"name": "DS_PROMETHEUS",
"label": "PROMETHEUS",
"description": "",
"type": "datasource",
"pluginId": "prometheus",
"pluginName": "Prometheus"
}
],
"__requires": [
{
"type": "grafana",
"id": "grafana",
"name": "Grafana",
"version": "6.7.4"
},
{
"type": "panel",
"id": "graph",
"name": "Graph",
"version": ""
},
{
"type": "datasource",
"id": "prometheus",
"name": "Prometheus",
"version": "1.0.0"
}
],
"annotations": {
"list": [
{
"$$hashKey": "object:111",
"builtIn": 1,
"datasource": "-- Grafana --",
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"editable": false,
"gnetId": null,
"graphTooltip": 0,
"id": null,
"iteration": 1596817489973,
"links": [
{
"icon": "external link",
"includeVars": true,
"keepTime": true,
"tags": [],
"type": "dashboards"
}
],
"panels": [
{
"aliasColors": {},
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": "PROMETHEUS",
"fill": 1,
"fillGradient": 0,
"gridPos": {
"h": 12,
"w": 24,
"x": 0,
"y": 0
},
"height": "480",
"hiddenSeries": false,
"id": 1,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"maxPerRow": 2,
"nullPointMode": "null",
"options": {
"dataLinks": []
},
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"repeat": null,
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"expr": "sum(rate(ccp_stat_user_tables_n_tup_ins{pg_cluster=\"[[cluster]]\", pod=~\"[[pod]]\", dbname=~\"[[dbname]]\", schemaname=~\"[[schemaname]]\", relname=~\"[[tablename]]\"}[60s]))",
"format": "time_series",
"intervalFactor": 2,
"legendFormat": "inserts - [[dbname]].[[schemaname]].[[tablename]]",
"refId": "A",
"step": 60
},
{
"expr": "sum(rate(ccp_stat_user_tables_n_tup_upd{pg_cluster=\"[[cluster]]\", pod=~\"[[pod]]\", dbname=~\"[[dbname]]\", schemaname=~\"[[schemaname]]\", relname=~\"[[tablename]]\"}[60s]))",
"format": "time_series",
"intervalFactor": 2,
"legendFormat": "Updates - [[dbname]].[[schemaname]].[[tablename]]",
"refId": "B",
"step": 60
},
{
"expr": "sum(rate(ccp_stat_user_tables_n_tup_del{pg_cluster=\"[[cluster]]\", pod=~\"[[pod]]\", dbname=~\"[[dbname]]\", schemaname=~\"[[schemaname]]\", relname=~\"[[tablename]]\"}[60s]))",
"format": "time_series",
"intervalFactor": 2,
"legendFormat": "Deletes - [[dbname]].[[schemaname]].[[tablename]]",
"refId": "C",
"step": 60
}
],
"thresholds": [],
"timeFrom": null,
"timeRegions": [],
"timeShift": null,
"title": "CRUD",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"buckets": null,
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
],
"yaxis": {
"align": false,
"alignLevel": null
}
}
],
"refresh": "30s",
"schemaVersion": 22,
"style": "dark",
"tags": [],
"templating": {
"list": [
{
"allValue": null,
"current": {},
"datasource": "PROMETHEUS",
"definition": "",
"hide": 0,
"includeAll": false,
"index": -1,
"label": null,
"multi": false,
"name": "cluster",
"options": [],
"query": "label_values(pg_cluster)",
"refresh": 1,
"regex": "",
"skipUrlSync": false,
"sort": 1,
"tagValuesQuery": "",
"tags": [],
"tagsQuery": "",
"type": "query",
"useTags": false
},
{
"allValue": ".*",
"current": {},
"datasource": "PROMETHEUS",
"definition": "label_values({pg_cluster=\"[[cluster]]\"},pod)",
"hide": 0,
"includeAll": true,
"index": -1,
"label": "pod",
"multi": true,
"name": "pod",
"options": [],
"query": "label_values({pg_cluster=\"[[cluster]]\"},pod)",
"refresh": 1,
"regex": "",
"skipUrlSync": false,
"sort": 1,
"tagValuesQuery": "",
"tags": [],
"tagsQuery": "",
"type": "query",
"useTags": false
},
{
"allValue": ".*",
"current": {},
"datasource": "PROMETHEUS",
"definition": "label_values(ccp_database_size_bytes{pg_cluster=\"[[cluster]]\"},dbname)",
"hide": 0,
"includeAll": true,
"index": -1,
"label": "dbname",
"multi": true,
"name": "dbname",
"options": [],
"query": "label_values(ccp_database_size_bytes{pg_cluster=\"[[cluster]]\"},dbname)",
"refresh": 1,
"regex": "",
"skipUrlSync": false,
"sort": 1,
"tagValuesQuery": "",
"tags": [],
"tagsQuery": "",
"type": "query",
"useTags": false
},
{
"allValue": ".*",
"current": {},
"datasource": "PROMETHEUS",
"definition": "",
"hide": 0,
"includeAll": true,
"index": -1,
"label": "schemaname",
"multi": true,
"name": "schemaname",
"options": [],
"query": "label_values(ccp_stat_user_tables_n_tup_ins{pg_cluster=\"[[cluster]]\",dbname=~\"[[dbname]]\"},schemaname)",
"refresh": 1,
"regex": "",
"skipUrlSync": false,
"sort": 1,
"tagValuesQuery": "",
"tags": [],
"tagsQuery": "",
"type": "query",
"useTags": false
},
{
"allValue": ".*",
"current": {},
"datasource": "PROMETHEUS",
"definition": "",
"hide": 0,
"includeAll": true,
"index": -1,
"label": null,
"multi": true,
"name": "tablename",
"options": [],
"query": "label_values(ccp_stat_user_tables_n_tup_ins{pg_cluster=\"[[cluster]]\",dbname=~\"[[dbname]]\",schemaname=~\"[[schemaname]]\"},relname)",
"refresh": 1,
"regex": "",
"skipUrlSync": false,
"sort": 1,
"tagValuesQuery": "",
"tags": [],
"tagsQuery": "",
"type": "query",
"useTags": false
}
]
},
"time": {
"from": "now-5m",
"to": "now"
},
"timepicker": {
"refresh_intervals": [
"5s",
"10s",
"30s",
"1m",
"5m",
"15m",
"30m",
"1h",
"2h",
"1d"
],
"time_options": [
"5m",
"15m",
"1h",
"6h",
"12h",
"24h",
"2d",
"7d",
"30d"
]
},
"timezone": "browser",
"title": "CRUD_Details",
"uid": "cruddetails",
"variables": {
"list": []
},
"version": 2
}

View File

@ -0,0 +1,14 @@
kind: Kustomization
apiVersion: kustomize.config.k8s.io/v1beta1
configMapGenerator:
- name: grafana-dashboards
files:
- pgbackrest.json
- pod_details.json
- postgres_overview.json
- postgresql_details.json
- postgresql_service_health.json
- prometheus_alerts.json
- query_statistics.json
generatorOptions:
disableNameSuffixHash: true

View File

@ -0,0 +1,687 @@
{
"__inputs": [
{
"name": "DS_PROMETHEUS",
"label": "PROMETHEUS",
"description": "",
"type": "datasource",
"pluginId": "prometheus",
"pluginName": "Prometheus"
}
],
"__requires": [
{
"type": "grafana",
"id": "grafana",
"name": "Grafana",
"version": "7.4.5"
},
{
"type": "panel",
"id": "graph",
"name": "Graph",
"version": ""
},
{
"type": "datasource",
"id": "prometheus",
"name": "Prometheus",
"version": "1.0.0"
},
{
"type": "panel",
"id": "stat",
"name": "Stat",
"version": ""
}
],
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": "-- Grafana --",
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"editable": false,
"gnetId": null,
"graphTooltip": 0,
"id": null,
"iteration": 1625069660860,
"links": [
{
"asDropdown": false,
"icon": "external link",
"includeVars": true,
"keepTime": true,
"tags": [
"vendor=crunchydata"
],
"title": "",
"type": "dashboards"
}
],
"panels": [
{
"datasource": "PROMETHEUS",
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"custom": {},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "semi-dark-blue",
"value": null
}
]
},
"unit": "dtdhms"
},
"overrides": []
},
"gridPos": {
"h": 3,
"w": 24,
"x": 0,
"y": 0
},
"id": 8,
"options": {
"colorMode": "background",
"graphMode": "area",
"justifyMode": "auto",
"orientation": "auto",
"reduceOptions": {
"calcs": [
"last"
],
"fields": "/^Value$/",
"values": false
},
"text": {
"valueSize": 45
},
"textMode": "auto"
},
"pluginVersion": "7.4.5",
"targets": [
{
"expr": "time()-ccp_backrest_oldest_full_backup_time_seconds{pg_cluster=\"[[cluster]]\", role=\"master\"}",
"format": "table",
"instant": true,
"interval": "",
"legendFormat": "Recovery window",
"refId": "A"
}
],
"title": "Recovery Window",
"type": "stat"
},
{
"aliasColors": {
"Differential": "dark-blue",
"Differential Backup": "dark-blue",
"Full": "dark-green",
"Full Backup": "dark-green",
"Incremental": "light-blue",
"Incremental Backup": "light-blue"
},
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": "PROMETHEUS",
"fieldConfig": {
"defaults": {
"custom": {},
"links": []
},
"overrides": []
},
"fill": 1,
"fillGradient": 0,
"gridPos": {
"h": 7,
"w": 12,
"x": 0,
"y": 3
},
"hiddenSeries": false,
"id": 2,
"legend": {
"alignAsTable": true,
"avg": false,
"current": false,
"max": false,
"min": false,
"rightSide": true,
"show": true,
"sideWidth": 150,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "null",
"options": {
"alertThreshold": false
},
"percentage": false,
"pluginVersion": "7.4.5",
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"expr": "min(ccp_backrest_last_incr_backup_time_since_completion_seconds{pg_cluster=\"[[cluster]]\", role=\"master\"}) without(deployment,instance,ip,pod)",
"format": "time_series",
"instant": false,
"interval": "",
"intervalFactor": 1,
"legendFormat": "Incremental Backup",
"refId": "A"
},
{
"expr": "min(ccp_backrest_last_diff_backup_time_since_completion_seconds{pg_cluster=\"[[cluster]]\", role=\"master\"}) without(deployment, instance,ip,pod)",
"hide": false,
"interval": "",
"legendFormat": "Differential Backup",
"refId": "B"
},
{
"expr": "min(ccp_backrest_last_full_backup_time_since_completion_seconds{pg_cluster=\"[[cluster]]\", role=\"master\"}) without(deployment, instance,ip,pod)",
"hide": false,
"interval": "",
"legendFormat": "Full Backup",
"refId": "C"
},
{
"expr": "min(ccp_archive_command_status_seconds_since_last_archive{pg_cluster=\"[[cluster]]\", role=\"master\"}) without(deployment, instance,ip,pod)",
"hide": false,
"interval": "",
"legendFormat": "WAL Archive",
"refId": "D"
}
],
"thresholds": [],
"timeFrom": null,
"timeRegions": [],
"timeShift": null,
"title": "Time Since",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"buckets": null,
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "s",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": false
}
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {
"Differential": "dark-blue",
"Full": "dark-green",
"Incremental": "light-blue"
},
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": "PROMETHEUS",
"fieldConfig": {
"defaults": {
"custom": {},
"links": []
},
"overrides": []
},
"fill": 1,
"fillGradient": 0,
"gridPos": {
"h": 7,
"w": 12,
"x": 12,
"y": 3
},
"hiddenSeries": false,
"id": 4,
"legend": {
"alignAsTable": true,
"avg": false,
"current": false,
"hideEmpty": false,
"hideZero": false,
"max": false,
"min": false,
"rightSide": true,
"show": true,
"sideWidth": 150,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "null",
"options": {
"alertThreshold": true
},
"percentage": false,
"pluginVersion": "7.4.5",
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"expr": "min(ccp_backrest_last_info_backup_runtime_seconds{pg_cluster=\"[[cluster]]\", role=\"master\", backup_type=\"incr\"}) without (deployment,instance,pod,ip)",
"format": "time_series",
"instant": false,
"interval": "",
"intervalFactor": 1,
"legendFormat": "Incremental",
"refId": "A"
},
{
"expr": "min(ccp_backrest_last_info_backup_runtime_seconds{pg_cluster=\"[[cluster]]\", role=\"master\", backup_type=\"diff\"}) without (deployment,instance,pod,ip)",
"hide": false,
"interval": "",
"legendFormat": "Differential",
"refId": "B"
},
{
"expr": "min(ccp_backrest_last_info_backup_runtime_seconds{pg_cluster=\"[[cluster]]\", role=\"master\", backup_type=\"full\"}) without (deployment,instance,pod,ip)",
"hide": false,
"interval": "",
"legendFormat": "Full",
"refId": "C"
}
],
"thresholds": [],
"timeFrom": null,
"timeRegions": [],
"timeShift": null,
"title": "Backup Runtimes",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"buckets": null,
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "s",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 2,
"max": null,
"min": null,
"show": false
}
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {
"Differential": "dark-blue",
"Full": "dark-green",
"Incremental": "light-blue"
},
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": "PROMETHEUS",
"description": "",
"fieldConfig": {
"defaults": {
"custom": {},
"links": []
},
"overrides": []
},
"fill": 1,
"fillGradient": 0,
"gridPos": {
"h": 7,
"w": 12,
"x": 0,
"y": 10
},
"hiddenSeries": false,
"id": 5,
"legend": {
"alignAsTable": true,
"avg": false,
"current": false,
"hideEmpty": false,
"hideZero": false,
"max": false,
"min": false,
"rightSide": true,
"show": true,
"sideWidth": 150,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "null",
"options": {
"alertThreshold": true
},
"percentage": false,
"pluginVersion": "7.4.5",
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"expr": "min(ccp_backrest_last_info_repo_backup_size_bytes{pg_cluster=\"[[cluster]]\", role=\"master\", backup_type=\"incr\"}) without (deployment, instance,pod,ip)",
"format": "time_series",
"instant": false,
"interval": "",
"intervalFactor": 1,
"legendFormat": "Incremental",
"refId": "A"
},
{
"expr": "min(ccp_backrest_last_info_repo_backup_size_bytes{pg_cluster=\"[[cluster]]\", role=\"master\", backup_type=\"diff\"}) without (deployment,instance,pod,ip)",
"hide": false,
"interval": "",
"legendFormat": "Differential",
"refId": "B"
},
{
"expr": "min(ccp_backrest_last_info_repo_backup_size_bytes{pg_cluster=\"[[cluster]]\", role=\"master\", backup_type=\"full\"}) without (deployment,instance,pod,ip)",
"hide": false,
"interval": "",
"legendFormat": "Full",
"refId": "C"
}
],
"thresholds": [],
"timeFrom": null,
"timeRegions": [],
"timeShift": null,
"title": "Backup Size",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"buckets": null,
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "bytes",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 2,
"max": null,
"min": null,
"show": false
}
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {
"Archive age": "blue",
"Archive count": "green",
"Differential": "dark-blue",
"Failed count": "red",
"Full": "dark-green",
"Incremental": "light-blue"
},
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": "PROMETHEUS",
"description": "",
"fieldConfig": {
"defaults": {
"custom": {},
"links": []
},
"overrides": []
},
"fill": 3,
"fillGradient": 0,
"gridPos": {
"h": 7,
"w": 12,
"x": 12,
"y": 10
},
"hiddenSeries": false,
"id": 6,
"legend": {
"alignAsTable": true,
"avg": false,
"current": false,
"hideEmpty": false,
"hideZero": false,
"max": false,
"min": false,
"rightSide": true,
"show": true,
"sideWidth": 150,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "null",
"options": {
"alertThreshold": true
},
"percentage": false,
"pluginVersion": "7.4.5",
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"expr": "avg(idelta(ccp_archive_command_status_failed_count{pg_cluster=\"[[cluster]]\", role=\"master\"}[1m])) without (instance,ip)",
"format": "time_series",
"instant": false,
"interval": "",
"intervalFactor": 1,
"legendFormat": "Failed count",
"refId": "A"
},
{
"expr": "avg(idelta(ccp_archive_command_status_archived_count{pg_cluster=\"[[cluster]]\", role=\"master\"}[1m])) without (instance,pod, ip)",
"hide": false,
"interval": "",
"legendFormat": "Archive count",
"refId": "B"
}
],
"thresholds": [],
"timeFrom": null,
"timeRegions": [],
"timeShift": null,
"title": "WAL Stats",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"buckets": null,
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"label": "",
"logBase": 1,
"max": null,
"min": "0",
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": "0",
"show": false
}
],
"yaxis": {
"align": false,
"alignLevel": null
}
}
],
"refresh": "5m",
"schemaVersion": 27,
"style": "dark",
"tags": [
"vendor=crunchydata"
],
"templating": {
"list": [
{
"allValue": null,
"current": {},
"datasource": "PROMETHEUS",
"definition": "label_values(pg_cluster)",
"description": null,
"error": null,
"hide": 0,
"includeAll": false,
"label": "cluster",
"multi": false,
"name": "cluster",
"options": [],
"query": {
"query": "label_values(pg_cluster)",
"refId": "PROMETHEUS-cluster-Variable-Query"
},
"refresh": 1,
"regex": "",
"skipUrlSync": false,
"sort": 1,
"tagValuesQuery": "",
"tags": [],
"tagsQuery": "",
"type": "query",
"useTags": false
}
]
},
"time": {
"from": "now-2w",
"to": "now"
},
"timepicker": {
"time_options": [
"5m",
"15m",
"1h",
"6h",
"12h",
"24h",
"2d",
"7d",
"30d"
]
},
"timezone": "browser",
"title": "pgBackRest",
"uid": "2fcFZ6PGk",
"version": 1
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,237 @@
{
"__inputs": [
{
"name": "DS_PROMETHEUS",
"label": "PROMETHEUS",
"description": "",
"type": "datasource",
"pluginId": "prometheus",
"pluginName": "Prometheus"
}
],
"__requires": [
{
"type": "grafana",
"id": "grafana",
"name": "Grafana",
"version": "7.4.5"
},
{
"type": "datasource",
"id": "prometheus",
"name": "Prometheus",
"version": "1.0.0"
},
{
"type": "panel",
"id": "stat",
"name": "Stat",
"version": ""
}
],
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": "-- Grafana --",
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"editable": false,
"gnetId": null,
"graphTooltip": 0,
"id": null,
"iteration": 1625069480601,
"links": [],
"panels": [
{
"cacheTimeout": null,
"datasource": "PROMETHEUS",
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"custom": {},
"links": [
{
"targetBlank": true,
"title": "Cluster Details",
"url": "dashboard/db/postgresqldetails?$__all_variables"
},
{
"targetBlank": true,
"title": "Backup Details",
"url": "dashboard/db/pgbackrest?$__all_variables"
},
{
"targetBlank": true,
"title": "POD Details",
"url": "dashboard/db/pod-details?$__all_variables"
},
{
"targetBlank": true,
"title": "Query Statistics",
"url": "dashboard/db/query-statistics?$__all_variables"
},
{
"targetBlank": true,
"title": "Service Health",
"url": "dashboard/db/postgresql-service-health?$__all_variables"
}
],
"mappings": [
{
"from": "0",
"id": 0,
"text": "DOWN",
"to": "99",
"type": 2
},
{
"from": "100",
"id": 1,
"text": "Standalone Cluster",
"to": "199",
"type": 2
},
{
"from": "200",
"id": 2,
"text": "HA CLUSTER",
"to": "1000",
"type": 2
}
],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "#bf1b00",
"value": null
},
{
"color": "#eab839",
"value": 10
},
{
"color": "#56A64B",
"value": 100
}
]
},
"unit": "short"
},
"overrides": []
},
"gridPos": {
"h": 2,
"w": 12,
"x": 0,
"y": 0
},
"id": 1,
"interval": null,
"links": [],
"maxDataPoints": 100,
"maxPerRow": 2,
"options": {
"colorMode": "background",
"graphMode": "none",
"justifyMode": "auto",
"orientation": "horizontal",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"text": {
"valueSize": 30
},
"textMode": "auto"
},
"pluginVersion": "7.4.5",
"repeat": "cluster",
"repeatDirection": "h",
"targets": [
{
"$hashKey": "object:243",
"expr": "sum(pg_up{pg_cluster=~\"$cluster\"})*100+sum(ccp_is_in_recovery_status{pg_cluster=~\"$cluster\"})",
"format": "time_series",
"interval": "",
"intervalFactor": 1,
"legendFormat": "{{cluster}}",
"metric": "up",
"refId": "A",
"step": 2
}
],
"title": "$cluster - Overview",
"type": "stat"
}
],
"refresh": "5m",
"schemaVersion": 27,
"style": "dark",
"tags": [],
"templating": {
"list": [
{
"allFormat": "glob",
"allValue": null,
"current": {},
"datasource": "PROMETHEUS",
"definition": "label_values(pg_cluster)",
"description": null,
"error": null,
"hide": 1,
"includeAll": true,
"label": "cluster",
"multi": true,
"name": "cluster",
"options": [],
"query": {
"query": "label_values(pg_cluster)",
"refId": "PROMETHEUS-cluster-Variable-Query"
},
"refresh": 1,
"regex": "",
"skipUrlSync": false,
"sort": 0,
"tagValuesQuery": "",
"tags": [],
"tagsQuery": "",
"type": "query",
"useTags": false
}
]
},
"time": {
"from": "now-5m",
"to": "now"
},
"timepicker": {
"time_options": [
"5m",
"15m",
"1h",
"6h",
"12h",
"24h",
"2d",
"7d",
"30d"
]
},
"timezone": "browser",
"title": "PostgreSQL Overview",
"uid": "D2X39SlGk",
"version": 1
}

Some files were not shown because too many files have changed in this diff Show More