feat: operator support set basic auth for prometheus server#7004
feat: operator support set basic auth for prometheus server#7004Xu-Wentao wants to merge 1 commit intoprometheus-operator:mainfrom
Conversation
simonpasquier
left a comment
There was a problem hiding this comment.
We have to solve the issue of Kubernetes probes not working if you configure basic-auth.
pkg/apis/monitoring/v1/types.go
Outdated
| // +k8s:openapi-gen=true | ||
| type WebBasicAuthUsers struct { | ||
| Username string `json:"username"` | ||
| Password string `json:"password"` |
There was a problem hiding this comment.
you don't want passwords in clear text inside the Prometheus CRD.
There was a problem hiding this comment.
yes, i'm on the way to slove this. i'm going to store username and password in secret use the BasicAuth, and when reconcile Prometheus resource, we can get info from secret and then set basic auth. Also, set probe to solve the kubernetes readiness check.
There was a problem hiding this comment.
It's not acceptable from a security standpoint to store credentials in clear-text in the statefulset spec. We need prometheus/exporter-toolkit#151 to allow unauthenticated access to the probe endpoints.
afbf6ef to
f6f68dd
Compare
|
@simonpasquier hi, i have changed the type of |
9d5cf60 to
4394394
Compare
|
There's also the question of the Thanos sidecar and config reloader which require authentication credentials too. |
ok.I will finish it. bytheway, maybe prometheus and other components can exclued health check api for authicated like the issue prometheus/prometheus#9166 mentioned. |
f1c5222 to
7294342
Compare
|
I'm on the fence regarding the API: I wonder if the operator should be in charge of producing the brypt hashes or if it should pass the secret data as-is to Prometheus (and let the user provide the hashes). In particular involving the operator with security concerns is always a risk for the long-term maintenance. |
|
After more thinking, I realize that the simplest API might be for the user to provide a secret containing all the credentials where the username would be the key and the password the value: apiVersion: v1
kind: Secret
metadata:
name: web-users
stringData:
foo: $2b$12$hNf2lSsxfm0.i4a.1kVpSOVyBCfIB51VRjgBUyv6kdnyTlgWj81Ay
bar: $2b$12$hNf2lSsxfm0.i4a.1kVpSOVyBCfIB51VRjgBUyv6kdnyTlgWj81Ay
prometheus: $2b$12$hNf2lSsxfm0.i4a.1kVpSOVyBCfIB51VRjgBUyv6kdnyTlgWj81Ay
---
apiVersion: v1
kind: Secret
metadata:
name: example-webconfig
stringData:
password: test
---
apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
name: example
spec:
web:
basicAuthUsers:
secretName: web-users
podCredentials:
username: prometheus
password:
key: password
name: example-webconfigThe operator can fail the reconciliation if it detects invalid hashes in the secret (e.g. using Again sorry for the back and forth but I didn't put a lot of effort in this part before your PR so thanks for doing it! |
Ok, I'll try to change the API as you recommended, But the way, when i try to set a correct config of |
For sure, we don't want the HTTP client config to be in clear-text if it contains sensitive information like password so yes, we'll need to change this and probably use a dedicated secret mounted in the sidecar. And we need the same for the config reloader sidecar. I'd say that it should be a preliminary PR to this one to facilitate the review process. For context, both thanos and config-reloader sidecars had to disable TLS verification because they only connect through localhost and we didn't want to bother with configuring the right CA. |
I find that the config-reloader's |
|
For the config reloader, the idea should be to add CLI arguments to pass the basic-auth user/password in https://github.com/prometheus-operator/prometheus-operator/blob/main/cmd/prometheus-config-reloader/main.go and use something like https://pkg.go.dev/k8s.io/[email protected]/transport#NewBasicAuthRoundTripper to inject the header in the request. |
| if err != nil { | ||
| fmt.Printf("Failed to read password file: %v\n", err) | ||
| } else { | ||
| rt = newBasicAuthRoundTripper(podCredentialsUsername, strings.TrimSpace(string(password)), rt) |
There was a problem hiding this comment.
There is an existing basic roundtripper in prometheus common config.NewBasicAuthRoundTripper() https://github.com/prometheus/common/blob/main/config/http_config.go#L839 maybe it would be better to reuse it
1a40b77 to
5a97c7b
Compare
51926ed to
efc4822
Compare
simonpasquier
left a comment
There was a problem hiding this comment.
I've got remarks on the API. We need to add more validations.
| RUN --mount=type=cache,target=/go/pkg/mod --mount=type=cache,target=/root/.cache/go-build make prometheus-config-reloader | ||
|
|
||
| FROM quay.io/prometheus/busybox-${OS}-${ARCH}:latest | ||
| FROM quay.io/prometheus/busybox-linux-${ARCH}:latest |
There was a problem hiding this comment.
Sorry, i built on my mac and run on linux machine. i will revert this.
| runtimeInfoURL := app.Flag("runtimeinfo-url", "URL to check the status of the runtime configuration"). | ||
| Default("http://127.0.0.1:9090/api/v1/status/runtimeinfo").URL() | ||
|
|
||
| podCredentialsUsername := app.Flag("pod-credentials-username", "Username for basic auth for prometheus server.").Default("").String() |
There was a problem hiding this comment.
| podCredentialsUsername := app.Flag("pod-credentials-username", "Username for basic auth for prometheus server.").Default("").String() | |
| podCredentialsUsername := app.Flag("basic-auth-username", "Username for Basic-Auth authorization.").Default("").String() |
| Default("http://127.0.0.1:9090/api/v1/status/runtimeinfo").URL() | ||
|
|
||
| podCredentialsUsername := app.Flag("pod-credentials-username", "Username for basic auth for prometheus server.").Default("").String() | ||
| podCredentialsPassword := app.Flag("pod-credentials-password-file", "Password file for basic auth for prometheus server.").Default("").String() |
There was a problem hiding this comment.
| podCredentialsPassword := app.Flag("pod-credentials-password-file", "Password file for basic auth for prometheus server.").Default("").String() | |
| podCredentialsPassword := app.Flag("basic-auth-password-file", "File containing the password for Basic-Auth authorization.").Default("").String() |
pkg/apis/monitoring/v1/types.go
Outdated
| // Defines the name of secret stored basic auth users. | ||
| SecretName *string `json:"secretName"` |
There was a problem hiding this comment.
| // Defines the name of secret stored basic auth users. | |
| SecretName *string `json:"secretName"` | |
| // Defines the secret containing the list of users (keys) with their hashed passwords (values). | |
| // The secret must contain a key for the service account. | |
| // +required | |
| SecretRef SecretReference `json:"secretRef"` |
with
type SecretReference struct {
// Name of the secret in the resource's namespace.
// +required
// +kubebuilder:validation:MinLength=1
Name string `json:"name"`
}
pkg/apis/monitoring/v1/types.go
Outdated
| type BasicAuthUsers struct { | ||
| // Defines the name of secret stored basic auth users. | ||
| SecretName *string `json:"secretName"` | ||
| // Defines the pod credentials for health check probe of prometheus server. |
There was a problem hiding this comment.
| // Defines the pod credentials for health check probe of prometheus server. | |
| // Defines the secret's key holding the password used by the service account to query the web server. | |
| // The service account must exist in the users secret. |
pkg/apis/monitoring/v1/types.go
Outdated
| // Defines the name of secret stored basic auth users. | ||
| SecretName *string `json:"secretName"` | ||
| // Defines the pod credentials for health check probe of prometheus server. | ||
| PodCredentials *v1.SecretKeySelector `json:"podCredentials"` |
There was a problem hiding this comment.
| PodCredentials *v1.SecretKeySelector `json:"podCredentials"` | |
| // +required | |
| ServiceAccountPasswordRef SecretKeySelector `json:"serviceAccountPasswordRef"` |
type SecretKeySelector struct {
SecretReference
// The key of the secret to select from.
// +required
// +kubebuilder:validation:MinLength=1
Key string `json:"key"`
}042c98d to
ac8a562
Compare
|
@simonpasquier hi, i have use object reference to secrets as you mentioned, is there any other things i can to to move on? |
80006bb to
fde3e1e
Compare
bf191d8 to
1f09e0b
Compare
Signed-off-by: xuwentao <[email protected]>
Description
Support set basic auth info from secret and set statefulset probe's httpGet headers.
Aim to solve #5836
Type of change
What type of changes does your code introduce to the Prometheus operator? Put an
xin the box that apply.CHANGE(fix or feature that would cause existing functionality to not work as expected)FEATURE(non-breaking change which adds functionality)BUGFIX(non-breaking change which fixes an issue)ENHANCEMENT(non-breaking change which improves existing functionality)NONE(if none of the other choices apply. Example, tooling, build system, CI, docs, etc.)Verification
Please check the Prometheus-Operator testing guidelines for recommendations about automated tests.
Changelog entry
Please put a one-line changelog entry below. This will be copied to the changelog file during the release process.