Skip to content
This repository has been archived by the owner on Jan 18, 2024. It is now read-only.

Commit

Permalink
charts/timescaledb-single: allow to override pod security context (e.…
Browse files Browse the repository at this point in the history
…g. run as different user)

* fixed running timescaledb container with user id other than 1000
  • Loading branch information
joschiwald committed Mar 11, 2023
1 parent dd4db38 commit 63a3406
Show file tree
Hide file tree
Showing 10 changed files with 80 additions and 21 deletions.
2 changes: 1 addition & 1 deletion charts/timescaledb-single/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
apiVersion: v1
name: timescaledb-single
description: 'TimescaleDB HA Deployment.'
version: 0.33.2
version: 0.34.0
icon: https://cdn.iconscout.com/icon/free/png-256/timescaledb-1958407-1651618.png

# appVersion specifies the version of the software, which can vary wildly,
Expand Down
1 change: 1 addition & 0 deletions charts/timescaledb-single/docs/admin-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ The following table lists the configurable parameters of the TimescaleDB Helm ch
| `pgBouncer.pg_hba` | The `pg_hba` to be used by pgBouncer | A `pg_hba` allowing non-superuser ssl-only connections |
| `pgBouncer.userListSecretName` | If set, a [user authentication file](https://www.pgbouncer.org/config.html#authentication-file-format) to be used by pgBouncer. | `nil` |
| `podManagementPolicy` | Either [`OrderedReady` or `Parallel`](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#pod-management-policies) | `OrderedReady` |
| `podSecurityContext` | Security Context of the timescaledb pod. | `{ fsGroup: 1000, runAsGroup: 1000, runAsNonRoot: true, runAsUser: 1000 }` |
| `podMonitor.enabled` | Enable deployment of podMonitor used with prometheus-operator. | `false` |
| `podMonitor.path` | Path on which prometheus metrics are exposed. | `/metrics` |
| `podMonitor.interval` | Prometheus scrape interval. Lower values increase resolution, higher values reduce prometheus memory consumption. Do not set over 2m. | `10s` |
Expand Down
5 changes: 3 additions & 2 deletions charts/timescaledb-single/scripts/pgbackrest_restore.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ fi
# A missing PGDATA points to Patroni removing a botched PGDATA, or manual
# intervention. In this scenario, we need to recreate the DATA and WALDIRs
# to keep pgBackRest happy
[ -d "${PGDATA}" ] || install -o postgres -g postgres -d -m 0700 "${PGDATA}"
[ -d "${WALDIR}" ] || install -o postgres -g postgres -d -m 0700 "${WALDIR}"
uid="$(id -u)"; gid="$(id -g)"
[ -d "${PGDATA}" ] || install -o $uid -g $gid -d -m 0700 "${PGDATA}"
[ -d "${WALDIR}" ] || install -o $uid -g $gid -d -m 0700 "${WALDIR}"

exec pgbackrest --force --delta --log-level-console=detail restore
2 changes: 2 additions & 0 deletions charts/timescaledb-single/scripts/post_init.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ __SQL__
for tablespace in $POSTGRES_TABLESPACES
do
log "Creating tablespace ${tablespace}"
# FIX ME: PGDATA points to the wrong directory
# "${PGDATA}/tablespaces" should be replaced with {{ include "tablespaces_dir" . }}
tablespacedir="${PGDATA}/tablespaces/${tablespace}/data"
psql -d "$URL" --set tablespace="${tablespace}" --set directory="${tablespacedir}" --set ON_ERROR_STOP=1 <<__SQL__
SET synchronous_commit to 'off';
Expand Down
11 changes: 8 additions & 3 deletions charts/timescaledb-single/scripts/restore_or_initdb.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ log() {
# A missing PGDATA points to Patroni removing a botched PGDATA, or manual
# intervention. In this scenario, we need to recreate the DATA and WALDIRs
# to keep pgBackRest happy
[ -d "${PGDATA}" ] || install -o postgres -g postgres -d -m 0700 "${PGDATA}"
[ -d "${WALDIR}" ] || install -o postgres -g postgres -d -m 0700 "${WALDIR}"
uid="$(id -u)"; gid="$(id -g)"
[ -d "${PGDATA}" ] || install -o $uid -g $gid -d -m 0700 "${PGDATA}"
[ -d "${WALDIR}" ] || install -o $uid -g $gid -d -m 0700 "${WALDIR}"

if [ "${BOOTSTRAP_FROM_BACKUP}" = "1" ]; then
log "Attempting restore from backup"
Expand Down Expand Up @@ -104,7 +105,11 @@ else

log "Invoking initdb"
# shellcheck disable=SC2086
initdb --auth-local=peer --auth-host=md5 --pgdata="${PGDATA}" --waldir="${WALDIR}" ${initdb_args}
initdb --username="$POSTGRES_USER" --auth-local=peer --auth-host=md5 --pgdata="${PGDATA}" --waldir="${WALDIR}" ${initdb_args}
EXITCODE=$?
if [ ${EXITCODE} -ne 0 ]; then
exit $EXITCODE
fi
fi

echo "include_if_exists = '${TSTUNE_FILE}'" >> "${PGDATA}/postgresql.conf"
4 changes: 0 additions & 4 deletions charts/timescaledb-single/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,6 @@ Create the name of the service account to use.
{{- end -}}
{{- end -}}

{{- define "postgres.uid" -}}
{{- default .Values.uid "1000" -}}
{{- end -}}

{{- define "data_directory" -}}
{{ printf "%s/data" .Values.persistentVolumes.data.mountPath }}
{{- end -}}
Expand Down
36 changes: 25 additions & 11 deletions charts/timescaledb-single/templates/statefulset-timescaledb.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,7 @@ spec:
spec:
serviceAccountName: {{ template "timescaledb.serviceAccountName" . }}
securityContext:
# The postgres user inside the TimescaleDB image has uid=1000.
# This configuration ensures the permissions of the mounts are suitable
fsGroup: {{ template "postgres.uid" }}
runAsGroup: {{ template "postgres.uid" }}
runAsNonRoot: true
runAsUser: {{ template "postgres.uid" }}
{{- toYaml .Values.podSecurityContext | nindent 8 }}
initContainers:
{{- if .Values.timescaledbTune.enabled }}
- name: tstune
Expand Down Expand Up @@ -133,10 +128,12 @@ spec:
- "-c"
- |
{{ .Values.debug.execStartPre }}
install -o postgres -g postgres -d -m 0700 {{ include "data_directory" . | quote }} {{ include "wal_directory" . | quote }} || exit 1
TABLESPACES={{ $.Values.persistentVolumes.tablespaces | default dict | keys | join " " | quote }}
for tablespace in {{ $.Values.persistentVolumes.tablespaces | default dict | keys | join " " }}; do
install -o postgres -g postgres -d -m 0700 "{{ include "tablespaces_dir" . }}/${tablespace}/data"
uid="$(id -u)"; gid="$(id -g)"
install -o $uid -g $gid -d -m 0700 {{ include "data_directory" . | quote }} {{ include "wal_directory" . | quote }} || exit 1
: "${POSTGRES_TABLESPACES:=""}"
for tablespace in $POSTGRES_TABLESPACES; do
install -o $uid -g $gid -d -m 0700 "{{ include "tablespaces_dir" . }}/${tablespace}/data"
done
# Environment variables can be read by regular users of PostgreSQL. Especially in a Kubernetes
Expand All @@ -154,7 +151,7 @@ spec:
export -p > "${HOME}/.pod_environment"
export -p | grep PGBACKREST > "${HOME}/.pgbackrest_environment"
for UNKNOWNVAR in $(env | awk -F '=' '!/^(PATRONI_.*|HOME|PGDATA|PGHOST|LC_.*|LANG|PATH|KUBERNETES_SERVICE_.*|AWS_ROLE_ARN|AWS_WEB_IDENTITY_TOKEN_FILE)=/ {print $1}')
for UNKNOWNVAR in $(env | awk -F '=' '!/^(PATRONI_.*|HOME|PGDATA|PGHOST|PGUSER|LC_.*|LANG|PATH|KUBERNETES_SERVICE_.*|AWS_ROLE_ARN|AWS_WEB_IDENTITY_TOKEN_FILE)=/ {print $1}')
do
unset "${UNKNOWNVAR}"
done
Expand All @@ -167,6 +164,11 @@ spec:
export PATRONI_POSTGRESQL_PGPASS="${HOME}/.pgpass.patroni"
# "patroni" does not set the user correctly on connect to postgres and authentication will be rejected
# "initdb" is particular about the current user existing in "/etc/passwd"
# so we use "nss_wrapper" to fake that
. docker-entrypoint.sh && setup_nss_wrapper
exec patroni /etc/timescaledb/patroni.yaml
env:
# We use mixed case environment variables for Patroni User management,
Expand All @@ -178,6 +180,8 @@ spec:
value: "/etc/timescaledb/patroni.yaml"
- name: PATRONI_admin_OPTIONS
value: createrole,createdb
- name: PATRONI_SUPERUSER_USERNAME
value: postgres
- name: PATRONI_REPLICATION_USERNAME
value: standby
# To specify the PostgreSQL and Rest API connect addresses we need
Expand Down Expand Up @@ -223,6 +227,10 @@ spec:
value: "/var/run/postgresql"
- name: WALDIR
value: {{ include "wal_directory" . | quote }}
- name: PGUSER
value: postgres
- name: POSTGRES_USER
value: postgres
- name: BOOTSTRAP_FROM_BACKUP
value: {{ .Values.bootstrapFromBackup.enabled | int | quote }}
{{- if .Values.bootstrapFromBackup.enabled }}
Expand All @@ -233,6 +241,8 @@ spec:
value: {{ .Values.backup.enabled | quote }}
- name: TSTUNE_FILE
value: {{ template "tstune_config" . }}
- name: HOME
value: /home/postgres
{{- if .Values.env }}{{ .Values.env | default list | toYaml | nindent 8 }}{{- end }}
# pgBackRest is also called using the archive_command if the backup is enabled.
# this script will also need access to the environment variables specified for
Expand Down Expand Up @@ -304,6 +314,8 @@ spec:
- mountPath: /etc/certificate
name: certificate
readOnly: true
- name: home
mountPath: /home/postgres
- name: socket-directory
mountPath: /var/run/postgresql
{{ if .Values.callbacks.configMap -}}
Expand Down Expand Up @@ -473,6 +485,8 @@ spec:
{{- .Values.affinity | toYaml | nindent 8 }}
{{- end }}
volumes:
- name: home
emptyDir: {}
- name: socket-directory
emptyDir: {}
- name: patroni-config
Expand Down
19 changes: 19 additions & 0 deletions charts/timescaledb-single/values.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,24 @@
"podMonitor": {
"type": "object"
},
"podSecurityContext": {
"additionalProperties": true,
"properties": {
"fsGroup": {
"type": "integer"
},
"runAsGroup": {
"type": "integer"
},
"runAsNonRoot": {
"type": "boolean"
},
"runAsUser": {
"type": "integer"
}
},
"type": "object"
},
"postInit": {
"description": "postInit allows you to configure additional scripts that will be run once\ndirectly after initialization of the database. It takes a list of VolumeProjection,\nevery .sh, .sql, and .sql.gz script will be executed in sorted order and they should\nreturn exitcode 0 on success.\n",
"items": {
Expand Down Expand Up @@ -826,6 +844,7 @@
"podAnnotations",
"podLabels",
"podManagementPolicy",
"podSecurityContext",
"prometheus",
"rbac",
"readinessProbe",
Expand Down
13 changes: 13 additions & 0 deletions charts/timescaledb-single/values.schema.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ required:
- podAnnotations
- podLabels
- podManagementPolicy
- podSecurityContext
- prometheus
- rbac
- readinessProbe
Expand All @@ -45,6 +46,18 @@ properties:
podManagementPolicy:
type:
- string
podSecurityContext:
type: object
additionalProperties: true
properties:
fsGroup:
type: integer
runAsGroup:
type: integer
runAsNonRoot:
type: boolean
runAsUser:
type: integer
postInit:
description: |
postInit allows you to configure additional scripts that will be run once
Expand Down
8 changes: 8 additions & 0 deletions charts/timescaledb-single/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,14 @@ persistentVolumes:
# size: 5Gi
# storageClass: gp2

podSecurityContext:
# The postgres user inside the TimescaleDB image has uid=1000.
# This configuration ensures the permissions of the mounts are suitable
fsGroup: 1000
runAsGroup: 1000
runAsNonRoot: true
runAsUser: 1000

resources: {}
# If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
Expand Down

0 comments on commit 63a3406

Please sign in to comment.