Use consul-template in KV for application configuration in Spring - spring-cloud-consul

Does anyone have an idea how to retrieve values from consul template and insert it as a value in KV data as Spring application.yml config properties?
As an example, I have a service 1, that runs with the specific IP (e.g. 192.168.233.32). Additionally, I have another service 2, written with Spring, that uses configuration, specified in Consul-KV config folder. This config should use the reference to the IP of mentioned service 1. For instance, the configuration of the service 2 is following:
third-party:
service:
host-name: *the_reference_to_service_1*
The service 1 has several instances and its IP is prone to be changed. I've found the example how to insert the dynamic values, particularly for server address, it looks like {{ range service "service1" }}{{ .Address }}:{{ .Port }}{{ end }} - but it doesn't work with application properties configuration file.
But the question is what kind of consul-template (or anything else) I should use to achieve the purpose of dynamic value insertion to the KV configuration file in Spring?

Related

Kubernetes Config Map reload issue

I am having Kubernetes Config map in spring boot project and My application should dynamically get the values from config map if any values changes in config map so for that I have used spring cloud kubernetes config like below in bootstarp.yml file
spring:
profiles: dev, preprod
cloud:
kubernetes:
reload:
enabled: true
config:
enabled: true
sources:
- namespace: ${kubernetesnamespace}
name: ${configmapname}
After deploying the application , If I go and change the config map value I am able to get in application without restart which is expected but If I change the config map value after 1 hour of deployment this new value of config map is not reflecting in application but same I f do after 5 mins of deployment it is working.
So what could be the reason.
what could be the reason
My first suspect would be the application itself. That probably "watches" for the ConfigMap (opens a long-living connection, subscribing for changes on that object). Eventually, those connections may close, which is normal/expected (container restart, etcd leader changes, SDN issues, ...).
I would make sure my application properly acknowledges those and re-connects to the API.
For reload to work, the classes candidate for reloading are needed to be annotated with #RefreshScope.
Please see documentation reference:
https://docs.spring.io/spring-cloud-kubernetes/docs/current/reference/html/#propertysource-reload
Notice that default reload strategy is "refresh" and whole context is not reloaded unless specified. I hope that helps.

helmfile best practices with multiple customers

We would like to have some recommendations, since we want to integrate helmfile in our deployment process...
Our infrastructure has following details:
we have many customers
all customers have the same installed services
(each customer get's it's own services, no sharing between customers)
credentials are different for each customer
we prefer a seperate
deployment process (we dont want to upgrade all customers at the same
time)
all customer-config data is seperated into seperate config
files, like:
config/customer1.yaml
config/customer2.yaml
config/customer3.yaml
So I'm wondering, if we should use "Environment" with the customer name, to upgrade it.. or would you recommend another variable?
And do you think it's better to create multiple helmfiles for this process, or just one?
Thank you!
do you think it's better to create multiple helmfiles for this process, or just one?
Using one helmfile for multiple environemnts is quite practical and it saves you writing multiple helmfiles.
we should use "Environment" with the customer name?
For a similar setup (deploying to multiple environements with different values and configurations), I have in Helmfile:
- name: my-app
namespace: "{{ .Namespace }}"
chart: k4r-distance-matrix-api
values:
- my-app/values.yaml ## here go the common values if any exists
- my-app/values.{{ .Environment.Name }}.yaml ## here goes the environment specific values
In the deploy step in my CI I have:
.deploy:
stage: deploy
variables:
ENVIRONMENT: ""
CONTEXT: ""
NAMESPACE: ""
before_script:
- kubectl config use-context $CONTEXT
script:
- helmfile -e "$ENVIRONMENT" --namespace "$NAMESPACE" sync

Turbine Dashboard Metrics without Eureka

