Integrating traefik

This commit is contained in:
plm
2024-11-28 11:09:51 +01:00
parent 086161d0ad
commit e86898eb44
69 changed files with 32483 additions and 0 deletions

View File

@@ -0,0 +1,36 @@
{{ .Release.Name }} with {{ .Values.image.registry }}/{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }} has been deployed successfully on {{ template "traefik.namespace" . }} namespace !
{{- if .Values.persistence }}
{{- if and .Values.persistence.enabled (empty .Values.deployment.initContainer)}}
🚨 When enabling persistence for certificates, permissions on acme.json can be
lost when Traefik restarts. You can ensure correct permissions with an
initContainer. See https://github.com/traefik/traefik-helm-chart/blob/master/EXAMPLES.md#use-traefik-native-lets-encrypt-integration-without-cert-manager
for more info. 🚨
{{- end }}
{{- end }}
{{- with .Values.providers.kubernetesCRD.labelSelector }}
{{- $labelsApplied := include "traefik.labels" $ }}
{{- $labelSelectors := regexSplit "," . -1 }}
{{- range $labelSelectors }}
{{- $labelSelectorRaw := regexSplit "=" . -1 }}
{{- $labelSelector := printf "%s: %s" (first $labelSelectorRaw) (last $labelSelectorRaw) }}
{{- if not (contains $labelSelector $labelsApplied) }}
🚨 Resources populated with this chart don't match with labelSelector `{{.}}` applied on kubernetesCRD provider 🚨
{{- end }}
{{- end }}
{{- end }}
{{- with .Values.providers.kubernetesIngress.labelSelector }}
{{- $labelsApplied := include "traefik.labels" $ }}
{{- $labelSelectors := regexSplit "," . -1 }}
{{- range $labelSelectors }}
{{- $labelSelectorRaw := regexSplit "=" . -1 }}
{{- $labelSelector := printf "%s: %s" (first $labelSelectorRaw) (last $labelSelectorRaw) }}
{{- if not (contains $labelSelector $labelsApplied) }}
🚨 Resources populated with this chart don't match with labelSelector `{{.}}` applied on kubernetesIngress provider 🚨
{{- end }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,178 @@
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "traefik.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "traefik.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Create the chart image name.
*/}}
{{- define "traefik.image-name" -}}
{{- printf "%s/%s:%s" .Values.image.registry .Values.image.repository (.Values.image.tag | default .Chart.AppVersion) }}
{{- 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 "traefik.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 -}}
{{/*
Allow customization of the instance label value.
*/}}
{{- define "traefik.instance-name" -}}
{{- default (printf "%s-%s" .Release.Name .Release.Namespace) .Values.instanceLabelOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/* Shared labels used for selector*/}}
{{/* This is an immutable field: this should not change between upgrade */}}
{{- define "traefik.labelselector" -}}
app.kubernetes.io/name: {{ template "traefik.name" . }}
app.kubernetes.io/instance: {{ template "traefik.instance-name" . }}
{{- end }}
{{/* Shared labels used in metada */}}
{{- define "traefik.labels" -}}
{{ include "traefik.labelselector" . }}
helm.sh/chart: {{ template "traefik.chart" . }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- with .Values.commonLabels }}
{{ toYaml . }}
{{- end }}
{{- end }}
{{/*
Construct the namespace for all namespaced resources
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
Preserve the default behavior of the Release namespace if no override is provided
*/}}
{{- define "traefik.namespace" -}}
{{- if .Values.namespaceOverride -}}
{{- .Values.namespaceOverride | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- .Release.Namespace -}}
{{- end -}}
{{- end -}}
{{/*
The name of the service account to use
*/}}
{{- define "traefik.serviceAccountName" -}}
{{- default (include "traefik.fullname" .) .Values.serviceAccount.name -}}
{{- end -}}
{{/*
The name of the ClusterRole and ClusterRoleBinding to use.
Adds the namespace to name to prevent duplicate resource names when there
are multiple namespaced releases with the same release name.
*/}}
{{- define "traefik.clusterRoleName" -}}
{{- (printf "%s-%s" (include "traefik.fullname" .) .Release.Namespace) | trunc 63 | trimSuffix "-" }}
{{- end -}}
{{/*
Construct the path for the providers.kubernetesingress.ingressendpoint.publishedservice.
By convention this will simply use the <namespace>/<service-name> to match the name of the
service generated.
Users can provide an override for an explicit service they want bound via `.Values.providers.kubernetesIngress.publishedService.pathOverride`
*/}}
{{- define "providers.kubernetesIngress.publishedServicePath" -}}
{{- $defServiceName := printf "%s/%s" .Release.Namespace (include "traefik.fullname" .) -}}
{{- $servicePath := default $defServiceName .Values.providers.kubernetesIngress.publishedService.pathOverride }}
{{- print $servicePath | trimSuffix "-" -}}
{{- end -}}
{{/*
Construct a comma-separated list of whitelisted namespaces
*/}}
{{- define "providers.kubernetesCRD.namespaces" -}}
{{- default (include "traefik.namespace" .) (join "," .Values.providers.kubernetesCRD.namespaces) }}
{{- end -}}
{{- define "providers.kubernetesGateway.namespaces" -}}
{{- default (include "traefik.namespace" .) (join "," .Values.providers.kubernetesGateway.namespaces) }}
{{- end -}}
{{- define "providers.kubernetesIngress.namespaces" -}}
{{- default (include "traefik.namespace" .) (join "," .Values.providers.kubernetesIngress.namespaces) }}
{{- end -}}
{{/*
Renders a complete tree, even values that contains template.
*/}}
{{- define "traefik.render" -}}
{{- if typeIs "string" .value }}
{{- tpl .value .context }}
{{ else }}
{{- tpl (.value | toYaml) .context }}
{{- end }}
{{- end -}}
{{- define "imageVersion" -}}
{{/*
Traefik hub is based on v3.1 (v3.0 before v3.3.1) of traefik proxy, so this is a hack to avoid to much complexity in RBAC management which are
based on semverCompare
*/}}
{{- if $.Values.hub.token -}}
{{ if and (regexMatch "v[0-9]+.[0-9]+.[0-9]+" (default "" $.Values.image.tag)) (semverCompare "<v3.3.2-0" $.Values.image.tag) -}}
v3.0
{{- else -}}
v3.1
{{- end -}}
{{- else -}}
{{ (split "@" (default $.Chart.AppVersion $.Values.image.tag))._0 | replace "latest-" "" | replace "experimental-" "" }}
{{- end -}}
{{- end -}}
{{/* Generate/load self-signed certificate for admission webhooks */}}
{{- define "traefik-hub.webhook_cert" -}}
{{- $cert := lookup "v1" "Secret" .Release.Namespace "hub-agent-cert" -}}
{{- if $cert -}}
{{/* reusing value of existing cert */}}
Cert: {{ index $cert.data "tls.crt" }}
Key: {{ index $cert.data "tls.key" }}
{{- else -}}
{{/* generate a new one */}}
{{- $altNames := list ( printf "admission.%s.svc" .Release.Namespace ) -}}
{{- $cert := genSelfSignedCert ( printf "admission.%s.svc" .Release.Namespace ) (list) $altNames 3650 -}}
Cert: {{ $cert.Cert | b64enc }}
Key: {{ $cert.Key | b64enc }}
{{- end -}}
{{- end -}}
{{- define "traefik.yaml2CommandLineArgsRec" -}}
{{- $path := .path -}}
{{- range $key, $value := .content -}}
{{- if kindIs "map" $value }}
{{- include "traefik.yaml2CommandLineArgsRec" (dict "path" (printf "%s.%s" $path $key) "content" $value) -}}
{{- else }}
--{{ join "." (list $path $key)}}={{ join "," $value }}
{{- end -}}
{{- end -}}
{{- end -}}
{{- define "traefik.yaml2CommandLineArgs" -}}
{{- range ((regexSplit "\n" ((include "traefik.yaml2CommandLineArgsRec" (dict "path" .path "content" .content)) | trim) -1) | compact) -}}
{{ printf "- \"%s\"\n" . }}
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,850 @@
{{- define "traefik.podTemplate" }}
{{- $version := include "imageVersion" $ }}
metadata:
annotations:
{{- if .Values.deployment.podAnnotations }}
{{- tpl (toYaml .Values.deployment.podAnnotations) . | nindent 8 }}
{{- end }}
{{- if .Values.metrics }}
{{- if and (.Values.metrics.prometheus) (not (.Values.metrics.prometheus.serviceMonitor).enabled) }}
prometheus.io/scrape: "true"
prometheus.io/path: "/metrics"
prometheus.io/port: {{ quote (index .Values.ports .Values.metrics.prometheus.entryPoint).port }}
{{- end }}
{{- end }}
labels:
{{- include "traefik.labels" . | nindent 8 -}}
{{- with .Values.deployment.podLabels }}
{{- toYaml . | nindent 8 }}
{{- end }}
spec:
{{- with .Values.deployment.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ include "traefik.serviceAccountName" . }}
automountServiceAccountToken: true
terminationGracePeriodSeconds: {{ default 60 .Values.deployment.terminationGracePeriodSeconds }}
hostNetwork: {{ .Values.hostNetwork }}
{{- with .Values.deployment.dnsPolicy }}
dnsPolicy: {{ . }}
{{- end }}
{{- with .Values.deployment.dnsConfig }}
dnsConfig:
{{- if .searches }}
searches:
{{- toYaml .searches | nindent 10 }}
{{- end }}
{{- if .nameservers }}
nameservers:
{{- toYaml .nameservers | nindent 10 }}
{{- end }}
{{- if .options }}
options:
{{- toYaml .options | nindent 10 }}
{{- end }}
{{- end }}
{{- with .Values.deployment.hostAliases }}
hostAliases: {{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.deployment.initContainers }}
initContainers:
{{- toYaml . | nindent 6 }}
{{- end }}
{{- if .Values.deployment.shareProcessNamespace }}
shareProcessNamespace: true
{{- end }}
{{- with .Values.deployment.runtimeClassName }}
runtimeClassName: {{ . }}
{{- end }}
containers:
- image: {{ template "traefik.image-name" . }}
imagePullPolicy: {{ .Values.image.pullPolicy }}
name: {{ template "traefik.fullname" . }}
resources:
{{- with .Values.resources }}
{{- toYaml . | nindent 10 }}
{{- end }}
{{- if (and (empty .Values.ports.traefik) (empty .Values.deployment.healthchecksPort)) }}
{{- fail "ERROR: When disabling traefik port, you need to specify `deployment.healthchecksPort`" }}
{{- end }}
{{- $healthchecksPort := (default (.Values.ports.traefik).port .Values.deployment.healthchecksPort) }}
{{- $healthchecksHost := (default (.Values.ports.traefik).hostIP .Values.deployment.healthchecksHost) }}
{{- $healthchecksScheme := (default "HTTP" .Values.deployment.healthchecksScheme) }}
{{- $readinessPath := (default "/ping" .Values.deployment.readinessPath) }}
{{- $livenessPath := (default "/ping" .Values.deployment.livenessPath) }}
readinessProbe:
httpGet:
{{- with $healthchecksHost }}
host: {{ . }}
{{- end }}
path: {{ $readinessPath }}
port: {{ $healthchecksPort }}
scheme: {{ $healthchecksScheme }}
{{- toYaml .Values.readinessProbe | nindent 10 }}
livenessProbe:
httpGet:
{{- with $healthchecksHost }}
host: {{ . }}
{{- end }}
path: {{ $livenessPath }}
port: {{ $healthchecksPort }}
scheme: {{ $healthchecksScheme }}
{{- toYaml .Values.livenessProbe | nindent 10 }}
{{- with .Values.startupProbe}}
startupProbe:
{{- toYaml . | nindent 10 }}
{{- end }}
lifecycle:
{{- with .Values.deployment.lifecycle }}
{{- toYaml . | nindent 10 }}
{{- end }}
ports:
{{- $hostNetwork := .Values.hostNetwork }}
{{- range $name, $config := .Values.ports }}
{{- if $config }}
{{- if and $hostNetwork (and $config.hostPort $config.port) }}
{{- if ne ($config.hostPort | int) ($config.port | int) }}
{{- fail "ERROR: All hostPort must match their respective containerPort when `hostNetwork` is enabled" }}
{{- end }}
{{- end }}
- name: {{ $name | quote }}
containerPort: {{ default $config.port $config.containerPort }}
{{- if $config.hostPort }}
hostPort: {{ $config.hostPort }}
{{- end }}
{{- if $config.hostIP }}
hostIP: {{ $config.hostIP }}
{{- end }}
protocol: {{ default "TCP" $config.protocol | quote }}
{{- if ($config.http3).enabled }}
- name: "{{ $name }}-http3"
containerPort: {{ $config.port }}
{{- if $config.hostPort }}
hostPort: {{ default $config.hostPort $config.http3.advertisedPort }}
{{- end }}
protocol: UDP
{{- end }}
{{- end }}
{{- end }}
{{- if .Values.hub.token }}
{{- $listenAddr := default ":9943" .Values.hub.apimanagement.admission.listenAddr }}
- name: admission
containerPort: {{ last (mustRegexSplit ":" $listenAddr 2) }}
protocol: TCP
{{- if .Values.hub.apimanagement.enabled }}
- name: apiportal
containerPort: 9903
protocol: TCP
{{- end }}
{{- end }}
{{- with .Values.securityContext }}
securityContext:
{{- toYaml . | nindent 10 }}
{{- end }}
volumeMounts:
- name: {{ .Values.persistence.name }}
mountPath: {{ .Values.persistence.path }}
{{- if .Values.persistence.subPath }}
subPath: {{ .Values.persistence.subPath }}
{{- end }}
- name: tmp
mountPath: /tmp
{{- $root := . }}
{{- range .Values.volumes }}
- name: {{ tpl (.name) $root | replace "." "-" }}
mountPath: {{ .mountPath }}
readOnly: true
{{- end }}
{{- if gt (len .Values.experimental.plugins) 0 }}
- name: plugins
mountPath: "/plugins-storage"
{{- end }}
{{- if .Values.providers.file.enabled }}
- name: traefik-extra-config
mountPath: "/etc/traefik/dynamic"
{{- end }}
{{- if .Values.additionalVolumeMounts }}
{{- toYaml .Values.additionalVolumeMounts | nindent 10 }}
{{- end }}
args:
{{- with .Values.globalArguments }}
{{- range . }}
- {{ . | quote }}
{{- end }}
{{- end }}
{{- range $name, $config := .Values.ports }}
{{- if $config }}
- "--entryPoints.{{$name}}.address={{ $config.hostIP }}:{{ $config.port }}/{{ default "tcp" $config.protocol | lower }}"
{{- with $config.asDefault }}
- "--entryPoints.{{$name}}.asDefault={{ . }}"
{{- end }}
{{- end }}
{{- end }}
- "--api.dashboard=true"
- "--ping=true"
{{- with .Values.core }}
{{- with .defaultRuleSyntax }}
- "--core.defaultRuleSyntax={{ . }}"
{{- end }}
{{- end }}
{{- if .Values.metrics }}
{{- if .Values.metrics.addInternals }}
- "--metrics.addinternals"
{{- end }}
{{- with .Values.metrics.datadog }}
- "--metrics.datadog=true"
{{- with .address }}
- "--metrics.datadog.address={{ . }}"
{{- end }}
{{- with .pushInterval }}
- "--metrics.datadog.pushInterval={{ . }}"
{{- end }}
{{- with .prefix }}
- "--metrics.datadog.prefix={{ . }}"
{{- end }}
{{- if ne .addRoutersLabels nil }}
{{- with .addRoutersLabels | toString }}
- "--metrics.datadog.addRoutersLabels={{ . }}"
{{- end }}
{{- end }}
{{- if ne .addEntryPointsLabels nil }}
{{- with .addEntryPointsLabels | toString }}
- "--metrics.datadog.addEntryPointsLabels={{ . }}"
{{- end }}
{{- end }}
{{- if ne .addServicesLabels nil }}
{{- with .addServicesLabels | toString }}
- "--metrics.datadog.addServicesLabels={{ . }}"
{{- end }}
{{- end }}
{{- end }}
{{- with .Values.metrics.influxdb2 }}
- "--metrics.influxdb2=true"
- "--metrics.influxdb2.address={{ .address }}"
- "--metrics.influxdb2.token={{ .token }}"
- "--metrics.influxdb2.org={{ .org }}"
- "--metrics.influxdb2.bucket={{ .bucket }}"
{{- with .pushInterval }}
- "--metrics.influxdb2.pushInterval={{ . }}"
{{- end }}
{{- range $name, $value := .additionalLabels }}
- "--metrics.influxdb2.additionalLabels.{{ $name }}={{ $value }}"
{{- end }}
{{- if ne .addRoutersLabels nil }}
{{- with .addRoutersLabels | toString }}
- "--metrics.influxdb2.addRoutersLabels={{ . }}"
{{- end }}
{{- end }}
{{- if ne .addEntryPointsLabels nil }}
{{- with .addEntryPointsLabels | toString }}
- "--metrics.influxdb2.addEntryPointsLabels={{ . }}"
{{- end }}
{{- end }}
{{- if ne .addServicesLabels nil }}
{{- with .addServicesLabels | toString }}
- "--metrics.influxdb2.addServicesLabels={{ . }}"
{{- end }}
{{- end }}
{{- end }}
{{- if (.Values.metrics.prometheus) }}
- "--metrics.prometheus=true"
- "--metrics.prometheus.entrypoint={{ .Values.metrics.prometheus.entryPoint }}"
{{- if (eq (.Values.metrics.prometheus.addRoutersLabels | toString) "true") }}
- "--metrics.prometheus.addRoutersLabels=true"
{{- end }}
{{- if ne .Values.metrics.prometheus.addEntryPointsLabels nil }}
{{- with .Values.metrics.prometheus.addEntryPointsLabels | toString }}
- "--metrics.prometheus.addEntryPointsLabels={{ . }}"
{{- end }}
{{- end }}
{{- if ne .Values.metrics.prometheus.addServicesLabels nil }}
{{- with .Values.metrics.prometheus.addServicesLabels| toString }}
- "--metrics.prometheus.addServicesLabels={{ . }}"
{{- end }}
{{- end }}
{{- if .Values.metrics.prometheus.buckets }}
- "--metrics.prometheus.buckets={{ .Values.metrics.prometheus.buckets }}"
{{- end }}
{{- if .Values.metrics.prometheus.manualRouting }}
- "--metrics.prometheus.manualrouting=true"
{{- end }}
{{- end }}
{{- with .Values.metrics.statsd }}
- "--metrics.statsd=true"
- "--metrics.statsd.address={{ .address }}"
{{- with .pushInterval }}
- "--metrics.statsd.pushInterval={{ . }}"
{{- end }}
{{- with .prefix }}
- "--metrics.statsd.prefix={{ . }}"
{{- end }}
{{- if .addRoutersLabels}}
- "--metrics.statsd.addRoutersLabels=true"
{{- end }}
{{- if ne .addEntryPointsLabels nil }}
{{- with .addEntryPointsLabels | toString }}
- "--metrics.statsd.addEntryPointsLabels={{ . }}"
{{- end }}
{{- end }}
{{- if ne .addServicesLabels nil }}
{{- with .addServicesLabels | toString }}
- "--metrics.statsd.addServicesLabels={{ . }}"
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- with .Values.metrics.otlp }}
{{- if .enabled }}
- "--metrics.otlp=true"
{{- if ne .addEntryPointsLabels nil }}
{{- with .addEntryPointsLabels | toString }}
- "--metrics.otlp.addEntryPointsLabels={{ . }}"
{{- end }}
{{- end }}
{{- if ne .addRoutersLabels nil }}
{{- with .addRoutersLabels | toString }}
- "--metrics.otlp.addRoutersLabels={{ . }}"
{{- end }}
{{- end }}
{{- if ne .addServicesLabels nil }}
{{- with .addServicesLabels | toString }}
- "--metrics.otlp.addServicesLabels={{ . }}"
{{- end }}
{{- end }}
{{- with .explicitBoundaries }}
- "--metrics.otlp.explicitBoundaries={{ join "," . }}"
{{- end }}
{{- with .pushInterval }}
- "--metrics.otlp.pushInterval={{ . }}"
{{- end }}
{{- with .http }}
{{- if .enabled }}
- "--metrics.otlp.http=true"
{{- with .endpoint }}
- "--metrics.otlp.http.endpoint={{ . }}"
{{- end }}
{{- range $name, $value := .headers }}
- "--metrics.otlp.http.headers.{{ $name }}={{ $value }}"
{{- end }}
{{- with .tls }}
{{- with .ca }}
- "--metrics.otlp.http.tls.ca={{ . }}"
{{- end }}
{{- with .cert }}
- "--metrics.otlp.http.tls.cert={{ . }}"
{{- end }}
{{- with .key }}
- "--metrics.otlp.http.tls.key={{ . }}"
{{- end }}
{{- with .insecureSkipVerify }}
- "--metrics.otlp.http.tls.insecureSkipVerify={{ . }}"
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- with .grpc }}
{{- if .enabled }}
- "--metrics.otlp.grpc=true"
{{- with .endpoint }}
- "--metrics.otlp.grpc.endpoint={{ . }}"
{{- end }}
{{- with .insecure }}
- "--metrics.otlp.grpc.insecure={{ . }}"
{{- end }}
{{- range $name, $value := .headers }}
- "--metrics.otlp.grpc.headers.{{ $name }}={{ $value }}"
{{- end }}
{{- with .tls }}
{{- with .ca }}
- "--metrics.otlp.grpc.tls.ca={{ . }}"
{{- end }}
{{- with .cert }}
- "--metrics.otlp.grpc.tls.cert={{ . }}"
{{- end }}
{{- with .key }}
- "--metrics.otlp.grpc.tls.key={{ . }}"
{{- end }}
{{- with .insecureSkipVerify }}
- "--metrics.otlp.grpc.tls.insecureSkipVerify={{ . }}"
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- if .Values.tracing.addInternals }}
- "--tracing.addinternals"
{{- end }}
{{- with .Values.tracing.otlp }}
{{- if .enabled }}
- "--tracing.otlp=true"
{{- with .http }}
{{- if .enabled }}
- "--tracing.otlp.http=true"
{{- with .endpoint }}
- "--tracing.otlp.http.endpoint={{ . }}"
{{- end }}
{{- range $name, $value := .headers }}
- "--tracing.otlp.http.headers.{{ $name }}={{ $value }}"
{{- end }}
{{- with .tls }}
{{- with .ca }}
- "--tracing.otlp.http.tls.ca={{ . }}"
{{- end }}
{{- with .cert }}
- "--tracing.otlp.http.tls.cert={{ . }}"
{{- end }}
{{- with .key }}
- "--tracing.otlp.http.tls.key={{ . }}"
{{- end }}
{{- with .insecureSkipVerify }}
- "--tracing.otlp.http.tls.insecureSkipVerify={{ . }}"
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- with .grpc }}
{{- if .enabled }}
- "--tracing.otlp.grpc=true"
{{- with .endpoint }}
- "--tracing.otlp.grpc.endpoint={{ . }}"
{{- end }}
{{- with .insecure }}
- "--tracing.otlp.grpc.insecure={{ . }}"
{{- end }}
{{- range $name, $value := .headers }}
- "--tracing.otlp.grpc.headers.{{ $name }}={{ $value }}"
{{- end }}
{{- with .tls }}
{{- with .ca }}
- "--tracing.otlp.grpc.tls.ca={{ . }}"
{{- end }}
{{- with .cert }}
- "--tracing.otlp.grpc.tls.cert={{ . }}"
{{- end }}
{{- with .key }}
- "--tracing.otlp.grpc.tls.key={{ . }}"
{{- end }}
{{- with .insecureSkipVerify }}
- "--tracing.otlp.grpc.tls.insecureSkipVerify={{ . }}"
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- range $pluginName, $plugin := .Values.experimental.plugins }}
{{- if or (ne (typeOf $plugin) "map[string]interface {}") (not (hasKey $plugin "moduleName")) (not (hasKey $plugin "version")) }}
{{- fail (printf "ERROR: plugin %s is missing moduleName/version keys !" $pluginName) }}
{{- end }}
- "--experimental.plugins.{{ $pluginName }}.moduleName={{ $plugin.moduleName }}"
- "--experimental.plugins.{{ $pluginName }}.version={{ $plugin.version }}"
{{- end }}
{{- if .Values.providers.kubernetesCRD.enabled }}
- "--providers.kubernetescrd"
{{- if .Values.providers.kubernetesCRD.labelSelector }}
- "--providers.kubernetescrd.labelSelector={{ .Values.providers.kubernetesCRD.labelSelector }}"
{{- end }}
{{- if .Values.providers.kubernetesCRD.ingressClass }}
- "--providers.kubernetescrd.ingressClass={{ .Values.providers.kubernetesCRD.ingressClass }}"
{{- end }}
{{- if .Values.providers.kubernetesCRD.allowCrossNamespace }}
- "--providers.kubernetescrd.allowCrossNamespace=true"
{{- end }}
{{- if .Values.providers.kubernetesCRD.allowExternalNameServices }}
- "--providers.kubernetescrd.allowExternalNameServices=true"
{{- end }}
{{- if .Values.providers.kubernetesCRD.allowEmptyServices }}
- "--providers.kubernetescrd.allowEmptyServices=true"
{{- end }}
{{- if and .Values.rbac.namespaced (semverCompare ">=3.1.2-0" $version) }}
- "--providers.kubernetescrd.disableClusterScopeResources=true"
{{- end }}
{{- if .Values.providers.kubernetesCRD.nativeLBByDefault }}
- "--providers.kubernetescrd.nativeLBByDefault=true"
{{- end }}
{{- end }}
{{- if .Values.providers.kubernetesIngress.enabled }}
- "--providers.kubernetesingress"
{{- if .Values.providers.kubernetesIngress.allowExternalNameServices }}
- "--providers.kubernetesingress.allowExternalNameServices=true"
{{- end }}
{{- if .Values.providers.kubernetesIngress.allowEmptyServices }}
- "--providers.kubernetesingress.allowEmptyServices=true"
{{- end }}
{{- if and .Values.service.enabled .Values.providers.kubernetesIngress.publishedService.enabled }}
- "--providers.kubernetesingress.ingressendpoint.publishedservice={{ template "providers.kubernetesIngress.publishedServicePath" . }}"
{{- end }}
{{- if .Values.providers.kubernetesIngress.labelSelector }}
- "--providers.kubernetesingress.labelSelector={{ .Values.providers.kubernetesIngress.labelSelector }}"
{{- end }}
{{- if .Values.providers.kubernetesIngress.ingressClass }}
- "--providers.kubernetesingress.ingressClass={{ .Values.providers.kubernetesIngress.ingressClass }}"
{{- end }}
{{- if .Values.rbac.namespaced }}
{{- if semverCompare "<3.1.5-0" $version }}
- "--providers.kubernetesingress.disableIngressClassLookup=true"
{{- if semverCompare ">=3.1.2-0" $version }}
- "--providers.kubernetesingress.disableClusterScopeResources=true"
{{- end }}
{{- else }}
- "--providers.kubernetesingress.disableClusterScopeResources=true"
{{- end }}
{{- end }}
{{- if .Values.providers.kubernetesIngress.nativeLBByDefault }}
- "--providers.kubernetesingress.nativeLBByDefault=true"
{{- end }}
{{- end }}
{{- if .Values.experimental.kubernetesGateway.enabled }}
- "--experimental.kubernetesgateway"
{{- end }}
{{- with .Values.providers.kubernetesCRD }}
{{- if (and .enabled (or .namespaces (and $.Values.rbac.enabled $.Values.rbac.namespaced))) }}
- "--providers.kubernetescrd.namespaces={{ template "providers.kubernetesCRD.namespaces" $ }}"
{{- end }}
{{- end }}
{{- with .Values.providers.kubernetesGateway }}
{{- if .enabled }}
- "--providers.kubernetesgateway"
{{- with .statusAddress }}
{{- with .ip }}
- "--providers.kubernetesgateway.statusaddress.ip={{ . }}"
{{- end }}
{{- with .hostname }}
- "--providers.kubernetesgateway.statusaddress.hostname={{ . }}"
{{- end }}
{{- with .service }}
- "--providers.kubernetesgateway.statusaddress.service.name={{ tpl .name $ }}"
- "--providers.kubernetesgateway.statusaddress.service.namespace={{ tpl .namespace $ }}"
{{- end }}
{{- end }}
{{- if or .namespaces (and $.Values.rbac.enabled $.Values.rbac.namespaced) }}
- "--providers.kubernetesgateway.namespaces={{ template "providers.kubernetesGateway.namespaces" $ }}"
{{- end }}
{{- if .experimentalChannel }}
- "--providers.kubernetesgateway.experimentalchannel=true"
{{- end }}
{{- with .labelselector }}
- "--providers.kubernetesgateway.labelselector={{ . }}"
{{- end }}
{{- end }}
{{- end }}
{{- with .Values.providers.kubernetesIngress }}
{{- if (and .enabled (or .namespaces (and $.Values.rbac.enabled $.Values.rbac.namespaced))) }}
- "--providers.kubernetesingress.namespaces={{ template "providers.kubernetesIngress.namespaces" $ }}"
{{- end }}
{{- end }}
{{- with .Values.providers.file }}
{{- if .enabled }}
- "--providers.file.directory=/etc/traefik/dynamic"
{{- if .watch }}
- "--providers.file.watch=true"
{{- end }}
{{- end }}
{{- end }}
{{- range $entrypoint, $config := $.Values.ports }}
{{- if $config }}
{{- if $config.redirectTo }}
{{- $toPort := index $.Values.ports $config.redirectTo.port }}
- "--entryPoints.{{ $entrypoint }}.http.redirections.entryPoint.to=:{{ $toPort.exposedPort }}"
- "--entryPoints.{{ $entrypoint }}.http.redirections.entryPoint.scheme=https"
{{- if $config.redirectTo.priority }}
- "--entryPoints.{{ $entrypoint }}.http.redirections.entryPoint.priority={{ $config.redirectTo.priority }}"
{{- end }}
{{- if $config.redirectTo.permanent }}
- "--entryPoints.{{ $entrypoint }}.http.redirections.entryPoint.permanent=true"
{{- end }}
{{- end }}
{{- if $config.middlewares }}
- "--entryPoints.{{ $entrypoint }}.http.middlewares={{ join "," $config.middlewares }}"
{{- end }}
{{- if $config.tls }}
{{- if $config.tls.enabled }}
- "--entryPoints.{{ $entrypoint }}.http.tls=true"
{{- if $config.tls.options }}
- "--entryPoints.{{ $entrypoint }}.http.tls.options={{ $config.tls.options }}"
{{- end }}
{{- if $config.tls.certResolver }}
- "--entryPoints.{{ $entrypoint }}.http.tls.certResolver={{ $config.tls.certResolver }}"
{{- end }}
{{- if $config.tls.domains }}
{{- range $index, $domain := $config.tls.domains }}
{{- if $domain.main }}
- "--entryPoints.{{ $entrypoint }}.http.tls.domains[{{ $index }}].main={{ $domain.main }}"
{{- end }}
{{- if $domain.sans }}
- "--entryPoints.{{ $entrypoint }}.http.tls.domains[{{ $index }}].sans={{ join "," $domain.sans }}"
{{- end }}
{{- end }}
{{- end }}
{{- if $config.http3 }}
{{- if $config.http3.enabled }}
- "--entryPoints.{{ $entrypoint }}.http3"
{{- if $config.http3.advertisedPort }}
- "--entryPoints.{{ $entrypoint }}.http3.advertisedPort={{ $config.http3.advertisedPort }}"
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- if $config.allowACMEByPass }}
{{- if (semverCompare "<3.1.3-0" $version) }}
{{- fail "ERROR: allowACMEByPass has been introduced with Traefik v3.1.3+" -}}
{{- end }}
- "--entryPoints.name.allowACMEByPass=true"
{{- end }}
{{- if $config.forwardedHeaders }}
{{- if $config.forwardedHeaders.trustedIPs }}
- "--entryPoints.{{ $entrypoint }}.forwardedHeaders.trustedIPs={{ join "," $config.forwardedHeaders.trustedIPs }}"
{{- end }}
{{- if $config.forwardedHeaders.insecure }}
- "--entryPoints.{{ $entrypoint }}.forwardedHeaders.insecure"
{{- end }}
{{- end }}
{{- if $config.proxyProtocol }}
{{- if $config.proxyProtocol.trustedIPs }}
- "--entryPoints.{{ $entrypoint }}.proxyProtocol.trustedIPs={{ join "," $config.proxyProtocol.trustedIPs }}"
{{- end }}
{{- if $config.proxyProtocol.insecure }}
- "--entryPoints.{{ $entrypoint }}.proxyProtocol.insecure"
{{- end }}
{{- end }}
{{- with $config.transport }}
{{- with .respondingTimeouts }}
{{- if and (ne .readTimeout nil) (toString .readTimeout) }}
- "--entryPoints.{{ $entrypoint }}.transport.respondingTimeouts.readTimeout={{ .readTimeout }}"
{{- end }}
{{- if and (ne .writeTimeout nil) (toString .writeTimeout) }}
- "--entryPoints.{{ $entrypoint }}.transport.respondingTimeouts.writeTimeout={{ .writeTimeout }}"
{{- end }}
{{- if and (ne .idleTimeout nil) (toString .idleTimeout) }}
- "--entryPoints.{{ $entrypoint }}.transport.respondingTimeouts.idleTimeout={{ .idleTimeout }}"
{{- end }}
{{- end }}
{{- with .lifeCycle }}
{{- if and (ne .requestAcceptGraceTimeout nil) (toString .requestAcceptGraceTimeout) }}
- "--entryPoints.{{ $entrypoint }}.transport.lifeCycle.requestAcceptGraceTimeout={{ .requestAcceptGraceTimeout }}"
{{- end }}
{{- if and (ne .graceTimeOut nil) (toString .graceTimeOut) }}
- "--entryPoints.{{ $entrypoint }}.transport.lifeCycle.graceTimeOut={{ .graceTimeOut }}"
{{- end }}
{{- end }}
{{- if and (ne .keepAliveMaxRequests nil) (toString .keepAliveMaxRequests) }}
- "--entryPoints.{{ $entrypoint }}.transport.keepAliveMaxRequests={{ .keepAliveMaxRequests }}"
{{- end }}
{{- if and (ne .keepAliveMaxTime nil) (toString .keepAliveMaxTime) }}
- "--entryPoints.{{ $entrypoint }}.transport.keepAliveMaxTime={{ .keepAliveMaxTime }}"
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- with .Values.logs }}
{{- if and .general.format (not (has .general.format (list "common" "json"))) }}
{{- fail "ERROR: .Values.logs.general.format must be either common or json" }}
{{- end }}
{{- with .general.format }}
- "--log.format={{ . }}"
{{- end }}
{{- with .general.filePath }}
- "--log.filePath={{ . }}"
{{- end }}
{{- if and (or (eq .general.format "common") (not .general.format)) (eq .general.noColor true) }}
- "--log.noColor={{ .general.noColor }}"
{{- end }}
{{- with .general.level }}
- "--log.level={{ . | upper }}"
{{- end }}
{{- if .access.enabled }}
- "--accesslog=true"
{{- with .access.format }}
- "--accesslog.format={{ . }}"
{{- end }}
{{- with .access.filePath }}
- "--accesslog.filepath={{ . }}"
{{- end }}
{{- if .access.addInternals }}
- "--accesslog.addinternals"
{{- end }}
{{- with .access.bufferingSize }}
- "--accesslog.bufferingsize={{ . }}"
{{- end }}
{{- with .access.filters }}
{{- with .statuscodes }}
- "--accesslog.filters.statuscodes={{ . }}"
{{- end }}
{{- if .retryattempts }}
- "--accesslog.filters.retryattempts"
{{- end }}
{{- with .minduration }}
- "--accesslog.filters.minduration={{ . }}"
{{- end }}
{{- end }}
- "--accesslog.fields.defaultmode={{ .access.fields.general.defaultmode }}"
{{- range $fieldname, $fieldaction := .access.fields.general.names }}
- "--accesslog.fields.names.{{ $fieldname }}={{ $fieldaction }}"
{{- end }}
- "--accesslog.fields.headers.defaultmode={{ .access.fields.headers.defaultmode }}"
{{- range $fieldname, $fieldaction := .access.fields.headers.names }}
- "--accesslog.fields.headers.names.{{ $fieldname }}={{ $fieldaction }}"
{{- end }}
{{- end }}
{{- end }}
{{- include "traefik.yaml2CommandLineArgs" (dict "path" "certificatesresolvers" "content" $.Values.certificatesResolvers) | nindent 10 }}
{{- with .Values.additionalArguments }}
{{- range . }}
- {{ . | quote }}
{{- end }}
{{- end }}
{{- with .Values.hub }}
{{- if .token }}
- "--hub.token=$(HUB_TOKEN)"
{{- if and (not .apimanagement.enabled) ($.Values.hub.apimanagement.admission.listenAddr) }}
{{- fail "ERROR: Cannot configure admission without enabling hub.apimanagement" }}
{{- end }}
{{- with .apimanagement }}
{{- if .enabled }}
{{- $listenAddr := default ":9943" .admission.listenAddr }}
- "--hub.apimanagement"
- "--hub.apimanagement.admission.listenAddr={{ $listenAddr }}"
{{- with .admission.secretName }}
- "--hub.apimanagement.admission.secretName={{ . }}"
{{- end }}
{{- end }}
{{- end }}
{{- with .platformUrl }}
- "--hub.platformUrl={{ . }}"
{{- end -}}
{{- range $field, $value := .redis }}
{{- if has $field (list "cluster" "database" "endpoints" "username" "password" "timeout") -}}
{{- with $value }}
- "--hub.redis.{{ $field }}={{ $value }}"
{{- end }}
{{- end }}
{{- end }}
{{- range $field, $value := .redis.sentinel }}
{{- if has $field (list "masterset" "password" "username") -}}
{{- with $value }}
- "--hub.redis.sentinel.{{ $field }}={{ $value }}"
{{- end }}
{{- end }}
{{- end }}
{{- range $field, $value := .redis.tls }}
{{- if has $field (list "ca" "cert" "insecureSkipVerify" "key") -}}
{{- with $value }}
- "--hub.redis.tls.{{ $field }}={{ $value }}"
{{- end }}
{{- end }}
{{- end }}
{{- with .sendlogs }}
- "--hub.sendlogs={{ . }}"
{{- end }}
{{- end }}
{{- end }}
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
{{- if ($.Values.resources.limits).cpu }}
- name: GOMAXPROCS
valueFrom:
resourceFieldRef:
resource: limits.cpu
divisor: '1'
{{- end }}
{{- if ($.Values.resources.limits).memory }}
- name: GOMEMLIMIT
valueFrom:
resourceFieldRef:
resource: limits.memory
divisor: '1'
{{- end }}
{{- with .Values.hub.token }}
- name: HUB_TOKEN
valueFrom:
secretKeyRef:
name: {{ . }}
key: token
{{- end }}
{{- with .Values.env }}
{{- toYaml . | nindent 10 }}
{{- end }}
{{- with .Values.envFrom }}
envFrom:
{{- toYaml . | nindent 10 }}
{{- end }}
{{- if .Values.deployment.additionalContainers }}
{{- toYaml .Values.deployment.additionalContainers | nindent 6 }}
{{- end }}
volumes:
- name: {{ .Values.persistence.name }}
{{- if .Values.persistence.enabled }}
persistentVolumeClaim:
claimName: {{ default (include "traefik.fullname" .) .Values.persistence.existingClaim }}
{{- else }}
emptyDir: {}
{{- end }}
- name: tmp
emptyDir: {}
{{- $root := . }}
{{- range .Values.volumes }}
- name: {{ tpl (.name) $root | replace "." "-" }}
{{- if eq .type "secret" }}
secret:
secretName: {{ tpl (.name) $root }}
{{- else if eq .type "configMap" }}
configMap:
name: {{ tpl (.name) $root }}
{{- end }}
{{- end }}
{{- if .Values.deployment.additionalVolumes }}
{{- toYaml .Values.deployment.additionalVolumes | nindent 8 }}
{{- end }}
{{- if gt (len .Values.experimental.plugins) 0 }}
- name: plugins
emptyDir: {}
{{- end }}
{{- if .Values.providers.file.enabled }}
- name: traefik-extra-config
configMap:
name: {{ template "traefik.fullname" . }}-file-provider
{{- end }}
{{- if .Values.affinity }}
affinity:
{{- tpl (toYaml .Values.affinity) . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- if .Values.priorityClassName }}
priorityClassName: {{ .Values.priorityClassName }}
{{- end }}
{{- with .Values.podSecurityContext }}
securityContext:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- if .Values.topologySpreadConstraints }}
{{- if (semverCompare "<1.19.0-0" .Capabilities.KubeVersion.Version) }}
{{- fail "ERROR: topologySpreadConstraints are supported only on kubernetes >= v1.19" -}}
{{- end }}
topologySpreadConstraints:
{{- tpl (toYaml .Values.topologySpreadConstraints) . | nindent 8 }}
{{- end }}
{{ end -}}

