From f4cb691b05f2c3ba6bb99f7456b19167182d5e76 Mon Sep 17 00:00:00 2001 From: Isaac Johnson Date: Fri, 24 Jul 2026 07:01:49 -0500 Subject: [PATCH] add secret, install instructions --- INSTALL.md | 152 +++++++++++++++++++++++++++ helm-chart/INSTALL.md | 79 +++++++++++++- helm-chart/templates/_helpers.tpl | 12 +++ helm-chart/templates/deployment.yaml | 24 ++++- helm-chart/templates/secret.yaml | 12 +++ helm-chart/values.yaml | 16 +++ version.ini | 2 +- 7 files changed, 291 insertions(+), 6 deletions(-) create mode 100644 INSTALL.md create mode 100644 helm-chart/templates/secret.yaml diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 0000000..0c77e31 --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,152 @@ +# k8s-pulse Helm Chart Installation Guide + +This guide provides instructions on installing **k8s-pulse** using Helm and configuring the `kubeconfig` secret to match the container setup in `docker-compose.yml`. + +## Prerequisites + +- A running Kubernetes cluster (v1.19+ recommended). +- [Helm v3+](https://helm.sh/) installed. +- (Optional) Metrics Server installed in your cluster for detailed container CPU & memory usage. + +## Kubeconfig & Secret Setup + +To mirror the `docker-compose.yml` setup where `KUBECONFIG=/root/.kube/config` is mounted into the container, the Helm chart mounts a Kubernetes `Secret` containing your `kubeconfig` file to `/root/.kube/config` and sets the `KUBECONFIG` environment variable. + +You can configure and set up the `kubeconfig` secret using one of the following methods: + +### Method 1: Create a Kubernetes Secret manually with `kubectl` (Recommended) + +1. Create a secret containing your `.kube/config` file: + ```bash + kubectl create secret generic k8s-pulse-kubeconfig --from-file=config=$HOME/.kube/config + ``` + +2. Install or upgrade the Helm chart specifying the existing secret: + ```bash + helm install k8s-pulse ./helm-chart \ + --set kubeconfig.enabled=true \ + --set kubeconfig.secretName=k8s-pulse-kubeconfig + ``` + +### Method 2: Create the Secret via Helm using `--set-file` + +You can have Helm create the `Secret` resource directly from your local `kubeconfig` file during installation: + +```bash +helm install k8s-pulse ./helm-chart \ + --set kubeconfig.enabled=true \ + --set kubeconfig.createSecret=true \ + --set-file kubeconfig.content=$HOME/.kube/config +``` + +### Method 3: Use a custom `values.yaml` file + +Create a custom values file (e.g. `my-values.yaml`): + +```yaml +kubeconfig: + enabled: true + createSecret: true + secretName: "k8s-pulse-kubeconfig" + secretKey: "config" + mountPath: "/root/.kube/config" + content: | + apiVersion: v1 + clusters: + - cluster: + server: https://127.0.0.1:6443 + name: my-cluster + ... +``` + +Then install the chart using: + +```bash +helm install k8s-pulse ./helm-chart -f my-values.yaml +``` + +--- + +## Quick Start + +### 1. Install the Chart + +Default installation (uses `kubeconfig.enabled=true` with secret `-kubeconfig`): + +```bash +# 1. Create the secret +kubectl create secret generic k8s-pulse-kubeconfig --from-file=config=$HOME/.kube/config + +# 2. Install the chart +helm install k8s-pulse ./helm-chart --set kubeconfig.secretName=k8s-pulse-kubeconfig +``` + +### 2. Custom Configuration + +You can override default settings by passing a custom `values.yaml` file or using `--set`: + +```bash +helm install k8s-pulse ./helm-chart -f custom-values.yaml +``` + +Example: Enable Ingress and change image tag: + +```bash +helm install k8s-pulse ./helm-chart \ + --set image.tag="1.0.0" \ + --set ingress.enabled=true \ + --set ingress.hosts[0].host="k8s-pulse.example.com" +``` + +### 3. Upgrade the Release + +```bash +helm upgrade k8s-pulse ./helm-chart +``` + +### 4. Uninstall + +```bash +helm uninstall k8s-pulse +``` + +--- + +## Configuration Parameters + +| Parameter | Description | Default | +|-----------|-------------|---------| +| `replicaCount` | Number of application replicas | `1` | +| `image.repository` | Docker image repository | `k8s-pulse` | +| `image.tag` | Docker image tag | `latest` | +| `image.pullPolicy` | Image pull policy | `IfNotPresent` | +| `kubeconfig.enabled` | Enable mounting kubeconfig Secret and `KUBECONFIG` env var | `true` | +| `kubeconfig.secretName` | Name of existing Secret containing kubeconfig file | `""` (defaults to `-kubeconfig`) | +| `kubeconfig.createSecret` | Create Secret resource via Helm from `kubeconfig.content` | `false` | +| `kubeconfig.content` | Raw kubeconfig content when `createSecret` is true | `""` | +| `kubeconfig.secretKey` | Secret data key containing kubeconfig file content | `"config"` | +| `kubeconfig.mountPath` | Container path to mount kubeconfig file and set `KUBECONFIG` env | `"/root/.kube/config"` | +| `service.type` | Kubernetes service type | `ClusterIP` | +| `service.port` | Service port exposed | `80` | +| `service.targetPort` | Container application port | `5000` | +| `rbac.create` | Create ClusterRole & ClusterRoleBinding for K8s API access | `true` | +| `serviceAccount.create` | Create ServiceAccount for the deployment | `true` | +| `serviceAccount.name` | Explicit ServiceAccount name | `""` | +| `ingress.enabled` | Enable Ingress resource | `false` | +| `resources` | Pod CPU/Memory resource limits & requests | `{ limits: { cpu: 200m, memory: 256Mi }, requests: { cpu: 100m, memory: 128Mi } }` | +| `persistence.enabled` | Enable optional PersistentVolumeClaim | `false` | + +--- + +## RBAC Requirements + +`k8s-pulse` requires read access to cluster nodes, pods, and `metrics.k8s.io` custom objects. By default, `rbac.create: true` creates a `ClusterRole` and `ClusterRoleBinding` bound to the pod's `ServiceAccount`. + +## Verification + +Check the deployment status: + +```bash +kubectl get pods -l app.kubernetes.io/name=k8s-pulse +kubectl get svc -l app.kubernetes.io/name=k8s-pulse +``` diff --git a/helm-chart/INSTALL.md b/helm-chart/INSTALL.md index 1c17077..1691939 100644 --- a/helm-chart/INSTALL.md +++ b/helm-chart/INSTALL.md @@ -5,17 +5,80 @@ This Helm chart provides a production-ready Kubernetes deployment for **k8s-puls ## Prerequisites - A running Kubernetes cluster (v1.19+ recommended). -- [Helm v3](https://helm.sh/) installed. +- [Helm v3+](https://helm.sh/) installed. - (Optional) Metrics Server installed in your cluster for detailed container CPU & memory usage. +## Kubeconfig & Secret Setup + +To mirror the `docker-compose.yml` setup where `KUBECONFIG=/root/.kube/config` is mounted into the container, the Helm chart mounts a Kubernetes `Secret` containing your `kubeconfig` file to `/root/.kube/config` and sets the `KUBECONFIG` environment variable. + +You can configure and set up the `kubeconfig` secret using one of the following methods: + +### Method 1: Create a Kubernetes Secret manually with `kubectl` (Recommended) + +1. Create a secret containing your `.kube/config` file: + ```bash + kubectl create secret generic k8s-pulse-kubeconfig --from-file=config=$HOME/.kube/config + ``` + +2. Install or upgrade the Helm chart specifying the existing secret: + ```bash + helm install k8s-pulse ./helm-chart \ + --set kubeconfig.enabled=true \ + --set kubeconfig.secretName=k8s-pulse-kubeconfig + ``` + +### Method 2: Create the Secret via Helm using `--set-file` + +You can have Helm create the `Secret` resource directly from your local `kubeconfig` file during installation: + +```bash +helm install k8s-pulse ./helm-chart \ + --set kubeconfig.enabled=true \ + --set kubeconfig.createSecret=true \ + --set-file kubeconfig.content=$HOME/.kube/config +``` + +### Method 3: Use a custom `values.yaml` file + +Create a custom values file (e.g. `my-values.yaml`): + +```yaml +kubeconfig: + enabled: true + createSecret: true + secretName: "k8s-pulse-kubeconfig" + secretKey: "config" + mountPath: "/root/.kube/config" + content: | + apiVersion: v1 + clusters: + - cluster: + server: https://127.0.0.1:6443 + name: my-cluster + ... +``` + +Then install the chart using: + +```bash +helm install k8s-pulse ./helm-chart -f my-values.yaml +``` + +--- + ## Quick Start ### 1. Install the Chart -To install the chart with default release name `k8s-pulse`: +Default installation (uses `kubeconfig.enabled=true` with secret `-kubeconfig`): ```bash -helm install k8s-pulse ./helm-chart +# 1. Create the secret +kubectl create secret generic k8s-pulse-kubeconfig --from-file=config=$HOME/.kube/config + +# 2. Install the chart +helm install k8s-pulse ./helm-chart --set kubeconfig.secretName=k8s-pulse-kubeconfig ``` ### 2. Custom Configuration @@ -47,6 +110,8 @@ helm upgrade k8s-pulse ./helm-chart helm uninstall k8s-pulse ``` +--- + ## Configuration Parameters | Parameter | Description | Default | @@ -55,6 +120,12 @@ helm uninstall k8s-pulse | `image.repository` | Docker image repository | `k8s-pulse` | | `image.tag` | Docker image tag | `latest` | | `image.pullPolicy` | Image pull policy | `IfNotPresent` | +| `kubeconfig.enabled` | Enable mounting kubeconfig Secret and `KUBECONFIG` env var | `true` | +| `kubeconfig.secretName` | Name of existing Secret containing kubeconfig file | `""` (defaults to `-kubeconfig`) | +| `kubeconfig.createSecret` | Create Secret resource via Helm from `kubeconfig.content` | `false` | +| `kubeconfig.content` | Raw kubeconfig content when `createSecret` is true | `""` | +| `kubeconfig.secretKey` | Secret data key containing kubeconfig file content | `"config"` | +| `kubeconfig.mountPath` | Container path to mount kubeconfig file and set `KUBECONFIG` env | `"/root/.kube/config"` | | `service.type` | Kubernetes service type | `ClusterIP` | | `service.port` | Service port exposed | `80` | | `service.targetPort` | Container application port | `5000` | @@ -65,6 +136,8 @@ helm uninstall k8s-pulse | `resources` | Pod CPU/Memory resource limits & requests | `{ limits: { cpu: 200m, memory: 256Mi }, requests: { cpu: 100m, memory: 128Mi } }` | | `persistence.enabled` | Enable optional PersistentVolumeClaim | `false` | +--- + ## RBAC Requirements `k8s-pulse` requires read access to cluster nodes, pods, and `metrics.k8s.io` custom objects. By default, `rbac.create: true` creates a `ClusterRole` and `ClusterRoleBinding` bound to the pod's `ServiceAccount`. diff --git a/helm-chart/templates/_helpers.tpl b/helm-chart/templates/_helpers.tpl index 9cccf79..505ce80 100644 --- a/helm-chart/templates/_helpers.tpl +++ b/helm-chart/templates/_helpers.tpl @@ -60,3 +60,15 @@ Create the name of the service account to use {{- default "default" .Values.serviceAccount.name }} {{- end }} {{- end }} + +{{/* +Create the name of the kubeconfig secret to use +*/}} +{{- define "k8s-pulse.kubeconfigSecretName" -}} +{{- if .Values.kubeconfig.secretName }} +{{- .Values.kubeconfig.secretName }} +{{- else }} +{{- printf "%s-kubeconfig" (include "k8s-pulse.fullname" .) }} +{{- end }} +{{- end }} + diff --git a/helm-chart/templates/deployment.yaml b/helm-chart/templates/deployment.yaml index 8d8303d..3793e4e 100644 --- a/helm-chart/templates/deployment.yaml +++ b/helm-chart/templates/deployment.yaml @@ -31,6 +31,11 @@ spec: {{- toYaml .Values.securityContext | nindent 12 }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- if .Values.kubeconfig.enabled }} + env: + - name: KUBECONFIG + value: {{ .Values.kubeconfig.mountPath | quote }} + {{- end }} ports: - name: http containerPort: {{ .Values.service.targetPort }} @@ -49,16 +54,31 @@ spec: periodSeconds: 10 resources: {{- toYaml .Values.resources | nindent 12 }} - {{- if .Values.persistence.enabled }} + {{- if or .Values.persistence.enabled .Values.kubeconfig.enabled }} volumeMounts: + {{- if .Values.persistence.enabled }} - name: data mountPath: /app/data + {{- end }} + {{- if .Values.kubeconfig.enabled }} + - name: kubeconfig-volume + mountPath: {{ .Values.kubeconfig.mountPath | quote }} + subPath: {{ .Values.kubeconfig.secretKey | default "config" | quote }} + readOnly: true + {{- end }} {{- end }} - {{- if .Values.persistence.enabled }} + {{- if or .Values.persistence.enabled .Values.kubeconfig.enabled }} volumes: + {{- if .Values.persistence.enabled }} - name: data persistentVolumeClaim: claimName: {{ include "k8s-pulse.fullname" . }}-data + {{- end }} + {{- if .Values.kubeconfig.enabled }} + - name: kubeconfig-volume + secret: + secretName: {{ include "k8s-pulse.kubeconfigSecretName" . }} + {{- end }} {{- end }} {{- with .Values.nodeSelector }} nodeSelector: diff --git a/helm-chart/templates/secret.yaml b/helm-chart/templates/secret.yaml new file mode 100644 index 0000000..c556ccf --- /dev/null +++ b/helm-chart/templates/secret.yaml @@ -0,0 +1,12 @@ +{{- if and .Values.kubeconfig.enabled .Values.kubeconfig.createSecret }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "k8s-pulse.kubeconfigSecretName" . }} + labels: + {{- include "k8s-pulse.labels" . | nindent 4 }} +type: Opaque +stringData: + {{ .Values.kubeconfig.secretKey | default "config" }}: | + {{- .Values.kubeconfig.content | nindent 4 }} +{{- end }} diff --git a/helm-chart/values.yaml b/helm-chart/values.yaml index abb035d..0b13a3d 100644 --- a/helm-chart/values.yaml +++ b/helm-chart/values.yaml @@ -12,6 +12,22 @@ imagePullSecrets: [] nameOverride: "" fullnameOverride: "" +# Kubeconfig configuration & secret mounting +kubeconfig: + # Enable mounting kubeconfig Secret into the pod + enabled: true + # Name of existing secret containing kubeconfig. + # If empty and createSecret is true, defaults to "-kubeconfig" + secretName: "" + # Set to true to create a Secret resource from 'content' + createSecret: false + # Content of the kubeconfig file when createSecret is true + content: "" + # Key name inside the secret containing kubeconfig data + secretKey: "config" + # Path inside container where kubeconfig is mounted + mountPath: "/root/.kube/config" + rbac: create: true diff --git a/version.ini b/version.ini index 232ddc5..e20caa7 100644 --- a/version.ini +++ b/version.ini @@ -1,2 +1,2 @@ [metadata] -version = 0.1 +version = 0.2