feat(charts):完成第一版helm charts

This commit is contained in:
Yu Sun
2022-10-03 19:40:37 +08:00
parent 8b878b603a
commit fbe6bda621
14 changed files with 925 additions and 0 deletions

View File

@@ -0,0 +1,28 @@
# This file and its contents are licensed under the Apache License 2.0.
# Please see the included NOTICE for copyright information and LICENSE for a copy of the license.
TimescaleDB can be accessed via port 5432 on the following DNS name from within your cluster:
{{ template "timescaledb.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local
To get your password for superuser run:
# superuser password
PGPASSWORD_SUPERUSER=$(kubectl get secret --namespace {{ .Release.Namespace }} {{ template "timescaledb.fullname" . }} -o jsonpath="{.data.password-superuser}" | base64 --decode)
# admin password
PGPASSWORD_ADMIN=$(kubectl get secret --namespace {{ .Release.Namespace }} {{ template "timescaledb.fullname" . }} -o jsonpath="{.data.password-admin}" | base64 --decode)
To connect to your database:
1. Run a postgres pod and connect using the psql cli:
# login as superuser
kubectl run -i --tty --rm psql --image=postgres \
--env "PGPASSWORD=$PGPASSWORD_SUPERUSER" \
--command -- psql -U postgres \
-h {{ template "timescaledb.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local postgres
# login as admin
kubectl run -i -tty --rm psql --image=postgres \
--env "PGPASSWORD=$PGPASSWORD_ADMIN" \
--command -- psql -U admin \
-h {{ template "timescaledb.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local postgres

View File

@@ -0,0 +1,60 @@
{{/*
This file and its contents are licensed under the Apache License 2.0.
Please see the included NOTICE for copyright information and LICENSE for a copy of the license.
*/}}
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "timescaledb.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "timescaledb.fullname" -}}
{{- if .Values.fullnameOverride -}}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- if contains $name .Release.Name -}}
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- define "timescaledb.dataname" -}}
{{ template "timescaledb.fullname" . }}-data
{{- end -}}
{{- define "timescaledb.accessname" -}}
{{ template "timescaledb.fullname" . }}-access
{{- end -}}
{{- define "postgres.uid" -}}
{{- default .Values.uid "1000" -}}
{{- end -}}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "timescaledb.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Create the name of the service account to use.
*/}}
{{- define "timescaledb.serviceAccountName" -}}
{{- if .Values.serviceAccount.create -}}
{{ default (include "timescaledb.fullname" .) .Values.serviceAccount.name }}
{{- else -}}
{{ default "default" .Values.serviceAccount.name }}
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,77 @@
# This file and its contents are licensed under the Apache License 2.0.
# Please see the included NOTICE for copyright information and LICENSE for a copy of the license.
{{- range $pod, $e := until ( .Values.dataNodes | int) }}
{{- range $index, $dbname := $.Values.postgresql.databases }}
---
apiVersion: batch/v1
kind: Job
metadata:
name: {{ printf "attachdn-%s-db%s-data%s" $.Release.Name ($index | toString) ($pod | toString) | trunc 63 }}
labels:
app: {{ template "timescaledb.fullname" $ }}
chart: {{ template "timescaledb.chart" $ }}
release: {{ $.Release.Name }}
heritage: {{ $.Release.Service }}
annotations:
"helm.sh/hook-delete-policy": hook-succeeded
spec:
ttlSecondsAfterFinished: 600
template:
metadata:
labels:
app: {{ template "timescaledb.fullname" $ }}
chart: {{ template "timescaledb.chart" $ }}
release: {{ $.Release.Name }}
heritage: {{ $.Release.Service }}
dataNode: {{ template "timescaledb.dataname" $ }}-{{ $pod }}
spec:
containers:
- name: attachdn-{{ $index }}
image: postgres:14.5-alpine # A relatively small official image that can run psql
command:
- sh
- -c
# We wait for the data node to allow connections
# We wait for the access node to allow connections to DBNAME
- >
while ! pg_isready -U postgres -h "${DATA_NODE_DNS}"; do sleep 1; done;
while ! psql -d "${ACCESS_SVC_CONNSTR}" --set dbname="${DBNAME}" --set ON_ERROR_STOP=1 --command '\c :"dbname"'; do sleep 1; done;
echo "${SQLCOMMAND}" | psql -d "${ACCESS_SVC_CONNSTR}" --file=- --echo-queries --set ON_ERROR_STOP=1 \
--set dbname="${DBNAME}" \
--set data_node_name="${DATA_NODE_NAME}" \
--set data_node_dns="${DATA_NODE_DNS}"
env:
{{- /*
Some parameter juggling is required to ensure we don't have SQL injection;
which is not necessarily a major security leak at this stage, but we want
to be able to support database names like 'test db' or, 'CamelCase'.
The template quote function ensures bash will be able to interpret the variable.
The --set dbname= and subsequent :'dbname' psql_variable ensures no SQL injection can occur.
https://www.postgresql.org/docs/current/app-psql.html#APP-PSQL-INTERPOLATION
*/}}
- name: DBNAME
value: {{ $dbname | quote }}
- name: ACCESS_SVC_CONNSTR
value: host={{ template "timescaledb.fullname" $ }} user=postgres connect_timeout=3 sslmode=disable
- name: DATA_NODE_DNS
value: {{ template "timescaledb.dataname" $ }}-{{ $pod }}.{{ template "timescaledb.dataname" $ }}
- name: DATA_NODE_NAME
value: {{ template "timescaledb.dataname" $ }}-{{ $pod }}
- name: SQLCOMMAND
value: |
\c :"dbname"
SELECT *
FROM add_data_node(:'data_node_name'::name, host => :'data_node_dns', if_not_exists => true)
- name: PGPASSWORD
valueFrom:
secretKeyRef:
name: {{ template "timescaledb.accessname" $ }}
key: password-superuser
restartPolicy: OnFailure
backoffLimit: 2
...
{{ end }}
{{ end }}

View File

@@ -0,0 +1,72 @@
# This file and its contents are licensed under the Apache License 2.0.
# Please see the included NOTICE for copyright information and LICENSE for a copy of the license.
{{- range $index, $dbname := .Values.postgresql.databases }}
---
apiVersion: batch/v1
kind: Job
metadata:
name: {{ printf "createdb-%s-db%s" $.Release.Name ($index | toString) | trunc 63 }}
labels:
app: {{ template "timescaledb.fullname" $ }}
chart: {{ template "timescaledb.chart" $ }}
release: {{ $.Release.Name }}
heritage: {{ $.Release.Service }}
annotations:
"helm.sh/hook-delete-policy": hook-succeeded
spec:
ttlSecondsAfterFinished: 600
template:
metadata:
labels:
app: {{ template "timescaledb.fullname" $ }}
chart: {{ template "timescaledb.chart" $ }}
release: {{ $.Release.Name }}
heritage: {{ $.Release.Service }}
spec:
containers:
- name: createdb-{{ $index }}
image: postgres:14.5-alpine # A relatively small official image that can run psql
command:
- sh
- -c
- >
while ! pg_isready -U postgres -h {{ template "timescaledb.fullname" $ }}; do sleep 1; done;
echo "${SQLCOMMAND}" | psql --file=- --echo-queries -d "${ACCESS_SVC_CONNSTR}" \
--set ON_ERROR_STOP=1 \
--set dbname="${DBNAME}"
env:
{{- /*
Some parameter juggling is required to ensure we don't have SQL injection;
which is not necessarily a major security leak at this stage, but we want
to be able to support database names like 'test db' or, 'CamelCase'.
The template quote function ensures bash will be able to interpret the variable.
The --set dbname= and subsequent :'dbname' psql_variable ensures no SQL injection can occur.
https://www.postgresql.org/docs/current/app-psql.html#APP-PSQL-INTERPOLATION
*/}}
- name: DBNAME
value: {{ $dbname | quote }}
- name: ACCESS_SVC_CONNSTR
value: host={{ template "timescaledb.fullname" $ }} user=postgres connect_timeout=3 sslmode=disable
- name: SQLCOMMAND
value: |
SELECT format('CREATE DATABASE %I', :'dbname')
WHERE NOT EXISTS (
SELECT
FROM pg_database
WHERE datname=:'dbname'
)
\gexec
\c :"dbname"
CREATE EXTENSION IF NOT EXISTS timescaledb;
- name: PGPASSWORD
valueFrom:
secretKeyRef:
name: {{ template "timescaledb.accessname" $ }}
key: password-superuser
restartPolicy: OnFailure
backoffLimit: 2
...
{{ end }}

View File

@@ -0,0 +1,31 @@
# This file and its contents are licensed under the Apache License 2.0.
# Please see the included NOTICE for copyright information and LICENSE for a copy of the license.
---
apiVersion: v1
kind: Secret
metadata:
name: {{ template "timescaledb.accessname" . }}
labels:
app: {{ template "timescaledb.fullname" . }}
chart: {{ template "timescaledb.chart" . }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
type: Opaque
data:
password-superuser: {{ .Values.credentials.accessNode.superuser | b64enc }}
...
---
apiVersion: v1
kind: Secret
metadata:
name: {{ template "timescaledb.dataname" . }}
labels:
app: {{ template "timescaledb.fullname" . }}
chart: {{ template "timescaledb.chart" . }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
type: Opaque
data:
password-superuser: {{ .Values.credentials.dataNode.superuser | b64enc }}
...

View File

@@ -0,0 +1,14 @@
# This file and its contents are licensed under the Apache License 2.0.
# Please see the included NOTICE for copyright information and LICENSE for a copy of the license.
{{- if .Values.serviceAccount.create }}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ template "timescaledb.serviceAccountName" . }}
labels:
app: {{ template "timescaledb.fullname" . }}
chart: {{ template "timescaledb.chart" . }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
{{- end }}

View File

@@ -0,0 +1,166 @@
# This file and its contents are licensed under the Apache License 2.0.
# Please see the included NOTICE for copyright information and LICENSE for a copy of the license.
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: {{ template "timescaledb.accessname" . }}
labels:
app: {{ template "timescaledb.fullname" . }}
chart: {{ template "timescaledb.chart" . }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
spec:
serviceName: {{ template "timescaledb.accessname" . }}
replicas: 1
podManagementPolicy: Parallel
selector:
matchLabels:
app: {{ template "timescaledb.fullname" . }}
release: {{ .Release.Name }}
timescaleNodeType: access
template:
metadata:
name: {{ template "timescaledb.accessname" . }}
labels:
app: {{ template "timescaledb.fullname" . }}
release: {{ .Release.Name }}
timescaleNodeType: access
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" }}
initContainers:
- name: initdb
securityContext:
allowPrivilegeEscalation: false
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
env:
- name: POSTGRESQL_CUSTOM_PARAMETERS
value: |
{{- range $key, $value := .Values.postgresql.parameters }}
{{ printf "%s = '%s'" $key ($value | toString) }}
{{- end }}
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: {{ template "timescaledb.accessname" . }}
key: password-superuser
- name: POSTGRES_PASSWORD_DATA_NODE
valueFrom:
secretKeyRef:
name: {{ template "timescaledb.dataname" . }}
key: password-superuser
{{- if .Values.env }}
{{ .Values.env | default list | toYaml | indent 8 }}
{{- end }}
command:
- sh
- '-c'
# By calling the original entrypoint with the first argument being postgres
# we ensure we do everything that is required to init a PostgreSQL instance.
# By supplying --single however, we ensure the postmaster is running in the
# foreground, allowing us to do some more initialization
- |
set -e
install -o postgres -g postgres -m 0700 -d "${PGDATA}"
/docker-entrypoint.sh postgres --single < /dev/null
grep -qxF "include 'postgresql_helm_customizations.conf'" "${PGDATA}/postgresql.conf" \
|| echo "include 'postgresql_helm_customizations.conf'" >> "${PGDATA}/postgresql.conf"
echo "Writing custom PostgreSQL Parameters to ${PGDATA}/postgresql_helm_customizations.conf"
echo "cluster_name = '$(hostname)'" > "${PGDATA}/postgresql_helm_customizations.conf"
echo "${POSTGRESQL_CUSTOM_PARAMETERS}" | sort >> "${PGDATA}/postgresql_helm_customizations.conf"
echo "*:*:*:postgres:${POSTGRES_PASSWORD_DATA_NODE}" > "${PGDATA}/../.pgpass"
chown postgres:postgres "${PGDATA}/../.pgpass" "${PGDATA}/postgresql_helm_customizations.conf"
chmod 0600 "${PGDATA}/../.pgpass"
echo "Adding host all all all md5 in pg_hba.conf"
grep -qxF "host all all all md5" "${PGDATA}/pg_hba.conf" \
|| echo "host all all all md5" >> ${PGDATA}/pg_hba.conf
volumeMounts:
- name: storage-volume
mountPath: "{{ .Values.persistentVolume.mountPath }}"
subPath: "{{ .Values.persistentVolume.subPath }}"
containers:
- name: timescaledb
securityContext:
allowPrivilegeEscalation: false
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
# We start postgres with a fully cleared environment
command:
- sh
- '-c'
- exec env -i PGDATA="${PGDATA}" PATH="${PATH}" /docker-entrypoint.sh postgres
env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
{{- if .Values.env }}
{{ .Values.env | default list | toYaml | indent 8 }}
{{- end }}
ports:
- containerPort: 5432
volumeMounts:
- name: storage-volume
mountPath: "{{ .Values.persistentVolume.mountPath }}"
subPath: "{{ .Values.persistentVolume.subPath }}"
resources:
{{ toYaml .Values.resources | indent 10 }}
# {{- with .Values.nodeSelector }}
# nodeSelector:
nodeSelector:
kubernetes.io/hostname: an
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{ toYaml . | indent 8 }}
{{- end }}
{{- if .Values.schedulerName }}
schedulerName: {{ .Values.schedulerName }}
{{- end }}
{{- if .Values.affinity }}
affinity:
{{ .Values.affinity | toYaml | indent 8 }}
{{- else if .Values.affinityTemplate }}
affinity:
{{ tpl .Values.affinityTemplate . | indent 8 }}
{{- end }}
{{- if not .Values.persistentVolume.enabled }}
- name: storage-volume
emptyDir: {}
{{- end }}
{{- if .Values.persistentVolume.enabled }}
volumeClaimTemplates:
- metadata:
name: storage-volume
annotations:
{{- if .Values.persistentVolume.annotations }}
{{ toYaml .Values.persistentVolume.annotations | indent 8 }}
{{- end }}
labels:
app: {{ template "timescaledb.fullname" . }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
spec:
accessModes:
{{ toYaml .Values.persistentVolume.accessModes | indent 8 }}
resources:
requests:
storage: "{{ .Values.persistentVolume.size }}"
{{- if .Values.persistentVolume.storageClass }}
{{- if (eq "-" .Values.persistentVolume.storageClass) }}
storageClassName: ""
{{- else }}
storageClassName: "{{ .Values.persistentVolume.storageClass }}"
{{- end }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,159 @@
# This file and its contents are licensed under the Apache License 2.0.
# Please see the included NOTICE for copyright information and LICENSE for a copy of the license.
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: {{ template "timescaledb.dataname" . }}
labels:
app: {{ template "timescaledb.fullname" . }}
chart: {{ template "timescaledb.chart" . }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
spec:
serviceName: {{ template "timescaledb.dataname" . }}
replicas: {{ .Values.dataNodes }}
podManagementPolicy: Parallel
selector:
matchLabels:
app: {{ template "timescaledb.fullname" . }}
release: {{ .Release.Name }}
timescaleNodeType: data
template:
metadata:
name: {{ template "timescaledb.dataname" . }}
labels:
app: {{ template "timescaledb.fullname" . }}
release: {{ .Release.Name }}
timescaleNodeType: data
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" }}
initContainers:
- name: initdb
securityContext:
allowPrivilegeEscalation: false
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
env:
- name: POSTGRESQL_CUSTOM_PARAMETERS
value: |
{{- range $key, $value := .Values.postgresql.parameters }}
{{ printf "%s = '%s'" $key ($value | toString) }}
{{- end }}
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: {{ template "timescaledb.dataname" . }}
key: password-superuser
{{- if .Values.env }}
{{ .Values.env | default list | toYaml | indent 8 }}
{{- end }}
command:
- sh
- '-c'
# By calling the original entrypoint with the first argument being postgres
# we ensure we do everything that is required to init a PostgreSQL instance.
# By supplying --single however, we ensure the postmaster is running in the
# foreground, allowing us to do some more initialization
- |
set -e
install -o postgres -g postgres -m 0700 -d "${PGDATA}" "${PGDATA}/../conf.d"
/docker-entrypoint.sh postgres --single < /dev/null
grep -qxF "include 'postgresql_helm_customizations.conf'" "${PGDATA}/postgresql.conf" \
|| echo "include 'postgresql_helm_customizations.conf'" >> "${PGDATA}/postgresql.conf"
echo "Writing custom PostgreSQL Parameters to ${PGDATA}/postgresql_helm_customizations.conf"
echo "cluster_name = '$(hostname)'" > "${PGDATA}/postgresql_helm_customizations.conf"
echo "${POSTGRESQL_CUSTOM_PARAMETERS}" | sort >> "${PGDATA}/postgresql_helm_customizations.conf"
echo "Adding host all all all md5 in pg_hba.conf"
grep -qxF "host all all all md5" "${PGDATA}/pg_hba.conf" \
|| echo "host all all all md5" >> ${PGDATA}/pg_hba.conf
# The TimescaleDB extension should not be available by default, as this interferes with the bootstrapping
# done by the access nodes. Therefore we drop the extensions from template1
echo "DROP EXTENSION timescaledb" | /docker-entrypoint.sh postgres --single -D "${PGDATA}" template1
volumeMounts:
- name: storage-volume
mountPath: "{{ .Values.persistentVolume.mountPath }}"
subPath: "{{ .Values.persistentVolume.subPath }}"
containers:
- name: timescaledb
securityContext:
allowPrivilegeEscalation: false
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
# We start postgres with a fully cleared environment
command:
- sh
- '-c'
- exec env -i PGDATA="${PGDATA}" PATH="${PATH}" /docker-entrypoint.sh postgres
env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
{{- if .Values.env }}
{{ .Values.env | default list | toYaml | indent 8 }}
{{- end }}
ports:
- containerPort: 5432
volumeMounts:
- name: storage-volume
mountPath: "{{ .Values.persistentVolume.mountPath }}"
subPath: "{{ .Values.persistentVolume.subPath }}"
resources:
{{ toYaml .Values.resources | indent 10 }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{ toYaml . | indent 8 }}
{{- end }}
{{- if .Values.schedulerName }}
schedulerName: {{ .Values.schedulerName }}
{{- end }}
{{- if .Values.affinity }}
affinity:
{{ .Values.affinity | toYaml | indent 8 }}
{{- else if .Values.affinityTemplate }}
affinity:
{{ tpl .Values.affinityTemplate . | indent 8 }}
{{- end }}
{{- if not .Values.persistentVolume.enabled }}
- name: storage-volume
emptyDir: {}
{{- end }}
{{- if .Values.persistentVolume.enabled }}
volumeClaimTemplates:
- metadata:
name: storage-volume
annotations:
{{- if .Values.persistentVolume.annotations }}
{{ toYaml .Values.persistentVolume.annotations | indent 8 }}
{{- end }}
labels:
app: {{ template "timescaledb.fullname" . }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
spec:
accessModes:
{{ toYaml .Values.persistentVolume.accessModes | indent 8 }}
resources:
requests:
storage: "{{ .Values.persistentVolume.size }}"
{{- if .Values.persistentVolume.storageClass }}
{{- if (eq "-" .Values.persistentVolume.storageClass) }}
storageClassName: ""
{{- else }}
storageClassName: "{{ .Values.persistentVolume.storageClass }}"
{{- end }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,25 @@
# This file and its contents are licensed under the Apache License 2.0.
# Please see the included NOTICE for copyright information and LICENSE for a copy of the license.
---
apiVersion: v1
kind: Service
metadata:
name: {{ template "timescaledb.fullname" . }}
labels:
app: {{ template "timescaledb.fullname" . }}
chart: {{ template "timescaledb.chart" . }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
annotations:
service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout: "4000"
spec:
type: LoadBalancer
ports:
- name: postgresql
port: 5432
protocol: TCP
selector:
app: {{ template "timescaledb.fullname" . }}
timescaleNodeType: access
...

View File

@@ -0,0 +1,23 @@
# This file and its contents are licensed under the Apache License 2.0.
# Please see the included NOTICE for copyright information and LICENSE for a copy of the license.
---
apiVersion: v1
kind: Service
metadata:
name: {{ template "timescaledb.dataname" . }}
labels:
app: {{ template "timescaledb.fullname" . }}
chart: {{ template "timescaledb.chart" . }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
spec:
clusterIP: None
ports:
- name: postgresql
port: 5432
protocol: TCP
selector:
app: {{ template "timescaledb.fullname" . }}
timescaleNodeType: data
...