Skip to content

Commit ddaf913

Browse files
feat: expose prometheus port in helm chart (#10448)
Co-authored-by: Dean Sheather <dean@deansheather.com>
1 parent 44bb958 commit ddaf913

File tree

6 files changed

+273
-6
lines changed

6 files changed

+273
-6
lines changed

docs/admin/prometheus.md

+22-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ The Prometheus endpoint can be enabled in the
3535
[Helm chart's](https://github.com/coder/coder/tree/main/helm) `values.yml` by
3636
setting the environment variable `CODER_PROMETHEUS_ADDRESS` to `0.0.0.0:2112`.
3737
The environment variable `CODER_PROMETHEUS_ENABLE` will be enabled
38-
automatically.
38+
automatically. A Service Endpoint will also be exposed allowing Prometheus
39+
Service Monitors to be used.
3940

4041
### Prometheus configuration
4142

@@ -53,6 +54,26 @@ scrape_configs:
5354
apps: "coder"
5455
```
5556
57+
To use the Kubernetes Prometheus operator to scrape metrics, you will need to
58+
create a `ServiceMonitor` in your Coder deployment namespace. Below is an
59+
example `ServiceMonitor`:
60+
61+
```yaml
62+
apiVersion: monitoring.coreos.com/v1
63+
kind: ServiceMonitor
64+
metadata:
65+
name: coder-service-monitor
66+
namespace: coder
67+
spec:
68+
endpoints:
69+
- port: prometheus-http
70+
interval: 10s
71+
scrapeTimeout: 10s
72+
selector:
73+
matchLabels:
74+
app.kubernetes.io/name: coder
75+
```
76+
5677
## Available metrics
5778

5879
<!-- Code generated by 'make docs/admin/prometheus.md'. DO NOT EDIT -->

helm/coder/templates/service.yaml

+19
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,25 @@ spec:
2828
nodePort: {{ .Values.coder.service.httpsNodePort }}
2929
{{ end }}
3030
{{- end }}
31+
{{- range .Values.coder.env }}
32+
{{- if eq .name "CODER_PROMETHEUS_ENABLE" }}
33+
{{/*
34+
This sadly has to be nested to avoid evaluating the second part
35+
of the condition too early and potentially getting type errors if
36+
the value is not a string (like a `valueFrom`). We do not support
37+
`valueFrom` for this env var specifically.
38+
*/}}
39+
{{- if eq .value "true" }}
40+
- name: "prometheus-http"
41+
port: 2112
42+
targetPort: "prometheus-http"
43+
protocol: TCP
44+
{{ if eq $.Values.coder.service.type "NodePort" }}
45+
nodePort: {{ $.Values.coder.service.prometheusNodePort }}
46+
{{ end }}
47+
{{- end }}
48+
{{- end }}
49+
{{- end }}
3150
{{- if eq "LoadBalancer" .Values.coder.service.type }}
3251
{{- with .Values.coder.service.loadBalancerIP }}
3352
loadBalancerIP: {{ . | quote }}

helm/coder/tests/chart_test.go

+8-1
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,10 @@ var testCases = []testCase{
8080
name: "extra_templates",
8181
expectedError: "",
8282
},
83+
{
84+
name: "prometheus",
85+
expectedError: "",
86+
},
8387
}
8488

8589
type testCase struct {
@@ -158,7 +162,10 @@ func TestUpdateGoldenFiles(t *testing.T) {
158162

159163
valuesPath := tc.valuesFilePath()
160164
templateOutput, err := runHelmTemplate(t, helmPath, "..", valuesPath)
161-
165+
if err != nil {
166+
t.Logf("error running `helm template -f %q`: %v", valuesPath, err)
167+
t.Logf("output: %s", templateOutput)
168+
}
162169
require.NoError(t, err, "failed to run `helm template -f %q`", valuesPath)
163170

164171
goldenFilePath := tc.goldenFilePath()
+204
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
---
2+
# Source: coder/templates/coder.yaml
3+
apiVersion: v1
4+
kind: ServiceAccount
5+
metadata:
6+
annotations: {}
7+
labels:
8+
app.kubernetes.io/instance: release-name
9+
app.kubernetes.io/managed-by: Helm
10+
app.kubernetes.io/name: coder
11+
app.kubernetes.io/part-of: coder
12+
app.kubernetes.io/version: 0.1.0
13+
helm.sh/chart: coder-0.1.0
14+
name: coder
15+
---
16+
# Source: coder/templates/rbac.yaml
17+
apiVersion: rbac.authorization.k8s.io/v1
18+
kind: Role
19+
metadata:
20+
name: coder-workspace-perms
21+
rules:
22+
- apiGroups: [""]
23+
resources: ["pods"]
24+
verbs:
25+
- create
26+
- delete
27+
- deletecollection
28+
- get
29+
- list
30+
- patch
31+
- update
32+
- watch
33+
- apiGroups: [""]
34+
resources: ["persistentvolumeclaims"]
35+
verbs:
36+
- create
37+
- delete
38+
- deletecollection
39+
- get
40+
- list
41+
- patch
42+
- update
43+
- watch
44+
- apiGroups:
45+
- apps
46+
resources:
47+
- deployments
48+
verbs:
49+
- create
50+
- delete
51+
- deletecollection
52+
- get
53+
- list
54+
- patch
55+
- update
56+
- watch
57+
---
58+
# Source: coder/templates/rbac.yaml
59+
apiVersion: rbac.authorization.k8s.io/v1
60+
kind: RoleBinding
61+
metadata:
62+
name: "coder"
63+
subjects:
64+
- kind: ServiceAccount
65+
name: "coder"
66+
roleRef:
67+
apiGroup: rbac.authorization.k8s.io
68+
kind: Role
69+
name: coder-workspace-perms
70+
---
71+
# Source: coder/templates/service.yaml
72+
apiVersion: v1
73+
kind: Service
74+
metadata:
75+
name: coder
76+
labels:
77+
helm.sh/chart: coder-0.1.0
78+
app.kubernetes.io/name: coder
79+
app.kubernetes.io/instance: release-name
80+
app.kubernetes.io/part-of: coder
81+
app.kubernetes.io/version: "0.1.0"
82+
app.kubernetes.io/managed-by: Helm
83+
annotations:
84+
{}
85+
spec:
86+
type: NodePort
87+
sessionAffinity: None
88+
ports:
89+
- name: "http"
90+
port: 80
91+
targetPort: "http"
92+
protocol: TCP
93+
94+
nodePort:
95+
96+
97+
- name: "prometheus-http"
98+
port: 2112
99+
targetPort: "prometheus-http"
100+
protocol: TCP
101+
102+
nodePort: 31112
103+
104+
selector:
105+
app.kubernetes.io/name: coder
106+
app.kubernetes.io/instance: release-name
107+
---
108+
# Source: coder/templates/coder.yaml
109+
apiVersion: apps/v1
110+
kind: Deployment
111+
metadata:
112+
annotations: {}
113+
labels:
114+
app.kubernetes.io/instance: release-name
115+
app.kubernetes.io/managed-by: Helm
116+
app.kubernetes.io/name: coder
117+
app.kubernetes.io/part-of: coder
118+
app.kubernetes.io/version: 0.1.0
119+
helm.sh/chart: coder-0.1.0
120+
name: coder
121+
spec:
122+
replicas: 1
123+
selector:
124+
matchLabels:
125+
app.kubernetes.io/instance: release-name
126+
app.kubernetes.io/name: coder
127+
template:
128+
metadata:
129+
annotations: {}
130+
labels:
131+
app.kubernetes.io/instance: release-name
132+
app.kubernetes.io/managed-by: Helm
133+
app.kubernetes.io/name: coder
134+
app.kubernetes.io/part-of: coder
135+
app.kubernetes.io/version: 0.1.0
136+
helm.sh/chart: coder-0.1.0
137+
spec:
138+
affinity:
139+
podAntiAffinity:
140+
preferredDuringSchedulingIgnoredDuringExecution:
141+
- podAffinityTerm:
142+
labelSelector:
143+
matchExpressions:
144+
- key: app.kubernetes.io/instance
145+
operator: In
146+
values:
147+
- coder
148+
topologyKey: kubernetes.io/hostname
149+
weight: 1
150+
containers:
151+
- args:
152+
- server
153+
command:
154+
- /opt/coder
155+
env:
156+
- name: CODER_HTTP_ADDRESS
157+
value: 0.0.0.0:8080
158+
- name: CODER_PROMETHEUS_ADDRESS
159+
value: 0.0.0.0:2112
160+
- name: CODER_ACCESS_URL
161+
value: http://coder.default.svc.cluster.local
162+
- name: KUBE_POD_IP
163+
valueFrom:
164+
fieldRef:
165+
fieldPath: status.podIP
166+
- name: CODER_DERP_SERVER_RELAY_URL
167+
value: http://$(KUBE_POD_IP):8080
168+
- name: CODER_PROMETHEUS_ENABLE
169+
value: "true"
170+
image: ghcr.io/coder/coder:latest
171+
imagePullPolicy: IfNotPresent
172+
lifecycle: {}
173+
livenessProbe:
174+
httpGet:
175+
path: /healthz
176+
port: http
177+
scheme: HTTP
178+
name: coder
179+
ports:
180+
- containerPort: 8080
181+
name: http
182+
protocol: TCP
183+
- containerPort: 2112
184+
name: prometheus-http
185+
protocol: TCP
186+
readinessProbe:
187+
httpGet:
188+
path: /healthz
189+
port: http
190+
scheme: HTTP
191+
resources: {}
192+
securityContext:
193+
allowPrivilegeEscalation: false
194+
readOnlyRootFilesystem: null
195+
runAsGroup: 1000
196+
runAsNonRoot: true
197+
runAsUser: 1000
198+
seccompProfile:
199+
type: RuntimeDefault
200+
volumeMounts: []
201+
restartPolicy: Always
202+
serviceAccountName: coder
203+
terminationGracePeriodSeconds: 60
204+
volumes: []
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
coder:
2+
image:
3+
tag: latest
4+
service:
5+
type: NodePort
6+
prometheusNodePort: 31112
7+
env:
8+
- name: CODER_PROMETHEUS_ENABLE
9+
value: "true"

helm/coder/values.yaml

+11-4
Original file line numberDiff line numberDiff line change
@@ -259,12 +259,19 @@ coder:
259259
# coder.service.annotations -- The service annotations. See:
260260
# https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer
261261
annotations: {}
262-
# coder.service.httpNodePort -- Enabled if coder.service.type is set to NodePort.
263-
# If not set, Kubernetes will allocate a port from the default range, 30000-32767.
262+
# coder.service.httpNodePort -- Enabled if coder.service.type is set to
263+
# NodePort. If not set, Kubernetes will allocate a port from the default
264+
# range, 30000-32767.
264265
httpNodePort: ""
265-
# coder.service.httpsNodePort -- Enabled if coder.service.type is set to NodePort.
266-
# If not set, Kubernetes will allocate a port from the default range, 30000-32767.
266+
# coder.service.httpsNodePort -- Enabled if coder.service.type is set to
267+
# NodePort. If not set, Kubernetes will allocate a port from the default
268+
# range, 30000-32767.
267269
httpsNodePort: ""
270+
# coder.service.prometheusNodePort -- Enabled if coder.service.type is set
271+
# to NodePort. If not set, Kubernetes will allocate a port from the default
272+
# range, 30000-32767. The "prometheus-http" port on the coder service is
273+
# only exposed if CODER_PROMETHEUS_ENABLE is set to true.
274+
prometheusNodePort: ""
268275

269276
# coder.ingress -- The Ingress object to expose for Coder.
270277
ingress:

0 commit comments

Comments
 (0)