|
| 1 | +--- |
| 2 | +title: "Performance Profiling Metrics" |
| 3 | +weight: 10 |
| 4 | +description: > |
| 5 | + The goal of this document is to familiarize you with the steps to enable and review OLM's performance profiling metrics. |
| 6 | +--- |
| 7 | + |
| 8 | +## Prerequisites |
| 9 | + |
| 10 | +- [go](https://golang.org/dl/) |
| 11 | + |
| 12 | +## Background |
| 13 | + |
| 14 | +OLM utilizes the [pprof package](https://golang.org/pkg/net/http/pprof/) from the standard go library to expose performance profiles for the OLM Operator, the Catalog Operator, and Registry Servers. Due to the sensitive nature of this data, OLM must be configured to use TLS Certificates before performance profiling can be enabled. |
| 15 | + |
| 16 | +Requests against the performance profiling endpoint will be rejected unless the client certificate is validated by OLM. Unfortunately, Kubernetes does not provide a native way to prevent pods on cluster from iterating over the list of available ports and retrieving the data exposed. Without authenticating the requests, OLM could leak customer usage statistics on multitenant clusters. |
| 17 | + |
| 18 | +This document will dive into the steps to [enable olm performance profiling](enable-performance-profiling) and retrieving pprof data from each component. |
| 19 | + |
| 20 | +## Enabling Performance Profiling |
| 21 | + |
| 22 | +### Creating a Certificate |
| 23 | + |
| 24 | +A valid server certiciate must be created for each component before Performance Profiling can be enabled. If you are unfamiliar with certificate generation, I recomend using the [OpenSSL](https://www.openssl.org/) tool-kit and refer to the [request certificate](https://www.openssl.org/docs/manmaster/man1/openssl-req.html) documentation. |
| 25 | + |
| 26 | +Once you have generated a private and public key, this data should be stored in a `TLS Secret`: |
| 27 | + |
| 28 | +```bash |
| 29 | + |
| 30 | +$ export TLS_SECRET=my-tls-secret |
| 31 | +$ export PRIVATE_KEY_FILENAME=private.key # Replace with the name of the file that contains the private key you generated. |
| 32 | +$ export PUBLIC_KEY_FILENAME=certificate.crt # Replace with the name of the file that contains the public key you generated. |
| 33 | + |
| 34 | +$ cat << EOF | kubectl apply -f - |
| 35 | +apiVersion: v1 |
| 36 | +kind: Secret |
| 37 | +metadata: |
| 38 | + name: $TLS_SECRET |
| 39 | + namespace: olm |
| 40 | +type: kubernetes.io/tls |
| 41 | +data: |
| 42 | + tls.key: $(base64 -w0 $PRIVATE_KEY_FILENAME) |
| 43 | + tls.crt: $(base64 -w0 $PUBLIC_KEY_FILENAME) |
| 44 | +EOF |
| 45 | +``` |
| 46 | + |
| 47 | +### Updating OLM to Use the TLS Secret |
| 48 | + |
| 49 | +Patch the OLM Deployment's pod template to use the generated TLS secret: |
| 50 | + |
| 51 | +- Defining a volume and volumeMount |
| 52 | +- Adding the `client-ca`, `tls-key` and `tls-crt` arguments |
| 53 | +- Replacing all mentions of port `8080` with `8443` |
| 54 | +- Updating the `livenessProbe` and `readinessProbe` to use HTTPS as the scheme. |
| 55 | + |
| 56 | +This can by generating patching an existing OLM deployment: |
| 57 | + |
| 58 | +```bash |
| 59 | +$ export TLS_SECRET=my-tls-secret |
| 60 | +$ export CERT_PATH=/var/run/secrets # Define where to mount the certs. |
| 61 | +# Set Deployment name to olm-operator or catalog-operator |
| 62 | +$ export DEPLOYMENT_NAME=olm-operator |
| 63 | + |
| 64 | +$ kubectl patch deployment $DEPLOYMENT_NAME -n olm --type json -p='[ |
| 65 | + # Mount the secret to the pod |
| 66 | + {"op": "add", "path": "/spec/template/spec/volumes", "value":[{"name": '$TLS_SECRET', "secret": {"secretName": '$TLS_SECRET'}}]}, |
| 67 | + {"op": "add", "path": "/spec/template/spec/containers/0/volumeMounts", "value":[{"name": '$TLS_SECRET', "mountPath": '$CERT_PATH'}]}, |
| 68 | + |
| 69 | + # Add startup arguments |
| 70 | + {"op": "add", "path": "/spec/template/spec/containers/0/args/-", "value":"--client-ca"}, |
| 71 | + {"op": "add", "path": "/spec/template/spec/containers/0/args/-", "value":"'$CERT_PATH'/tls.crt"}, |
| 72 | + {"op": "add", "path": "/spec/template/spec/containers/0/args/-", "value":"--tls-key"}, |
| 73 | + {"op": "add", "path": "/spec/template/spec/containers/0/args/-", "value":"'$CERT_PATH'/tls.key"}, |
| 74 | + {"op": "add", "path": "/spec/template/spec/containers/0/args/-", "value":"--tls-cert"}, |
| 75 | + {"op": "add", "path": "/spec/template/spec/containers/0/args/-", "value":"'$CERT_PATH'/tls.crt"}, |
| 76 | + |
| 77 | + # Replace port 8080 with 8443 |
| 78 | + {"op": "replace", "path": "/spec/template/spec/containers/0/ports/0", "value":{"containerPort": 8443}}, |
| 79 | + {"op": "replace", "path": "/spec/template/spec/containers/0/livenessProbe/httpGet/port", "value":8443}, |
| 80 | + {"op": "replace", "path": "/spec/template/spec/containers/0/readinessProbe/httpGet/port", "value":8443}, |
| 81 | +
|
| 82 | + # Update livenessProbe and readinessProbe to use HTTPS |
| 83 | + {"op": "replace", "path": "/spec/template/spec/containers/0/readinessProbe/httpGet/scheme", "value":"HTTPS"}, |
| 84 | + {"op": "replace", "path": "/spec/template/spec/containers/0/livenessProbe/httpGet/scheme", "value":"HTTPS"}, |
| 85 | +]' |
| 86 | +deployment.apps/olm-operator patched |
| 87 | + |
| 88 | +``` |
| 89 | + |
| 90 | +## Accessing PPROF Data |
| 91 | + |
| 92 | +You will need to be able to access OLM port, for dev purposes the following commands may prove useful: |
| 93 | + |
| 94 | +```bash |
| 95 | +# Set Deployment name to olm-operator or catalog-operator |
| 96 | +$ export DEPLOYMENT_NAME=olm-operator |
| 97 | +$ kubectl port-forward deployment/$DEPLOYMENT_NAME 8443:8443 -n olm |
| 98 | +``` |
| 99 | + |
| 100 | +You can then curl the OLM `/debug/pprof` endpoint to retrieve default pprof profiles like so: |
| 101 | + |
| 102 | +```bash |
| 103 | +$ curl https://localhost:8443/debug/pprof/heap --cert certificate.crt --key private.key --insecure -o olm-heap |
| 104 | + |
| 105 | +$ go tool pprof --top olm-heap |
| 106 | +``` |
0 commit comments