I am working on two Spring-boot applications. I am using spring-cloud-starter-hystrix for circuit-breaking & fallback methods using #EnableCircuitBreaker.
Now I also want to have an hystrix dashboard with metrics which can be achieved by Turbine Server using #EnableTurbine #EnableHystrixDashboard.
AFAIK the Turbine service gets the application URLs from Eureka Instance. And in Turbine server app.properties we should give the other apps name. So that Turbine will check with Eureka on app url:port.
In my case, I am not using Eureka. So how can I use a Turbine Service to manually hardcode my application URL to fetch metric streams & display the metrics dashboard?
So basically in Turbine Server can I disable connection to Eureka & hardcode URLs to fetch metrics?
I have browsed for few hours & couldnt find a solution. Any help is appreciated.
Download and run turbine-web war file from HERE and deploy it on any server say a tomcat with a JVM runtime argument specifying the location of your turbine config file. Something like-
-Darchaius.configurationSource.additionalUrls=file:///etc/files/turbine-archaius.properties"
Add configuration like your server IPs, URI of hystrix stream servlet in that file. Take more help from HERE.
Here's my sample config file for better understanding-
turbine.aggregator.clusterConfig=<cluster-name>
turbine.instanceUrlSuffix.<cluster-name>=/hystrix.stream
#I am using a separate file to list down all my server IPs that turbine need to agregate data from
turbine.FileBasedInstanceDiscovery.filePath=/etc/files/turbine-server-list
InstanceDiscovery.impl=com.netflix.turbine.discovery.FileBasedInstanceDiscovery
turbine.InstanceMonitor.eventStream.skipLineLogic.enabled=false
The other file turbine-server-list contains server IPs from which to aggregate metrics. something like-
APPLICATION-IP1:PORT,<cluster-name>,up
APPLICATION-IP2:PORT,<cluster-name>,up
Find your aggregated turbine metrics at- http://TURBINE-SERVER-IP:PORT/turbine/turbine.stream?cluster=cluster-name

spring cloud consul service names

I am switching all my service infrastructure from eureka to consul.
In the eureka case I have multiple services with the same name and Eureka handles this via the Application and instance to differentiate.
In the consul case, if I have this naming scheme, does spring cloud generate unique ids under eh covers?
I read where consul will use the id and name synonymously unless you register them under unique ids.
So you can have service 1 as (name=myservice, id=xxx) and service 2 as (name=myservice, id=yyy).
So in that way consul preserves uniqueness. What does spring cloud do under the covers?
Ok, so it appears that the question is not clear.
I know that I can specify uniqueness when I define them but I don't
I have a large microservices-based system in production. We have multiples of each microservices for both redundancy and scaling and we do not specifically set uniqueness on the services.
We don't because Eureka does this for us. Say I have a CustomerAccountService with 5 instances then I when I request customer account service I can see 5 instances. Looking at the Eureka data model, we see one Application and 5 instances of it.
So I am planning on moving to consul and want t preserve a similar mode of operation. Many instances of the same time of service.
What I really want to know is how the spring consul registration works under the covers or do I have to do something special for this.
I do know that COnsul defines a name and an id and that they can be the same or they can be different.
So can I have the name for 5 instances the same and have the id variate? If so, how does that happen in the spring cloud consul version of this.
Any application registered with the same spring.application.name in Consul using Spring Cloud will be grouped together just like Eureka.

Spring Cloud Configuration Server Through Sidecar

We are using spring cloud sidecar with a node.js application. It would be extremely useful if we could serve up configuration from the spring configuration server and make that configuration available to the node application.
I would like the sidecar to resolve any property place holders on behalf of the node application.
The sidecar already hits the configuration server and I know that the Environment in the sidecar WILL resolve all the property place holders. My problem is, how do I efficiently expose all those properties to the node application? I could create a simple rest endpoint that accepts a key and then returns environment.getProperty(key) but that would be extremely inefficient.
I am thinking that I could iterate over all property sources (I know that not all property sources can be enumerated), collect a unique set of the names and then turn around and call environment.getProperty() for each name....
But is there a better way?
I have to imagine this is functionality that others have needed when using Spring Cloud in a polyglot environment?