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

Replace usage of static client credentials for components running in seed talking to the shoot API server #4661

Closed
35 tasks done
Tracked by #4878
rfranzke opened this issue Sep 14, 2021 · 3 comments · Fixed by #5685
Closed
35 tasks done
Tracked by #4878
Assignees
Labels
area/security Security related kind/enhancement Enhancement, improvement, extension priority/2 Priority (lower number equals higher priority) roadmap/cloud Roadmap for the (managed) cloud delivery, i.e. gardener.cloud.sap
Milestone

Comments

@rfranzke
Copy link
Member

rfranzke commented Sep 14, 2021

How to categorize this issue?

/area security
/kind enhancement
/priority 2

What would you like to be added:

Today, all of the components running in the seed clusters and talking to the shoot's API server use a kubeconfig with a static client certificate issued by the cluster's certificate authority (example).

Instead, let's start using similar concepts compared to projected ServiceAccount tokens supported since Kubernetes v1.12.

Concretely, we have to use the TokenRequest API of the shoot's API server to issue short-lived tokens for the respective components.
The tokens should be stored in dedicated Secrets in the shoot namespace in the seed cluster so that they can be mounted to the respective Pods.
Similar to how the kubelet issues a new token when the lifetime reaches 80%, we should refresh such tokens regularly and update them in the respective Secrets in the seed.

This also allows us to use the same kubeconfig for all components which plays well together with what is proposed in #3598.
Also, it helps reducing the load of the Garden cluster since no client certificates/kubeconfigs would be generated anymore for such components, hence, reducing the size of the ShootState and also the size of the etcd backup.

For example, the following kubeconfig could be generated by gardenlet and stored in the kubeconfig Secret in the shoot namespace:

apiVersion: v1
kind: Secret
metadata:
  name: kubeconfig
  namespace: shoot--foo--bar
type: Opaque
stringData:
  kubeconfig.yaml: |
    apiVersion: v1
    kind: Config
    current-context: shoot--foo--bar
    clusters:
    - cluster:
        server: https://kube-apiserver
      name: shoot--foo--bar
    contexts:
    - name: shoot--foo--bar
      context:
        user: shoot--foo--bar
        cluster: shoot--foo--bar
    users:
    - name: shoot--foo--bar
      user:
        tokenFile: /var/run/secrets/gardener.cloud/shoot/token

Also, let's say the short-lived token was stored in the some-component-shoot-token Secret in the shot namespace:

apiVersion: v1
kind: Secret
metadata:
  name: some-component-shoot-token
  namespace: shoot--foo--bar
type: Opaque
stringData:
  token: some-token

Then the PodSpec would look as follows:

apiVersion: v1
kind: Pod
spec:
  volumes:
  - name: kubeconfig
    secret:
      secretName: kubeconfig
  - name: shoot-token
    secret:
      secretName: some-component-shoot-token
  containers:
  - name: foo
    volumeMounts:
    - name: kubeconfig
      mountPath: /var/run/secrets/gardener.cloud/kubeconfig
      readOnly: true
    - name: shoot-token
      mountPath: /var/run/secrets/gardener.cloud/shoot
      readOnly: true
    command:
    - /foo
    - --kubeconfig=/var/run/secrets/gardener.cloud/kubeconfig/kubeconfig.yaml
...

Why is this needed:

In order to eliminate static credentials requiring costly manual rotation which doesn't scale.
Projected ServiceAccount tokens can be configured with expirationSeconds and are regularly auto-rotated and re-mounted by the kubelet without further do.
Clients are expected to regularly reload the token, however, the client-go supports reloading the tokens specified in tokenFiles since v10.0.0, (see kubernetes/kubernetes#70606), and most of the components are either already using this version or could be updated.

Target Picture:

New in this picture is: Secret with short-lived token. Also the pod spec is adapted to mount the token and the component-kubeconfig points to the mounted tokenFile.
In the Shoot the ServiceAccount needs to be added and referenced by the existing rolebinding.

target Picture

Open Questions:

  • Do all components support auto reloading tokens from disk -> Seems like yes supported in client-go since v1.13.0.
  • Does the kubelet auto-remount secrets if the data of the secret changes -> yes
  • Do we want to reuse a component for our controller (like the grm) or create a new component which includes this token functionality. -> we use the grm for now
  • How is the controller itself authenticated against the KAPI?
  • Adapt all components running in the Seed targeting the Shoot to use a non-static token.
  • We create a significant amount of API requests on the Seed API server when updating tokens of all components in the Shoot namespaces upon token expiration. Will this have scaling performance implications on the Seed APIServer?
  • How often do we want to rotate the tokens? What to choose for expiration time?
  • A TokenRequest also includes an audiences. We are currently unsure what this field does.

Tasks:

@rfranzke rfranzke added the kind/enhancement Enhancement, improvement, extension label Sep 14, 2021
@gardener-robot gardener-robot added area/security Security related priority/2 Priority (lower number equals higher priority) labels Sep 14, 2021
@rfranzke rfranzke added the roadmap/cloud Roadmap for the (managed) cloud delivery, i.e. gardener.cloud.sap label Sep 14, 2021
@rfranzke rfranzke changed the title Replace usage of static ServiceAccount tokens for components running in seed talking to the shoot API server Replace usage of static client certificates for components running in seed talking to the shoot API server Sep 14, 2021
@rfranzke rfranzke added this to the 2022-Q1 milestone Sep 14, 2021
@rfranzke
Copy link
Member Author

/assign @BeckerMax @rfranzke
/in-progress

@rfranzke rfranzke changed the title Replace usage of static client certificates for components running in seed talking to the shoot API server Replace usage of static client credentials for components running in seed talking to the shoot API server Dec 8, 2021
@jia-jerry
Copy link
Contributor

@rfranzke , I like this pic you drew because it help us understand how to rotate shoot kubeconfig token easily. Do you have plan to add this token rotation process in the gardener doc?

@rfranzke
Copy link
Member Author

@jia-jerry There are already other, probably more detailed pics in the docs: https://github.com/gardener/gardener/blob/master/docs/concepts/resource-manager.md#tokenrequestor

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/security Security related kind/enhancement Enhancement, improvement, extension priority/2 Priority (lower number equals higher priority) roadmap/cloud Roadmap for the (managed) cloud delivery, i.e. gardener.cloud.sap
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants