From f64c396906e9f99999ec14bd3ac7336e6609a86a Mon Sep 17 00:00:00 2001 From: Sijie Guo Date: Wed, 8 Apr 2020 11:20:01 -0700 Subject: [PATCH] Improve Helm chart (#6673) * Improve Helm chart - Support TLS for all components - Support Authentication & Authorization (TLS) - Add CI for different cluster settings --- examples/values-cs.yaml | 45 ++ examples/values-jwt-asymmetric.yaml | 37 + examples/values-jwt-symmetric.yaml | 37 + examples/values-local-cluster.yaml | 37 + examples/values-local-pv.yaml | 21 + examples/values-minikube.yaml | 50 ++ examples/values-no-persistence.yaml | 28 + examples/values-one-node.yaml | 54 ++ examples/values-pulsar.yaml | 50 ++ examples/values-tls.yaml | 34 + hack/common.sh | 135 ++++ hack/kind-cluster-build.sh | 251 ++++++ pulsar/Chart.yaml | 7 + pulsar/templates/_autorecovery.tpl | 80 ++ pulsar/templates/_bookkeeper.tpl | 121 +++ pulsar/templates/_broker.tpl | 76 ++ pulsar/templates/_helpers.tpl | 36 + pulsar/templates/_toolset.tpl | 69 ++ pulsar/templates/_zookeeper.tpl | 34 + pulsar/templates/autorecovery-configmap.yaml | 19 +- pulsar/templates/autorecovery-deployment.yaml | 105 --- ...nfigmap.yaml => autorecovery-service.yaml} | 22 +- .../templates/autorecovery-statefulset.yaml | 124 +++ pulsar/templates/bastion-deployment.yaml | 80 -- .../bookkeeper-cluster-initialize.yaml | 71 ++ pulsar/templates/bookkeeper-configmap.yaml | 22 +- pulsar/templates/bookkeeper-pdb.yaml | 11 +- pulsar/templates/bookkeeper-service.yaml | 16 +- pulsar/templates/bookkeeper-statefulset.yaml | 114 +-- pulsar/templates/bookkeeper-storageclass.yaml | 21 +- .../broker-cluster-role-binding.yaml | 66 ++ pulsar/templates/broker-configmap.yaml | 125 ++- pulsar/templates/broker-deployment.yaml | 131 ---- pulsar/templates/broker-pdb.yaml | 11 +- pulsar/templates/broker-service-account.yaml | 29 + pulsar/templates/broker-service.yaml | 22 +- pulsar/templates/broker-statefulset.yaml | 236 ++++++ .../templates/function-worker-configmap.yaml | 32 + pulsar/templates/grafana-deployment.yaml | 42 +- pulsar/templates/grafana-service.yaml | 21 +- pulsar/templates/keytool.yaml | 98 +++ pulsar/templates/prometheus-configmap.yaml | 8 +- pulsar/templates/prometheus-deployment.yaml | 28 +- pulsar/templates/prometheus-pvc.yaml | 8 +- pulsar/templates/prometheus-rbac.yaml | 4 +- pulsar/templates/prometheus-service.yaml | 13 +- pulsar/templates/prometheus-storageclass.yaml | 10 +- pulsar/templates/proxy-configmap.yaml | 65 +- pulsar/templates/proxy-deployment.yaml | 124 --- pulsar/templates/proxy-pdb.yaml | 11 +- pulsar/templates/proxy-service.yaml | 29 +- pulsar/templates/proxy-statefulset.yaml | 234 ++++++ .../templates/pulsar-cluster-initialize.yaml | 102 +++ .../pulsar-manager-admin-secret.yaml | 2 +- .../templates/pulsar-manager-configmap.yaml | 8 +- .../templates/pulsar-manager-deployment.yaml | 21 +- pulsar/templates/pulsar-manager-service.yaml | 12 +- .../templates/tls-cert-internal-issuer.yaml | 62 ++ pulsar/templates/tls-certs-internal.yaml | 247 ++++++ pulsar/templates/toolset-configmap.yaml | 70 ++ pulsar/templates/toolset-service.yaml | 34 + pulsar/templates/toolset-statefulset.yaml | 108 +++ pulsar/templates/zookeeper-configmap.yaml | 17 +- pulsar/templates/zookeeper-metadata.yaml | 62 -- pulsar/templates/zookeeper-pdb.yaml | 12 +- pulsar/templates/zookeeper-service.yaml | 23 +- pulsar/templates/zookeeper-statefulset.yaml | 113 ++- pulsar/templates/zookeeper-storageclass.yaml | 15 +- pulsar/values-mini.yaml | 528 ------------- pulsar/values.yaml | 728 +++++++++++++----- scripts/cert-manager/install-cert-manager.sh | 55 ++ scripts/pulsar/clean_tls.sh | 115 +++ scripts/pulsar/cleanup_helm_release.sh | 87 +++ scripts/pulsar/common.sh | 73 ++ scripts/pulsar/common_auth.sh | 66 ++ scripts/pulsar/generate_token.sh | 121 +++ scripts/pulsar/generate_token_secret_key.sh | 109 +++ scripts/pulsar/get_token.sh | 95 +++ scripts/pulsar/prepare_helm_release.sh | 155 ++++ scripts/pulsar/upload_tls.sh | 135 ++++ 80 files changed, 4816 insertions(+), 1513 deletions(-) create mode 100644 examples/values-cs.yaml create mode 100644 examples/values-jwt-asymmetric.yaml create mode 100644 examples/values-jwt-symmetric.yaml create mode 100644 examples/values-local-cluster.yaml create mode 100644 examples/values-local-pv.yaml create mode 100644 examples/values-minikube.yaml create mode 100644 examples/values-no-persistence.yaml create mode 100644 examples/values-one-node.yaml create mode 100644 examples/values-pulsar.yaml create mode 100644 examples/values-tls.yaml create mode 100755 hack/common.sh create mode 100755 hack/kind-cluster-build.sh create mode 100644 pulsar/templates/_autorecovery.tpl create mode 100644 pulsar/templates/_bookkeeper.tpl create mode 100644 pulsar/templates/_broker.tpl create mode 100644 pulsar/templates/_toolset.tpl create mode 100644 pulsar/templates/_zookeeper.tpl delete mode 100644 pulsar/templates/autorecovery-deployment.yaml rename pulsar/templates/{bastion-configmap.yaml => autorecovery-service.yaml} (68%) create mode 100644 pulsar/templates/autorecovery-statefulset.yaml delete mode 100644 pulsar/templates/bastion-deployment.yaml create mode 100644 pulsar/templates/bookkeeper-cluster-initialize.yaml create mode 100644 pulsar/templates/broker-cluster-role-binding.yaml delete mode 100644 pulsar/templates/broker-deployment.yaml create mode 100644 pulsar/templates/broker-service-account.yaml create mode 100644 pulsar/templates/broker-statefulset.yaml create mode 100644 pulsar/templates/function-worker-configmap.yaml create mode 100644 pulsar/templates/keytool.yaml delete mode 100644 pulsar/templates/proxy-deployment.yaml create mode 100644 pulsar/templates/proxy-statefulset.yaml create mode 100644 pulsar/templates/pulsar-cluster-initialize.yaml create mode 100644 pulsar/templates/tls-cert-internal-issuer.yaml create mode 100644 pulsar/templates/tls-certs-internal.yaml create mode 100644 pulsar/templates/toolset-configmap.yaml create mode 100644 pulsar/templates/toolset-service.yaml create mode 100644 pulsar/templates/toolset-statefulset.yaml delete mode 100644 pulsar/templates/zookeeper-metadata.yaml delete mode 100644 pulsar/values-mini.yaml create mode 100755 scripts/cert-manager/install-cert-manager.sh create mode 100755 scripts/pulsar/clean_tls.sh create mode 100755 scripts/pulsar/cleanup_helm_release.sh create mode 100755 scripts/pulsar/common.sh create mode 100755 scripts/pulsar/common_auth.sh create mode 100755 scripts/pulsar/generate_token.sh create mode 100755 scripts/pulsar/generate_token_secret_key.sh create mode 100755 scripts/pulsar/get_token.sh create mode 100755 scripts/pulsar/prepare_helm_release.sh create mode 100755 scripts/pulsar/upload_tls.sh diff --git a/examples/values-cs.yaml b/examples/values-cs.yaml new file mode 100644 index 0000000..1611c36 --- /dev/null +++ b/examples/values-cs.yaml @@ -0,0 +1,45 @@ +# +# 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. +# + +metadataPrefix: "/configuration-store" + +## start +components: + # zookeeper + zookeeper: true + # bookkeeper + bookkeeper: false + # bookkeeper - autorecovery + autorecovery: false + # broker + broker: false + # proxy + proxy: false + # toolset + toolset: false + # pulsar manager + pulsar_manager: false + +monitoring: + # monitoring - prometheus + prometheus: false + # monitoring - grafana + grafana: false + # monitoring - node_exporter + node_exporter: false \ No newline at end of file diff --git a/examples/values-jwt-asymmetric.yaml b/examples/values-jwt-asymmetric.yaml new file mode 100644 index 0000000..1948894 --- /dev/null +++ b/examples/values-jwt-asymmetric.yaml @@ -0,0 +1,37 @@ +# +# 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. +# + +auth: + authentication: + enabled: true + provider: "jwt" + jwt: + # Enable JWT authentication + # If the token is generated by a secret key, set the usingSecretKey as true. + # If the token is generated by a private key, set the usingSecretKey as false. + usingSecretKey: false + authorization: + enabled: true + superUsers: + # broker to broker communication + broker: "broker-admin" + # proxy to broker communication + proxy: "proxy-admin" + # pulsar-admin client to broker/proxy communication + client: "admin" \ No newline at end of file diff --git a/examples/values-jwt-symmetric.yaml b/examples/values-jwt-symmetric.yaml new file mode 100644 index 0000000..22b05ce --- /dev/null +++ b/examples/values-jwt-symmetric.yaml @@ -0,0 +1,37 @@ +# +# 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. +# + +auth: + authentication: + enabled: true + provider: "jwt" + jwt: + # Enable JWT authentication + # If the token is generated by a secret key, set the usingSecretKey as true. + # If the token is generated by a private key, set the usingSecretKey as false. + usingSecretKey: true + authorization: + enabled: true + superUsers: + # broker to broker communication + broker: "broker-admin" + # proxy to broker communication + proxy: "proxy-admin" + # pulsar-admin client to broker/proxy communication + client: "admin" \ No newline at end of file diff --git a/examples/values-local-cluster.yaml b/examples/values-local-cluster.yaml new file mode 100644 index 0000000..19eac4a --- /dev/null +++ b/examples/values-local-cluster.yaml @@ -0,0 +1,37 @@ +# +# 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. +# + +metadataPrefix: "/cluster1" + +pulsar_metadata: + configurationStore: pulsar-cs-zookeeper + configurationStoreMetadataPrefix: "/configuration-store" + +## disable pulsar-manager +components: + pulsar_manager: true + +## disable monitoring stack +monitoring: + # monitoring - prometheus + prometheus: false + # monitoring - grafana + grafana: false + # monitoring - node_exporter + node_exporter: false \ No newline at end of file diff --git a/examples/values-local-pv.yaml b/examples/values-local-pv.yaml new file mode 100644 index 0000000..c393763 --- /dev/null +++ b/examples/values-local-pv.yaml @@ -0,0 +1,21 @@ +# +# 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. +# + +volumes: + local_storage: true \ No newline at end of file diff --git a/examples/values-minikube.yaml b/examples/values-minikube.yaml new file mode 100644 index 0000000..2cd2a22 --- /dev/null +++ b/examples/values-minikube.yaml @@ -0,0 +1,50 @@ +# +# 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. +# + +## deployed withh emptyDir +volumes: + persistence: false + +# disabled AntiAffinity +affinity: + anti_affinity: false + +# disable auto recovery +components: + autorecovery: false + +zookeeper: + replicaCount: 1 + +bookkeeper: + replicaCount: 1 + +broker: + replicaCount: 1 + configData: + ## Enable `autoSkipNonRecoverableData` since bookkeeper is running + ## without persistence + autoSkipNonRecoverableData: "true" + # storage settings + managedLedgerDefaultEnsembleSize: "1" + managedLedgerDefaultWriteQuorum: "1" + managedLedgerDefaultAckQuorum: "1" + +proxy: + replicaCount: 1 \ No newline at end of file diff --git a/examples/values-no-persistence.yaml b/examples/values-no-persistence.yaml new file mode 100644 index 0000000..a613366 --- /dev/null +++ b/examples/values-no-persistence.yaml @@ -0,0 +1,28 @@ +# +# 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. +# + +## deployed withh emptyDir +volumes: + persistence: false + +## Enable `autoSkipNonRecoverableData` since bookkeeper is running +## without persistence +broker: + configData: + autoSkipNonRecoverableData: "true" \ No newline at end of file diff --git a/examples/values-one-node.yaml b/examples/values-one-node.yaml new file mode 100644 index 0000000..80a31dd --- /dev/null +++ b/examples/values-one-node.yaml @@ -0,0 +1,54 @@ +# +# 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. +# + +# disabled AntiAffinity +affinity: + anti_affinity: false + +images: + broker: + repository: apachepulsar/pulsar-all + tag: 2.5.0 + functions: + repository: apachepulsar/pulsar-all + tag: 2.5.0 + +# disable auto recovery +components: + autorecovery: false + +zookeeper: + replicaCount: 1 + +bookkeeper: + replicaCount: 1 + +broker: + replicaCount: 1 + configData: + ## Enable `autoSkipNonRecoverableData` since bookkeeper is running + ## without persistence + autoSkipNonRecoverableData: "true" + # storage settings + managedLedgerDefaultEnsembleSize: "1" + managedLedgerDefaultWriteQuorum: "1" + managedLedgerDefaultAckQuorum: "1" + +proxy: + replicaCount: 1 \ No newline at end of file diff --git a/examples/values-pulsar.yaml b/examples/values-pulsar.yaml new file mode 100644 index 0000000..b1cfb0c --- /dev/null +++ b/examples/values-pulsar.yaml @@ -0,0 +1,50 @@ +# +# 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. +# + +images: + zookeeper: + repository: apachepulsar/pulsar-all + tag: 2.5.0 + bookie: + repository: apachepulsar/pulsar-all + tag: 2.5.0 + autorecovery: + repository: apachepulsar/pulsar-all + tag: 2.5.0 + broker: + repository: apachepulsar/pulsar-all + tag: 2.5.0 + functions: + repository: apachepulsar/pulsar-all + tag: 2.5.0 + proxy: + repository: apachepulsar/pulsar-all + tag: 2.5.0 + +bookkeeper: + metadata: + image: + repository: apachepulsar/pulsar-all + tag: 2.5.0 + + +pulsar_metadata: + image: + repository: apachepulsar/pulsar-all + tag: 2.5.0 diff --git a/examples/values-tls.yaml b/examples/values-tls.yaml new file mode 100644 index 0000000..fadab07 --- /dev/null +++ b/examples/values-tls.yaml @@ -0,0 +1,34 @@ +# +# 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. +# + +# enable TLS +tls: + enabled: true + proxy: + enabled: true + broker: + enabled: true + zookeeper: + enabled: true + +# issue selfsigning certs +certs: + internal_issuer: + enabled: true + type: selfsigning \ No newline at end of file diff --git a/hack/common.sh b/hack/common.sh new file mode 100755 index 0000000..3d13b06 --- /dev/null +++ b/hack/common.sh @@ -0,0 +1,135 @@ +#!/usr/bin/env bash +# +# 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 [ -z "$PULSAR_CHART_HOME" ]; then + echo "error: PULSAR_CHART_HOME should be initialized" + exit 1 +fi + +OUTPUT=${PULSAR_CHART_HOME}/output +OUTPUT_BIN=${OUTPUT}/bin +KUBECTL_VERSION=1.14.3 +KUBECTL_BIN=$OUTPUT_BIN/kubectl +HELM_BIN=$OUTPUT_BIN/helm +HELM_VERSION=3.0.1 +KIND_VERSION=0.6.1 +KIND_BIN=$OUTPUT_BIN/kind +CR_BIN=$OUTPUT_BIN/cr +CR_VERSION=1.0.0-beta.1 + +test -d "$OUTPUT_BIN" || mkdir -p "$OUTPUT_BIN" + +ARCH="" +hack::discoverArch() { + ARCH=$(uname -m) + case $ARCH in + x86) ARCH="386";; + x86_64) ARCH="amd64";; + i686) ARCH="386";; + i386) ARCH="386";; + esac +} + +hack::discoverArch +OS=$(echo `uname`|tr '[:upper:]' '[:lower:]') + +function hack::verify_kubectl() { + if test -x "$KUBECTL_BIN"; then + [[ "$($KUBECTL_BIN version --client --short | grep -o -E '[0-9]+\.[0-9]+\.[0-9]+')" == "$KUBECTL_VERSION" ]] + return + fi + return 1 +} + +function hack::ensure_kubectl() { + if hack::verify_kubectl; then + return 0 + fi + echo "Installing kubectl v$KUBECTL_VERSION..." + tmpfile=$(mktemp) + trap "test -f $tmpfile && rm $tmpfile" RETURN + curl --retry 10 -L -o $tmpfile https://storage.googleapis.com/kubernetes-release/release/v${KUBECTL_VERSION}/bin/${OS}/${ARCH}/kubectl + mv $tmpfile $KUBECTL_BIN + chmod +x $KUBECTL_BIN +} + +function hack::verify_helm() { + if test -x "$HELM_BIN"; then + local v=$($HELM_BIN version --short --client | grep -o -E '[0-9]+\.[0-9]+\.[0-9]+') + [[ "$v" == "$HELM_VERSION" ]] + return + fi + return 1 +} + +function hack::ensure_helm() { + if hack::verify_helm; then + return 0 + fi + local HELM_URL=https://get.helm.sh/helm-v${HELM_VERSION}-${OS}-${ARCH}.tar.gz + curl --retry 10 -L -s "$HELM_URL" | tar --strip-components 1 -C $OUTPUT_BIN -zxf - ${OS}-${ARCH}/helm +} + +function hack::verify_kind() { + if test -x "$KIND_BIN"; then + [[ "$($KIND_BIN --version 2>&1 | cut -d ' ' -f 3)" == "$KIND_VERSION" ]] + return + fi + return 1 +} + +function hack::ensure_kind() { + if hack::verify_kind; then + return 0 + fi + echo "Installing kind v$KIND_VERSION..." + tmpfile=$(mktemp) + trap "test -f $tmpfile && rm $tmpfile" RETURN + curl --retry 10 -L -o $tmpfile https://github.com/kubernetes-sigs/kind/releases/download/v${KIND_VERSION}/kind-$(uname)-amd64 + mv $tmpfile $KIND_BIN + chmod +x $KIND_BIN +} + +# hack::version_ge "$v1" "$v2" checks whether "v1" is greater or equal to "v2" +function hack::version_ge() { + [ "$(printf '%s\n' "$1" "$2" | sort -V | head -n1)" = "$2" ] +} + +function hack::verify_cr() { + if test -x "$CR_BIN"; then + return + fi + return 1 +} + +function hack::ensure_cr() { + if hack::verify_cr; then + $CR_BIN version + return 0 + fi + echo "Installing chart-releaser ${CR_VERSION} ..." + tmpfile=$(mktemp) + trap "test -f $tmpfile && rm $tmpfile" RETURN + echo curl --retry 10 -L -o $tmpfile https://github.com/helm/chart-releaser/releases/download/v${CR_VERSION}/chart-releaser_${CR_VERSION}_${OS}_${ARCH}.tar.gz + curl --retry 10 -L -o $tmpfile https://github.com/helm/chart-releaser/releases/download/v${CR_VERSION}/chart-releaser_${CR_VERSION}_${OS}_${ARCH}.tar.gz + mv $tmpfile $CR_BIN + chmod +x $CR_BIN + $CR_BIN version +} diff --git a/hack/kind-cluster-build.sh b/hack/kind-cluster-build.sh new file mode 100755 index 0000000..0ae3468 --- /dev/null +++ b/hack/kind-cluster-build.sh @@ -0,0 +1,251 @@ +#!/usr/bin/env bash +# +# 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. +# + +PULSAR_CHART_HOME=$(unset CDPATH && cd $(dirname "${BASH_SOURCE[0]}")/.. && pwd) +cd ${PULSAR_CHART_HOME} + +source ${PULSAR_CHART_HOME}/hack/common.sh + +hack::ensure_kubectl +hack::ensure_helm + +usage() { + cat </dev/null;then + echo "${requirement} have installed" + else + echo "this script needs ${requirement}, please install ${requirement} first." + exit 1 + fi +done + +echo "############# start create cluster:[${clusterName}] #############" +workDir=${HOME}/kind/${clusterName} +mkdir -p ${workDir} + +data_dir=${workDir}/data + +echo "clean data dir: ${data_dir}" +if [ -d ${data_dir} ]; then + rm -rf ${data_dir} +fi + +configFile=${workDir}/kind-config.yaml + +cat < ${configFile} +kind: Cluster +apiVersion: kind.sigs.k8s.io/v1alpha3 +nodes: +- role: control-plane + extraPortMappings: + - containerPort: 5000 + hostPort: 5000 + listenAddress: 127.0.0.1 + protocol: TCP +EOF + +for ((i=0;i<${nodeNum};i++)) +do + mkdir -p ${data_dir}/worker${i} + cat <> ${configFile} +- role: worker + extraMounts: +EOF + for ((k=1;k<=${volumeNum};k++)) + do + mkdir -p ${data_dir}/worker${i}/vol${k} + cat <> ${configFile} + - containerPath: /mnt/disks/vol${k} + hostPath: ${data_dir}/worker${i}/vol${k} +EOF + done +done + +matchedCluster=$(kind get clusters | grep ${clusterName}) +if [[ "${matchedCluster}" == "${clusterName}" ]]; then + echo "Kind cluster ${clusterName} already exists" + kind delete cluster --name=${clusterName} +fi +echo "start to create k8s cluster" +kind create cluster --config ${configFile} --image kindest/node:${k8sVersion} --name=${clusterName} +export KUBECONFIG=${workDir}/kubeconfig.yaml +kind get kubeconfig --name=${clusterName} > ${KUBECONFIG} + +echo "deploy docker registry in kind" +registryNode=${clusterName}-control-plane +registryNodeIP=$($KUBECTL_BIN get nodes ${registryNode} -o template --template='{{range.status.addresses}}{{if eq .type "InternalIP"}}{{.address}}{{end}}{{end}}') +registryFile=${workDir}/registry.yaml + +cat <${registryFile} +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: registry +spec: + selector: + matchLabels: + app: registry + template: + metadata: + labels: + app: registry + spec: + hostNetwork: true + nodeSelector: + kubernetes.io/hostname: ${registryNode} + tolerations: + - key: node-role.kubernetes.io/master + operator: "Equal" + effect: "NoSchedule" + containers: + - name: registry + image: registry:2 + volumeMounts: + - name: data + mountPath: /data + volumes: + - name: data + hostPath: + path: /data +--- +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: registry-proxy + labels: + app: registry-proxy +spec: + selector: + matchLabels: + app: registry-proxy + template: + metadata: + labels: + app: registry-proxy + spec: + hostNetwork: true + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/hostname + operator: NotIn + values: + - ${registryNode} + tolerations: + - key: node-role.kubernetes.io/master + operator: "Equal" + effect: "NoSchedule" + containers: + - name: socat + image: alpine/socat:1.0.5 + args: + - tcp-listen:5000,fork,reuseaddr + - tcp-connect:${registryNodeIP}:5000 +EOF +$KUBECTL_BIN apply -f ${registryFile} + +echo "init pulsar env" +$KUBECTL_BIN apply -f ${PULSAR_CHART_HOME}/manifests/local-dind/local-volume-provisioner.yaml + +docker pull gcr.io/google-containers/kube-scheduler:${k8sVersion} +docker tag gcr.io/google-containers/kube-scheduler:${k8sVersion} mirantis/hypokube:final +kind load docker-image --name=${clusterName} mirantis/hypokube:final + +echo "############# success create cluster:[${clusterName}] #############" + +echo "To start using your cluster, run:" +echo " export KUBECONFIG=${KUBECONFIG}" +echo "" +echo < && kind load +docker-image ' command to load images into nodes. +EOF \ No newline at end of file diff --git a/pulsar/Chart.yaml b/pulsar/Chart.yaml index f4cefc0..f2c535e 100644 --- a/pulsar/Chart.yaml +++ b/pulsar/Chart.yaml @@ -22,3 +22,10 @@ appVersion: "1.0" description: Apache Pulsar Helm chart for Kubernetes name: pulsar version: 1.0.0 +home: https://pulsar.apache.org +sources: +- https://github.com/apache/pulsar +icon: http://pulsar.apache.org/img/pulsar.svg +maintainers: +- name: The Apache Pulsar Team + email: dev@pulsar.apache.org diff --git a/pulsar/templates/_autorecovery.tpl b/pulsar/templates/_autorecovery.tpl new file mode 100644 index 0000000..3fb3f4b --- /dev/null +++ b/pulsar/templates/_autorecovery.tpl @@ -0,0 +1,80 @@ +{{/* +Define the pulsar autorecovery service +*/}} +{{- define "pulsar.autorecovery.service" -}} +{{ template "pulsar.fullname" . }}-{{ .Values.autorecovery.component }} +{{- end }} + +{{/* +Define the autorecovery hostname +*/}} +{{- define "pulsar.autorecovery.hostname" -}} +${HOSTNAME}.{{ template "pulsar.autorecovery.service" . }}.{{ .Values.namespace }}.svc.cluster.local +{{- end -}} + +{{/* +Define autorecovery zookeeper client tls settings +*/}} +{{- define "pulsar.autorecovery.zookeeper.tls.settings" -}} +{{- if and .Values.tls.enabled .Values.tls.zookeeper.enabled }} +/pulsar/keytool/keytool.sh autorecovery {{ template "pulsar.autorecovery.hostname" . }} true; +{{- end }} +{{- end }} + +{{/* +Define autorecovery tls certs mounts +*/}} +{{- define "pulsar.autorecovery.certs.volumeMounts" -}} +{{- if and .Values.tls.enabled .Values.tls.zookeeper.enabled }} +- name: autorecovery-certs + mountPath: "/pulsar/certs/autorecovery" + readOnly: true +- name: ca + mountPath: "/pulsar/certs/ca" + readOnly: true +{{- if .Values.tls.zookeeper.enabled }} +- name: keytool + mountPath: "/pulsar/keytool/keytool.sh" + subPath: keytool.sh +{{- end }} +{{- end }} +{{- end }} + +{{/* +Define autorecovery tls certs volumes +*/}} +{{- define "pulsar.autorecovery.certs.volumes" -}} +{{- if and .Values.tls.enabled .Values.tls.zookeeper.enabled }} +- name: autorecovery-certs + secret: + secretName: "{{ template "pulsar.fullname" . }}-{{ .Values.tls.autorecovery.cert_name }}" + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key +- name: ca + secret: + secretName: "{{ template "pulsar.fullname" . }}-ca-tls" + items: + - key: ca.crt + path: ca.crt +{{- if .Values.tls.zookeeper.enabled }} +- name: keytool + configMap: + name: "{{ template "pulsar.fullname" . }}-keytool-configmap" + defaultMode: 0755 +{{- end }} +{{- end }} +{{- end }} + +{{/* +Define autorecovery init container : verify cluster id +*/}} +{{- define "pulsar.autorecovery.init.verify_cluster_id" -}} +bin/apply-config-from-env.py conf/bookkeeper.conf; +{{- include "pulsar.autorecovery.zookeeper.tls.settings" . -}} +until bin/bookkeeper shell whatisinstanceid; do + sleep 3; +done; +{{- end }} \ No newline at end of file diff --git a/pulsar/templates/_bookkeeper.tpl b/pulsar/templates/_bookkeeper.tpl new file mode 100644 index 0000000..d828009 --- /dev/null +++ b/pulsar/templates/_bookkeeper.tpl @@ -0,0 +1,121 @@ +{{/* +Define the pulsar bookkeeper service +*/}} +{{- define "pulsar.bookkeeper.service" -}} +{{ template "pulsar.fullname" . }}-{{ .Values.bookkeeper.component }} +{{- end }} + +{{/* +Define the bookkeeper hostname +*/}} +{{- define "pulsar.bookkeeper.hostname" -}} +${HOSTNAME}.{{ template "pulsar.bookkeeper.service" . }}.{{ .Values.namespace }}.svc.cluster.local +{{- end -}} + + +{{/* +Define bookie zookeeper client tls settings +*/}} +{{- define "pulsar.bookkeeper.zookeeper.tls.settings" -}} +{{- if and .Values.tls.enabled .Values.tls.zookeeper.enabled }} +/pulsar/keytool/keytool.sh bookie {{ template "pulsar.bookkeeper.hostname" . }} true; +{{- end }} +{{- end }} + +{{/* +Define bookie tls certs mounts +*/}} +{{- define "pulsar.bookkeeper.certs.volumeMounts" -}} +{{- if and .Values.tls.enabled (or .Values.tls.bookie.enabled .Values.tls.zookeeper.enabled) }} +- name: bookie-certs + mountPath: "/pulsar/certs/bookie" + readOnly: true +- name: ca + mountPath: "/pulsar/certs/ca" + readOnly: true +{{- if .Values.tls.zookeeper.enabled }} +- name: keytool + mountPath: "/pulsar/keytool/keytool.sh" + subPath: keytool.sh +{{- end }} +{{- end }} +{{- end }} + +{{/* +Define bookie tls certs volumes +*/}} +{{- define "pulsar.bookkeeper.certs.volumes" -}} +{{- if and .Values.tls.enabled (or .Values.tls.bookie.enabled .Values.tls.zookeeper.enabled) }} +- name: bookie-certs + secret: + secretName: "{{ template "pulsar.fullname" . }}-{{ .Values.tls.bookie.cert_name }}" + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key +- name: ca + secret: + secretName: "{{ template "pulsar.fullname" . }}-ca-tls" + items: + - key: ca.crt + path: ca.crt +{{- if .Values.tls.zookeeper.enabled }} +- name: keytool + configMap: + name: "{{ template "pulsar.fullname" . }}-keytool-configmap" + defaultMode: 0755 +{{- end }} +{{- end }} +{{- end }} + +{{/* +Define bookie common config +*/}} +{{- define "pulsar.bookkeeper.config.common" -}} +zkServers: "{{ template "pulsar.zookeeper.connect" . }}" +zkLedgersRootPath: "{{ .Values.metadataPrefix }}/ledgers" +# enable bookkeeper http server +httpServerEnabled: "true" +httpServerPort: "{{ .Values.bookkeeper.ports.http }}" +# config the stats provider +statsProviderClass: org.apache.bookkeeper.stats.prometheus.PrometheusMetricsProvider +# use hostname as the bookie id +useHostNameAsBookieID: "true" +{{- end }} + +{{/* +Define bookie tls config +*/}} +{{- define "pulsar.bookkeeper.config.tls" -}} +{{- if and .Values.tls.enabled .Values.tls.bookie.enabled }} +PULSAR_PREFIX_tlsProviderFactoryClass: org.apache.bookkeeper.tls.TLSContextFactory +PULSAR_PREFIX_tlsCertificatePath: /pulsar/certs/bookie/tls.crt +PULSAR_PREFIX_tlsKeyStoreType: PEM +PULSAR_PREFIX_tlsKeyStore: /pulsar/certs/bookie/tls.key +PULSAR_PREFIX_tlsTrustStoreType: PEM +PULSAR_PREFIX_tlsTrustStore: /pulsar/certs/ca/ca.crt +{{- end }} +{{- end }} + +{{/* +Define bookie init container : verify cluster id +*/}} +{{- define "pulsar.bookkeeper.init.verify_cluster_id" -}} +{{- if not (and .Values.volumes.persistence .Values.bookkeeper.volumes.persistence) }} +bin/apply-config-from-env.py conf/bookkeeper.conf; +{{- include "pulsar.bookkeeper.zookeeper.tls.settings" . -}} +until bin/bookkeeper shell whatisinstanceid; do + sleep 3; +done; +bin/bookkeeper shell bookieformat -nonInteractive -force -deleteCookie || true +{{- end }} +{{- if and .Values.volumes.persistence .Values.bookkeeper.volumes.persistence }} +set -e; +bin/apply-config-from-env.py conf/bookkeeper.conf; +{{- include "pulsar.bookkeeper.zookeeper.tls.settings" . -}} +until bin/bookkeeper shell whatisinstanceid; do + sleep 3; +done; +{{- end }} +{{- end }} \ No newline at end of file diff --git a/pulsar/templates/_broker.tpl b/pulsar/templates/_broker.tpl new file mode 100644 index 0000000..cff94f9 --- /dev/null +++ b/pulsar/templates/_broker.tpl @@ -0,0 +1,76 @@ +{{/* +Define the pulsar brroker service +*/}} +{{- define "pulsar.broker.service" -}} +{{ template "pulsar.fullname" . }}-{{ .Values.broker.component }} +{{- end }} + +{{/* +Define the hostname +*/}} +{{- define "pulsar.broker.hostname" -}} +${HOSTNAME}.{{ template "pulsar.broker.service" . }}.{{ .Values.namespace }}.svc.cluster.local +{{- end -}} + +{{/* +Define the broker znode +*/}} +{{- define "pulsar.broker.znode" -}} +{{ .Values.metadataPrefix }}/loadbalance/brokers/{{ template "pulsar.broker.hostname" . }}:{{ .Values.broker.ports.http }} +{{- end }} + +{{/* +Define broker zookeeper client tls settings +*/}} +{{- define "pulsar.broker.zookeeper.tls.settings" -}} +{{- if and .Values.tls.enabled .Values.tls.zookeeper.enabled }} +/pulsar/keytool/keytool.sh broker {{ template "pulsar.broker.hostname" . }} true; +{{- end }} +{{- end }} + +{{/* +Define broker tls certs mounts +*/}} +{{- define "pulsar.broker.certs.volumeMounts" -}} +{{- if and .Values.tls.enabled (or .Values.tls.broker.enabled (or .Values.tls.bookie.enabled .Values.tls.zookeeper.enabled)) }} +- name: broker-certs + mountPath: "/pulsar/certs/broker" + readOnly: true +- name: ca + mountPath: "/pulsar/certs/ca" + readOnly: true +{{- if .Values.tls.zookeeper.enabled }} +- name: keytool + mountPath: "/pulsar/keytool/keytool.sh" + subPath: keytool.sh +{{- end }} +{{- end }} +{{- end }} + +{{/* +Define broker tls certs volumes +*/}} +{{- define "pulsar.broker.certs.volumes" -}} +{{- if and .Values.tls.enabled (or .Values.tls.broker.enabled (or .Values.tls.bookie.enabled .Values.tls.zookeeper.enabled)) }} +- name: broker-certs + secret: + secretName: "{{ template "pulsar.fullname" . }}-{{ .Values.tls.broker.cert_name }}" + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key +- name: ca + secret: + secretName: "{{ template "pulsar.fullname" . }}-ca-tls" + items: + - key: ca.crt + path: ca.crt +{{- if .Values.tls.zookeeper.enabled }} +- name: keytool + configMap: + name: "{{ template "pulsar.fullname" . }}-keytool-configmap" + defaultMode: 0755 +{{- end }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/pulsar/templates/_helpers.tpl b/pulsar/templates/_helpers.tpl index ba25c6e..931e097 100644 --- a/pulsar/templates/_helpers.tpl +++ b/pulsar/templates/_helpers.tpl @@ -1,4 +1,12 @@ {{/* vim: set filetype=mustache: */}} + +{{/* +pulsar home +*/}} +{{- define "pulsar.home" -}} +{{- print "/pulsar" -}} +{{- end -}} + {{/* Expand the name of the chart. */}} @@ -30,3 +38,31 @@ 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 -}} + +{{/* +Create the common labels. +*/}} +{{- define "pulsar.standardLabels" -}} +app: {{ template "pulsar.name" . }} +chart: {{ template "pulsar.chart" . }} +release: {{ .Release.Name }} +heritage: {{ .Release.Service }} +cluster: {{ template "pulsar.fullname" . }} +{{- end }} + +{{/* +Create the template labels. +*/}} +{{- define "pulsar.template.labels" -}} +app: {{ template "pulsar.name" . }} +release: {{ .Release.Name }} +cluster: {{ template "pulsar.fullname" . }} +{{- end }} + +{{/* +Create the match labels. +*/}} +{{- define "pulsar.matchLabels" -}} +app: {{ template "pulsar.name" . }} +release: {{ .Release.Name }} +{{- end }} diff --git a/pulsar/templates/_toolset.tpl b/pulsar/templates/_toolset.tpl new file mode 100644 index 0000000..405fa71 --- /dev/null +++ b/pulsar/templates/_toolset.tpl @@ -0,0 +1,69 @@ +{{/* +Define the pulsar toolset service +*/}} +{{- define "pulsar.toolset.service" -}} +{{ template "pulsar.fullname" . }}-{{ .Values.toolset.component }} +{{- end }} + +{{/* +Define the toolset hostname +*/}} +{{- define "pulsar.toolset.hostname" -}} +${HOSTNAME}.{{ template "pulsar.toolset.service" . }}.{{ .Values.namespace }}.svc.cluster.local +{{- end -}} + +{{/* +Define toolset zookeeper client tls settings +*/}} +{{- define "pulsar.toolset.zookeeper.tls.settings" -}} +{{- if and .Values.tls.enabled .Values.tls.zookeeper.enabled -}} +/pulsar/keytool/keytool.sh toolset {{ template "pulsar.toolset.hostname" . }} true; +{{- end -}} +{{- end }} + +{{/* +Define toolset tls certs mounts +*/}} +{{- define "pulsar.toolset.certs.volumeMounts" -}} +{{- if and .Values.tls.enabled .Values.tls.zookeeper.enabled }} +- name: toolset-certs + mountPath: "/pulsar/certs/toolset" + readOnly: true +- name: ca + mountPath: "/pulsar/certs/ca" + readOnly: true +{{- if .Values.tls.zookeeper.enabled }} +- name: keytool + mountPath: "/pulsar/keytool/keytool.sh" + subPath: keytool.sh +{{- end }} +{{- end }} +{{- end }} + +{{/* +Define toolset tls certs volumes +*/}} +{{- define "pulsar.toolset.certs.volumes" -}} +{{- if and .Values.tls.enabled .Values.tls.zookeeper.enabled }} +- name: toolset-certs + secret: + secretName: "{{ template "pulsar.fullname" . }}-{{ .Values.tls.toolset.cert_name }}" + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key +- name: ca + secret: + secretName: "{{ template "pulsar.fullname" . }}-ca-tls" + items: + - key: ca.crt + path: ca.crt +{{- if .Values.tls.zookeeper.enabled }} +- name: keytool + configMap: + name: "{{ template "pulsar.fullname" . }}-keytool-configmap" + defaultMode: 0755 +{{- end }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/pulsar/templates/_zookeeper.tpl b/pulsar/templates/_zookeeper.tpl new file mode 100644 index 0000000..ca5c1d1 --- /dev/null +++ b/pulsar/templates/_zookeeper.tpl @@ -0,0 +1,34 @@ +{{/* +Define the pulsar zookeeper +*/}} +{{- define "pulsar.zookeeper.service" -}} +{{ template "pulsar.fullname" . }}-{{ .Values.zookeeper.component }} +{{- end }} + +{{/* +Define the pulsar zookeeper +*/}} +{{- define "pulsar.zookeeper.connect" -}} +{{- if not (and .Values.tls.enabled .Values.tls.zookeeper.enabled) -}} +{{ template "pulsar.zookeeper.service" . }}:{{ .Values.zookeeper.ports.client }} +{{- end -}} +{{- if and .Values.tls.enabled .Values.tls.zookeeper.enabled -}} +{{ template "pulsar.zookeeper.service" . }}:{{ .Values.zookeeper.ports.clientTls }} +{{- end -}} +{{- end -}} + +{{/* +Define the zookeeper hostname +*/}} +{{- define "pulsar.zookeeper.hostname" -}} +${HOSTNAME}.{{ template "pulsar.zookeeper.service" . }}.{{ .Values.namespace }}.svc.cluster.local +{{- end -}} + +{{/* +Define zookeeper tls settings +*/}} +{{- define "pulsar.zookeeper.tls.settings" -}} +{{- if and .Values.tls.enabled .Values.tls.zookeeper.enabled }} +/pulsar/keytool/keytool.sh zookeeper {{ template "pulsar.zookeeper.hostname" . }} false; +{{- end }} +{{- end }} diff --git a/pulsar/templates/autorecovery-configmap.yaml b/pulsar/templates/autorecovery-configmap.yaml index 4200e6c..8d7fb3f 100644 --- a/pulsar/templates/autorecovery-configmap.yaml +++ b/pulsar/templates/autorecovery-configmap.yaml @@ -17,22 +17,17 @@ # under the License. # -{{- if .Values.extra.autoRecovery }} +{{- if or .Values.components.autorecovery .Values.extra.autoRecovery }} apiVersion: v1 kind: ConfigMap metadata: - name: "{{ template "pulsar.fullname" . }}-{{ .Values.autoRecovery.component }}" + 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" . }} + {{- include "pulsar.standardLabels" . | nindent 4 }} + component: {{ .Values.autorecovery.component }} data: - zkServers: - {{- $global := . }} - {{ range $i, $e := until (.Values.zookeeper.replicaCount | int) }}{{ if ne $i 0 }},{{ end }}{{ template "pulsar.fullname" $global }}-{{ $global.Values.zookeeper.component }}-{{ printf "%d" $i }}.{{ template "pulsar.fullname" $global }}-{{ $global.Values.zookeeper.component }}{{ end }} -{{ toYaml .Values.autoRecovery.configData | indent 2 }} + # common config + {{- include "pulsar.bookkeeper.config.common" . | nindent 2 }} +{{ toYaml .Values.autorecovery.configData | indent 2 }} {{- end }} diff --git a/pulsar/templates/autorecovery-deployment.yaml b/pulsar/templates/autorecovery-deployment.yaml deleted file mode 100644 index 0872693..0000000 --- a/pulsar/templates/autorecovery-deployment.yaml +++ /dev/null @@ -1,105 +0,0 @@ -# -# 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" . }}" - - key: "release" - operator: In - values: - - {{ .Release.Name }} - - key: "component" - operator: In - values: - - {{ .Values.bookkeeper.component }} - topologyKey: "kubernetes.io/hostname" - terminationGracePeriodSeconds: {{ .Values.autoRecovery.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 bin/pulsar zookeeper-shell -server {{ template "pulsar.fullname" . }}-{{ .Values.zookeeper.component }} ls /admin/clusters/{{ template "pulsar.fullname" . }}; 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/pulsar/templates/bastion-configmap.yaml b/pulsar/templates/autorecovery-service.yaml similarity index 68% rename from pulsar/templates/bastion-configmap.yaml rename to pulsar/templates/autorecovery-service.yaml index 4e42fcc..ab237c9 100644 --- a/pulsar/templates/bastion-configmap.yaml +++ b/pulsar/templates/autorecovery-service.yaml @@ -17,19 +17,23 @@ # under the License. # -{{- if .Values.extra.bastion }} +{{- if or .Values.components.autorecovery .Values.extra.autoRecovery }} apiVersion: v1 -kind: ConfigMap +kind: Service metadata: - name: "{{ template "pulsar.fullname" . }}-{{ .Values.bastion.component }}" + name: "{{ template "pulsar.fullname" . }}-{{ .Values.autorecovery.component }}" namespace: {{ .Values.namespace }} labels: + {{- include "pulsar.standardLabels" . | nindent 4 }} + component: {{ .Values.autorecovery.component }} +spec: + ports: + - name: http + port: {{ .Values.autorecovery.ports.http }} + clusterIP: None + selector: 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 }} + component: {{ .Values.autorecovery.component }} {{- end }} + diff --git a/pulsar/templates/autorecovery-statefulset.yaml b/pulsar/templates/autorecovery-statefulset.yaml new file mode 100644 index 0000000..c4e1f61 --- /dev/null +++ b/pulsar/templates/autorecovery-statefulset.yaml @@ -0,0 +1,124 @@ +# +# 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 or .Values.components.autorecovery .Values.extra.autoRecovery }} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: "{{ template "pulsar.fullname" . }}-{{ .Values.autorecovery.component }}" + namespace: {{ .Values.namespace }} + labels: + {{- include "pulsar.standardLabels" . | nindent 4 }} + component: {{ .Values.autorecovery.component }} +spec: + serviceName: "{{ template "pulsar.fullname" . }}-{{ .Values.autorecovery.component }}" + replicas: {{ .Values.autorecovery.replicaCount }} + updateStrategy: + type: RollingUpdate + podManagementPolicy: Parallel + # nodeSelector: + selector: + matchLabels: + {{- include "pulsar.matchLabels" . | nindent 6 }} + component: {{ .Values.autorecovery.component }} + template: + metadata: + labels: + {{- include "pulsar.template.labels" . | nindent 8 }} + component: {{ .Values.autorecovery.component }} + annotations: + prometheus.io/scrape: "true" + prometheus.io/port: "{{ .Values.autorecovery.ports.http }}" +{{- with .Values.autorecovery.annotations }} +{{ toYaml . | indent 8 }} +{{- end }} + spec: + {{- if .Values.autorecovery.nodeSelector }} + nodeSelector: +{{ toYaml .Values.autorecovery.nodeSelector | indent 8 }} + {{- end }} + {{- if .Values.autorecovery.tolerations }} + tolerations: +{{- with .Values.autorecovery.tolerations }} +{{ toYaml . | indent 8 }} +{{- end }} + {{- end }} + affinity: + {{- if and .Values.affinity.anti_affinity .Values.autorecovery.affinity.anti_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" + {{- end }} + terminationGracePeriodSeconds: {{ .Values.autorecovery.gracePeriod }} + initContainers: + # This initContainer will wait for bookkeeper initnewcluster to complete + # before deploying the bookies + - name: pulsar-bookkeeper-verify-clusterid + image: "{{ .Values.images.autorecovery.repository }}:{{ .Values.images.autorecovery.tag }}" + imagePullPolicy: {{ .Values.images.autorecovery.pullPolicy }} + command: ["sh", "-c"] + args: + - > + {{- include "pulsar.autorecovery.init.verify_cluster_id" . | nindent 10 }} + envFrom: + - configMapRef: + name: "{{ template "pulsar.fullname" . }}-{{ .Values.autorecovery.component }}" + volumeMounts: + {{- include "pulsar.autorecovery.certs.volumeMounts" . | nindent 8 }} + containers: + - name: "{{ template "pulsar.fullname" . }}-{{ .Values.autorecovery.component }}" + image: "{{ .Values.images.autorecovery.repository }}:{{ .Values.images.autorecovery.tag }}" + imagePullPolicy: {{ .Values.images.autorecovery.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/apply-config-from-env.py conf/bkenv.sh; + {{- include "pulsar.autorecovery.zookeeper.tls.settings" . | nindent 10 }} + bin/bookkeeper autorecovery + ports: + - name: http + containerPort: {{ .Values.autorecovery.ports.http }} + envFrom: + - configMapRef: + name: "{{ template "pulsar.fullname" . }}-{{ .Values.autorecovery.component }}" + volumeMounts: + {{- include "pulsar.autorecovery.certs.volumeMounts" . | nindent 8 }} + volumes: + {{- include "pulsar.autorecovery.certs.volumes" . | nindent 6 }} +{{- end }} + diff --git a/pulsar/templates/bastion-deployment.yaml b/pulsar/templates/bastion-deployment.yaml deleted file mode 100644 index afc6a73..0000000 --- a/pulsar/templates/bastion-deployment.yaml +++ /dev/null @@ -1,80 +0,0 @@ -# -# 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/pulsar/templates/bookkeeper-cluster-initialize.yaml b/pulsar/templates/bookkeeper-cluster-initialize.yaml new file mode 100644 index 0000000..a9ab647 --- /dev/null +++ b/pulsar/templates/bookkeeper-cluster-initialize.yaml @@ -0,0 +1,71 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +{{- if .Values.components.bookkeeper }} +apiVersion: batch/v1 +kind: Job +metadata: + name: "{{ template "pulsar.fullname" . }}-{{ .Values.bookkeeper.component }}-init" + namespace: {{ .Values.namespace }} + labels: + {{- include "pulsar.standardLabels" . | nindent 4 }} + component: "{{ .Values.bookkeeper.component }}-init" +spec: + template: + spec: + initContainers: + - name: wait-zookeeper-ready + image: "{{ .Values.bookkeeper.metadata.image.repository }}:{{ .Values.bookkeeper.metadata.image.tag }}" + imagePullPolicy: {{ .Values.bookkeeper.metadata.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.bookkeeper.component }}-init" + image: "{{ .Values.bookkeeper.metadata.image.repository }}:{{ .Values.bookkeeper.metadata.image.tag }}" + imagePullPolicy: {{ .Values.bookkeeper.metadata.image.pullPolicy }} + {{- if .Values.bookkeeper.metadata.resources }} + resources: +{{ toYaml .Values.bookkeeper.metadata.resources | indent 10 }} + {{- end }} + command: ["sh", "-c"] + args: + - > + bin/apply-config-from-env.py conf/bookkeeper.conf; + {{- include "pulsar.toolset.zookeeper.tls.settings" . | nindent 12 }} + if bin/bookkeeper shell whatisinstanceid; then + echo "bookkeeper cluster already initialized"; + else + {{- if not (eq .Values.metadataPrefix "") }} + bin/bookkeeper org.apache.zookeeper.ZooKeeperMain -server {{ template "pulsar.fullname" . }}-{{ .Values.zookeeper.component }} create {{ .Values.metadataPrefix }} 'created for pulsar cluster "{{ template "pulsar.fullname" . }}"' || yes && + {{- end }} + bin/bookkeeper shell initnewcluster; + fi + envFrom: + - configMapRef: + name: "{{ template "pulsar.fullname" . }}-{{ .Values.bookkeeper.component }}" + volumeMounts: + {{- include "pulsar.toolset.certs.volumeMounts" . | nindent 8 }} + volumes: + {{- include "pulsar.toolset.certs.volumes" . | nindent 6 }} + restartPolicy: Never +{{- end }} diff --git a/pulsar/templates/bookkeeper-configmap.yaml b/pulsar/templates/bookkeeper-configmap.yaml index 45a8546..05c43ce 100644 --- a/pulsar/templates/bookkeeper-configmap.yaml +++ b/pulsar/templates/bookkeeper-configmap.yaml @@ -17,22 +17,28 @@ # under the License. # +{{- if .Values.components.bookkeeper }} 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 }} + {{- include "pulsar.standardLabels" . | nindent 4 }} component: {{ .Values.bookkeeper.component }} - cluster: {{ template "pulsar.fullname" . }} data: - zkServers: - {{- $global := . }} - {{ range $i, $e := until (.Values.zookeeper.replicaCount | int) }}{{ if ne $i 0 }},{{ end }}{{ template "pulsar.fullname" $global }}-{{ $global.Values.zookeeper.component }}-{{ printf "%d" $i }}.{{ template "pulsar.fullname" $global }}-{{ $global.Values.zookeeper.component }}{{ end }} + # common config + {{- include "pulsar.bookkeeper.config.common" . | nindent 2 }} + {{- if .Values.components.autorecovery }} # disable auto recovery on bookies since we will start AutoRecovery in separated pods autoRecoveryDaemonEnabled: "false" + {{- end }} + # Do not retain journal files as it increase the disk utilization + journalMaxBackups: "0" + journalDirectories: "/pulsar/data/bookkeeper/journal" + PULSAR_PREFIX_journalDirectories: "/pulsar/data/bookkeeper/journal" + ledgerDirectories: "/pulsar/data/bookkeeper/ledgers" + # TLS config + {{- include "pulsar.bookkeeper.config.tls" . | nindent 2 }} {{ toYaml .Values.bookkeeper.configData | indent 2 }} +{{- end }} \ No newline at end of file diff --git a/pulsar/templates/bookkeeper-pdb.yaml b/pulsar/templates/bookkeeper-pdb.yaml index 8f045f7..35ac16d 100644 --- a/pulsar/templates/bookkeeper-pdb.yaml +++ b/pulsar/templates/bookkeeper-pdb.yaml @@ -17,6 +17,7 @@ # under the License. # +{{- if .Values.components.bookkeeper }} {{- if .Values.bookkeeper.pdb.usePolicy }} apiVersion: policy/v1beta1 kind: PodDisruptionBudget @@ -24,17 +25,13 @@ 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 }} + {{- include "pulsar.standardLabels" . | nindent 4 }} component: {{ .Values.bookkeeper.component }} - cluster: {{ template "pulsar.fullname" . }} spec: selector: matchLabels: - app: {{ template "pulsar.name" . }} - release: {{ .Release.Name }} + {{- include "pulsar.matchLabels" . | nindent 6 }} component: {{ .Values.bookkeeper.component }} maxUnavailable: {{ .Values.bookkeeper.pdb.maxUnavailable }} {{- end }} +{{- end }} diff --git a/pulsar/templates/bookkeeper-service.yaml b/pulsar/templates/bookkeeper-service.yaml index 82658ba..388635b 100644 --- a/pulsar/templates/bookkeeper-service.yaml +++ b/pulsar/templates/bookkeeper-service.yaml @@ -17,25 +17,25 @@ # under the License. # +{{- if .Values.components.bookkeeper }} 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 }} + {{- include "pulsar.standardLabels" . | nindent 4 }} 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 }} + - name: bookie + port: {{ .Values.bookkeeper.ports.bookie }} + - name: http + port: {{ .Values.bookkeeper.ports.http }} clusterIP: None selector: - app: {{ template "pulsar.name" . }} - release: {{ .Release.Name }} + {{- include "pulsar.matchLabels" . | nindent 4 }} component: {{ .Values.bookkeeper.component }} +{{- end }} diff --git a/pulsar/templates/bookkeeper-statefulset.yaml b/pulsar/templates/bookkeeper-statefulset.yaml index 012eb4e..71df9ab 100644 --- a/pulsar/templates/bookkeeper-statefulset.yaml +++ b/pulsar/templates/bookkeeper-statefulset.yaml @@ -17,25 +17,21 @@ # under the License. # +{{- if .Values.components.bookkeeper }} 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 }} + {{- include "pulsar.standardLabels" . | nindent 4 }} 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 }} + {{- include "pulsar.matchLabels" . | nindent 6 }} component: {{ .Values.bookkeeper.component }} updateStrategy: {{ toYaml .Values.bookkeeper.updateStrategy | indent 4 }} @@ -43,12 +39,14 @@ spec: template: metadata: labels: - app: {{ template "pulsar.name" . }} - release: {{ .Release.Name }} + {{- include "pulsar.template.labels" . | nindent 8 }} component: {{ .Values.bookkeeper.component }} - cluster: {{ template "pulsar.fullname" . }} annotations: -{{ toYaml .Values.bookkeeper.annotations | indent 8 }} + prometheus.io/scrape: "true" + prometheus.io/port: "{{ .Values.bookkeeper.ports.http }}" +{{- with .Values.bookkeeper.annotations }} +{{ toYaml . | indent 8 }} +{{- end }} spec: {{- if .Values.bookkeeper.nodeSelector }} nodeSelector: @@ -59,6 +57,7 @@ spec: {{ toYaml .Values.bookkeeper.tolerations | indent 8 }} {{- end }} affinity: + {{- if and .Values.affinity.anti_affinity .Values.bookkeeper.affinity.anti_affinity}} podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: @@ -66,7 +65,7 @@ spec: - key: "app" operator: In values: - - "{{ template "pulsar.name" . }}" + - "{{ template "pulsar.name" . }}-{{ .Values.bookkeeper.component }}" - key: "release" operator: In values: @@ -76,36 +75,55 @@ spec: values: - {{ .Values.bookkeeper.component }} topologyKey: "kubernetes.io/hostname" + {{- end }} 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 bin/pulsar zookeeper-shell -server {{ template "pulsar.fullname" . }}-{{ .Values.zookeeper.component }} ls /admin/clusters/{{ template "pulsar.fullname" . }}; 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 }} + # This initContainer will wait for bookkeeper initnewcluster to complete + # before deploying the bookies + - name: pulsar-bookkeeper-verify-clusterid + image: "{{ .Values.images.bookie.repository }}:{{ .Values.images.bookie.tag }}" + imagePullPolicy: {{ .Values.images.bookie.pullPolicy }} command: ["sh", "-c"] args: + # only reformat bookie if bookkeeper is running without persistence - > - bin/apply-config-from-env.py conf/bookkeeper.conf && - bin/bookkeeper shell metaformat --nonInteractive || true; + {{- include "pulsar.bookkeeper.init.verify_cluster_id" . | nindent 10 }} envFrom: - configMapRef: name: "{{ template "pulsar.fullname" . }}-{{ .Values.bookkeeper.component }}" + volumeMounts: + {{- include "pulsar.bookkeeper.certs.volumeMounts" . | nindent 8 }} containers: - name: "{{ template "pulsar.fullname" . }}-{{ .Values.bookkeeper.component }}" - image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" - imagePullPolicy: {{ .Values.image.pullPolicy }} + image: "{{ .Values.images.bookie.repository }}:{{ .Values.images.bookie.tag }}" + imagePullPolicy: {{ .Values.images.bookie.pullPolicy }} + {{- if .Values.bookkeeper.probe.liveness.enabled }} + livenessProbe: + httpGet: + path: /api/v1/bookie/state + port: {{ .Values.bookkeeper.ports.http }} + initialDelaySeconds: {{ .Values.bookkeeper.probe.liveness.initialDelaySeconds }} + periodSeconds: {{ .Values.bookkeeper.probe.liveness.periodSeconds }} + failureThreshold: {{ .Values.bookkeeper.probe.liveness.failureThreshold }} + {{- end }} + {{- if .Values.bookkeeper.probe.readiness.enabled }} + readinessProbe: + httpGet: + path: /api/v1/bookie/is_ready + port: {{ .Values.bookkeeper.ports.http }} + initialDelaySeconds: {{ .Values.bookkeeper.probe.readiness.initialDelaySeconds }} + periodSeconds: {{ .Values.bookkeeper.probe.readiness.periodSeconds }} + failureThreshold: {{ .Values.bookkeeper.probe.readiness.failureThreshold }} + {{- end }} + {{- if .Values.bookkeeper.probe.startup.enabled }} + startupProbe: + httpGet: + path: /api/v1/bookie/is_ready + port: {{ .Values.bookkeeper.ports.http }} + initialDelaySeconds: {{ .Values.bookkeeper.probe.startup.initialDelaySeconds }} + periodSeconds: {{ .Values.bookkeeper.probe.startup.periodSeconds }} + failureThreshold: {{ .Values.bookkeeper.probe.startup.failureThreshold }} + {{- end }} {{- if .Values.bookkeeper.resources }} resources: {{ toYaml .Values.bookkeeper.resources | indent 10 }} @@ -113,13 +131,16 @@ spec: command: ["sh", "-c"] args: - > - bin/apply-config-from-env.py conf/bookkeeper.conf && - bin/apply-config-from-env.py conf/pulsar_env.sh && - bin/apply-config-from-env.py conf/bkenv.sh && - bin/pulsar bookie + bin/apply-config-from-env.py conf/bookkeeper.conf; + bin/apply-config-from-env.py conf/pulsar_env.sh; + bin/apply-config-from-env.py conf/bkenv.sh; + {{- include "pulsar.bookkeeper.zookeeper.tls.settings" . | nindent 10 }} + bin/pulsar bookie; ports: - - name: client - containerPort: 3181 + - name: bookie + containerPort: {{ .Values.bookkeeper.ports.bookie }} + - name: http + containerPort: {{ .Values.bookkeeper.ports.http }} envFrom: - configMapRef: name: "{{ template "pulsar.fullname" . }}-{{ .Values.bookkeeper.component }}" @@ -128,14 +149,16 @@ spec: 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 }} + {{- include "pulsar.bookkeeper.certs.volumeMounts" . | nindent 8 }} volumes: + {{- if not (and (and .Values.persistence .Values.volumes.persistence) .Values.bookkeeper.volumes.persistence) }} - 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 }} + {{- end }} + {{- include "pulsar.bookkeeper.certs.volumes" . | nindent 6 }} +{{- if and (and .Values.persistence .Values.volumes.persistence) .Values.bookkeeper.volumes.persistence}} volumeClaimTemplates: - metadata: name: "{{ template "pulsar.fullname" . }}-{{ .Values.bookkeeper.component }}-{{ .Values.bookkeeper.volumes.journal.name }}" @@ -146,8 +169,10 @@ spec: storage: {{ .Values.bookkeeper.volumes.journal.size }} {{- if .Values.bookkeeper.volumes.journal.storageClassName }} storageClassName: "{{ .Values.bookkeeper.volumes.journal.storageClassName }}" - {{- else if .Values.bookkeeper.volumes.journal.storageClass }} + {{- else if and (not (and .Values.volumes.local_storage .Values.bookkeeper.volumes.journal.local_storage)) .Values.bookkeeper.volumes.journal.storageClass }} storageClassName: "{{ template "pulsar.fullname" . }}-{{ .Values.bookkeeper.component }}-{{ .Values.bookkeeper.volumes.journal.name }}" + {{- else if and .Values.volumes.local_storage .Values.bookkeeper.volumes.journal.local_storage }} + storageClassName: "local-storage" {{- end }} - metadata: name: "{{ template "pulsar.fullname" . }}-{{ .Values.bookkeeper.component }}-{{ .Values.bookkeeper.volumes.ledgers.name }}" @@ -158,7 +183,10 @@ spec: storage: {{ .Values.bookkeeper.volumes.ledgers.size }} {{- if .Values.bookkeeper.volumes.ledgers.storageClassName }} storageClassName: "{{ .Values.bookkeeper.volumes.ledgers.storageClassName }}" - {{- else if .Values.bookkeeper.volumes.ledgers.storageClass }} + {{- else if and (not (and .Values.volumes.local_storage .Values.bookkeeper.volumes.ledgers.local_storage)) .Values.bookkeeper.volumes.ledgers.storageClass }} storageClassName: "{{ template "pulsar.fullname" . }}-{{ .Values.bookkeeper.component }}-{{ .Values.bookkeeper.volumes.ledgers.name }}" + {{- else if and .Values.volumes.local_storage .Values.bookkeeper.volumes.ledgers.local_storage }} + storageClassName: "local-storage" {{- end }} {{- end }} +{{- end }} diff --git a/pulsar/templates/bookkeeper-storageclass.yaml b/pulsar/templates/bookkeeper-storageclass.yaml index f6e7fc7..3e8ebce 100644 --- a/pulsar/templates/bookkeeper-storageclass.yaml +++ b/pulsar/templates/bookkeeper-storageclass.yaml @@ -17,20 +17,17 @@ # under the License. # -{{- if .Values.persistence }} -{{- if .Values.bookkeeper.volumes.journal.storageClass }} +{{- if .Values.components.bookkeeper }} +{{- if and (and .Values.persistence .Values.volumes.persistence) .Values.bookkeeper.volumes.persistence }} +{{- if and (not (and .Values.volumes.local_storage .Values.bookkeeper.volumes.journal.local_storage)) .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 }} + {{- include "pulsar.standardLabels" . | nindent 4 }} component: {{ .Values.bookkeeper.component }} - cluster: {{ template "pulsar.fullname" . }} provisioner: {{ .Values.bookkeeper.volumes.journal.storageClass.provisioner }} parameters: type: {{ .Values.bookkeeper.volumes.journal.storageClass.type }} @@ -38,22 +35,20 @@ parameters: {{- end }} --- -{{- if .Values.bookkeeper.volumes.ledgers.storageClass }} +{{- if and (not (and .Values.volumes.local_storage .Values.bookkeeper.volumes.journal.local_storage)) .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 }} + {{- include "pulsar.standardLabels" . | nindent 4 }} 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 }} {{- end }} diff --git a/pulsar/templates/broker-cluster-role-binding.yaml b/pulsar/templates/broker-cluster-role-binding.yaml new file mode 100644 index 0000000..803fccb --- /dev/null +++ b/pulsar/templates/broker-cluster-role-binding.yaml @@ -0,0 +1,66 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +{{- if .Values.components.broker }} +## TODO create our own cluster role with less privledges than admin +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: "{{ template "pulsar.fullname" . }}-{{ .Values.broker.component }}-clusterrolebinding" + labels: + {{- include "pulsar.standardLabels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: "{{ template "pulsar.fullname" . }}-{{ .Values.broker.component }}-clusterrole" +subjects: +- kind: ServiceAccount + name: "{{ template "pulsar.fullname" . }}-{{ .Values.broker.component }}-acct" + namespace: {{ .Values.namespace }} +--- + +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRole +metadata: + name: "{{ template "pulsar.fullname" . }}-{{ .Values.broker.component }}-clusterrole" + labels: + {{- include "pulsar.standardLabels" . | nindent 4 }} +rules: +- apiGroups: [""] + resources: + - configmap + verbs: ["get", "list", "watch"] +- apiGroups: ["", "extensions", "apps"] + resources: + - pods + - services + - deployments + - secrets + - statefulsets + verbs: + - list + - watch + - get + - update + - create + - delete + - patch +--- + +{{- end }} \ No newline at end of file diff --git a/pulsar/templates/broker-configmap.yaml b/pulsar/templates/broker-configmap.yaml index 6a35e39..721038a 100644 --- a/pulsar/templates/broker-configmap.yaml +++ b/pulsar/templates/broker-configmap.yaml @@ -17,31 +17,130 @@ # under the License. # +{{- if .Values.components.broker }} 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 }} + {{- include "pulsar.standardLabels" . | nindent 4 }} component: {{ .Values.broker.component }} - cluster: {{ template "pulsar.fullname" . }} data: - zookeeperServers: - {{- $global := . }} - {{ range $i, $e := until (.Values.zookeeper.replicaCount | int) }}{{ if ne $i 0 }},{{ end }}{{ template "pulsar.fullname" $global }}-{{ $global.Values.zookeeper.component }}-{{ printf "%d" $i }}.{{ template "pulsar.fullname" $global }}-{{ $global.Values.zookeeper.component }}{{ end }} - configurationStoreServers: - {{- $global := . }} - {{ range $i, $e := until (.Values.zookeeper.replicaCount | int) }}{{ if ne $i 0 }},{{ end }}{{ template "pulsar.fullname" $global }}-{{ $global.Values.zookeeper.component }}-{{ printf "%d" $i }}.{{ template "pulsar.fullname" $global }}-{{ $global.Values.zookeeper.component }}{{ end }} + # Metadata settings + zookeeperServers: "{{ template "pulsar.zookeeper.connect" . }}{{ .Values.metadataPrefix }}" + {{- if .Values.pulsar_metadata.configurationStore }} + configurationStoreServers: "{{ .Values.pulsar_metadata.configurationStore }}{{ .Values.pulsar_metadata.configurationStoreMetadataPrefix }}" + {{- end }} + {{- if not .Values.pulsar_metadata.configurationStore }} + configurationStoreServers: "{{ template "pulsar.zookeeper.connect" . }}{{ .Values.metadataPrefix }}" + {{- end }} + + # Broker settings clusterName: {{ template "pulsar.fullname" . }} + exposeTopicLevelMetricsInPrometheus: "true" + numHttpServerThreads: "8" + zooKeeperSessionTimeoutMillis: "30000" + statusFilePath: "{{ template "pulsar.home" . }}/status" + + # Function Worker Settings + # function worker configuration + {{- if not (or .Values.components.functions .Values.extra.functionsAsPods) }} + functionsWorkerEnabled: "false" + {{- end }} + {{- if or .Values.components.functions .Values.extra.functionsAsPods }} functionsWorkerEnabled: "true" - PF_pulsarFunctionsCluster: {{ template "pulsar.fullname" . }} - {{- if .Values.extra.functionsAsPods }} PF_functionRuntimeFactoryClassName: "org.apache.pulsar.functions.runtime.kubernetes.KubernetesRuntimeFactory" + PF_pulsarFunctionsCluster: {{ template "pulsar.fullname" . }} + PF_connectorsDirectory: ./connectors + PF_containerFactory: k8s + PF_numFunctionPackageReplicas: "{{ .Values.broker.configData.managedLedgerDefaultEnsembleSize }}" + # support version >= 2.5.0 + PF_functionRuntimeFactoryConfigs_pulsarRootDir: {{ template "pulsar.home" . }} + PF_kubernetesContainerFactory_pulsarRootDir: {{ template "pulsar.home" . }} + PF_functionRuntimeFactoryConfigs_pulsarDockerImageName: "{{ .Values.images.functions.repository }}:{{ .Values.images.functions.tag }}" PF_functionRuntimeFactoryConfigs_submittingInsidePod: "true" + PF_functionRuntimeFactoryConfigs_installUserCodeDependencies: "true" PF_functionRuntimeFactoryConfigs_jobNamespace: {{ .Values.namespace }} + PF_functionRuntimeFactoryConfigs_expectedMetricsCollectionInterval: "30" + {{- if not (and .Values.tls.enabled .Values.tls.broker.enabled) }} + PF_functionRuntimeFactoryConfigs_pulsarAdminUrl: "http://{{ template "pulsar.fullname" . }}-{{ .Values.broker.component }}:{{ .Values.broker.ports.http }}/" + PF_functionRuntimeFactoryConfigs_pulsarServiceUrl: "pulsar://{{ template "pulsar.fullname" . }}-{{ .Values.broker.component }}:{{ .Values.broker.ports.pulsar }}/" + {{- end }} + {{- if and .Values.tls.enabled .Values.tls.broker.enabled }} + PF_functionRuntimeFactoryConfigs_pulsarAdminUrl: "https://{{ template "pulsar.fullname" . }}-{{ .Values.broker.component }}:{{ .Values.broker.ports.https }}/" + PF_functionRuntimeFactoryConfigs_pulsarServiceUrl: "pulsar+ssl://{{ template "pulsar.fullname" . }}-{{ .Values.broker.component }}:{{ .Values.broker.ports.pulsarssl }}/" + {{- end }} + PF_functionRuntimeFactoryConfigs_changeConfigMap: "{{ template "pulsar.fullname" . }}-{{ .Values.functions.component }}-config" + PF_functionRuntimeFactoryConfigs_changeConfigMapNamespace: {{ .Values.namespace }} + # support version < 2.5.0 + PF_kubernetesContainerFactory_pulsarDockerImageName: "{{ .Values.images.functions.repository }}:{{ .Values.images.functions.tag }}" + PF_kubernetesContainerFactory_submittingInsidePod: "true" + PF_kubernetesContainerFactory_installUserCodeDependencies: "true" + PF_kubernetesContainerFactory_jobNamespace: {{ .Values.namespace }} + PF_kubernetesContainerFactory_expectedMetricsCollectionInterval: "30" + {{- if not (and .Values.tls.enabled .Values.tls.broker.enabled) }} + PF_kubernetesContainerFactory_pulsarAdminUrl: "http://{{ template "pulsar.fullname" . }}-{{ .Values.broker.component }}:{{ .Values.broker.ports.http }}/" + PF_kubernetesContainerFactory_pulsarServiceUrl: "pulsar://{{ template "pulsar.fullname" . }}-{{ .Values.broker.component }}:{{ .Values.broker.ports.pulsar }}/" + {{- end }} + {{- if and .Values.tls.enabled .Values.tls.broker.enabled }} + PF_kubernetesContainerFactory_pulsarAdminUrl: "https://{{ template "pulsar.fullname" . }}-{{ .Values.broker.component }}:{{ .Values.broker.ports.https }}/" + PF_kubernetesContainerFactory_pulsarServiceUrl: "pulsar+ssl://{{ template "pulsar.fullname" . }}-{{ .Values.broker.component }}:{{ .Values.broker.ports.pulsarssl }}/" + {{- end }} + PF_kubernetesContainerFactory_changeConfigMap: "{{ template "pulsar.fullname" . }}-{{ .Values.functions.component }}-config" + PF_kubernetesContainerFactory_changeConfigMapNamespace: {{ .Values.namespace }} + {{- end }} + + # prometheus needs to access /metrics endpoint + webServicePort: "{{ .Values.broker.ports.http }}" + {{- if or (not .Values.tls.enabled) (not .Values.tls.broker.enabled) }} + brokerServicePort: "{{ .Values.broker.ports.pulsar }}" + {{- end }} + {{- if and .Values.tls.enabled .Values.tls.broker.enabled }} + brokerServicePortTls: "{{ .Values.broker.ports.pulsarssl }}" + webServicePortTls: "{{ .Values.broker.ports.https }}" + # TLS Settings + tlsCertificateFilePath: "/pulsar/certs/broker/tls.crt" + tlsKeyFilePath: "/pulsar/certs/broker/tls.key" + tlsTrustCertsFilePath: "/pulsar/certs/ca/ca.crt" + {{- end }} + + # Authentication Settings + {{- if .Values.auth.authentication.enabled }} + authenticationEnabled: "true" + {{- if .Values.auth.authorization.enabled }} + authorizationEnabled: "true" + superUserRoles: {{ .Values.auth.superUsers.broker }},{{ .Values.auth.superUsers.proxy }},{{ .Values.auth.superUsers.client }} + {{- end }} + {{- if eq .Values.auth.authentication.provider "jwt" }} + # token authentication configuration + authenticationProviders: "org.apache.pulsar.broker.authentication.AuthenticationProviderToken" + brokerClientAuthenticationParameters: "file:///pulsar/tokens/broker/token" + brokerClientAuthenticationPlugin: "org.apache.pulsar.client.impl.auth.AuthenticationToken" + {{- if .Values.auth.authentication.jwt.usingSecretKey }} + tokenSecretKey: "file:///pulsar/keys/token/secret.key" + {{- else }} + tokenPublicKey: "file:///pulsar/keys/token/public.key" + {{- end }} + {{- end }} + {{- end }} + + {{- if and .Values.tls.enabled .Values.tls.bookie.enabled }} + # bookkeeper tls settings + bookkeeperTLSClientAuthentication: "true" + bookkeeperTLSKeyFileType: "PEM" + bookkeeperTLSKeyFilePath: "/pulsar/certs/broker/tls.key" + bookkeeperTLSCertificateFilePath: "/pulsar/certs/broker/tls.crt" + bookkeeperTLSTrustCertsFilePath: "/pulsar/certs/ca/ca.crt" + bookkeeperTLSTrustCertTypes: "PEM" + PULSAR_PREFIX_bookkeeperTLSClientAuthentication: "true" + PULSAR_PREFIX_bookkeeperTLSKeyFileType: "PEM" + PULSAR_PREFIX_bookkeeperTLSKeyFilePath: "/pulsar/certs/broker/tls.key" + PULSAR_PREFIX_bookkeeperTLSCertificateFilePath: "/pulsar/certs/broker/tls.crt" + PULSAR_PREFIX_bookkeeperTLSTrustCertsFilePath: "/pulsar/certs/ca/ca.crt" + PULSAR_PREFIX_bookkeeperTLSTrustCertTypes: "PEM" + # https://github.com/apache/bookkeeper/pull/2300 + bookkeeperUseV2WireProtocol: "false" {{- end }} {{ toYaml .Values.broker.configData | indent 2 }} +{{- end }} \ No newline at end of file diff --git a/pulsar/templates/broker-deployment.yaml b/pulsar/templates/broker-deployment.yaml deleted file mode 100644 index 5571489..0000000 --- a/pulsar/templates/broker-deployment.yaml +++ /dev/null @@ -1,131 +0,0 @@ -# -# 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. -# - -{{- $ensembleSize := .Values.broker.configData.managedLedgerDefaultEnsembleSize }} -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 }} - {{- if .Values.extra.functionsAsPods }} - serviceAccount: "{{ template "pulsar.fullname" . }}-{{ .Values.broker.functions.component }}" - {{- end }} - affinity: - podAntiAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - - labelSelector: - matchExpressions: - - key: "app" - operator: In - values: - - "{{ template "pulsar.name" . }}" - - 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 bin/pulsar zookeeper-shell -server {{ template "pulsar.fullname" . }}-{{ .Values.zookeeper.component }} ls /admin/clusters/{{ template "pulsar.fullname" . }}; do - sleep 3; - done; - # This init container will wait for bookkeeper to be ready before - # deploying the broker - - name: wait-bookkeeper-ready - image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" - imagePullPolicy: {{ .Values.image.pullPolicy }} - command: ["sh", "-c"] - args: - - >- - bin/apply-config-from-env.py conf/bookkeeper.conf && - until bin/bookkeeper shell simpletest -ensemble {{$ensembleSize}}; 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/gen-yml-from-env.py conf/functions_worker.yml && - 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/pulsar/templates/broker-pdb.yaml b/pulsar/templates/broker-pdb.yaml index 6f60d59..a3843a1 100644 --- a/pulsar/templates/broker-pdb.yaml +++ b/pulsar/templates/broker-pdb.yaml @@ -17,6 +17,7 @@ # under the License. # +{{- if .Values.components.broker }} {{- if .Values.broker.pdb.usePolicy }} apiVersion: policy/v1beta1 kind: PodDisruptionBudget @@ -24,17 +25,13 @@ 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 }} + {{- include "pulsar.standardLabels" . | nindent 4 }} component: {{ .Values.broker.component }} - cluster: {{ template "pulsar.fullname" . }} spec: selector: matchLabels: - app: {{ template "pulsar.name" . }} - release: {{ .Release.Name }} + {{- include "pulsar.matchLabels" . | nindent 6 }} component: {{ .Values.broker.component }} maxUnavailable: {{ .Values.broker.pdb.maxUnavailable }} {{- end }} +{{- end }} diff --git a/pulsar/templates/broker-service-account.yaml b/pulsar/templates/broker-service-account.yaml new file mode 100644 index 0000000..257f593 --- /dev/null +++ b/pulsar/templates/broker-service-account.yaml @@ -0,0 +1,29 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +{{- if .Values.components.broker }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: "{{ template "pulsar.fullname" . }}-{{ .Values.broker.component }}-acct" + namespace: {{ .Values.namespace }} + labels: + {{- include "pulsar.standardLabels" . | nindent 4 }} + component: {{ .Values.broker.component }} +{{- end }} \ No newline at end of file diff --git a/pulsar/templates/broker-service.yaml b/pulsar/templates/broker-service.yaml index 8cfe718..2b30333 100644 --- a/pulsar/templates/broker-service.yaml +++ b/pulsar/templates/broker-service.yaml @@ -17,25 +17,35 @@ # under the License. # +{{- if .Values.components.broker }} 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 }} + {{- include "pulsar.standardLabels" . | nindent 4 }} 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 }} + # prometheus needs to access /metrics endpoint + - name: http + port: {{ .Values.broker.ports.http }} + {{- if or (not .Values.tls.enabled) (not .Values.tls.broker.enabled) }} + - name: pulsar + port: {{ .Values.broker.ports.pulsar }} + {{- end }} + {{- if and .Values.tls.enabled .Values.tls.broker.enabled }} + - name: https + port: {{ .Values.broker.ports.https }} + - name: pulsarssl + port: {{ .Values.broker.ports.pulsarssl }} + {{- end }} clusterIP: None selector: app: {{ template "pulsar.name" . }} release: {{ .Release.Name }} component: {{ .Values.broker.component }} +{{- end }} diff --git a/pulsar/templates/broker-statefulset.yaml b/pulsar/templates/broker-statefulset.yaml new file mode 100644 index 0000000..591c104 --- /dev/null +++ b/pulsar/templates/broker-statefulset.yaml @@ -0,0 +1,236 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +{{- if .Values.components.broker }} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: "{{ template "pulsar.fullname" . }}-{{ .Values.broker.component }}" + namespace: {{ .Values.namespace }} + labels: + {{- include "pulsar.standardLabels" . | nindent 4 }} + component: {{ .Values.broker.component }} +spec: + serviceName: "{{ template "pulsar.fullname" . }}-{{ .Values.broker.component }}" + replicas: {{ .Values.broker.replicaCount }} + selector: + matchLabels: + {{- include "pulsar.matchLabels" . | nindent 6 }} + component: {{ .Values.broker.component }} + updateStrategy: + type: RollingUpdate + podManagementPolicy: Parallel + template: + metadata: + labels: + {{- include "pulsar.template.labels" . | nindent 8 }} + component: {{ .Values.broker.component }} + annotations: + prometheus.io/scrape: "true" + prometheus.io/port: "{{ .Values.broker.ports.http }}" +{{- with .Values.broker.annotations }} +{{ toYaml . | indent 8 }} +{{- end }} + spec: + serviceAccountName: "{{ template "pulsar.fullname" . }}-{{ .Values.broker.component }}-acct" + {{- 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: + {{- if and .Values.affinity.anti_affinity .Values.broker.affinity.anti_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" + {{- end }} + 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.images.broker.repository }}:{{ .Values.images.broker.tag }}" + imagePullPolicy: {{ .Values.images.broker.pullPolicy }} + command: ["sh", "-c"] + args: + - >- + {{- include "pulsar.broker.zookeeper.tls.settings" . | nindent 12 }} + {{- if .Values.pulsar_metadata.configurationStore }} + until bin/bookkeeper org.apache.zookeeper.ZooKeeperMain -server {{ .Values.pulsar_metadata.configurationStore}} get {{ .Values.configurationStoreMetadataPrefix }}/admin/clusters/{{ template "pulsar.fullname" . }}; do + {{- end }} + {{- if not .Values.pulsar_metadata.configurationStore }} + until bin/bookkeeper org.apache.zookeeper.ZooKeeperMain -server {{ template "pulsar.zookeeper.connect" . }} get {{ .Values.metadataPrefix }}/admin/clusters/{{ template "pulsar.fullname" . }}; do + {{- end }} + echo "pulsar cluster {{ template "pulsar.fullname" . }} isn't initialized yet ... check in 3 seconds ..." && sleep 3; + done; + volumeMounts: + {{- include "pulsar.broker.certs.volumeMounts" . | nindent 8 }} + # This init container will wait for bookkeeper to be ready before + # deploying the broker + - name: wait-bookkeeper-ready + image: "{{ .Values.images.broker.repository }}:{{ .Values.images.broker.tag }}" + imagePullPolicy: {{ .Values.images.broker.pullPolicy }} + command: ["sh", "-c"] + args: + - > + {{- include "pulsar.broker.zookeeper.tls.settings" . | nindent 12 }} + bin/apply-config-from-env.py conf/bookkeeper.conf; + until bin/bookkeeper shell whatisinstanceid; do + echo "bookkeeper cluster is not initialized yet. backoff for 3 seconds ..."; + sleep 3; + done; + echo "bookkeeper cluster is already initialized"; + bookieServiceNumber="$(nslookup -timeout=10 {{ template "pulsar.fullname" . }}-{{ .Values.bookkeeper.component }} | grep Name | wc -l)"; + until [ ${bookieServiceNumber} -ge {{ .Values.broker.configData.managedLedgerDefaultEnsembleSize }} ]; do + echo "bookkeeper cluster {{ template "pulsar.fullname" . }} isn't ready yet ... check in 10 seconds ..."; + sleep 10; + bookieServiceNumber="$(nslookup -timeout=10 {{ template "pulsar.fullname" . }}-{{ .Values.bookkeeper.component }} | grep Name | wc -l)"; + done; + echo "bookkeeper cluster is ready"; + envFrom: + - configMapRef: + name: "{{ template "pulsar.fullname" . }}-{{ .Values.bookkeeper.component }}" + volumeMounts: + {{- include "pulsar.broker.certs.volumeMounts" . | nindent 10 }} + containers: + - name: "{{ template "pulsar.fullname" . }}-{{ .Values.broker.component }}" + image: "{{ .Values.images.broker.repository }}:{{ .Values.images.broker.tag }}" + imagePullPolicy: {{ .Values.images.broker.pullPolicy }} + {{- if .Values.broker.probe.liveness.enabled }} + livenessProbe: + httpGet: + path: /status.html + port: {{ .Values.broker.ports.http }} + initialDelaySeconds: {{ .Values.broker.probe.liveness.initialDelaySeconds }} + periodSeconds: {{ .Values.broker.probe.liveness.periodSeconds }} + failureThreshold: {{ .Values.broker.probe.liveness.failureThreshold }} + {{- end }} + {{- if .Values.broker.probe.readiness.enabled }} + readinessProbe: + httpGet: + path: /status.html + port: {{ .Values.broker.ports.http }} + initialDelaySeconds: {{ .Values.broker.probe.readiness.initialDelaySeconds }} + periodSeconds: {{ .Values.broker.probe.readiness.periodSeconds }} + failureThreshold: {{ .Values.broker.probe.readiness.failureThreshold }} + {{- end }} + {{- if .Values.broker.probe.startup.enabled }} + startupProbe: + httpGet: + path: /status.html + port: {{ .Values.broker.ports.http }} + initialDelaySeconds: {{ .Values.broker.probe.startup.initialDelaySeconds }} + periodSeconds: {{ .Values.broker.probe.startup.periodSeconds }} + failureThreshold: {{ .Values.broker.probe.startup.failureThreshold }} + {{- end }} + {{- 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/gen-yml-from-env.py conf/functions_worker.yml; + echo "OK" > status; + {{- include "pulsar.broker.zookeeper.tls.settings" . | nindent 10 }} + bin/pulsar zookeeper-shell -server {{ template "pulsar.zookeeper.connect" . }} get {{ template "pulsar.broker.znode" . }}; + while [ $? -eq 0 ]; do + echo "broker {{ template "pulsar.broker.hostname" . }} znode still exists ... check in 10 seconds ..."; + sleep 10; + bin/pulsar zookeeper-shell -server {{ template "pulsar.zookeeper.connect" . }} get {{ template "pulsar.broker.znode" . }}; + done; + cat conf/pulsar_env.sh; + bin/pulsar broker; + ports: + # prometheus needs to access /metrics endpoint + - name: http + containerPort: {{ .Values.broker.ports.http }} + {{- if or (not .Values.tls.enabled) (not .Values.tls.broker.enabled) }} + - name: pulsar + containerPort: {{ .Values.broker.ports.pulsar }} + {{- end }} + {{- if and .Values.tls.enabled .Values.tls.broker.enabled }} + - name: https + containerPort: {{ .Values.broker.ports.https }} + - name: pulsarssl + containerPort: {{ .Values.broker.ports.pulsarssl }} + {{- end }} + envFrom: + - configMapRef: + name: "{{ template "pulsar.fullname" . }}-{{ .Values.broker.component }}" + volumeMounts: + {{- if .Values.auth.authentication.enabled }} + {{- if eq .Values.auth.authentication.provider "jwt" }} + - mountPath: "/pulsar/keys" + name: token-keys + readOnly: true + - mountPath: "/pulsar/tokens" + name: broker-token + readOnly: true + {{- end }} + {{- end }} + {{- include "pulsar.broker.certs.volumeMounts" . | nindent 10 }} + volumes: + {{- if .Values.auth.authentication.enabled }} + {{- if eq .Values.auth.authentication.provider "jwt" }} + - name: token-keys + secret: + {{- if not .Values.auth.authentication.jwt.usingSecretKey }} + secretName: "{{ .Release.Name }}-token-asymmetric-key" + {{- end}} + {{- if .Values.auth.authentication.jwt.usingSecretKey }} + secretName: "{{ .Release.Name }}-token-symmetric-key" + {{- end}} + items: + {{- if .Values.auth.authentication.jwt.usingSecretKey }} + - key: SECRETKEY + path: token/secret.key + {{- else }} + - key: PUBLICKEY + path: token/public.key + {{- end}} + - name: broker-token + secret: + secretName: "{{ .Release.Name }}-token-{{ .Values.auth.superUsers.broker }}" + items: + - key: TOKEN + path: broker/token + {{- end}} + {{- end}} + {{- include "pulsar.broker.certs.volumes" . | nindent 6 }} +{{- end }} \ No newline at end of file diff --git a/pulsar/templates/function-worker-configmap.yaml b/pulsar/templates/function-worker-configmap.yaml new file mode 100644 index 0000000..98d9cfd --- /dev/null +++ b/pulsar/templates/function-worker-configmap.yaml @@ -0,0 +1,32 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +{{- if .Values.components.functions }} +## function config map +apiVersion: v1 +kind: ConfigMap +metadata: + name: "{{ template "pulsar.fullname" . }}-{{ .Values.functions.component }}-config" + namespace: {{ .Values.namespace }} + labels: + {{- include "pulsar.standardLabels" . | nindent 4 }} + component: {{ .Values.functions.component }} +data: + pulsarDockerImageName: "{{ .Values.images.functions.repository }}:{{ .Values.images.functions.tag }}" +{{- end }} \ No newline at end of file diff --git a/pulsar/templates/grafana-deployment.yaml b/pulsar/templates/grafana-deployment.yaml index 45f83de..675d897 100644 --- a/pulsar/templates/grafana-deployment.yaml +++ b/pulsar/templates/grafana-deployment.yaml @@ -17,35 +17,30 @@ # under the License. # -{{- if .Values.extra.monitoring }} +{{- if or .Values.monitoring.grafana .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 }} + {{- include "pulsar.standardLabels" . | nindent 4 }} component: {{ .Values.grafana.component }} - cluster: {{ template "pulsar.fullname" . }} spec: replicas: {{ .Values.grafana.replicaCount }} selector: matchLabels: - app: {{ template "pulsar.name" . }} - release: {{ .Release.Name }} + {{- include "pulsar.matchLabels" . | nindent 6 }} component: {{ .Values.grafana.component }} template: metadata: labels: - app: {{ template "pulsar.name" . }} - release: {{ .Release.Name }} + {{- include "pulsar.template.labels" . | nindent 8 }} component: {{ .Values.grafana.component }} - cluster: {{ template "pulsar.fullname" . }} annotations: -{{ toYaml .Values.grafana.annotations | indent 8 }} +{{- with .Values.grafana.annotations }} +{{ toYaml . | indent 8 }} +{{- end }} spec: {{- if .Values.grafana.nodeSelector }} nodeSelector: @@ -58,15 +53,32 @@ spec: 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 }} + image: "{{ .Values.images.grafana.repository }}:{{ .Values.images.grafana.tag }}" + imagePullPolicy: {{ .Values.images.grafana.pullPolicy }} {{- if .Values.grafana.resources }} resources: {{ toYaml .Values.grafana.resources | indent 10 }} {{- end }} ports: - - containerPort: 3000 + - name: server + containerPort: {{ .Values.grafana.port }} env: + # for supporting apachepulsar/pulsar-grafana - name: PROMETHEUS_URL value: http://{{ template "pulsar.fullname" . }}-{{ .Values.prometheus.component }}:9090/ + # for supporting streamnative/apache-pulsar-grafana-dashboard + - name: PULSAR_PROMETHEUS_URL + value: http://{{ template "pulsar.fullname" . }}-{{ .Values.prometheus.component }}:9090/ + - name: PULSAR_CLUSTER + value: {{ template "pulsar.fullname" . }} + - name: GRAFANA_ADMIN_USER + valueFrom: + secretKeyRef: + name: "{{ template "pulsar.fullname" . }}-admin-secret" + key: USER + - name: GRAFANA_ADMIN_PASSWORD + valueFrom: + secretKeyRef: + name: "{{ template "pulsar.fullname" . }}-admin-secret" + key: PASSWORD {{- end }} diff --git a/pulsar/templates/grafana-service.yaml b/pulsar/templates/grafana-service.yaml index 56dadde..2c1ddd1 100644 --- a/pulsar/templates/grafana-service.yaml +++ b/pulsar/templates/grafana-service.yaml @@ -17,28 +17,27 @@ # under the License. # -{{- if .Values.extra.monitoring }} +{{- if or .Values.monitoring.grafana .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 }} + {{- include "pulsar.standardLabels" . | nindent 4 }} component: {{ .Values.grafana.component }} - cluster: {{ template "pulsar.fullname" . }} annotations: -{{ toYaml .Values.grafana.service.annotations | indent 4 }} +{{- with .Values.grafana.service.annotations }} +{{ toYaml . | indent 4 }} +{{- end }} spec: + type: {{ .Values.grafana.service.type }} ports: -{{ toYaml .Values.grafana.service.ports | indent 2 }} + - name: server + port: {{ .Values.grafana.port }} + protocol: TCP selector: - app: {{ template "pulsar.name" . }} - release: {{ .Release.Name }} + {{- include "pulsar.matchLabels" . | nindent 4 }} component: {{ .Values.grafana.component }} - type: ClusterIP sessionAffinity: None {{- end }} diff --git a/pulsar/templates/keytool.yaml b/pulsar/templates/keytool.yaml new file mode 100644 index 0000000..b3da4a0 --- /dev/null +++ b/pulsar/templates/keytool.yaml @@ -0,0 +1,98 @@ +# +# 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. +# + +# script to process key/cert to keystore and truststore +{{- if .Values.tls.zookeeper.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: "{{ template "pulsar.fullname" . }}-keytool-configmap" + namespace: {{ .Values.namespace }} + labels: + {{- include "pulsar.standardLabels" . | nindent 4 }} + component: keytool +data: + keytool.sh: | + #!/bin/bash + component=$1 + name=$2 + isClient=$3 + crtFile=/pulsar/certs/${component}/tls.crt + keyFile=/pulsar/certs/${component}/tls.key + caFile=/pulsar/certs/ca/ca.crt + p12File=/pulsar/${component}.p12 + keyStoreFile=/pulsar/${component}.keystore.jks + trustStoreFile=/pulsar/${component}.truststore.jks + + function ensureFileNotEmpty() { + local file=$1 + local len=$(wc -c ${file} | awk '{print $1}') + echo "processing ${file} : len = ${len}" + if [ ! -f ${file} ]; then + echo "${file} is not found" + exit -1 + fi + if [ $len -le 0 ]; then + echo "${file} is empty" + exit -1 + fi + } + + ensureFileNotEmpty ${crtFile} + ensureFileNotEmpty ${keyFile} + ensureFileNotEmpty ${caFile} + + PASSWORD=$(head /dev/urandom | base64 | head -c 24) + + openssl pkcs12 \ + -export \ + -in ${crtFile} \ + -inkey ${keyFile} \ + -out ${p12File} \ + -name ${name} \ + -passout "pass:${PASSWORD}" + + keytool -importkeystore \ + -srckeystore ${p12File} \ + -srcstoretype PKCS12 -srcstorepass "${PASSWORD}" \ + -alias ${name} \ + -destkeystore ${keyStoreFile} \ + -deststorepass "${PASSWORD}" + + keytool -import \ + -file ${caFile} \ + -storetype JKS \ + -alias ${name} \ + -keystore ${trustStoreFile} \ + -storepass "${PASSWORD}" \ + -trustcacerts -noprompt + + ensureFileNotEmpty ${keyStoreFile} + ensureFileNotEmpty ${trustStoreFile} + + if [[ "x${isClient}" == "xtrue" ]]; then + echo $'\n' >> conf/pulsar_env.sh + echo "PULSAR_EXTRA_OPTS=\"${PULSAR_EXTRA_OPTS} -Dzookeeper.clientCnxnSocket=org.apache.zookeeper.ClientCnxnSocketNetty -Dzookeeper.client.secure=true -Dzookeeper.ssl.keyStore.location=${keyStoreFile} -Dzookeeper.ssl.keyStore.password=${PASSWORD} -Dzookeeper.ssl.trustStore.location=${trustStoreFile} -Dzookeeper.ssl.trustStore.password=${PASSWORD}\"" >> conf/pulsar_env.sh + echo $'\n' >> conf/bkenv.sh + echo "BOOKIE_EXTRA_OPTS=\"${BOOKIE_EXTRA_OPTS} -Dzookeeper.clientCnxnSocket=org.apache.zookeeper.ClientCnxnSocketNetty -Dzookeeper.client.secure=true -Dzookeeper.ssl.keyStore.location=${keyStoreFile} -Dzookeeper.ssl.keyStore.password=${PASSWORD} -Dzookeeper.ssl.trustStore.location=${trustStoreFile} -Dzookeeper.ssl.trustStore.password=${PASSWORD}\"" >> conf/bkenv.sh + else + echo $'\n' >> conf/pulsar_env.sh + echo "PULSAR_EXTRA_OPTS=\"${PULSAR_EXTRA_OPTS} -Dzookeeper.ssl.keyStore.location=${keyStoreFile} -Dzookeeper.ssl.keyStore.password=${PASSWORD} -Dzookeeper.ssl.trustStore.location=${trustStoreFile} -Dzookeeper.ssl.trustStore.password=${PASSWORD}\"" >> conf/pulsar_env.sh + fi +{{- end }} diff --git a/pulsar/templates/prometheus-configmap.yaml b/pulsar/templates/prometheus-configmap.yaml index 889abf5..ab971ad 100644 --- a/pulsar/templates/prometheus-configmap.yaml +++ b/pulsar/templates/prometheus-configmap.yaml @@ -17,19 +17,15 @@ # under the License. # -{{- if .Values.extra.monitoring }} +{{- if or .Values.monitoring.prometheus .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 }} + {{- include "pulsar.standardLabels" . | nindent 4 }} 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. diff --git a/pulsar/templates/prometheus-deployment.yaml b/pulsar/templates/prometheus-deployment.yaml index e722993..75bae72 100644 --- a/pulsar/templates/prometheus-deployment.yaml +++ b/pulsar/templates/prometheus-deployment.yaml @@ -17,33 +17,26 @@ # under the License. # -{{- if .Values.extra.monitoring }} +{{- if or .Values.monitoring.prometheus .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 }} + {{- include "pulsar.standardLabels" . | nindent 4 }} component: {{ .Values.prometheus.component }} - cluster: {{ template "pulsar.fullname" . }} spec: replicas: {{ .Values.prometheus.replicaCount }} selector: matchLabels: - app: {{ template "pulsar.name" . }} - release: {{ .Release.Name }} + {{- include "pulsar.matchLabels" . | nindent 6 }} component: {{ .Values.prometheus.component }} template: metadata: labels: - app: {{ template "pulsar.name" . }} - release: {{ .Release.Name }} + {{- include "pulsar.template.labels" . | nindent 8 }} component: {{ .Values.prometheus.component }} - cluster: {{ template "pulsar.fullname" . }} annotations: {{ toYaml .Values.prometheus.annotations | indent 8 }} spec: @@ -55,20 +48,21 @@ spec: tolerations: {{ toYaml .Values.prometheus.tolerations | indent 8 }} {{- end }} - {{- if .Values.prometheus_rbac }} + {{- if or .Values.prometheus.rbac.enabled .Values.prometheus_rbac }} serviceAccount: "{{ template "pulsar.fullname" . }}-{{ .Values.prometheus.component }}" {{- end }} 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 }} + image: "{{ .Values.images.prometheus.repository }}:{{ .Values.images.prometheus.tag }}" + imagePullPolicy: {{ .Values.images.prometheus.pullPolicy }} {{- if .Values.prometheus.resources }} resources: {{ toYaml .Values.prometheus.resources | indent 10 }} {{- end }} ports: - - containerPort: 9090 + - name: server + containerPort: {{ .Values.prometheus.port }} volumeMounts: - name: "{{ template "pulsar.fullname" . }}-{{ .Values.prometheus.component }}-config" mountPath: /etc/prometheus @@ -78,11 +72,11 @@ spec: - name: "{{ template "pulsar.fullname" . }}-{{ .Values.prometheus.component }}-config" configMap: name: "{{ template "pulsar.fullname" . }}-{{ .Values.prometheus.component }}" - {{- if not .Values.prometheus_persistence }} + {{- if not (and (and .Values.persistence .Values.volumes.persistence) .Values.prometheus.volumes.persistence) }} - name: "{{ template "pulsar.fullname" . }}-{{ .Values.prometheus.component }}-{{ .Values.prometheus.volumes.data.name }}" emptyDir: {} {{- end }} - {{- if .Values.prometheus_persistence }} + {{- if and (and .Values.persistence .Values.volumes.persistence) .Values.prometheus.volumes.persistence }} - 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 }}" diff --git a/pulsar/templates/prometheus-pvc.yaml b/pulsar/templates/prometheus-pvc.yaml index bccb773..d647db3 100644 --- a/pulsar/templates/prometheus-pvc.yaml +++ b/pulsar/templates/prometheus-pvc.yaml @@ -17,8 +17,8 @@ # under the License. # -{{- if .Values.extra.monitoring }} -{{- if .Values.persistence }} +{{- if or .Values.monitoring.prometheus .Values.extra.monitoring }} +{{- if and (and .Values.persistence .Values.volumes.persistence) .Values.prometheus.volumes.persistence }} apiVersion: v1 kind: PersistentVolumeClaim metadata: @@ -31,8 +31,10 @@ spec: accessModes: [ "ReadWriteOnce" ] {{- if .Values.prometheus.volumes.data.storageClassName }} storageClassName: "{{ .Values.prometheus.volumes.data.storageClassName }}" -{{- else if .Values.prometheus.volumes.data.storageClass }} +{{- else if and (not (and .Values.volumes.local_storage .Values.prometheus.volumes.data.local_storage)) .Values.prometheus.volumes.data.storageClass }} storageClassName: "{{ template "pulsar.fullname" . }}-{{ .Values.prometheus.component }}-{{ .Values.prometheus.volumes.data.name }}" +{{- else if and .Values.volumes.local_storage .Values.prometheus.volumes.data.local_storage }} + storageClassName: "local-storage" {{- end }} {{- end }} {{- end }} diff --git a/pulsar/templates/prometheus-rbac.yaml b/pulsar/templates/prometheus-rbac.yaml index a25bbb9..d027676 100644 --- a/pulsar/templates/prometheus-rbac.yaml +++ b/pulsar/templates/prometheus-rbac.yaml @@ -17,8 +17,8 @@ # under the License. # -{{- if .Values.extra.monitoring }} -{{- if .Values.prometheus_rbac }} +{{- if or .Values.monitoring.prometheus .Values.extra.monitoring }} +{{- if or .Values.prometheus.rbac.enabled .Values.prometheus_rbac }} apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRole metadata: diff --git a/pulsar/templates/prometheus-service.yaml b/pulsar/templates/prometheus-service.yaml index 965256d..c4a660d 100644 --- a/pulsar/templates/prometheus-service.yaml +++ b/pulsar/templates/prometheus-service.yaml @@ -17,25 +17,22 @@ # under the License. # -{{- if .Values.extra.monitoring }} +{{- if or .Values.monitoring.prometheus .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 }} + {{- include "pulsar.standardLabels" . | nindent 4 }} 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 + ports: + - name: server + port: {{ .Values.prometheus.port }} selector: app: {{ template "pulsar.name" . }} release: {{ .Release.Name }} diff --git a/pulsar/templates/prometheus-storageclass.yaml b/pulsar/templates/prometheus-storageclass.yaml index 1623a5f..7cda9e0 100644 --- a/pulsar/templates/prometheus-storageclass.yaml +++ b/pulsar/templates/prometheus-storageclass.yaml @@ -17,8 +17,8 @@ # under the License. # -{{- if .Values.extra.monitoring }} -{{- if .Values.persistence }} +{{- if or .Values.monitoring.prometheus .Values.extra.monitoring }} +{{- if and (and .Values.persistence .Values.volumes.persistence) .Values.prometheus.volumes.persistence }} {{- if .Values.prometheus.volumes.data.storageClass }} apiVersion: storage.k8s.io/v1 kind: StorageClass @@ -26,12 +26,8 @@ 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 }} + {{- include "pulsar.standardLabels" . | nindent 4 }} component: {{ .Values.prometheus.component }} - cluster: {{ template "pulsar.fullname" . }} provisioner: {{ .Values.prometheus.volumes.data.storageClass.provisioner }} parameters: type: {{ .Values.prometheus.volumes.data.storageClass.type }} diff --git a/pulsar/templates/proxy-configmap.yaml b/pulsar/templates/proxy-configmap.yaml index 4d9d3ad..491d1bc 100644 --- a/pulsar/templates/proxy-configmap.yaml +++ b/pulsar/templates/proxy-configmap.yaml @@ -17,26 +17,67 @@ # under the License. # -{{- if .Values.extra.proxy }} +{{- if or .Values.components.proxy .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 }} + {{- include "pulsar.standardLabels" . | nindent 4 }} component: {{ .Values.proxy.component }} - cluster: {{ template "pulsar.fullname" . }} data: - zookeeperServers: - {{- $global := . }} - {{ range $i, $e := until (.Values.zookeeper.replicaCount | int) }}{{ if ne $i 0 }},{{ end }}{{ template "pulsar.fullname" $global }}-{{ $global.Values.zookeeper.component }}-{{ printf "%d" $i }}.{{ template "pulsar.fullname" $global }}-{{ $global.Values.zookeeper.component }}{{ end }} - configurationStoreServers: - {{- $global := . }} - {{ range $i, $e := until (.Values.zookeeper.replicaCount | int) }}{{ if ne $i 0 }},{{ end }}{{ template "pulsar.fullname" $global }}-{{ $global.Values.zookeeper.component }}-{{ printf "%d" $i }}.{{ template "pulsar.fullname" $global }}-{{ $global.Values.zookeeper.component }}{{ end }} clusterName: {{ template "pulsar.fullname" . }} + httpNumThreads: "8" + statusFilePath: "{{ template "pulsar.home" . }}/status" + # prometheus needs to access /metrics endpoint + webServicePort: "{{ .Values.proxy.ports.http }}" + {{- if or (not .Values.tls.enabled) (not .Values.tls.proxy.enabled) }} + servicePort: "{{ .Values.proxy.ports.pulsar }}" + brokerServiceURL: pulsar://{{ template "pulsar.fullname" . }}-{{ .Values.broker.component }}:{{ .Values.broker.ports.pulsar }} + brokerWebServiceURL: http://{{ template "pulsar.fullname" . }}-{{ .Values.broker.component }}:{{ .Values.broker.ports.http }} + {{- end }} + {{- if and .Values.tls.enabled .Values.tls.proxy.enabled }} + tlsEnabledInProxy: "true" + servicePortTls: "{{ .Values.proxy.ports.pulsarssl }}" + webServicePortTls: "{{ .Values.proxy.ports.https }}" + tlsCertificateFilePath: "/pulsar/certs/proxy/tls.crt" + tlsKeyFilePath: "/pulsar/certs/proxy/tls.key" + tlsTrustCertsFilePath: "/pulsar/certs/ca/ca.crt" + {{- if and .Values.tls.enabled .Values.tls.broker.enabled }} + # if broker enables TLS, configure proxy to talk to broker using TLS + brokerServiceURLTLS: pulsar+ssl://{{ template "pulsar.fullname" . }}-{{ .Values.broker.component }}:{{ .Values.broker.ports.pulsarssl }} + brokerWebServiceURLTLS: https://{{ template "pulsar.fullname" . }}-{{ .Values.broker.component }}:{{ .Values.broker.ports.https }} + tlsEnabledWithBroker: "true" + tlsCertRefreshCheckDurationSec: "300" + brokerClientTrustCertsFilePath: "/pulsar/certs/ca/ca.crt" + {{- end }} + {{- if not (and .Values.tls.enabled .Values.tls.broker.enabled) }} + brokerServiceURL: pulsar://{{ template "pulsar.fullname" . }}-{{ .Values.broker.component }}:{{ .Values.broker.ports.pulsar }} + brokerWebServiceURL: http://{{ template "pulsar.fullname" . }}-{{ .Values.broker.component }}:{{ .Values.broker.ports.http }} + {{- end }} + {{- end }} + + # Authentication Settings + {{- if .Values.auth.authentication.enabled }} + authenticationEnabled: "true" + {{- if .Values.auth.authorization.enabled }} + # disable authorization on proxy and forward authorization credentials to broker + authorizationEnabled: "false" + forwardAuthorizationCredentials: "true" + superUserRoles: {{ .Values.auth.superUsers.broker }},{{ .Values.auth.superUsers.proxy }},{{ .Values.auth.superUsers.client }} + {{- end }} + {{- if eq .Values.auth.authentication.provider "jwt" }} + # token authentication configuration + authenticationProviders: "org.apache.pulsar.broker.authentication.AuthenticationProviderToken" + brokerClientAuthenticationParameters: "file:///pulsar/tokens/proxy/token" + brokerClientAuthenticationPlugin: "org.apache.pulsar.client.impl.auth.AuthenticationToken" + {{- if .Values.auth.authentication.jwt.usingSecretKey }} + tokenSecretKey: "file:///pulsar/keys/token/secret.key" + {{- else }} + tokenPublicKey: "file:///pulsar/keys/token/public.key" + {{- end }} + {{- end }} + {{- end }} {{ toYaml .Values.proxy.configData | indent 2 }} {{- end }} diff --git a/pulsar/templates/proxy-deployment.yaml b/pulsar/templates/proxy-deployment.yaml deleted file mode 100644 index 476f608..0000000 --- a/pulsar/templates/proxy-deployment.yaml +++ /dev/null @@ -1,124 +0,0 @@ -# -# 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" . }}" - - 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 proxies - - name: wait-zookeeper-ready - image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" - imagePullPolicy: {{ .Values.image.pullPolicy }} - command: ["sh", "-c"] - args: - - >- - until bin/pulsar zookeeper-shell -server {{ template "pulsar.fullname" . }}-{{ .Values.zookeeper.component }} ls /admin/clusters/{{ template "pulsar.fullname" . }}; do - sleep 3; - done; - # This init container will wait for at least one broker to be ready before - # deploying the proxy - - name: wait-broker-ready - image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" - imagePullPolicy: {{ .Values.image.pullPolicy }} - command: ["bash", "-c"] - args: - - >- - for i in {0..{{ .Values.broker.replicaCount }}}; do - brokerServiceNumber="$(nslookup -timeout=10 {{ template "pulsar.fullname" . }}-{{ .Values.broker.component }} | grep Name | wc -l)" - if [[ ${brokerServiceNumber} -ge 1 ]]; then - break - fi - sleep 30; - 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/pulsar/templates/proxy-pdb.yaml b/pulsar/templates/proxy-pdb.yaml index 10188d3..50cfe7a 100644 --- a/pulsar/templates/proxy-pdb.yaml +++ b/pulsar/templates/proxy-pdb.yaml @@ -17,7 +17,7 @@ # under the License. # -{{- if .Values.extra.proxy }} +{{- if or .Values.components.proxy .Values.extra.proxy }} {{- if .Values.proxy.pdb.usePolicy }} apiVersion: policy/v1beta1 kind: PodDisruptionBudget @@ -25,17 +25,12 @@ 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 }} + {{- include "pulsar.standardLabels" . | nindent 4 }} component: {{ .Values.proxy.component }} - cluster: {{ template "pulsar.fullname" . }} spec: selector: matchLabels: - app: {{ template "pulsar.name" . }} - release: {{ .Release.Name }} + {{- include "pulsar.matchLabels" . | nindent 6 }} component: {{ .Values.proxy.component }} maxUnavailable: {{ .Values.proxy.pdb.maxUnavailable }} {{- end }} diff --git a/pulsar/templates/proxy-service.yaml b/pulsar/templates/proxy-service.yaml index 522cfbf..273d5aa 100644 --- a/pulsar/templates/proxy-service.yaml +++ b/pulsar/templates/proxy-service.yaml @@ -17,25 +17,38 @@ # under the License. # -{{- if .Values.extra.proxy }} +{{- if or .Values.components.proxy .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 }} + {{- include "pulsar.standardLabels" . | nindent 4 }} component: {{ .Values.proxy.component }} - cluster: {{ template "pulsar.fullname" . }} annotations: -{{ toYaml .Values.proxy.service.annotations | indent 4 }} + {{- with .Values.proxy.service.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} spec: type: {{ .Values.proxy.service.type }} ports: -{{ toYaml .Values.proxy.service.ports | indent 2 }} + {{- if or (not .Values.tls.enabled) (not .Values.tls.proxy.enabled) }} + - name: http + port: {{ .Values.proxy.ports.http }} + protocol: TCP + - name: pulsar + port: {{ .Values.proxy.ports.pulsar }} + protocol: TCP + {{- end }} + {{- if and .Values.tls.enabled .Values.tls.proxy.enabled }} + - name: https + port: {{ .Values.proxy.ports.https }} + protocol: TCP + - name: pulsarssl + port: {{ .Values.proxy.ports.pulsarssl }} + protocol: TCP + {{- end }} selector: app: {{ template "pulsar.name" . }} release: {{ .Release.Name }} diff --git a/pulsar/templates/proxy-statefulset.yaml b/pulsar/templates/proxy-statefulset.yaml new file mode 100644 index 0000000..c83c2e3 --- /dev/null +++ b/pulsar/templates/proxy-statefulset.yaml @@ -0,0 +1,234 @@ +# +# 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 or .Values.components.proxy .Values.extra.proxy }} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: "{{ template "pulsar.fullname" . }}-{{ .Values.proxy.component }}" + namespace: {{ .Values.namespace }} + labels: + {{- include "pulsar.standardLabels" . | nindent 4 }} + component: {{ .Values.proxy.component }} +spec: + serviceName: "{{ template "pulsar.fullname" . }}-{{ .Values.proxy.component }}" + replicas: {{ .Values.proxy.replicaCount }} + selector: + matchLabels: + {{- include "pulsar.matchLabels" . | nindent 6 }} + component: {{ .Values.proxy.component }} + updateStrategy: + type: RollingUpdate + podManagementPolicy: Parallel + template: + metadata: + labels: + {{- include "pulsar.template.labels" . | nindent 8 }} + component: {{ .Values.proxy.component }} + annotations: + prometheus.io/scrape: "true" + prometheus.io/port: "{{ .Values.proxy.ports.http }}" +{{- with .Values.proxy.annotations }} +{{ toYaml . | indent 8 }} +{{- end }} + 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: + {{- if and .Values.affinity.anti_affinity .Values.proxy.affinity.anti_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" + {{- end }} + 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.images.proxy.repository }}:{{ .Values.images.proxy.tag }}" + imagePullPolicy: {{ .Values.images.proxy.pullPolicy }} + command: ["sh", "-c"] + args: + - >- + until bin/pulsar zookeeper-shell -server {{ template "pulsar.fullname" . }}-{{ .Values.zookeeper.component }} get {{ .Values.metadataPrefix }}/admin/clusters/{{ template "pulsar.fullname" . }}; do + sleep 3; + done; + # This init container will wait for at least one broker to be ready before + # deploying the proxy + - name: wait-broker-ready + image: "{{ .Values.images.proxy.repository }}:{{ .Values.images.proxy.tag }}" + imagePullPolicy: {{ .Values.images.proxy.pullPolicy }} + command: ["sh", "-c"] + args: + - >- + set -e; + brokerServiceNumber="$(nslookup -timeout=10 {{ template "pulsar.fullname" . }}-{{ .Values.broker.component }} | grep Name | wc -l)"; + until [ ${brokerServiceNumber} -ge 1 ]; do + echo "pulsar cluster {{ template "pulsar.fullname" . }} isn't initialized yet ... check in 10 seconds ..."; + sleep 10; + brokerServiceNumber="$(nslookup -timeout=10 {{ template "pulsar.fullname" . }}-{{ .Values.broker.component }} | grep Name | wc -l)"; + done; + containers: + - name: "{{ template "pulsar.fullname" . }}-{{ .Values.proxy.component }}" + image: "{{ .Values.images.proxy.repository }}:{{ .Values.images.proxy.tag }}" + imagePullPolicy: {{ .Values.images.proxy.pullPolicy }} + {{- if .Values.proxy.probe.liveness.enabled }} + livenessProbe: + httpGet: + path: /status.html + port: {{ .Values.proxy.ports.http }} + initialDelaySeconds: {{ .Values.proxy.probe.liveness.initialDelaySeconds }} + periodSeconds: {{ .Values.proxy.probe.liveness.periodSeconds }} + failureThreshold: {{ .Values.proxy.probe.liveness.failureThreshold }} + {{- end }} + {{- if .Values.proxy.probe.readiness.enabled }} + readinessProbe: + httpGet: + path: /status.html + port: {{ .Values.proxy.ports.http }} + initialDelaySeconds: {{ .Values.proxy.probe.readiness.initialDelaySeconds }} + periodSeconds: {{ .Values.proxy.probe.readiness.periodSeconds }} + failureThreshold: {{ .Values.proxy.probe.readiness.failureThreshold }} + {{- end }} + {{- if .Values.proxy.probe.startup.enabled }} + startupProbe: + httpGet: + path: /status.html + port: {{ .Values.proxy.ports.http }} + initialDelaySeconds: {{ .Values.proxy.probe.startup.initialDelaySeconds }} + periodSeconds: {{ .Values.proxy.probe.startup.periodSeconds }} + failureThreshold: {{ .Values.proxy.probe.startup.failureThreshold }} + {{- end }} + {{- 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 && + echo "OK" > status && + bin/pulsar proxy + ports: + # prometheus needs to access /metrics endpoint + - name: http + containerPort: {{ .Values.proxy.ports.http }} + {{- if or (not .Values.tls.enabled) (not .Values.tls.proxy.enabled) }} + - name: pulsar + containerPort: {{ .Values.proxy.ports.pulsar }} + {{- end }} + {{- if and (.Values.tls.enabled) (.Values.tls.proxy.enabled) }} + - name: https + containerPort: {{ .Values.proxy.ports.https }} + - name: pulsarssl + containerPort: {{ .Values.proxy.ports.pulsarssl }} + {{- end }} + envFrom: + - configMapRef: + name: "{{ template "pulsar.fullname" . }}-{{ .Values.proxy.component }}" + {{- if or .Values.auth.authentication.enabled (and .Values.tls.enabled (or .Values.tls.proxy.enabled .Values.tls.broker.enabled)) }} + volumeMounts: + {{- if .Values.auth.authentication.enabled }} + {{- if eq .Values.auth.authentication.provider "jwt" }} + - mountPath: "/pulsar/keys" + name: token-keys + readOnly: true + - mountPath: "/pulsar/tokens" + name: proxy-token + readOnly: true + {{- end }} + {{- end }} + {{- if .Values.tls.proxy.enabled }} + - mountPath: "/pulsar/certs/proxy" + name: proxy-certs + readOnly: true + {{- end}} + {{- if .Values.tls.enabled }} + - mountPath: "/pulsar/certs/ca" + name: ca + readOnly: true + {{- end}} + {{- end}} + {{- if or .Values.auth.authentication.enabled (and .Values.tls.enabled .Values.tls.proxy.enabled) }} + volumes: + {{- if .Values.auth.authentication.enabled }} + {{- if eq .Values.auth.authentication.provider "jwt" }} + - name: token-keys + secret: + {{- if not .Values.auth.authentication.jwt.usingSecretKey }} + secretName: "{{ .Release.Name }}-token-asymmetric-key" + {{- end}} + {{- if .Values.auth.authentication.jwt.usingSecretKey }} + secretName: "{{ .Release.Name }}-token-symmetric-key" + {{- end}} + items: + {{- if .Values.auth.authentication.jwt.usingSecretKey }} + - key: SECRETKEY + path: token/secret.key + {{- else }} + - key: PUBLICKEY + path: token/public.key + {{- end}} + - name: proxy-token + secret: + secretName: "{{ .Release.Name }}-token-{{ .Values.auth.superUsers.proxy }}" + items: + - key: TOKEN + path: proxy/token + {{- end}} + {{- end}} + {{- if .Values.tls.proxy.enabled }} + - name: ca + secret: + secretName: "{{ template "pulsar.fullname" . }}-ca-tls" + items: + - key: ca.crt + path: ca.crt + - name: proxy-certs + secret: + secretName: "{{ template "pulsar.fullname" . }}-{{ .Values.tls.proxy.cert_name }}" + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + {{- end}} + {{- end}} +{{- end }} diff --git a/pulsar/templates/pulsar-cluster-initialize.yaml b/pulsar/templates/pulsar-cluster-initialize.yaml new file mode 100644 index 0000000..a57db8e --- /dev/null +++ b/pulsar/templates/pulsar-cluster-initialize.yaml @@ -0,0 +1,102 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +{{- if .Values.components.broker }} +apiVersion: batch/v1 +kind: Job +metadata: + name: "{{ template "pulsar.fullname" . }}-{{ .Values.pulsar_metadata.component }}" + namespace: {{ .Values.namespace }} + labels: + {{- include "pulsar.standardLabels" . | nindent 4 }} + component: {{ .Values.pulsar_metadata.component }} +spec: + template: + spec: + initContainers: + {{- if .Values.pulsar_metadata.configurationStore }} + - name: wait-cs-ready + image: "{{ .Values.pulsar_metadata.image.repository }}:{{ .Values.pulsar_metadata.image.tag }}" + imagePullPolicy: {{ .Values.pulsar_metadata.image.pullPolicy }} + command: ["sh", "-c"] + args: + - >- + until nslookup {{ .Values.pulsar_metadata.configurationStore}}; do + sleep 3; + done; + + {{- end }} + - name: wait-zookeeper-ready + image: "{{ .Values.pulsar_metadata.image.repository }}:{{ .Values.pulsar_metadata.image.tag }}" + imagePullPolicy: {{ .Values.pulsar_metadata.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 wait for bookkeeper initnewcluster to complete + # before initializing pulsar metadata + - name: pulsar-bookkeeper-verify-clusterid + image: "{{ .Values.pulsar_metadata.image.repository }}:{{ .Values.pulsar_metadata.image.tag }}" + imagePullPolicy: {{ .Values.pulsar_metadata.image.pullPolicy }} + command: ["sh", "-c"] + args: + - > + bin/apply-config-from-env.py conf/bookkeeper.conf; + {{- include "pulsar.toolset.zookeeper.tls.settings" . | nindent 10 }} + until bin/bookkeeper shell whatisinstanceid; do + sleep 3; + done; + envFrom: + - configMapRef: + name: "{{ template "pulsar.fullname" . }}-{{ .Values.bookkeeper.component }}" + volumeMounts: + {{- include "pulsar.toolset.certs.volumeMounts" . | nindent 8 }} + containers: + - name: "{{ template "pulsar.fullname" . }}-{{ .Values.pulsar_metadata.component }}" + image: "{{ .Values.pulsar_metadata.image.repository }}:{{ .Values.pulsar_metadata.image.tag }}" + imagePullPolicy: {{ .Values.pulsar_metadata.image.pullPolicy }} + {{- if .Values.pulsar_metadata.resources }} + resources: +{{ toYaml .Values.pulsar_metadata.resources | indent 10 }} + {{- end }} + command: ["sh", "-c"] + args: + - > + {{- include "pulsar.toolset.zookeeper.tls.settings" . | nindent 12 }} + bin/pulsar initialize-cluster-metadata \ + --cluster {{ template "pulsar.fullname" . }} \ + --zookeeper {{ template "pulsar.zookeeper.connect" . }}{{ .Values.metadataPrefix }} \ + {{- if .Values.pulsar_metadata.configurationStore }} + --configuration-store {{ .Values.pulsar_metadata.configurationStore }}{{ .Values.pulsar_metadata.configurationStoreMetadataPrefix }} \ + {{- end }} + {{- if not .Values.pulsar_metadata.configurationStore }} + --configuration-store {{ template "pulsar.zookeeper.connect" . }}{{ .Values.metadataPrefix }} \ + {{- end }} + --web-service-url http://{{ template "pulsar.fullname" . }}-{{ .Values.broker.component }}.{{ .Values.namespace }}.svc.cluster.local:8080/ \ + --web-service-url-tls https://{{ template "pulsar.fullname" . }}-{{ .Values.broker.component }}.{{ .Values.namespace }}.svc.cluster.local:8443/ \ + --broker-service-url pulsar://{{ template "pulsar.fullname" . }}-{{ .Values.broker.component }}.{{ .Values.namespace }}.svc.cluster.local:6650/ \ + --broker-service-url-tls pulsar+ssl://{{ template "pulsar.fullname" . }}-{{ .Values.broker.component }}.{{ .Values.namespace }}.svc.cluster.local:6651/ || true; + volumeMounts: + {{- include "pulsar.toolset.certs.volumeMounts" . | nindent 8 }} + volumes: + {{- include "pulsar.toolset.certs.volumes" . | nindent 6 }} + restartPolicy: Never +{{- end }} diff --git a/pulsar/templates/pulsar-manager-admin-secret.yaml b/pulsar/templates/pulsar-manager-admin-secret.yaml index 427ac25..ef4ecf9 100644 --- a/pulsar/templates/pulsar-manager-admin-secret.yaml +++ b/pulsar/templates/pulsar-manager-admin-secret.yaml @@ -17,7 +17,7 @@ # under the License. # -{{- if .Values.extra.pulsar_manager }} +{{- if or .Values.components.pulsar_manager .Values.extra.pulsar_manager }} apiVersion: v1 kind: Secret metadata: diff --git a/pulsar/templates/pulsar-manager-configmap.yaml b/pulsar/templates/pulsar-manager-configmap.yaml index 5444469..acfb315 100644 --- a/pulsar/templates/pulsar-manager-configmap.yaml +++ b/pulsar/templates/pulsar-manager-configmap.yaml @@ -17,17 +17,15 @@ # under the License. # +{{- if or .Values.components.pulsar_manager .Values.extra.pulsar_manager }} apiVersion: v1 kind: ConfigMap metadata: name: "{{ template "pulsar.fullname" . }}-{{ .Values.pulsar_manager.component }}" namespace: {{ .Values.namespace }} labels: - app: {{ template "pulsar.name" . }} - chart: {{ template "pulsar.chart" . }} - release: {{ .Release.Name }} - heritage: {{ .Release.Service }} + {{- include "pulsar.standardLabels" . | nindent 4 }} component: {{ .Values.pulsar_manager.component }} - cluster: {{ template "pulsar.fullname" . }} data: {{ toYaml .Values.pulsar_manager.configData | indent 2 }} +{{- end }} diff --git a/pulsar/templates/pulsar-manager-deployment.yaml b/pulsar/templates/pulsar-manager-deployment.yaml index 8a8493a..73ffc1a 100644 --- a/pulsar/templates/pulsar-manager-deployment.yaml +++ b/pulsar/templates/pulsar-manager-deployment.yaml @@ -17,33 +17,26 @@ # under the License. # -{{- if .Values.extra.pulsar_manager }} +{{- if or .Values.components.pulsar_manager .Values.extra.pulsar_manager }} apiVersion: apps/v1 kind: Deployment metadata: name: "{{ template "pulsar.fullname" . }}-{{ .Values.pulsar_manager.component }}" namespace: {{ .Values.namespace }} labels: - app: {{ template "pulsar.name" . }} - chart: {{ template "pulsar.chart" . }} - release: {{ .Release.Name }} - heritage: {{ .Release.Service }} + {{- include "pulsar.standardLabels" . | nindent 4 }} component: {{ .Values.pulsar_manager.component }} - cluster: {{ template "pulsar.fullname" . }} spec: replicas: 1 selector: matchLabels: - app: {{ template "pulsar.name" . }} - release: {{ .Release.Name }} + {{- include "pulsar.matchLabels" . | nindent 6 }} component: {{ .Values.pulsar_manager.component }} template: metadata: labels: - app: {{ template "pulsar.name" . }} - release: {{ .Release.Name }} + {{- include "pulsar.template.labels" . | nindent 8 }} component: {{ .Values.pulsar_manager.component }} - cluster: {{ template "pulsar.fullname" . }} annotations: {{ toYaml .Values.pulsar_manager.annotations | indent 8 }} spec: @@ -58,14 +51,14 @@ spec: terminationGracePeriodSeconds: {{ .Values.pulsar_manager.gracePeriod }} containers: - name: "{{ template "pulsar.fullname" . }}-{{ .Values.pulsar_manager.component }}" - image: "{{ .Values.pulsar_manager.image.repository }}:{{ .Values.pulsar_manager.image.tag }}" - imagePullPolicy: {{ .Values.pulsar_manager.image.pullPolicy }} + image: "{{ .Values.images.pulsar_manager.repository }}:{{ .Values.images.pulsar_manager.tag }}" + imagePullPolicy: {{ .Values.images.pulsar_manager.pullPolicy }} {{- if .Values.pulsar_manager.resources }} resources: {{ toYaml .Values.pulsar_manager.resources | indent 12 }} {{- end }} ports: - - containerPort: 9527 + - containerPort: {{ .Values.pulsar_manager.port }} volumeMounts: - name: pulsar-manager-data mountPath: /data diff --git a/pulsar/templates/pulsar-manager-service.yaml b/pulsar/templates/pulsar-manager-service.yaml index aa61a6b..188b3a4 100644 --- a/pulsar/templates/pulsar-manager-service.yaml +++ b/pulsar/templates/pulsar-manager-service.yaml @@ -17,25 +17,23 @@ # under the License. # -{{- if .Values.extra.pulsar_manager }} +{{- if or .Values.components.pulsar_manager .Values.extra.pulsar_manager }} apiVersion: v1 kind: Service metadata: name: "{{ template "pulsar.fullname" . }}-{{ .Values.pulsar_manager.component }}" namespace: {{ .Values.namespace }} labels: - app: {{ template "pulsar.name" . }} - chart: {{ template "pulsar.chart" . }} - release: {{ .Release.Name }} - heritage: {{ .Release.Service }} + {{- include "pulsar.standardLabels" . | nindent 4 }} component: {{ .Values.pulsar_manager.component }} - cluster: {{ template "pulsar.fullname" . }} annotations: {{ toYaml .Values.pulsar_manager.service.annotations | indent 4 }} spec: type: {{ .Values.pulsar_manager.service.type }} ports: -{{ toYaml .Values.pulsar_manager.service.ports | indent 2 }} + - name: server + port: {{ .Values.pulsar_manager.port }} + protocol: TCP selector: app: {{ template "pulsar.name" . }} release: {{ .Release.Name }} diff --git a/pulsar/templates/tls-cert-internal-issuer.yaml b/pulsar/templates/tls-cert-internal-issuer.yaml new file mode 100644 index 0000000..5d924f4 --- /dev/null +++ b/pulsar/templates/tls-cert-internal-issuer.yaml @@ -0,0 +1,62 @@ +# +# 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.certs.internal_issuer.enabled }} +{{- if eq .Values.certs.internal_issuer.type "selfsigning" }} +apiVersion: cert-manager.io/v1alpha2 +kind: Issuer +metadata: + name: "{{ template "pulsar.fullname" . }}-{{ .Values.certs.internal_issuer.component }}" + namespace: {{ .Values.namespace }} +spec: + selfSigned: {} +--- + +apiVersion: cert-manager.io/v1alpha2 +kind: Certificate +metadata: + name: "{{ template "pulsar.fullname" . }}-ca" + namespace: {{ .Values.namespace }} +spec: + secretName: "{{ template "pulsar.fullname" . }}-ca-tls" + commonName: "{{ .Values.namespace }}.svc.cluster.local" + usages: + - server auth + - client auth + isCA: true + issuerRef: + name: "{{ template "pulsar.fullname" . }}-{{ .Values.certs.internal_issuer.component }}" + # We can reference ClusterIssuers by changing the kind here. + # The default value is Issuer (i.e. a locally namespaced Issuer) + kind: Issuer + # This is optional since cert-manager will default to this value however + # if you are using an external issuer, change this to that issuer group. + group: cert-manager.io +--- + +apiVersion: cert-manager.io/v1alpha2 +kind: Issuer +metadata: + name: "{{ template "pulsar.fullname" . }}-{{ .Values.certs.internal_issuer.component }}-ca-issuer" + namespace: {{ .Values.namespace }} +spec: + ca: + secretName: "{{ template "pulsar.fullname" . }}-ca-tls" +{{- end }} +{{- end }} \ No newline at end of file diff --git a/pulsar/templates/tls-certs-internal.yaml b/pulsar/templates/tls-certs-internal.yaml new file mode 100644 index 0000000..5b249c0 --- /dev/null +++ b/pulsar/templates/tls-certs-internal.yaml @@ -0,0 +1,247 @@ +# +# 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.tls.enabled }} +{{- if .Values.certs.internal_issuer.enabled }} + +{{- if .Values.tls.proxy.enabled }} +apiVersion: cert-manager.io/v1alpha2 +kind: Certificate +metadata: + name: "{{ template "pulsar.fullname" . }}-{{ .Values.tls.proxy.cert_name }}" + namespace: {{ .Values.namespace }} +spec: + # Secret names are always required. + secretName: "{{ template "pulsar.fullname" . }}-{{ .Values.tls.proxy.cert_name }}" + duration: "{{ .Values.tls.common.duration }}" + renewBefore: "{{ .Values.tls.common.renewBefore }}" + organization: +{{ toYaml .Values.tls.common.organization | indent 2 }} + # The use of the common name field has been deprecated since 2000 and is + # discouraged from being used. + commonName: "*.{{ template "pulsar.fullname" . }}-{{ .Values.proxy.component }}.{{ .Values.namespace }}.svc.cluster.local" + isCA: false + keySize: {{ .Values.tls.common.keySize }} + keyAlgorithm: {{ .Values.tls.common.keyAlgorithm }} + keyEncoding: {{ .Values.tls.common.keyEncoding }} + usages: + - server auth + - client auth + # At least one of a DNS Name, USI SAN, or IP address is required. + dnsNames: + - "*.{{ template "pulsar.fullname" . }}-{{ .Values.proxy.component }}.{{ .Values.namespace }}.svc.cluster.local" + - "{{ template "pulsar.fullname" . }}-{{ .Values.proxy.component }}" + # Issuer references are always required. + issuerRef: + name: "{{ template "pulsar.fullname" . }}-{{ .Values.certs.internal_issuer.component }}-ca-issuer" + # We can reference ClusterIssuers by changing the kind here. + # The default value is Issuer (i.e. a locally namespaced Issuer) + kind: Issuer + # This is optional since cert-manager will default to this value however + # if you are using an external issuer, change this to that issuer group. + group: cert-manager.io +--- +{{- end }} + +{{- if or .Values.tls.broker.enabled (or .Values.tls.bookie.enabled .Values.tls.zookeeper.enabled) }} +apiVersion: cert-manager.io/v1alpha2 +kind: Certificate +metadata: + name: "{{ template "pulsar.fullname" . }}-{{ .Values.tls.broker.cert_name }}" + namespace: {{ .Values.namespace }} +spec: + # Secret names are always required. + secretName: "{{ template "pulsar.fullname" . }}-{{ .Values.tls.broker.cert_name }}" + duration: "{{ .Values.tls.common.duration }}" + renewBefore: "{{ .Values.tls.common.renewBefore }}" + organization: +{{ toYaml .Values.tls.common.organization | indent 2 }} + # The use of the common name field has been deprecated since 2000 and is + # discouraged from being used. + commonName: "*.{{ template "pulsar.fullname" . }}-{{ .Values.broker.component }}.{{ .Values.namespace }}.svc.cluster.local" + isCA: false + keySize: {{ .Values.tls.common.keySize }} + keyAlgorithm: {{ .Values.tls.common.keyAlgorithm }} + keyEncoding: {{ .Values.tls.common.keyEncoding }} + usages: + - server auth + - client auth + # At least one of a DNS Name, USI SAN, or IP address is required. + dnsNames: + - "*.{{ template "pulsar.fullname" . }}-{{ .Values.broker.component }}.{{ .Values.namespace }}.svc.cluster.local" + - "{{ template "pulsar.fullname" . }}-{{ .Values.broker.component }}" + # Issuer references are always required. + issuerRef: + name: "{{ template "pulsar.fullname" . }}-{{ .Values.certs.internal_issuer.component }}-ca-issuer" + # We can reference ClusterIssuers by changing the kind here. + # The default value is Issuer (i.e. a locally namespaced Issuer) + kind: Issuer + # This is optional since cert-manager will default to this value however + # if you are using an external issuer, change this to that issuer group. + group: cert-manager.io +--- +{{- end }} + +{{- if or .Values.tls.bookie.enabled .Values.tls.zookeeper.enabled }} +apiVersion: cert-manager.io/v1alpha2 +kind: Certificate +metadata: + name: "{{ template "pulsar.fullname" . }}-{{ .Values.tls.bookie.cert_name }}" + namespace: {{ .Values.namespace }} +spec: + # Secret names are always required. + secretName: "{{ template "pulsar.fullname" . }}-{{ .Values.tls.bookie.cert_name }}" + duration: "{{ .Values.tls.common.duration }}" + renewBefore: "{{ .Values.tls.common.renewBefore }}" + organization: +{{ toYaml .Values.tls.common.organization | indent 2 }} + # The use of the common name field has been deprecated since 2000 and is + # discouraged from being used. + commonName: "*.{{ template "pulsar.fullname" . }}-{{ .Values.bookkeeper.component }}.{{ .Values.namespace }}.svc.cluster.local" + isCA: false + keySize: {{ .Values.tls.common.keySize }} + keyAlgorithm: {{ .Values.tls.common.keyAlgorithm }} + keyEncoding: {{ .Values.tls.common.keyEncoding }} + usages: + - server auth + - client auth + dnsNames: + - "*.{{ template "pulsar.fullname" . }}-{{ .Values.bookkeeper.component }}.{{ .Values.namespace }}.svc.cluster.local" + - "{{ template "pulsar.fullname" . }}-{{ .Values.bookkeeper.component }}" + # Issuer references are always required. + issuerRef: + name: "{{ template "pulsar.fullname" . }}-{{ .Values.certs.internal_issuer.component }}-ca-issuer" + # We can reference ClusterIssuers by changing the kind here. + # The default value is Issuer (i.e. a locally namespaced Issuer) + kind: Issuer + # This is optional since cert-manager will default to this value however + # if you are using an external issuer, change this to that issuer group. + group: cert-manager.io +--- +{{- end }} + +{{- if .Values.tls.zookeeper.enabled }} +apiVersion: cert-manager.io/v1alpha2 +kind: Certificate +metadata: + name: "{{ template "pulsar.fullname" . }}-{{ .Values.tls.autorecovery.cert_name }}" + namespace: {{ .Values.namespace }} +spec: + # Secret names are always required. + secretName: "{{ template "pulsar.fullname" . }}-{{ .Values.tls.autorecovery.cert_name }}" + duration: "{{ .Values.tls.common.duration }}" + renewBefore: "{{ .Values.tls.common.renewBefore }}" + organization: +{{ toYaml .Values.tls.common.organization | indent 2 }} + # The use of the common name field has been deprecated since 2000 and is + # discouraged from being used. + commonName: "*.{{ template "pulsar.fullname" . }}-{{ .Values.autorecovery.component }}.{{ .Values.namespace }}.svc.cluster.local" + isCA: false + keySize: {{ .Values.tls.common.keySize }} + keyAlgorithm: {{ .Values.tls.common.keyAlgorithm }} + keyEncoding: {{ .Values.tls.common.keyEncoding }} + usages: + - server auth + - client auth + dnsNames: + - "*.{{ template "pulsar.fullname" . }}-{{ .Values.autorecovery.component }}.{{ .Values.namespace }}.svc.cluster.local" + - "{{ template "pulsar.fullname" . }}-{{ .Values.autorecovery.component }}" + # Issuer references are always required. + issuerRef: + name: "{{ template "pulsar.fullname" . }}-{{ .Values.certs.internal_issuer.component }}-ca-issuer" + # We can reference ClusterIssuers by changing the kind here. + # The default value is Issuer (i.e. a locally namespaced Issuer) + kind: Issuer + # This is optional since cert-manager will default to this value however + # if you are using an external issuer, change this to that issuer group. + group: cert-manager.io +--- +apiVersion: cert-manager.io/v1alpha2 +kind: Certificate +metadata: + name: "{{ template "pulsar.fullname" . }}-{{ .Values.tls.toolset.cert_name }}" + namespace: {{ .Values.namespace }} +spec: + # Secret names are always required. + secretName: "{{ template "pulsar.fullname" . }}-{{ .Values.tls.toolset.cert_name }}" + duration: "{{ .Values.tls.common.duration }}" + renewBefore: "{{ .Values.tls.common.renewBefore }}" + organization: +{{ toYaml .Values.tls.common.organization | indent 2 }} + # The use of the common name field has been deprecated since 2000 and is + # discouraged from being used. + commonName: "*.{{ template "pulsar.fullname" . }}-{{ .Values.toolset.component }}.{{ .Values.namespace }}.svc.cluster.local" + isCA: false + keySize: {{ .Values.tls.common.keySize }} + keyAlgorithm: {{ .Values.tls.common.keyAlgorithm }} + keyEncoding: {{ .Values.tls.common.keyEncoding }} + usages: + - server auth + - client auth + dnsNames: + - "*.{{ template "pulsar.fullname" . }}-{{ .Values.toolset.component }}.{{ .Values.namespace }}.svc.cluster.local" + - "{{ template "pulsar.fullname" . }}-{{ .Values.toolset.component }}" + # Issuer references are always required. + issuerRef: + name: "{{ template "pulsar.fullname" . }}-{{ .Values.certs.internal_issuer.component }}-ca-issuer" + # We can reference ClusterIssuers by changing the kind here. + # The default value is Issuer (i.e. a locally namespaced Issuer) + kind: Issuer + # This is optional since cert-manager will default to this value however + # if you are using an external issuer, change this to that issuer group. + group: cert-manager.io +--- +apiVersion: cert-manager.io/v1alpha2 +kind: Certificate +metadata: + name: "{{ template "pulsar.fullname" . }}-{{ .Values.tls.zookeeper.cert_name }}" + namespace: {{ .Values.namespace }} +spec: + # Secret names are always required. + secretName: "{{ template "pulsar.fullname" . }}-{{ .Values.tls.zookeeper.cert_name }}" + duration: "{{ .Values.tls.common.duration }}" + renewBefore: "{{ .Values.tls.common.renewBefore }}" + organization: +{{ toYaml .Values.tls.common.organization | indent 2 }} + # The use of the common name field has been deprecated since 2000 and is + # discouraged from being used. + commonName: "*.{{ template "pulsar.fullname" . }}-{{ .Values.zookeeper.component }}.{{ .Values.namespace }}.svc.cluster.local" + isCA: false + keySize: {{ .Values.tls.common.keySize }} + keyAlgorithm: {{ .Values.tls.common.keyAlgorithm }} + keyEncoding: {{ .Values.tls.common.keyEncoding }} + usages: + - server auth + - client auth + dnsNames: + - "*.{{ template "pulsar.fullname" . }}-{{ .Values.zookeeper.component }}.{{ .Values.namespace }}.svc.cluster.local" + - "{{ template "pulsar.fullname" . }}-{{ .Values.zookeeper.component }}" + # Issuer references are always required. + issuerRef: + name: "{{ template "pulsar.fullname" . }}-{{ .Values.certs.internal_issuer.component }}-ca-issuer" + # We can reference ClusterIssuers by changing the kind here. + # The default value is Issuer (i.e. a locally namespaced Issuer) + kind: Issuer + # This is optional since cert-manager will default to this value however + # if you are using an external issuer, change this to that issuer group. + group: cert-manager.io +{{- end }} + +{{- end }} +{{- end }} \ No newline at end of file diff --git a/pulsar/templates/toolset-configmap.yaml b/pulsar/templates/toolset-configmap.yaml new file mode 100644 index 0000000..4e8fc16 --- /dev/null +++ b/pulsar/templates/toolset-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.components.toolset }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: "{{ template "pulsar.fullname" . }}-{{ .Values.toolset.component }}" + namespace: {{ .Values.namespace }} + labels: + {{- include "pulsar.standardLabels" . | nindent 4 }} + component: {{ .Values.toolset.component }} +data: + BOOKIE_LOG_APPENDER: "RollingFile" + {{- include "pulsar.bookkeeper.config.common" . | nindent 2 }} + {{- if not .Values.toolset.useProxy }} + # talk to broker + {{- if and .Values.tls.enabled .Values.tls.broker.enabled }} + webServiceUrl: "https://{{ template "pulsar.fullname" . }}-{{ .Values.broker.component }}:{{ .Values.broker.ports.https }}/" + brokerServiceUrl: "pulsar+ssl://{{ template "pulsar.fullname" . }}-{{ .Values.broker.component }}:{{ .Values.broker.ports.pulsarssl }}/" + useTls: "true" + tlsAllowInsecureConnection: "false" + tlsTrustCertsFilePath: "/pulsar/certs/proxy-ca/ca.crt" + tlsEnableHostnameVerification: "false" + {{- end }} + {{- if not (and .Values.tls.enabled .Values.tls.broker.enabled) }} + webServiceUrl: "http://{{ template "pulsar.fullname" . }}-{{ .Values.broker.component }}:{{ .Values.broker.ports.http }}/" + brokerServiceUrl: "pulsar://{{ template "pulsar.fullname" . }}-{{ .Values.broker.component }}:{{ .Values.broker.ports.pulsar }}/" + {{- end }} + {{- end }} + {{- if .Values.toolset.useProxy }} + # talk to proxy + {{- if and .Values.tls.enabled .Values.tls.proxy.enabled }} + webServiceUrl: "https://{{ template "pulsar.fullname" . }}-{{ .Values.proxy.component }}:{{ .Values.proxy.ports.https }}/" + brokerServiceUrl: "pulsar+ssl://{{ template "pulsar.fullname" . }}-{{ .Values.proxy.component }}:{{ .Values.proxy.ports.pulsarssl }}/" + useTls: "true" + tlsAllowInsecureConnection: "false" + tlsTrustCertsFilePath: "/pulsar/certs/proxy-ca/ca.crt" + tlsEnableHostnameVerification: "false" + {{- end }} + {{- if not (and .Values.tls.enabled .Values.tls.proxy.enabled) }} + webServiceUrl: "http://{{ template "pulsar.fullname" . }}-{{ .Values.proxy.component }}:{{ .Values.proxy.ports.http }}/" + brokerServiceUrl: "pulsar://{{ template "pulsar.fullname" . }}-{{ .Values.proxy.component }}:{{ .Values.proxy.ports.pulsar }}/" + {{- end }} + {{- end }} + # Authentication Settings + {{- if .Values.auth.authentication.enabled }} + {{- if eq .Values.auth.authentication.provider "jwt" }} + authParams: "file:///pulsar/tokens/client/token" + authPlugin: "org.apache.pulsar.client.impl.auth.AuthenticationToken" + {{- end }} + {{- end }} +{{ toYaml .Values.toolset.configData | indent 2 }} +{{- end }} diff --git a/pulsar/templates/toolset-service.yaml b/pulsar/templates/toolset-service.yaml new file mode 100644 index 0000000..e1c0ccc --- /dev/null +++ b/pulsar/templates/toolset-service.yaml @@ -0,0 +1,34 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +{{- if .Values.components.toolset }} +apiVersion: v1 +kind: Service +metadata: + name: "{{ template "pulsar.fullname" . }}-{{ .Values.toolset.component }}" + namespace: {{ .Values.namespace }} + labels: + {{- include "pulsar.standardLabels" . | nindent 4 }} + component: {{ .Values.toolset.component }} +spec: + clusterIP: None + selector: + {{- include "pulsar.matchLabels" . | nindent 4 }} + component: {{ .Values.toolset.component }} +{{- end }} \ No newline at end of file diff --git a/pulsar/templates/toolset-statefulset.yaml b/pulsar/templates/toolset-statefulset.yaml new file mode 100644 index 0000000..b15ad8d --- /dev/null +++ b/pulsar/templates/toolset-statefulset.yaml @@ -0,0 +1,108 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +{{- if .Values.components.toolset }} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: "{{ template "pulsar.fullname" . }}-{{ .Values.toolset.component }}" + namespace: {{ .Values.namespace }} + labels: + {{- include "pulsar.standardLabels" . | nindent 4 }} + component: {{ .Values.toolset.component }} +spec: + serviceName: "{{ template "pulsar.fullname" . }}-{{ .Values.toolset.component }}" + replicas: {{ .Values.toolset.replicaCount }} + updateStrategy: + type: RollingUpdate + podManagementPolicy: Parallel + selector: + matchLabels: + {{- include "pulsar.matchLabels" . | nindent 6 }} + component: {{ .Values.toolset.component }} + template: + metadata: + labels: + {{- include "pulsar.template.labels" . | nindent 8 }} + component: {{ .Values.toolset.component }} + annotations: +{{ toYaml .Values.toolset.annotations | indent 8 }} + spec: + {{- if .Values.toolset.nodeSelector }} + nodeSelector: +{{ toYaml .Values.toolset.nodeSelector | indent 8 }} + {{- end }} + {{- if .Values.toolset.tolerations }} + tolerations: +{{ toYaml .Values.toolset.tolerations | indent 8 }} + {{- end }} + terminationGracePeriodSeconds: {{ .Values.toolset.gracePeriod }} + containers: + - name: "{{ template "pulsar.fullname" . }}-{{ .Values.toolset.component }}" + image: "{{ .Values.images.broker.repository }}:{{ .Values.images.broker.tag }}" + imagePullPolicy: {{ .Values.images.broker.pullPolicy }} + {{- if .Values.toolset.resources }} + resources: +{{ toYaml .Values.toolset.resources | indent 10 }} + {{- end }} + command: ["sh", "-c"] + args: + - > + bin/apply-config-from-env.py conf/client.conf; + bin/apply-config-from-env.py conf/bookkeeper.conf; + {{- include "pulsar.toolset.zookeeper.tls.settings" . | nindent 10 }} + sleep 10000000000 + envFrom: + - configMapRef: + name: "{{ template "pulsar.fullname" . }}-{{ .Values.toolset.component }}" + volumeMounts: + {{- if .Values.auth.authentication.enabled }} + {{- if eq .Values.auth.authentication.provider "jwt" }} + - mountPath: "/pulsar/tokens" + name: client-token + readOnly: true + {{- end }} + {{- end }} + {{- if and .Values.tls.enabled (or .Values.tls.broker.enabled .Values.tls.proxy.enabled) }} + - mountPath: "/pulsar/certs/proxy-ca" + name: proxy-ca + readOnly: true + {{- end}} + {{- include "pulsar.toolset.certs.volumeMounts" . | nindent 8 }} + volumes: + {{- if .Values.auth.authentication.enabled }} + {{- if eq .Values.auth.authentication.provider "jwt" }} + - name: client-token + secret: + secretName: "{{ .Release.Name }}-token-{{ .Values.auth.superUsers.client }}" + items: + - key: TOKEN + path: client/token + {{- end}} + {{- end}} + {{- if and .Values.tls.enabled (or .Values.tls.broker.enabled .Values.tls.proxy.enabled) }} + - name: proxy-ca + secret: + secretName: "{{ template "pulsar.fullname" . }}-ca-tls" + items: + - key: ca.crt + path: ca.crt + {{- end}} + {{- include "pulsar.toolset.certs.volumes" . | nindent 6 }} +{{- end }} diff --git a/pulsar/templates/zookeeper-configmap.yaml b/pulsar/templates/zookeeper-configmap.yaml index 754f814..3b4cabf 100644 --- a/pulsar/templates/zookeeper-configmap.yaml +++ b/pulsar/templates/zookeeper-configmap.yaml @@ -17,17 +17,24 @@ # under the License. # +# deploy zookeeper only when `components.zookeeper` is true +{{- if .Values.components.zookeeper }} 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 }} + {{- include "pulsar.standardLabels" . | nindent 4 }} component: {{ .Values.zookeeper.component }} - cluster: {{ template "pulsar.fullname" . }} data: + dataDir: /pulsar/data/zookeeper + PULSAR_PREFIX_serverCnxnFactory: org.apache.zookeeper.server.NettyServerCnxnFactory + serverCnxnFactory: org.apache.zookeeper.server.NettyServerCnxnFactory + # enable zookeeper tls + {{- if and .Values.tls.enabled .Values.tls.zookeeper.enabled }} + secureClientPort: "{{ .Values.zookeeper.ports.clientTls }}" + PULSAR_PREFIX_secureClientPort: "{{ .Values.zookeeper.ports.clientTls }}" + {{- end }} {{ toYaml .Values.zookeeper.configData | indent 2 }} +{{- end }} diff --git a/pulsar/templates/zookeeper-metadata.yaml b/pulsar/templates/zookeeper-metadata.yaml deleted file mode 100644 index 5115286..0000000 --- a/pulsar/templates/zookeeper-metadata.yaml +++ /dev/null @@ -1,62 +0,0 @@ -# -# 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 }} - {{- if .Values.zookeeperMetadata.resources }} - resources: -{{ toYaml .Values.zookeeperMetadata.resources | indent 10 }} - {{- end }} - 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/pulsar/templates/zookeeper-pdb.yaml b/pulsar/templates/zookeeper-pdb.yaml index d205883..5417bed 100644 --- a/pulsar/templates/zookeeper-pdb.yaml +++ b/pulsar/templates/zookeeper-pdb.yaml @@ -17,6 +17,8 @@ # under the License. # +# deploy zookeeper only when `components.zookeeper` is true +{{- if .Values.components.zookeeper }} {{- if .Values.zookeeper.pdb.usePolicy }} apiVersion: policy/v1beta1 kind: PodDisruptionBudget @@ -24,17 +26,13 @@ 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 }} + {{- include "pulsar.standardLabels" . | nindent 4 }} component: {{ .Values.zookeeper.component }} - cluster: {{ template "pulsar.fullname" . }} spec: selector: matchLabels: - app: {{ template "pulsar.name" . }} - release: {{ .Release.Name }} + {{- include "pulsar.matchLabels" . | nindent 6 }} component: {{ .Values.zookeeper.component }} maxUnavailable: {{ .Values.zookeeper.pdb.maxUnavailable }} {{- end }} +{{- end }} diff --git a/pulsar/templates/zookeeper-service.yaml b/pulsar/templates/zookeeper-service.yaml index d7d8167..478a264 100644 --- a/pulsar/templates/zookeeper-service.yaml +++ b/pulsar/templates/zookeeper-service.yaml @@ -17,25 +17,32 @@ # under the License. # +# deploy zookeeper only when `components.zookeeper` is true +{{- if .Values.components.zookeeper }} 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 }} + {{- include "pulsar.standardLabels" . | nindent 4 }} 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 }} + - name: follower + port: {{ .Values.zookeeper.ports.follower }} + - name: leader-election + port: {{ .Values.zookeeper.ports.leaderElection }} + - name: client + port: {{ .Values.zookeeper.ports.client }} + {{- if and .Values.tls.enabled .Values.tls.zookeeper.enabled }} + - name: client-tls + port: {{ .Values.zookeeper.ports.clientTls }} + {{- end }} clusterIP: None selector: - app: {{ template "pulsar.name" . }} - release: {{ .Release.Name }} + {{- include "pulsar.matchLabels" . | nindent 4 }} component: {{ .Values.zookeeper.component }} +{{- end }} diff --git a/pulsar/templates/zookeeper-statefulset.yaml b/pulsar/templates/zookeeper-statefulset.yaml index fda52fe..21a4553 100644 --- a/pulsar/templates/zookeeper-statefulset.yaml +++ b/pulsar/templates/zookeeper-statefulset.yaml @@ -17,25 +17,22 @@ # under the License. # +# deploy zookeeper only when `components.zookeeper` is true +{{- if .Values.components.zookeeper }} 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 }} + {{- include "pulsar.standardLabels" . | nindent 4 }} 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 }} + {{- include "pulsar.matchLabels" . | nindent 6 }} component: {{ .Values.zookeeper.component }} updateStrategy: {{ toYaml .Values.zookeeper.updateStrategy | indent 4 }} @@ -43,10 +40,8 @@ spec: template: metadata: labels: - app: {{ template "pulsar.name" . }} - release: {{ .Release.Name }} + {{- include "pulsar.template.labels" . | nindent 8 }} component: {{ .Values.zookeeper.component }} - cluster: {{ template "pulsar.fullname" . }} annotations: {{ toYaml .Values.zookeeper.annotations | indent 8 }} spec: @@ -59,6 +54,7 @@ spec: {{ toYaml .Values.zookeeper.tolerations | indent 8 }} {{- end }} affinity: + {{- if and .Values.affinity.anti_affinity .Values.zookeeper.affinity.anti_affinity}} podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: @@ -66,7 +62,7 @@ spec: - key: "app" operator: In values: - - "{{ template "pulsar.name" . }}" + - "{{ template "pulsar.name" . }}-{{ .Values.zookeeper.component }}" - key: "release" operator: In values: @@ -76,11 +72,12 @@ spec: values: - {{ .Values.zookeeper.component }} topologyKey: "kubernetes.io/hostname" + {{- end }} terminationGracePeriodSeconds: {{ .Values.zookeeper.gracePeriod }} containers: - name: "{{ template "pulsar.fullname" . }}-{{ .Values.zookeeper.component }}" - image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" - imagePullPolicy: {{ .Values.image.pullPolicy }} + image: "{{ .Values.images.zookeeper.repository }}:{{ .Values.images.zookeeper.tag }}" + imagePullPolicy: {{ .Values.images.zookeeper.pullPolicy }} {{- if .Values.zookeeper.resources }} resources: {{ toYaml .Values.zookeeper.resources | indent 10 }} @@ -88,17 +85,22 @@ spec: 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 + bin/apply-config-from-env.py conf/zookeeper.conf; + bin/apply-config-from-env.py conf/pulsar_env.sh; + {{- include "pulsar.zookeeper.tls.settings" . | nindent 10 }} + bin/generate-zookeeper-config.sh conf/zookeeper.conf; + bin/pulsar zookeeper; ports: - name: client - containerPort: 2181 - - name: server - containerPort: 2888 + containerPort: {{ .Values.zookeeper.ports.client }} + - name: follower + containerPort: {{ .Values.zookeeper.ports.follower }} - name: leader-election - containerPort: 3888 + containerPort: {{ .Values.zookeeper.ports.leaderElection }} + {{- if and .Values.tls.enabled .Values.tls.zookeeper.enabled }} + - name: client-tls + containerPort: {{ .Values.zookeeper.ports.clientTls }} + {{- end }} env: - name: ZOOKEEPER_SERVERS value: @@ -107,27 +109,73 @@ spec: envFrom: - configMapRef: name: "{{ template "pulsar.fullname" . }}-{{ .Values.zookeeper.component }}" + {{- if .Values.zookeeper.probe.readiness.enabled }} readinessProbe: exec: command: - - "bin/pulsar-zookeeper-ruok.sh" - initialDelaySeconds: 5 - timeoutSeconds: 5 + - bin/pulsar-zookeeper-ruok.sh + initialDelaySeconds: {{ .Values.zookeeper.probe.readiness.initialDelaySeconds }} + periodSeconds: {{ .Values.zookeeper.probe.readiness.periodSeconds }} + failureThreshold: {{ .Values.zookeeper.probe.readiness.failureThreshold }} + {{- end }} + {{- if .Values.zookeeper.probe.liveness.enabled }} livenessProbe: exec: command: - - "bin/pulsar-zookeeper-ruok.sh" - initialDelaySeconds: 15 - timeoutSeconds: 5 + - bin/pulsar-zookeeper-ruok.sh + initialDelaySeconds: {{ .Values.zookeeper.probe.liveness.initialDelaySeconds }} + periodSeconds: {{ .Values.zookeeper.probe.liveness.periodSeconds }} + failureThreshold: {{ .Values.zookeeper.probe.liveness.failureThreshold }} + {{- end }} + {{- if .Values.zookeeper.probe.startup.enabled }} + startupProbe: + exec: + command: + - bin/pulsar-zookeeper-ruok.sh + initialDelaySeconds: {{ .Values.zookeeper.probe.startup.initialDelaySeconds }} + periodSeconds: {{ .Values.zookeeper.probe.startup.periodSeconds }} + failureThreshold: {{ .Values.zookeeper.probe.startup.failureThreshold }} + {{- end }} volumeMounts: - name: "{{ template "pulsar.fullname" . }}-{{ .Values.zookeeper.component }}-{{ .Values.zookeeper.volumes.data.name }}" mountPath: /pulsar/data - {{- if not .Values.persistence }} + {{- if and .Values.tls.enabled .Values.tls.zookeeper.enabled }} + - mountPath: "/pulsar/certs/zookeeper" + name: zookeeper-certs + readOnly: true + - mountPath: "/pulsar/certs/ca" + name: ca + readOnly: true + - name: keytool + mountPath: "/pulsar/keytool/keytool.sh" + subPath: keytool.sh + {{- end }} volumes: + {{- if not (and (and .Values.volumes.persistence .Values.volumes.persistence) .Values.zookeeper.volumes.persistence) }} - name: "{{ template "pulsar.fullname" . }}-{{ .Values.zookeeper.component }}-{{ .Values.zookeeper.volumes.data.name }}" emptyDir: {} - {{- end }} -{{- if .Values.persistence }} + {{- end }} + {{- if and .Values.tls.enabled .Values.tls.zookeeper.enabled }} + - name: zookeeper-certs + secret: + secretName: "{{ template "pulsar.fullname" . }}-{{ .Values.tls.zookeeper.cert_name }}" + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + - name: ca + secret: + secretName: "{{ template "pulsar.fullname" . }}-ca-tls" + items: + - key: ca.crt + path: ca.crt + - name: keytool + configMap: + name: "{{ template "pulsar.fullname" . }}-keytool-configmap" + defaultMode: 0755 + {{- end}} +{{- if and (and .Values.persistence .Values.volumes.persistence) .Values.zookeeper.volumes.persistence }} volumeClaimTemplates: - metadata: name: "{{ template "pulsar.fullname" . }}-{{ .Values.zookeeper.component }}-{{ .Values.zookeeper.volumes.data.name }}" @@ -138,7 +186,10 @@ spec: storage: {{ .Values.zookeeper.volumes.data.size }} {{- if .Values.zookeeper.volumes.data.storageClassName }} storageClassName: "{{ .Values.zookeeper.volumes.data.storageClassName }}" - {{- else if .Values.zookeeper.volumes.data.storageClass }} + {{- else if and (not (and .Values.volumes.local_storage .Values.zookeeper.volumes.data.local_storage)) .Values.zookeeper.volumes.data.storageClass }} storageClassName: "{{ template "pulsar.fullname" . }}-{{ .Values.zookeeper.component }}-{{ .Values.zookeeper.volumes.data.name }}" + {{- else if and .Values.volumes.local_storage .Values.zookeeper.volumes.data.local_storage }} + storageClassName: "local-storage" {{- end }} {{- end }} +{{- end }} diff --git a/pulsar/templates/zookeeper-storageclass.yaml b/pulsar/templates/zookeeper-storageclass.yaml index 7562337..08b66c8 100644 --- a/pulsar/templates/zookeeper-storageclass.yaml +++ b/pulsar/templates/zookeeper-storageclass.yaml @@ -17,23 +17,24 @@ # under the License. # -{{- if .Values.persistence }} -{{- if .Values.zookeeper.volumes.data.storageClass }} +# deploy zookeeper only when `components.zookeeper` is true +{{- if .Values.components.zookeeper }} +{{- if and (and .Values.persistence .Values.volumes.persistence) .Values.zookeeper.volumes.persistence }} + +# define the storage class for data directory +{{- if and (not (and .Values.volumes.local_storage .Values.zookeeper.volumes.data.local_storage)) .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 }} + {{- include "pulsar.standardLabels" . | nindent 4 }} 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 }} +{{- end }} diff --git a/pulsar/values-mini.yaml b/pulsar/values-mini.yaml deleted file mode 100644 index e21c3d0..0000000 --- a/pulsar/values-mini.yaml +++ /dev/null @@ -1,528 +0,0 @@ -# -# 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 have state will -## be deployed with PersistentVolumeClaims, otherwise, for test -## purposes, they will be deployed with emptyDir -persistence: no - -## If prometheus_persistence is enabled, prometheus will be deployed -## with PersistentVolumeClaims, otherwise, for test purposes, they -## will be deployed with emptyDir -prometheus_persistence: no - -prometheus_rbac: yes - -## which extra components to deploy -extra: - # Pulsar proxy - proxy: yes - # Bookkeeper auto-recovery - autoRecovery: yes - # Pulsar dashboard - # Deprecated - # Replace pulsar-dashboard with pulsar-manager - dashboard: no - # pulsar manager - pulsar_manager: yes - # Bastion pod for administrative commands - bastion: yes - # Monitoring stack (prometheus and grafana) - monitoring: yes - # Configure Kubernetes runtime for Functions - functionsAsPods: no - -## Which pulsar image to use -image: - repository: apachepulsar/pulsar-all - 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" - tolerations: [] - gracePeriod: 0 - resources: - requests: - memory: 64Mi - cpu: 0.1 - volumes: - data: - name: data - size: 2Gi - ## If you already have an existent storage class and want to reuse it, you can specify its name with the option below - ## - # storageClassName: existent-storage-class - # - ## Instead if you want to create a new storage class define it below - ## If left undefined no storage class will be defined along with PVC - ## - # storageClass: - # type: pd-ssd - # fsType: xfs - # provisioner: kubernetes.io/gce-pd - ## Zookeeper configmap - ## templates/zookeeper-configmap.yaml - ## - configData: - PULSAR_MEM: "\"-Xms64m -Xmx128m -Dcom.sun.management.jmxremote -Djute.maxbuffer=10485760 -XX:+ParallelRefProcEnabled -XX:+UnlockExperimentalVMOptions -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 last zookeeper node is reachable. The deployment -## of other components that depends on 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: 3 - updateStrategy: - type: OnDelete - podManagementPolicy: OrderedReady - # nodeSelector: - # cloud.google.com/gke-nodepool: default-pool - annotations: - prometheus.io/scrape: "true" - prometheus.io/port: "8000" - tolerations: [] - gracePeriod: 0 - resources: - requests: - memory: 128Mi - cpu: 0.2 - volumes: - journal: - name: journal - size: 5Gi - ## If you already have an existent storage class and want to reuse it, you can specify its name with the option below - ## - # storageClassName: existent-storage-class - # - ## Instead if you want to create a new storage class define it below - ## If left undefined no storage class will be defined along with PVC - ## - # storageClass: - # type: pd-ssd - # fsType: xfs - # provisioner: kubernetes.io/gce-pd - ledgers: - name: ledgers - size: 5Gi - ## If you already have an existent storage class and want to reuse it, you can specify its name with the option below - ## - # storageClassName: existent-storage-class - # - ## Instead if you want to create a new storage class define it below - ## If left undefined no storage class will be defined along with PVC - ## - # storageClass: - # type: pd-ssd - # fsType: xfs - # provisioner: kubernetes.io/gce-pd - ## Bookkeeper configmap - ## templates/bookkeeper-configmap.yaml - ## - configData: - BOOKIE_MEM: "\"-Xms128m -Xmx256m -XX:MaxDirectMemorySize=128m -Dio.netty.leakDetectionLevel=disabled -Dio.netty.recycler.linkCapacity=1024 -XX:+ParallelRefProcEnabled -XX:+UnlockExperimentalVMOptions -XX:+DoEscapeAnalysis -XX:ParallelGCThreads=32 -XX:ConcGCThreads=32 -XX:G1NewSizePercent=50 -XX:+DisableExplicitGC -XX:-ResizePLAB -XX:+ExitOnOutOfMemoryError -XX:+PerfDisableSharedMem\"" - BOOKIE_GC: "\"-XX:+UseG1GC -XX:MaxGCPauseMillis=10\"" - dbStorage_writeCacheMaxSizeMb: "32" - dbStorage_readAheadCacheMaxSizeMb: "32" - 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: 2 - # nodeSelector: - # cloud.google.com/gke-nodepool: default-pool - annotations: - prometheus.io/scrape: "true" - prometheus.io/port: "8080" - tolerations: [] - gracePeriod: 0 - resources: - requests: - memory: 128Mi - cpu: 0.2 - ## Broker configmap - ## templates/broker-configmap.yaml - ## - configData: - PULSAR_MEM: "\"-Xms128m -Xmx256m -XX:MaxDirectMemorySize=128m -Dio.netty.leakDetectionLevel=disabled -Dio.netty.recycler.linkCapacity=1024 -XX:+ParallelRefProcEnabled -XX:+UnlockExperimentalVMOptions -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: "2" - managedLedgerDefaultWriteQuorum: "2" - 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 - ## Broker rbac - ## templates/broker-rbac.yaml - ## - functions: - component: functions-worker - -## Pulsar Extra: Proxy -## templates/proxy-deployment.yaml -## -proxy: - component: proxy - replicaCount: 1 - # nodeSelector: - # cloud.google.com/gke-nodepool: default-pool - annotations: - prometheus.io/scrape: "true" - prometheus.io/port: "8080" - tolerations: [] - gracePeriod: 0 - resources: - requests: - memory: 64Mi - cpu: 0.1 - ## Proxy configmap - ## templates/proxy-configmap.yaml - ## - configData: - PULSAR_MEM: "\"-Xms64m -Xmx128m -XX:MaxDirectMemorySize=64m\"" - ## Proxy service - ## templates/proxy-service.yaml - ## - service: - annotations: {} - type: NodePort - 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: {} - tolerations: [] - gracePeriod: 0 - resources: - requests: - memory: 64Mi - cpu: 0.05 - ## Bookkeeper auto-recovery configmap - ## templates/autorecovery-configmap.yaml - ## - configData: - BOOKIE_MEM: "\" -Xms64m -Xmx128m \"" - -## Pulsar Extra: Dashboard -## templates/dashboard-deployment.yaml -## Deprecated -## -dashboard: - component: dashboard - replicaCount: 1 - # nodeSelector: - # cloud.google.com/gke-nodepool: default-pool - annotations: {} - tolerations: [] - gracePeriod: 0 - image: - repository: apachepulsar/pulsar-dashboard - tag: latest - pullPolicy: IfNotPresent - resources: - requests: - memory: 64Mi - cpu: 0.1 - ## Dashboard service - ## templates/dashboard-service.yaml - ## - service: - annotations: {} - ports: - - name: server - port: 80 - ingress: - enabled: false - annotations: {} - tls: - enabled: false - - ## Optional. Leave it blank if your Ingress Controller can provide a default certificate. - secretName: "" - - ## Required if ingress is enabled - hostname: "" - path: "/" - port: 80 - - -## Pulsar Extra: Bastion -## templates/bastion-deployment.yaml -## -bastion: - component: bastion - replicaCount: 1 - # nodeSelector: - # cloud.google.com/gke-nodepool: default-pool - annotations: {} - tolerations: [] - gracePeriod: 0 - resources: - requests: - memory: 128Mi - cpu: 0.1 - ## Bastion configmap - ## templates/bastion-configmap.yaml - ## - configData: - PULSAR_MEM: "\"-Xms128m -Xmx256m -XX:MaxDirectMemorySize=128m\"" - -## Monitoring Stack: Prometheus -## templates/prometheus-deployment.yaml -## -prometheus: - component: prometheus - replicaCount: 1 - # nodeSelector: - # cloud.google.com/gke-nodepool: default-pool - annotations: {} - tolerations: [] - gracePeriod: 0 - image: - repository: prom/prometheus - tag: v1.6.3 - pullPolicy: IfNotPresent - resources: - requests: - memory: 64Mi - cpu: 0.1 - volumes: - data: - name: data - size: 2Gi - ## If you already have an existent storage class and want to reuse it, you can specify its name with the option below - ## - # storageClassName: existent-storage-class - # - ## Instead if you want to create a new storage class define it below - ## If left undefined no storage class will be defined along with PVC - ## - # 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: {} - tolerations: [] - gracePeriod: 0 - image: - repository: apachepulsar/pulsar-grafana - tag: latest - pullPolicy: IfNotPresent - resources: - requests: - memory: 64Mi - cpu: 0.1 - ## Grafana service - ## templates/grafana-service.yaml - ## - service: - annotations: {} - ports: - - name: server - port: 3000 - plugins: [] - ## Grafana ingress - ## templates/grafana-ingress.yaml - ## - ingress: - enabled: false - annotations: - kubernetes.io/ingress.class: nginx - # nginx.ingress.kubernetes.io/rewrite-target: /$1 - # ingress.kubernetes.io/force-ssl-redirect: "true" - ingress.kubernetes.io/rewrite-target: / - labels: {} - - tls: [] - - ## Optional. Leave it blank if your Ingress Controller can provide a default certificate. - #- secretName: "" - - ## Extra paths to prepend to every host configuration. This is useful when working with annotation based services. - extraPaths: [] - ## Required if ingress is enabled - hostname: "" - protocol: http - path: /grafana - port: 80 - -zookeeper_metadata: - resources: - requests: - memory: 128Mi - cpu: 0.1 - -## Components Stack: pulsar_manager -## templates/pulsar-manager.yaml -## - -pulsar_manager: - component: pulsar-manager - replicaCount: 1 - # nodeSelector: - # cloud.google.com/gke-nodepool: default-pool - annotations: {} - tolerations: [] - gracePeriod: 0 - image: - repository: apachepulsar/pulsar-manager - tag: v0.1.0 - pullPolicy: IfNotPresent - resources: - requests: - memory: 250Mi - cpu: 0.1 - configData: - REDIRECT_HOST: "http://127.0.0.1" - REDIRECT_PORT: "9527" - DRIVER_CLASS_NAME: org.postgresql.Driver - URL: jdbc:postgresql://127.0.0.1:5432/pulsar_manager - LOG_LEVEL: DEBUG - ## If you enabled authentication support - #JWT_TOKEN: - #SECRET_KEY: data:base64, - ## Pulsar manager service - ## templates/pulsar-manager-service.yaml - ## - service: - type: LoadBalancer - annotations: {} - ports: - - name: server - port: 9527 - admin: - user: pulsar - password: pulsar diff --git a/pulsar/values.yaml b/pulsar/values.yaml index 312dfb7..5c1582d 100644 --- a/pulsar/values.yaml +++ b/pulsar/values.yaml @@ -17,71 +17,285 @@ # under the License. # + +### +### K8S Settings +### + ## Namespace to deploy pulsar namespace: pulsar -namespaceCreate: yes +namespaceCreate: false +### +### Global Settings +### + +## Pulsar Metadata Prefix +## +## By default, pulsar stores all the metadata at root path. +## You can configure to have a prefix (e.g. "/my-pulsar-cluster"). +## If you do so, all the pulsar and bookkeeper metadata will +## be stored under the provided path +metadataPrefix: "" + +## Persistence +## ## If persistence is enabled, components that have state will ## be deployed with PersistentVolumeClaims, otherwise, for test ## purposes, they will be deployed with emptyDir -persistence: no +## +## This is a global setting that is applied to all components. +## If you need to disable persistence for a component, +## you can set the `volume.persistence` setting to `false` for +## that component. +## +## Deprecated in favor of using `volumes.persistence` +persistence: true +## Volume settings +volumes: + persistence: true + # configure the components to use local persistent volume + # the local provisioner should be installed prior to enable local persistent volume + local_storage: false -## If prometheus_persistence is enabled, prometheus will be deployed -## with PersistentVolumeClaims, otherwise, for test purposes, they -## will be deployed with emptyDir -prometheus_persistence: yes +## AntiAffinity +## +## Flag to enable and disable `AntiAffinity` for all components. +## This is a global setting that is applied to all components. +## If you need to disable AntiAffinity for a component, you can set +## the `affinity.anti_affinity` settings to `false` for that component. +affinity: + anti_affinity: true -prometheus_rbac: yes +## Components +## +## Control what components of Apache Pulsar to deploy for the cluster +components: + # zookeeper + zookeeper: true + # bookkeeper + bookkeeper: true + # bookkeeper - autorecovery + autorecovery: true + # broker + broker: true + # functions + functions: true + # proxy + proxy: true + # toolset + toolset: true + # pulsar manager + pulsar_manager: true -## which extra components to deploy +## Monitoring Components +## +## Control what components of the monitoring stack to deploy for the cluster +monitoring: + # monitoring - prometheus + prometheus: true + # monitoring - grafana + grafana: true + # monitoring - node_exporter + node_exporter: true + # alerting - alert-manager + alert_manager: true + +## which extra components to deploy (Deprecated) extra: # Pulsar proxy - proxy: yes + proxy: false # Bookkeeper auto-recovery - autoRecovery: yes + autoRecovery: false # Pulsar dashboard # Deprecated # Replace pulsar-dashboard with pulsar-manager - dashboard: no + dashboard: false # pulsar manager - pulsar_manager: yes + pulsar_manager: false # Bastion pod for administrative commands - bastion: yes + bastion: false # Monitoring stack (prometheus and grafana) - monitoring: yes + monitoring: false # Configure Kubernetes runtime for Functions - functionsAsPods: no + functionsAsPods: false -## Which pulsar image to use -image: - repository: apachepulsar/pulsar-all - tag: latest - pullPolicy: IfNotPresent +## Images +## +## Control what images to use for each component +images: + zookeeper: + repository: apachepulsar/pulsar-all + tag: 2.5.0 + pullPolicy: IfNotPresent + bookie: + repository: apachepulsar/pulsar-all + tag: 2.5.0 + pullPolicy: IfNotPresent + autorecovery: + repository: apachepulsar/pulsar-all + tag: 2.5.0 + pullPolicy: IfNotPresent + broker: + repository: apachepulsar/pulsar-all + tag: 2.5.0 + pullPolicy: IfNotPresent + proxy: + repository: apachepulsar/pulsar-all + tag: 2.5.0 + pullPolicy: IfNotPresent + functions: + repository: apachepulsar/pulsar-all + tag: 2.5.0 + prometheus: + repository: prom/prometheus + tag: v1.6.3 + pullPolicy: IfNotPresent + grafana: + repository: streamnative/apache-pulsar-grafana-dashboard-k8s + tag: 0.0.4 + pullPolicy: IfNotPresent + pulsar_manager: + repository: apachepulsar/pulsar-manager + tag: v0.1.0 + pullPolicy: IfNotPresent + hasCommand: false + +## TLS +## templates/tls-certs.yaml +## +## The chart is using cert-manager for provisioning TLS certs for +## brokers and proxies. +tls: + enabled: false + # common settings for generating certs + common: + # 90d + duration: 2160h + # 15d + renewBefore: 360h + organization: + - pulsar + keySize: 4096 + keyAlgorithm: rsa + keyEncoding: pkcs8 + # settings for generating certs for proxy + proxy: + enabled: false + cert_name: tls-proxy + # settings for generating certs for broker + broker: + enabled: false + cert_name: tls-broker + # settings for generating certs for bookies + bookie: + enabled: false + cert_name: tls-bookie + # settings for generating certs for zookeeper + zookeeper: + enabled: false + cert_name: tls-zookeeper + # settings for generating certs for recovery + autorecovery: + cert_name: tls-recovery + # settings for generating certs for toolset + toolset: + cert_name: tls-toolset + +# Enable or disable broker authentication and authorization. +auth: + authentication: + enabled: false + provider: "jwt" + jwt: + # Enable JWT authentication + # If the token is generated by a secret key, set the usingSecretKey as true. + # If the token is generated by a private key, set the usingSecretKey as false. + usingSecretKey: false + authorization: + enabled: false + superUsers: + # broker to broker communication + broker: "broker-admin" + # proxy to broker communication + proxy: "proxy-admin" + # pulsar-admin client to broker/proxy communication + client: "admin" + +###################################################################### +# External dependencies +###################################################################### + +## cert-manager +## templates/tls-cert-issuer.yaml +## +## Cert manager is used for automatically provisioning TLS certificates +## for components within a Pulsar cluster +certs: + internal_issuer: + enabled: false + component: internal-cert-issuer + type: selfsigning + issuers: + selfsigning: + +###################################################################### +# Below are settings for each component +###################################################################### ## Pulsar: Zookeeper cluster ## templates/zookeeper-statefulset.yaml ## zookeeper: + # use a component name that matches your grafana configuration + # so the metrics are correctly rendered in grafana dashboard component: zookeeper + # the number of zookeeper servers to run. it should be an odd number larger than or equal to 3. replicaCount: 3 updateStrategy: - type: OnDelete + type: RollingUpdate podManagementPolicy: OrderedReady + ports: + client: 2181 + clientTls: 2281 + follower: 2888 + leaderElection: 3888 # nodeSelector: # cloud.google.com/gke-nodepool: default-pool + probe: + liveness: + enabled: true + failureThreshold: 10 + initialDelaySeconds: 10 + periodSeconds: 30 + readiness: + enabled: true + failureThreshold: 10 + initialDelaySeconds: 10 + periodSeconds: 30 + startup: + enabled: false + failureThreshold: 30 + initialDelaySeconds: 10 + periodSeconds: 30 + affinity: + anti_affinity: true annotations: prometheus.io/scrape: "true" prometheus.io/port: "8000" tolerations: [] - gracePeriod: 0 + gracePeriod: 30 resources: requests: - memory: 15Gi - cpu: 4 + memory: 256Mi + cpu: 0.1 volumes: + # use a persistent volume or emptyDir + persistence: true data: name: data size: 20Gi + local_storage: true ## If you already have an existent storage class and want to reuse it, you can specify its name with the option below ## # storageClassName: existent-storage-class @@ -97,61 +311,98 @@ zookeeper: ## templates/zookeeper-configmap.yaml ## configData: - PULSAR_MEM: "\"-Xms15g -Xmx15g -Dcom.sun.management.jmxremote -Djute.maxbuffer=10485760 -XX:+ParallelRefProcEnabled -XX:+UnlockExperimentalVMOptions -XX:+DoEscapeAnalysis -XX:+DisableExplicitGC -XX:+PerfDisableSharedMem -Dzookeeper.forceSync=no\"" - PULSAR_GC: "\"-XX:+UseG1GC -XX:MaxGCPauseMillis=10\"" + PULSAR_MEM: > + " + -Xms64m -Xmx128m + -Dcom.sun.management.jmxremote + -Djute.maxbuffer=10485760 + -XX:+ParallelRefProcEnabled + -XX:+UnlockExperimentalVMOptions + -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 + usePolicy: true maxUnavailable: 1 -## Pulsar Zookeeper metadata. The metadata will be deployed as -## soon as the last zookeeper node is reachable. The deployment -## of other components that depends on 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 + # use a component name that matches your grafana configuration + # so the metrics are correctly rendered in grafana dashboard + component: bookie + ## BookKeeper Cluster Initialize + ## templates/bookkeeper-cluster-initialize.yaml + metadata: + image: + # the image used for running `bookkeeper-cluster-initialize` job + repository: apachepulsar/pulsar-all + tag: 2.5.0 + pullPolicy: IfNotPresent + ## Set the resources used for running `bin/bookkeeper shell initnewcluster` + ## + resources: + # requests: + # memory: 4Gi + # cpu: 2 replicaCount: 4 updateStrategy: - type: OnDelete - podManagementPolicy: OrderedReady + type: RollingUpdate + podManagementPolicy: Parallel + ports: + http: 8000 + bookie: 3181 # nodeSelector: # cloud.google.com/gke-nodepool: default-pool - annotations: - prometheus.io/scrape: "true" - prometheus.io/port: "8000" + probe: + liveness: + enabled: true + failureThreshold: 60 + initialDelaySeconds: 10 + periodSeconds: 30 + readiness: + enabled: true + failureThreshold: 60 + initialDelaySeconds: 10 + periodSeconds: 30 + startup: + enabled: false + failureThreshold: 30 + initialDelaySeconds: 60 + periodSeconds: 30 + affinity: + anti_affinity: true + annotations: {} tolerations: [] - gracePeriod: 0 + gracePeriod: 30 resources: requests: - memory: 15Gi - cpu: 4 + memory: 512Mi + cpu: 0.2 volumes: + # use a persistent volume or emptyDir + persistence: true journal: name: journal - size: 50Gi + size: 10Gi + local_storage: true ## If you already have an existent storage class and want to reuse it, you can specify its name with the option below ## # storageClassName: existent-storage-class @@ -166,6 +417,7 @@ bookkeeper: ledgers: name: ledgers size: 50Gi + local_storage: true ## If you already have an existent storage class and want to reuse it, you can specify its name with the option below ## # storageClassName: existent-storage-class @@ -181,145 +433,271 @@ bookkeeper: ## templates/bookkeeper-configmap.yaml ## configData: - BOOKIE_MEM: "\"-Xms15g -Xmx15g -XX:MaxDirectMemorySize=15g -Dio.netty.leakDetectionLevel=disabled -Dio.netty.recycler.linkCapacity=1024 -XX:+ParallelRefProcEnabled -XX:+UnlockExperimentalVMOptions -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\"" - BOOKIE_GC: "\"-XX:+UseG1GC -XX:MaxGCPauseMillis=10\"" - dbStorage_writeCacheMaxSizeMb: "2048" - dbStorage_readAheadCacheMaxSizeMb: "2048" - dbStorage_rocksDB_blockCacheSize: "268435456" - journalMaxSizeMB: "2048" - statsProviderClass: org.apache.bookkeeper.stats.prometheus.PrometheusMetricsProvider - useHostNameAsBookieID: "true" - ## Bookkeeper configmap + # `BOOKIE_MEM` is used for `bookie shell` + BOOKIE_MEM: > + " + -Xms128m + -Xmx256m + -XX:MaxDirectMemorySize=256m + " + # we use `bin/pulsar` for starting bookie daemons + PULSAR_MEM: > + " + -Xms128m + -Xmx256m + -XX:MaxDirectMemorySize=256m + " + PULSAR_GC: > + " + -XX:+UseG1GC + -XX:MaxGCPauseMillis=10 + -XX:+ParallelRefProcEnabled + -XX:+UnlockExperimentalVMOptions + -XX:+DoEscapeAnalysis + -XX:ParallelGCThreads=4 + -XX:ConcGCThreads=4 + -XX:G1NewSizePercent=50 + -XX:+DisableExplicitGC + -XX:-ResizePLAB + -XX:+ExitOnOutOfMemoryError + -XX:+PerfDisableSharedMem + -XX:+PrintGCDetails + -XX:+PrintGCTimeStamps + -XX:+PrintGCApplicationStoppedTime + -XX:+PrintHeapAtGC + -verbosegc + -Xloggc:/var/log/bookie-gc.log + -XX:G1LogLevel=finest + " + # configure the memory settings based on jvm memory settings + dbStorage_writeCacheMaxSizeMb: "32" + dbStorage_readAheadCacheMaxSizeMb: "32" + dbStorage_rocksDB_writeBufferSizeMB: "8" + dbStorage_rocksDB_blockCacheSize: "8388608" + ## Bookkeeper Service ## templates/bookkeeper-service.yaml ## service: annotations: publishNotReadyAddresses: "true" - ports: - - name: server - port: 3181 ## Bookkeeper PodDisruptionBudget ## templates/bookkeeper-pdb.yaml ## pdb: - usePolicy: yes + usePolicy: true maxUnavailable: 1 -## Pulsar: Broker cluster -## templates/broker-deployment.yaml +## Pulsar: Bookkeeper AutoRecovery +## templates/autorecovery-statefulset.yaml ## -broker: - component: broker - replicaCount: 3 +autorecovery: + # use a component name that matches your grafana configuration + # so the metrics are correctly rendered in grafana dashboard + component: recovery + replicaCount: 1 + ports: + http: 8000 # nodeSelector: # cloud.google.com/gke-nodepool: default-pool - annotations: - prometheus.io/scrape: "true" - prometheus.io/port: "8080" - tolerations: [] - gracePeriod: 0 + affinity: + anti_affinity: true + annotations: {} + # tolerations: [] + gracePeriod: 30 resources: requests: - memory: 15Gi - cpu: 4 + memory: 64Mi + cpu: 0.05 + ## Bookkeeper auto-recovery configmap + ## templates/autorecovery-configmap.yaml + ## + configData: + BOOKIE_MEM: > + " + -Xms64m -Xmx64m + " + +## Pulsar Zookeeper metadata. The metadata will be deployed as +## soon as the last zookeeper node is reachable. The deployment +## of other components that depends on 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 +pulsar_metadata: + component: pulsar-init + image: + # the image used for running `pulsar-cluster-initialize` job + repository: apachepulsar/pulsar-all + tag: 2.5.0 + pullPolicy: IfNotPresent + ## set an existing configuration store + # configurationStore: + configurationStoreMetadataPrefix: "" + +## Pulsar: Broker cluster +## templates/broker-statefulset.yaml +## +broker: + # use a component name that matches your grafana configuration + # so the metrics are correctly rendered in grafana dashboard + component: broker + replicaCount: 3 + ports: + http: 8080 + https: 8443 + pulsar: 6650 + pulsarssl: 6651 + # nodeSelector: + # cloud.google.com/gke-nodepool: default-pool + probe: + liveness: + enabled: true + failureThreshold: 10 + initialDelaySeconds: 30 + periodSeconds: 10 + readiness: + enabled: true + failureThreshold: 10 + initialDelaySeconds: 30 + periodSeconds: 10 + startup: + enabled: false + failureThreshold: 30 + initialDelaySeconds: 60 + periodSeconds: 10 + affinity: + anti_affinity: true + annotations: {} + tolerations: [] + gracePeriod: 30 + resources: + requests: + memory: 512Mi + cpu: 0.2 ## 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:+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\"" + PULSAR_MEM: > + " + -Xms128m -Xmx256m -XX:MaxDirectMemorySize=256m + -Dio.netty.leakDetectionLevel=disabled + -Dio.netty.recycler.linkCapacity=1024 + -XX:+ParallelRefProcEnabled + -XX:+UnlockExperimentalVMOptions + -XX:+DoEscapeAnalysis + -XX:ParallelGCThreads=4 + -XX:ConcGCThreads=4 + -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 + usePolicy: true maxUnavailable: 1 - ## Broker rbac - ## templates/broker-rbac.yaml - ## - functions: - component: functions-worker -## Pulsar Extra: Proxy -## templates/proxy-deployment.yaml +## Pulsar: Functions Worker +## templates/function-worker-configmap.yaml +## +functions: + component: functions-worker + +## Pulsar: Proxy Cluster +## templates/proxy-statefulset.yaml ## proxy: + # use a component name that matches your grafana configuration + # so the metrics are correctly rendered in grafana dashboard component: proxy replicaCount: 3 # nodeSelector: # cloud.google.com/gke-nodepool: default-pool - annotations: - prometheus.io/scrape: "true" - prometheus.io/port: "8080" + probe: + liveness: + enabled: true + failureThreshold: 10 + initialDelaySeconds: 30 + periodSeconds: 10 + readiness: + enabled: true + failureThreshold: 10 + initialDelaySeconds: 30 + periodSeconds: 10 + startup: + enabled: false + failureThreshold: 30 + initialDelaySeconds: 60 + periodSeconds: 10 + affinity: + anti_affinity: true + annotations: {} tolerations: [] - gracePeriod: 0 + gracePeriod: 30 resources: requests: - memory: 4Gi - cpu: 1 + memory: 128Mi + cpu: 0.2 ## Proxy configmap ## templates/proxy-configmap.yaml ## configData: - PULSAR_MEM: "\"-Xms4g -Xmx4g -XX:MaxDirectMemorySize=4g\"" + PULSAR_MEM: > + " + -Xms64m -Xmx64m -XX:MaxDirectMemorySize=64m + -Dio.netty.leakDetectionLevel=disabled + -Dio.netty.recycler.linkCapacity=1024 + -XX:+ParallelRefProcEnabled + -XX:+UnlockExperimentalVMOptions + -XX:+DoEscapeAnalysis + -XX:ParallelGCThreads=4 + -XX:ConcGCThreads=4 + -XX:G1NewSizePercent=50 + -XX:+DisableExplicitGC + -XX:-ResizePLAB + -XX:+ExitOnOutOfMemoryError + -XX:+PerfDisableSharedMem + " + PULSAR_GC: > + " + -XX:+UseG1GC + -XX:MaxGCPauseMillis=10 + " ## Proxy service ## templates/proxy-service.yaml ## + ports: + http: 80 + https: 443 + pulsar: 6650 + pulsarssl: 6651 service: annotations: {} - type: NodePort - ports: - - name: http - port: 8080 - nodePort: 30001 - protocol: TCP - - name: tcp - port: 6650 - nodePort: 30002 - protocol: TCP + type: LoadBalancer ## Proxy PodDisruptionBudget ## templates/proxy-pdb.yaml ## pdb: - usePolicy: yes + usePolicy: true 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: {} - tolerations: [] - gracePeriod: 0 - resources: - requests: - memory: 1Gi - cpu: 250m - ## Bookkeeper auto-recovery configmap - ## templates/autorecovery-configmap.yaml - ## - configData: - BOOKIE_MEM: "\" -Xms1g -Xmx1g \"" - ## Pulsar Extra: Dashboard ## templates/dashboard-deployment.yaml ## Deprecated @@ -363,50 +741,65 @@ dashboard: port: 80 -## Pulsar Extra: Bastion -## templates/bastion-deployment.yaml +## Pulsar ToolSet +## templates/toolset-deployment.yaml ## -bastion: - component: bastion +toolset: + component: toolset + useProxy: true replicaCount: 1 # nodeSelector: # cloud.google.com/gke-nodepool: default-pool annotations: {} tolerations: [] - gracePeriod: 0 + gracePeriod: 30 resources: requests: - memory: 1Gi - cpu: 250m + memory: 256Mi + cpu: 0.1 ## Bastion configmap ## templates/bastion-configmap.yaml ## configData: - PULSAR_MEM: "\"-Xms1g -Xmx1g -XX:MaxDirectMemorySize=1g\"" + PULSAR_MEM: > + " + -Xms64M + -Xmx128M + -XX:MaxDirectMemorySize=128M + " + +############################################################# +### Monitoring Stack : Prometheus / Grafana +############################################################# ## Monitoring Stack: Prometheus ## templates/prometheus-deployment.yaml ## + +## Deprecated in favor of using `prometheus.rbac.enabled` +prometheus_rbac: false prometheus: component: prometheus + rbac: + enabled: true replicaCount: 1 # nodeSelector: # cloud.google.com/gke-nodepool: default-pool annotations: {} tolerations: [] - gracePeriod: 0 - image: - repository: prom/prometheus - tag: v1.6.3 - pullPolicy: IfNotPresent + gracePeriod: 5 + port: 9090 resources: requests: - memory: 4Gi - cpu: 1 + memory: 256Mi + cpu: 0.1 volumes: + # use a persistent volume or emptyDir + persistence: true data: name: data - size: 50Gi + size: 10Gi + local_storage: true ## If you already have an existent storage class and want to reuse it, you can specify its name with the option below ## # storageClassName: existent-storage-class @@ -423,9 +816,6 @@ prometheus: ## service: annotations: {} - ports: - - name: server - port: 9090 ## Monitoring Stack: Grafana ## templates/grafana-deployment.yaml @@ -437,23 +827,18 @@ grafana: # cloud.google.com/gke-nodepool: default-pool annotations: {} tolerations: [] - gracePeriod: 0 - image: - repository: apachepulsar/pulsar-grafana - tag: latest - pullPolicy: IfNotPresent + gracePeriod: 30 + port: 3000 resources: requests: - memory: 4Gi - cpu: 1 + memory: 250Mi + cpu: 0.1 ## Grafana service ## templates/grafana-service.yaml ## service: + type: LoadBalancer annotations: {} - ports: - - name: server - port: 3000 plugins: [] ## Grafana ingress ## templates/grafana-ingress.yaml @@ -470,7 +855,7 @@ grafana: tls: [] ## Optional. Leave it blank if your Ingress Controller can provide a default certificate. - #- secretName: "" + ## - secretName: "" ## Extra paths to prepend to every host configuration. This is useful when working with annotation based services. extraPaths: [] @@ -483,19 +868,15 @@ grafana: ## Components Stack: pulsar_manager ## templates/pulsar-manager.yaml ## - pulsar_manager: component: pulsar-manager + port: 9527 replicaCount: 1 # nodeSelector: # cloud.google.com/gke-nodepool: default-pool annotations: {} tolerations: [] - gracePeriod: 0 - image: - repository: apachepulsar/pulsar-manager - tag: v0.1.0 - pullPolicy: IfNotPresent + gracePeriod: 30 resources: requests: memory: 250Mi @@ -507,17 +888,14 @@ pulsar_manager: URL: jdbc:postgresql://127.0.0.1:5432/pulsar_manager LOG_LEVEL: DEBUG ## If you enabled authentication support - #JWT_TOKEN: - #SECRET_KEY: data:base64, + ## JWT_TOKEN: + ## SECRET_KEY: data:base64, ## Pulsar manager service ## templates/pulsar-manager-service.yaml ## service: type: LoadBalancer annotations: {} - ports: - - name: server - port: 9527 admin: user: pulsar password: pulsar diff --git a/scripts/cert-manager/install-cert-manager.sh b/scripts/cert-manager/install-cert-manager.sh new file mode 100755 index 0000000..5670b92 --- /dev/null +++ b/scripts/cert-manager/install-cert-manager.sh @@ -0,0 +1,55 @@ +# +# 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. +# + +#!/usr/bin/env bash + +NAMESPACE=cert-manager +NAME=cert-manager +VERSION=v0.13.0 + +# Install cert-manager CustomResourceDefinition resources +echo "Installing cert-manager CRD resources ..." +kubectl apply --validate=false -f https://raw.githubusercontent.com/jetstack/cert-manager/${VERSION}/deploy/manifests/00-crds.yaml + +# Create the namespace +kubectl get ns ${NAMESPACE} +if [ $? == 0 ]; then + echo "Namespace '${NAMESPACE}' already exists." +else + echo "Creating namespace '${NAMESPACE}' ..." + kubectl create namespace ${NAMESPACE} + echo "Successfully created namespace '${NAMESPACE}'." +fi + +# Add the Jetstack Helm repository. +echo "Adding Jetstack Helm repository." +helm repo add jetstack https://charts.jetstack.io +echo "Successfully added Jetstack Helm repository." + +# Update local helm chart repository cache. +echo "Updating local helm chart repository cache ..." +helm repo update + +echo "Installing cert-manager ${VERSION} to namespace ${NAMESPACE} as '${NAME}' ..." +helm install \ + --namespace ${NAMESPACE} \ + --version ${VERSION} \ + ${NAME} \ + jetstack/cert-manager +echo "Successfully installed cert-manager ${VERSION}." \ No newline at end of file diff --git a/scripts/pulsar/clean_tls.sh b/scripts/pulsar/clean_tls.sh new file mode 100755 index 0000000..8dba53d --- /dev/null +++ b/scripts/pulsar/clean_tls.sh @@ -0,0 +1,115 @@ +#!/usr/bin/env bash +# +# 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. +# + +set -e + +CHART_HOME=$(unset CDPATH && cd $(dirname "${BASH_SOURCE[0]}")/../.. && pwd) +cd ${CHART_HOME} + +namespace=${namespace:-pulsar} +release=${release:-pulsar-dev} +clientComponents=${clientComponents:-"toolset"} +serverComponents=${serverComponents:-"bookie,broker,proxy,recovery,zookeeper"} + +usage() { + cat <&2 "${tool} is required. Please follow ${url}" + exit 1 +} + +function need_gcloud(){ + need_tool "gcloud" "https://cloud.google.com/sdk/downloads" +} + +function need_kubectl(){ + need_tool "kubectl" "https://kubernetes.io/docs/tasks/tools/install-kubectl" +} + +function need_helm(){ + need_tool "helm" "https://github.com/helm/helm/#install" +} + +function need_eksctl(){ + need_tool "eksctl" "https://eksctl.io" +} + +function validate_gke_required_tools(){ + if [ -z "$PROJECT" ]; then + echo "\$PROJECT needs to be set to your project id"; + exit 1; + fi + + for comm in gcloud kubectl helm + do + command -v "${comm}" > /dev/null 2>&1 || "need_${comm}" + done + + gcloud container clusters list --project $PROJECT >/dev/null 2>&1 || { echo >&2 "Gcloud seems to be configured incorrectly or authentication is unsuccessfull"; exit 1; } + +} + +function cluster_admin_password_gke(){ + gcloud container clusters describe $CLUSTER_NAME --zone $ZONE --project $PROJECT --format='value(masterAuth.password)'; +} + +function validate_eks_required_tools(){ + for comm in eksctl kubectl helm + do + command -v "${comm}" > /dev/null 2>&1 || "need_${comm}" + done +} diff --git a/scripts/pulsar/common_auth.sh b/scripts/pulsar/common_auth.sh new file mode 100755 index 0000000..b9d3aba --- /dev/null +++ b/scripts/pulsar/common_auth.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash +# +# 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 [ -z "$CHART_HOME" ]; then + echo "error: CHART_HOME should be initialized" + exit 1 +fi + +OUTPUT=${CHART_HOME}/output +OUTPUT_BIN=${OUTPUT}/bin +PULSARCTL_VERSION=v0.4.0 +PULSARCTL_BIN=${HOME}/.pulsarctl/pulsarctl +export PATH=${HOME}/.pulsarctl/plugins:${PATH} + +discoverArch() { + ARCH=$(uname -m) + case $ARCH in + x86) ARCH="386";; + x86_64) ARCH="amd64";; + i686) ARCH="386";; + i386) ARCH="386";; + esac +} + +discoverArch +OS=$(echo `uname`|tr '[:upper:]' '[:lower:]') + +test -d "$OUTPUT_BIN" || mkdir -p "$OUTPUT_BIN" + +function pulsar::verify_pulsarctl() { + if test -x "$PULSARCTL_BIN"; then + return + fi + return 1 +} + +function pulsar::ensure_pulsarctl() { + if pulsar::verify_pulsarctl; then + return 0 + fi + echo "Get pulsarctl install.sh script ..." + install_script=$(mktemp) + trap "test -f $install_script && rm $install_script" RETURN + curl --retry 10 -L -o $install_script https://raw.githubusercontent.com/streamnative/pulsarctl/master/install.sh + chmod +x $install_script + $install_script --user --version ${PULSARCTL_VERSION} +} + + diff --git a/scripts/pulsar/generate_token.sh b/scripts/pulsar/generate_token.sh new file mode 100755 index 0000000..b152bf1 --- /dev/null +++ b/scripts/pulsar/generate_token.sh @@ -0,0 +1,121 @@ +#!/usr/bin/env bash +# +# 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. +# + +set -e + +CHART_HOME=$(unset CDPATH && cd $(dirname "${BASH_SOURCE[0]}")/../.. && pwd) +cd ${CHART_HOME} + +usage() { + cat < +EOF +} + +symmetric=false + +while [[ $# -gt 0 ]] +do +key="$1" + +case $key in + -n|--namespace) + namespace="$2" + shift + shift + ;; + -k|--release) + release="$2" + shift + shift + ;; + -r|--role) + role="$2" + shift + shift + ;; + -s|--symmetric) + symmetric=true + shift + ;; + -h|--help) + usage + exit 0 + ;; + *) + echo "unknown option: $key" + usage + exit 1 + ;; +esac +done + +if [[ "x${role}" == "x" ]]; then + echo "No pulsar role is provided!" + usage + exit 1 +fi + +source ${CHART_HOME}/scripts/pulsar/common_auth.sh + +pulsar::ensure_pulsarctl + +namespace=${namespace:-pulsar} +release=${release:-pulsar-dev} + +function pulsar::jwt::generate_symmetric_token() { + local token_name="${release}-token-${role}" + local secret_name="${release}-token-symmetric-key" + + tmpfile=$(mktemp) + trap "test -f $tmpfile && rm $tmpfile" RETURN + tokentmpfile=$(mktemp) + trap "test -f $tokentmpfile && rm $tokentmpfile" RETURN + kubectl get -n ${namespace} secrets ${secret_name} -o jsonpath="{.data['SECRETKEY']}" | base64 --decode > ${tmpfile} + ${PULSARCTL_BIN} token create -a HS256 --secret-key-file ${tmpfile} --subject ${role} 2&> ${tokentmpfile} + kubectl create secret generic ${token_name} -n ${namespace} --from-file="TOKEN=${tokentmpfile}" --from-literal="TYPE=symmetric" +} + +function pulsar::jwt::generate_asymmetric_token() { + local token_name="${release}-token-${role}" + local secret_name="${release}-token-asymmetric-key" + + privatekeytmpfile=$(mktemp) + trap "test -f $privatekeytmpfile && rm $privatekeytmpfile" RETURN + tokentmpfile=$(mktemp) + trap "test -f $tokentmpfile && rm $tokentmpfile" RETURN + kubectl get -n ${namespace} secrets ${secret_name} -o jsonpath="{.data['PRIVATEKEY']}" | base64 --decode > ${privatekeytmpfile} + ${PULSARCTL_BIN} token create -a RS256 --private-key-file ${privatekeytmpfile} --subject ${role} 2&> ${tokentmpfile} + kubectl create secret generic ${token_name} -n ${namespace} --from-file="TOKEN=${tokentmpfile}" --from-literal="TYPE=asymmetric" +} + +if [[ "${symmetric}" == "true" ]]; then + pulsar::jwt::generate_symmetric_token +else + pulsar::jwt::generate_asymmetric_token +fi diff --git a/scripts/pulsar/generate_token_secret_key.sh b/scripts/pulsar/generate_token_secret_key.sh new file mode 100755 index 0000000..be2f76e --- /dev/null +++ b/scripts/pulsar/generate_token_secret_key.sh @@ -0,0 +1,109 @@ +#!/usr/bin/env bash +# +# 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. +# + +set -e + +CHART_HOME=$(unset CDPATH && cd $(dirname "${BASH_SOURCE[0]}")/../.. && pwd) +cd ${CHART_HOME} + +usage() { + cat < +EOF +} + +while [[ $# -gt 0 ]] +do +key="$1" + +case $key in + -n|--namespace) + namespace="$2" + shift + shift + ;; + -k|--release) + release="$2" + shift + shift + ;; + -r|--role) + role="$2" + shift + shift + ;; + -h|--help) + usage + exit 0 + ;; + *) + echo "unknown option: $key" + usage + exit 1 + ;; +esac +done + +if [[ "x${role}" == "x" ]]; then + echo "No pulsar role is provided!" + usage + exit 1 +fi + +source ${CHART_HOME}/scripts/pulsar/common_auth.sh + +pulsar::ensure_pulsarctl + +namespace=${namespace:-pulsar} +release=${release:-pulsar-dev} + +function pulsar::jwt::get_token() { + local token_name="${release}-token-${role}" + + local token=$(kubectl get -n ${namespace} secrets ${token_name} -o jsonpath="{.data['TOKEN']}" | base64 --decode) + local token_type=$(kubectl get -n ${namespace} secrets ${token_name} -o jsonpath="{.data['TYPE']}" | base64 --decode) + + echo "token type: ${token_type}" + echo "-------------------------" + echo "${token}" +} + +pulsar::jwt::get_token diff --git a/scripts/pulsar/prepare_helm_release.sh b/scripts/pulsar/prepare_helm_release.sh new file mode 100755 index 0000000..a174bc8 --- /dev/null +++ b/scripts/pulsar/prepare_helm_release.sh @@ -0,0 +1,155 @@ +#!/usr/bin/env bash +# +# 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. +# + +CHART_HOME=$(unset CDPATH && cd $(dirname "${BASH_SOURCE[0]}")/../.. && pwd) +cd ${CHART_HOME} + +usage() { + cat <