diff --git a/.ci/auth/keycloak/values.yaml b/.ci/auth/keycloak/values.yaml index 83340080..a9aaa03f 100644 --- a/.ci/auth/keycloak/values.yaml +++ b/.ci/auth/keycloak/values.yaml @@ -32,3 +32,15 @@ extraVolumeMounts: - name: realm-config mountPath: "/opt/bitnami/keycloak/data/import" readOnly: true + +# Fix for https://github.com/bitnami/charts/issues/35164 +global: + security: + allowInsecureImages: true +image: + repository: bitnamilegacy/keycloak + tag: 26.2.3-debian-12-r0 +postgresql: + image: + repository: bitnamilegacy/postgresql + tag: 17.4.0-debian-12-r17 diff --git a/.ci/clusters/values-dekaf.yaml b/.ci/clusters/values-dekaf.yaml new file mode 100644 index 00000000..c3c06ec0 --- /dev/null +++ b/.ci/clusters/values-dekaf.yaml @@ -0,0 +1,24 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +components: + dekaf: true +dekaf: + persistence: + enabled: false \ No newline at end of file diff --git a/.github/workflows/pulsar-helm-chart-ci.yaml b/.github/workflows/pulsar-helm-chart-ci.yaml index 6e4b8be7..107a69ae 100644 --- a/.github/workflows/pulsar-helm-chart-ci.yaml +++ b/.github/workflows/pulsar-helm-chart-ci.yaml @@ -224,6 +224,9 @@ jobs: - name: ZK & BK TLS Only values_file: .ci/clusters/values-zkbk-tls.yaml shortname: zkbk-tls + - name: Dekaf + values_file: .ci/clusters/values-dekaf.yaml + shortname: dekaf - name: Pulsar Manager values_file: .ci/clusters/values-pulsar-manager.yaml shortname: pulsar-manager diff --git a/README.md b/README.md index b877cfde..3f9e27cd 100644 --- a/README.md +++ b/README.md @@ -325,8 +325,32 @@ zookeeper: This is shown in some [examples/values-disable-monitoring.yaml](examples/values-disable-monitoring.yaml). +## Dekaf UI + +[Dekaf](github.com/visortelle/dekaf) is a new open-source UI for Apache Pulsar. + +> :warning: At this moment Dekaf doesn't have built-in authentication. In order to prevent unwanted access, it relies on authentication on the Pulsar broker side. +> If your Pulsar instance stores sensitive data, make sure that: +> - You have configured authentication on the Pulsar side +> - Dekaf isn't accessible from the Internet +> - Only authorized persons have access to you Kubernetes namespace +> Improvements in this area are planned to be implemented later. + +To enable the Dekaf component: + +- Set the `components.dekaf` property to `true` in the Helm release `values.yaml` file. +- Run the following command to make Dekaf service accessible on your local machine. + +``` +kubectl port-forward svc/$(kubectl get svc -l component=dekaf -o jsonpath='{.items[0].metadata.name}') 8090:8090 +``` + +- Open in browser. + ## Pulsar Manager +> :warning: Pulsar Manager has been poorly maintained for a long time. Consider the Dekaf UI instead. + The Pulsar Manager can be deployed alongside the pulsar cluster instance. Depending on the given settings it uses an existing Secret within the given namespace or creates a new one, with random passwords for both, the UI and the internal database. diff --git a/charts/pulsar/templates/_dekaf.tpl b/charts/pulsar/templates/_dekaf.tpl new file mode 100644 index 00000000..7ccf432d --- /dev/null +++ b/charts/pulsar/templates/_dekaf.tpl @@ -0,0 +1,22 @@ +{{/* +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +*/}} + +{{- define "dekaf.component" -}} +{{ (.Values.dekaf).component | default "dekaf" }} +{{- end }} diff --git a/charts/pulsar/templates/dekaf-deployment.yaml b/charts/pulsar/templates/dekaf-deployment.yaml new file mode 100644 index 00000000..67402c71 --- /dev/null +++ b/charts/pulsar/templates/dekaf-deployment.yaml @@ -0,0 +1,113 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +{{- if .Values.components.dekaf }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "pulsar.fullname" . }}-{{ template "dekaf.component" . }} + namespace: {{ template "pulsar.namespace" . }} + labels: + {{- include "pulsar.standardLabels" . | nindent 4 }} + component: {{ template "dekaf.component" . }} + annotations: + {{- toYaml (((.Values.dekaf).deployment).annotations | default dict) | nindent 4 }} +spec: + replicas: 1 + selector: + matchLabels: + {{- include "pulsar.matchLabels" . | nindent 6 }} + component: {{ template "dekaf.component" . }} + strategy: + type: Recreate + template: + metadata: + labels: + {{- include "pulsar.template.labels" . | nindent 8 }} + component: {{ template "dekaf.component" . }} + annotations: {{ ((.Values.dekaf).deployment).podAnnotations | default dict | toYaml | nindent 8 }} + spec: + {{- if ((.Values.dekaf).deployment).nodeSelector }} + nodeSelector: + {{ toYaml .Values.dekaf.deployment.nodeSelector | default dict | indent 10 }} + {{- end }} + + {{- if ((.Values.dekaf).deployment).tolerations }} + tolerations: + {{ toYaml .Values.dekaf.deployment.tolerations | default list | indent 8 }} + {{- end }} + + containers: + - name: dekaf + image: "{{ .Values.images.dekaf.repository }}:{{ .Values.images.dekaf.tag }}" + imagePullPolicy: "{{ template "pulsar.imagePullPolicy" (dict "image" .Values.images.dekaf "root" .) }}" + env: + - name: DEKAF_PULSAR_WEB_URL + value: "http://{{ template "pulsar.fullname" . }}-{{ .Values.broker.component }}:{{ .Values.broker.ports.http }}" + - name: DEKAF_PULSAR_BROKER_URL + value: "pulsar://{{ template "pulsar.fullname" . }}-{{ .Values.broker.component }}:{{ .Values.broker.ports.pulsar }}" + + {{- if ((.Values.dekaf).deployment).extraEnv }} + {{- toYaml .Values.dekaf.deployment.extraEnv | default list | nindent 10 }} + {{- end }} + + ports: + - containerPort: 8090 + name: http + + {{- if ((.Values.dekaf).deployment).resources }} + resources: + {{- toYaml .Values.dekaf.deployment.resources | nindent 12 }} + {{- end }} + + {{- if ((.Values.dekaf).deployment).livenessProbe }} + livenessProbe: + {{- toYaml .Values.dekaf.deployment.livenessProbe | nindent 12 }} + {{- end }} + + {{- if ((.Values.dekaf).deployment).readinessProbe }} + readinessProbe: + {{- toYaml .Values.dekaf.deployment.readinessProbe | nindent 12 }} + {{- end }} + + {{- if ((.Values.dekaf).persistence).enabled }} + volumeMounts: + - name: {{ template "pulsar.fullname" . }}-{{ template "dekaf.component" . }}-library + mountPath: /dekaf/data/library + {{- end }} + + {{- if ((.Values.dekaf).deployment).extraVolumeMounts }} + {{- toYaml .Values.dekaf.deployment.extraVolumeMounts | default list | nindent 12 }} + {{- end }} + + {{- range ((.Values.dekaf).deployment).extraContainers | default (list) }} + - {{- toYaml . | nindent 10 }} + {{- end }} + + volumes: + {{- if ((.Values.dekaf).persistence).enabled }} + - name: {{ template "pulsar.fullname" . }}-{{ template "dekaf.component" . }}-library + persistentVolumeClaim: + claimName: {{ template "pulsar.fullname" . }}-{{ template "dekaf.component" . }}-library + {{- end }} + + {{- if ((.Values.dekaf).deployment).extraVolumes }} + {{- toYaml .Values.dekaf.deployment.extraVolumes | default list | nindent 8 }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/pulsar/templates/dekaf-persistence.yaml b/charts/pulsar/templates/dekaf-persistence.yaml new file mode 100644 index 00000000..85786df5 --- /dev/null +++ b/charts/pulsar/templates/dekaf-persistence.yaml @@ -0,0 +1,47 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +{{- if .Values.components.dekaf }} +{{- if ((.Values.dekaf).persistence).enabled }} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ template "pulsar.fullname" . }}-{{ template "dekaf.component" . }}-library + namespace: {{ template "pulsar.namespace" . }} + + {{- with ((.Values.dekaf).persistence).annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + + labels: + {{- include "pulsar.standardLabels" . | nindent 4 }} + {{- if ((.Values.dekaf).persistence).labels }} + {{- toYaml .Values.dekaf.persistence.labels | nindent 4 }} + {{- end }} + +spec: + accessModes: + {{- (((.Values.dekaf).persistence).accessModes | default (list "ReadWriteOnce")) | toYaml | nindent 4 }} + resources: + requests: + storage: "{{ ((.Values.dekaf).persistence).size | default "2Gi" }}" + storageClassName: {{ ((.Values.dekaf).persistence).storageClass | default nil }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/pulsar/templates/dekaf-service.yaml b/charts/pulsar/templates/dekaf-service.yaml new file mode 100644 index 00000000..7f03c8a3 --- /dev/null +++ b/charts/pulsar/templates/dekaf-service.yaml @@ -0,0 +1,41 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +{{- if .Values.components.dekaf }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "pulsar.fullname" . }}-{{ template "dekaf.component" . }} + namespace: {{ template "pulsar.namespace" . }} + labels: + {{- include "pulsar.standardLabels" . | nindent 4 }} + component: {{ template "dekaf.component" . }} + annotations: + {{- if ((.Values.dekaf).service).annotations }} + {{ toYaml .Values.dekaf.service.annotations | indent 4 }} + {{- end }} +spec: + ports: + - name: http + port: 8090 + targetPort: 8090 + selector: + {{- include "pulsar.matchLabels" . | nindent 4 }} + component: {{ template "dekaf.component" . }} +{{- end }} \ No newline at end of file diff --git a/charts/pulsar/values.yaml b/charts/pulsar/values.yaml index 6e6293e9..97146acd 100755 --- a/charts/pulsar/values.yaml +++ b/charts/pulsar/values.yaml @@ -135,6 +135,8 @@ components: toolset: true # pulsar manager pulsar_manager: false + # dekaf UI + dekaf: false # default image repository for pulsar images defaultPulsarImageRepository: apachepulsar/pulsar-all @@ -208,6 +210,11 @@ images: # uses defaultPullPolicy when unspecified pullPolicy: hasCommand: false + dekaf: + repository: visortelle/dekaf + tag: 1.0.0 + # uses defaultPullPolicy when unspecified + pullPolicy: oxia: repository: oxia/oxia tag: 0.14.4 @@ -1807,6 +1814,7 @@ victoria-metrics-k8s-stack: caFile: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt insecureSkipVerify: true # For development environments like minikube +## Pulsar Manager has been poorly maintained for a long time. Consider the Dekaf UI instead. ## Components Stack: pulsar_manager ## templates/pulsar-manager.yaml ## @@ -1911,6 +1919,51 @@ pulsar_manager: db_username: "pulsar" db_password: "" # leave empty for random password +# Dekaf is an open-source web-based UI for Apache Pulsar https://pulsar.apache.org/docs/next/administration-dekaf-ui/ +dekaf: + component: dekaf + deployment: + annotations: {} + podAnnotations: {} + nodeSelector: {} + tolerations: [] + extraVolumes: [] + extraVolumeMounts: [] + extraContainers: [] + extraEnv: [] + resources: + requests: + memory: "768Mi" + cpu: "100m" + limits: + memory: "4096Mi" + cpu: "4000m" + livenessProbe: + httpGet: + path: /health + port: http + scheme: HTTP + periodSeconds: 5 + initialDelaySeconds: 5 + readinessProbe: + httpGet: + path: /health + port: http + scheme: HTTP + periodSeconds: 5 + service: + annotations: {} + port: 8090 + persistence: + enabled: true + # Storage class must be specified, otherwise you can get an error on Helm upgrade + storageClass: null + size: 2Gi + labels: {} + annotations: {} + accessModes: + - ReadWriteOnce + # These are jobs where job ttl configuration is used # pulsar-helm-chart/charts/pulsar/templates/pulsar-cluster-initialize.yaml # pulsar-helm-chart/charts/pulsar/templates/bookkeeper-cluster-initialize.yaml