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

Strongly discourage applications from talking to the Kubernetes API Server #461

Open
scothis opened this issue Sep 4, 2019 · 9 comments

Comments

@scothis
Copy link

scothis commented Sep 4, 2019

Spring Cloud Kubernetes encourages applications to talk directly to the Kubernetes API Server to get ConfigMap/Secret values and resolve Services. This is an anti-pattern that should be discouraged.

  1. An application that needs to talk to the API service is unnecessarily coupled to Kubernetes violating Inversion of Control.
  2. The API Server is a control plane and is not designed to scale out along side an application. If every application instance needs a connection to the server, the scalability of the cluster will be limited.
  3. It violates least privilege. An exploited application should not be able to fetch configuration and secrets that the application shouldn’t have access to. While RBAC is able to limit access to specific resources for a service account, this is inefficient and requires significant additional configuration that must be maintained.

In general, applications should not need to know that they are running in Kubernetes.

Alternatives:

ConfigMaps and Secrets can instead be bound to Pods via volume mounts where each key is exposed as a file in a directory. The PropertySource can read from the filesystem to get the same effect as talking to the API Server. The files will be updated with the latest values, so reloadability is still available by watching the filesystem for changes.

https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/#add-configmap-data-to-a-volume

Services are exposed via DNS within the cluster. Lookup the service name as an A record to resolve the IP, additional information is available as SRV records.

https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#services

Of course there is an exception to every rule. It is legitimate to talk to the API Server if the application needs to update resources or if it needs to watch for new resources that didn’t exist when the application was deployed. However, these are the traits of a controller (or operator), and not typically associated with applications.

@everflux
Copy link

everflux commented Sep 5, 2019

Just a remark: The usage of secrets and configmaps through volume mounts is supported by spring-cloud-kubernetes, that is what the paths configuration is for.

@spencergibb
Copy link
Member

See spring-cloud/spring-cloud-commons#604 for srv record integration

@spencergibb
Copy link
Member

See #190 for watching volume mount

@spencergibb
Copy link
Member

Let's use this issue to inform users of when it is appropriate to use the api (Spring Cloud Gateway for example)

@trisberg
Copy link
Member

I would suggest setting default to be disabling the enableApi for both config and secrets and updating the docs to favor mounting config and secrets as volumes.

Also trying the enable reload for config/secret without accessing the API but haven't been successful yet. I think we need to add a filewatcher on the paths for mounted config/secrets to trigger a reload.

@ryanjbaxter
Copy link
Contributor

We could just mount config maps and secrets to the container using a volume. Which would eliminate the reliance on the k8s API.

To solve the refresh issue we could implement a piece of infrastructure that would watch for changes to config maps and secrets the app is concerned about, then use something like Spring Cloud Bus to notify the application that something has changed and refresh. With this approach we get refresh working but also have just a single app using the k8s api.

@ojhughes
Copy link
Contributor

ojhughes commented Nov 7, 2019

Currently the core module sets up an API client. We can move that into a separate module such as spring-cloud-kubernetes-api-server. This will help people who consciously want a nice way of injecting a Kubernetes API client but it will opt-in.

@johanan1
Copy link

Hi!
Any update on this?
We are currently using spring cloud kubernetes but would like to disable the use of tha API completely.

@krunalsabnis
Copy link

krunalsabnis commented May 20, 2021

Hi!
Any update on this?
We are currently using spring cloud kubernetes but would like to disable the use of tha API completely.

spring:
  application:
    name: my-service
  cloud:
    kubernetes:
      config:
        enabled: false
      secrets:
        enabled: true
        enable-api: false

This works as expected. It does not lookup config at bootstrap, also I disabled API call for secret.
I am using
springBootVersion = '2.4.0'
group: 'org.springframework.cloud', name: 'spring-cloud-starter-kubernetes-fabric8-config', version: '2.0.2'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants