Skip to content
This repository was archived by the owner on Jan 29, 2025. It is now read-only.

Commit fda8e05

Browse files
madalazartogashidmadorney99
committed
Updating power demo
This commit will: * Via @dorney99. update collectd and stress-ng image * adding 30 second delay using init container * Update autoscaler to use new version of API * Update security settings for container and resource limits * Trivy fix for hostPort and doc updates * Update docs with latest changes --------- Co-authored-by: Denisio Togashi <[email protected]> Co-authored-by: Aaron Dorney <[email protected]> Co-authored-by: Madalina Lazar <[email protected]>
1 parent 88d6cd4 commit fda8e05

File tree

9 files changed

+202
-84
lines changed

9 files changed

+202
-84
lines changed

telemetry-aware-scheduling/docs/power/Dockerfile

-6
This file was deleted.

telemetry-aware-scheduling/docs/power/README.md

+130-37
Original file line numberDiff line numberDiff line change
@@ -17,62 +17,50 @@ The power metrics used to drive placement and scaling decisions derive from [Int
1717

1818
3) Clone and enter repo
1919

20-
``git clone https://github.com/intel/telemetry-aware-scheduling/ && cd telemetry-aware-scheduling/docs/power``
20+
``git clone https://github.com/intel/platform-aware-scheduling/ && cd platform-aware-scheduling/telemetry-aware-scheduling/docs/power``
2121

2222
4) Set the power directory (which contains this Readme) as an environment variable.
2323

2424
``export POW_DIR=$PWD``
2525

26-
### 1: Build collectd and stress-ng docker images
27-
Two new docker images are required:
2826

29-
1) **collectd** to read power metrics from each host in the cluster and expose them to the Prometheus metrics database.
30-
31-
``cd $POW_DIR/collectd && docker build . -t localhost:5000/collectdpower && docker push localhost:5000/collectdpower``
32-
33-
2) **stress-ng** to use as an example application for our deployment.
34-
35-
``cd $POW_DIR && docker build . -t localhost:5000/stressng && docker push localhost:5000/stressng``
36-
37-
Using the above commands both of these images will be built and then pushed to the local docker registry preparing them for deployment on Kubernetes.
38-
39-
### 2: Deploy collectd on Kubernetes
40-
Collectd can now be deployed on our Kubernetes cluster. Note that the collectd image is configured using a configmap and can be reconfigured by changing that file - located in `collectd/configmap.yaml`. In our default configuration collectd will only export stats on the node CPU package power. This is powered by the [Intel Comms Power Management collectd plugin](https://github.com/intel/CommsPowerManagement/tree/master/telemetry)
27+
### 1: Deploy collectd on Kubernetes
28+
Collectd can now be deployed on our Kubernetes cluster. Note that the collectd image is configured using a configmap and can be reconfigured by changing that file - located in `collectd/configmap.yaml`. In our default configuration collectd will only export stats on the node CPU package power. This is powered by the [Intel Comms Power Management collectd plugin](https://github.com/intel/CommsPowerManagement/tree/master/telemetry). The collectd [intel/observability-collectd image](https://hub.docker.com/r/intel/observability-collectd) will need an extra python script for reading and exporting power values which can be grabbed with a curl command and will need to be added as a configmap.
4129

4230
Deploy collectd using:
4331

44-
``kubectl apply -f $POW_DIR/collectd/daemonset.yaml && kubectl apply -f $POW_DIR/collectd/configmap.yaml && kubectl apply -f $POW_DIR/collectd/service.yaml``
32+
1) ``curl https://raw.githubusercontent.com/intel/CommsPowerManagement/master/telemetry/pkgpower.py -o $POW_DIR/collectd/pkgpower.py && kubectl create configmap pkgpower --from-file $POW_DIR/collectd/pkgpower.py --namespace monitoring``
33+
34+
2) ``kubectl apply -f $POW_DIR/collectd/daemonset.yaml && kubectl apply -f $POW_DIR/collectd/configmap.yaml && kubectl apply -f $POW_DIR/collectd/service.yaml``
4535

4636
The agent should soon be up and running on each node in the cluster. This can be checked by running:
4737

4838
`kubectl get pods -nmonitoring -lapp.kubernetes.io/name=collectd`
4939

50-
51-
Additionally we can check that collectd is indeed serving metrics by running `curl localhost:9103` on any node where the agent is running. The output should resemble the below:
40+
Additionally we can check that collectd is indeed serving metrics by running `collectd_ip=$(kubectl get svc -n monitoring -o json | jq -r '.items[] | select(.metadata.name=="collectd").spec.clusterIP'); curl -x "" $collectd_ip:9103/metrics`. The output should look similar to the lines below:
5241

5342
```
54-
# HELP collectd_package_0_TDP_power_power write_prometheus plugin: 'package_0_TDP_power' Type: 'power', Dstype: 'gauge', Dsname: 'value'
55-
# TYPE collectd_package_0_TDP_power_power gauge
56-
collectd_package_0_TDP_power_power{instance="localhost"} 145 XXXXX
57-
# HELP collectd_package_0_power_power write_prometheus plugin: 'package_0_power' Type: 'power', Dstype: 'gauge', Dsname: 'value'
58-
# TYPE collectd_package_0_power_power gauge
59-
collectd_package_0_power_power{instance="localhost"} 24.8610455766901 XXXXX
60-
# HELP collectd_package_1_TDP_power_power write_prometheus plugin: 'package_1_TDP_power' Type: 'power', Dstype: 'gauge', Dsname: 'value'
61-
# TYPE collectd_package_1_TDP_power_power gauge
62-
collectd_package_1_TDP_power_power{instance="localhost"} 145 XXXXX
63-
# HELP collectd_package_1_power_power write_prometheus plugin: 'package_1_power' Type: 'power', Dstype: 'gauge', Dsname: 'value'
64-
# TYPE collectd_package_1_power_power gauge
65-
collectd_package_1_power_power{instance="localhost"} 26.5859645878891 XXXXX
43+
# HELP collectd_package_0_TDP_power_power write_prometheus plugin: 'package_0_TDP_power' Type: 'power', Dstype: 'gauge', Dsname: 'value'
44+
# TYPE collectd_package_0_TDP_power_power gauge
45+
collectd_package_0_TDP_power_power{instance="collectd-llnxh"} 140 1686148275145
46+
# HELP collectd_package_0_power_power write_prometheus plugin: 'package_0_power' Type: 'power', Dstype: 'gauge', Dsname: 'value'
47+
# TYPE collectd_package_0_power_power gauge
48+
collectd_package_0_power_power{instance="collectd-llnxh"} 127.249769171414 1686148275145
49+
# HELP collectd_package_1_TDP_power_power write_prometheus plugin: 'package_1_TDP_power' Type: 'power', Dstype: 'gauge', Dsname: 'value'
50+
# TYPE collectd_package_1_TDP_power_power gauge
51+
collectd_package_1_TDP_power_power{instance="collectd-llnxh"} 140 1686148275145
52+
# HELP collectd_package_1_power_power write_prometheus plugin: 'package_1_power' Type: 'power', Dstype: 'gauge', Dsname: 'value'
53+
# TYPE collectd_package_1_power_power gauge
54+
collectd_package_1_power_power{instance="collectd-llnxh"} 117.843289048237 1686148275145
6655
67-
# collectd/write_prometheus 5.11.0.70.gd4c3c59 at localhost
6856
```
6957

70-
### 3: Install Kube State Metrics
58+
### 2: Install Kube State Metrics
7159

7260
Kube State Metrics reads information from a Kubernetes cluster and makes it available to Prometheus. In our use case we're looking for basic information about the pods currently running on the cluster. Kube state metrics can be installed using helm, the Kubernetes package manager, which comes preinstalled in the BMRA.
7361

7462
``
75-
helm install "master" stable/kube-state-metrics
63+
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts && helm install "master" prometheus-community/kube-state-metrics
7664
``
7765

7866
We can check to see that its running with:
@@ -82,16 +70,121 @@ kubectl get pods -l app.kubernetes.io/name=kube-state-metrics
8270
``
8371

8472
### 3: Configure Prometheus and the Prometheus adapter
85-
Now that we have our metrics collections agents up and running, Prometheus and Prometheus Adapter, which makes Prometheus metrics available inside the cluster to Telemetry Aware Scheduling, need to be configured to scrape metrics from collectd and Kube State Metrics and to calculate the compound power metrics linking pods to power usage.
8673

87-
``kubectl apply -f $POW_DIR/prometheus/prometheus-config.yaml && kubectl delete pods -nmonitoring -lapp=prometheus -lcomponent=server && kubectl apply -f $POW_DIR/prometheus/custom-metrics-config.yml && kubectl delete pods -n custom-metrics -lapp=prometheus-adapter``
74+
Now that we have our metrics collections agents up and running, Prometheus and Prometheus Adapter (it makes Prometheus metrics available inside the cluster to Telemetry Aware Scheduling) need to be configured to scrape metrics from collectd and Kube State Metrics and to calculate the compound power metrics linking pods to power usage.
75+
76+
77+
#### 3.1: Manually set-up and install new configuration
78+
79+
The above command creates a new configuration and reboots Prometheus and the Prometheus Adapter. Collectd power metrics should now be available in the Prometheus database and, more importantly, inside the Kubernetes cluster itself.
80+
81+
``kubectl apply -f $POW_DIR/prometheus/prometheus-config.yaml && kubectl delete pods -nmonitoring -lapp=prometheus -lcomponent=server && kubectl apply -f $POW_DIR/prometheus/custom-metrics-config.yml && kubectl delete pods -n custom-metrics -lapp=custom-metrics-apiserver``
82+
83+
84+
#### 3.2: Helm and updating an existing configuration
85+
86+
#### 3.2.1: Prometheus
87+
88+
To add a new metrics into Prometheus, update [prometheus-config-map.yaml](https://github.com/intel/platform-aware-scheduling/blob/master/telemetry-aware-scheduling/deploy/charts/prometheus_helm_chart/templates/prometheus-config-map.yaml) in a similar manner to the below:
89+
90+
1. Create a metric and add it to a Prometheus rule file
91+
```
92+
recording_rules.yml: |
93+
groups:
94+
- name: k8s rules
95+
rules:
96+
- record: node_package_power_avg
97+
expr: 100 * ((collectd_package_0_power_power/collectd_package_0_TDP_power_power) + (collectd_package_1_power_power/ collectd_package_1_TDP_power_power))/2
98+
- record: node_package_power_per_pod
99+
expr: kube_pod_info * on (node) group_left node_package_power_avg
100+
```
101+
102+
2. Add the rule file to Prometheus (if adding a completely new rule file). If the rule file has already been done (i.e. ***/etc/prometheus/prometheus.rules***) move to step 3
103+
```
104+
rule_files:
105+
- /etc/prometheus/prometheus.rules
106+
- recording_rules.yml
107+
```
108+
3. Inform prometheus to scrape kube-state-metrics and collectd and how to do do it
109+
110+
```
111+
112+
- job_name: 'kube-state-metrics'
113+
static_configs:
114+
- targets: ['master-kube-state-metrics.default.svc.cluster.local:8080']
115+
116+
- job_name: 'collectd'
117+
scheme: http
118+
kubernetes_sd_configs:
119+
- role: endpoints
120+
relabel_configs:
121+
- source_labels: [__address__]
122+
regex: ^(.*):\d+$
123+
target_label: __address__
124+
replacement: $1:9103
125+
- target_label: __scheme__
126+
replacement: http
127+
- source_labels: [__meta_kubernetes_pod_node_name]
128+
target_label: instance
129+
metric_relabel_configs:
130+
- source_labels: [instance]
131+
target_label: node
132+
133+
```
134+
135+
To check if the new metrics were scraped correctly you can look for the following in the Prometheus UI:
136+
* In the "Targets"/ "Service Discovery" sections the "kube-state-metrics" and "collectd" items should be present and should be "UP"
137+
* In the main search page look for the "node_package_power_avg" and "node_package_power_per_pod". Each of these queries should return and non-empty answer
138+
139+
140+
4. Upgrade the HELM chart & restart the pods
88141

89-
The above command creates a new updated configuration and reboots Prometheus and the Prometheus Adapter. Collectd power metrics should now be available in the Prometheus database and, more importantly, inside the Kubernetes cluster itself. In order to confirm we can run a raw metrics query against the Kubernetes api.
142+
``helm upgrade prometheus ../../../telemetry-aware-scheduling/deploy/charts/prometheus_helm_chart/ && kubectl delete pods -nmonitoring -lapp=prometheus-server``
143+
144+
***The name of the helm chart and the path to charts/prometheus_helm_chart might differ depending on your installation of Prometheus (what name you gave to the chart) and your current path.***
145+
146+
#### 3.2.2: Prometheus Adapter
147+
148+
1. Query & process the metric before exposing it
149+
150+
The newly created metrics now need to be exported from Prometheus to the Telemetry-Aware scheduler and to do so we need add two new rules in [custom-metrics-config-map.yaml](https://github.com/intel/platform-aware-scheduling/blob/master/telemetry-aware-scheduling/deploy/charts/prometheus_custom_metrics_helm_chart/templates/custom-metrics-config-map.yaml).
151+
152+
The config currently present in the [repo](https://github.com/intel/platform-aware-scheduling/blob/master/telemetry-aware-scheduling/deploy/charts/prometheus_custom_metrics_helm_chart/templates/custom-metrics-config-map.yaml) will expose these metrics by default, but if the metrics are not showing (see commands below) you can try adding the following ( the first item is responsible for fetching the "node_package_power_avg" metric, whereas the second is for "node_package_power_per_pod"):
153+
154+
```
155+
- seriesQuery: '{__name__=~"^node_.*"}'
156+
resources:
157+
overrides:
158+
instance:
159+
resource: node
160+
name:
161+
matches: ^node_(.*)
162+
metricsQuery: <<.Series>>
163+
- seriesQuery: '{__name__=~"^node_.*",pod!=""}'
164+
resources:
165+
template: <<.Resource>>
166+
metricsQuery: <<.Series>>
167+
168+
```
169+
170+
***Details about the rules and the schema are available [here](https://github.com/kubernetes-sigs/prometheus-adapter/blob/master/docs/config.md)***
171+
172+
2. Upgrade the HELM chart & restart the pods
173+
174+
``helm upgrade prometheus-adapter ../../../telemetry-aware-scheduling/deploy/charts/prometheus_custom_metrics_helm_chart/ && kubectl delete pods -n custom-metrics -lapp=custom-metrics-apiserver``
175+
176+
***The name of the helm chart and the path to charts/prometheus_custom_metrics_helm_chart/ might differ depending on your installation of Prometheus (what name you have to the chart) and your current path.***
177+
178+
179+
After running the above commands (section 3.1 or 3.2) Collectd power metrics should now be available in the Prometheus database and, more importantly, inside the Kubernetes cluster itself. In order to confirm the changes, we can run a raw metrics query against the Kubernetes api.
180+
181+
``kubectl get --raw /apis/custom.metrics.k8s.io/v1beta1/nodes/*/package_power_avg``
90182

91183
``kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/namespaces/default/pods/*/node_package_power_per_pod"``
92184

93185
This command should return some json objects containing pods and associated power metrics:
94186

187+
95188
```json
96189
"kind": "MetricValueList",
97190
"apiVersion": "custom.metrics.k8s.io/v1beta1",
@@ -183,7 +276,7 @@ TAS will schedule it to the node with the lowest power usage, and will avoid sch
183276

184277
```
185278
186-
kubectl logs -l app.kubernetes.io/name=telemetry-aware-scheduling -c tas-extender
279+
kubectl logs -l app=tas
187280
188281
2020/XX/XX XX:XX:XX filter request recieved
189282
2020/XX/XX XX:XX:XX node1 package_power_avg = 72.133

telemetry-aware-scheduling/docs/power/collectd/Dockerfile

-17
This file was deleted.

telemetry-aware-scheduling/docs/power/collectd/daemonset.yaml

+20-11
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,20 @@ spec:
1818
app.kubernetes.io/version: v5.11
1919
spec:
2020
containers:
21-
- image: localhost:5000/collectdpower
22-
imagePullPolicy: Always
21+
- image: intel/observability-collectd:1.0
22+
imagePullPolicy: IfNotPresent
23+
securityContext:
24+
capabilities:
25+
drop: [ 'ALL' ]
26+
readOnlyRootFilesystem: true
27+
runAsNonRoot: true
28+
runAsUser: 10001
29+
allowPrivilegeEscalation: false
30+
runAsGroup: 10001
31+
seccompProfile:
32+
type: RuntimeDefault
2333
name: collectd
24-
command: [ "/bin/sh", "-c", "collectd; while :; do sleep 300; done" ]
34+
command: ["/bin/sh", "-c","../../run_collectd.sh"]
2535
resources:
2636
limits:
2737
cpu: 150m
@@ -33,17 +43,16 @@ spec:
3343
- name: config
3444
mountPath: /opt/collectd/etc/collectd.conf
3545
subPath: collectd.conf
36-
- mountPath: /host/sys/
37-
name: sys
38-
readOnly: true
46+
- name: pkgpower
47+
mountPath: /opt/collectd/etc/python-scripts/pkgpower.py
48+
subPath: pkgpower.py
3949
ports:
4050
- containerPort: 9103
41-
hostPort: 9103
42-
name: http
51+
protocol: TCP
4352
volumes:
4453
- name: config
4554
configMap:
4655
name: collectd-config
47-
- hostPath:
48-
path: /sys
49-
name: sys
56+
- name: pkgpower
57+
configMap:
58+
name: pkgpower

telemetry-aware-scheduling/docs/power/collectd/service.yaml

+3-1
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@ metadata:
44
labels:
55
app.kubernetes.io/name: collectd
66
app.kubernetes.io/version: v5.11
7+
annotations:
8+
prometheus.io/scrape: 'true'
9+
prometheus.io/port: '9103'
710
name: collectd
811
namespace: monitoring
912
spec:
10-
clusterIP: None
1113
ports:
1214
- name: http
1315
port: 9103

telemetry-aware-scheduling/docs/power/power-autoscaler.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
apiVersion: autoscaling/v2beta2
1+
apiVersion: autoscaling/v2
22
kind: HorizontalPodAutoscaler
33
metadata:
44
name: power-autoscaler

telemetry-aware-scheduling/docs/power/power-hungry-application.yaml

+40-3
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,47 @@ spec:
1818
spec:
1919
containers:
2020
- name: stressng
21-
image: localhost:5000/stressng
22-
command: [ "/bin/bash", "-c", "--" ]
23-
args: [ "sleep 30; stress-ng --cpu 12 --timeout 300s" ]
21+
image: alexeiled/stress-ng:0.12.05
22+
imagePullPolicy: IfNotPresent
23+
securityContext:
24+
capabilities:
25+
drop: [ 'ALL' ]
26+
runAsNonRoot: true
27+
readOnlyRootFilesystem: true
28+
seccompProfile:
29+
type: RuntimeDefault
30+
allowPrivilegeEscalation: false
31+
runAsUser: 10001
32+
runAsGroup: 10001
33+
args: ["--cpu", "12","--timeout", "300s"]
2434
resources:
35+
requests:
36+
memory: "100Mi"
37+
cpu: 12
2538
limits:
39+
memory: "100Mi"
2640
telemetry/scheduling: 1
41+
cpu: 12
42+
initContainers:
43+
- name: init-stress-ng
44+
image: alpine:3.17.3
45+
imagePullPolicy: IfNotPresent
46+
command: ["sleep","30"]
47+
securityContext:
48+
capabilities:
49+
drop: [ 'ALL' ]
50+
runAsNonRoot: true
51+
readOnlyRootFilesystem: true
52+
seccompProfile:
53+
type: RuntimeDefault
54+
allowPrivilegeEscalation: false
55+
runAsUser: 10001
56+
runAsGroup: 10001
57+
resources:
58+
requests:
59+
memory: "50Mi"
60+
cpu: "50m"
61+
limits:
62+
memory: "50Mi"
63+
cpu: "50m"
2764

telemetry-aware-scheduling/docs/power/prometheus/custom-metrics-config.yml

+2-4
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,6 @@ data:
7777
resource: node
7878
seriesQuery: '{__name__=~"^node_.*"}'
7979
- metricsQuery: <<.Series>>
80-
name:
81-
matches: ^node_(.*)
8280
resources:
8381
overrides:
8482
pod_name:
@@ -87,6 +85,6 @@ data:
8785
kind: ConfigMap
8886
metadata:
8987
labels:
90-
app: prometheus-adapter
91-
name: custom-metrics-prometheus-adapter
88+
app: custom-metrics-apiserver
89+
name: adapter-config
9290
namespace: custom-metrics

0 commit comments

Comments
 (0)