merlimat closed pull request #1993: Helm charts for deployment on GKE
URL: https://github.com/apache/incubator-pulsar/pull/1993
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/deployment/kubernetes/helm/README.md 
b/deployment/kubernetes/helm/README.md
new file mode 100644
index 0000000000..627b0fc209
--- /dev/null
+++ b/deployment/kubernetes/helm/README.md
@@ -0,0 +1,23 @@
+<!--
+
+    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.
+
+-->
+
+This directory contains the Helm Chart required
+to do a complete Pulsar deployment on Kubernetes.
diff --git a/deployment/kubernetes/helm/pulsar/.helmignore 
b/deployment/kubernetes/helm/pulsar/.helmignore
new file mode 100644
index 0000000000..f0c1319444
--- /dev/null
+++ b/deployment/kubernetes/helm/pulsar/.helmignore
@@ -0,0 +1,21 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
diff --git a/deployment/kubernetes/helm/pulsar/Chart.yaml 
b/deployment/kubernetes/helm/pulsar/Chart.yaml
new file mode 100644
index 0000000000..f4cefc099b
--- /dev/null
+++ b/deployment/kubernetes/helm/pulsar/Chart.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.
+#
+
+apiVersion: v1
+appVersion: "1.0"
+description: Apache Pulsar Helm chart for Kubernetes
+name: pulsar
+version: 1.0.0
diff --git a/deployment/kubernetes/helm/pulsar/templates/_helpers.tpl 
b/deployment/kubernetes/helm/pulsar/templates/_helpers.tpl
new file mode 100644
index 0000000000..ba25c6e2eb
--- /dev/null
+++ b/deployment/kubernetes/helm/pulsar/templates/_helpers.tpl
@@ -0,0 +1,32 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "pulsar.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- 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 "pulsar.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 -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "pulsar.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | 
trimSuffix "-" -}}
+{{- end -}}
diff --git 
a/deployment/kubernetes/helm/pulsar/templates/autorecovery-configmap.yaml 
b/deployment/kubernetes/helm/pulsar/templates/autorecovery-configmap.yaml
new file mode 100644
index 0000000000..2e25112110
--- /dev/null
+++ b/deployment/kubernetes/helm/pulsar/templates/autorecovery-configmap.yaml
@@ -0,0 +1,38 @@
+#
+# 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.extra.autoRecovery }}
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: "{{ template "pulsar.fullname" . }}-{{ .Values.autoRecovery.component 
}}"
+  namespace: {{ .Values.namespace }}
+  labels:
+    app: {{ template "pulsar.name" . }}
+    chart: {{ template "pulsar.chart" . }}
+    release: {{ .Release.Name }}
+    heritage: {{ .Release.Service }}
+    component: {{ .Values.autoRecovery.component }}
+    cluster: {{ template "pulsar.fullname" . }}
+data:
+  zkServers:
+    {{- $global := . }}
+    {{ range $i, $e := until (.Values.zookeeper.replicaCount | int) }}{{ if ne 
$i 0 }},{{ end }}{{ printf "%s-%s-%s-%d.%s-%s-%s" $global.Release.Name 
$global.Chart.Name $global.Values.zookeeper.component $i $global.Release.Name 
$global.Chart.Name $global.Values.zookeeper.component }}{{ end }}
+{{ toYaml .Values.autoRecovery.configData | indent 2 }}
+{{- end }}
diff --git 
a/deployment/kubernetes/helm/pulsar/templates/autorecovery-deployment.yaml 
b/deployment/kubernetes/helm/pulsar/templates/autorecovery-deployment.yaml
new file mode 100644
index 0000000000..fb98e1bf20
--- /dev/null
+++ b/deployment/kubernetes/helm/pulsar/templates/autorecovery-deployment.yaml
@@ -0,0 +1,105 @@
+#
+# 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.extra.autoRecovery }}
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: "{{ template "pulsar.fullname" . }}-{{ .Values.autoRecovery.component 
}}"
+  namespace: {{ .Values.namespace }}
+  labels:
+    app: {{ template "pulsar.name" . }}
+    chart: {{ template "pulsar.chart" . }}
+    release: {{ .Release.Name }}
+    heritage: {{ .Release.Service }}
+    component: {{ .Values.autoRecovery.component }}
+    cluster: {{ template "pulsar.fullname" . }}
+spec:
+  replicas: {{ .Values.autoRecovery.replicaCount }}
+  selector:
+    matchLabels:
+      app: {{ template "pulsar.name" . }}
+      release: {{ .Release.Name }}
+      component: {{ .Values.autoRecovery.component }}
+  template:
+    metadata:
+      labels:
+        app: {{ template "pulsar.name" . }}
+        release: {{ .Release.Name }}
+        component: {{ .Values.autoRecovery.component }}
+        cluster: {{ template "pulsar.fullname" . }}
+      annotations:
+{{ toYaml .Values.autoRecovery.annotations | indent 8 }}
+    spec:
+    {{- if .Values.autoRecovery.nodeSelector }}
+      nodeSelector:
+{{ toYaml .Values.autoRecovery.nodeSelector | indent 8 }}
+    {{- end }}
+    {{- if .Values.autoRecovery.tolerations }}
+      tolerations:
+{{ toYaml .Values.autoRecovery.tolerations | indent 8 }}
+    {{- end }}
+      affinity:
+        podAntiAffinity:
+          requiredDuringSchedulingIgnoredDuringExecution:
+          - labelSelector:
+              matchExpressions:
+              - key: "app"
+                operator: In
+                values:
+                - "{{ template "pulsar.name" . }}-{{ 
.Values.bookkeeper.component }}"
+              - key: "release"
+                operator: In
+                values:
+                - {{ .Release.Name }}
+              - key: "component"
+                operator: In
+                values:
+                - {{ .Values.bookkeeper.component }}
+            topologyKey: "kubernetes.io/hostname"
+      terminationGracePeriodSeconds: {{ .Values.dashboard.gracePeriod }}
+      initContainers:
+      # This init container will wait for zookeeper to be ready before
+      # deploying the bookies
+      - name: wait-zookeeper-ready
+        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+        imagePullPolicy: {{ .Values.image.pullPolicy }}
+        command: ["sh", "-c"]
+        args:
+          - >-
+            until nslookup {{ template "pulsar.fullname" . }}-{{ 
.Values.zookeeper.component }}-{{ add (.Values.zookeeper.replicaCount | int) -1 
}}.{{ template "pulsar.fullname" . }}-{{ .Values.zookeeper.component }}.{{ 
.Values.namespace }}; do
+              sleep 3;
+            done;
+      containers:
+      - name: "{{ template "pulsar.fullname" . }}-{{ 
.Values.autoRecovery.component }}"
+        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+        imagePullPolicy: {{ .Values.image.pullPolicy }}
+      {{- if .Values.autoRecovery.resources }}
+        resources:
+{{ toYaml .Values.autoRecovery.resources | indent 10 }}
+      {{- end }}
+        command: ["sh", "-c"]
+        args:
+        - >
+          bin/apply-config-from-env.py conf/bookkeeper.conf &&
+          bin/bookkeeper autorecovery
+        envFrom:
+        - configMapRef:
+            name: "{{ template "pulsar.fullname" . }}-{{ 
.Values.autoRecovery.component }}"
+{{- end }}
diff --git a/deployment/kubernetes/helm/pulsar/templates/bastion-configmap.yaml 
b/deployment/kubernetes/helm/pulsar/templates/bastion-configmap.yaml
new file mode 100644
index 0000000000..4e42fcc3c6
--- /dev/null
+++ b/deployment/kubernetes/helm/pulsar/templates/bastion-configmap.yaml
@@ -0,0 +1,35 @@
+#
+# 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.extra.bastion }}
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: "{{ template "pulsar.fullname" . }}-{{ .Values.bastion.component }}"
+  namespace: {{ .Values.namespace }}
+  labels:
+    app: {{ template "pulsar.name" . }}
+    chart: {{ template "pulsar.chart" . }}
+    release: {{ .Release.Name }}
+    heritage: {{ .Release.Service }}
+    component: {{ .Values.bastion.component }}
+    cluster: {{ template "pulsar.fullname" . }}
+data:
+{{ toYaml .Values.bastion.configData | indent 2 }}
+{{- end }}
diff --git 
a/deployment/kubernetes/helm/pulsar/templates/bastion-deployment.yaml 
b/deployment/kubernetes/helm/pulsar/templates/bastion-deployment.yaml
new file mode 100644
index 0000000000..afc6a73033
--- /dev/null
+++ b/deployment/kubernetes/helm/pulsar/templates/bastion-deployment.yaml
@@ -0,0 +1,80 @@
+#
+# 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.extra.bastion }}
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: "{{ template "pulsar.fullname" . }}-{{ .Values.bastion.component }}"
+  namespace: {{ .Values.namespace }}
+  labels:
+    app: {{ template "pulsar.name" . }}
+    chart: {{ template "pulsar.chart" . }}
+    release: {{ .Release.Name }}
+    heritage: {{ .Release.Service }}
+    component: {{ .Values.bastion.component }}
+    cluster: {{ template "pulsar.fullname" . }}
+spec:
+  replicas: {{ .Values.bastion.replicaCount }}
+  selector:
+    matchLabels:
+      app: {{ template "pulsar.name" . }}
+      release: {{ .Release.Name }}
+      component: {{ .Values.bastion.component }}
+  template:
+    metadata:
+      labels:
+        app: {{ template "pulsar.name" . }}
+        release: {{ .Release.Name }}
+        component: {{ .Values.bastion.component }}
+        cluster: {{ template "pulsar.fullname" . }}
+      annotations:
+{{ toYaml .Values.bastion.annotations | indent 8 }}
+    spec:
+    {{- if .Values.bastion.nodeSelector }}
+      nodeSelector:
+{{ toYaml .Values.bastion.nodeSelector | indent 8 }}
+    {{- end }}
+    {{- if .Values.bastion.tolerations }}
+      tolerations:
+{{ toYaml .Values.bastion.tolerations | indent 8 }}
+    {{- end }}
+      terminationGracePeriodSeconds: {{ .Values.bastion.gracePeriod }}
+      containers:
+      - name: "{{ template "pulsar.fullname" . }}-{{ .Values.bastion.component 
}}"
+        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+        imagePullPolicy: {{ .Values.image.pullPolicy }}
+      {{- if .Values.bastion.resources }}
+        resources:
+{{ toYaml .Values.bastion.resources | indent 10 }}
+      {{- end }}
+        command: ["sh", "-c"]
+        args:
+        - >
+          bin/apply-config-from-env.py conf/client.conf &&
+          sleep 10000000000
+        envFrom:
+        - configMapRef:
+            name: "{{ template "pulsar.fullname" . }}-{{ 
.Values.bastion.component }}"
+        env:
+        - name: webServiceUrl
+          value: http://{{ template "pulsar.fullname" . }}-{{ 
.Values.broker.component }}:8080/
+        - name: brokerServiceUrl
+          value: pulsar://{{ template "pulsar.fullname" . }}-{{ 
.Values.broker.component }}:6650/
+{{- end }}
diff --git 
a/deployment/kubernetes/helm/pulsar/templates/bookkeeper-configmap.yaml 
b/deployment/kubernetes/helm/pulsar/templates/bookkeeper-configmap.yaml
new file mode 100644
index 0000000000..50ca87da4f
--- /dev/null
+++ b/deployment/kubernetes/helm/pulsar/templates/bookkeeper-configmap.yaml
@@ -0,0 +1,36 @@
+#
+# 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.
+#
+
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: "{{ template "pulsar.fullname" . }}-{{ .Values.bookkeeper.component }}"
+  namespace: {{ .Values.namespace }}
+  labels:
+    app: {{ template "pulsar.name" . }}
+    chart: {{ template "pulsar.chart" . }}
+    release: {{ .Release.Name }}
+    heritage: {{ .Release.Service }}
+    component: {{ .Values.bookkeeper.component }}
+    cluster: {{ template "pulsar.fullname" . }}
+data:
+  zkServers:
+    {{- $global := . }}
+    {{ range $i, $e := until (.Values.zookeeper.replicaCount | int) }}{{ if ne 
$i 0 }},{{ end }}{{ printf "%s-%s-%s-%d.%s-%s-%s" $global.Release.Name 
$global.Chart.Name $global.Values.zookeeper.component $i $global.Release.Name 
$global.Chart.Name $global.Values.zookeeper.component }}{{ end }}
+{{ toYaml .Values.bookkeeper.configData | indent 2 }}
diff --git a/deployment/kubernetes/helm/pulsar/templates/bookkeeper-pdb.yaml 
b/deployment/kubernetes/helm/pulsar/templates/bookkeeper-pdb.yaml
new file mode 100644
index 0000000000..8f045f751b
--- /dev/null
+++ b/deployment/kubernetes/helm/pulsar/templates/bookkeeper-pdb.yaml
@@ -0,0 +1,40 @@
+#
+# 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.bookkeeper.pdb.usePolicy }}
+apiVersion: policy/v1beta1
+kind: PodDisruptionBudget
+metadata:
+  name: "{{ template "pulsar.fullname" . }}-{{ .Values.bookkeeper.component }}"
+  namespace: {{ .Values.namespace }}
+  labels:
+    app: {{ template "pulsar.name" . }}
+    chart: {{ template "pulsar.chart" . }}
+    release: {{ .Release.Name }}
+    heritage: {{ .Release.Service }}
+    component: {{ .Values.bookkeeper.component }}
+    cluster: {{ template "pulsar.fullname" . }}
+spec:
+  selector:
+    matchLabels:
+      app: {{ template "pulsar.name" . }}
+      release: {{ .Release.Name }}
+      component: {{ .Values.bookkeeper.component }}
+  maxUnavailable: {{ .Values.bookkeeper.pdb.maxUnavailable }}
+{{- end }}
diff --git 
a/deployment/kubernetes/helm/pulsar/templates/bookkeeper-service.yaml 
b/deployment/kubernetes/helm/pulsar/templates/bookkeeper-service.yaml
new file mode 100644
index 0000000000..82658ba00e
--- /dev/null
+++ b/deployment/kubernetes/helm/pulsar/templates/bookkeeper-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.
+#
+
+apiVersion: v1
+kind: Service
+metadata:
+  name: "{{ template "pulsar.fullname" . }}-{{ .Values.bookkeeper.component }}"
+  namespace: {{ .Values.namespace }}
+  labels:
+    app: {{ template "pulsar.name" . }}
+    chart: {{ template "pulsar.chart" . }}
+    release: {{ .Release.Name }}
+    heritage: {{ .Release.Service }}
+    component: {{ .Values.bookkeeper.component }}
+    cluster: {{ template "pulsar.fullname" . }}
+  annotations:
+{{ toYaml .Values.bookkeeper.service.annotations | indent 4 }}
+spec:
+  ports:
+{{ toYaml .Values.bookkeeper.service.ports | indent 2 }}
+  clusterIP: None
+  selector:
+    app: {{ template "pulsar.name" . }}
+    release: {{ .Release.Name }}
+    component: {{ .Values.bookkeeper.component }}
diff --git 
a/deployment/kubernetes/helm/pulsar/templates/bookkeeper-statefulset.yaml 
b/deployment/kubernetes/helm/pulsar/templates/bookkeeper-statefulset.yaml
new file mode 100644
index 0000000000..a9c872a55b
--- /dev/null
+++ b/deployment/kubernetes/helm/pulsar/templates/bookkeeper-statefulset.yaml
@@ -0,0 +1,159 @@
+#
+# 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.
+#
+
+apiVersion: apps/v1
+kind: StatefulSet
+metadata:
+  name: "{{ template "pulsar.fullname" . }}-{{ .Values.bookkeeper.component }}"
+  namespace: {{ .Values.namespace }}
+  labels:
+    app: {{ template "pulsar.name" . }}
+    chart: {{ template "pulsar.chart" . }}
+    release: {{ .Release.Name }}
+    heritage: {{ .Release.Service }}
+    component: {{ .Values.bookkeeper.component }}
+    cluster: {{ template "pulsar.fullname" . }}
+spec:
+  serviceName: "{{ template "pulsar.fullname" . }}-{{ 
.Values.bookkeeper.component }}"
+  replicas: {{ .Values.bookkeeper.replicaCount }}
+  selector:
+    matchLabels:
+      app: {{ template "pulsar.name" . }}
+      release: {{ .Release.Name }}
+      component: {{ .Values.bookkeeper.component }}
+  updateStrategy:
+{{ toYaml .Values.bookkeeper.updateStrategy | indent 4 }}
+  podManagementPolicy: {{ .Values.bookkeeper.podManagementPolicy }}
+  template:
+    metadata:
+      labels:
+        app: {{ template "pulsar.name" . }}
+        release: {{ .Release.Name }}
+        component: {{ .Values.bookkeeper.component }}
+        cluster: {{ template "pulsar.fullname" . }}
+      annotations:
+{{ toYaml .Values.bookkeeper.annotations | indent 8 }}
+    spec:
+    {{- if .Values.bookkeeper.nodeSelector }}
+      nodeSelector:
+{{ toYaml .Values.bookkeeper.nodeSelector | indent 8 }}
+    {{- end }}
+    {{- if .Values.bookkeeper.tolerations }}
+      tolerations:
+{{ toYaml .Values.bookkeeper.tolerations | indent 8 }}
+    {{- end }}
+      affinity:
+        podAntiAffinity:
+          requiredDuringSchedulingIgnoredDuringExecution:
+          - labelSelector:
+              matchExpressions:
+              - key: "app"
+                operator: In
+                values:
+                - "{{ template "pulsar.name" . }}-{{ 
.Values.bookkeeper.component }}"
+              - key: "release"
+                operator: In
+                values:
+                - {{ .Release.Name }}
+              - key: "component"
+                operator: In
+                values:
+                - {{ .Values.bookkeeper.component }}
+            topologyKey: "kubernetes.io/hostname"
+      terminationGracePeriodSeconds: {{ .Values.bookkeeper.gracePeriod }}
+      initContainers:
+      # This init container will wait for zookeeper to be ready before
+      # deploying the bookies
+      - name: wait-zookeeper-ready
+        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+        imagePullPolicy: {{ .Values.image.pullPolicy }}
+        command: ["sh", "-c"]
+        args:
+          - >-
+            until nslookup {{ template "pulsar.fullname" . }}-{{ 
.Values.zookeeper.component }}-{{ add (.Values.zookeeper.replicaCount | int) -1 
}}.{{ template "pulsar.fullname" . }}-{{ .Values.zookeeper.component }}.{{ 
.Values.namespace }}; do
+              sleep 3;
+            done;
+      # This initContainer will make sure that the bookeeper
+      # metadata is in zookeeper
+      - name: pulsar-bookkeeper-metaformat
+        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+        imagePullPolicy: {{ .Values.image.pullPolicy }}
+        command: ["sh", "-c"]
+        args:
+        - >
+          bin/apply-config-from-env.py conf/bookkeeper.conf &&
+          bin/bookkeeper shell metaformat --nonInteractive || true;
+        envFrom:
+        - configMapRef:
+            name: "{{ template "pulsar.fullname" . }}-{{ 
.Values.bookkeeper.component }}"
+      containers:
+      - name: "{{ template "pulsar.fullname" . }}-{{ 
.Values.bookkeeper.component }}"
+        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+        imagePullPolicy: {{ .Values.image.pullPolicy }}
+      {{- if .Values.bookkeeper.resources }}
+        resources:
+{{ toYaml .Values.bookkeeper.resources | indent 10 }}
+      {{- end }}
+        command: ["sh", "-c"]
+        args:
+        - >
+          bin/apply-config-from-env.py conf/bookkeeper.conf &&
+          bin/apply-config-from-env.py conf/pulsar_env.sh &&
+          bin/pulsar bookie
+        ports:
+        - name: client
+          containerPort: 3181
+        envFrom:
+        - configMapRef:
+            name: "{{ template "pulsar.fullname" . }}-{{ 
.Values.bookkeeper.component }}"
+        volumeMounts:
+        - name: "{{ template "pulsar.fullname" . }}-{{ 
.Values.bookkeeper.component }}-{{ .Values.bookkeeper.volumes.journal.name }}"
+          mountPath: /pulsar/data/bookkeeper/journal
+        - name: "{{ template "pulsar.fullname" . }}-{{ 
.Values.bookkeeper.component }}-{{ .Values.bookkeeper.volumes.ledgers.name }}"
+          mountPath: /pulsar/data/bookkeeper/ledgers
+        {{- if not .Values.persistence }}
+      volumes:
+      - name: "{{ template "pulsar.fullname" . }}-{{ 
.Values.bookkeeper.component }}-{{ .Values.bookkeeper.volumes.journal.name }}"
+        emptyDir: {}
+      - name: "{{ template "pulsar.fullname" . }}-{{ 
.Values.bookkeeper.component }}-{{ .Values.bookkeeper.volumes.ledgers.name }}"
+        emptyDir: {}
+    {{- end }}
+{{- if .Values.persistence }}
+  volumeClaimTemplates:
+  - metadata:
+      name: "{{ template "pulsar.fullname" . }}-{{ 
.Values.bookkeeper.component }}-{{ .Values.bookkeeper.volumes.journal.name }}"
+    spec:
+      accessModes: [ "ReadWriteOnce" ]
+      resources:
+        requests:
+          storage: {{ .Values.bookkeeper.volumes.journal.size }}
+    {{- if .Values.bookkeeper.volumes.journal.storageClass }}
+      storageClassName: "{{ template "pulsar.fullname" . }}-{{ 
.Values.bookkeeper.component }}-{{ .Values.bookkeeper.volumes.journal.name }}"
+    {{- end }}
+  - metadata:
+      name: "{{ template "pulsar.fullname" . }}-{{ 
.Values.bookkeeper.component }}-{{ .Values.bookkeeper.volumes.ledgers.name }}"
+    spec:
+      accessModes: [ "ReadWriteOnce" ]
+      resources:
+        requests:
+          storage: {{ .Values.bookkeeper.volumes.ledgers.size }}
+    {{- if .Values.bookkeeper.volumes.ledgers.storageClass }}
+      storageClassName: "{{ template "pulsar.fullname" . }}-{{ 
.Values.bookkeeper.component }}-{{ .Values.bookkeeper.volumes.ledgers.name }}"
+    {{- end }}
+{{- end }}
diff --git 
a/deployment/kubernetes/helm/pulsar/templates/bookkeeper-storageclass.yaml 
b/deployment/kubernetes/helm/pulsar/templates/bookkeeper-storageclass.yaml
new file mode 100644
index 0000000000..f6e7fc750d
--- /dev/null
+++ b/deployment/kubernetes/helm/pulsar/templates/bookkeeper-storageclass.yaml
@@ -0,0 +1,59 @@
+#
+# 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.persistence }}
+{{- if .Values.bookkeeper.volumes.journal.storageClass }}
+apiVersion: storage.k8s.io/v1
+kind: StorageClass
+metadata:
+  name: "{{ template "pulsar.fullname" . }}-{{ .Values.bookkeeper.component 
}}-{{ .Values.bookkeeper.volumes.journal.name }}"
+  namespace: {{ .Values.namespace }}
+  labels:
+    app: {{ template "pulsar.name" . }}
+    chart: {{ template "pulsar.chart" . }}
+    release: {{ .Release.Name }}
+    heritage: {{ .Release.Service }}
+    component: {{ .Values.bookkeeper.component }}
+    cluster: {{ template "pulsar.fullname" . }}
+provisioner: {{ .Values.bookkeeper.volumes.journal.storageClass.provisioner }}
+parameters:
+  type: {{ .Values.bookkeeper.volumes.journal.storageClass.type }}
+  fsType: {{ .Values.bookkeeper.volumes.journal.storageClass.fsType }}
+{{- end }}
+---
+
+{{- if .Values.bookkeeper.volumes.ledgers.storageClass }}
+apiVersion: storage.k8s.io/v1
+kind: StorageClass
+metadata:
+  name: "{{ template "pulsar.fullname" . }}-{{ .Values.bookkeeper.component 
}}-{{ .Values.bookkeeper.volumes.ledgers.name }}"
+  namespace: {{ .Values.namespace }}
+  labels:
+    app: {{ template "pulsar.name" . }}
+    chart: {{ template "pulsar.chart" . }}
+    release: {{ .Release.Name }}
+    heritage: {{ .Release.Service }}
+    component: {{ .Values.bookkeeper.component }}
+    cluster: {{ template "pulsar.fullname" . }}
+provisioner: {{ .Values.bookkeeper.volumes.ledgers.storageClass.provisioner }}
+parameters:
+  type: {{ .Values.bookkeeper.volumes.ledgers.storageClass.type }}
+  fsType: {{ .Values.bookkeeper.volumes.ledgers.storageClass.fsType }}
+{{- end }}
+{{- end }}
diff --git a/deployment/kubernetes/helm/pulsar/templates/broker-configmap.yaml 
b/deployment/kubernetes/helm/pulsar/templates/broker-configmap.yaml
new file mode 100644
index 0000000000..4f7edb53c9
--- /dev/null
+++ b/deployment/kubernetes/helm/pulsar/templates/broker-configmap.yaml
@@ -0,0 +1,40 @@
+#
+# 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.
+#
+
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: "{{ template "pulsar.fullname" . }}-{{ .Values.broker.component }}"
+  namespace: {{ .Values.namespace }}
+  labels:
+    app: {{ template "pulsar.name" . }}
+    chart: {{ template "pulsar.chart" . }}
+    release: {{ .Release.Name }}
+    heritage: {{ .Release.Service }}
+    component: {{ .Values.broker.component }}
+    cluster: {{ template "pulsar.fullname" . }}
+data:
+  zookeeperServers:
+    {{- $global := . }}
+    {{ range $i, $e := until (.Values.zookeeper.replicaCount | int) }}{{ if ne 
$i 0 }},{{ end }}{{ printf "%s-%s-%s-%d.%s-%s-%s" $global.Release.Name 
$global.Chart.Name $global.Values.zookeeper.component $i $global.Release.Name 
$global.Chart.Name $global.Values.zookeeper.component }}{{ end }}
+  configurationStoreServers:
+    {{- $global := . }}
+    {{ range $i, $e := until (.Values.zookeeper.replicaCount | int) }}{{ if ne 
$i 0 }},{{ end }}{{ printf "%s-%s-%s-%d.%s-%s-%s" $global.Release.Name 
$global.Chart.Name $global.Values.zookeeper.component $i $global.Release.Name 
$global.Chart.Name $global.Values.zookeeper.component }}{{ end }}
+  clusterName: {{ template "pulsar.fullname" . }}
+{{ toYaml .Values.broker.configData | indent 2 }}
diff --git a/deployment/kubernetes/helm/pulsar/templates/broker-deployment.yaml 
b/deployment/kubernetes/helm/pulsar/templates/broker-deployment.yaml
new file mode 100644
index 0000000000..f9d8b7f1ff
--- /dev/null
+++ b/deployment/kubernetes/helm/pulsar/templates/broker-deployment.yaml
@@ -0,0 +1,114 @@
+#
+# 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.
+#
+
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: "{{ template "pulsar.fullname" . }}-{{ .Values.broker.component }}"
+  namespace: {{ .Values.namespace }}
+  labels:
+    app: {{ template "pulsar.name" . }}
+    chart: {{ template "pulsar.chart" . }}
+    release: {{ .Release.Name }}
+    heritage: {{ .Release.Service }}
+    component: {{ .Values.broker.component }}
+    cluster: {{ template "pulsar.fullname" . }}
+spec:
+  replicas: {{ .Values.broker.replicaCount }}
+  selector:
+    matchLabels:
+      app: {{ template "pulsar.name" . }}
+      release: {{ .Release.Name }}
+      component: {{ .Values.broker.component }}
+  template:
+    metadata:
+      labels:
+        app: {{ template "pulsar.name" . }}
+        release: {{ .Release.Name }}
+        component: {{ .Values.broker.component }}
+        cluster: {{ template "pulsar.fullname" . }}
+      annotations:
+{{ toYaml .Values.broker.annotations | indent 8 }}
+    spec:
+    {{- if .Values.broker.nodeSelector }}
+      nodeSelector:
+{{ toYaml .Values.broker.nodeSelector | indent 8 }}
+    {{- end }}
+    {{- if .Values.broker.tolerations }}
+      tolerations:
+{{ toYaml .Values.broker.tolerations | indent 8 }}
+    {{- end }}
+      affinity:
+        podAntiAffinity:
+          requiredDuringSchedulingIgnoredDuringExecution:
+          - labelSelector:
+              matchExpressions:
+              - key: "app"
+                operator: In
+                values:
+                - "{{ template "pulsar.name" . }}-{{ .Values.broker.component 
}}"
+              - key: "release"
+                operator: In
+                values:
+                - {{ .Release.Name }}
+              - key: "component"
+                operator: In
+                values:
+                - {{ .Values.broker.component }}
+            topologyKey: "kubernetes.io/hostname"
+      terminationGracePeriodSeconds: {{ .Values.broker.gracePeriod }}
+      initContainers:
+      # This init container will wait for zookeeper to be ready before
+      # deploying the bookies
+      - name: wait-zookeeper-ready
+        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+        imagePullPolicy: {{ .Values.image.pullPolicy }}
+        command: ["sh", "-c"]
+        args:
+          - >-
+            until nslookup {{ template "pulsar.fullname" . }}-{{ 
.Values.zookeeper.component }}-{{ add (.Values.zookeeper.replicaCount | int) -1 
}}.{{ template "pulsar.fullname" . }}-{{ .Values.zookeeper.component }}.{{ 
.Values.namespace }}; do
+              sleep 3;
+            done;
+      containers:
+      - name: "{{ template "pulsar.fullname" . }}-{{ .Values.broker.component 
}}"
+        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+        imagePullPolicy: {{ .Values.image.pullPolicy }}
+      {{- if .Values.broker.resources }}
+        resources:
+{{ toYaml .Values.broker.resources | indent 10 }}
+      {{- end }}
+        command: ["sh", "-c"]
+        args:
+        - >
+          bin/apply-config-from-env.py conf/broker.conf &&
+          bin/apply-config-from-env.py conf/pulsar_env.sh &&
+          bin/pulsar broker
+        ports:
+        - name: http
+          containerPort: 8080
+        - name: pulsar
+          containerPort: 6650
+        envFrom:
+        - configMapRef:
+            name: "{{ template "pulsar.fullname" . }}-{{ 
.Values.broker.component }}"
+        env:
+        - name: advertisedAddress
+          valueFrom:
+            fieldRef:
+              fieldPath: status.podIP
diff --git a/deployment/kubernetes/helm/pulsar/templates/broker-pdb.yaml 
b/deployment/kubernetes/helm/pulsar/templates/broker-pdb.yaml
new file mode 100644
index 0000000000..6f60d5910a
--- /dev/null
+++ b/deployment/kubernetes/helm/pulsar/templates/broker-pdb.yaml
@@ -0,0 +1,40 @@
+#
+# 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.broker.pdb.usePolicy }}
+apiVersion: policy/v1beta1
+kind: PodDisruptionBudget
+metadata:
+  name: "{{ template "pulsar.fullname" . }}-{{ .Values.broker.component }}"
+  namespace: {{ .Values.namespace }}
+  labels:
+    app: {{ template "pulsar.name" . }}
+    chart: {{ template "pulsar.chart" . }}
+    release: {{ .Release.Name }}
+    heritage: {{ .Release.Service }}
+    component: {{ .Values.broker.component }}
+    cluster: {{ template "pulsar.fullname" . }}
+spec:
+  selector:
+    matchLabels:
+      app: {{ template "pulsar.name" . }}
+      release: {{ .Release.Name }}
+      component: {{ .Values.broker.component }}
+  maxUnavailable: {{ .Values.broker.pdb.maxUnavailable }}
+{{- end }}
diff --git a/deployment/kubernetes/helm/pulsar/templates/broker-service.yaml 
b/deployment/kubernetes/helm/pulsar/templates/broker-service.yaml
new file mode 100644
index 0000000000..8cfe718434
--- /dev/null
+++ b/deployment/kubernetes/helm/pulsar/templates/broker-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.
+#
+
+apiVersion: v1
+kind: Service
+metadata:
+  name: "{{ template "pulsar.fullname" . }}-{{ .Values.broker.component }}"
+  namespace: {{ .Values.namespace }}
+  labels:
+    app: {{ template "pulsar.name" . }}
+    chart: {{ template "pulsar.chart" . }}
+    release: {{ .Release.Name }}
+    heritage: {{ .Release.Service }}
+    component: {{ .Values.broker.component }}
+    cluster: {{ template "pulsar.fullname" . }}
+  annotations:
+{{ toYaml .Values.broker.service.annotations | indent 4 }}
+spec:
+  ports:
+{{ toYaml .Values.broker.service.ports | indent 2 }}
+  clusterIP: None
+  selector:
+    app: {{ template "pulsar.name" . }}
+    release: {{ .Release.Name }}
+    component: {{ .Values.broker.component }}
diff --git 
a/deployment/kubernetes/helm/pulsar/templates/dashboard-deployment.yaml 
b/deployment/kubernetes/helm/pulsar/templates/dashboard-deployment.yaml
new file mode 100644
index 0000000000..618edb6f10
--- /dev/null
+++ b/deployment/kubernetes/helm/pulsar/templates/dashboard-deployment.yaml
@@ -0,0 +1,73 @@
+#
+# 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.extra.dashboard }}
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: "{{ template "pulsar.fullname" . }}-{{ .Values.dashboard.component }}"
+  namespace: {{ .Values.namespace }}
+  labels:
+    app: {{ template "pulsar.name" . }}
+    chart: {{ template "pulsar.chart" . }}
+    release: {{ .Release.Name }}
+    heritage: {{ .Release.Service }}
+    component: {{ .Values.dashboard.component }}
+    cluster: {{ template "pulsar.fullname" . }}
+spec:
+  replicas: {{ .Values.dashboard.replicaCount }}
+  selector:
+    matchLabels:
+      app: {{ template "pulsar.name" . }}
+      release: {{ .Release.Name }}
+      component: {{ .Values.dashboard.component }}
+  template:
+    metadata:
+      labels:
+        app: {{ template "pulsar.name" . }}
+        release: {{ .Release.Name }}
+        component: {{ .Values.dashboard.component }}
+        cluster: {{ template "pulsar.fullname" . }}
+      annotations:
+{{ toYaml .Values.dashboard.annotations | indent 8 }}
+    spec:
+    {{- if .Values.dashboard.nodeSelector }}
+      nodeSelector:
+{{ toYaml .Values.dashboard.nodeSelector | indent 8 }}
+    {{- end }}
+    {{- if .Values.dashboard.tolerations }}
+      tolerations:
+{{ toYaml .Values.dashboard.tolerations | indent 8 }}
+    {{- end }}
+      terminationGracePeriodSeconds: {{ .Values.dashboard.gracePeriod }}
+      containers:
+      - name: "{{ template "pulsar.fullname" . }}-{{ 
.Values.dashboard.component }}"
+        image: "{{ .Values.dashboard.image.repository }}:{{ 
.Values.dashboard.image.tag }}"
+        imagePullPolicy: {{ .Values.dashboard.image.pullPolicy }}
+      {{- if .Values.dashboard.resources }}
+        resources:
+{{ toYaml .Values.dashboard.resources | indent 10 }}
+      {{- end }}
+        ports:
+        - name: http
+          containerPort: 80
+        env:
+        - name: SERVICE_URL
+          value: http://{{ template "pulsar.fullname" . }}-{{ 
.Values.broker.component }}:8080/
+{{- end }}
diff --git a/deployment/kubernetes/helm/pulsar/templates/dashboard-service.yaml 
b/deployment/kubernetes/helm/pulsar/templates/dashboard-service.yaml
new file mode 100644
index 0000000000..34147af232
--- /dev/null
+++ b/deployment/kubernetes/helm/pulsar/templates/dashboard-service.yaml
@@ -0,0 +1,43 @@
+#
+# 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.extra.dashboard }}
+apiVersion: v1
+kind: Service
+metadata:
+  name: "{{ template "pulsar.fullname" . }}-{{ .Values.dashboard.component }}"
+  namespace: {{ .Values.namespace }}
+  labels:
+    app: {{ template "pulsar.name" . }}
+    chart: {{ template "pulsar.chart" . }}
+    release: {{ .Release.Name }}
+    heritage: {{ .Release.Service }}
+    component: {{ .Values.dashboard.component }}
+    cluster: {{ template "pulsar.fullname" . }}
+  annotations:
+{{ toYaml .Values.dashboard.service.annotations | indent 4 }}
+spec:
+  ports:
+{{ toYaml .Values.dashboard.service.ports | indent 2 }}
+  clusterIP: None
+  selector:
+    app: {{ template "pulsar.name" . }}
+    release: {{ .Release.Name }}
+    component: {{ .Values.dashboard.component }}
+{{- end }}
diff --git 
a/deployment/kubernetes/helm/pulsar/templates/grafana-deployment.yaml 
b/deployment/kubernetes/helm/pulsar/templates/grafana-deployment.yaml
new file mode 100644
index 0000000000..45f83de1fe
--- /dev/null
+++ b/deployment/kubernetes/helm/pulsar/templates/grafana-deployment.yaml
@@ -0,0 +1,72 @@
+#
+# 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.extra.monitoring }}
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: "{{ template "pulsar.fullname" . }}-{{ .Values.grafana.component }}"
+  namespace: {{ .Values.namespace }}
+  labels:
+    app: {{ template "pulsar.name" . }}
+    chart: {{ template "pulsar.chart" . }}
+    release: {{ .Release.Name }}
+    heritage: {{ .Release.Service }}
+    component: {{ .Values.grafana.component }}
+    cluster: {{ template "pulsar.fullname" . }}
+spec:
+  replicas: {{ .Values.grafana.replicaCount }}
+  selector:
+    matchLabels:
+      app: {{ template "pulsar.name" . }}
+      release: {{ .Release.Name }}
+      component: {{ .Values.grafana.component }}
+  template:
+    metadata:
+      labels:
+        app: {{ template "pulsar.name" . }}
+        release: {{ .Release.Name }}
+        component: {{ .Values.grafana.component }}
+        cluster: {{ template "pulsar.fullname" . }}
+      annotations:
+{{ toYaml .Values.grafana.annotations | indent 8 }}
+    spec:
+    {{- if .Values.grafana.nodeSelector }}
+      nodeSelector:
+{{ toYaml .Values.grafana.nodeSelector | indent 8 }}
+    {{- end }}
+    {{- if .Values.grafana.tolerations }}
+      tolerations:
+{{ toYaml .Values.grafana.tolerations | indent 8 }}
+    {{- end }}
+      terminationGracePeriodSeconds: {{ .Values.grafana.gracePeriod }}
+      containers:
+      - name: "{{ template "pulsar.fullname" . }}-{{ .Values.grafana.component 
}}"
+        image: "{{ .Values.grafana.image.repository }}:{{ 
.Values.grafana.image.tag }}"
+        imagePullPolicy: {{ .Values.grafana.image.pullPolicy }}
+      {{- if .Values.grafana.resources }}
+        resources:
+{{ toYaml .Values.grafana.resources | indent 10 }}
+      {{- end }}
+        ports:
+        - containerPort: 3000
+        env:
+        - name: PROMETHEUS_URL
+          value: http://{{ template "pulsar.fullname" . }}-{{ 
.Values.prometheus.component }}:9090/
+{{- end }}
diff --git a/deployment/kubernetes/helm/pulsar/templates/grafana-service.yaml 
b/deployment/kubernetes/helm/pulsar/templates/grafana-service.yaml
new file mode 100644
index 0000000000..cd73f43a75
--- /dev/null
+++ b/deployment/kubernetes/helm/pulsar/templates/grafana-service.yaml
@@ -0,0 +1,43 @@
+#
+# 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.extra.monitoring }}
+apiVersion: v1
+kind: Service
+metadata:
+  name: "{{ template "pulsar.fullname" . }}-{{ .Values.grafana.component }}"
+  namespace: {{ .Values.namespace }}
+  labels:
+    app: {{ template "pulsar.name" . }}
+    chart: {{ template "pulsar.chart" . }}
+    release: {{ .Release.Name }}
+    heritage: {{ .Release.Service }}
+    component: {{ .Values.grafana.component }}
+    cluster: {{ template "pulsar.fullname" . }}
+  annotations:
+{{ toYaml .Values.grafana.service.annotations | indent 4 }}
+spec:
+  ports:
+{{ toYaml .Values.grafana.service.ports | indent 2 }}
+  clusterIP: None
+  selector:
+    app: {{ template "pulsar.name" . }}
+    release: {{ .Release.Name }}
+    component: {{ .Values.grafana.component }}
+{{- end }}
diff --git a/deployment/kubernetes/helm/pulsar/templates/namespace.yaml 
b/deployment/kubernetes/helm/pulsar/templates/namespace.yaml
new file mode 100644
index 0000000000..c00b1e5908
--- /dev/null
+++ b/deployment/kubernetes/helm/pulsar/templates/namespace.yaml
@@ -0,0 +1,25 @@
+#
+# 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.namespaceCreate }}
+apiVersion: v1
+kind: Namespace
+metadata:
+  name: {{ .Values.namespace }}
+{{- end }}
diff --git 
a/deployment/kubernetes/helm/pulsar/templates/prometheus-configmap.yaml 
b/deployment/kubernetes/helm/pulsar/templates/prometheus-configmap.yaml
new file mode 100644
index 0000000000..889abf5975
--- /dev/null
+++ b/deployment/kubernetes/helm/pulsar/templates/prometheus-configmap.yaml
@@ -0,0 +1,70 @@
+#
+# 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.extra.monitoring }}
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: "{{ template "pulsar.fullname" . }}-{{ .Values.prometheus.component }}"
+  namespace: {{ .Values.namespace }}
+  labels:
+    app: {{ template "pulsar.name" . }}
+    chart: {{ template "pulsar.chart" . }}
+    release: {{ .Release.Name }}
+    heritage: {{ .Release.Service }}
+    component: {{ .Values.prometheus.component }}
+    cluster: {{ template "pulsar.fullname" . }}
+data:
+  # Include prometheus configuration file, setup to monitor all the
+  # Kubernetes pods with the "scrape=true" annotation.
+  prometheus.yml: |
+    global:
+      scrape_interval: 15s
+    scrape_configs:
+    - job_name: 'prometheus'
+      static_configs:
+      - targets: ['localhost:9090']
+    - job_name: 'kubernetes-pods'
+      kubernetes_sd_configs:
+      - role: pod
+      relabel_configs:
+      - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
+        action: keep
+        regex: true
+      - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
+        action: replace
+        target_label: __metrics_path__
+        regex: (.+)
+      - source_labels: [__address__, 
__meta_kubernetes_pod_annotation_prometheus_io_port]
+        action: replace
+        regex: ([^:]+)(?::\d+)?;(\d+)
+        replacement: $1:$2
+        target_label: __address__
+      - action: labelmap
+        regex: __meta_kubernetes_pod_label_(.+)
+      - source_labels: [__meta_kubernetes_namespace]
+        action: replace
+        target_label: kubernetes_namespace
+      - source_labels: [__meta_kubernetes_pod_label_component]
+        action: replace
+        target_label: job
+      - source_labels: [__meta_kubernetes_pod_name]
+        action: replace
+        target_label: kubernetes_pod_name
+{{- end }}
diff --git 
a/deployment/kubernetes/helm/pulsar/templates/prometheus-deployment.yaml 
b/deployment/kubernetes/helm/pulsar/templates/prometheus-deployment.yaml
new file mode 100644
index 0000000000..223fc6a0af
--- /dev/null
+++ b/deployment/kubernetes/helm/pulsar/templates/prometheus-deployment.yaml
@@ -0,0 +1,82 @@
+#
+# 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.extra.monitoring }}
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: "{{ template "pulsar.fullname" . }}-{{ .Values.prometheus.component }}"
+  namespace: {{ .Values.namespace }}
+  labels:
+    app: {{ template "pulsar.name" . }}
+    chart: {{ template "pulsar.chart" . }}
+    release: {{ .Release.Name }}
+    heritage: {{ .Release.Service }}
+    component: {{ .Values.prometheus.component }}
+    cluster: {{ template "pulsar.fullname" . }}
+spec:
+  replicas: {{ .Values.prometheus.replicaCount }}
+  selector:
+    matchLabels:
+      app: {{ template "pulsar.name" . }}
+      release: {{ .Release.Name }}
+      component: {{ .Values.prometheus.component }}
+  template:
+    metadata:
+      labels:
+        app: {{ template "pulsar.name" . }}
+        release: {{ .Release.Name }}
+        component: {{ .Values.prometheus.component }}
+        cluster: {{ template "pulsar.fullname" . }}
+      annotations:
+{{ toYaml .Values.prometheus.annotations | indent 8 }}
+    spec:
+    {{- if .Values.prometheus.nodeSelector }}
+      nodeSelector:
+{{ toYaml .Values.prometheus.nodeSelector | indent 8 }}
+    {{- end }}
+    {{- if .Values.prometheus.tolerations }}
+      tolerations:
+{{ toYaml .Values.prometheus.tolerations | indent 8 }}
+    {{- end }}
+      serviceAccount: "{{ template "pulsar.fullname" . }}-{{ 
.Values.prometheus.component }}"
+      terminationGracePeriodSeconds: {{ .Values.prometheus.gracePeriod }}
+      containers:
+      - name: "{{ template "pulsar.fullname" . }}-{{ 
.Values.prometheus.component }}"
+        image: "{{ .Values.prometheus.image.repository }}:{{ 
.Values.prometheus.image.tag }}"
+        imagePullPolicy: {{ .Values.prometheus.image.pullPolicy }}
+      {{- if .Values.prometheus.resources }}
+        resources:
+{{ toYaml .Values.prometheus.resources | indent 10 }}
+      {{- end }}
+        ports:
+        - containerPort: 9090
+        volumeMounts:
+        - name: "{{ template "pulsar.fullname" . }}-{{ 
.Values.prometheus.component }}-config"
+          mountPath: /etc/prometheus
+        - name: "{{ template "pulsar.fullname" . }}-{{ 
.Values.prometheus.component }}-{{ .Values.prometheus.volumes.data.name }}"
+          mountPath: /prometheus
+      volumes:
+      - name: "{{ template "pulsar.fullname" . }}-{{ 
.Values.prometheus.component }}-config"
+        configMap:
+          name: "{{ template "pulsar.fullname" . }}-{{ 
.Values.prometheus.component }}"
+      - name: "{{ template "pulsar.fullname" . }}-{{ 
.Values.prometheus.component }}-{{ .Values.prometheus.volumes.data.name }}"
+        persistentVolumeClaim:
+          claimName: "{{ template "pulsar.fullname" . }}-{{ 
.Values.prometheus.component }}-{{ .Values.prometheus.volumes.data.name }}"
+{{- end }}
diff --git a/deployment/kubernetes/helm/pulsar/templates/prometheus-pvc.yaml 
b/deployment/kubernetes/helm/pulsar/templates/prometheus-pvc.yaml
new file mode 100644
index 0000000000..3cbab53dbc
--- /dev/null
+++ b/deployment/kubernetes/helm/pulsar/templates/prometheus-pvc.yaml
@@ -0,0 +1,36 @@
+#
+# 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.extra.monitoring }}
+{{- if .Values.persistence }}
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+  name: "{{ template "pulsar.fullname" . }}-{{ .Values.prometheus.component 
}}-{{ .Values.prometheus.volumes.data.name }}"
+  namespace: {{ .Values.namespace }}
+spec:
+  resources:
+    requests:
+      storage: {{ .Values.prometheus.volumes.data.size }}
+  accessModes: [ "ReadWriteOnce" ]
+{{- if .Values.prometheus.volumes.data.storageClass }}
+  storageClassName: "{{ template "pulsar.fullname" . }}-{{ 
.Values.prometheus.component }}-{{ .Values.prometheus.volumes.data.name }}"
+{{- end }}
+{{- end }}
+{{- end }}
diff --git a/deployment/kubernetes/helm/pulsar/templates/prometheus-rbac.yaml 
b/deployment/kubernetes/helm/pulsar/templates/prometheus-rbac.yaml
new file mode 100644
index 0000000000..04c1b4335e
--- /dev/null
+++ b/deployment/kubernetes/helm/pulsar/templates/prometheus-rbac.yaml
@@ -0,0 +1,57 @@
+#
+# 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.extra.monitoring }}
+apiVersion: rbac.authorization.k8s.io/v1beta1
+kind: ClusterRole
+metadata:
+  name: "{{ template "pulsar.fullname" . }}-{{ .Values.prometheus.component }}"
+rules:
+- apiGroups: [""]
+  resources:
+  - nodes
+  - nodes/proxy
+  - services
+  - endpoints
+  - pods
+  verbs: ["get", "list", "watch"]
+- nonResourceURLs: ["/metrics"]
+  verbs: ["get"]
+---
+
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: "{{ template "pulsar.fullname" . }}-{{ .Values.prometheus.component }}"
+  namespace: {{ .Values.namespace }}
+---
+
+apiVersion: rbac.authorization.k8s.io/v1beta1
+kind: ClusterRoleBinding
+metadata:
+  name: "{{ template "pulsar.fullname" . }}-{{ .Values.prometheus.component }}"
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: "{{ template "pulsar.fullname" . }}-{{ .Values.prometheus.component }}"
+subjects:
+- kind: ServiceAccount
+  name: "{{ template "pulsar.fullname" . }}-{{ .Values.prometheus.component }}"
+  namespace: {{ .Values.namespace }}
+{{- end }}
diff --git 
a/deployment/kubernetes/helm/pulsar/templates/prometheus-service.yaml 
b/deployment/kubernetes/helm/pulsar/templates/prometheus-service.yaml
new file mode 100644
index 0000000000..965256d49a
--- /dev/null
+++ b/deployment/kubernetes/helm/pulsar/templates/prometheus-service.yaml
@@ -0,0 +1,43 @@
+#
+# 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.extra.monitoring }}
+apiVersion: v1
+kind: Service
+metadata:
+  name: "{{ template "pulsar.fullname" . }}-{{ .Values.prometheus.component }}"
+  namespace: {{ .Values.namespace }}
+  labels:
+    app: {{ template "pulsar.name" . }}
+    chart: {{ template "pulsar.chart" . }}
+    release: {{ .Release.Name }}
+    heritage: {{ .Release.Service }}
+    component: {{ .Values.prometheus.component }}
+    cluster: {{ template "pulsar.fullname" . }}
+  annotations:
+{{ toYaml .Values.prometheus.service.annotations | indent 4 }}
+spec:
+  ports:
+{{ toYaml .Values.prometheus.service.ports | indent 2 }}
+  clusterIP: None
+  selector:
+    app: {{ template "pulsar.name" . }}
+    release: {{ .Release.Name }}
+    component: {{ .Values.prometheus.component }}
+{{- end }}
diff --git 
a/deployment/kubernetes/helm/pulsar/templates/prometheus-storageclass.yaml 
b/deployment/kubernetes/helm/pulsar/templates/prometheus-storageclass.yaml
new file mode 100644
index 0000000000..1623a5f9c1
--- /dev/null
+++ b/deployment/kubernetes/helm/pulsar/templates/prometheus-storageclass.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.extra.monitoring }}
+{{- if .Values.persistence }}
+{{- if .Values.prometheus.volumes.data.storageClass }}
+apiVersion: storage.k8s.io/v1
+kind: StorageClass
+metadata:
+  name: "{{ template "pulsar.fullname" . }}-{{ .Values.prometheus.component 
}}-{{ .Values.prometheus.volumes.data.name }}"
+  namespace: {{ .Values.namespace }}
+  labels:
+    app: {{ template "pulsar.name" . }}
+    chart: {{ template "pulsar.chart" . }}
+    release: {{ .Release.Name }}
+    heritage: {{ .Release.Service }}
+    component: {{ .Values.prometheus.component }}
+    cluster: {{ template "pulsar.fullname" . }}
+provisioner: {{ .Values.prometheus.volumes.data.storageClass.provisioner }}
+parameters:
+  type: {{ .Values.prometheus.volumes.data.storageClass.type }}
+  fsType: {{ .Values.prometheus.volumes.data.storageClass.fsType }}
+{{- end }}
+{{- end }}
+{{- end }}
diff --git a/deployment/kubernetes/helm/pulsar/templates/proxy-configmap.yaml 
b/deployment/kubernetes/helm/pulsar/templates/proxy-configmap.yaml
new file mode 100644
index 0000000000..06051e4fe2
--- /dev/null
+++ b/deployment/kubernetes/helm/pulsar/templates/proxy-configmap.yaml
@@ -0,0 +1,42 @@
+#
+# 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.extra.proxy }}
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: "{{ template "pulsar.fullname" . }}-{{ .Values.proxy.component }}"
+  namespace: {{ .Values.namespace }}
+  labels:
+    app: {{ template "pulsar.name" . }}
+    chart: {{ template "pulsar.chart" . }}
+    release: {{ .Release.Name }}
+    heritage: {{ .Release.Service }}
+    component: {{ .Values.proxy.component }}
+    cluster: {{ template "pulsar.fullname" . }}
+data:
+  zookeeperServers:
+    {{- $global := . }}
+    {{ range $i, $e := until (.Values.zookeeper.replicaCount | int) }}{{ if ne 
$i 0 }},{{ end }}{{ printf "%s-%s-%s-%d.%s-%s-%s" $global.Release.Name 
$global.Chart.Name $global.Values.zookeeper.component $i $global.Release.Name 
$global.Chart.Name $global.Values.zookeeper.component }}{{ end }}
+  configurationStoreServers:
+    {{- $global := . }}
+    {{ range $i, $e := until (.Values.zookeeper.replicaCount | int) }}{{ if ne 
$i 0 }},{{ end }}{{ printf "%s-%s-%s-%d.%s-%s-%s" $global.Release.Name 
$global.Chart.Name $global.Values.zookeeper.component $i $global.Release.Name 
$global.Chart.Name $global.Values.zookeeper.component }}{{ end }}
+  clusterName: {{ template "pulsar.fullname" . }}
+{{ toYaml .Values.proxy.configData | indent 2 }}
+{{- end }}
diff --git a/deployment/kubernetes/helm/pulsar/templates/proxy-deployment.yaml 
b/deployment/kubernetes/helm/pulsar/templates/proxy-deployment.yaml
new file mode 100644
index 0000000000..4567ed3102
--- /dev/null
+++ b/deployment/kubernetes/helm/pulsar/templates/proxy-deployment.yaml
@@ -0,0 +1,109 @@
+#
+# 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.extra.proxy }}
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: "{{ template "pulsar.fullname" . }}-{{ .Values.proxy.component }}"
+  namespace: {{ .Values.namespace }}
+  labels:
+    app: {{ template "pulsar.name" . }}
+    chart: {{ template "pulsar.chart" . }}
+    release: {{ .Release.Name }}
+    heritage: {{ .Release.Service }}
+    component: {{ .Values.proxy.component }}
+    cluster: {{ template "pulsar.fullname" . }}
+spec:
+  replicas: {{ .Values.proxy.replicaCount }}
+  selector:
+    matchLabels:
+      app: {{ template "pulsar.name" . }}
+      release: {{ .Release.Name }}
+      component: {{ .Values.proxy.component }}
+  template:
+    metadata:
+      labels:
+        app: {{ template "pulsar.name" . }}
+        release: {{ .Release.Name }}
+        component: {{ .Values.proxy.component }}
+        cluster: {{ template "pulsar.fullname" . }}
+      annotations:
+{{ toYaml .Values.proxy.annotations | indent 8 }}
+    spec:
+    {{- if .Values.proxy.nodeSelector }}
+      nodeSelector:
+{{ toYaml .Values.proxy.nodeSelector | indent 8 }}
+    {{- end }}
+    {{- if .Values.proxy.tolerations }}
+      tolerations:
+{{ toYaml .Values.proxy.tolerations | indent 8 }}
+    {{- end }}
+      affinity:
+        podAntiAffinity:
+          requiredDuringSchedulingIgnoredDuringExecution:
+          - labelSelector:
+              matchExpressions:
+              - key: "app"
+                operator: In
+                values:
+                - "{{ template "pulsar.name" . }}-{{ .Values.proxy.component 
}}"
+              - key: "release"
+                operator: In
+                values:
+                - {{ .Release.Name }}
+              - key: "component"
+                operator: In
+                values:
+                - {{ .Values.proxy.component }}
+            topologyKey: "kubernetes.io/hostname"
+      terminationGracePeriodSeconds: {{ .Values.proxy.gracePeriod }}
+      initContainers:
+      # This init container will wait for zookeeper to be ready before
+      # deploying the bookies
+      - name: wait-zookeeper-ready
+        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+        imagePullPolicy: {{ .Values.image.pullPolicy }}
+        command: ["sh", "-c"]
+        args:
+          - >-
+            until nslookup {{ template "pulsar.fullname" . }}-{{ 
.Values.zookeeper.component }}-{{ add (.Values.zookeeper.replicaCount | int) -1 
}}.{{ template "pulsar.fullname" . }}-{{ .Values.zookeeper.component }}.{{ 
.Values.namespace }}; do
+              sleep 3;
+            done;
+      containers:
+      - name: "{{ template "pulsar.fullname" . }}-{{ .Values.proxy.component 
}}"
+        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+        imagePullPolicy: {{ .Values.image.pullPolicy }}
+      {{- if .Values.proxy.resources }}
+        resources:
+{{ toYaml .Values.proxy.resources | indent 10 }}
+      {{- end }}
+        command: ["sh", "-c"]
+        args:
+        - >
+          bin/apply-config-from-env.py conf/proxy.conf &&
+          bin/apply-config-from-env.py conf/pulsar_env.sh &&
+          bin/pulsar proxy
+        ports:
+        - name: http
+          containerPort: 8080
+        envFrom:
+        - configMapRef:
+            name: "{{ template "pulsar.fullname" . }}-{{ 
.Values.proxy.component }}"
+{{- end }}
diff --git a/deployment/kubernetes/helm/pulsar/templates/proxy-pdb.yaml 
b/deployment/kubernetes/helm/pulsar/templates/proxy-pdb.yaml
new file mode 100644
index 0000000000..10188d3867
--- /dev/null
+++ b/deployment/kubernetes/helm/pulsar/templates/proxy-pdb.yaml
@@ -0,0 +1,42 @@
+#
+# 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.extra.proxy }}
+{{- if .Values.proxy.pdb.usePolicy }}
+apiVersion: policy/v1beta1
+kind: PodDisruptionBudget
+metadata:
+  name: "{{ template "pulsar.fullname" . }}-{{ .Values.proxy.component }}"
+  namespace: {{ .Values.namespace }}
+  labels:
+    app: {{ template "pulsar.name" . }}
+    chart: {{ template "pulsar.chart" . }}
+    release: {{ .Release.Name }}
+    heritage: {{ .Release.Service }}
+    component: {{ .Values.proxy.component }}
+    cluster: {{ template "pulsar.fullname" . }}
+spec:
+  selector:
+    matchLabels:
+      app: {{ template "pulsar.name" . }}
+      release: {{ .Release.Name }}
+      component: {{ .Values.proxy.component }}
+  maxUnavailable: {{ .Values.proxy.pdb.maxUnavailable }}
+{{- end }}
+{{- end }}
diff --git a/deployment/kubernetes/helm/pulsar/templates/proxy-service.yaml 
b/deployment/kubernetes/helm/pulsar/templates/proxy-service.yaml
new file mode 100644
index 0000000000..99493711c9
--- /dev/null
+++ b/deployment/kubernetes/helm/pulsar/templates/proxy-service.yaml
@@ -0,0 +1,43 @@
+#
+# 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.extra.proxy }}
+apiVersion: v1
+kind: Service
+metadata:
+  name: "{{ template "pulsar.fullname" . }}-{{ .Values.proxy.component }}"
+  namespace: {{ .Values.namespace }}
+  labels:
+    app: {{ template "pulsar.name" . }}
+    chart: {{ template "pulsar.chart" . }}
+    release: {{ .Release.Name }}
+    heritage: {{ .Release.Service }}
+    component: {{ .Values.proxy.component }}
+    cluster: {{ template "pulsar.fullname" . }}
+  annotations:
+{{ toYaml .Values.proxy.service.annotations | indent 4 }}
+spec:
+  type: NodePort
+  ports:
+{{ toYaml .Values.proxy.service.ports | indent 2 }}
+  selector:
+    app: {{ template "pulsar.name" . }}
+    release: {{ .Release.Name }}
+    component: {{ .Values.proxy.component }}
+{{- end }}
diff --git 
a/deployment/kubernetes/helm/pulsar/templates/zookeeper-configmap.yaml 
b/deployment/kubernetes/helm/pulsar/templates/zookeeper-configmap.yaml
new file mode 100644
index 0000000000..754f814f04
--- /dev/null
+++ b/deployment/kubernetes/helm/pulsar/templates/zookeeper-configmap.yaml
@@ -0,0 +1,33 @@
+#
+# 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.
+#
+
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: "{{ template "pulsar.fullname" . }}-{{ .Values.zookeeper.component }}"
+  namespace: {{ .Values.namespace }}
+  labels:
+    app: {{ template "pulsar.name" . }}
+    chart: {{ template "pulsar.chart" . }}
+    release: {{ .Release.Name }}
+    heritage: {{ .Release.Service }}
+    component: {{ .Values.zookeeper.component }}
+    cluster: {{ template "pulsar.fullname" . }}
+data:
+{{ toYaml .Values.zookeeper.configData | indent 2 }}
diff --git 
a/deployment/kubernetes/helm/pulsar/templates/zookeeper-metadata.yaml 
b/deployment/kubernetes/helm/pulsar/templates/zookeeper-metadata.yaml
new file mode 100644
index 0000000000..4a62710cb1
--- /dev/null
+++ b/deployment/kubernetes/helm/pulsar/templates/zookeeper-metadata.yaml
@@ -0,0 +1,58 @@
+#
+# 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.
+#
+
+apiVersion: batch/v1
+kind: Job
+metadata:
+  name: "{{ template "pulsar.fullname" . }}-{{ 
.Values.zookeeperMetadata.component }}"
+  namespace: {{ .Values.namespace }}
+  labels:
+    app: {{ template "pulsar.name" . }}
+    chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}
+    release: {{ .Release.Name }}
+    heritage: {{ .Release.Service }}
+    component: {{ .Values.zookeeperMetadata.component }}
+    cluster: {{ template "pulsar.fullname" . }}
+spec:
+  template:
+    spec:
+      initContainers:
+      - name: wait-zookeeper-ready
+        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+        imagePullPolicy: {{ .Values.image.pullPolicy }}
+        command: ["sh", "-c"]
+        args:
+          - >-
+            until nslookup {{ template "pulsar.fullname" . }}-{{ 
.Values.zookeeper.component }}-{{ add (.Values.zookeeper.replicaCount | int) -1 
}}.{{ template "pulsar.fullname" . }}-{{ .Values.zookeeper.component }}.{{ 
.Values.namespace }}; do
+              sleep 3;
+            done;
+      containers:
+      - name: "{{ template "pulsar.fullname" . }}-{{ 
.Values.zookeeperMetadata.component }}"
+        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+        imagePullPolicy: {{ .Values.image.pullPolicy }}
+        command: ["sh", "-c"]
+        args:
+          - >
+            bin/pulsar initialize-cluster-metadata \
+              --cluster {{ template "pulsar.fullname" . }} \
+              --zookeeper {{ template "pulsar.fullname" . }}-{{ 
.Values.zookeeper.component }} \
+              --configuration-store {{ template "pulsar.fullname" . }}-{{ 
.Values.zookeeper.component }} \
+              --web-service-url http://{{ template "pulsar.fullname" . }}-{{ 
.Values.broker.component }}.{{ .Values.namespace }}.svc.cluster.local:8080/ \
+              --broker-service-url pulsar://{{ template "pulsar.fullname" . 
}}-{{ .Values.broker.component }}.{{ .Values.namespace 
}}.svc.cluster.local:6650/ || true;
+      restartPolicy: Never
diff --git a/deployment/kubernetes/helm/pulsar/templates/zookeeper-pdb.yaml 
b/deployment/kubernetes/helm/pulsar/templates/zookeeper-pdb.yaml
new file mode 100644
index 0000000000..d205883941
--- /dev/null
+++ b/deployment/kubernetes/helm/pulsar/templates/zookeeper-pdb.yaml
@@ -0,0 +1,40 @@
+#
+# 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.zookeeper.pdb.usePolicy }}
+apiVersion: policy/v1beta1
+kind: PodDisruptionBudget
+metadata:
+  name: "{{ template "pulsar.fullname" . }}-{{ .Values.zookeeper.component }}"
+  namespace: {{ .Values.namespace }}
+  labels:
+    app: {{ template "pulsar.name" . }}
+    chart: {{ template "pulsar.chart" . }}
+    release: {{ .Release.Name }}
+    heritage: {{ .Release.Service }}
+    component: {{ .Values.zookeeper.component }}
+    cluster: {{ template "pulsar.fullname" . }}
+spec:
+  selector:
+    matchLabels:
+      app: {{ template "pulsar.name" . }}
+      release: {{ .Release.Name }}
+      component: {{ .Values.zookeeper.component }}
+  maxUnavailable: {{ .Values.zookeeper.pdb.maxUnavailable }}
+{{- end }}
diff --git a/deployment/kubernetes/helm/pulsar/templates/zookeeper-service.yaml 
b/deployment/kubernetes/helm/pulsar/templates/zookeeper-service.yaml
new file mode 100644
index 0000000000..d7d8167e82
--- /dev/null
+++ b/deployment/kubernetes/helm/pulsar/templates/zookeeper-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.
+#
+
+apiVersion: v1
+kind: Service
+metadata:
+  name: "{{ template "pulsar.fullname" . }}-{{ .Values.zookeeper.component }}"
+  namespace: {{ .Values.namespace }}
+  labels:
+    app: {{ template "pulsar.name" . }}
+    chart: {{ template "pulsar.chart" . }}
+    release: {{ .Release.Name }}
+    heritage: {{ .Release.Service }}
+    component: {{ .Values.zookeeper.component }}
+    cluster: {{ template "pulsar.fullname" . }}
+  annotations:
+{{ toYaml .Values.zookeeper.service.annotations | indent 4 }}
+spec:
+  ports:
+{{ toYaml .Values.zookeeper.service.ports | indent 2 }}
+  clusterIP: None
+  selector:
+    app: {{ template "pulsar.name" . }}
+    release: {{ .Release.Name }}
+    component: {{ .Values.zookeeper.component }}
diff --git 
a/deployment/kubernetes/helm/pulsar/templates/zookeeper-statefulset.yaml 
b/deployment/kubernetes/helm/pulsar/templates/zookeeper-statefulset.yaml
new file mode 100644
index 0000000000..bc71fe60b0
--- /dev/null
+++ b/deployment/kubernetes/helm/pulsar/templates/zookeeper-statefulset.yaml
@@ -0,0 +1,142 @@
+#
+# 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.
+#
+
+apiVersion: apps/v1
+kind: StatefulSet
+metadata:
+  name: "{{ template "pulsar.fullname" . }}-{{ .Values.zookeeper.component }}"
+  namespace: {{ .Values.namespace }}
+  labels:
+    app: {{ template "pulsar.name" . }}
+    chart: {{ template "pulsar.chart" . }}
+    release: {{ .Release.Name }}
+    heritage: {{ .Release.Service }}
+    component: {{ .Values.zookeeper.component }}
+    cluster: {{ template "pulsar.fullname" . }}
+spec:
+  serviceName: "{{ template "pulsar.fullname" . }}-{{ 
.Values.zookeeper.component }}"
+  replicas: {{ .Values.zookeeper.replicaCount }}
+  selector:
+    matchLabels:
+      app: {{ template "pulsar.name" . }}
+      release: {{ .Release.Name }}
+      component: {{ .Values.zookeeper.component }}
+  updateStrategy:
+{{ toYaml .Values.zookeeper.updateStrategy | indent 4 }}
+  podManagementPolicy: {{ .Values.zookeeper.podManagementPolicy }}
+  template:
+    metadata:
+      labels:
+        app: {{ template "pulsar.name" . }}
+        release: {{ .Release.Name }}
+        component: {{ .Values.zookeeper.component }}
+        cluster: {{ template "pulsar.fullname" . }}
+      annotations:
+{{ toYaml .Values.zookeeper.annotations | indent 8 }}
+    spec:
+    {{- if .Values.zookeeper.nodeSelector }}
+      nodeSelector:
+{{ toYaml .Values.zookeeper.nodeSelector | indent 8 }}
+    {{- end }}
+    {{- if .Values.zookeeper.tolerations }}
+      tolerations:
+{{ toYaml .Values.zookeeper.tolerations | indent 8 }}
+    {{- end }}
+      affinity:
+        podAntiAffinity:
+          requiredDuringSchedulingIgnoredDuringExecution:
+          - labelSelector:
+              matchExpressions:
+              - key: "app"
+                operator: In
+                values:
+                - "{{ template "pulsar.name" . }}-{{ 
.Values.zookeeper.component }}"
+              - key: "release"
+                operator: In
+                values:
+                - {{ .Release.Name }}
+              - key: "component"
+                operator: In
+                values:
+                - {{ .Values.zookeeper.component }}
+            topologyKey: "kubernetes.io/hostname"
+      terminationGracePeriodSeconds: {{ .Values.zookeeper.gracePeriod }}
+      containers:
+      - name: "{{ template "pulsar.fullname" . }}-{{ 
.Values.zookeeper.component }}"
+        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+        imagePullPolicy: {{ .Values.image.pullPolicy }}
+      {{- if .Values.zookeeper.resources }}
+        resources:
+{{ toYaml .Values.zookeeper.resources | indent 10 }}
+      {{- end }}
+        command: ["sh", "-c"]
+        args:
+        - >
+          bin/apply-config-from-env.py conf/zookeeper.conf &&
+          bin/apply-config-from-env.py conf/pulsar_env.sh &&
+          bin/generate-zookeeper-config.sh conf/zookeeper.conf &&
+          bin/pulsar zookeeper
+        ports:
+        - name: client
+          containerPort: 2181
+        - name: server
+          containerPort: 2888
+        - name: leader-election
+          containerPort: 3888
+        env:
+        - name: ZOOKEEPER_SERVERS
+          value:
+            {{- $global := . }}
+            {{ range $i, $e := until (.Values.zookeeper.replicaCount | int) 
}}{{ if ne $i 0 }},{{ end }}{{ printf "%s-%s-%s-%d" $global.Release.Name 
$global.Chart.Name $global.Values.zookeeper.component $i }}{{ end }}
+        envFrom:
+        - configMapRef:
+            name: "{{ template "pulsar.fullname" . }}-{{ 
.Values.zookeeper.component }}"
+        readinessProbe:
+          exec:
+            command:
+            - "bin/pulsar-zookeeper-ruok.sh"
+          initialDelaySeconds: 5
+          timeoutSeconds: 5
+        livenessProbe:
+          exec:
+            command:
+            - "bin/pulsar-zookeeper-ruok.sh"
+          initialDelaySeconds: 15
+          timeoutSeconds: 5
+        volumeMounts:
+        - name: "{{ template "pulsar.fullname" . }}-{{ 
.Values.zookeeper.component }}-{{ .Values.zookeeper.volumes.data.name }}"
+          mountPath: /pulsar/data
+    {{- if not .Values.persistence }}
+      volumes:
+      - name: "{{ template "pulsar.fullname" . }}-{{ 
.Values.zookeeper.component }}-{{ .Values.zookeeper.volumes.data.name }}"
+        emptyDir: {}
+    {{- end }}
+{{- if .Values.persistence }}
+  volumeClaimTemplates:
+  - metadata:
+      name: "{{ template "pulsar.fullname" . }}-{{ .Values.zookeeper.component 
}}-{{ .Values.zookeeper.volumes.data.name }}"
+    spec:
+      accessModes: [ "ReadWriteOnce" ]
+      resources:
+        requests:
+          storage: {{ .Values.zookeeper.volumes.data.size }}
+    {{- if .Values.zookeeper.volumes.data.storageClass }}
+      storageClassName: "{{ template "pulsar.fullname" . }}-{{ 
.Values.zookeeper.component }}-{{ .Values.zookeeper.volumes.data.name }}"
+    {{- end }}
+{{- end }}
diff --git 
a/deployment/kubernetes/helm/pulsar/templates/zookeeper-storageclass.yaml 
b/deployment/kubernetes/helm/pulsar/templates/zookeeper-storageclass.yaml
new file mode 100644
index 0000000000..7562337e41
--- /dev/null
+++ b/deployment/kubernetes/helm/pulsar/templates/zookeeper-storageclass.yaml
@@ -0,0 +1,39 @@
+#
+# 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.persistence }}
+{{- if .Values.zookeeper.volumes.data.storageClass }}
+apiVersion: storage.k8s.io/v1
+kind: StorageClass
+metadata:
+  name: "{{ template "pulsar.fullname" . }}-{{ .Values.zookeeper.component 
}}-{{ .Values.zookeeper.volumes.data.name }}"
+  namespace: {{ .Values.namespace }}
+  labels:
+    app: {{ template "pulsar.name" . }}
+    chart: {{ template "pulsar.chart" . }}
+    release: {{ .Release.Name }}
+    heritage: {{ .Release.Service }}
+    component: {{ .Values.zookeeper.component }}
+    cluster: {{ template "pulsar.fullname" . }}
+provisioner: {{ .Values.zookeeper.volumes.data.storageClass.provisioner }}
+parameters:
+  type: {{ .Values.zookeeper.volumes.data.storageClass.type }}
+  fsType: {{ .Values.zookeeper.volumes.data.storageClass.fsType }}
+{{- end }}
+{{- end }}
diff --git a/deployment/kubernetes/helm/pulsar/values.yaml 
b/deployment/kubernetes/helm/pulsar/values.yaml
new file mode 100644
index 0000000000..2a274b5f88
--- /dev/null
+++ b/deployment/kubernetes/helm/pulsar/values.yaml
@@ -0,0 +1,405 @@
+#
+# 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.
+#
+
+## Namespace to deploy pulsar
+namespace: pulsar
+namespaceCreate: yes
+
+## If persistence is enabled, components that has state will
+## be deployed with PersistentVolumeClaims, otherwise, for test
+## purposes, they will be deployed with emptDir
+persistence: no
+
+## which extra components to deploy
+extra:
+  # Pulsar proxy
+  proxy: yes
+  # Bookkeeper auto-recovery
+  autoRecovery: yes
+  # Pulsar dashboard
+  dashboard: yes
+  # Bastion pod for administrative commands
+  bastion: yes
+  # Monitoring stack (prometheus and grafana)
+  monitoring: yes
+
+## Which pulsar image to use
+image:
+  repository: apachepulsar/pulsar
+  tag: latest
+  pullPolicy: IfNotPresent
+
+## Pulsar: Zookeeper cluster
+## templates/zookeeper-statefulset.yaml
+##
+zookeeper:
+  component: zookeeper
+  replicaCount: 3
+  updateStrategy:
+    type: OnDelete
+  podManagementPolicy: OrderedReady
+  # nodeSelector:
+    # cloud.google.com/gke-nodepool: default-pool
+  annotations:
+    prometheus.io/scrape: "true"
+    prometheus.io/port: "8000"
+  tolarations: []
+  gracePeriod: 0
+  resources:
+    requests:
+      memory: 15Gi
+      cpu: 4
+  volumes:
+    data:
+      name: data
+      size: 20Gi
+      ## If the storage class is left undefined when using persistence
+      ## the default storage class for the cluster will be used.
+      ##
+      # storageClass:
+        # type: pd-ssd
+        # fsType: xfs
+        # provisioner: kubernetes.io/gce-pd
+  ## Zookeeper configmap
+  ## templates/zookeeper-configmap.yaml
+  ##
+  configData:
+    PULSAR_MEM: "\"-Xms15g -Xmx15g -Dcom.sun.management.jmxremote 
-Djute.maxbuffer=10485760 -XX:+ParallelRefProcEnabled 
-XX:+UnlockExperimentalVMOptions -XX:+AggressiveOpts -XX:+DoEscapeAnalysis 
-XX:+DisableExplicitGC -XX:+PerfDisableSharedMem -Dzookeeper.forceSync=no\""
+    PULSAR_GC: "\"-XX:+UseG1GC -XX:MaxGCPauseMillis=10\""
+  ## Zookeeper service
+  ## templates/zookeeper-service.yaml
+  ##
+  service:
+    annotations:
+      service.alpha.kubernetes.io/tolerate-unready-endpoints: "true"
+    ports:
+    - name: server
+      port: 2888
+    - name: leader-election
+      port: 3888
+    - name: stats
+      port: 2181
+  ## Zookeeper PodDisruptionBudget
+  ## templates/zookeeper-pdb.yaml
+  ##
+  pdb:
+    usePolicy: yes
+    maxUnavailable: 1
+
+## Pulsar Zookeeper metadata. The metadata will be deployed as
+## soon as the las zookeeper node is reachable. The deployment
+## of other components that depends o zookeeper, such as the
+## bookkeeper nodes, broker nodes, etc will only start to be
+## deployed when the zookeeper cluster is ready and with the
+## metadata deployed
+zookeeperMetadata:
+  component: zookeeper-metadata
+
+## Pulsar: Bookkeeper cluster
+## templates/bookkeeper-statefulset.yaml
+##
+bookkeeper:
+  component: bookkeeper
+  replicaCount: 4
+  updateStrategy:
+    type: OnDelete
+  podManagementPolicy: OrderedReady
+  # nodeSelector:
+    # cloud.google.com/gke-nodepool: default-pool
+  annotations:
+    prometheus.io/scrape: "true"
+    prometheus.io/port: "8000"
+  tolarations: []
+  gracePeriod: 0
+  resources:
+    requests:
+      memory: 15Gi
+      cpu: 4
+  volumes:
+    journal:
+      name: journal
+      size: 50Gi
+      ## If the storage class is left undefined when using persistence
+      ## the default storage class for the cluster will be used.
+      ##
+      # storageClass:
+        # type: pd-ssd
+        # fsType: xfs
+        # provisioner: kubernetes.io/gce-pd
+    ledgers:
+      name: ledgers
+      size: 50Gi
+      ## If the storage class is left undefined when using persistence
+      ## the default storage class for the cluster will be used.
+      ##
+      # storageClass:
+        # type: pd-ssd
+        # fsType: xfs
+        # provisioner: kubernetes.io/gce-pd
+  ## Bookkeeper configmap
+  ## templates/bookkeeper-configmap.yaml
+  ##
+  configData:
+    PULSAR_MEM: "\"-Xms15g -Xmx15g -XX:MaxDirectMemorySize=15g 
-Dio.netty.leakDetectionLevel=disabled -Dio.netty.recycler.linkCapacity=1024 
-XX:+UseG1GC -XX:MaxGCPauseMillis=10 -XX:+ParallelRefProcEnabled 
-XX:+UnlockExperimentalVMOptions -XX:+AggressiveOpts -XX:+DoEscapeAnalysis 
-XX:ParallelGCThreads=32 -XX:ConcGCThreads=32 -XX:G1NewSizePercent=50 
-XX:+DisableExplicitGC -XX:-ResizePLAB -XX:+ExitOnOutOfMemoryError 
-XX:+PerfDisableSharedMem -XX:+PrintGCDetails -XX:+PrintGCTimeStamps 
-XX:+PrintGCApplicationStoppedTime -XX:+PrintHeapAtGC -verbosegc 
-XX:G1LogLevel=finest\""
+    dbStorage_writeCacheMaxSizeMb: "2048"
+    dbStorage_readAheadCacheMaxSizeMb: "2048"
+    dbStorage_rocksDB_blockCacheSize: "268435456"
+    journalMaxSizeMB: "2048"
+    statsProviderClass: 
org.apache.bookkeeper.stats.prometheus.PrometheusMetricsProvider
+    useHostNameAsBookieID: "true"
+  ## Bookkeeper configmap
+  ## templates/bookkeeper-service.yaml
+  ##
+  service:
+    annotations:
+      publishNotReadyAddresses: "true"
+    ports:
+    - name: server
+      port: 3181
+  ## Bookkeeper PodDisruptionBudget
+  ## templates/bookkeeper-pdb.yaml
+  ##
+  pdb:
+    usePolicy: yes
+    maxUnavailable: 1
+
+## Pulsar: Broker cluster
+## templates/broker-deployment.yaml
+##
+broker:
+  component: broker
+  replicaCount: 3
+  # nodeSelector:
+    # cloud.google.com/gke-nodepool: default-pool
+  annotations:
+    prometheus.io/scrape: "true"
+    prometheus.io/port: "8080"
+  tolarations: []
+  gracePeriod: 0
+  resources:
+    requests:
+      memory: 15Gi
+      cpu: 4
+  ## Broker configmap
+  ## templates/broker-configmap.yaml
+  ##
+  configData:
+    PULSAR_MEM: "\"-Xms15g -Xmx15g -XX:MaxDirectMemorySize=15g 
-Dio.netty.leakDetectionLevel=disabled -Dio.netty.recycler.linkCapacity=1024 
-XX:+ParallelRefProcEnabled -XX:+UnlockExperimentalVMOptions 
-XX:+AggressiveOpts -XX:+DoEscapeAnalysis -XX:ParallelGCThreads=32 
-XX:ConcGCThreads=32 -XX:G1NewSizePercent=50 -XX:+DisableExplicitGC 
-XX:-ResizePLAB -XX:+ExitOnOutOfMemoryError -XX:+PerfDisableSharedMem\""
+    PULSAR_GC: "\"-XX:+UseG1GC -XX:MaxGCPauseMillis=10\""
+    managedLedgerDefaultEnsembleSize: "3"
+    managedLedgerDefaultWriteQuorum: "3"
+    managedLedgerDefaultAckQuorum: "2"
+    deduplicationEnabled: "false"
+    exposeTopicLevelMetricsInPrometheus: "true"
+  ## Broker service
+  ## templates/broker-service.yaml
+  ##
+  service:
+    annotations: {}
+    ports:
+    - name: http
+      port: 8080
+    - name: pulsar
+      port: 6650
+  ## Broker PodDisruptionBudget
+  ## templates/broker-pdb.yaml
+  ##
+  pdb:
+    usePolicy: yes
+    maxUnavailable: 1
+
+## Pulsar Extra: Proxy
+## templates/proxy-deployment.yaml
+##
+proxy:
+  component: proxy
+  replicaCount: 3
+  # nodeSelector:
+    # cloud.google.com/gke-nodepool: default-pool
+  annotations:
+    prometheus.io/scrape: "true"
+    prometheus.io/port: "8080"
+  tolarations: []
+  gracePeriod: 0
+  resources:
+    requests:
+      memory: 4Gi
+      cpu: 1
+  ## Proxy configmap
+  ## templates/proxy-configmap.yaml
+  ##
+  configData:
+    PULSAR_MEM: "\"-Xms4g -Xmx4g -XX:MaxDirectMemorySize=4g\""
+  ## Proxy service
+  ## templates/proxy-service.yaml
+  ##
+  service:
+    annotations: {}
+    ports:
+    - name: http
+      port: 8080
+      nodePort: 30001
+      protocol: TCP
+    - name: tcp
+      port: 6650
+      nodePort: 30002
+      protocol: TCP
+  ## Proxy PodDisruptionBudget
+  ## templates/proxy-pdb.yaml
+  ##
+  pdb:
+    usePolicy: yes
+    maxUnavailable: 1
+
+## Pulsar Extra: Bookkeeper auto-recovery
+## templates/autorecovery-deployment.yaml
+##
+autoRecovery:
+  component: autorecovery
+  replicaCount: 1
+  # nodeSelector:
+    # cloud.google.com/gke-nodepool: default-pool
+  annotations: {}
+  tolarations: []
+  gracePeriod: 0
+  resources:
+    requests:
+      memory: 1Gi
+      cpu: 250m
+  ## Bookkeeper auto-recovery configmap
+  ## templates/autorecovery-configmap.yaml
+  ##
+  configData:
+    PULSAR_MEM: "\" -Xms1g -Xmx1g \""
+
+## Pulsar Extra: Dashboard
+## templates/dashboard-deployment.yaml
+##
+dashboard:
+  component: dashboard
+  replicaCount: 1
+  # nodeSelector:
+    # cloud.google.com/gke-nodepool: default-pool
+  annotations: {}
+  tolarations: []
+  gracePeriod: 0
+  image:
+    repository: apachepulsar/pulsar-dashboard
+    tag: latest
+    pullPolicy: IfNotPresent
+  resources:
+    requests:
+      memory: 1Gi
+      cpu: 250m
+  ## Dashboard service
+  ## templates/dashboard-service.yaml
+  ##
+  service:
+    annotations: {}
+    ports:
+    - name: server
+      port: 80
+
+## Pulsar Extra: Bastion
+## templates/bastion-deployment.yaml
+##
+bastion:
+  component: bastion
+  replicaCount: 1
+  # nodeSelector:
+    # cloud.google.com/gke-nodepool: default-pool
+  annotations: {}
+  tolarations: []
+  gracePeriod: 0
+  resources:
+    requests:
+      memory: 1Gi
+      cpu: 250m
+  ## Bastion configmap
+  ## templates/bastion-configmap.yaml
+  ##
+  configData:
+    PULSAR_MEM: "\"-Xms1g -Xmx1g -XX:MaxDirectMemorySize=1g\""
+
+## Monitoring Stack: Prometheus
+## templates/prometheus-deployment.yaml
+##
+prometheus:
+  component: prometheus
+  replicaCount: 1
+  # nodeSelector:
+    # cloud.google.com/gke-nodepool: default-pool
+  annotations: {}
+  tolarations: []
+  gracePeriod: 0
+  image:
+    repository: prom/prometheus
+    tag: v1.6.3
+    pullPolicy: IfNotPresent
+  resources:
+    requests:
+      memory: 4Gi
+      cpu: 1
+  volumes:
+    data:
+      name: data
+      size: 50Gi
+      ## If the storage class is left undefined when using persistence
+      ## the default storage class for the cluster will be used.
+      ##
+      # storageClass:
+        # type: pd-standard
+        # fsType: xfs
+        # provisioner: kubernetes.io/gce-pd
+  ## Prometheus service
+  ## templates/prometheus-service.yaml
+  ##
+  service:
+    annotations: {}
+    ports:
+    - name: server
+      port: 9090
+
+## Monitoring Stack: Grafana
+## templates/grafana-deployment.yaml
+##
+grafana:
+  component: grafana
+  replicaCount: 1
+  # nodeSelector:
+    # cloud.google.com/gke-nodepool: default-pool
+  annotations: {}
+  tolarations: []
+  gracePeriod: 0
+  image:
+    repository: apachepulsar/pulsar-grafana
+    tag: latest
+    pullPolicy: IfNotPresent
+  resources:
+    requests:
+      memory: 4Gi
+      cpu: 1
+  ## Grafana service
+  ## templates/grafana-service.yaml
+  ##
+  service:
+    annotations: {}
+    ports:
+    - name: server
+      port: 3000


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
[email protected]


With regards,
Apache Git Services

Reply via email to