Skip to content
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

client-go's InClusterConfig does not implement documented API discovery heuristics #112263

Closed
olix0r opened this issue Sep 6, 2022 · 6 comments · Fixed by kubernetes/website#36691
Labels
kind/bug Categorizes issue or PR as related to a bug. sig/api-machinery Categorizes an issue or PR as relevant to SIG API Machinery. triage/accepted Indicates an issue or PR is ready to be actively worked on.

Comments

@olix0r
Copy link

olix0r commented Sep 6, 2022

What happened?

client-go uses KUBERNETES_SERVICE_HOST to discover the API service address:

// InClusterConfig returns a config object which uses the service account
// kubernetes gives to pods. It's intended for clients that expect to be
// running inside a pod running on kubernetes. It will return ErrNotInCluster
// if called from a process not running in a kubernetes environment.
func InClusterConfig() (*Config, error) {
const (
tokenFile = "/var/run/secrets/kubernetes.io/serviceaccount/token"
rootCAFile = "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
)
host, port := os.Getenv("KUBERNETES_SERVICE_HOST"), os.Getenv("KUBERNETES_SERVICE_PORT")
if len(host) == 0 || len(port) == 0 {
return nil, ErrNotInCluster
}
token, err := os.ReadFile(tokenFile)
if err != nil {
return nil, err
}
tlsClientConfig := TLSClientConfig{}
if _, err := certutil.NewPool(rootCAFile); err != nil {
klog.Errorf("Expected to load root CA config from %s, but got err: %v", rootCAFile, err)
} else {
tlsClientConfig.CAFile = rootCAFile
}
return &Config{
// TODO: switch to using cluster DNS.
Host: "https://" + net.JoinHostPort(host, port),
TLSClientConfig: tlsClientConfig,
BearerToken: string(token),
BearerTokenFile: tokenFile,
}, nil
}

This at odds with the documentation at https://kubernetes.io/docs/tasks/run-application/access-api-from-pod/#directly-accessing-the-rest-api which states:

While running in a Pod, the Kubernetes apiserver is accessible via a Service named kubernetes in the default namespace. Therefore, Pods can use the kubernetes.default.svc hostname to query the API server. Official client libraries do this automatically.

client-go does not do this. Though, it includes a TODO:

		// TODO: switch to using cluster DNS.
		Host:            "https://" + net.JoinHostPort(host, port),

Ambiguity around the documented client discovery policy causes problems for client libraries; and cloud providers continue to promulgate the (now undocumented) legacy env configuration, e.g. Azure/AKS#3183.

Would you accept a PR to remove the environment based in-cluster configuration in favor of always using kubernetes.default.svc?

What did you expect to happen?

client-go should use kubernetes.default.svc and it should not honor the KUBERNETES_SERVICE_HOST environment variable.

OR the client docs should be updated with the proper heuristics.

How can we reproduce it (as minimally and precisely as possible)?

...

Anything else we need to know?

No response

Kubernetes version

1.24

Cloud provider

AKS

OS version

No response

Install tools

No response

Container runtime (CRI) and version (if applicable)

No response

Related plugins (CNI, CSI, ...) and versions (if applicable)

No response

@olix0r olix0r added the kind/bug Categorizes issue or PR as related to a bug. label Sep 6, 2022
@k8s-ci-robot k8s-ci-robot added needs-sig Indicates an issue or PR lacks a `sig/foo` label and requires one. needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one. labels Sep 6, 2022
@olix0r
Copy link
Author

olix0r commented Sep 6, 2022

/sig api-machinery

@k8s-ci-robot k8s-ci-robot added sig/api-machinery Categorizes an issue or PR as relevant to SIG API Machinery. and removed needs-sig Indicates an issue or PR lacks a `sig/foo` label and requires one. labels Sep 6, 2022
@leilajal
Copy link
Contributor

leilajal commented Sep 6, 2022

/cc @Jefftree
/triage accepted

@k8s-ci-robot k8s-ci-robot added triage/accepted Indicates an issue or PR is ready to be actively worked on. and removed needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one. labels Sep 6, 2022
olix0r added a commit to olix0r/kube-rs that referenced this issue Sep 7, 2022
The `Config::from_cluster_env` constructor is misleadingly named: it
doesn't use the environment, it uses the default cluster configurations.

This change deprecates the `Config::from_cluster_env` constructor in
favor of `Config::load_in_cluster`. An additional constructor,
`Config::load_in_cluster_from_legacy_env`, uses the
`KUBERNETES_SERVICE_HOST` and `KUBERNETES_SERVICE_PORT` environment
variables to match client-go's behavior.

This changes does NOT alter the default inferred configuration in any
way. It simply allows users to opt-in to using the old behavior.

Related to kubernetes/kubernetes#112263
Closes kube-rs#1000

