From c47c259f0644b7e5b9c3645758e4680164304ce2 Mon Sep 17 00:00:00 2001 From: Andrew Block Date: Tue, 4 Nov 2025 09:52:24 -0600 Subject: [PATCH] Added Helm chart Signed-off-by: Andrew Block --- .gitignore | 1 + README.md | 4 + charts/kubernetes-mcp-server/.helmignore | 23 ++++ charts/kubernetes-mcp-server/Chart.yaml | 13 ++ charts/kubernetes-mcp-server/README.md | 76 +++++++++++ charts/kubernetes-mcp-server/README.md.gotpl | 40 ++++++ .../templates/_helpers.tpl | 73 +++++++++++ .../templates/configmap.yaml | 10 ++ .../templates/deployment.yaml | 85 ++++++++++++ .../templates/ingress.yaml | 38 ++++++ .../templates/service.yaml | 16 +++ .../templates/serviceaccount.yaml | 13 ++ charts/kubernetes-mcp-server/values.yaml | 121 ++++++++++++++++++ 13 files changed, 513 insertions(+) create mode 100644 charts/kubernetes-mcp-server/.helmignore create mode 100644 charts/kubernetes-mcp-server/Chart.yaml create mode 100644 charts/kubernetes-mcp-server/README.md create mode 100644 charts/kubernetes-mcp-server/README.md.gotpl create mode 100644 charts/kubernetes-mcp-server/templates/_helpers.tpl create mode 100644 charts/kubernetes-mcp-server/templates/configmap.yaml create mode 100644 charts/kubernetes-mcp-server/templates/deployment.yaml create mode 100644 charts/kubernetes-mcp-server/templates/ingress.yaml create mode 100644 charts/kubernetes-mcp-server/templates/service.yaml create mode 100644 charts/kubernetes-mcp-server/templates/serviceaccount.yaml create mode 100644 charts/kubernetes-mcp-server/values.yaml diff --git a/.gitignore b/.gitignore index 12b624e7..4efe7690 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ node_modules/ .npmrc kubernetes-mcp-server +!charts/kubernetes-mcp-server !cmd/kubernetes-mcp-server !pkg/kubernetes-mcp-server npm/kubernetes-mcp-server/README.md diff --git a/README.md b/README.md index 4c916af9..fb71ea9f 100644 --- a/README.md +++ b/README.md @@ -342,6 +342,10 @@ In case multi-cluster support is enabled (default) and you have access to multip +## Helm Chart + +A [Helm Chart](https://helm.sh) is available to simplify the deployment of the Kubernetes MCP server. Additional details can be found in he [chart README](./charts/kubernetes-mcp-server/README.md). + ## 🧑‍💻 Development ### Running with mcp-inspector diff --git a/charts/kubernetes-mcp-server/.helmignore b/charts/kubernetes-mcp-server/.helmignore new file mode 100644 index 00000000..0e8a0eb3 --- /dev/null +++ b/charts/kubernetes-mcp-server/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/charts/kubernetes-mcp-server/Chart.yaml b/charts/kubernetes-mcp-server/Chart.yaml new file mode 100644 index 00000000..a66650bb --- /dev/null +++ b/charts/kubernetes-mcp-server/Chart.yaml @@ -0,0 +1,13 @@ +apiVersion: v2 +name: kubernetes-mcp-server +description: Helm Chart for the Kubernetes MCP Server +home: https://github.com/containers/kubernetes-mcp-server +keywords: + - kubernetes + - mcp +maintainers: + - name: Andrew Block + email: ablock@redhat.com + - name: Marc Nuri + email: marc.nuri@redhat.com +version: 0.1.0 diff --git a/charts/kubernetes-mcp-server/README.md b/charts/kubernetes-mcp-server/README.md new file mode 100644 index 00000000..f20b7fbc --- /dev/null +++ b/charts/kubernetes-mcp-server/README.md @@ -0,0 +1,76 @@ +# kubernetes-mcp-server + +![Version: 0.1.0](https://img.shields.io/badge/Version-0.1.0-informational?style=flat-square) + +Helm Chart for the Kubernetes MCP Server + +**Homepage:** + +## Maintainers + +| Name | Email | Url | +| ---- | ------ | --- | +| Andrew Block | | | +| Marc Nuri | | | + +## Installing the Chart + +The Chart can be installed quickly and easily to a Kubernetes cluster. Since an _Ingress_ is added as part of the default install of the Chart, the `ingress.host` Value must be specified. + +Install the Chart using the following command from the root of this directory: + +```shell +helm upgrade -i -n kubernetes-mcp-server --create-namespace kubernetes-mcp-server . --set openshift=true --set ingress.host= +``` + +### Optimized OpenShift Deployment + +Functionality has bee added to the Chart to simplify the deployment to OpenShift Cluster. + +## Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| affinity | object | `{}` | | +| config.port | string | `"{{ .Values.service.port }}"` | | +| configFilePath | string | `"/etc/kubernetes-mcp-server/config.toml"` | | +| defaultPodSecurityContext | object | `{"seccompProfile":{"type":"RuntimeDefault"}}` | Default Security Context for the Pod when one is not provided | +| defaultSecurityContext | object | `{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"runAsNonRoot":true}` | Default Security Context for the Container when one is not provided | +| extraVolumeMounts | list | `[]` | Additional volumeMounts on the output Deployment definition. | +| extraVolumes | list | `[]` | Additional volumes on the output Deployment definition. | +| fullnameOverride | string | `""` | | +| image | object | `{"pullPolicy":"IfNotPresent","registry":"quay.io","repository":"manusa/kubernetes_mcp_server","version":"latest"}` | This sets the container image more information can be found here: https://kubernetes.io/docs/concepts/containers/images/ | +| image.pullPolicy | string | `"IfNotPresent"` | This sets the pull policy for images. | +| image.version | string | `"latest"` | This sets the tag or sha digest for the image. | +| imagePullSecrets | list | `[]` | This is for the secrets for pulling an image from a private repository more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ | +| ingress | object | `{"annotations":{},"className":"","enabled":true,"host":"","hosts":null,"path":"/","pathType":"ImplementationSpecific","termination":"edge","tls":null}` | This block is for setting up the ingress for more information can be found here: https://kubernetes.io/docs/concepts/services-networking/ingress/ | +| livenessProbe | object | `{"httpGet":{"path":"/healthz","port":"http"}}` | Liveness and readiness probes for the container. | +| nameOverride | string | `""` | | +| nodeSelector | object | `{}` | | +| openshift | bool | `false` | Enable OpenShift specific features | +| podAnnotations | object | `{}` | For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ | +| podLabels | object | `{}` | For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ | +| podSecurityContext | object | `{}` | Define the Security Context for the Pod | +| readinessProbe.httpGet.path | string | `"/healthz"` | | +| readinessProbe.httpGet.port | string | `"http"` | | +| replicaCount | int | `1` | This will set the replicaset count more information can be found here: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/ | +| resources | object | `{"limits":{"cpu":"100m","memory":"128Mi"},"requests":{"cpu":"100m","memory":"128Mi"}}` | Resource requests and limits for the container. | +| securityContext | object | `{}` | Define the Security Context for the Container | +| service | object | `{"port":8080,"type":"ClusterIP"}` | This is for setting up a service more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/ | +| service.port | int | `8080` | This sets the ports more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#field-spec-ports | +| service.type | string | `"ClusterIP"` | This sets the service type more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types | +| serviceAccount | object | `{"annotations":{},"create":true,"name":""}` | This section builds out the service account more information can be found here: https://kubernetes.io/docs/concepts/security/service-accounts/ | +| serviceAccount.annotations | object | `{}` | Annotations to add to the service account | +| serviceAccount.create | bool | `true` | Specifies whether a service account should be created | +| serviceAccount.name | string | `""` | If not set and create is true, a name is generated using the fullname template | +| tolerations | list | `[]` | | + +## Updating the README + +The contents of the README.md file is generated using [helm-docs](https://github.com/norwoodj/helm-docs). Whenever changes are introduced to the Chart and its _Values_, the documentation should be regenerated. + +Execute the following command to regenerate the documentation from within the Helm Chart directory. + +```shell +helm-docs -t README.md.gotpl +``` diff --git a/charts/kubernetes-mcp-server/README.md.gotpl b/charts/kubernetes-mcp-server/README.md.gotpl new file mode 100644 index 00000000..9e6ba772 --- /dev/null +++ b/charts/kubernetes-mcp-server/README.md.gotpl @@ -0,0 +1,40 @@ +{{ template "chart.header" . }} +{{ template "chart.deprecationWarning" . }} + +{{ template "chart.badgesSection" . }} + +{{ template "chart.description" . }} + +{{ template "chart.homepageLine" . }} + +{{ template "chart.maintainersSection" . }} + +{{ template "chart.sourcesSection" . }} + +{{ template "chart.requirementsSection" . }} + +## Installing the Chart + +The Chart can be installed quickly and easily to a Kubernetes cluster. Since an _Ingress_ is added as part of the default install of the Chart, the `ingress.host` Value must be specified. + +Install the Chart using the following command from the root of this directory: + +```shell +helm upgrade -i -n kubernetes-mcp-server --create-namespace kubernetes-mcp-server . --set openshift=true --set ingress.host= +``` + +### Optimized OpenShift Deployment + +Functionality has bee added to the Chart to simplify the deployment to OpenShift Cluster. + +{{ template "chart.valuesSection" . }} + +## Updating the README + +The contents of the README.md file is generated using [helm-docs](https://github.com/norwoodj/helm-docs). Whenever changes are introduced to the Chart and its _Values_, the documentation should be regenerated. + +Execute the following command to regenerate the documentation from within the Helm Chart directory. + +```shell +helm-docs -t README.md.gotpl +``` diff --git a/charts/kubernetes-mcp-server/templates/_helpers.tpl b/charts/kubernetes-mcp-server/templates/_helpers.tpl new file mode 100644 index 00000000..991c9331 --- /dev/null +++ b/charts/kubernetes-mcp-server/templates/_helpers.tpl @@ -0,0 +1,73 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "kubernetes-mcp-server.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "kubernetes-mcp-server.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "kubernetes-mcp-server.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "kubernetes-mcp-server.labels" -}} +helm.sh/chart: {{ include "kubernetes-mcp-server.chart" . }} +{{ include "kubernetes-mcp-server.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "kubernetes-mcp-server.selectorLabels" -}} +app.kubernetes.io/name: {{ include "kubernetes-mcp-server.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "kubernetes-mcp-server.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "kubernetes-mcp-server.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +Create the image path for the passed in image field +*/}} +{{- define "kubernetes-mcp-server.image" -}} +{{- if eq (substr 0 7 .version) "sha256:" -}} +{{- printf "%s/%s@%s" .registry .repository .version -}} +{{- else -}} +{{- printf "%s/%s:%s" .registry .repository .version -}} +{{- end -}} +{{- end -}} diff --git a/charts/kubernetes-mcp-server/templates/configmap.yaml b/charts/kubernetes-mcp-server/templates/configmap.yaml new file mode 100644 index 00000000..9d066b35 --- /dev/null +++ b/charts/kubernetes-mcp-server/templates/configmap.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "kubernetes-mcp-server.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "kubernetes-mcp-server.labels" . | nindent 4 }} +data: + config.toml: | + {{- tpl (toToml .Values.config) . | replace ".0" "" | nindent 4 }} diff --git a/charts/kubernetes-mcp-server/templates/deployment.yaml b/charts/kubernetes-mcp-server/templates/deployment.yaml new file mode 100644 index 00000000..e6bc8a34 --- /dev/null +++ b/charts/kubernetes-mcp-server/templates/deployment.yaml @@ -0,0 +1,85 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "kubernetes-mcp-server.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "kubernetes-mcp-server.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + {{- include "kubernetes-mcp-server.selectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} + {{- with .Values.podAnnotations }} + {{- tpl (toYaml .) . | nindent 8 }} + {{- end }} + labels: + {{- include "kubernetes-mcp-server.labels" . | nindent 8 }} + {{- with .Values.podLabels }} + {{- tpl (toYaml .) . | nindent 8 }} + {{- end }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- tpl (toYaml .) . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "kubernetes-mcp-server.serviceAccountName" . }} + securityContext: + {{- tpl (toYaml (default .Values.defaultPodSecurityContext .Values.podSecurityContext)) . | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- tpl (toYaml (default .Values.defaultSecurityContext .Values.securityContext)) . | nindent 12 }} + image: "{{ template "kubernetes-mcp-server.image" .Values.image }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - name: http + containerPort: {{ .Values.service.port }} + protocol: TCP + args: + - "--config" + - "{{ .Values.configFilePath }}" + {{- with .Values.livenessProbe }} + livenessProbe: + {{- tpl (toYaml .) . | nindent 12 }} + {{- end }} + {{- with .Values.readinessProbe }} + readinessProbe: + {{- tpl (toYaml .) . | nindent 12 }} + {{- end }} + {{- with .Values.resources }} + resources: + {{- tpl (toYaml .) . | nindent 12 }} + {{- end }} + volumeMounts: + - name: config + mountPath: {{ .Values.configFilePath | dir }} + {{- with .Values.extraVolumeMounts }} + {{- tpl (toYaml .) . | nindent 12 }} + {{- end }} + {{- with .Values.extraVolumeMounts }} + {{- tpl (toYaml .) . | nindent 12 }} + {{- end }} + volumes: + - name: config + configMap: + name: {{ include "kubernetes-mcp-server.fullname" . }} + {{- with .Values.extraVolumes }} + {{- tpl (toYaml .) . | nindent 8 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- tpl (toYaml .) . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- tpl (toYaml .) . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- tpl (toYaml .) . | nindent 8 }} + {{- end }} diff --git a/charts/kubernetes-mcp-server/templates/ingress.yaml b/charts/kubernetes-mcp-server/templates/ingress.yaml new file mode 100644 index 00000000..e6179fcb --- /dev/null +++ b/charts/kubernetes-mcp-server/templates/ingress.yaml @@ -0,0 +1,38 @@ +{{- if .Values.ingress.enabled -}} +{{- $host := required "Ingress hostname must be specified" (tpl .Values.ingress.host .) }} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ include "kubernetes-mcp-server.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "kubernetes-mcp-server.labels" . | nindent 4 }} + annotations: + {{- if eq .Values.openshift true }} + route.openshift.io/termination: {{ .Values.ingress.termination }} + {{- end }} + {{- with .Values.ingress.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- with .Values.ingress.className }} + ingressClassName: {{ . }} + {{- end }} + {{- if .Values.ingress.tls }} + tls: + - hosts: + - "{{ $host }}" + secretName: {{ .Values.ingress.tls.secretName }} + {{- end }} + rules: + - host: "{{ $host }}" + http: + paths: + - path: {{ .Values.ingress.path }} + pathType: {{ .Values.ingress.pathType }} + backend: + service: + name: {{ include "kubernetes-mcp-server.fullname" $ }} + port: + number: {{ $.Values.service.port }} +{{- end }} diff --git a/charts/kubernetes-mcp-server/templates/service.yaml b/charts/kubernetes-mcp-server/templates/service.yaml new file mode 100644 index 00000000..20bccf21 --- /dev/null +++ b/charts/kubernetes-mcp-server/templates/service.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "kubernetes-mcp-server.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "kubernetes-mcp-server.labels" . | nindent 4 }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: http + protocol: TCP + name: http + selector: + {{- include "kubernetes-mcp-server.selectorLabels" . | nindent 4 }} diff --git a/charts/kubernetes-mcp-server/templates/serviceaccount.yaml b/charts/kubernetes-mcp-server/templates/serviceaccount.yaml new file mode 100644 index 00000000..b75f47bf --- /dev/null +++ b/charts/kubernetes-mcp-server/templates/serviceaccount.yaml @@ -0,0 +1,13 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "kubernetes-mcp-server.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "kubernetes-mcp-server.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- tpl (toYaml .) . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/kubernetes-mcp-server/values.yaml b/charts/kubernetes-mcp-server/values.yaml new file mode 100644 index 00000000..64f5fc6a --- /dev/null +++ b/charts/kubernetes-mcp-server/values.yaml @@ -0,0 +1,121 @@ +# -- Enable OpenShift specific features +openshift: false + +# -- This will set the replicaset count more information can be found here: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/ +replicaCount: 1 + +# -- This sets the container image more information can be found here: https://kubernetes.io/docs/concepts/containers/images/ +image: + registry: quay.io + repository: manusa/kubernetes_mcp_server + # -- This sets the tag or sha digest for the image. + version: latest + # -- This sets the pull policy for images. + pullPolicy: IfNotPresent + +# -- This is for the secrets for pulling an image from a private repository more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ +imagePullSecrets: [] +# This is to override the chart name. +nameOverride: "" +fullnameOverride: "" + +# -- This section builds out the service account more information can be found here: https://kubernetes.io/docs/concepts/security/service-accounts/ +serviceAccount: + # -- Specifies whether a service account should be created + create: true + # -- Annotations to add to the service account + annotations: {} + # -- The name of the service account to use. + # -- If not set and create is true, a name is generated using the fullname template + name: "" + +# -- This is for setting Kubernetes Annotations to a Pod. +# -- For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ +podAnnotations: {} +# -- This is for setting Kubernetes Labels to a Pod. +# -- For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ +podLabels: {} + +# -- Default Security Context for the Pod when one is not provided +defaultPodSecurityContext: + seccompProfile: + type: RuntimeDefault + +# -- Define the Security Context for the Pod +podSecurityContext: {} + +# -- Default Security Context for the Container when one is not provided +defaultSecurityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + runAsNonRoot: true + +# -- Define the Security Context for the Container +securityContext: {} + +# -- This is for setting up a service more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/ +service: + # -- This sets the service type more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: ClusterIP + # -- This sets the ports more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#field-spec-ports + port: 8080 + +# -- This block is for setting up the ingress for more information can be found here: https://kubernetes.io/docs/concepts/services-networking/ingress/ +ingress: + enabled: true + className: "" + annotations: {} + host: "" + path: / + pathType: ImplementationSpecific + termination: edge + hosts: + tls: + #secretName: "" + +# -- Resource requests and limits for the container. +resources: + limits: + cpu: 100m + memory: 128Mi + requests: + cpu: 100m + memory: 128Mi + +# -- Liveness and readiness probes for the container. +livenessProbe: + httpGet: + path: /healthz + port: http +readinessProbe: + httpGet: + path: /healthz + port: http + +# -- Additional volumes on the output Deployment definition. +extraVolumes: [] +# - name: foo +# secret: +# secretName: mysecret +# optional: false + +# -- Additional volumeMounts on the output Deployment definition. +extraVolumeMounts: [] +# - name: foo +# mountPath: "/etc/foo" +# readOnly: true + +nodeSelector: {} + +tolerations: [] + +affinity: {} + +# Path to the configuration file inside the container +configFilePath: /etc/kubernetes-mcp-server/config.toml + +# MCP Server configuration options. See https://github.com/containers/kubernetes-mcp-server/blob/main/pkg/config/config.go for details. +config: + port: "{{ .Values.service.port }}"