View File

@@ -0,0 +1,25 @@
{{- define "traefik.metrics-service-metadata" }}
labels:
{{- include "traefik.metricsservicelabels" . | nindent 4 -}}
{{- with .Values.metrics.prometheus.service.labels }}
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}
{{/* Labels used for metrics-relevant selector*/}}
{{/* This is an immutable field: this should not change between upgrade */}}
{{- define "traefik.metricslabelselector" -}}
{{- include "traefik.labelselector" . }}
app.kubernetes.io/component: metrics
{{- end }}
{{/* Shared labels used in metadata of metrics-service and servicemonitor */}}
{{- define "traefik.metricsservicelabels" -}}
{{ include "traefik.metricslabelselector" . }}
helm.sh/chart: {{ template "traefik.chart" . }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- with .Values.commonLabels }}
{{ toYaml . }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,84 @@
{{- define "traefik.service-name" -}}
{{- $fullname := printf "%s-%s" (include "traefik.fullname" .root) .name -}}
{{- if eq .name "default" -}}
{{- $fullname = include "traefik.fullname" .root -}}
{{- end -}}
{{- if ge (len $fullname) 60 -}} # 64 - 4 (udp-postfix) = 60
{{- fail "ERROR: Cannot create a service whose full name contains more than 60 characters" -}}
{{- end -}}
{{- $fullname -}}
{{- end -}}
{{- define "traefik.service-metadata" }}
labels:
{{- include "traefik.labels" .root | nindent 4 -}}
{{- with .service.labels }}
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}
{{- define "traefik.service-spec" -}}
{{- $type := default "LoadBalancer" .service.type }}
type: {{ $type }}
{{- with .service.loadBalancerClass }}
loadBalancerClass: {{ . }}
{{- end}}
{{- with .service.spec }}
{{- toYaml . | nindent 2 }}
{{- end }}
selector:
{{- include "traefik.labelselector" .root | nindent 4 }}
{{- if eq $type "LoadBalancer" }}
{{- with .service.loadBalancerSourceRanges }}
loadBalancerSourceRanges:
{{- toYaml . | nindent 2 }}
{{- end -}}
{{- end -}}
{{- with .service.externalIPs }}
externalIPs:
{{- toYaml . | nindent 2 }}
{{- end -}}
{{- with .service.ipFamilyPolicy }}
ipFamilyPolicy: {{ . }}
{{- end }}
{{- with .service.ipFamilies }}
ipFamilies:
{{- toYaml . | nindent 2 }}
{{- end -}}
{{- end }}
{{- define "traefik.service-ports" }}
{{- range $name, $config := .ports }}
{{- if (index (default dict $config.expose) $.serviceName) }}
{{- $port := default $config.port $config.exposedPort }}
{{- if empty $port }}
{{- fail (print "ERROR: Cannot create " (trim $name) " port on Service without .port or .exposedPort") }}
{{- end }}
- port: {{ $port }}
name: {{ $name | quote }}
targetPort: {{ default $name $config.targetPort }}
protocol: {{ default "TCP" $config.protocol }}
{{- if $config.nodePort }}
nodePort: {{ $config.nodePort }}
{{- end }}
{{- if $config.appProtocol }}
appProtocol: {{ $config.appProtocol }}
{{- end }}
{{- if and ($config.http3).enabled ($config.single) }}
{{- $http3Port := default $config.exposedPort $config.http3.advertisedPort }}
- port: {{ $http3Port }}
name: "{{ $name }}-http3"
targetPort: "{{ $name }}-http3"
protocol: UDP
{{- if $config.nodePort }}
nodePort: {{ $config.nodePort }}
{{- end }}
{{- if $config.appProtocol }}
appProtocol: {{ $config.appProtocol }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,58 @@
{{- if and .Values.deployment.enabled (eq .Values.deployment.kind "DaemonSet") -}}
{{- with .Values.additionalArguments -}}
{{- range . -}}
{{- if contains ".acme." . -}}
{{- fail (printf "ACME functionality is not supported when running Traefik as a DaemonSet") -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- if eq (default .Chart.AppVersion .Values.image.tag) "latest" }}
{{- fail "\n\n ERROR: latest tag should not be used" }}
{{- end }}
{{- with .Values.updateStrategy }}
{{- if and (eq (.type) "RollingUpdate") (.rollingUpdate) }}
{{- if not (contains "%" (toString .rollingUpdate.maxUnavailable)) }}
{{- if and ($.Values.hostNetwork) (lt (float64 .rollingUpdate.maxUnavailable) 1.0) }}
{{- fail "maxUnavailable should be greater than 1 when using hostNetwork." }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: {{ template "traefik.fullname" . }}
namespace: {{ template "traefik.namespace" . }}
labels:
{{- include "traefik.labels" . | nindent 4 }}
{{- with .Values.deployment.labels }}
{{- toYaml . | nindent 4 }}
{{- end }}
annotations:
{{- if and .Values.providers.file.enabled (not .Values.providers.file.watch) }}
checksum/traefik-dynamic-conf: {{ include (print $.Template.BasePath "/provider-file-cm.yaml") . | sha256sum }}
{{- end }}
{{- with .Values.deployment.annotations }}
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
selector:
matchLabels:
{{- include "traefik.labelselector" . | nindent 6 }}
{{- with .Values.updateStrategy }}
updateStrategy:
type: {{ .type }}
{{- if (eq .type "RollingUpdate") }}
rollingUpdate:
maxUnavailable: {{ .rollingUpdate.maxUnavailable }}
maxSurge: {{ .rollingUpdate.maxSurge }}
{{- end }}
{{- end }}
minReadySeconds: {{ .Values.deployment.minReadySeconds }}
{{- if .Values.deployment.revisionHistoryLimit }}
revisionHistoryLimit: {{ .Values.deployment.revisionHistoryLimit }}
{{- end }}
template: {{ template "traefik.podTemplate" . }}
{{- end -}}

View File

@@ -0,0 +1,58 @@
{{/* check helm version */}}
{{- if (semverCompare "<v3.9.0" (.Capabilities.HelmVersion.Version | default "v3.0.0")) -}}
{{- fail "ERROR: Helm >= 3.9.0 is required" -}}
{{- end -}}
{{- if and .Values.deployment.enabled (eq .Values.deployment.kind "Deployment") -}}
{{- if gt (int .Values.deployment.replicas) 1 -}}
{{- with .Values.additionalArguments -}}
{{- range . -}}
{{- if contains ".acme." . -}}
{{- fail (printf "You can not enable acme if you set more than one traefik replica") -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- if eq (default .Chart.AppVersion .Values.image.tag) "latest" }}
{{- fail "\n\n ERROR: latest tag should not be used" }}
{{- end }}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ template "traefik.fullname" . }}
namespace: {{ template "traefik.namespace" . }}
labels:
{{- include "traefik.labels" . | nindent 4 }}
{{- with .Values.deployment.labels }}
{{- toYaml . | nindent 4 }}
{{- end }}
annotations:
{{- if and .Values.providers.file.enabled (not .Values.providers.file.watch) }}
checksum/traefik-dynamic-conf: {{ include (print $.Template.BasePath "/provider-file-cm.yaml") . | sha256sum }}
{{- end }}
{{- with .Values.deployment.annotations }}
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if not .Values.autoscaling.enabled }}
replicas: {{ default 1 .Values.deployment.replicas }}
{{- end }}
{{- if .Values.deployment.revisionHistoryLimit }}
revisionHistoryLimit: {{ .Values.deployment.revisionHistoryLimit }}
{{- end }}
selector:
matchLabels:
{{- include "traefik.labelselector" . | nindent 6 }}
{{- with .Values.updateStrategy }}
strategy:
type: {{ .type }}
{{- if (eq .type "RollingUpdate") }}
rollingUpdate:
maxUnavailable: {{ .rollingUpdate.maxUnavailable }}
maxSurge: {{ .rollingUpdate.maxSurge }}
{{- end }}
{{- end }}
minReadySeconds: {{ .Values.deployment.minReadySeconds }}
template: {{ template "traefik.podTemplate" . }}
{{- end -}}

View File

@@ -0,0 +1,4 @@
{{- range .Values.extraObjects }}
---
{{ include "traefik.render" (dict "value" . "context" $) }}
{{- end }}

View File

@@ -0,0 +1,62 @@
{{- if and (.Values.gateway).enabled (.Values.providers.kubernetesGateway).enabled }}
{{- if not .Values.gateway.listeners }}
{{- fail "ERROR: gateway must have at least one listener or should be disabled" }}
{{- end }}
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: {{ default "traefik-gateway" .Values.gateway.name }}
namespace: {{ template "traefik.namespace" . }}
labels:
{{- include "traefik.labels" . | nindent 4 }}
{{- with .Values.gateway.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
gatewayClassName: {{ default "traefik" .Values.gatewayClass.name }}
{{- with .Values.gateway.infrastructure }}
infrastructure:
{{ toYaml . | nindent 4 }}
{{- end }}
listeners:
{{- range $name, $config := .Values.gateway.listeners }}
- name: {{ $name }}
{{ if not .port }}
{{- fail "ERROR: port needs to be specified" }}
{{- end -}}
{{ $found := false }}
{{- range $portName, $portConfig := $.Values.ports -}}
{{- if eq $portConfig.port $config.port -}}
{{ $found = true }}
{{- end -}}
{{- end -}}
{{ if not $found }}
{{- fail (printf "ERROR: port %0.f is not declared in ports" .port ) }}
{{- end -}}
port: {{ .port }}
protocol: {{ .protocol }}
{{- with .hostname }}
hostname: {{ . | toYaml }}
{{- end }}
{{- with .namespacePolicy }}
allowedRoutes:
namespaces:
from: {{ . }}
{{- end }}
{{ if and (eq .protocol "HTTPS") (not .certificateRefs) }}
{{- fail "ERROR: certificateRefs needs to be specified using HTTPS" }}
{{- end }}
{{ if or .certificateRefs .mode }}
tls:
{{ with .mode }}
mode: {{ . }}
{{- end }}
{{ with .certificateRefs }}
certificateRefs:
{{- toYaml . | nindent 10 }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,14 @@
{{- if and (.Values.gatewayClass).enabled (.Values.providers.kubernetesGateway).enabled }}
---
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: {{ default "traefik" .Values.gatewayClass.name }}
labels:
{{- include "traefik.labels" . | nindent 4 }}
{{- with .Values.gatewayClass.labels }}
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
controllerName: traefik.io/gateway-controller
{{- end }}

View File

@@ -0,0 +1,35 @@
{{- if .Values.autoscaling.enabled }}
{{- if not .Values.autoscaling.maxReplicas }}
{{- fail "ERROR: maxReplicas is required on HPA" }}
{{- end }}
{{- if semverCompare ">=1.23.0-0" .Capabilities.KubeVersion.Version }}
apiVersion: autoscaling/v2
{{- else }}
apiVersion: autoscaling/v2beta2
{{- end }}
kind: HorizontalPodAutoscaler
metadata:
name: {{ template "traefik.fullname" . }}
namespace: {{ template "traefik.namespace" . }}
labels:
{{- include "traefik.labels" . | nindent 4 }}
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: {{ template "traefik.fullname" . }}
{{- if .Values.autoscaling.minReplicas }}
minReplicas: {{ .Values.autoscaling.minReplicas }}
{{- end }}
maxReplicas: {{ .Values.autoscaling.maxReplicas }}
{{- if .Values.autoscaling.metrics }}
metrics:
{{ toYaml .Values.autoscaling.metrics | indent 4 }}
{{- end }}
{{- if .Values.autoscaling.behavior }}
behavior:
{{ toYaml .Values.autoscaling.behavior | indent 4 }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,198 @@
{{- if .Values.hub.token -}}
{{- if .Values.hub.apimanagement.enabled }}
{{- $cert := include "traefik-hub.webhook_cert" . | fromYaml }}
---
apiVersion: v1
kind: Secret
type: kubernetes.io/tls
metadata:
name: hub-agent-cert
namespace: {{ template "traefik.namespace" . }}
labels:
{{- include "traefik.labels" . | nindent 4 }}
data:
tls.crt: {{ $cert.Cert }}
tls.key: {{ $cert.Key }}
---
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
name: hub-acp
labels:
{{- include "traefik.labels" . | nindent 4 }}
webhooks:
- name: admission.traefik.svc
clientConfig:
service:
name: admission
namespace: {{ template "traefik.namespace" . }}
path: /acp
caBundle: {{ $cert.Cert }}
sideEffects: None
admissionReviewVersions:
- v1
rules:
- operations:
- CREATE
- UPDATE
- DELETE
apiGroups:
- hub.traefik.io
apiVersions:
- v1alpha1
resources:
- accesscontrolpolicies
---
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
name: hub-api
labels:
{{- include "traefik.labels" . | nindent 4 }}
webhooks:
- name: hub-agent.traefik.portal
clientConfig:
service:
name: admission
namespace: {{ template "traefik.namespace" . }}
path: /api-portal
caBundle: {{ $cert.Cert }}
sideEffects: None
admissionReviewVersions:
- v1
rules:
- operations:
- CREATE
- UPDATE
- DELETE
apiGroups:
- hub.traefik.io
apiVersions:
- v1alpha1
resources:
- apiportals
- name: hub-agent.traefik.api
clientConfig:
service:
name: admission
namespace: {{ template "traefik.namespace" . }}
path: /api
caBundle: {{ $cert.Cert }}
sideEffects: None
admissionReviewVersions:
- v1
rules:
- operations:
- CREATE
- UPDATE
- DELETE
apiGroups:
- hub.traefik.io
apiVersions:
- v1alpha1
resources:
- apis
- name: hub-agent.traefik.access
clientConfig:
service:
name: admission
namespace: {{ template "traefik.namespace" . }}
path: /api-access
caBundle: {{ $cert.Cert }}
sideEffects: None
admissionReviewVersions:
- v1
rules:
- operations:
- CREATE
- UPDATE
- DELETE
apiGroups:
- hub.traefik.io
apiVersions:
- v1alpha1
resources:
- apiaccesses
- name: hub-agent.traefik.plan
clientConfig:
service:
name: admission
namespace: {{ template "traefik.namespace" . }}
path: /api-plan
caBundle: {{ $cert.Cert }}
sideEffects: None
admissionReviewVersions:
- v1
rules:
- operations:
- CREATE
- UPDATE
- DELETE
apiGroups:
- hub.traefik.io
apiVersions:
- v1alpha1
resources:
- apiplans
- name: hub-agent.traefik.bundle
clientConfig:
service:
name: admission
namespace: {{ template "traefik.namespace" . }}
path: /api-bundle
caBundle: {{ $cert.Cert }}
sideEffects: None
admissionReviewVersions:
- v1
rules:
- operations:
- CREATE
- UPDATE
- DELETE
apiGroups:
- hub.traefik.io
apiVersions:
- v1alpha1
resources:
- apibundles
- name: hub-agent.traefik.version
clientConfig:
service:
name: admission
namespace: {{ template "traefik.namespace" . }}
path: /api-version
caBundle: {{ $cert.Cert }}
sideEffects: None
admissionReviewVersions:
- v1
rules:
- operations:
- CREATE
- UPDATE
- DELETE
apiGroups:
- hub.traefik.io
apiVersions:
- v1alpha1
resources:
- apiversions
---
apiVersion: v1
kind: Service
metadata:
name: admission
namespace: {{ template "traefik.namespace" . }}
labels:
{{- include "traefik.labels" . | nindent 4 }}
spec:
ports:
- name: https
port: 443
targetPort: admission
selector:
{{- include "traefik.labelselector" . | nindent 4 }}
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,19 @@
{{- if .Values.hub.apimanagement.enabled }}
---
apiVersion: v1
kind: Service
metadata:
name: apiportal
namespace: {{ template "traefik.namespace" . }}
labels:
{{- include "traefik.labels" . | nindent 4 }}
spec:
ports:
- name: apiportal
port: 9903
protocol: TCP
targetPort: apiportal
selector:
{{- include "traefik.labelselector" . | nindent 4 }}
{{- end -}}

View File

@@ -0,0 +1,12 @@
{{- if .Values.ingressClass.enabled -}}
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
annotations:
ingressclass.kubernetes.io/is-default-class: {{ .Values.ingressClass.isDefaultClass | quote }}
labels:
{{- include "traefik.labels" . | nindent 4 }}
name: {{ .Values.ingressClass.name | default (include "traefik.fullname" .) }}
spec:
controller: traefik.io/ingress-controller
{{- end -}}

View File

@@ -0,0 +1,43 @@
{{ range $name, $config := .Values.ingressRoute }}
{{ if $config.enabled }}
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: {{ $.Release.Name }}-{{ $name }}
namespace: {{ template "traefik.namespace" $ }}
annotations:
{{- if and $.Values.ingressClass.enabled $.Values.providers.kubernetesCRD.enabled $.Values.providers.kubernetesCRD.ingressClass }}
kubernetes.io/ingress.class: {{ $.Values.providers.kubernetesCRD.ingressClass }}
{{- end }}
{{- with $config.annotations }}
{{- toYaml . | nindent 4 }}
{{- end }}
labels:
{{- include "traefik.labels" $ | nindent 4 }}
{{- with $config.labels }}
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
entryPoints:
{{- range $config.entryPoints }}
- {{ . }}
{{- end }}
routes:
- match: {{ $config.matchRule }}
kind: Rule
{{- with $config.services }}
services:
{{- toYaml . | nindent 6 }}
{{- end -}}
{{- with $config.middlewares }}
middlewares:
{{- toYaml . | nindent 6 }}
{{- end -}}
{{- with $config.tls }}
tls:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end -}}
{{ end }}

View File

@@ -0,0 +1,23 @@
{{- if .Values.podDisruptionBudget.enabled -}}
{{- if .Capabilities.APIVersions.Has "policy/v1/PodDisruptionBudget" }}
apiVersion: policy/v1
{{- else }}
apiVersion: policy/v1beta1
{{- end }}
kind: PodDisruptionBudget
metadata:
name: {{ template "traefik.fullname" . }}
namespace: {{ template "traefik.namespace" . }}
labels:
{{- include "traefik.labels" . | nindent 4 }}
spec:
selector:
matchLabels:
{{- include "traefik.labelselector" . | nindent 6 }}
{{- if .Values.podDisruptionBudget.minAvailable }}
minAvailable: {{ .Values.podDisruptionBudget.minAvailable }}
{{- end }}
{{- if .Values.podDisruptionBudget.maxUnavailable }}
maxUnavailable: {{ .Values.podDisruptionBudget.maxUnavailable }}
{{- end }}
{{- end -}}

View File

@@ -0,0 +1,28 @@
{{- if .Values.metrics.prometheus }}
{{- if (.Values.metrics.prometheus.prometheusRule).enabled }}
{{- if (not (.Capabilities.APIVersions.Has "monitoring.coreos.com/v1")) }}
{{- if (not (.Values.metrics.prometheus.disableAPICheck)) }}
{{- fail "ERROR: You have to deploy monitoring.coreos.com/v1 first" }}
{{- end }}
{{- end }}
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: {{ template "traefik.fullname" . }}
namespace: {{ .Values.metrics.prometheus.prometheusRule.namespace | default (include "traefik.namespace" .) }}
labels:
{{- include "traefik.labels" . | nindent 4 }}
{{- with .Values.metrics.prometheus.prometheusRule.additionalLabels }}
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if .Values.metrics.prometheus.prometheusRule.rules }}
groups:
- name: {{ template "traefik.name" $ }}
rules:
{{- with .Values.metrics.prometheus.prometheusRule.rules }}
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,12 @@
{{- if .Values.providers.file.enabled -}}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "traefik.fullname" . }}-file-provider
namespace: {{ template "traefik.namespace" . }}
labels:
{{- include "traefik.labels" . | nindent 4 }}
data:
config.yml:
{{ toYaml .Values.providers.file.content | nindent 4 }}
{{- end -}}

View File

@@ -0,0 +1,26 @@
{{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) -}}
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: {{ template "traefik.fullname" . }}
namespace: {{ template "traefik.namespace" . }}
annotations:
{{- with .Values.persistence.annotations }}
{{ toYaml . | nindent 4 }}
{{- end }}
helm.sh/resource-policy: keep
labels:
{{- include "traefik.labels" . | nindent 4 }}
spec:
accessModes:
- {{ .Values.persistence.accessMode | quote }}
resources:
requests:
storage: {{ .Values.persistence.size | quote }}
{{- if .Values.persistence.storageClass }}
storageClassName: {{ .Values.persistence.storageClass | quote }}
{{- end }}
{{- if .Values.persistence.volumeName }}
volumeName: {{ .Values.persistence.volumeName | quote }}
{{- end }}
{{- end -}}

View File

@@ -0,0 +1,271 @@
{{- $version := include "imageVersion" $ }}
{{- if and .Values.rbac.enabled (not .Values.rbac.namespaced) }}
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: {{ template "traefik.clusterRoleName" . }}
labels:
{{- include "traefik.labels" . | nindent 4 }}
{{- range .Values.rbac.aggregateTo }}
rbac.authorization.k8s.io/aggregate-to-{{ . }}: "true"
{{- end }}
rules:
{{- if semverCompare ">=v3.1.0-0" $version }}
- apiGroups:
- ""
resources:
- nodes
verbs:
- get
- list
- watch
{{- end }}
{{- if (semverCompare "<v3.1.0-0" $version) }}
- apiGroups:
- ""
resources:
- endpoints
- services
verbs:
- get
- list
- watch
{{- if $.Values.hub.token }}
- apiGroups:
- discovery.k8s.io
resources:
- endpointslices
verbs:
- get
- list
- watch
{{- end }}
{{- else }}
- apiGroups:
- ""
resources:
- services
verbs:
- get
- list
- watch
- apiGroups:
- discovery.k8s.io
resources:
- endpointslices
verbs:
- list
- watch
{{- end }}
- apiGroups:
- ""
resources:
- secrets
{{- with .Values.rbac.secretResourceNames }}
resourceNames: {{ toYaml . | nindent 6 }}
{{- end }}
verbs:
- get
- list
- watch
{{- if and .Values.hub.token }}
- update
- create
- delete
- deletecollection
{{- end }}
{{- if .Values.podSecurityPolicy.enabled }}
- apiGroups:
- policy
resourceNames:
- {{ template "traefik.fullname" . }}
resources:
- podsecuritypolicies
verbs:
- use
{{- end -}}
{{- if .Values.providers.kubernetesIngress.enabled }}
- apiGroups:
- extensions
- networking.k8s.io
resources:
- ingressclasses
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- extensions
- networking.k8s.io
resources:
- ingresses/status
verbs:
- update
{{- end -}}
{{- if .Values.providers.kubernetesCRD.enabled }}
- apiGroups:
- traefik.io
resources:
- ingressroutes
- ingressroutetcps
- ingressrouteudps
- middlewares
- middlewaretcps
- serverstransports
- serverstransporttcps
- tlsoptions
- tlsstores
- traefikservices
verbs:
- get
- list
- watch
{{- end -}}
{{- if (.Values.providers.kubernetesGateway).enabled }}
- apiGroups:
- ""
resources:
- namespaces
{{- if (semverCompare "<v3.1.0-0" $version) }}
- endpoints
{{- end }}
- secrets
- services
{{- if semverCompare ">=v3.2.0-0" $version }}
- configmaps
{{- end }}
verbs:
- get
- list
- watch
{{- if (semverCompare ">=v3.1.0-0" $version) }}
- apiGroups:
- discovery.k8s.io
resources:
- endpointslices
verbs:
- list
- watch
{{- end }}
- apiGroups:
- gateway.networking.k8s.io
resources:
{{- if semverCompare ">=v3.2.0-0" $version }}
- backendtlspolicies
{{- end }}
- gatewayclasses
- gateways
{{- if semverCompare ">=v3.2.0-0" $version }}
- grpcroutes
{{- end }}
- httproutes
- referencegrants
- tcproutes
- tlsroutes
verbs:
- get
- list
- watch
- apiGroups:
- gateway.networking.k8s.io
resources:
{{- if semverCompare ">=v3.2.0-0" $version }}
- backendtlspolicies/status
{{- end }}
- gatewayclasses/status
- gateways/status
{{- if semverCompare ">=v3.2.0-0" $version }}
- grpcroutes/status
{{- end }}
- httproutes/status
- tcproutes/status
- tlsroutes/status
verbs:
- update
{{- end }}
{{- if .Values.hub.token }}
- apiGroups:
- coordination.k8s.io
resources:
- leases
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
{{- end }}
{{- if .Values.hub.token }}
{{- if or (semverCompare ">=v3.1.0-0" $version) .Values.hub.apimanagement.enabled }}
- apiGroups:
- ""
resources:
- endpoints
verbs:
- list
- watch
{{- end }}
- apiGroups:
- ""
resources:
- namespaces
{{- if .Values.hub.apimanagement.enabled }}
- pods
{{- end }}
verbs:
- get
- list
{{- if .Values.hub.apimanagement.enabled }}
- watch
{{- end }}
{{- if .Values.hub.apimanagement.enabled }}
- apiGroups:
- hub.traefik.io
resources:
- accesscontrolpolicies
- apiaccesses
- apiportals
- apiratelimits
- apis
- apiversions
- apibundles
- apiplans
verbs:
- list
- watch
- create
- update
- patch
- delete
- get
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
- apiGroups:
- apps
resources:
- replicasets
verbs:
- get
- list
- watch
{{- if (semverCompare "<v3.1.0-0" $version) }}
- apiGroups:
- ""
resources:
- nodes
verbs:
- list
- watch
{{- end -}}
{{- end -}}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,17 @@
{{- if and .Values.rbac.enabled (not .Values.rbac.namespaced) }}
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: {{ template "traefik.clusterRoleName" . }}
labels:
{{- include "traefik.labels" . | nindent 4 }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ template "traefik.clusterRoleName" . }}
subjects:
- kind: ServiceAccount
name: {{ include "traefik.serviceAccountName" . }}
namespace: {{ template "traefik.namespace" . }}
{{- end -}}

