Keycloak Operator on a sub-path URL 404

91 views Asked by At

I am trying to deploy Keycloak using the operator onto a kubernetes cluster. I need the app to exist on '/auth' and not '/'. I am using the ingress-nginx ingress controller and creating the ingress using a helm template.

ingress-template.yaml:

{{- if .Values.auth.ingress.enabled -}}
{{- $fullName := printf "%s-%s" (include "appname.fullname" .) .Values.auth.name }}
{{- $svcPort := .Values.auth.service.port -}}
{{- if and .Values.auth.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
  {{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }}
  {{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.auth.ingress.className}}
  {{- end }}
{{- end }}
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}}
apiVersion: networking.k8s.io/v1
{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
apiVersion: networking.k8s.io/v1beta1
{{- else -}}
apiVersion: extensions/v1beta1
{{- end }}
kind: Ingress
metadata:
  name: {{ $fullName }}
  labels:
    {{- include "appname.labels" . | nindent 4 }}
  {{- with .Values.auth.ingress.annotations }}
  annotations:
    {{- toYaml . | nindent 4 }}
  {{- end }}
spec:
  {{- if and .Values.auth.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
  ingressClassName: {{ .Values.auth.ingress.className }}
  {{- end }}
  {{- if .Values.auth.ingress.tls }}
  tls:
    {{- range .Values.auth.ingress.tls }}
    - hosts:
        {{- range .hosts }}
        - {{ . | quote }}
        {{- end }}
      secretName: {{ .secretName }}
    {{- end }}
  {{- end }}
  rules:
    {{- range .Values.auth.ingress.hosts }}
    - host: {{ .host | quote }}
      http:
        paths:
          {{- range .paths }}
          - path: {{ .path }}
            {{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }}
            pathType: {{ .pathType }}
            {{- end }}
            backend:
              {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
              service:
                name: {{ $fullName }}-service
                port:
                  number: {{ $svcPort }}
              {{- else }}
              serviceName: {{ include "appname.fullname" . }}-{{ .Values.auth.name }}-service
              servicePort: {{ $svcPort }}
              {{- end }}
          {{- end }}
    {{- end }}
{{- end }}

keycloak-template.yaml:

apiVersion: k8s.keycloak.org/v2alpha1
kind: Keycloak
metadata:
  name: {{ include "appname.fullname" . }}-{{ .Values.auth.name }}
spec:
{{/**
  image: {{ .Values.auth.image.repository }}:{{ .Values.auth.image.tag }}
  **/}}
  ingress:
    enabled: false
  db:
    vendor: {{ .Values.auth.config.vendor }}
    usernameSecret:
      name: {{ .Values.auth.secret.name }}
      key: {{ .Values.auth.secret.usernameKey }}
    passwordSecret:
      name: {{ .Values.auth.secret.name }}
      key: {{ .Values.auth.secret.passwordKey }}
    host: "appname-{{ .Values.authdb.name }}.{{ .Release.Namespace }}.svc.cluster.local"
    database: {{ .Values.auth.config.dbname }}
    port: {{ .Values.authdb.config.dbport }}
    schema: {{ .Values.auth.config.schema }}
    poolInitialSize: 1
    poolMinSize: 1
    poolMaxSize: 3
  http:
    httpEnabled: true
    httpPort: {{ .Values.auth.service.port }}
    httpsPort: {{ .Values.auth.service.httpsPort }}
    tlsSecret: ingress-certificate
  hostname:
    strict: false
    strictBackchannel: false
  features:
    enabled:
      - docker
      - authorization
    disabled:
      - step-up-authentication
  transaction:
    xaEnabled: false

  unsupported:
    podTemplate:
      metadata:
        labels:
          {{- include "appname.labels" . | nindent 10 }}
          name: {{ include "appname.fullname" . }}-{{ .Values.auth.name }}
      spec:
        containers:
          - name: {{ include "appname.fullname" . }}-{{ .Values.auth.name }}
            env:
            {{/**}}
              - name: PROXY_ADDRESS_FORWARDING
                value: "{{ .Values.auth.extraEnv.proxyForwarding.value }}"
              - name: KC_HTTP_RELATIVE_PATH
                value: "/auth"
                **/}}
              - name: KC_PROXY
                value: "edge"
              - name: KC_EXTRA_ARGS
                value: "--proxy edge"
              - name: KC_HOSTNAME_PATH
                value: "/auth"
              - name: KC_LOG_LEVEL
                value: DEBUG
              - name: KC_HOSTNAME_URL
                value: "https://devapp.myapps.co.uk/auth"

values.yaml:

auth:
  name: auth
  replicaCount: 1
  image:
    tag: "1.42.1"
    repository: appname.azurecr.io/appname-keycloak
    pullPolicy: IfNotPresent

  extraEnv:
    proxyForwarding:
      value: "true"

  ingress:
    enabled: true
    className: nginx
    hosts:
      - host: prodapp.myapps.co.uk
        paths:
          - path: /auth
            pathType: Prefix
    annotations:
      nginx.ingress.kubernetes.io/use-regex: "true"
      nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
      nginx.ingress.kubernetes.io/ssl-redirect: "true"
      nginx.ingress.kubernetes.io/backend-protocol: HTTP
      nginx.ingress.kubernetes.io/protocol: http
      nginx.ingress.kubernetes.io/proxy-body-size: "0"
      nginx.ingress.kubernetes.io/proxy-http-version: "1.1"
      nginx.ingress.kubernetes.io/enable-cors: "true"
      nginx.ingress.kubernetes.io/cors-allow-headers: "X-Forwarded-*"
    tls: []

  config:
    name: auth-configmap
    dbname: database
    path: /auth
    vendor: postgres
    address: '{{ include "appname.fullname" . }}-{{ .Values.authdb.name }}.{{ .Release.Namespace }}.svc.cluster.local'
    schema: public
    dbhost: "appname-auth-database.appname.svc.cluster.local"

  secret:
    name: auth-database-env
    usernameKey: POSTGRES_USER
    passwordKey: POSTGRES_PASSWORD

  args: ["start-dev --import-realm"]

  probes:
    liveness: /auth/
    readiness: /auth/realms/master

  service:
    type: ClusterIP
    port: 8080
    httpsPort: 8443

  nodeSelector: {}
  tolerations: []
  affinity: {}
  serviceAccount:
    create: true
    annotations: {}
    name: ""

  podAnnotations: {}
  podSecurityContext: {}
  securityContext: {}

  resources: {}

  autoscaling:
    enabled: false
    minReplicas: 1
    maxReplicas: 100
    targetCPUUtilizationPercentage: 80

when I install the chart via helm everything appears to deploy fine, but every path I browse to under /auth is getting routed to the keycloak app running in its pod, but I am getting a 404 returned from keycloak for all resources. there are no other errors in the keycloak logs or the ingress controller logs.

any help on what I have misconfigured would be greatly appreciated :-)

I have tried configuring the ingress to do a target rewrite as opposed to configuring the web context of keycloak, meaning that keycloak expects traffic on '/' and the ingress controller rewrites URLS from '/auth' to '/' when forwarding traffic to the pod, however this results in keycloak writing URLS that need resolving on '/' so it doesn't work.

1

There are 1 answers

1
Aooo Rooo On

Try by changing

- name: KC_HTTP_RELATIVE_PATH
  value: "/keycloak"

to

- name: KC_HTTP_RELATIVE_PATH
  value: "/auth"

in keycloak-template.yaml file. It sets the path relative to / for serving resources.