Signed-off-by: Oliver Gould <ver@buoyant.io>
olix0r added a commit to olix0r/kube-rs that referenced this issue Sep 7, 2022
The `Config::from_cluster_env` constructor is misleadingly named: it
doesn't use the environment, it uses the default cluster configurations.

This change deprecates the `Config::from_cluster_env` constructor in
favor of `Config::load_in_cluster`. An additional constructor,
`Config::load_in_cluster_from_legacy_env`, uses the
`KUBERNETES_SERVICE_HOST` and `KUBERNETES_SERVICE_PORT` environment
variables to match client-go's behavior.

This changes does NOT alter the default inferred configuration in any
way. It simply allows users to opt-in to using the old behavior.

Related to kubernetes/kubernetes#112263
Closes kube-rs#1000

Signed-off-by: Oliver Gould <ver@buoyant.io>
@liggitt
Copy link
Member

liggitt commented Sep 7, 2022

The client docs should be updated, rather than change the client-go implementation. Making client-go depend on DNS is not a completely compatible change

olix0r added a commit to olix0r/website that referenced this issue Sep 8, 2022
The documentation incorrectly describes the way that client libraries
discover the Kubernetes API server. While the `kubernetes.default.svc`
DNS is provided as a convenience, **all** of the officially supported API
clients use environment variables to discover the address of the API server.

This change updates the documentation to reflect this.

Fixes kubernetes/kubernetes#112263

Signed-off-by: Oliver Gould <ver@buoyant.io>
clux pushed a commit to kube-rs/kube that referenced this issue Sep 9, 2022
* client: Expose a Config constructor to support legacy configurations

The `Config::from_cluster_env` constructor is misleadingly named: it
doesn't use the environment, it uses the default cluster configurations.

This change deprecates the `Config::from_cluster_env` constructor in
favor of `Config::load_in_cluster`. An additional constructor,
`Config::load_in_cluster_from_legacy_env`, uses the
`KUBERNETES_SERVICE_HOST` and `KUBERNETES_SERVICE_PORT` environment
variables to match client-go's behavior.

This changes does NOT alter the default inferred configuration in any
way. It simply allows users to opt-in to using the old behavior.

Related to kubernetes/kubernetes#112263
Closes #1000

Signed-off-by: Oliver Gould <ver@buoyant.io>

* constify "https" scheme to make accidental "http" harder

Signed-off-by: Oliver Gould <ver@buoyant.io>

* Restore `Config::from_cluster_env` naming

Add `Config::from_cluster_dns` to support the current behavior.

Signed-off-by: Oliver Gould <ver@buoyant.io>

* Disable the in-cluster rustls test

Signed-off-by: Oliver Gould <ver@buoyant.io>

* fix typo

Signed-off-by: Oliver Gould <ver@buoyant.io>

* client: Make discovery conditional on the TLS impl

When `rustls-tls` is enabled, the `kubernetes.default.svc` DNS name is
used. Otherwise, the `KUBERNETES_SERVICE_{HOST,PORT}` environment
variables are used.

Signed-off-by: Oliver Gould <ver@buoyant.io>

* Review feedback

* Make `Config::incluster_env` and `Config::incluster_dns` public
  regardless of what features are enabled.
* Restrict visibility for `pub` helpers that are not actually publicly
  exported.

Signed-off-by: Oliver Gould <ver@buoyant.io>

* Add URI-formatting tests

Signed-off-by: Oliver Gould <ver@buoyant.io>

* fmt

Signed-off-by: Oliver Gould <ver@buoyant.io>

Signed-off-by: Oliver Gould <ver@buoyant.io>
@k8s-triage-robot
Copy link

The Kubernetes project currently lacks enough contributors to adequately respond to all issues and PRs.

This bot triages issues and PRs according to the following rules:

  • After 90d of inactivity, lifecycle/stale is applied
  • After 30d of inactivity since lifecycle/stale was applied, lifecycle/rotten is applied
  • After 30d of inactivity since lifecycle/rotten was applied, the issue is closed

You can:

  • Mark this issue or PR as fresh with /remove-lifecycle stale
  • Mark this issue or PR as rotten with /lifecycle rotten
  • Close this issue or PR with /close
  • Offer to help out with Issue Triage

Please send feedback to sig-contributor-experience at kubernetes/community.

/lifecycle stale

@k8s-ci-robot k8s-ci-robot added the lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. label Dec 7, 2022
@olix0r
Copy link
Author

olix0r commented Dec 7, 2022

/remove-lifecycle stale

kubernetes/website#36691 has been open since September. Has approvals. Still waiting for a merge...

@k8s-ci-robot k8s-ci-robot removed the lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. label Dec 7, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/bug Categorizes issue or PR as related to a bug. sig/api-machinery Categorizes an issue or PR as relevant to SIG API Machinery. triage/accepted Indicates an issue or PR is ready to be actively worked on.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants