[keycloak-user] Keycloak and Kubernetes

Graham Burgess graham.burgess at razer.com
Fri Oct 5 16:02:33 EDT 2018


So just if you are curious, here is my values for the Keycloak Helm chart to get HA working with KUBE_PING and Keycloak 4.5:

  init:
    image:
      repository: alpine
      tag: 3.7
      pullPolicy: IfNotPresent

  keycloak:
    replicas: 3

    image:
      repository: jboss/keycloak
      tag: 4.5.0.Final
      pullPolicy: IfNotPresent

      ## Optionally specify an array of imagePullSecrets.
      ## Secrets must be manually created in the namespace.
      ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
      ##
      pullSecrets: []
      #  - myRegistrKeySecretName

    securityContext:
      runAsUser: 1000
      fsGroup: 1000
      runAsNonRoot: true

    ## The path keycloak will be served from. To serve keycloak from the root path, use two quotes (e.g. "").
    basepath: "auth"

    ## Additional init containers, e. g. for providing custom themes
    extraInitContainers: |-
      - name: pg-isready
        image: "{{ .Values.global.db.image }}:{{ .Values.global.db.tag }}"
        env:
        - name: POSTGRES_PASSWORD
          valueFrom:
            secretKeyRef:
              name: {{ .Release.Name }}-pg-auth
              key: POSTGRES_PASSWORD
        command:
        - sh
        - -c
        - |
          sleep 10; until pg_isready -h {{ .Release.Name }}-pg -U postgres -d postgres; do
            sleep 1;
          done;
          echo 'PostgreSQL OK ✓'

    ## Additional sidecar containers, e. g. for a database proxy, such as Google's cloudsql-proxy
    extraContainers: |

    ## Custom script that is run before Keycloak is started.
    preStartScript: |
      ln /opt/jboss/tools/docker-entrypoint.sh /opt/jboss/docker-entrypoint.sh
      exec /opt/jboss/docker-entrypoint.sh -b 0.0.0.0
      exit "$?"
    ## Additional arguments to start command e.g. -Dkeycloak.import= to load a realm
    extraArgs: ""

    ## Username for the initial Keycloak admin user
    username: keycloak

    ## Password for the initial Keycloak admin user
    ## If not set, a random 10 characters password will be used
    password: ""

    ## Allows the specification of additional environment variables for Keycloak
    extraEnv: |
      - name: KEYCLOAK_LOGLEVEL
        value: DEBUG
      - name: WILDFLY_LOGLEVEL
        value: DEBUG
      - name: PROXY_ADDRESS_FORWARDING
        value: "true"
      # - name: CACHE_OWNERS
      #   value: "2"
      - name: POD_NAMESPACE
        valueFrom:
          fieldRef:
            fieldPath: metadata.namespace
      - name: POD_NAME
        valueFrom:
          fieldRef:
            fieldPath: metadata.name
      - name: POD_IP
        valueFrom:
          fieldRef:
            fieldPath: status.podIP
      - name: JAVA_OPTS
        value: "-server -Xms128m -Xmx1024m -XX:MetaspaceSize=192M -XX:MaxMetaspaceSize=512m -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true"

    affinity: |
      podAntiAffinity:
        requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchLabels:
                app:  {{ template "keycloak.name" . }}
                release: "{{ .Release.Name }}"
              matchExpressions:
                - key: role
                  operator: NotIn
                  values:
                    - test
            topologyKey: kubernetes.io/hostname
        preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchLabels:
                  app:  {{ template "keycloak.name" . }}
                  release: "{{ .Release.Name }}"
                matchExpressions:
                  - key: role
                    operator: NotIn
                    values:
                      - test
              topologyKey: failure-domain.beta.kubernetes.io/zone

    nodeSelector: {}
    tolerations: []

    livenessProbe:
      initialDelaySeconds: 120
      timeoutSeconds: 5
    readinessProbe:
      initialDelaySeconds: 30
      timeoutSeconds: 1

    resources:
      limits:
        cpu: "1"
        memory: "4096Mi"
      requests:
        cpu: "500m"
        memory: "1024Mi"

    ## WildFly CLI configurations. They all end up in the file 'keycloak.cli' configured in the configmap whichn is
    ## executed on server startup.
    cli:
      ## Sets the node identifier to the node name (= pod name). Node identifiers have to be unique. They can have a
      ## maximum length of 23 characters. Thus, the chart's fullname template truncates its length accordingly.
      nodeIdentifier: |
        # Makes node identifier unique getting rid of a warning in the logs
        /subsystem=transactions:write-attribute(name=node-identifier, value=${jboss.node.name})

      logging: |
        # Allow log level to be configured via environment variable
        /subsystem=logging/console-handler=CONSOLE:write-attribute(name=level, value=${env.WILDFLY_LOGLEVEL:INFO})
        /subsystem=logging/root-logger=ROOT:write-attribute(name=level, value=${env.WILDFLY_LOGLEVEL:INFO})

        # Log only to console
        /subsystem=logging/root-logger=ROOT:write-attribute(name=handlers, value=[CONSOLE])

      reverseProxy: |
        /socket-binding-group=standard-sockets/socket-binding=proxy-https:add(port=443)
        /subsystem=undertow/server=default-server/http-listener=default:write-attribute(name=redirect-socket, value=proxy-https)
        /subsystem=undertow/server=default-server/http-listener=default:write-attribute(name=proxy-address-forwarding, value=true)

      # discovery: ""
      discovery: |
        /subsystem=infinispan/cache-container=keycloak/distributed-cache=sessions:write-attribute(name=owners, value=${env.CACHE_OWNERS:2})
        /subsystem=infinispan/cache-container=keycloak/distributed-cache=authenticationSessions:write-attribute(name=owners, value=${env.CACHE_OWNERS:2})
        /subsystem=infinispan/cache-container=keycloak/distributed-cache=offlineSessions:write-attribute(name=owners, value=${env.CACHE_OWNERS:2})
        /subsystem=infinispan/cache-container=keycloak/distributed-cache=loginFailures:write-attribute(name=owners, value=${env.CACHE_OWNERS:2})

        /subsystem=jgroups/stack=tcp:remove()
        /subsystem=jgroups/stack=tcp:add()
        /subsystem=jgroups/stack=tcp/transport=TCP:add(socket-binding="jgroups-tcp")
        /subsystem=jgroups/stack=tcp/protocol=kubernetes.KUBE_PING: add()
        /subsystem=jgroups/stack=tcp/protocol=kubernetes.KUBE_PING/property=namespace: add(value=${env.POD_NAMESPACE:default})
        /subsystem=jgroups/stack=tcp/protocol=MERGE3:add()
        /subsystem=jgroups/stack=tcp/protocol=FD_SOCK:add()
        /subsystem=jgroups/stack=tcp/protocol=FD_ALL:add()
        /subsystem=jgroups/stack=tcp/protocol=VERIFY_SUSPECT:add()
        /subsystem=jgroups/stack=tcp/protocol=pbcast.NAKACK2:add()
        /subsystem=jgroups/stack=tcp/protocol=UNICAST3:add()
        /subsystem=jgroups/stack=tcp/protocol=pbcast.STABLE:add()
        /subsystem=jgroups/stack=tcp/protocol=pbcast.GMS:add()
        /subsystem=jgroups/stack=tcp/protocol=MFC:add()
        /subsystem=jgroups/stack=tcp/protocol=FRAG2:add()


        /subsystem=jgroups/channel=ee:write-attribute(name=stack, value=tcp)
        /subsystem=jgroups/stack=udp:remove()
        /socket-binding-group=standard-sockets/socket-binding=jgroups-mping:remove()

        /interface=private:write-attribute(name=nic, value=eth0)
        /interface=private:undefine-attribute(name=inet-address)

      postgresql: ""
      # postgresql: |
      #   # Statements must be adapted for PostgreSQL. Additionally, we add a 'creation_timestamp' column.
      #   /subsystem=jgroups/stack=tcp/protocol=JDBC_PING/property=initialize_sql:add(value="CREATE TABLE IF NOT EXISTS JGROUPSPING (own_addr varchar(200) NOT NULL, creation_timestamp timestamp NOT NULL, cluster_name varchar(200) NOT NULL, ping_data bytea, constraint PK_JGROUPSPING PRIMARY KEY (own_addr, cluster_name))")
      #   /subsystem=jgroups/stack=tcp/protocol=JDBC_PING/property=insert_single_sql:add(value="INSERT INTO JGROUPSPING (own_addr, creation_timestamp, cluster_name, ping_data) values (?, NOW(), ?, ?)")

      # Custom CLI script
      custom: ""

    ## Add additional volumes and mounts, e. g. for custom themes
    extraVolumes: |
    extraVolumeMounts: |

    podDisruptionBudget: {}
      # maxUnavailable: 1
      # minAvailable: 1

    service:
      annotations: {}
      # service.beta.kubernetes.io/aws-load-balancer-internal: "0.0.0.0/0"

      labels: {}
      # key: value

      ## ServiceType
      ## ref: https://kubernetes.io/docs/user-guide/services/#publishing-services---service-types
      type: ClusterIP

      ## Optional static port assignment for service type NodePort.
      # nodePort: 30000

      port: 80

    ## Ingress configuration.
    ## ref: https://kubernetes.io/docs/user-guide/ingress/
    ingress:
      enabled: true
      path: /auth

      annotations:
        zalando.org/skipper-predicate: Source("34.218.139.139/32", "35.163.194.239/32", "52.39.154.222/32", "69.170.21.2/32", "71.6.10.107/32", "182.23.151.172/32", "202.73.58.90/32")

        # kubernetes.io/ingress.class: nginx
        # kubernetes.io/tls-acme: "true"
        # ingress.kubernetes.io/affinity: cookie

      ## List of hosts for the ingress
      hosts:
        - dev.domain.com


      ## TLS configuration
      tls: []
      # - hosts:
      #     - keycloak.example.com
      #   secretName: tls-keycloak

    ## Persistence configuration
    persistence:
      # If true, the Postgres chart is deployed
      deployPostgres: false

      # The database vendor. Can be either "postgres", "mysql", "mariadb", or "h2"
      dbVendor: postgres

      ## The following values only apply if "deployPostgres" is set to "false"

      # Specifies an existing secret to be used for the database password
      existingSecret: "auth-pg-auth"

      # The key in the existing secret that stores the password
      existingSecretKey: POSTGRES_PASSWORD

      dbHost: auth-pg
      dbPort: 5432
      dbName: postgres
      dbUser: postgres

      # Only used if no existing secret is specified. In this case a new secret is created
      dbPassword: ""

  test:
    image:
      repository: unguiculus/docker-python3-phantomjs-selenium
      tag: v1
      pullPolicy: IfNotPresent

Best regards,
Graham Burgess
RΛZΞR|stormmore
Sr. DevOps Engineer (USA)
Email: graham.burgess at razer.com
DID: (415) 374 0639
Razer Inc. Stock Code: 1337.HK
IMPORTANT NOTICE: This e-mail may be confidential, legally privileged or otherwise protected from disclosure. If you are not an intended recipient, do not copy, distribute or use its contents. Do inform the sender that you have received the message in error and delete it from your system. E-mails are not secure and may suffer errors, computer viruses, delay, interception and amendment. Razer accepts neither risk nor liability for any damage or loss caused by this e-mail. To the extent permitted by applicable law, Razer reserves the right to retain, monitor and intercept e-mails to and from its systems.

-----Original Message-----
From: keycloak-user-bounces at lists.jboss.org <keycloak-user-bounces at lists.jboss.org> On Behalf Of Graham Burgess
Sent: Thursday, October 4, 2018 8:58 AM
To: keycloak-user at lists.jboss.org; Fox, Kevin M <kevin.fox at pnnl.gov>
Subject: Re: [keycloak-user] Keycloak and Kubernetes

Totally would agree, that is how I became a OSS contributor.

I could have sworn the chart needed something but the docker container definitely needs work. It even looks like the did work on it for the containers too :)

