feat(charts): add OCI chart publishing and runtime charts

This commit is contained in:
Haitao Pan 2026-04-02 15:01:47 +08:00
parent 2183d475a6
commit 446dd16c03
44 changed files with 1911 additions and 0 deletions

View File

@ -0,0 +1,66 @@
name: release-oci-charts
on:
push:
branches:
- main
paths:
- "oci/charts/apps/app-service/**"
- "oci/charts/infra/platform/k3s/**"
- "oci/charts/postgresql/**"
- "oci/charts/observability/**"
- ".github/workflows/release-oci-charts.yml"
workflow_dispatch:
permissions:
contents: read
packages: write
jobs:
publish:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Helm
uses: azure/setup-helm@v4
with:
version: v3.15.4
- name: Login to GHCR
run: echo "${{ secrets.GITHUB_TOKEN }}" | helm registry login ghcr.io -u "${{ github.actor }}" --password-stdin
- name: Lint charts
run: |
set -euo pipefail
charts=(
"oci/charts/apps/app-service"
"oci/charts/infra/platform/k3s"
"oci/charts/postgresql"
"oci/charts/observability"
)
for chart in "${charts[@]}"; do
helm lint "./${chart}"
done
- name: Package charts
run: |
set -euo pipefail
mkdir -p dist
charts=(
"oci/charts/apps/app-service"
"oci/charts/infra/platform/k3s"
"oci/charts/postgresql"
"oci/charts/observability"
)
for chart in "${charts[@]}"; do
helm package "./${chart}" --destination dist
done
- name: Push charts to GHCR
run: |
set -euo pipefail
for pkg in dist/*.tgz; do
helm push "${pkg}" oci://ghcr.io/x-evor/charts
done

16
oci/charts/README.md Normal file
View File

@ -0,0 +1,16 @@
# OCI Charts
This repository stores reusable Helm charts published to `ghcr.io/x-evor/charts`.
## Layout
- `apps/app-service`: reusable runtime chart for application services
- `infra/platform/k3s`: platform composition chart for `caddy`, `apisix`, and `vault`
- `postgresql`: PostgreSQL service chart with optional `stunnel` server/client
- `observability`: observability composition chart for server and agent components
## Release Model
- Registry: `oci://ghcr.io/x-evor/charts`
- Each chart is versioned independently
- Runtime image tags are managed by GitOps values rather than chart versions

View File

@ -0,0 +1,6 @@
apiVersion: v2
name: app-service
description: Reusable chart for core HTTP application services
type: application
version: 0.1.0
appVersion: "1.0.0"

View File

@ -0,0 +1,26 @@
{{- define "app-service.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- define "app-service.fullname" -}}
{{- if .Values.fullnameOverride -}}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- include "app-service.name" . -}}
{{- end -}}
{{- end -}}
{{- define "app-service.labels" -}}
app.kubernetes.io/name: {{ include "app-service.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}
{{- end -}}
{{- define "app-service.serviceAccountName" -}}
{{- if .Values.serviceAccount.create -}}
{{- default (include "app-service.fullname" .) .Values.serviceAccount.name -}}
{{- else -}}
{{- default "default" .Values.serviceAccount.name -}}
{{- end -}}
{{- end -}}

View File

@ -0,0 +1,83 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "app-service.fullname" . }}
labels:
{{- include "app-service.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
revisionHistoryLimit: 3
strategy:
type: {{ .Values.strategy.type }}
rollingUpdate:
maxUnavailable: {{ .Values.strategy.rollingUpdate.maxUnavailable }}
maxSurge: {{ .Values.strategy.rollingUpdate.maxSurge }}
selector:
matchLabels:
app.kubernetes.io/name: {{ include "app-service.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
template:
metadata:
labels:
{{- include "app-service.labels" . | nindent 8 }}
{{- with .Values.podLabels }}
{{- toYaml . | nindent 8 }}
{{- end }}
annotations:
{{- if and .Values.reloader.enabled .Values.existingSecretName }}
secret.reloader.stakater.com/reload: {{ default .Values.existingSecretName .Values.reloader.secretMatch | quote }}
{{- end }}
{{- with .Values.podAnnotations }}
{{- toYaml . | nindent 8 }}
{{- end }}
spec:
serviceAccountName: {{ include "app-service.serviceAccountName" . }}
{{- with .Values.image.pullSecrets }}
imagePullSecrets:
{{- range . }}
- name: {{ . }}
{{- end }}
{{- end }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
containers:
- name: app
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- name: http
containerPort: {{ .Values.containerPort }}
{{- if .Values.env }}
env:
{{- range $key, $value := .Values.env }}
- name: {{ $key }}
value: {{ $value | quote }}
{{- end }}
{{- end }}
{{- if or .Values.existingSecretName .Values.envFromSecretRefs }}
envFrom:
{{- if .Values.existingSecretName }}
- secretRef:
name: {{ .Values.existingSecretName }}
{{- end }}
{{- range .Values.envFromSecretRefs }}
- secretRef:
name: {{ . }}
{{- end }}
{{- end }}
resources:
{{- toYaml .Values.resources | nindent 12 }}
readinessProbe:
{{- toYaml .Values.readinessProbe | nindent 12 }}
livenessProbe:
{{- toYaml .Values.livenessProbe | nindent 12 }}

View File

@ -0,0 +1,35 @@
{{- if .Values.ingress.enabled }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ include "app-service.fullname" . }}
labels:
{{- include "app-service.labels" . | nindent 4 }}
{{- with .Values.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if .Values.ingress.className }}
ingressClassName: {{ .Values.ingress.className }}
{{- end }}
{{- with .Values.ingress.tls }}
tls:
{{- toYaml . | nindent 4 }}
{{- end }}
rules:
{{- range .Values.ingress.hosts }}
- host: {{ .host }}
http:
paths:
{{- range .paths }}
- path: {{ .path }}
pathType: {{ default "Prefix" .pathType }}
backend:
service:
name: {{ include "app-service.fullname" $ }}
port:
number: {{ default $.Values.service.port .servicePort }}
{{- end }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,14 @@
{{- if .Values.pdb.enabled }}
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: {{ include "app-service.fullname" . }}
labels:
{{- include "app-service.labels" . | nindent 4 }}
spec:
minAvailable: {{ .Values.pdb.minAvailable }}
selector:
matchLabels:
app.kubernetes.io/name: {{ include "app-service.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}

View File

@ -0,0 +1,19 @@
apiVersion: v1
kind: Service
metadata:
name: {{ include "app-service.fullname" . }}
labels:
{{- include "app-service.labels" . | nindent 4 }}
{{- with .Values.service.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
type: {{ .Values.service.type }}
selector:
app.kubernetes.io/name: {{ include "app-service.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
ports:
- name: http
port: {{ .Values.service.port }}
targetPort: http

View File

@ -0,0 +1,12 @@
{{- if .Values.serviceAccount.create }}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "app-service.serviceAccountName" . }}
labels:
{{- include "app-service.labels" . | nindent 4 }}
{{- with .Values.serviceAccount.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,76 @@
nameOverride: ""
fullnameOverride: ""
replicaCount: 1
image:
repository: ghcr.io/example/app
tag: latest
pullPolicy: IfNotPresent
pullSecrets: []
containerPort: 8080
service:
port: 80
type: ClusterIP
annotations: {}
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 0
maxSurge: 1
podLabels: {}
podAnnotations: {}
serviceAccount:
create: false
name: ""
annotations: {}
env: {}
existingSecretName: ""
envFromSecretRefs: []
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
readinessProbe:
httpGet:
path: /healthz
port: http
initialDelaySeconds: 10
periodSeconds: 10
livenessProbe:
httpGet:
path: /healthz
port: http
initialDelaySeconds: 30
periodSeconds: 20
pdb:
enabled: true
minAvailable: 1
ingress:
enabled: false
className: ""
annotations: {}
tls: []
hosts: []
nodeSelector: {}
tolerations: []
affinity: {}
reloader:
enabled: true
secretMatch: ""

View File

@ -0,0 +1,6 @@
apiVersion: v2
name: k3s-platform-chart
description: Composes Flux-managed platform components for the k3s platform
type: application
version: 0.1.0
appVersion: "1.0.0"

View File

@ -0,0 +1,26 @@
{{- if .Values.components.apisix.enabled }}
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: {{ .Values.components.apisix.releaseName }}
namespace: {{ .Values.namespaces.platform }}
spec:
interval: 10m0s
releaseName: {{ .Values.components.apisix.releaseName }}
chart:
spec:
chart: {{ .Values.components.apisix.chart.name }}
version: {{ .Values.components.apisix.chart.version | quote }}
sourceRef:
kind: {{ .Values.components.apisix.sourceRef.kind }}
name: {{ .Values.components.apisix.sourceRef.name }}
namespace: {{ .Values.components.apisix.sourceRef.namespace }}
install:
remediation:
retries: 3
upgrade:
remediation:
retries: 3
values:
{{- toYaml .Values.components.apisix.values | nindent 4 }}
{{- end }}

View File

@ -0,0 +1,30 @@
{{- if .Values.apisixIngress.enabled }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ .Values.apisixIngress.name }}
namespace: {{ .Values.apisixIngress.namespace }}
{{- with .Values.apisixIngress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
ingressClassName: {{ .Values.apisixIngress.className }}
tls:
- hosts:
{{- toYaml .Values.apisixIngress.tls.hosts | nindent 8 }}
secretName: {{ .Values.apisixIngress.tls.secretName }}
rules:
{{- range .Values.apisixIngress.hosts }}
- host: {{ .host }}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: {{ .serviceName }}
port:
number: {{ .servicePort }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,27 @@
{{- if .Values.components.caddy.enabled }}
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: {{ .Values.components.caddy.releaseName }}
namespace: {{ .Values.namespaces.platform }}
spec:
interval: 10m0s
releaseName: {{ .Values.components.caddy.releaseName }}
chart:
spec:
chart: {{ .Values.components.caddy.chart.name }}
version: {{ .Values.components.caddy.chart.version | quote }}
sourceRef:
kind: {{ .Values.components.caddy.sourceRef.kind }}
name: {{ .Values.components.caddy.sourceRef.name }}
namespace: {{ .Values.components.caddy.sourceRef.namespace }}
install:
createNamespace: false
remediation:
retries: 3
upgrade:
remediation:
retries: 3
values:
{{- toYaml .Values.components.caddy.values | nindent 4 }}
{{- end }}

View File

@ -0,0 +1,4 @@
{{- range .Values.extraObjects }}
---
{{ toYaml . }}
{{- end }}

View File

@ -0,0 +1,75 @@
{{- if .Values.vaultBootstrap.enabled }}
apiVersion: batch/v1
kind: Job
metadata:
name: vault-bootstrap
namespace: {{ .Values.namespaces.vault }}
spec:
template:
spec:
serviceAccountName: {{ .Values.vaultBootstrap.serviceAccountName }}
restartPolicy: OnFailure
containers:
- name: bootstrap
image: {{ .Values.vaultBootstrap.image }}
env:
- name: VAULT_ADDR
value: http://vault.{{ .Values.namespaces.vault }}.svc.cluster.local:8200
- name: VAULT_TOKEN
valueFrom:
secretKeyRef:
name: {{ .Values.vaultBootstrap.rootTokenSecretName }}
key: {{ .Values.vaultBootstrap.rootTokenSecretKey }}
- name: CLOUDFLARE_API_TOKEN
valueFrom:
secretKeyRef:
name: {{ .Values.vaultBootstrap.cloudflareSecretName }}
key: {{ .Values.vaultBootstrap.cloudflareSecretKey }}
command:
- /bin/sh
- -ec
- |
until vault status >/dev/null 2>&1; do
sleep 5
done
vault secrets enable -path=secret kv-v2 || true
cat <<'EOF' >/tmp/eso-policy.hcl
path "secret/data/*" {
capabilities = ["read"]
}
path "secret/metadata/*" {
capabilities = ["read", "list"]
}
EOF
vault policy write eso-read /tmp/eso-policy.hcl
vault auth enable kubernetes || true
vault write auth/kubernetes/config \
kubernetes_host="https://kubernetes.default.svc:443" \
kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt \
token_reviewer_jwt="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)"
vault write auth/kubernetes/role/external-secrets \
bound_service_account_names="external-secrets" \
bound_service_account_namespaces="{{ .Values.vaultBootstrap.externalSecretsRoleNamespace }}" \
policies="eso-read" \
ttl="1h"
vault kv put secret/platform/cloudflare api-token="${CLOUDFLARE_API_TOKEN}"
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ .Values.vaultBootstrap.serviceAccountName }}
namespace: {{ .Values.namespaces.vault }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: vault-bootstrap-auth-delegator
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:auth-delegator
subjects:
- kind: ServiceAccount
name: {{ .Values.vaultBootstrap.serviceAccountName }}
namespace: {{ .Values.namespaces.vault }}
{{- end }}

View File

@ -0,0 +1,26 @@
{{- if .Values.components.vault.enabled }}
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: {{ .Values.components.vault.releaseName }}
namespace: {{ .Values.namespaces.vault }}
spec:
interval: 10m0s
releaseName: {{ .Values.components.vault.releaseName }}
chart:
spec:
chart: {{ .Values.components.vault.chart.name }}
version: {{ .Values.components.vault.chart.version | quote }}
sourceRef:
kind: {{ .Values.components.vault.sourceRef.kind }}
name: {{ .Values.components.vault.sourceRef.name }}
namespace: {{ .Values.components.vault.sourceRef.namespace }}
install:
remediation:
retries: 3
upgrade:
remediation:
retries: 3
values:
{{- toYaml .Values.components.vault.values | nindent 4 }}
{{- end }}

View File

@ -0,0 +1,111 @@
namespaces:
platform: platform
vault: extsvc
components:
caddy:
enabled: true
releaseName: caddy
sourceRef:
kind: HelmRepository
name: caddy-ingress
namespace: flux-system
chart:
name: caddy-ingress-controller
version: ">=1.0.0 <2.0.0"
values:
ingressController:
enabled: true
ingressClass:
create: true
name: caddy
default: false
service:
type: LoadBalancer
apisix:
enabled: true
releaseName: apisix
sourceRef:
kind: HelmRepository
name: apisix
namespace: flux-system
chart:
name: apisix
version: ">=2.7.0 <3.0.0"
values:
etcd:
enabled: false
ingress-controller:
enabled: false
dashboard:
enabled: false
gateway:
type: ClusterIP
apisix:
deployment:
role: traditional
roleTraditional:
configProvider: yaml
standalone:
enabled: true
admin:
enabled: false
vault:
enabled: true
releaseName: vault
sourceRef:
kind: HelmRepository
name: hashicorp
namespace: flux-system
chart:
name: vault
version: ">=0.28.0 <1.0.0"
values:
injector:
enabled: false
server:
standalone:
enabled: false
dataStorage:
enabled: true
size: 8Gi
ha:
enabled: true
replicas: 1
raft:
enabled: true
setNodeId: true
service:
enabled: true
apisixIngress:
enabled: true
name: apisix-gateway
namespace: platform
className: caddy
annotations:
external-dns.alpha.kubernetes.io/hostname: api.svc.plus,api-pre.svc.plus
tls:
secretName: apisix-gateway-tls
hosts:
- api.svc.plus
- api-pre.svc.plus
hosts:
- host: api.svc.plus
serviceName: apisix-gateway
servicePort: 80
- host: api-pre.svc.plus
serviceName: apisix-gateway
servicePort: 80
vaultBootstrap:
enabled: true
image: hashicorp/vault:1.16.3
serviceAccountName: vault-bootstrap
cloudflareSecretName: vault-bootstrap
cloudflareSecretKey: cloudflareApiToken
rootTokenSecretName: vault-bootstrap
rootTokenSecretKey: rootToken
externalSecretsRoleNamespace: platform
extraObjects: []

View File

@ -0,0 +1,18 @@
apiVersion: v2
name: observability
description: Observability composition chart for server and agent components
type: application
version: 0.1.0
appVersion: "1.0.0"
keywords:
- observability
- prometheus
- victoria
- grafana
- otel
home: https://github.com/cloud-neutral-toolkit/observability.svc.plus
sources:
- https://github.com/cloud-neutral-toolkit/observability.svc.plus
maintainers:
- name: Cloud-Neutral Toolkit
email: admin@svc.plus

View File

@ -0,0 +1,4 @@
{{- range .Values.extraObjects }}
---
{{ toYaml . }}
{{- end }}

View File

@ -0,0 +1,26 @@
{{- if .Values.server.grafana.enabled }}
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: {{ .Values.server.grafana.releaseName }}
namespace: {{ .Values.namespaces.observability }}
spec:
interval: 10m0s
releaseName: {{ .Values.server.grafana.releaseName }}
chart:
spec:
chart: {{ .Values.server.grafana.chart.name }}
version: {{ .Values.server.grafana.chart.version | quote }}
sourceRef:
kind: {{ .Values.server.grafana.sourceRef.kind }}
name: {{ .Values.server.grafana.sourceRef.name }}
namespace: {{ .Values.server.grafana.sourceRef.namespace }}
install:
remediation:
retries: 3
upgrade:
remediation:
retries: 3
values:
{{- toYaml .Values.server.grafana.values | nindent 4 }}
{{- end }}

View File

@ -0,0 +1,26 @@
{{- if .Values.agent.nodeExporter.enabled }}
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: {{ .Values.agent.nodeExporter.releaseName }}
namespace: {{ .Values.namespaces.observability }}
spec:
interval: 10m0s
releaseName: {{ .Values.agent.nodeExporter.releaseName }}
chart:
spec:
chart: {{ .Values.agent.nodeExporter.chart.name }}
version: {{ .Values.agent.nodeExporter.chart.version | quote }}
sourceRef:
kind: {{ .Values.agent.nodeExporter.sourceRef.kind }}
name: {{ .Values.agent.nodeExporter.sourceRef.name }}
namespace: {{ .Values.agent.nodeExporter.sourceRef.namespace }}
install:
remediation:
retries: 3
upgrade:
remediation:
retries: 3
values:
{{- toYaml .Values.agent.nodeExporter.values | nindent 4 }}
{{- end }}

View File

@ -0,0 +1,26 @@
{{- if .Values.server.otelConnector.enabled }}
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: {{ .Values.server.otelConnector.releaseName }}
namespace: {{ .Values.namespaces.observability }}
spec:
interval: 10m0s
releaseName: {{ .Values.server.otelConnector.releaseName }}
chart:
spec:
chart: {{ .Values.server.otelConnector.chart.name }}
version: {{ .Values.server.otelConnector.chart.version | quote }}
sourceRef:
kind: {{ .Values.server.otelConnector.sourceRef.kind }}
name: {{ .Values.server.otelConnector.sourceRef.name }}
namespace: {{ .Values.server.otelConnector.sourceRef.namespace }}
install:
remediation:
retries: 3
upgrade:
remediation:
retries: 3
values:
{{- toYaml .Values.server.otelConnector.values | nindent 4 }}
{{- end }}

View File

@ -0,0 +1,65 @@
{{- if .Values.agent.processExporter.enabled }}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ .Values.agent.processExporter.serviceAccountName }}
namespace: {{ .Values.namespaces.observability }}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: process-exporter-config
namespace: {{ .Values.namespaces.observability }}
data:
config.yaml: |
{{- .Values.agent.processExporter.config | nindent 4 }}
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: process-exporter
namespace: {{ .Values.namespaces.observability }}
spec:
selector:
matchLabels:
app.kubernetes.io/name: process-exporter
template:
metadata:
labels:
app.kubernetes.io/name: process-exporter
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "{{ .Values.agent.processExporter.port }}"
spec:
serviceAccountName: {{ .Values.agent.processExporter.serviceAccountName }}
hostPID: true
containers:
- name: process-exporter
image: "{{ .Values.agent.processExporter.image.repository }}:{{ .Values.agent.processExporter.image.tag }}"
imagePullPolicy: {{ .Values.agent.processExporter.image.pullPolicy }}
args:
- --procfs
- /host/proc
- --config.path
- /etc/process-exporter/config.yaml
- --web.listen-address=:{{ .Values.agent.processExporter.port }}
ports:
- name: metrics
containerPort: {{ .Values.agent.processExporter.port }}
protocol: TCP
resources:
{{- toYaml .Values.agent.processExporter.resources | nindent 12 }}
volumeMounts:
- name: config
mountPath: /etc/process-exporter
- name: proc
mountPath: /host/proc
readOnly: true
volumes:
- name: config
configMap:
name: process-exporter-config
- name: proc
hostPath:
path: /proc
{{- end }}

View File

@ -0,0 +1,26 @@
{{- if .Values.server.prometheus.enabled }}
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: {{ .Values.server.prometheus.releaseName }}
namespace: {{ .Values.namespaces.observability }}
spec:
interval: 10m0s
releaseName: {{ .Values.server.prometheus.releaseName }}
chart:
spec:
chart: {{ .Values.server.prometheus.chart.name }}
version: {{ .Values.server.prometheus.chart.version | quote }}
sourceRef:
kind: {{ .Values.server.prometheus.sourceRef.kind }}
name: {{ .Values.server.prometheus.sourceRef.name }}
namespace: {{ .Values.server.prometheus.sourceRef.namespace }}
install:
remediation:
retries: 3
upgrade:
remediation:
retries: 3
values:
{{- toYaml .Values.server.prometheus.values | nindent 4 }}
{{- end }}

View File

@ -0,0 +1,58 @@
{{- if .Values.agent.vector.enabled }}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ .Values.agent.vector.serviceAccountName }}
namespace: {{ .Values.namespaces.observability }}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: vector-agent-config
namespace: {{ .Values.namespaces.observability }}
data:
vector.yaml: |
{{- .Values.agent.vector.config | nindent 4 }}
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: vector-agent
namespace: {{ .Values.namespaces.observability }}
spec:
selector:
matchLabels:
app.kubernetes.io/name: vector-agent
template:
metadata:
labels:
app.kubernetes.io/name: vector-agent
spec:
serviceAccountName: {{ .Values.agent.vector.serviceAccountName }}
containers:
- name: vector
image: "{{ .Values.agent.vector.image.repository }}:{{ .Values.agent.vector.image.tag }}"
imagePullPolicy: {{ .Values.agent.vector.image.pullPolicy }}
resources:
{{- toYaml .Values.agent.vector.resources | nindent 12 }}
volumeMounts:
- name: config
mountPath: /etc/vector
- name: var-log
mountPath: /var/log
readOnly: true
- name: machine-id
mountPath: /etc/machine-id
readOnly: true
volumes:
- name: config
configMap:
name: vector-agent-config
- name: var-log
hostPath:
path: /var/log
- name: machine-id
hostPath:
path: /etc/machine-id
type: File
{{- end }}

View File

@ -0,0 +1,26 @@
{{- if .Values.server.victoriaLogs.enabled }}
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: {{ .Values.server.victoriaLogs.releaseName }}
namespace: {{ .Values.namespaces.observability }}
spec:
interval: 10m0s
releaseName: {{ .Values.server.victoriaLogs.releaseName }}
chart:
spec:
chart: {{ .Values.server.victoriaLogs.chart.name }}
version: {{ .Values.server.victoriaLogs.chart.version | quote }}
sourceRef:
kind: {{ .Values.server.victoriaLogs.sourceRef.kind }}
name: {{ .Values.server.victoriaLogs.sourceRef.name }}
namespace: {{ .Values.server.victoriaLogs.sourceRef.namespace }}
install:
remediation:
retries: 3
upgrade:
remediation:
retries: 3
values:
{{- toYaml .Values.server.victoriaLogs.values | nindent 4 }}
{{- end }}

View File

@ -0,0 +1,26 @@
{{- if .Values.server.victoriaMetrics.enabled }}
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: {{ .Values.server.victoriaMetrics.releaseName }}
namespace: {{ .Values.namespaces.observability }}
spec:
interval: 10m0s
releaseName: {{ .Values.server.victoriaMetrics.releaseName }}
chart:
spec:
chart: {{ .Values.server.victoriaMetrics.chart.name }}
version: {{ .Values.server.victoriaMetrics.chart.version | quote }}
sourceRef:
kind: {{ .Values.server.victoriaMetrics.sourceRef.kind }}
name: {{ .Values.server.victoriaMetrics.sourceRef.name }}
namespace: {{ .Values.server.victoriaMetrics.sourceRef.namespace }}
install:
remediation:
retries: 3
upgrade:
remediation:
retries: 3
values:
{{- toYaml .Values.server.victoriaMetrics.values | nindent 4 }}
{{- end }}

View File

@ -0,0 +1,26 @@
{{- if .Values.server.victoriaTraces.enabled }}
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: {{ .Values.server.victoriaTraces.releaseName }}
namespace: {{ .Values.namespaces.observability }}
spec:
interval: 10m0s
releaseName: {{ .Values.server.victoriaTraces.releaseName }}
chart:
spec:
chart: {{ .Values.server.victoriaTraces.chart.name }}
version: {{ .Values.server.victoriaTraces.chart.version | quote }}
sourceRef:
kind: {{ .Values.server.victoriaTraces.sourceRef.kind }}
name: {{ .Values.server.victoriaTraces.sourceRef.name }}
namespace: {{ .Values.server.victoriaTraces.sourceRef.namespace }}
install:
remediation:
retries: 3
upgrade:
remediation:
retries: 3
values:
{{- toYaml .Values.server.victoriaTraces.values | nindent 4 }}
{{- end }}

View File

@ -0,0 +1,183 @@
namespaces:
observability: observability
server:
prometheus:
enabled: true
releaseName: prometheus
sourceRef:
kind: HelmRepository
name: prometheus-community
namespace: flux-system
chart:
name: prometheus
version: ">=25.0.0 <26.0.0"
values:
server:
persistentVolume:
enabled: true
size: 20Gi
victoriaMetrics:
enabled: true
releaseName: victoria-metrics
sourceRef:
kind: HelmRepository
name: victoria-metrics
namespace: flux-system
chart:
name: victoria-metrics-single
version: ">=0.13.0 <1.0.0"
values:
server:
persistentVolume:
enabled: true
size: 50Gi
victoriaLogs:
enabled: true
releaseName: victoria-logs
sourceRef:
kind: HelmRepository
name: victoria-metrics
namespace: flux-system
chart:
name: victoria-logs-single
version: ">=0.9.0 <1.0.0"
values:
server:
persistentVolume:
enabled: true
size: 50Gi
victoriaTraces:
enabled: true
releaseName: victoria-traces
sourceRef:
kind: HelmRepository
name: victoria-metrics
namespace: flux-system
chart:
name: victoria-traces-single
version: ">=0.0.1 <1.0.0"
values: {}
grafana:
enabled: true
releaseName: grafana
sourceRef:
kind: HelmRepository
name: grafana
namespace: flux-system
chart:
name: grafana
version: ">=8.0.0 <9.0.0"
values:
persistence:
enabled: true
size: 10Gi
otelConnector:
enabled: true
releaseName: otel-connector
sourceRef:
kind: HelmRepository
name: open-telemetry
namespace: flux-system
chart:
name: opentelemetry-collector
version: ">=0.104.0 <1.0.0"
values:
mode: deployment
config:
receivers:
otlp:
protocols:
grpc: {}
http: {}
processors:
batch: {}
exporters:
debug: {}
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch]
exporters: [debug]
metrics:
receivers: [otlp]
processors: [batch]
exporters: [debug]
logs:
receivers: [otlp]
processors: [batch]
exporters: [debug]
agent:
nodeExporter:
enabled: true
releaseName: node-exporter
sourceRef:
kind: HelmRepository
name: prometheus-community
namespace: flux-system
chart:
name: prometheus-node-exporter
version: ">=4.30.0 <5.0.0"
values: {}
vector:
enabled: true
image:
repository: timberio/vector
tag: "0.36.0-distroless-libc"
pullPolicy: IfNotPresent
serviceAccountName: vector-agent
vlogsEndpoint: http://victoria-logs-victoria-logs-single-server.observability.svc.cluster.local:9428
config: |
data_dir: /vector-data-dir
sources:
journald:
type: journald
transforms:
normalize:
type: remap
inputs: ["journald"]
source: |
.cluster = "k3s"
.origin = "vector-agent"
sinks:
vlogs:
type: elasticsearch
inputs: ["normalize"]
endpoints:
- http://victoria-logs-victoria-logs-single-server.observability.svc.cluster.local:9428/insert/elasticsearch/
mode: bulk
compression: gzip
resources:
limits:
cpu: 300m
memory: 512Mi
requests:
cpu: 100m
memory: 128Mi
processExporter:
enabled: true
image:
repository: ncabatoff/process-exporter
tag: v0.8.3
pullPolicy: IfNotPresent
serviceAccountName: process-exporter
port: 9256
config: |
process_names:
- name: "{{.Comm}}"
cmdline:
- '.+'
resources:
limits:
cpu: 100m
memory: 128Mi
requests:
cpu: 25m
memory: 64Mi
extraObjects: []

View File

@ -0,0 +1,19 @@
apiVersion: v2
name: postgresql
description: PostgreSQL service chart with optional stunnel server and client for cloud-neutral deployments
type: application
version: 1.1.0
appVersion: "16.4"
keywords:
- postgresql
- database
- vector
- search
- queue
home: https://github.com/cloud-neutral-toolkit/postgresql.svc.plus
sources:
- https://github.com/cloud-neutral-toolkit/postgresql.svc.plus
maintainers:
- name: Cloud-Neutral Toolkit
email: admin@svc.plus
icon: https://www.postgresql.org/media/img/about/press/elephant.png

View File

@ -0,0 +1,82 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "postgresql.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Create a default fully qualified app name.
*/}}
{{- define "postgresql.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 }}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "postgresql.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "postgresql.labels" -}}
helm.sh/chart: {{ include "postgresql.chart" . }}
{{ include "postgresql.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "postgresql.selectorLabels" -}}
app.kubernetes.io/name: {{ include "postgresql.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{/*
Create the name of the service account to use
*/}}
{{- define "postgresql.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "postgresql.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}
{{/*
Get the password secret name
*/}}
{{- define "postgresql.secretName" -}}
{{- if .Values.auth.existingSecret -}}
{{- .Values.auth.existingSecret -}}
{{- else -}}
{{- include "postgresql.fullname" . -}}
{{- end -}}
{{- end -}}
{{/*
Get the password key
*/}}
{{- define "postgresql.secretKey" -}}
{{- if .Values.auth.existingSecret -}}
{{- .Values.auth.secretKey -}}
{{- else -}}
password
{{- end -}}
{{- end -}}

View File

@ -0,0 +1,13 @@
{{- if and .Values.server.enabled .Values.initScripts.enabled }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "postgresql.fullname" . }}-init-scripts
labels:
{{- include "postgresql.labels" . | nindent 4 }}
data:
{{- range $key, $value := .Values.initScripts.scripts }}
{{ $key }}: |
{{- $value | nindent 4 }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,11 @@
{{- if and .Values.server.enabled .Values.stunnel.enabled }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "postgresql.fullname" . }}-stunnel-config
labels:
{{- include "postgresql.labels" . | nindent 4 }}
data:
stunnel.conf: |
{{- .Values.stunnel.config | nindent 4 }}
{{- end }}

View File

@ -0,0 +1,25 @@
{{- if .Values.server.enabled }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "postgresql.fullname" . }}-config
labels:
{{- include "postgresql.labels" . | nindent 4 }}
data:
postgresql.conf: |
{{- .Values.postgresql.config | nindent 4 }}
{{- if .Values.postgresql.pgHba }}
pg_hba.conf: |
# TYPE DATABASE USER ADDRESS METHOD
# Default entries
local all all trust
host all all 127.0.0.1/32 trust
host all all ::1/128 trust
host all all 0.0.0.0/0 md5
host all all ::/0 md5
# Custom entries
{{- .Values.postgresql.pgHba | nindent 4 }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,11 @@
{{- if and .Values.server.enabled (not .Values.auth.existingSecret) }}
apiVersion: v1
kind: Secret
metadata:
name: {{ include "postgresql.fullname" . }}
labels:
{{- include "postgresql.labels" . | nindent 4 }}
type: Opaque
data:
password: {{ .Values.auth.password | b64enc | quote }}
{{- end }}

View File

@ -0,0 +1,21 @@
{{- if and .Values.server.enabled .Values.metrics.enabled }}
apiVersion: v1
kind: Service
metadata:
name: {{ include "postgresql.fullname" . }}-metrics
labels:
{{- include "postgresql.labels" . | nindent 4 }}
{{- with .Values.metrics.service.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
type: {{ .Values.metrics.service.type }}
ports:
- port: {{ .Values.metrics.service.port }}
targetPort: metrics
protocol: TCP
name: metrics
selector:
{{- include "postgresql.selectorLabels" . | nindent 4 }}
{{- end }}

View File

@ -0,0 +1,27 @@
{{- if .Values.server.enabled }}
apiVersion: v1
kind: Service
metadata:
name: {{ include "postgresql.fullname" . }}
labels:
{{- include "postgresql.labels" . | nindent 4 }}
{{- with .Values.service.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: postgres
protocol: TCP
name: postgres
{{- if .Values.stunnel.enabled }}
- port: {{ .Values.stunnel.port }}
targetPort: stunnel
protocol: TCP
name: stunnel
{{- end }}
selector:
{{- include "postgresql.selectorLabels" . | nindent 4 }}
{{- end }}

View File

@ -0,0 +1,12 @@
{{- if and .Values.server.enabled .Values.serviceAccount.create -}}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "postgresql.serviceAccountName" . }}
labels:
{{- include "postgresql.labels" . | nindent 4 }}
{{- with .Values.serviceAccount.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,203 @@
{{- if .Values.server.enabled }}
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: {{ include "postgresql.fullname" . }}
labels:
{{- include "postgresql.labels" . | nindent 4 }}
spec:
serviceName: {{ include "postgresql.fullname" . }}
replicas: 1
selector:
matchLabels:
{{- include "postgresql.selectorLabels" . | nindent 6 }}
template:
metadata:
annotations:
checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }}
{{- with .Values.podAnnotations }}
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "postgresql.selectorLabels" . | nindent 8 }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ include "postgresql.serviceAccountName" . }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: postgresql
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- name: postgres
containerPort: 5432
protocol: TCP
env:
- name: POSTGRES_USER
value: {{ .Values.auth.username | quote }}
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: {{ include "postgresql.secretName" . }}
key: {{ include "postgresql.secretKey" . }}
- name: POSTGRES_DB
value: {{ .Values.auth.database | quote }}
- name: PGDATA
value: /var/lib/postgresql/data/pgdata
{{- if .Values.livenessProbe.enabled }}
livenessProbe:
exec:
command:
- /bin/sh
- -c
- pg_isready -U {{ .Values.auth.username }}
initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }}
periodSeconds: {{ .Values.livenessProbe.periodSeconds }}
timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }}
failureThreshold: {{ .Values.livenessProbe.failureThreshold }}
successThreshold: {{ .Values.livenessProbe.successThreshold }}
{{- end }}
{{- if .Values.readinessProbe.enabled }}
readinessProbe:
exec:
command:
- /bin/sh
- -c
- pg_isready -U {{ .Values.auth.username }}
initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }}
periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }}
failureThreshold: {{ .Values.readinessProbe.failureThreshold }}
successThreshold: {{ .Values.readinessProbe.successThreshold }}
{{- end }}
resources:
{{- toYaml .Values.resources | nindent 12 }}
volumeMounts:
- name: data
mountPath: /var/lib/postgresql/data
- name: config
mountPath: /etc/postgresql
{{- if .Values.initScripts.enabled }}
- name: init-scripts
mountPath: /docker-entrypoint-initdb.d
{{- end }}
{{- if .Values.tls.enabled }}
- name: tls-certs
mountPath: /etc/postgresql/certs
readOnly: true
{{- end }}
{{- if .Values.stunnel.enabled }}
- name: stunnel
image: "{{ .Values.stunnel.image.repository }}:{{ .Values.stunnel.image.tag }}"
imagePullPolicy: {{ .Values.stunnel.image.pullPolicy }}
ports:
- name: stunnel
containerPort: {{ .Values.stunnel.port }}
protocol: TCP
volumeMounts:
- name: stunnel-config
mountPath: /etc/stunnel/stunnel.conf
subPath: stunnel.conf
{{- if .Values.stunnel.certificatesSecret }}
- name: stunnel-certs
mountPath: /etc/stunnel/certs
readOnly: true
{{- end }}
{{- end }}
{{- if .Values.metrics.enabled }}
- name: metrics
image: "{{ .Values.metrics.image.repository }}:{{ .Values.metrics.image.tag }}"
imagePullPolicy: {{ .Values.metrics.image.pullPolicy }}
ports:
- name: metrics
containerPort: 9187
protocol: TCP
env:
- name: DATA_SOURCE_NAME
value: "postgresql://{{ .Values.auth.username }}:$(POSTGRES_PASSWORD)@localhost:5432/{{ .Values.auth.database }}?sslmode=disable"
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: {{ include "postgresql.secretName" . }}
key: {{ include "postgresql.secretKey" . }}
resources:
{{- toYaml .Values.metrics.resources | nindent 12 }}
{{- end }}
volumes:
- name: config
configMap:
name: {{ include "postgresql.fullname" . }}-config
{{- if .Values.initScripts.enabled }}
- name: init-scripts
configMap:
name: {{ include "postgresql.fullname" . }}-init-scripts
{{- end }}
{{- if .Values.tls.enabled }}
- name: tls-certs
secret:
secretName: {{ .Values.tls.certificatesSecret }}
defaultMode: 0600
{{- end }}
{{- if .Values.stunnel.enabled }}
- name: stunnel-config
configMap:
name: {{ include "postgresql.fullname" . }}-stunnel-config
{{- if .Values.stunnel.certificatesSecret }}
- name: stunnel-certs
secret:
secretName: {{ .Values.stunnel.certificatesSecret }}
defaultMode: 0600
{{- end }}
{{- end }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- if .Values.persistence.enabled }}
volumeClaimTemplates:
- metadata:
name: data
{{- with .Values.persistence.annotations }}
annotations:
{{- toYaml . | nindent 10 }}
{{- end }}
spec:
accessModes:
{{- range .Values.persistence.accessModes }}
- {{ . | quote }}
{{- end }}
{{- if .Values.persistence.storageClass }}
storageClassName: {{ .Values.persistence.storageClass | quote }}
{{- end }}
resources:
requests:
storage: {{ .Values.persistence.size | quote }}
{{- with .Values.persistence.selector }}
selector:
{{- toYaml . | nindent 10 }}
{{- end }}
{{- else }}
- name: data
emptyDir: {}
{{- end }}
{{- end }}

