How to config consul cluster in spring? - spring

If there is only one consul node, it can config consul like following:
spring:
cloud:
consul:
host: localhost
port: 8500
But if there is consul cluster, for example there are three concul nodes.
in this case, how to config the consul?
Do it need DNS to route the host name to multi IP address?

you should run a consul agent in client mode on a node and join consul cluster.
then run your spring boot instance on this node and connect to this consul agent.

Related

Spring application unable to access kafka running in kubernetes minikube

I used bitnami/kafka to deploy kafka on minikube. A describe of the pod kafka-0 looks says that server address is:
KAFKA_CFG_ADVERTISED_LISTENERS:INTERNAL://$(MY_POD_NAME).kafka-headless.default.svc.cluster.local:9093,CLIENT://$(MY_POD_NAME).kafka-headless.default.svc.cluster.local:9092
My kafka address is set like so in Spring config properties:
spring.kafka.bootstrap-servers=["kafka-0.kafka-headless.default.svc.cluster.local:9092"]
But when I try to send a message I get the following error:
Failed to construct kafka producer] with root cause:
org.apache.kafka.common.config.ConfigException:
Invalid url in bootstrap.servers: ["kafka-0.kafka-headless.default.svc.cluster.local:9092"]
Note that this works when I run kafka locally and set the bootstrap-servers address to localhost:9092
How do I fix this error? What is the correct kafka URL to use and where do I find it? thanks
Minikube network is different to the host network, you need a bridge.
The advertised listener is in the minikube realm, not findable from the host.
You could setup a service and an ingress in minikube pointing to your kafka, setup your hosts file to the ip address of the ingress and the hostname advertised.
spring.kafka.bootstrap-servers needs valid server hostnames along with port number as comma-separated
hostname-1:port,hostname-2:port
["kafka-0.kafka-headless.default.svc.cluster.local:9092"] is not looking like one!

How do I curl my elasticsearch on AWS EC2

I installed elasticsearch(docker) 8.2 on aws ec2(ubuntu 20.04.)
Everything is working.My only problem is that I can't reach(curl) it from other instances and my backend server(it is on same vpc).
I added my node to its discovery node, and also set network.host: 0.0.0.0
but I still can't reach it
(I tried with both private and public ip)
Is it necessary to install SSL/TSL on it with elastic 8?
Does anyone has any suggestion how to access it?
Looks like you forgot to bind the docker container port to host port, you need to add below config, to your Elasticsearch container docker yml
ports:
- "9202:9200" (bind 9200 port of host to docker port of 9200, 9200 is the Elasticsearch port by default)
After that you should be able to do the curl from other instances in the VPC.

Access Docker Containers Host by DNS name

From my Spring Boot application deployed as a Docker container I need to be able to access the parent node (within a Swarm) by some kind of docker-exposed DNS name so that I can add it to a configuration file and was wondering if there was a DNS name exposed automatically by Docker for this purpose?
Another container that is scheduled on the same host running in "network_mode: host" is running Consul and advertising on port 8500 (real IP is 192.168.1.233).
If I run netstat on the Swarm node (ip 192.168.1.233) I can see it's listening on port 8500:
# netstat -anp | grep 8500
tcp6 0 0 :::8500 :::* LISTEN 25010/docker-proxy
I want to be able to define a connection string as configuration in the Spring Boot app on the swarm node to the local instance of Consul sheduled on the same physical host as the Spring Boot app.
If I refer to "localhost" within the Spring Boot container then there's nothing listening on the 8500 port, proven by running this after shelling into the Spring Boot container (using a sample Consul API call)
# wget http://localhost:8500/v1/status/leader
Connecting to localhost:8500 (127.0.0.1:8500)
wget: can't connect to remote host (127.0.0.1): Connection refused
I've also tried using "host.docker.internal" but that doesn't work:
# ping host.docker.internal
ping: bad address 'host.docker.internal'
The hosts are all Centos 7 hosts, and Docker version 18.09.1, build 4c52b90.
The firewalld service is disabled on all hosts.

Kubernetes networking, How to transfer a variable to container

I have a K8s, currently running in single node (master+kubelet,172.16.100.81). I have an config server image which I will run it in pod. The image is talking to another pod named eureka server. Both two images are spring boot application. And eureka server's http address and port is defined by me. I need to transfer eureka server's http address and port to config pod so that it could talk to eureka server.
I start eureka server: ( pesudo code)
kubectl run eureka-server --image=eureka-server-image --port=8761
kubectl expose deployment eureka-server --type NodePort:31000
Then I use command "docker pull" to download config server image and run it as below:
kubectl run config-server --image=config-server-image --port=8888
kubectl expose deployment config-server --type NodePort:31001
With these steps, I did not find the way to transfer eureka-server http
server (master IP address 172.16.100.81:31000) to config server, are there
methods I could transer variable eureka-server=172.16.100.81:31000 to Pod config server? I know I shall use ingress in K8s networking, but currently I use NodePort.
Generally, you don't need nodePort when you want two pods to communicate with each other. A simpler clusterIP is enough.
Whenever you are exposing a deployment with a service, it will be internally discoverable from the DNS. Both of your exposed services can be accessed using:
http://config-server.default:31001 and http://eureka-server.default:31000. default is the namespace here.
172.16.100.81:31000 will make it accessible from outside the cluster.

How to register a service using Spring Cloud Consul

I have registered a service using Spring Cloud Consul, but for this I had to run a Consul local agent which establishes a channel communication to Consul server node (running as bootstrap).
For example:
#Server
consul agent -server -bootstrap -bind -data-dir data -ui-dir web_ui
#Desktop
consul agent -data-dir consul -ui-dir consul/dist -join server_ip_address
Is there any way to avoid of having this local agent in my desktop, I mean from my desktop Spring Cloud Consul would register the service to server node?
An example of this is what Netflix Eureka client does with Netflix Eureka server, no external agents running in machines to bind services names.
you have to use property file or yaml file i just give sample yaml file
application.yml
# Configure this Discovery Server
spring:
cloud:
consul:
host: localhost
port: 8500
bootstrap.yml
spring:
application:
name: service-name

Resources