diff --git a/helm/kagent/templates/controller-configmap.yaml b/helm/kagent/templates/controller-configmap.yaml index ed4ed0ecb..99f136a62 100644 --- a/helm/kagent/templates/controller-configmap.yaml +++ b/helm/kagent/templates/controller-configmap.yaml @@ -71,3 +71,7 @@ data: {{- if and .Values.controller.agentDeployment .Values.controller.agentDeployment.serviceAccountName (not (eq .Values.controller.agentDeployment.serviceAccountName "")) }} DEFAULT_SERVICE_ACCOUNT_NAME: {{ .Values.controller.agentDeployment.serviceAccountName | quote }} {{- end }} + {{- if .Values.controller.metrics.enabled }} + METRICS_BIND_ADDRESS: {{ printf ":%v" .Values.controller.metrics.port | quote }} + METRICS_SECURE: {{ .Values.controller.metrics.secure | quote }} + {{- end }} diff --git a/helm/kagent/templates/controller-deployment.yaml b/helm/kagent/templates/controller-deployment.yaml index 2909cdc78..a01c4b0ec 100644 --- a/helm/kagent/templates/controller-deployment.yaml +++ b/helm/kagent/templates/controller-deployment.yaml @@ -78,6 +78,11 @@ spec: - name: http containerPort: {{ .Values.controller.service.ports.targetPort }} protocol: TCP + {{- if .Values.controller.metrics.enabled }} + - name: metrics + containerPort: {{ .Values.controller.metrics.port }} + protocol: TCP + {{- end }} resources: {{- toYaml .Values.controller.resources | nindent 12 }} securityContext: diff --git a/helm/kagent/templates/controller-metrics-service.yaml b/helm/kagent/templates/controller-metrics-service.yaml new file mode 100644 index 000000000..bfcfdfd17 --- /dev/null +++ b/helm/kagent/templates/controller-metrics-service.yaml @@ -0,0 +1,19 @@ +{{- if .Values.controller.metrics.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "kagent.fullname" . }}-controller-metrics + namespace: {{ include "kagent.namespace" . }} + labels: + {{- include "kagent.labels" . | nindent 4 }} + app.kubernetes.io/component: metrics +spec: + type: ClusterIP + ports: + - port: {{ .Values.controller.metrics.port }} + targetPort: {{ .Values.controller.metrics.port }} + protocol: TCP + name: metrics + selector: + {{- include "kagent.controller.selectorLabels" . | nindent 4 }} +{{- end }} diff --git a/helm/kagent/templates/controller-servicemonitor.yaml b/helm/kagent/templates/controller-servicemonitor.yaml new file mode 100644 index 000000000..4f14db201 --- /dev/null +++ b/helm/kagent/templates/controller-servicemonitor.yaml @@ -0,0 +1,40 @@ +{{- if and .Values.controller.metrics.enabled .Values.controller.metrics.serviceMonitor.enabled (.Capabilities.APIVersions.Has "monitoring.coreos.com/v1") }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ include "kagent.fullname" . }}-controller + namespace: {{ include "kagent.namespace" . }} + labels: + {{- include "kagent.controller.labels" . | nindent 4 }} + {{- with .Values.controller.metrics.serviceMonitor.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + selector: + matchLabels: + {{- include "kagent.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: metrics + endpoints: + - port: metrics + interval: {{ .Values.controller.metrics.serviceMonitor.interval }} + scrapeTimeout: {{ .Values.controller.metrics.serviceMonitor.scrapeTimeout }} + {{- if .Values.controller.metrics.secure }} + scheme: https + tlsConfig: + insecureSkipVerify: true + {{- with .Values.controller.metrics.serviceMonitor.bearerTokenSecret }} + bearerTokenSecret: + {{- toYaml . | nindent 8 }} + {{- else }} + bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + {{- end }} + {{- end }} + {{- with .Values.controller.metrics.serviceMonitor.metricRelabelings }} + metricRelabelings: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.controller.metrics.serviceMonitor.relabelings }} + relabelings: + {{- toYaml . | nindent 8 }} + {{- end }} +{{- end }} diff --git a/helm/kagent/tests/controller-deployment_test.yaml b/helm/kagent/tests/controller-deployment_test.yaml index 2b43c31be..db22ffca0 100644 --- a/helm/kagent/tests/controller-deployment_test.yaml +++ b/helm/kagent/tests/controller-deployment_test.yaml @@ -239,4 +239,53 @@ tests: - isNull: path: spec.template.spec.volumes - isNull: - path: spec.template.spec.containers[0].volumeMounts \ No newline at end of file + path: spec.template.spec.containers[0].volumeMounts + + - it: should not include metrics port by default + template: controller-deployment.yaml + asserts: + - lengthEqual: + path: spec.template.spec.containers[0].ports + count: 1 + + - it: should include metrics port when enabled + template: controller-deployment.yaml + set: + controller: + metrics: + enabled: true + port: 9093 + asserts: + - lengthEqual: + path: spec.template.spec.containers[0].ports + count: 2 + - equal: + path: spec.template.spec.containers[0].ports[1].name + value: metrics + - equal: + path: spec.template.spec.containers[0].ports[1].containerPort + value: 9093 + + - it: should set metrics env vars in configmap when enabled + template: controller-configmap.yaml + set: + controller: + metrics: + enabled: true + port: 9093 + secure: false + asserts: + - equal: + path: data.METRICS_BIND_ADDRESS + value: ":9093" + - equal: + path: data.METRICS_SECURE + value: "false" + + - it: should not set metrics env vars when disabled + template: controller-configmap.yaml + asserts: + - notExists: + path: data.METRICS_BIND_ADDRESS + - notExists: + path: data.METRICS_SECURE \ No newline at end of file diff --git a/helm/kagent/tests/controller-service_test.yaml b/helm/kagent/tests/controller-service_test.yaml index f3bb1d97b..b7e394250 100644 --- a/helm/kagent/tests/controller-service_test.yaml +++ b/helm/kagent/tests/controller-service_test.yaml @@ -68,4 +68,16 @@ tests: asserts: - equal: path: metadata.namespace - value: custom-namespace \ No newline at end of file + value: custom-namespace + + - it: should only have controller port (metrics use dedicated service) + set: + controller.metrics.enabled: true + controller.metrics.port: 9093 + asserts: + - lengthEqual: + path: spec.ports + count: 1 + - equal: + path: spec.ports[0].name + value: controller \ No newline at end of file diff --git a/helm/kagent/tests/controller-servicemonitor_test.yaml b/helm/kagent/tests/controller-servicemonitor_test.yaml new file mode 100644 index 000000000..fa2de3e7d --- /dev/null +++ b/helm/kagent/tests/controller-servicemonitor_test.yaml @@ -0,0 +1,135 @@ +suite: test controller servicemonitor +templates: + - controller-servicemonitor.yaml +tests: + - it: should not render when metrics are disabled + asserts: + - hasDocuments: + count: 0 + + - it: should not render when metrics enabled but serviceMonitor disabled + set: + controller.metrics.enabled: true + controller.metrics.serviceMonitor.enabled: false + asserts: + - hasDocuments: + count: 0 + + - it: should not render when CRD is not available + set: + controller.metrics.enabled: true + controller.metrics.serviceMonitor.enabled: true + asserts: + - hasDocuments: + count: 0 + + - it: should render when both metrics and serviceMonitor are enabled + capabilities: + apiVersions: + - monitoring.coreos.com/v1 + set: + controller.metrics.enabled: true + controller.metrics.serviceMonitor.enabled: true + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ServiceMonitor + - equal: + path: metadata.name + value: RELEASE-NAME-controller + + - it: should have correct endpoint configuration + capabilities: + apiVersions: + - monitoring.coreos.com/v1 + set: + controller.metrics.enabled: true + controller.metrics.port: 9093 + controller.metrics.serviceMonitor.enabled: true + controller.metrics.serviceMonitor.interval: 30s + controller.metrics.serviceMonitor.scrapeTimeout: 10s + asserts: + - equal: + path: spec.endpoints[0].port + value: metrics + - equal: + path: spec.endpoints[0].interval + value: 30s + - equal: + path: spec.endpoints[0].scrapeTimeout + value: 10s + + - it: should use HTTPS scheme and default bearerTokenFile when metrics are secure + capabilities: + apiVersions: + - monitoring.coreos.com/v1 + set: + controller.metrics.enabled: true + controller.metrics.secure: true + controller.metrics.serviceMonitor.enabled: true + asserts: + - equal: + path: spec.endpoints[0].scheme + value: https + - equal: + path: spec.endpoints[0].bearerTokenFile + value: /var/run/secrets/kubernetes.io/serviceaccount/token + - isNull: + path: spec.endpoints[0].bearerTokenSecret + + - it: should use bearerTokenSecret when configured for secure metrics + capabilities: + apiVersions: + - monitoring.coreos.com/v1 + set: + controller.metrics.enabled: true + controller.metrics.secure: true + controller.metrics.serviceMonitor.enabled: true + controller.metrics.serviceMonitor.bearerTokenSecret: + name: my-prometheus-token + key: token + asserts: + - equal: + path: spec.endpoints[0].scheme + value: https + - equal: + path: spec.endpoints[0].bearerTokenSecret.name + value: my-prometheus-token + - equal: + path: spec.endpoints[0].bearerTokenSecret.key + value: token + - isNull: + path: spec.endpoints[0].bearerTokenFile + + - it: should include additional labels + capabilities: + apiVersions: + - monitoring.coreos.com/v1 + set: + controller.metrics.enabled: true + controller.metrics.serviceMonitor.enabled: true + controller.metrics.serviceMonitor.additionalLabels: + release: prometheus + asserts: + - equal: + path: metadata.labels.release + value: prometheus + + - it: should have correct selector labels + capabilities: + apiVersions: + - monitoring.coreos.com/v1 + set: + controller.metrics.enabled: true + controller.metrics.serviceMonitor.enabled: true + asserts: + - equal: + path: spec.selector.matchLabels["app.kubernetes.io/name"] + value: kagent + - equal: + path: spec.selector.matchLabels["app.kubernetes.io/instance"] + value: RELEASE-NAME + - equal: + path: spec.selector.matchLabels["app.kubernetes.io/component"] + value: metrics diff --git a/helm/kagent/values.yaml b/helm/kagent/values.yaml index 7f6142dd8..31b1236ac 100644 --- a/helm/kagent/values.yaml +++ b/helm/kagent/values.yaml @@ -126,6 +126,37 @@ controller: ports: port: 8083 targetPort: 8083 + # -- Prometheus metrics configuration + metrics: + # -- Enable the metrics endpoint + enabled: false + # -- Port for the metrics endpoint + port: 9093 + # -- Serve metrics via HTTPS (true) or HTTP (false) + secure: false + # -- Deploy a Prometheus Operator ServiceMonitor + serviceMonitor: + # -- Create a ServiceMonitor resource + enabled: false + # -- Additional labels for the ServiceMonitor (e.g. release: prometheus) + additionalLabels: {} + # -- Scrape interval + interval: 30s + # -- Scrape timeout + scrapeTimeout: 10s + # -- Override the default bearerTokenFile with a Kubernetes Secret reference. + # When set and secure=true, uses bearerTokenSecret instead of the default + # service account token file for Prometheus authentication. + # Example: + # bearerTokenSecret: + # name: my-prometheus-token + # key: token + bearerTokenSecret: {} + # -- Metric relabeling configs + metricRelabelings: [] + # -- Relabeling configs + relabelings: [] + env: [] envFrom: []