View File

@ -0,0 +1,11 @@
{{- if .Values.stunnelClient.enabled }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "postgresql.fullname" . }}-stunnel-client
labels:
{{- include "postgresql.labels" . | nindent 4 }}
data:
stunnel.conf: |
{{- .Values.stunnelClient.config | nindent 4 }}
{{- end }}

View File

@ -0,0 +1,40 @@
{{- if .Values.stunnelClient.enabled }}
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "postgresql.fullname" . }}-stunnel-client
labels:
{{- include "postgresql.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.stunnelClient.replicaCount }}
selector:
matchLabels:
app.kubernetes.io/name: {{ include "postgresql.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/component: stunnel-client
template:
metadata:
labels:
app.kubernetes.io/name: {{ include "postgresql.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/component: stunnel-client
spec:
containers:
- name: stunnel-client
image: "{{ .Values.stunnelClient.image.repository }}:{{ .Values.stunnelClient.image.tag }}"
imagePullPolicy: {{ .Values.stunnelClient.image.pullPolicy }}
ports:
- name: postgres
containerPort: {{ .Values.stunnelClient.service.port }}
protocol: TCP
resources:
{{- toYaml .Values.stunnelClient.resources | nindent 12 }}
volumeMounts:
- name: config
mountPath: /etc/stunnel/stunnel.conf
subPath: stunnel.conf
volumes:
- name: config
configMap:
name: {{ include "postgresql.fullname" . }}-stunnel-client
{{- end }}

View File

@ -0,0 +1,23 @@
{{- if .Values.stunnelClient.enabled }}
apiVersion: v1
kind: Service
metadata:
name: {{ include "postgresql.fullname" . }}-stunnel-client
labels:
{{- include "postgresql.labels" . | nindent 4 }}
{{- with .Values.stunnelClient.service.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
type: {{ .Values.stunnelClient.service.type }}
ports:
- name: postgres
port: {{ .Values.stunnelClient.service.port }}
targetPort: postgres
protocol: TCP
selector:
app.kubernetes.io/name: {{ include "postgresql.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/component: stunnel-client
{{- end }}

View File

@ -0,0 +1,245 @@
# Default values for postgresql chart
server:
enabled: true
# Image configuration
image:
repository: postgres-extensions
tag: "16"
pullPolicy: IfNotPresent
# Image pull secrets for private registries
imagePullSecrets: []
# Override name
nameOverride: ""
fullnameOverride: ""
# Service account
serviceAccount:
create: true
annotations: {}
name: ""
# Pod annotations
podAnnotations: {}
# Pod security context
podSecurityContext:
fsGroup: 999
# Container security context
securityContext:
runAsUser: 999
runAsNonRoot: true
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# Service configuration
service:
type: ClusterIP
port: 5432
annotations: {}
# Ingress (not typically used for PostgreSQL, but available)
ingress:
enabled: false
className: ""
annotations: {}
hosts: []
tls: []
# PostgreSQL authentication
auth:
username: postgres
password: "" # Set this or use existingSecret
database: postgres
existingSecret: "" # Name of existing secret with password
secretKey: "password" # Key in the secret
# PostgreSQL configuration
postgresql:
# Custom postgresql.conf settings
config: |
shared_buffers = 256MB
effective_cache_size = 1GB
work_mem = 16MB
maintenance_work_mem = 64MB
max_connections = 100
wal_buffers = 16MB
checkpoint_completion_target = 0.9
random_page_cost = 1.1
effective_io_concurrency = 200
log_min_duration_statement = 1000
# Custom pg_hba.conf entries (appended to defaults)
pgHba: |
# Custom entries
# host all all 0.0.0.0/0 md5
# Initialization scripts
initScripts:
enabled: true
# Scripts will be created from the scripts below
scripts:
01-init-extensions.sql: |
CREATE EXTENSION IF NOT EXISTS vector;
CREATE EXTENSION IF NOT EXISTS pg_jieba;
CREATE EXTENSION IF NOT EXISTS pgmq;
CREATE EXTENSION IF NOT EXISTS pg_trgm;
CREATE EXTENSION IF NOT EXISTS hstore;
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
# Persistence
persistence:
enabled: true
storageClass: "" # Use default storage class
accessModes:
- ReadWriteOnce
size: 10Gi
annotations: {}
selector: {}
# Resource limits
resources:
limits:
cpu: 2000m
memory: 2Gi
requests:
cpu: 500m
memory: 1Gi
# Liveness probe
livenessProbe:
enabled: true
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 6
successThreshold: 1
# Readiness probe
readinessProbe:
enabled: true
initialDelaySeconds: 5
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 6
successThreshold: 1
# Node selector
nodeSelector: {}
# Tolerations
tolerations: []
# Affinity
affinity: {}
# Metrics (for Prometheus)
metrics:
enabled: false
image:
repository: prometheuscommunity/postgres-exporter
tag: v0.15.0
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 9187
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "9187"
resources:
limits:
cpu: 100m
memory: 128Mi
requests:
cpu: 50m
memory: 64Mi
# Backup configuration (optional)
backup:
enabled: false
schedule: "0 2 * * *" # Daily at 2 AM
retention: 7 # Keep 7 days of backups
storageClass: ""
size: 20Gi
# TLS/SSL configuration
tls:
enabled: false
certificatesSecret: "" # Name of secret containing tls.crt and tls.key
certFilename: "tls.crt"
certKeyFilename: "tls.key"
certCAFilename: "ca.crt"
# Stunnel sidecar for TLS over TCP
stunnel:
enabled: false
image:
repository: dweomer/stunnel
tag: latest
pullPolicy: IfNotPresent
port: 5433
certificatesSecret: "" # Name of secret containing stunnel certificates
config: |
[postgres-tunnel]
client = no
accept = 0.0.0.0:5433
connect = 127.0.0.1:5432
cert = /etc/stunnel/certs/server-cert.pem
key = /etc/stunnel/certs/server-key.pem
sslVersion = TLSv1.2
options = NO_SSLv2
options = NO_SSLv3
ciphers = HIGH:!aNULL:!MD5
# NetworkPolicy
networkPolicy:
enabled: false
policyTypes:
- Ingress
ingress:
- from:
- podSelector: {}
ports:
- protocol: TCP
port: 5432
# PodDisruptionBudget
podDisruptionBudget:
enabled: false
minAvailable: 1
# maxUnavailable: 1
stunnelClient:
enabled: false
replicaCount: 1
image:
repository: dweomer/stunnel
tag: latest
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 5432
annotations: {}
config: |
[postgres-client]
client = yes
accept = 0.0.0.0:5432
connect = postgresql.database.svc.cluster.local:5433
verifyChain = no
sslVersion = TLSv1.2
options = NO_SSLv2
options = NO_SSLv3
ciphers = HIGH:!aNULL:!MD5
resources:
limits:
cpu: 100m
memory: 128Mi
requests:
cpu: 25m
memory: 64Mi