View File

@@ -0,0 +1,68 @@
{{- if .Values.podSecurityPolicy.enabled }}
{{- if semverCompare ">=1.25.0-0" .Capabilities.KubeVersion.Version }}
{{- fail "ERROR: PodSecurityPolicy has been removed in Kubernetes v1.25+" }}
{{- end }}
---
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
annotations:
seccomp.security.alpha.kubernetes.io/allowedProfileNames: runtime/default
seccomp.security.alpha.kubernetes.io/defaultProfileName: runtime/default
name: {{ template "traefik.fullname" . }}
labels:
{{- include "traefik.labels" . | nindent 4 }}
spec:
privileged: false
allowPrivilegeEscalation: false
requiredDropCapabilities:
- ALL
{{- if not .Values.securityContext.runAsNonRoot }}
allowedCapabilities:
- NET_BIND_SERVICE
{{- end }}
hostNetwork: {{ .Values.hostNetwork }}
hostIPC: false
hostPID: false
fsGroup:
{{- if .Values.securityContext.runAsNonRoot }}
ranges:
- max: 65535
min: 1
rule: MustRunAs
{{- else }}
rule: RunAsAny
{{- end }}
{{- if .Values.hostNetwork }}
hostPorts:
- max: 65535
min: 1
{{- end }}
readOnlyRootFilesystem: true
runAsUser:
{{- if .Values.securityContext.runAsNonRoot }}
rule: MustRunAsNonRoot
{{- else }}
rule: RunAsAny
{{- end }}
seLinux:
rule: RunAsAny
supplementalGroups:
{{- if .Values.securityContext.runAsNonRoot }}
ranges:
- max: 65535
min: 1
rule: MustRunAs
{{- else }}
rule: RunAsAny
{{- end }}
volumes:
- configMap
- downwardAPI
- secret
- emptyDir
- projected
{{- if .Values.persistence.enabled }}
- persistentVolumeClaim
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,143 @@
{{- $version := include "imageVersion" $ }}
{{- $ingressNamespaces := concat (include "traefik.namespace" . | list) .Values.providers.kubernetesIngress.namespaces -}}
{{- $CRDNamespaces := concat (include "traefik.namespace" . | list) .Values.providers.kubernetesCRD.namespaces -}}
{{- $allNamespaces := sortAlpha (uniq (concat $ingressNamespaces $CRDNamespaces)) -}}
{{- if and .Values.rbac.enabled .Values.rbac.namespaced -}}
{{- range $allNamespaces }}
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: {{ template "traefik.fullname" $ }}
namespace: {{ . }}
labels:
{{- include "traefik.labels" $ | nindent 4 }}
rules:
{{- if (semverCompare "<v3.1.0-0" $version) }}
- apiGroups:
- ""
resources:
- endpoints
- services
verbs:
- get
- list
- watch
{{- else }}
- apiGroups:
- ""
resources:
- services
verbs:
- get
- list
- watch
- apiGroups:
- discovery.k8s.io
resources:
- endpointslices
verbs:
- list
- watch
{{- end }}
# Required while https://github.com/traefik/traefik/issues/7097#issuecomment-1983581843
- apiGroups:
- ""
resources:
- secrets
verbs:
- list
- apiGroups:
- ""
resources:
- secrets
{{- if gt (len $.Values.rbac.secretResourceNames) 0 }}
resourceNames: {{ $.Values.rbac.secretResourceNames }}
{{- end }}
verbs:
- get
- list
- watch
{{- if (and (has . $ingressNamespaces) $.Values.providers.kubernetesIngress.enabled) }}
- apiGroups:
- extensions
- networking.k8s.io
resources:
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- extensions
- networking.k8s.io
resources:
- ingresses/status
verbs:
- update
{{- end -}}
{{- if (and (has . $CRDNamespaces) $.Values.providers.kubernetesCRD.enabled) }}
- apiGroups:
- traefik.io
resources:
- ingressroutes
- ingressroutetcps
- ingressrouteudps
- middlewares
- middlewaretcps
- tlsoptions
- tlsstores
- traefikservices
- serverstransports
- serverstransporttcps
verbs:
- get
- list
- watch
{{- end -}}
{{- if $.Values.podSecurityPolicy.enabled }}
- apiGroups:
- extensions
resourceNames:
- {{ template "traefik.fullname" $ }}
resources:
- podsecuritypolicies
verbs:
- use
{{- end -}}
{{- if $.Values.hub.token }}
- apiGroups:
- ""
resources:
- services
- endpoints
- namespaces
- pods
verbs:
- get
- list
- watch
- apiGroups:
- discovery.k8s.io
resources:
- endpointslices
verbs:
- get
- list
- watch
- apiGroups:
- coordination.k8s.io
resources:
- leases
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
{{- end }}
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,25 @@
{{- $ingressNamespaces := concat (include "traefik.namespace" . | list) .Values.providers.kubernetesIngress.namespaces -}}
{{- $CRDNamespaces := concat (include "traefik.namespace" . | list) .Values.providers.kubernetesCRD.namespaces -}}
{{- $gatewayNamespaces := concat (include "traefik.namespace" . | list) ((.Values.providers.kubernetesGateway).namespaces) -}}
{{- $allNamespaces := sortAlpha (uniq (concat $ingressNamespaces $CRDNamespaces $gatewayNamespaces)) -}}
{{- if and .Values.rbac.enabled .Values.rbac.namespaced }}
{{- range $allNamespaces }}
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: {{ template "traefik.fullname" $ }}
namespace: {{ . }}
labels:
{{- include "traefik.labels" $ | nindent 4 }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: {{ template "traefik.fullname" $ }}
subjects:
- kind: ServiceAccount
name: {{ include "traefik.serviceAccountName" $ }}
namespace: {{ template "traefik.namespace" $ }}
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,14 @@
{{- if not .Values.serviceAccount.name -}}
kind: ServiceAccount
apiVersion: v1
metadata:
name: {{ include "traefik.serviceAccountName" . }}
namespace: {{ template "traefik.namespace" . }}
labels:
{{- include "traefik.labels" . | nindent 4 }}
annotations:
{{- with .Values.serviceAccountAnnotations }}
{{- toYaml . | nindent 4 }}
{{- end }}
automountServiceAccountToken: false
{{- end -}}

View File

@@ -0,0 +1,33 @@
{{- $version := include "imageVersion" $ }}
{{- if (ne $version "experimental-v3.0") }}
{{- if (semverCompare "<3.0.0-0" $version) }}
{{- fail "ERROR: This version of the Chart only supports Traefik Proxy v3" -}}
{{- end }}
{{- end }}
{{- if .Values.certResolvers }}
{{- fail "ERROR: certResolvers setting has been removed. See v33.0.0 Changelog." }}
{{- end }}
{{- if and .Values.hub.enabled (not (contains "traefik-hub" .Values.image.repository)) }}
{{- fail "ERROR: traefik-hub image is required when enabling Traefik Hub" -}}
{{- end }}
{{- if and (.Values.providers.kubernetesGateway).enabled (and (semverCompare "<3.1.0-rc3" $version) (not .Values.experimental.kubernetesGateway.enabled)) }}
{{- fail "ERROR: Before traefik v3.1.0-rc3, kubernetesGateway is experimental. Enable it by setting experimental.kubernetesGateway.enabled to true" -}}
{{- end }}
{{- if .Values.hub.token }}
{{- if and .Values.hub.apimanagement.enabled (and .Values.rbac.enabled .Values.rbac.namespaced) }}
{{- fail "ERROR: Currently Traefik Hub doesn't support namespaced RBACs" -}}
{{- end }}
{{- end }}
{{- if .Values.rbac.namespaced }}
{{- if .Values.providers.kubernetesGateway.enabled }}
{{- fail "ERROR: Kubernetes Gateway provider requires ClusterRole. RBAC cannot be namespaced." }}
{{- end }}
{{- if and (not .Values.providers.kubernetesIngress.enabled) (not .Values.providers.kubernetesCRD.enabled) }}
{{- fail "ERROR: namespaced rbac requires Kubernetes CRD or Kubernetes Ingress provider." }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,33 @@
{{- if .Values.metrics.prometheus }}
{{- if .Values.metrics.prometheus.service }}
{{- if (.Values.metrics.prometheus.service).enabled -}}
{{- $fullname := include "traefik.fullname" . }}
{{- if ge (len $fullname) 50 }}
{{- fail "ERROR: Cannot create a metrics service when name contains more than 50 characters" }}
{{- end }}
apiVersion: v1
kind: Service
metadata:
name: {{ template "traefik.service-name" (dict "root" . "name" "metrics") }}
namespace: {{ template "traefik.namespace" . }}
{{- template "traefik.metrics-service-metadata" . }}
annotations:
{{- with .Values.metrics.prometheus.service.annotations }}
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
type: ClusterIP
selector:
{{- include "traefik.labelselector" . | nindent 4 }}
ports:
- port: {{ .Values.ports.metrics.port }}
name: "metrics"
targetPort: metrics
protocol: TCP
{{- if .Values.ports.metrics.nodePort }}
nodePort: {{ .Values.ports.metrics.nodePort }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,86 @@
{{- $services := .Values.service.additionalServices -}}
{{- $services = set $services "default" (omit .Values.service "additionalServices") }}
{{- range $name, $service := $services -}}
{{- if ne $service.enabled false -}}
{{- $fullname := include "traefik.service-name" (dict "root" $ "name" $name) }}
{{- $tcpPorts := dict -}}
{{- $udpPorts := dict -}}
{{- $exposedPorts := false -}}
{{- range $portName, $config := $.Values.ports -}}
{{- if $config -}}
{{- if ($config.http3).enabled -}}
{{- if (not $config.tls.enabled) -}}
{{- fail "ERROR: You cannot enable http3 without enabling tls" -}}
{{- end -}}
{{ $udpConfig := deepCopy $config -}}
{{ $_ := set $udpConfig "protocol" "UDP" -}}
{{ $_ := set $udpConfig "exposedPort" (default $config.exposedPort $config.http3.advertisedPort) -}}
{{- if (not $service.single) }}
{{ $_ := set $udpPorts (printf "%s-http3" $portName) $udpConfig -}}
{{- else }}
{{ $_ := set $tcpPorts (printf "%s-http3" $portName) $udpConfig -}}
{{- end }}
{{- end -}}
{{- if eq (toString $config.protocol) "UDP" -}}
{{ $_ := set $udpPorts $portName $config -}}
{{- end -}}
{{- if eq (toString (default "TCP" $config.protocol)) "TCP" -}}
{{ $_ := set $tcpPorts $portName $config -}}
{{- end -}}
{{- if (index (default dict $config.expose) $name) -}}
{{- $exposedPorts = true -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- if (eq $exposedPorts false) -}}
{{- fail (printf "ERROR: Cannot create Service %s without ports" $fullname) -}}
{{- end -}}
{{- if and $exposedPorts (or $tcpPorts $service.single) }}
---
apiVersion: v1
kind: Service
metadata:
name: {{ $fullname }}
namespace: {{ template "traefik.namespace" $ }}
{{- template "traefik.service-metadata" (dict "root" $ "service" $service) }}
annotations:
{{- with (merge dict (default dict $service.annotationsTCP) (default dict $service.annotations)) }}
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- template "traefik.service-spec" (dict "root" $ "service" $service) }}
ports:
{{- template "traefik.service-ports" (dict "ports" $tcpPorts "serviceName" $name) }}
{{- if $service.single }}
{{- template "traefik.service-ports" (dict "ports" $udpPorts "serviceName" $name) }}
{{- end }}
{{- end }}
{{- if and $exposedPorts (and $udpPorts (not $service.single)) }}
{{- $ports := include "traefik.service-ports" (dict "ports" $udpPorts "serviceName" $name) }}
{{- if not (empty $ports) }}
---
apiVersion: v1
kind: Service
metadata:
name: {{ $fullname }}-udp
namespace: {{ template "traefik.namespace" $ }}
{{- template "traefik.service-metadata" (dict "root" $ "service" $service) }}
annotations:
{{- with (merge dict (default dict $service.annotationsUDP) (default dict $service.annotations)) }}
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- template "traefik.service-spec" (dict "root" $ "service" $service) }}
ports:
{{- $ports }}
{{- end }}
{{- end }}
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,69 @@
{{- if .Values.metrics.prometheus }}
{{- if (.Values.metrics.prometheus.serviceMonitor).enabled }}
{{- if (not (.Capabilities.APIVersions.Has "monitoring.coreos.com/v1")) }}
{{- if (not (.Values.metrics.prometheus.disableAPICheck)) }}
{{- fail "ERROR: You have to deploy monitoring.coreos.com/v1 first" }}
{{- end }}
{{- end }}
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: {{ template "traefik.fullname" . }}
namespace: {{ .Values.metrics.prometheus.serviceMonitor.namespace | default (include "traefik.namespace" .) }}
labels:
{{- if (.Values.metrics.prometheus.service).enabled }}
{{- include "traefik.metricsservicelabels" . | nindent 4 }}
{{- else }}
{{- include "traefik.labels" . | nindent 4 }}
{{- end }}
{{- with .Values.metrics.prometheus.serviceMonitor.additionalLabels }}
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
jobLabel: {{ .Values.metrics.prometheus.serviceMonitor.jobLabel | default .Release.Name }}
endpoints:
- targetPort: metrics
path: /{{ .Values.metrics.prometheus.entryPoint }}
{{- with .Values.metrics.prometheus.serviceMonitor.honorLabels }}
honorLabels: {{ . }}
{{- end }}
{{- with .Values.metrics.prometheus.serviceMonitor.honorTimestamps }}
honorTimestamps: {{ . }}
{{- end }}
{{- with .Values.metrics.prometheus.serviceMonitor.enableHttp2 }}
enableHttp2: {{ . }}
{{- end }}
{{- with .Values.metrics.prometheus.serviceMonitor.followRedirects }}
followRedirects: {{ . }}
{{- end }}
{{- with .Values.metrics.prometheus.serviceMonitor.interval }}
interval: {{ . }}
{{- end }}
{{- with .Values.metrics.prometheus.serviceMonitor.scrapeTimeout }}
scrapeTimeout: {{ . }}
{{- end }}
{{- if .Values.metrics.prometheus.serviceMonitor.metricRelabelings }}
metricRelabelings:
{{ tpl (toYaml .Values.metrics.prometheus.serviceMonitor.metricRelabelings | indent 6) . }}
{{- end }}
{{- if .Values.metrics.prometheus.serviceMonitor.relabelings }}
relabelings:
{{ toYaml .Values.metrics.prometheus.serviceMonitor.relabelings | indent 6 }}
{{- end }}
{{- if .Values.metrics.prometheus.serviceMonitor.namespaceSelector }}
namespaceSelector:
{{ toYaml .Values.metrics.prometheus.serviceMonitor.namespaceSelector | indent 4 -}}
{{ else }}
namespaceSelector:
matchNames:
- {{ template "traefik.namespace" . }}
{{- end }}
selector:
matchLabels:
{{- if (.Values.metrics.prometheus.service).enabled }}
{{- include "traefik.metricslabelselector" . | nindent 6 }}
{{- else }}
{{- include "traefik.labelselector" . | nindent 6 }}
{{- end }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,39 @@
{{- range $name, $config := .Values.tlsOptions }}
apiVersion: traefik.io/v1alpha1
kind: TLSOption
metadata:
name: {{ $name }}
namespace: {{ template "traefik.namespace" $ }}
labels:
{{- include "traefik.labels" $ | nindent 4 }}
{{- with $config.labels }}
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- with $config.alpnProtocols }}
alpnProtocols:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- with $config.cipherSuites }}
cipherSuites:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- with $config.clientAuth }}
clientAuth:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- with $config.curvePreferences }}
curvePreferences:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- with $config.maxVersion }}
maxVersion: {{ . }}
{{- end }}
{{- with $config.minVersion }}
minVersion: {{ . }}
{{- end }}
{{- with $config.sniStrict }}
sniStrict: {{ . }}
{{- end }}
---
{{- end -}}

View File

@@ -0,0 +1,12 @@
{{- range $name, $config := .Values.tlsStore }}
apiVersion: traefik.io/v1alpha1
kind: TLSStore
metadata:
name: {{ $name }}
namespace: {{ template "traefik.namespace" $ }}
labels:
{{- include "traefik.labels" $ | nindent 4 }}
spec:
{{- toYaml $config | nindent 2 }}
---
{{- end -}}