Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion .github/workflows/verify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,15 @@ jobs:
- run: go build ./cmd/minigate
- uses: azure/setup-helm@v5
- run: helm lint charts/minigate --set existingSecret=minigate-config
- run: helm template minigate charts/minigate --set existingSecret=minigate-config --set replicaCount=3 --set ingress.enabled=true --set ingress.host=files.example.com --set ingress.tlsSecretName=files-tls --set serviceMonitor.enabled=true > /dev/null
- name: Check Helm chart defaults and options
run: |
helm template minigate charts/minigate --set existingSecret=minigate-config > /tmp/minigate-default.yaml
! grep -Eq '^kind: (Ingress|Route|HTTPProxy|ServiceMonitor|HorizontalPodAutoscaler|PodDisruptionBudget|ServiceAccount)$' /tmp/minigate-default.yaml
helm template minigate charts/minigate --set existingSecret=minigate-config --set autoscaling.enabled=true --set podDisruptionBudget.enabled=true --set serviceAccount.create=true --set ingress.enabled=true --set ingress.host=files.example.com --set ingress.tlsSecretName=files-tls --set serviceMonitor.enabled=true > /dev/null
helm template minigate charts/minigate --set existingSecret=minigate-config --set route.enabled=true > /tmp/minigate-route.yaml
grep -q '^kind: Route$' /tmp/minigate-route.yaml
helm template minigate charts/minigate --set existingSecret=minigate-config --set httpProxy.enabled=true --set httpProxy.fqdn=files.example.com --set httpProxy.tlsSecretName=files-tls > /tmp/minigate-httpproxy.yaml
grep -q '^kind: HTTPProxy$' /tmp/minigate-httpproxy.yaml
- if: github.event_name == 'pull_request'
run: docker build -t minigate:ci .

Expand Down
57 changes: 57 additions & 0 deletions charts/minigate/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# MiniGate Helm chart

This chart runs MiniGate as a stateless Kubernetes Deployment. Its default manifests are only a Deployment and a ClusterIP Service. Ingress, OpenShift Route, Contour HTTPProxy, HPA, PDB, ServiceAccount, and ServiceMonitor are opt-in.

## Install

Create a Secret with a `config.yaml` key before installing. Keep S3 credentials out of chart values and Git:

```sh
kubectl create secret generic minigate-config --from-file=config.yaml=./private-config.yaml
helm upgrade --install minigate ./charts/minigate \
--set existingSecret=minigate-config \
--set replicaCount=3
```

For three fixed replicas that tolerate one voluntary eviction:

```sh
helm upgrade --install minigate ./charts/minigate \
--set existingSecret=minigate-config \
--set replicaCount=3 \
--set podDisruptionBudget.enabled=true
```

To let Kubernetes adjust replica count, enable `autoscaling.enabled` and set `minReplicas`/`maxReplicas`; `replicaCount` is ignored while HPA is enabled. CPU autoscaling needs a working resource metrics API and a CPU request, which this chart sets by default.

## Main values

| Value | Default | Purpose |
| --- | --- | --- |
| `existingSecret` | `""` | Required Secret containing `config.yaml` |
| `replicaCount` | `1` | Fixed replicas when HPA is off |
| `image.repository` | `ghcr.io/ehsanmsb/minigate` | Container image |
| `image.tag` | `""` | Uses the chart's `appVersion` when empty |
| `imagePullSecrets` | `[]` | Credentials for a private registry |
| `logLevel` | `WARN` | Application log level |
| `service.port` | `80` | Internal HTTP Service port |
| `service.metricsPort` | `9090` | Internal Prometheus Service port |
| `ingress.enabled` | `false` | Expose file URLs through an Ingress |
| `route.enabled` | `false` | Create an OpenShift Route |
| `route.host` | `""` | Let OpenShift assign the host when empty |
| `route.tls.enabled` | `true` | Edge TLS and HTTP-to-HTTPS redirect when Route is enabled |
| `httpProxy.enabled` | `false` | Create a Contour HTTPProxy |
| `httpProxy.fqdn` | `""` | Required hostname when HTTPProxy is enabled |
| `httpProxy.tlsSecretName` | `""` | Optional TLS Secret for HTTPProxy |
| `serviceMonitor.enabled` | `false` | Create a Prometheus Operator ServiceMonitor |
| `autoscaling.enabled` | `false` | Create a CPU-based HPA |
| `podDisruptionBudget.enabled` | `false` | Create a PDB with `maxUnavailable: 1` |
| `serviceAccount.create` | `false` | Create a dedicated ServiceAccount |
| `resources.requests` | `100m` CPU, `64Mi` memory | Pod scheduling and HPA CPU baseline |
| `resources.limits` | `500m` CPU, `256Mi` memory | Default container limits; tune for traffic and object sizes |

