-
Notifications
You must be signed in to change notification settings - Fork 203
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remove dependency for kube-rbac-proxy and add secure-metrics feature #3833
Changes from 3 commits
7938491
ec4b7fb
3df85ba
f0dc11a
93964d0
b15c3f7
e544203
a04af18
5283762
8f243f3
99969f3
752e319
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,7 +7,7 @@ The metrics exposed fall into two groups: Azure based metrics, and reconciler me | |
|
||
## Toggling the metrics | ||
|
||
By default, metrics for ASOv2 are turned on and can be toggled by the following options: | ||
By default, secure metrics for ASOv2 are turned on and can be toggled by the following options: | ||
matthchr marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
- ### ASOv2 Helm Chart | ||
|
||
|
@@ -16,7 +16,8 @@ By default, metrics for ASOv2 are turned on and can be toggled by the following | |
|
||
``` | ||
--set metrics.enable=true/false (default: true) | ||
--set metrics.address=0.0.0.0:8080 (default) | ||
--set metrics.secure-metrics=true/false (default: false) | ||
--set metrics.address=0.0.0.0:8080 (default) | ||
``` | ||
|
||
- ### Deployment YAML | ||
|
@@ -29,8 +30,71 @@ By default, metrics for ASOv2 are turned on and can be toggled by the following | |
containers: | ||
- args: | ||
- --metrics-addr=0.0.0.0:8080 (default) | ||
- --secure-metrics=true/false (default: false) | ||
``` | ||
|
||
|
||
## Scraping Metrics Securely via HTTPs | ||
|
||
A ServiceAccount token is required to scrape metrics securely. The corresponding ServiceAccount needs permissions on the "/metrics" and "debug/pprof" paths. | ||
This can be achieved e.g. by following the [Kubernetes documentation](https://kubernetes.io/docs/concepts/cluster-administration/system-metrics/). | ||
|
||
- Use the settings below in your deployment: | ||
super-harsh marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
- #### ASOv2 Helm Chart | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think this bullet point needs to be a heading - and if it were a heading, it would be 3rd level, not 4th. Suggest changing to plain text. |
||
``` | ||
--set metrics.enable=true | ||
--set metrics.secure-metrics=true | ||
--set metrics.address=0.0.0.0:8443 | ||
``` | ||
|
||
- #### Deployment YAML | ||
``` | ||
spec: | ||
containers: | ||
- args: | ||
- --metrics-addr=0.0.0.0:8443 | ||
- --secure-metrics=true | ||
``` | ||
|
||
- Deploy the following RBAC configuration: | ||
super-harsh marked this conversation as resolved.
Show resolved
Hide resolved
|
||
``` | ||
cat << EOT | kubectl apply -f - | ||
apiVersion: rbac.authorization.k8s.io/v1 | ||
kind: ClusterRole | ||
metadata: | ||
name: default-metrics | ||
rules: | ||
- nonResourceURLs: | ||
- "/metrics" | ||
- "/debug/pprof/*" | ||
verbs: | ||
- get | ||
--- | ||
apiVersion: rbac.authorization.k8s.io/v1 | ||
kind: ClusterRoleBinding | ||
metadata: | ||
name: default-metrics | ||
roleRef: | ||
apiGroup: rbac.authorization.k8s.io | ||
kind: ClusterRole | ||
name: default-metrics | ||
subjects: | ||
- kind: ServiceAccount | ||
name: default | ||
namespace: default | ||
EOT | ||
``` | ||
- Open a port-forward | ||
super-harsh marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
``` | ||
kubectl port-forward deployments/azureserviceoperator-controller-manager -n azureserviceoperator-system 8443 | ||
``` | ||
- Create a ServiceAccount token and scrape metrics | ||
``` | ||
TOKEN=$(kubectl create token default) | ||
curl https://localhost:8443/metrics --header "Authorization: Bearer $TOKEN" -k | ||
``` | ||
|
||
## Understanding the ASOv2 Metrics | ||
|
||
| Metric | Description | Label 1 | Label 2 | Label 3 | | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,11 +4,10 @@ | |
|
||
set -e | ||
|
||
KUBE_RBAC_PROXY=$1 | ||
LOCAL_REGISTRY_CONTROLLER_DOCKER_IMAGE=$2 | ||
PUBLIC_REGISTRY=$3 | ||
VERSION=$4 | ||
DIR=$5 | ||
LOCAL_REGISTRY_CONTROLLER_DOCKER_IMAGE=$1 | ||
PUBLIC_REGISTRY=$2 | ||
VERSION=$3 | ||
DIR=$4 | ||
|
||
ASO_CHART="$DIR"charts/azure-service-operator | ||
GEN_FILES_DIR="$ASO_CHART"/templates/generated | ||
|
@@ -43,8 +42,8 @@ rm "$GEN_FILES_DIR"/*_namespace_* # remove namespace as we will let Helm manage | |
sed -i "s/\(version: \)\(.*\)/\1${VERSION//v}/g" "$ASO_CHART"/Chart.yaml # find version key and update the value with the current version | ||
|
||
# Deployment replacements | ||
grep -E $KUBE_RBAC_PROXY "$GEN_FILES_DIR"/*_deployment_* > /dev/null # Ensure that what we're about to try to replace actually exists (if it doesn't we want to fail) | ||
sed -i "s@$KUBE_RBAC_PROXY.*@{{.Values.image.kubeRBACProxy}}@g" "$GEN_FILES_DIR"/*_deployment_* | ||
#grep -E $KUBE_RBAC_PROXY "$GEN_FILES_DIR"/*_deployment_* > /dev/null # Ensure that what we're about to try to replace actually exists (if it doesn't we want to fail) | ||
#sed -i "s@$KUBE_RBAC_PROXY.*@{{.Values.image.kubeRBACProxy}}@g" "$GEN_FILES_DIR"/*_deployment_* | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Commented out - either restore or delete. |
||
sed -i "s@$LOCAL_REGISTRY_CONTROLLER_DOCKER_IMAGE@{{.Values.image.repository}}@g" "$GEN_FILES_DIR"/*_deployment_* # Replace hardcoded ASO image | ||
# Perl multiline replacements - using this because it's tricky to do these sorts of multiline replacements with sed | ||
perl -0777 -i -pe 's/(template:\n.*metadata:\n.*annotations:\n(\s*))/$1\{\{- if .Values.podAnnotations \}\}\n$2\{\{ toYaml .Values.podAnnotations \}\}\n$2\{\{- end \}\}\n$2/igs' "$GEN_FILES_DIR"/*_deployment_* # Add pod annotations | ||
|
@@ -54,7 +53,8 @@ perl -0777 -i -pe 's/(spec:\n.*template:\n.*spec:\n(\s*))/$1\{\{- with .Values.a | |
perl -0777 -i -pe 's/(spec:\n.*template:\n.*spec:\n(\s*))/$1\{\{- with .Values.tolerations \}\}\n$2tolerations:\n$2\{\{- toYaml . | nindent 8 \}\}\n$2\{\{- end \}\}\n$2/igs' "$GEN_FILES_DIR"/*_deployment_* # Add pod annotations | ||
|
||
# Metrics Configuration | ||
flow_control "metrics-addr" "metrics-addr" "{{- if .Values.metrics.enable}}" "$GEN_FILES_DIR"/*_deployment_* | ||
flow_control "metrics-addr" "secure-metrics" "{{- if .Values.metrics.enable}}" "$GEN_FILES_DIR"/*_deployment_* | ||
sed -i "1,/secure-metrics=.*/s/\(secure-metrics=\)\(.*\)/\1{{ .Values.metrics.secureMetrics }}/g" "$GEN_FILES_DIR"/*_deployment_* | ||
sed -i "1,/metrics-addr=.*/s/\(metrics-addr=\)\(.*\)/\1{{ tpl .Values.metrics.address . }}/g" "$GEN_FILES_DIR"/*_deployment_* | ||
sed -i 's/containerPort: 8080/containerPort: {{ .Values.metrics.port | default 8080 }}/g' "$GEN_FILES_DIR"/*_deployment_* | ||
sed -i '1 i {{- if .Values.metrics.enable -}}' "$GEN_FILES_DIR"/*controller-manager-metrics-service* | ||
|
@@ -87,8 +87,8 @@ flow_control "aadpodidbinding" "aadpodidbinding" "$IF_TENANT" "$GEN_FILES_DIR"/* | |
|
||
flow_control "--enable-leader-election" "--enable-leader-election" "$IF_TENANT" "$GEN_FILES_DIR"/*_deployment_* | ||
|
||
# TODO: This bit is tricky to exclude kube-rbac-proxy and webhook stuff. | ||
flow_control "mountPath: \/tmp\/k8s-webhook-server\/serving-certs" "name: https" "$IF_CLUSTER" "$GEN_FILES_DIR"/*_deployment_* | ||
sed -i "/mountPath: \/tmp\/k8s-webhook-server\/serving-certs/i \ \ $IF_CLUSTER" "$GEN_FILES_DIR"/*_deployment_* | ||
sed -i "/nodeSelector:/i \ \ {{- end }}" "$GEN_FILES_DIR"/*_deployment_* | ||
flow_control "- name: cert" "secretName" "$IF_CLUSTER" "$GEN_FILES_DIR"/*_deployment_* | ||
flow_control "--webhook-cert-dir=" "--webhook-cert-dir=" "$IF_CLUSTER" "$GEN_FILES_DIR"/*_deployment_* | ||
sed -i 's/\/tmp\/k8s-webhook-server\/serving-certs/{{ .Values.webhook.certDir }}/g' "$GEN_FILES_DIR"/*_deployment_* | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -92,6 +92,9 @@ image: | |
# 'address' field defines the metrics binding address on which metrics | ||
metrics: | ||
enable: true | ||
# secureMetrics controls whether metrics should be served via 'http' or 'https'. | ||
matthchr marked this conversation as resolved.
Show resolved
Hide resolved
|
||
# Flagging secureMetrics as true would use https | ||
secureMetrics: false | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The comment in this yaml file reinforces my earlier question about whether secure metrics are turned on by default. |
||
address: 0.0.0.0:{{ .Values.metrics.port }} | ||
port: 8080 | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,6 +9,8 @@ import ( | |
"context" | ||
"fmt" | ||
"math/rand" | ||
"net/http" | ||
"net/http/pprof" | ||
"os" | ||
"regexp" | ||
"time" | ||
|
@@ -131,9 +133,7 @@ func SetupControllerManager(ctx context.Context, setupLog logr.Logger, flgs Flag | |
LeaderElection: flgs.EnableLeaderElection, | ||
LeaderElectionID: "controllers-leader-election-azinfra-generated", | ||
HealthProbeBindAddress: flgs.HealthAddr, | ||
Metrics: server.Options{ | ||
BindAddress: flgs.MetricsAddr, | ||
}, | ||
Metrics: getMetricsOpts(flgs), | ||
WebhookServer: webhook.NewServer(webhook.Options{ | ||
Port: flgs.WebhookPort, | ||
CertDir: flgs.WebhookCertDir, | ||
|
@@ -253,6 +253,29 @@ func SetupControllerManager(ctx context.Context, setupLog logr.Logger, flgs Flag | |
return mgr | ||
} | ||
|
||
func getMetricsOpts(flags Flags) server.Options { | ||
var metricsOptions server.Options | ||
if flags.SecureMetrics { | ||
metricsOptions = server.Options{ | ||
BindAddress: flags.MetricsAddr, | ||
SecureServing: flags.SecureMetrics, | ||
// Note that pprof endpoints are meant to be sensitive and shouldn't be exposed publicly. | ||
ExtraHandlers: map[string]http.Handler{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We probably should have a specific cmdline flag that enables this and it should default to off. This is what apiserver does via the I'd argue we should have both Secure metrics shouldn't (IMO) require that you expose pprof. |
||
"/debug/pprof/": http.HandlerFunc(pprof.Index), | ||
"/debug/pprof/cmdline": http.HandlerFunc(pprof.Cmdline), | ||
"/debug/pprof/profile": http.HandlerFunc(pprof.Profile), | ||
"/debug/pprof/symbol": http.HandlerFunc(pprof.Symbol), | ||
"/debug/pprof/trace": http.HandlerFunc(pprof.Trace), | ||
}, | ||
} | ||
} else { | ||
metricsOptions = server.Options{ | ||
BindAddress: flags.MetricsAddr, | ||
} | ||
} | ||
return metricsOptions | ||
} | ||
|
||
func getDefaultAzureCredential(cfg config.Values, setupLog logr.Logger) (*identity.Credential, error) { | ||
tokenCred, err := getDefaultAzureTokenCredential(cfg, setupLog) | ||
if err != nil { | ||
|
This file was deleted.
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are they really turned on, given the option below says
default: false
?