Using Kubernetes configmap as config server for spring boot - spring-boot

Can we use a configmap on Kubernetes as config server. Kind of a central config and do away with config server?

Short answer: Yes, this is what we did.
One thing to note though is that config maps aren't as centralized as the config server.
As the config map is local to your namespace you would have to keep all your environments (test, staging, production) inside the same namespace (which I do not recommend) in order to have a single config in the same manner as the cloud config gives you.
But even if you separate your environments into separate namespaces (which I recommend) and have one config map for each it's still easy to maintain and a good replacement for the config server.

Related

Don't want to store properties in database

I have some properties in my microservice. They are changed a lot so I want to store them somewhere out of microservice so that I don't have to undeploy it again and again. One solution is to store them in database but it will be less efficient that way. Can you advise me a solution where I can store them?
Basically this microservice is used by a vast number of people. I want that file to be read ONCE when microservice is deployed (unless or until there is some change in the file) to minimize the calls.
You should use Spring Cloud Config which enables to use a centralized server which exposes a Git Repo which you can use to store environment specific configuration files (application.properties)
You should go with Centralized configuration, spring cloud supports config server, It is highly recommended for microservice architecture.
For reference: https://spring.io/guides/gs/centralized-configuration/
Basically, you have a centralized place to store all the configurations and don't need the redeploy the application every time you change the configs.
NOTE: in case you change the db properties then probably you need the restart the service

Clone only specific path - Spring Cloud Config Server

Is there any way by chance to make spring config server to clone only specific path instead of whole git repo? When I'm running it on production I may not want my entire code base repository to be cloned to some location as it is always a risk. I've done my research and couldn't figure out ways to clone only specific paths of git repo.
One solution is to host the configurations in a seperate repo. But that would defeat the purpose of one code many deploys suggestion of 12factor.net.
Another possibility is to copy the properties into config server's classpath and then to use native profile to load them. But this would defeat the purpose of Spring ConfigServer.
Also kindly do clarify What would be the best way to run spring config server on a production?
You should be separating your code base from your configuration settings.
Repo 1: Your App Code
Repo 2: Your Spring Cloud Config Server Code
Repo 3: Your configuration settings
When you're deploying, you're deploying the code. Not the configuration. A configuration change should not require a new deployment. A new deployment might require an updated configuration change, but the two are generally decoupled.
Configuration can be dynamically updated while code is running. This is completely separate from updating code and deploying the app. That's the whole point of externalized configuration.
TL;DR: You're looking at "one code many deploys" wrong. Configuration is externalized.
I took this straight from 12factor.net
Apps sometimes store config as constants in the code. This is a violation of twelve-factor, which requires strict separation of config from code. Config varies substantially across deploys, code does not.
Even though you are no longer storing them as constants but still in the same repository is not enough separation from the code. Use a separate repository for configurations.

Spring Cloud Config without the server

The role of the Config Server while using Spring Cloud Config seems to be pretty dumb and hosting it seems to be an unnecessary overhead. Is there a way to get the Clients to directly read configs from the git repo?
You can let Spring Boot look at specific locations for the config files: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-application-property-files
If you set this location to your cloned git repo (checked out on the branch you need) and solve the update from the origin repository, this might work.
It is achievable via the embedding config server approach
Do refer to Embedding The Config Server section
If you want to read the configuration for an application directly from the backend repository (instead of from the config server), you basically want an embedded config server with no endpoints. You can switch off the endpoints entirely by not using the #EnableConfigServer annotation (set spring.cloud.config.server.bootstrap=true).

Spring Boot external configuration order when using Cloud Config Server?

I'm starting to use Spring Cloud Config and would like to give a way for clients to override properties that come from cofnig server. However, after reading https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html, it isn't apparent when the Cloud Configuration applies.
I've also read http://cloud.spring.io/spring-cloud-config/spring-cloud-config.html and it talks about overrides. But they seem to be the opposite of what I want (those overrides are for overriding the client provided properties).
So, where does the Cloud Config fit in the ordering? Would I still be able to give a local application.properties file on the classpath to override certain Cloud Config properties?
The git commit/push process is part of the process, actually...Spring Cloud Config uses git to handle the config files, changes, auditing, etc., as git is ideally suited for that, & Config leverages those strengths.
If you're just looking for a way to expedite testing of config changes and are willing to accept the tradeoffs, you can use a local (or local network) repo for your config repository for testing. I realize this isn't what you're asking specifically, but it's an option that may help, assuming you're using the Config server app's application.properties to point to the underlying git repo. If so, you can override spring.cloud.config.server.git.uri on the command line like so:
java -Dspring.cloud.config.server.git.uri=${HOME}/testing/config-repo -jar your_jar_here.jar
This will allow you to tweak the config settings for client apps/services that obtain their settings from the Config server without affecting the production config files (even branches).
I hope this helps. If not, or if I've misunderstood your goals or constraints, please clarify (a use case or two might help me triangulate better, if you can share them) and I'll take another run at it. :)
Cheers,
Mark

Spring Cloud Config Server Shared Properties Across Applications

I currently have a number of deployable applications that work in a distributed fashion to solve a business problem. We are currently using a number of property configuration files to provide changing configuration per environment based off a system environment variable. All these deployable application share common configuration for database and messaging. This is currently achieved by picking up property files from the class path and having both deployed apps share a common jar for each connection (db, jms) containing property files.
I am looking to start using Spring Config Server to externalize this configuration if possible. I have a question about how to share this common config.
Currently it looks something like this:-
Web1
- database
- jms
Messaging1
- database
- jms
In this situation both deployed apps share the same connections and these connections change per environment (lab, prf, prd, etc). How can I achieve the same with the Spring Configuration Server where I have app config for each deployable app?
Application.yml
Web1.yml
Web1-dev.yml
Messaging1.yml
Messaging1-dev.yml
If a connection property changed for an environment I would need to make the change to each deployable app configuration rather than making it just once.
Is there currently anyway to achieve this? Am I just missing a simple point?
I found working solution here https://cloud.spring.io/spring-cloud-config/single/spring-cloud-config.html, paragraph "2.1.5 Sharing Configuration With All Applications". It says:
With file-based (i.e. git, svn and native) repositories, resources
with file names in application* are shared between all client
applications (so application.properties, application.yml,
application-*.properties etc.). You can use resources with these file
names to configure global defaults and have them overridden by
application-specific files as necessary.
You should create application.properties or application.yml at the top level of configuration repository (if it is git or svn based). Don't forget to commit the changes.
This is how I have configured for my setup.
1 All Common properties across all services and environments will be in root->application.properties files
2 All Common properties across all environments specific to service will be root->service-X.properties files
3: Similarly, to have common properties across specific environment use env->application.properties file
server:
port: 8888
spring:
cloud:
config:
server:
git:
uri:[git repo]
search-paths: /,/{profile}/
Finally found a solution. It's buried in the issues at github ...
https://github.com/spring-cloud/spring-cloud-config/issues/32
It worked liked described. I only noticed, that you need to put the files in a /config folder to make it work. If you put it in the root the file ist used by the configserver itself and is not included in the config requests.
application.properties/application.yml will be shared across all applications.
application-DEV.properties/application-DEV.yml will be shared across all DEV environment applications. You can replace DEV with any spring profile.
{applicationName}.properties/{applicationName}.yml will be shared across the give application.

Resources