From 63c5b401233a428e9ba83281f3c2ba4b9fa41dee Mon Sep 17 00:00:00 2001 From: Arlan Lloyd Date: Wed, 9 Apr 2025 05:13:29 +0000 Subject: [PATCH] initial add Traefik Signed-off-by: Arlan Lloyd --- chart/README.md | 18 ++- chart/templates/_helpers.tpl | 18 +++ chart/templates/traefikproxy/configmap.yaml | 55 ++++++++++ chart/templates/traefikproxy/deployment.yaml | 103 ++++++++++++++++++ chart/templates/traefikproxy/service.yaml | 28 +++++ .../traefikproxy/serviceaccount.yaml | 13 +++ chart/values.yaml | 33 ++++++ 7 files changed, 267 insertions(+), 1 deletion(-) create mode 100644 chart/templates/traefikproxy/configmap.yaml create mode 100644 chart/templates/traefikproxy/deployment.yaml create mode 100644 chart/templates/traefikproxy/service.yaml create mode 100644 chart/templates/traefikproxy/serviceaccount.yaml diff --git a/chart/README.md b/chart/README.md index 76eee5c8..5a26d6e8 100644 --- a/chart/README.md +++ b/chart/README.md @@ -106,4 +106,20 @@ stringData: Kyoo consists of multiple microservices. Best practice is for each microservice to use its own database. Kyoo workloads support best practices or sharing a single postgres database. Please see the `POSTGRES_SCHEMA` setting for additional information. Strongly recomended to use a Kubernetes operator for managing Postgres. ## Subchart Support -Subcharts are updated frequently and subject to changes. This chart includes subcharts for deploying Meilisearch, PostgreSQL, and RabbitMQ. Please consider hosting those independently of Kyoo to better handle versioning and lifecycle management. \ No newline at end of file +Subcharts are updated frequently and subject to changes. This chart includes subcharts for deploying Meilisearch, PostgreSQL, and RabbitMQ. Please consider hosting those independently of Kyoo to better handle versioning and lifecycle management. + +# v5 Traefik Requirement +Starting with v5, Kyoo leverages ForwardAuth middleware for offloading auth from the microservices onto a gateway. ForwardAuth is currently a custom specification implemented by Traefik and could be generalized as GatewayAPI spec matures. For additional reading, please see gateway-api sigs [documentation](https://gateway-api.sigs.k8s.io/geps/gep-1494/?h=auth#currently-implemented-auth-mechanisms-in-implementations). + +In order for Kyoo to function there needs to Traefik proxy included somewhere in the network. There are several ways to accomplish this. + +## Additional Hop (Default) +Using the existing IngressController/GatewayController, we deploy a Traefik instance dedicated towards handling Kyoo's traffic. This avoids needing to add more operators/controllers into the cluster. + +Using this approach, we can offload the TLS certificate to the existing controller and reduces the configuration needed in Traefik. + +## Direct to Traefik +Instead of adding additional hop, Traefik can be exposed via LoadBalancer. To do this securely, please be sure to mount and configuring the TLS certificate inside of Traefik. + +## Add Traefik as IngressController/GatewayController +Disable the integrated Traefik and adopt Traefik into your cluster. This option will offer the most Kubernetes native experience. \ No newline at end of file diff --git a/chart/templates/_helpers.tpl b/chart/templates/_helpers.tpl index a8b62d96..11868d58 100644 --- a/chart/templates/_helpers.tpl +++ b/chart/templates/_helpers.tpl @@ -127,3 +127,21 @@ Create kyoo transcoder-metadata name {{- define "kyoo.transcodermetadata.fullname" -}} {{- printf "%s-%s%s" (include "kyoo.fullname" .) .Values.transcoder.name "metadata" | trunc 63 | trimSuffix "-" -}} {{- end -}} + +{{/* +Create kyoo traefikproxy name +*/}} +{{- define "kyoo.traefikproxy.fullname" -}} +{{- printf "%s-%s" (include "kyoo.fullname" .) .Values.traefikproxy.name | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create the name of the traefikproxy service account to use +*/}} +{{- define "kyoo.traefikproxy.serviceAccountName" -}} +{{- if .Values.traefikproxy.serviceAccount.create -}} + {{ default (include "kyoo.traefikproxy.fullname" .) .Values.traefikproxy.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.traefikproxy.serviceAccount.name }} +{{- end -}} +{{- end -}} \ No newline at end of file diff --git a/chart/templates/traefikproxy/configmap.yaml b/chart/templates/traefikproxy/configmap.yaml new file mode 100644 index 00000000..a63a0501 --- /dev/null +++ b/chart/templates/traefikproxy/configmap.yaml @@ -0,0 +1,55 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "kyoo.traefikproxy.fullname" . }} + labels: + {{- include "kyoo.labels" (dict "context" . "component" .Values.traefikproxy.name "name" .Values.traefikproxy.name) | nindent 4 }} + {{- with (mergeOverwrite (deepCopy .Values.global.configmapAnnotations) .Values.traefikproxy.configmapAnnotations) }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} +data: + # TODO: finish templating + # can probably remove host rules, since this will only be infront of Kyoo + # WILL ONLY SUPPORT WEB BY DEFAULT + # forwardAuth.address will be taken from $values.kyoo.address + dynamic_config.yaml: | + http: + routers: + phantomtest-basepath: + entryPoints: + - web + middlewares: + - phantomtest-api + service: phantomtest-api + rule: "Host(`pt2.bitey.life`) && PathPrefix(`/`)" + phantomtest-wellknown: + entryPoints: + - web + service: phantomtest-auth + rule: "Host(`pt2.bitey.life`) && PathPrefix(`/.well-known/`)" + phantomtest-auth: + entryPoints: + - web + service: phantomtest-auth + rule: "Host(`pt2.bitey.life`) && PathPrefix(`/auth`)" + middlewares: + phantomtest-api: + forwardAuth: + address: "http://pt2.bitey.life/auth/jwt" + authRequestHeaders: + - "Authorization" + - "X-Api-Key" + authResponseHeaders: + - Authorization + services: + phantomtest-api: + loadBalancer: + servers: + - url: http://phantomtest-api.phantomtest.svc.cluster.local:3000/ + phantomtest-auth: + loadBalancer: + servers: + - url: http://phantomtest-auth.phantomtest.svc.cluster.local:8080/ \ No newline at end of file diff --git a/chart/templates/traefikproxy/deployment.yaml b/chart/templates/traefikproxy/deployment.yaml new file mode 100644 index 00000000..f5543297 --- /dev/null +++ b/chart/templates/traefikproxy/deployment.yaml @@ -0,0 +1,103 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + {{- with (mergeOverwrite (deepCopy .Values.global.deploymentAnnotations) .Values.traefikproxy.deploymentAnnotations) }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} + name: {{ include "kyoo.traefikproxy.fullname" . }} + labels: + {{- include "kyoo.labels" (dict "context" . "component" .Values.traefikproxy.name "name" .Values.traefikproxy.name) | nindent 4 }} +spec: + replicas: {{ .Values.traefikproxy.replicaCount }} + {{- with .Values.traefikproxy.updateStrategy }} + strategy: + {{- toYaml . | nindent 4 }} + {{- end }} + selector: + matchLabels: + {{- include "kyoo.selectorLabels" (dict "context" . "name" .Values.traefikproxy.name) | nindent 6 }} + template: + metadata: + {{- with (mergeOverwrite (deepCopy .Values.global.podAnnotations) .Values.traefikproxy.podAnnotations) }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} + labels: + {{- include "kyoo.labels" (dict "context" . "component" .Values.traefikproxy.name "name" .Values.traefikproxy.name) | nindent 8 }} + {{- with (mergeOverwrite (deepCopy .Values.global.podLabels) .Values.traefikproxy.podLabels) }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- with .Values.traefikproxy.imagePullSecrets | default .Values.global.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.global.securityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "kyoo.traefikproxy.serviceAccountName" . }} + containers: + - name: main + image: {{ .Values.traefikproxy.traefik.image.repository | default (printf "%s/traefikproxy" .Values.global.image.repositoryBase) }}:{{ default (include "kyoo.defaultTag" .) .Values.traefikproxy.traefik.image.tag }} + imagePullPolicy: {{ default .Values.global.image.imagePullPolicy }} + args: + {{- with .Values.traefikproxy.traefik.extraArgs }} + {{- toYaml . | nindent 12 }} + {{- end }} + env: + {{- with (concat .Values.global.extraEnv .Values.traefikproxy.traefik.extraEnv) }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: web + containerPort: 80 + protocol: TCP + - name: websecure + containerPort: 443 + protocol: TCP + - name: traefik + containerPort: 8080 + protocol: TCP + {{- with .Values.traefikproxy.traefik.livenessProbe }} + livenessProbe: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.traefikproxy.traefik.readinessProbe }} + readinessProbe: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.traefikproxy.traefik.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.traefikproxy.traefik.containerSecurityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + {{- with .Values.traefikproxy.traefik.volumeMounts }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.traefikproxy.traefik.extraVolumeMounts }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.traefikproxy.extraContainers }} + {{- tpl (toYaml .) $ | nindent 8 }} + {{- end }} + {{- with .Values.traefikproxy.extraInitContainers }} + initContainers: + {{- tpl (toYaml .) $ | nindent 6 }} + {{- end }} + volumes: + {{- with .Values.traefikproxy.volumes }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.traefikproxy.extraVolumes }} + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/chart/templates/traefikproxy/service.yaml b/chart/templates/traefikproxy/service.yaml new file mode 100644 index 00000000..6737a5a1 --- /dev/null +++ b/chart/templates/traefikproxy/service.yaml @@ -0,0 +1,28 @@ +apiVersion: v1 +kind: Service +metadata: +{{- if .Values.traefikproxy.service.annotations }} + annotations: + {{- range $key, $value := .Values.traefikproxy.service.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} +{{- end }} + name: {{ include "kyoo.traefikproxy.fullname" . }} + labels: + {{- include "kyoo.labels" (dict "context" . "component" .Values.traefikproxy.name "name" .Values.traefikproxy.name) | nindent 4 }} + {{- with .Values.traefikproxy.service.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + type: {{ .Values.traefikproxy.service.type }} + ports: + - port: 80 + targetPort: 80 + protocol: TCP + name: web + - port: 443 + targetPort: 443 + protocol: TCP + name: websecure + selector: + {{- include "kyoo.selectorLabels" (dict "context" . "name" .Values.traefikproxy.name) | nindent 4 }} diff --git a/chart/templates/traefikproxy/serviceaccount.yaml b/chart/templates/traefikproxy/serviceaccount.yaml new file mode 100644 index 00000000..5ae35f9b --- /dev/null +++ b/chart/templates/traefikproxy/serviceaccount.yaml @@ -0,0 +1,13 @@ +{{- if .Values.traefikproxy.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +automountServiceAccountToken: {{ .Values.traefikproxy.serviceAccount.automount }} +metadata: + name: {{ include "kyoo.traefikproxy.serviceAccountName" . }} + labels: + {{- include "kyoo.labels" (dict "context" . "component" .Values.traefikproxy.name "name" .Values.traefikproxy.name) | nindent 4 }} + {{- with .Values.traefikproxy.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/chart/values.yaml b/chart/values.yaml index 2c81cde5..25dae7d0 100644 --- a/chart/values.yaml +++ b/chart/values.yaml @@ -8,6 +8,7 @@ global: tag: "" imagePullPolicy: IfNotPresent imagePullSecrets: [] + configmapAnnotations: {} deploymentAnnotations: {} persistentVolumeClaimAnnotations: {} podAnnotations: {} @@ -427,6 +428,38 @@ ingress: tls: false tlsSecret: ~ +# traefikproxy deployment configuration +traefikproxy: + enabled: true + name: traefik + # traefik container configuration + traefik: + livenessProbe: {} + readinessProbe: {} + resources: {} + containerSecurityContext: {} + extraVolumeMounts: [] + extraArgs: [] + extraEnv: [] + image: + repository: ~ + tag: ~ + replicaCount: 1 + updateStrategy: ~ + podLabels: {} + configmapAnnotations: {} + deploymentAnnotations: {} + podAnnotations: {} + imagePullSecrets: [] + serviceAccount: + create: true + automount: true + annotations: {} + name: ~ + extraContainers: [] + extraInitContainers: [] + extraVolumes: [] + # subchart settings meilisearch: enabled: false