sigs.k8s.io/cluster-api@v1.7.1/docs/book/src/tasks/diagnostics.md (about) 1 # Diagnostics 2 3 ## Introduction 4 5 With CAPI v1.6 we introduced new flags to allow serving metrics, the pprof endpoint and an endpoint to dynamically change log levels securely in production. 6 7 This feature is enabled per default via: 8 ```yaml 9 args: 10 - "--diagnostics-address=${CAPI_DIAGNOSTICS_ADDRESS:=:8443}" 11 ``` 12 13 As soon as the feature is enabled the metrics endpoint is served via https and protected via authentication and authorization. This works the same way as 14 metrics in core Kubernetes components: [Metrics in Kubernetes](https://kubernetes.io/docs/concepts/cluster-administration/system-metrics/). 15 16 To continue serving metrics via http the following configuration can be used: 17 ```yaml 18 args: 19 - "--diagnostics-address=localhost:8080" 20 - "--insecure-diagnostics" 21 ``` 22 23 The same can be achieved via clusterctl: 24 ```bash 25 export CAPI_DIAGNOSTICS_ADDRESS: "localhost:8080" 26 export CAPI_INSECURE_DIAGNOSTICS: "true" 27 clusterctl init ... 28 ``` 29 30 **Note**: If insecure serving is configured the pprof and log level endpoints are disabled for security reasons. 31 32 ## Scraping metrics 33 34 A ServiceAccount token is now required to scrape metrics. The corresponding ServiceAccount needs permissions on the `/metrics` path. 35 This can be achieved e.g. by following the [Kubernetes documentation](https://kubernetes.io/docs/concepts/cluster-administration/system-metrics/). 36 37 ### via Prometheus 38 39 With the Prometheus Helm chart it is as easy as using the following config for the Prometheus job scraping the Cluster API controllers: 40 ```yaml 41 scheme: https 42 authorization: 43 type: Bearer 44 credentials_file: /var/run/secrets/kubernetes.io/serviceaccount/token 45 tls_config: 46 ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt 47 # The diagnostics endpoint is using a self-signed certificate, so we don't verify it. 48 insecure_skip_verify: true 49 ``` 50 51 For more details please see our Prometheus development setup: [Prometheus](https://github.com/kubernetes-sigs/cluster-api/tree/main/hack/observability/prometheus) 52 53 **Note**: The Prometheus Helm chart deploys the required ClusterRole out-of-the-box. 54 55 ### via kubectl 56 57 First deploy the following RBAC configuration: 58 ```yaml 59 cat << EOT | kubectl apply -f - 60 apiVersion: rbac.authorization.k8s.io/v1 61 kind: ClusterRole 62 metadata: 63 name: default-metrics 64 rules: 65 - nonResourceURLs: 66 - "/metrics" 67 verbs: 68 - get 69 --- 70 apiVersion: rbac.authorization.k8s.io/v1 71 kind: ClusterRoleBinding 72 metadata: 73 name: default-metrics 74 roleRef: 75 apiGroup: rbac.authorization.k8s.io 76 kind: ClusterRole 77 name: default-metrics 78 subjects: 79 - kind: ServiceAccount 80 name: default 81 namespace: default 82 EOT 83 ``` 84 85 Then let's open a port-forward, create a ServiceAccount token and scrape the metrics: 86 ```bash 87 # Terminal 1 88 kubectl -n capi-system port-forward deployments/capi-controller-manager 8443 89 90 # Terminal 2 91 TOKEN=$(kubectl create token default) 92 curl https://localhost:8443/metrics --header "Authorization: Bearer $TOKEN" -k 93 ``` 94 95 ## Collecting profiles 96 97 ### via Parca 98 99 Parca can be used to continuously scrape profiles from CAPI providers. For more details please see our Parca 100 development setup: [parca](https://github.com/kubernetes-sigs/cluster-api/tree/main/hack/observability/parca) 101 102 ### via kubectl 103 104 First deploy the following RBAC configuration: 105 ```yaml 106 cat << EOT | kubectl apply -f - 107 apiVersion: rbac.authorization.k8s.io/v1 108 kind: ClusterRole 109 metadata: 110 name: default-pprof 111 rules: 112 - nonResourceURLs: 113 - "/debug/pprof/*" 114 verbs: 115 - get 116 --- 117 apiVersion: rbac.authorization.k8s.io/v1 118 kind: ClusterRoleBinding 119 metadata: 120 name: default-pprof 121 roleRef: 122 apiGroup: rbac.authorization.k8s.io 123 kind: ClusterRole 124 name: default-pprof 125 subjects: 126 - kind: ServiceAccount 127 name: default 128 namespace: default 129 EOT 130 ``` 131 132 Then let's open a port-forward, create a ServiceAccount token and scrape the profile: 133 ```bash 134 # Terminal 1 135 kubectl -n capi-system port-forward deployments/capi-controller-manager 8443 136 137 # Terminal 2 138 TOKEN=$(kubectl create token default) 139 140 # Get a goroutine dump 141 curl "https://localhost:8443/debug/pprof/goroutine?debug=2" --header "Authorization: Bearer $TOKEN" -k > ./goroutine.txt 142 143 # Get a profile 144 curl "https://localhost:8443/debug/pprof/profile?seconds=10" --header "Authorization: Bearer $TOKEN" -k > ./profile.out 145 go tool pprof -http=:8080 ./profile.out 146 ``` 147 148 ## Changing the log level 149 150 ### via kubectl 151 152 First deploy the following RBAC configuration: 153 ```yaml 154 cat << EOT | kubectl apply -f - 155 apiVersion: rbac.authorization.k8s.io/v1 156 kind: ClusterRole 157 metadata: 158 name: default-loglevel 159 rules: 160 - nonResourceURLs: 161 - "/debug/flags/v" 162 verbs: 163 - put 164 --- 165 apiVersion: rbac.authorization.k8s.io/v1 166 kind: ClusterRoleBinding 167 metadata: 168 name: default-loglevel 169 roleRef: 170 apiGroup: rbac.authorization.k8s.io 171 kind: ClusterRole 172 name: default-loglevel 173 subjects: 174 - kind: ServiceAccount 175 name: default 176 namespace: default 177 EOT 178 ``` 179 180 Then let's open a port-forward, create a ServiceAccount token and change the log level to `8`: 181 ```bash 182 # Terminal 1 183 kubectl -n capi-system port-forward deployments/capi-controller-manager 8443 184 185 # Terminal 2 186 TOKEN=$(kubectl create token default) 187 curl "https://localhost:8443/debug/flags/v" --header "Authorization: Bearer $TOKEN" -X PUT -d '8' -k 188 ```