Well that is today's project.

Graham


From: Fox, Kevin M
Sent: Thursday, October 4, 8:46 AM
Subject: RE: Keycloak and Kubernetes
To: Graham Burgess, keycloak-user at lists.jboss.org


Oh, and the upstream charts developers seem pretty open to contributions. so if you do have to jerry rig something, lets try and get that upstream? Either you could try or let me know what you did and maybe I can? Thanks, Kevin ________________________________________ From: Graham Burgess [graham.burgess at razer.com] Sent: Thursday, October 04, 2018 12:54 AM To: Fox, Kevin M; keycloak-user at lists.jboss.org Subject: RE: Keycloak and Kubernetes I don't know what is recommended, however I am in the process of using the Helm chart. That said, neither the Helm chart or the container used currently support HA, so I am going to be probably "jerry rigging" something to get that to work based on the work done in both. Best regards, Graham Burgess RΛZΞR|stormmore Sr. DevOps Engineer (USA) Email: graham.burgess at razer.com DID: (415) 374 0639 Razer Inc. Stock Code: 1337.HK IMPORTANT NOTICE: This e-mail may be confidential, legally privileged or otherwise protected from disclosure. If you are not an intended recipient, do not copy, distribute or use its contents. Do inform the sender that you have received the message in error and delete it from your system. E-mails are not secure and may suffer errors, computer viruses, delay, interception and amendment. Razer accepts neither risk nor liability for any damage or loss caused by this e-mail. To the extent permitted by applicable law, Razer reserves the right to retain, monitor and intercept e-mails to and from its systems. -----Original Message----- From: keycloak-user-bounces at lists.jboss.org On Behalf Of Fox, Kevin M Sent: Wednesday, October 3, 2018 4:36 PM To: keycloak-user at lists.jboss.org Subject: [keycloak-user] Keycloak and Kubernetes I saw in the most recent CNCF TOC meeting notes, that there is a good amount of Kubernetes/OpenShift based Keycloak deployments. How are these being done? The example demo youtube link looks to just be kubectling stuff. What is the recommended way to do this? Is the helm chart at github.com/helm/charts/tree/master/stable/keycloak the way this 
is usually done? Some other way? Thanks, Kevin _______________________________________________ keycloak-user mailing list keycloak-user at lists.jboss.org https://lists.jboss.org/mailman/listinfo/keycloak-user

_______________________________________________
keycloak-user mailing list
keycloak-user at lists.jboss.org
https://lists.jboss.org/mailman/listinfo/keycloak-user



More information about the keycloak-user mailing list