The chart also supports `nameOverride`, `fullnameOverride`, `podAnnotations`, `podLabels`, `podSecurityContext`, `securityContext`, `nodeSelector`, `tolerations`, `affinity`, and configurable probes. See [`values.yaml`](values.yaml) for all defaults.

Ingress sends traffic only to the file-serving port. Metrics stay on the internal Service. Enable ServiceMonitor only when its CRD is installed. The chart does not create or store S3 credentials.

For OpenShift, see the [deployment guide](../../docs/deployment.md#openshift). HTTPProxy requires Contour and its `projectcontour.io/v1` CRD; it is not an OpenShift built-in. Enable only the exposure template your cluster uses. Route and HTTPProxy also send traffic only to the file-serving Service port.
16 changes: 16 additions & 0 deletions charts/minigate/templates/NOTES.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
MiniGate is available inside the cluster at:
http://{{ include "minigate.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local:{{ .Values.service.port }}/health

{{- if .Values.ingress.enabled }}
File URLs are available at:
{{ if .Values.ingress.tlsSecretName }}https{{ else }}http{{ end }}://{{ .Values.ingress.host }}/<public-name>/<object-key>
{{- end }}
{{- if .Values.route.enabled }}
OpenShift Route: run `oc get route {{ include "minigate.fullname" . }}` to see its hostname.
{{- end }}
{{- if .Values.httpProxy.enabled }}
Contour HTTPProxy file URLs:
{{ if .Values.httpProxy.tlsSecretName }}https{{ else }}http{{ end }}://{{ .Values.httpProxy.fqdn }}/<public-name>/<object-key>
{{- end }}

Prometheus metrics: port {{ .Values.service.metricsPort }}, path /metrics.
36 changes: 34 additions & 2 deletions charts/minigate/templates/_helpers.tpl
Original file line number Diff line number Diff line change
@@ -1,9 +1,41 @@
{{- define "minigate.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}

{{- define "minigate.fullname" -}}
{{- if .Values.fullnameOverride -}}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- $name := include "minigate.name" . -}}
{{- if contains $name .Release.Name -}}
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
{{- end -}}

{{- define "minigate.labels" -}}
app.kubernetes.io/name: minigate
{{- define "minigate.selectorLabels" -}}
app.kubernetes.io/name: {{ include "minigate.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end -}}

{{- define "minigate.podLabels" -}}
{{- $selector := dict "app.kubernetes.io/name" (include "minigate.name" .) "app.kubernetes.io/instance" .Release.Name -}}
{{- toYaml (mergeOverwrite (deepCopy .Values.podLabels) $selector) -}}
{{- end -}}

{{- define "minigate.labels" -}}
helm.sh/chart: {{ printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" }}
{{ include "minigate.selectorLabels" . }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end -}}

{{- define "minigate.serviceAccountName" -}}
{{- if .Values.serviceAccount.create -}}
{{- default (include "minigate.fullname" .) .Values.serviceAccount.name -}}
{{- else -}}
{{- default "default" .Values.serviceAccount.name -}}
{{- end -}}
{{- end -}}
46 changes: 30 additions & 16 deletions charts/minigate/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,30 @@ metadata:
labels:
{{- include "minigate.labels" . | nindent 4 }}
spec:
{{- if not .Values.autoscaling.enabled }}
replicas: {{ .Values.replicaCount }}
{{- end }}
selector:
matchLabels:
app.kubernetes.io/name: minigate
app.kubernetes.io/instance: {{ .Release.Name }}
{{- include "minigate.selectorLabels" . | nindent 6 }}
template:
metadata:
{{- with .Values.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "minigate.labels" . | nindent 8 }}
{{- include "minigate.podLabels" . | nindent 8 }}
spec:
terminationGracePeriodSeconds: 35
serviceAccountName: {{ include "minigate.serviceAccountName" . }}
automountServiceAccountToken: {{ .Values.serviceAccount.automount }}
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }}
containers:
- name: minigate
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
Expand All @@ -36,29 +45,34 @@ spec:
containerPort: 8080
- name: metrics
containerPort: 9090
readinessProbe:
httpGet:
path: /health
port: http
livenessProbe:
httpGet:
path: /health
port: http
{{- toYaml .Values.livenessProbe | nindent 12 }}
readinessProbe:
{{- toYaml .Values.readinessProbe | nindent 12 }}
resources:
{{- toYaml .Values.resources | nindent 12 }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
volumeMounts:
- name: config
mountPath: /etc/minigate
readOnly: true
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
volumes:
- name: config
secret:
secretName: {{ .Values.existingSecret | quote }}
items:
- key: config.yaml
path: config.yaml
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
22 changes: 22 additions & 0 deletions charts/minigate/templates/hpa.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{{- if .Values.autoscaling.enabled }}
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: {{ include "minigate.fullname" . }}
labels:
{{- include "minigate.labels" . | nindent 4 }}
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: {{ include "minigate.fullname" . }}
minReplicas: {{ .Values.autoscaling.minReplicas }}
maxReplicas: {{ .Values.autoscaling.maxReplicas }}
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}
{{- end }}
24 changes: 24 additions & 0 deletions charts/minigate/templates/httpproxy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{{- if .Values.httpProxy.enabled }}
{{- if not .Values.httpProxy.fqdn }}
{{- fail "httpProxy.fqdn is required when httpProxy.enabled=true" }}
{{- end }}
apiVersion: projectcontour.io/v1
kind: HTTPProxy
metadata:
name: {{ include "minigate.fullname" . }}
labels:
{{- include "minigate.labels" . | nindent 4 }}
spec:
virtualhost:
fqdn: {{ .Values.httpProxy.fqdn | quote }}
{{- with .Values.httpProxy.tlsSecretName }}
tls:
secretName: {{ . | quote }}
{{- end }}
routes:
- conditions:
- prefix: /
services:
- name: {{ include "minigate.fullname" . }}
port: {{ .Values.service.port }}
{{- end }}
4 changes: 4 additions & 0 deletions charts/minigate/templates/ingress.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ metadata:
name: {{ include "minigate.fullname" . }}
labels:
{{- include "minigate.labels" . | nindent 4 }}
{{- with .Values.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- with .Values.ingress.className }}
ingressClassName: {{ . | quote }}
Expand Down
13 changes: 13 additions & 0 deletions charts/minigate/templates/pdb.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{{- if .Values.podDisruptionBudget.enabled }}
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: {{ include "minigate.fullname" . }}
labels:
{{- include "minigate.labels" . | nindent 4 }}
spec:
maxUnavailable: {{ .Values.podDisruptionBudget.maxUnavailable }}
selector:
matchLabels:
{{- include "minigate.selectorLabels" . | nindent 6 }}
{{- end }}
26 changes: 26 additions & 0 deletions charts/minigate/templates/route.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{{- if .Values.route.enabled }}
apiVersion: route.openshift.io/v1
kind: Route
metadata:
name: {{ include "minigate.fullname" . }}
labels:
{{- include "minigate.labels" . | nindent 4 }}
{{- with .Values.route.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- with .Values.route.host }}
host: {{ . | quote }}
{{- end }}
port:
targetPort: http
to:
kind: Service
name: {{ include "minigate.fullname" . }}
{{- if .Values.route.tls.enabled }}
tls:
termination: edge
insecureEdgeTerminationPolicy: Redirect
{{- end }}
{{- end }}
3 changes: 1 addition & 2 deletions charts/minigate/templates/service.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,4 @@ spec:
port: {{ .Values.service.metricsPort }}
targetPort: metrics
selector:
app.kubernetes.io/name: minigate
app.kubernetes.io/instance: {{ .Release.Name }}
{{- include "minigate.selectorLabels" . | nindent 4 }}
13 changes: 13 additions & 0 deletions charts/minigate/templates/serviceaccount.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{{- if .Values.serviceAccount.create }}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "minigate.serviceAccountName" . }}
labels:
{{- include "minigate.labels" . | nindent 4 }}
{{- with .Values.serviceAccount.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
automountServiceAccountToken: {{ .Values.serviceAccount.automount }}
{{- end }}
4 changes: 2 additions & 2 deletions charts/minigate/templates/servicemonitor.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ metadata:
spec:
selector:
matchLabels:
app.kubernetes.io/name: minigate
app.kubernetes.io/instance: {{ .Release.Name }}
{{- include "minigate.selectorLabels" . | nindent 6 }}
endpoints:
- port: metrics
path: /metrics
interval: {{ .Values.serviceMonitor.interval }}
{{- end }}
Loading
Loading