diff --git a/.github/workflows/release-zookeeper-ghcr.yml b/.github/workflows/release-zookeeper-ghcr.yml new file mode 100644 index 00000000..32085dd8 --- /dev/null +++ b/.github/workflows/release-zookeeper-ghcr.yml @@ -0,0 +1,61 @@ +name: Release Zookeeper Chart to GHCR + +# Publishes the zookeeper chart to ghcr.io/radiantlogic-devops/helm/zookeeper-dev +# as an OCI artifact. This is the dev-channel counterpart to the GitHub Pages +# helm repository at https://radiantlogic-devops.github.io/helm/ and allows +# consumers (e.g. helm-v8 fid chart dependency) to pull feature-branch builds +# directly without waiting for a master merge. +# +# Trigger model: +# - push to master -> publishes with the Chart.yaml version +# - workflow_dispatch -> can be run manually from any branch to produce a +# testable OCI artifact tagged with that branch's +# Chart.yaml version (overwrites if same version). +# +# To test a feature branch: +# 1. Bump charts/zookeeper/Chart.yaml version (e.g. 0.1.7-my-feature) +# 2. Push the branch +# 3. Manually trigger this workflow on that branch +# 4. helm pull oci://ghcr.io/radiantlogic-devops/helm/zookeeper-dev --version + +on: + push: + branches: + - master + paths: + - 'charts/zookeeper/**' + - '.github/workflows/release-zookeeper-ghcr.yml' + workflow_dispatch: + +jobs: + release-ghcr: + permissions: + contents: read + packages: write + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Read zookeeper chart version + uses: mikefarah/yq@master + id: read_zk_chart + with: + cmd: yq '.version' charts/zookeeper/Chart.yaml + + - name: Publish zookeeper chart to GHCR + uses: appany/helm-oci-chart-releaser@v0.4.1 + with: + name: zookeeper-dev + repository: helm + tag: ${{ steps.read_zk_chart.outputs.result }} + registry: ghcr.io/${{ github.repository_owner }} + path: charts/zookeeper + registry_username: ${{ github.actor }} + registry_password: ${{ secrets.GITHUB_TOKEN }} + update_dependencies: 'false' + + # Consumers can pull with: + # helm pull oci://ghcr.io/radiantlogic-devops/helm/zookeeper-dev --version diff --git a/charts/zookeeper/Chart.yaml b/charts/zookeeper/Chart.yaml index f57a9d74..d50f0d2f 100644 --- a/charts/zookeeper/Chart.yaml +++ b/charts/zookeeper/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.6 +version: 0.1.7 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to diff --git a/charts/zookeeper/templates/service.yaml b/charts/zookeeper/templates/service.yaml index c4230b8b..dbdf4f37 100644 --- a/charts/zookeeper/templates/service.yaml +++ b/charts/zookeeper/templates/service.yaml @@ -8,6 +8,11 @@ spec: type: {{ .Values.service.type }} {{- if contains "ClusterIP" .Values.service.type }} clusterIP: None + # Required for StatefulSet pod-DNS resolution during cluster bootstrap. + # ZK pods need DNS for sibling pods (zookeeper-0,1,2) BEFORE they are Ready + # so they can form a quorum. Without this, K8s 1.22+ EndpointSlice handling + # withholds DNS records until pods are Ready -> chicken-and-egg deadlock. + publishNotReadyAddresses: true {{- end }} ports: - port: {{ .Values.service.port }} diff --git a/charts/zookeeper/templates/statefulset.yaml b/charts/zookeeper/templates/statefulset.yaml index 412810ea..77e27fa2 100644 --- a/charts/zookeeper/templates/statefulset.yaml +++ b/charts/zookeeper/templates/statefulset.yaml @@ -88,7 +88,14 @@ spec: command: ["/bin/sh","-c"] args: ["/opt/radiantone/run.sh"] {{- end }} -{{- if .Values.metrics.enabled }} +{{- /* + Sidecar container spawns if EITHER metrics.enabled or metrics.fluentd.enabled is true. + The two subsystems are independent: + - metrics.enabled=true → zookeeper-exporter Go binary runs (pull-mode at :9095) + - metrics.enabled + pushMode → additionally pushes to Pushgateway via cron + - metrics.fluentd.enabled → Fluentd runs for log forwarding (no dependency on metrics.enabled) +*/}} +{{- if or .Values.metrics.enabled .Values.metrics.fluentd.enabled }} - name: {{ .Chart.Name }}-exporter image: {{ .Values.metrics.image }}:{{ .Values.metrics.imageTag }} imagePullPolicy: {{ .Values.image.pullPolicy }} @@ -99,30 +106,33 @@ spec: requests: cpu: 100m memory: 128Mi +{{- if .Values.metrics.enabled }} ports: - containerPort: 9095 name: exporter +{{- end }} volumeMounts: - name: zk-pvc mountPath: /opt/radiantone/rli-zookeeper-external -{{- if eq .Values.metrics.fluentd.enabled true }} +{{- if .Values.metrics.fluentd.enabled }} - name: fluentd-config-volume mountPath: /fluentd/etc {{- end }} securityContext: runAsUser: 0 env: +{{- if .Values.metrics.enabled }} - name: ZK_CONN value: {{ .Values.metrics.zk_conn | quote }} - name: PUSH_MODE value: {{ .Values.metrics.pushMode | quote }} - name: PUSHGATEWAY_URI value: {{ .Values.metrics.pushGateway | quote }} - - name: JOB_NAME - value: {{ .Release.Namespace | quote }} - name: METRICS_PORT value: '9095' -{{- if hasKey .Values.metrics.fluentd "enabled" }} +{{- end }} + - name: JOB_NAME + value: {{ .Release.Namespace | quote }} {{- if .Values.metrics.fluentd.enabled }} - name: FLUENTD_ENABLE value: {{ .Values.metrics.fluentd.enabled | quote }} @@ -133,7 +143,6 @@ spec: - name: ELASTICSEARCH_TYPE value: {{ .Values.metrics.fluentd.elasticSearchType | default "elasticsearch" | quote }} {{- end }} -{{- end }} {{- end }} {{- with .Values.nodeSelector }} nodeSelector: diff --git a/charts/zookeeper/values.yaml b/charts/zookeeper/values.yaml index 69a4a5ba..b71c2382 100644 --- a/charts/zookeeper/values.yaml +++ b/charts/zookeeper/values.yaml @@ -103,14 +103,26 @@ persistence: metrics: + # Controls the zk-exporter sidecar. Two independent subsystems: + # metrics.enabled=true -> zookeeper-exporter Go binary runs, + # serving pull-mode metrics at :9095/metrics + # metrics.enabled + pushMode -> additionally pushes to Pushgateway via cron + # metrics.fluentd.enabled -> Fluentd runs independently for log forwarding + # The sidecar container spawns if EITHER metrics.enabled or fluentd.enabled is true. enabled: false image: radiantone/zk-exporter imageTag: latest zk_conn: localhost:2181 + # NOTE: this securityContext is currently unused by the template — the sidecar + # uses the runtime default user (uid 1000 from Dockerfile USER fluent). + # Left for future wiring. securityContext: runAsUser: 0 annotations: {} - pushMode: true + # pushMode: false by default. Only enable when a reachable Pushgateway exists. + # The exporter exits with code 1 after a 300s Pushgateway timeout, causing + # CrashLoopBackOff if pushMode=true but PUSHGATEWAY_URI is unreachable. + pushMode: false pushGateway: http://prometheus-pushgateway:9091 pushMetricCron: "* * * * *" fluentd: