What config option sets DNS name to use in Eureka - netflix-eureka

I am trying to set an eip binding strategy in Eureka server.
Unfortunately i get an exception:
java.lang.RuntimeException: Cannot get cnames bound to the region:txt.ap-southeast-2.null"
The exception is pretty clear about what's happening - it sets the DNS name to use to 'null'.
I have the following in my config:
eureka:
server:
domainName: mydomain.com
Obviously this doesn't seem to be enough.
The Eureka doc seems to suggest this is all i need -https://github.com/Netflix/eureka/wiki/Deploying-Eureka-Servers-in-EC2#configuring-eips-using-dns
Unfortunately this doesn't work. Is there another config parameter i need?

Related

Remote EJB in Kubernetes

I'm trying to setup a remote EJB call between 2 WebSphere Liberty servers deployed in k8s.
Yes, I'm aware that EJB is not something one would want to use when deploying in k8s, but I have to deal with it for now.
The problem I have is how to expose remote ORB IP:port in k8s. From what I understand, it's only possible to get it to work if both client and remote "listen" on the same IP. I'm not a network expert, and I'm quite fresh in k8s, so maybe I'm missing something here, that's why I need help.
The only way I got it to work is when I explicitly set host on remote server to it's own IP address and then accessed it from client on that same IP. This test was done on Docker host with macvlan0 network (each container had it's own IP address).
This is ORB setup for remote server.xml configuration:
<iiopEndpoint id="defaultIiopEndpoint" host="172.30.106.227" iiopPort="2809" />
<orb id="defaultOrb" iiopEndpointRef="defaultIiopEndpoint">
<serverPolicy.csiv2>
<layers>
<!-- don't care about security at this point -->
<authenticationLayer establishTrustInClient="Never"/>
<transportLayer sslEnabled="false"/>
</layers>
</serverPolicy.csiv2>
</orb>
And client server.xml configuration:
<orb id="defaultOrb">
<clientPolicy.csiv2>
<layers>
<!-- really, I don't care about security -->
<authenticationLayer establishTrustInClient="Never"/>
<transportLayer sslEnabled="false"/>
</layers>
</clientPolicy.csiv2>
</orb>
From client, this is JNDI name I try to access it:
corbaname::172.30.106.227:2809#ejb/global/some-app/ejb/BeanName!org\.example\.com\.BeanRemote
And this works.
Since one doesn't want to set fixed IP when exposing ORB port, I have to find a way to expose it dynamically, based on host IP.
Exposing on 0.0.0.0 does not work. Same goes for localhost. In both cases, client refuses to connect with this kind of error:
Error connecting to host=0.0.0.0, port=2809: Connection refused (Connection refused)
In k8s, I've exposed port 2809 through LoadBalancer service for remote pods, and try to access remote server from client pod, where I've set remote's service IP address in corbaname definition.
This, of course, does not work. I can access remote ip:port by telnet, so it's not a network issue.
I've tried all combinations of setup on remote server. Exporting on host="0.0.0.0" results with same exception as above (Connection refused).
I'm not sure exporting on internal IP address would work either, but even if it would, I don't know the internal IP before pod is deployed in k8s. Or is there a way to know? There is no env. variable with it, I've checked.
Exposing on service IP address (with host="${REMOTE_APP_SERVICE_HOST}") fails with this error:
The server socket could not be opened on 2,809. The exception message is Cannot assign requested address (Bind failed).
Again, I know replacing EJB with Rest is the way to go, but it's not an option for now (don't ask why).
Help, please!
EDIT:
I've managed to get some progress. Actually, I believe I've successfully called remote EJB.
What I did was add hostAliases in pod definition, which added alias for my host, something like this:
hostAliases:
- ip: 0.0.0.0
hostnames:
- my.host.name
Then I added this host name to remote server.xml:
<iiopEndpoint id="defaultIiopEndpoint" host="my.host.name" iiopPort="2809" />
I've also added host alias to my client pod:
hostAliases:
- ip: {remote.server.service.ip.here}
hostnames:
- my.host.name
Finally, I've changed JNDI name to:
corbaname::my.host.name:2809#ejb/global/some-app/ejb/BeanName!org\.example\.com\.BeanRemote
With this setup, remote server was successfully called!
However, now I have another problem which I didn't have while testing on Docker host. Lookup is done, but what I get is not what I expect.
Lookup code is pretty much what you'd expect:
Object obj = new InitialContext().lookup(jndi);
BeanRemote remote = (BeanRemote) PortableRemoteObject.narrow(obj, BeanRemote.class);
Unfortunatelly, this narrow call fails with ClassCastException:
Caused by: java.lang.ClassCastException: org.example.com.BeanRemote
at com.ibm.ws.transport.iiop.internal.WSPortableRemoteObjectImpl.narrow(WSPortableRemoteObjectImpl.java:50)
at [internal classes]
at javax.rmi.PortableRemoteObject.narrow(PortableRemoteObject.java:62)
Object I do receive is org.omg.stub.java.rmi._Remote_Stub. Any ideas?
Solved it!
So, the first problem was resolving host mapping, which was resolved as mentioned in edit above, by adding host aliases id pod definitions:
Remote pod:
hostAliases:
- ip: 0.0.0.0
hostnames:
- my.host.name
Client pod:
hostAliases:
- ip: {remote.server.service.ip.here}
hostnames:
- my.host.name
Remote server then has to use that host name in iiop host definition:
<iiopEndpoint id="defaultIiopEndpoint" host="my.host.name" iiopPort="2809" />
Also, client has to reference that host name through JNDI lookup:
corbaname::my.host.name:2809#ejb/global/some-app/ejb/BeanName!org\.example\.com\.BeanRemote
This setup resolves remote EJB call.
The other problem with ClassCastException was really unusual. I managed to reproduce the error on Docker host and then changed one thing at a time until the problem was resolved. It turns out that the problem was with ldapRegistry-3.0 feature (!?). Adding this feature to client's feature list resolved my problem:
<feature>ldapRegistry-3.0</feature>
With this feature added, remote EJB was successfully called.

Eureka and Consul

I am implementing a service discovery and I evaluating two options: Eureka and Consul.
Help me decide! I am leaning towards Eureka, but I need to clear a main tech problem. My infrastructure is based on openshift. I can have multiple containers running Eureka Servers behind a load balancer. As far as I know each server needs to communicate with each other. Also, Eureka is mainly used with AWS...
(newbie) Question:
1) How can I configure each Eureka Server to communicate with each other? I have a single (load balanced) URL. My fear is that each server potentially may become desynchronized.
2) Am i missing something?
You're right, each of the Eureka Server must communicate with each other. You can also play with regions depending on your approach.
To make it work (without zones), you must configure the property:
eureka.client.service-url.defaultZone: http://1st-eureka-server-ip-or-hostname:port/eureka/,http://2nd-eureka-server-hostname:porta/eureka/
The configuration above accepts a comma-delimited set of IP/hostname of all the Eureka Servers.
If you want to have a multi-zone configuration, I recommend you to read this blog post.
To Configure each Eureka Server to communicate with each other try this way to make a diffrent diffrent zone in resource in folder.
application-zone1.yml
server.port: 8001
eureka:
instance:
hostname: localhost
metadataMap.zone: zone1
application-zone2.yml
server.port: 8002
eureka:
instance:
hostname: 127.0.0.1
metadataMap.zone: zone2
application.yml
client:
register-with-eureka: false
fetch-registry: false
region: region-1
service-url:
zone1: http://localhost:8001/eureka/
zone2: http://127.0.0.1:800/eureka/
availability-zones:
region-1: zone1,zone2
spring.profiles.active: zone1
Follow this tutorial

Configuration based fallback for route

There are two instances of an application: instance-1 and instance-2.
Let us assume that
instance-1 is reachable at localhost:8090
instance-2 is reachable at localhost:9080
How do I configure zuul proxy so that --- First visit instance-1 and in case of any exception / failure, switch to instance-2
Note: Not using Eureka
I was able to get it work using hystrix with a facade controller and in the fallback, calling instance-2 via RestTemplate.
But I am looking for some better approach wherein the routing is taken care by Zuul along with mirroring of HTTPHeaders, HttpMethod and other request attributes.
If anyone have tried similar thing, please suggest me.
You can configure Zuul to retry on current and next instance.
zuul:
retryable: true
ribbon:
MaxAutoRetries: 1
MaxAutoRetriesNextServer: 3
OkToRetryOnAllOperations: true
yourApplication:
ribbon:
listOfServers: localhost:8090, localhost:9080
As per above configuration, if routing to 8090 instance fails Zuul will try one more time to connect to 8090 and if that call also fails, Zuul will route to 9080 for the next call. You can read more about these retry configurations here.

How to expose amqps rabbitmq protocol in k8s environment externally?

I was wondering -
When setting rabbitmq nodes to use a TLS connection (as seen here https://github.com/artooro/rabbitmq-kubernetes-ha/blob/master/configmap.yaml), as I understand, I need to create a certificate that matches the hostname, wildcard can be used - https://www.rabbitmq.com/clustering-ssl.html.
As cluster dns is internal, I guess I should create a certificate with a common name such as - ‘*.rabbitmq.default.svc.cluster.local’.
When I’m exposing the service, I'm supposed to create either a NodePort service or a LoadBalancer service - with a totally different hostname (it should route internally).
My question is - how will the amqps connection work? Won't it present me with one of the node’s certificates - which will not match the load balancer’s dns?
What's the correct way to expose the amqps protocol?
Thanks in advance
If anyone is looking at it, it doesn't matter - this is not a "standard" https connection.
The client needs to specify the correct common name and that's enough for the connection to work.

how does zuul work without eureka and ribbon for dynamic destination from kubernetes

I am a beginner of using Zuul. I would like to create a http proxy for dynamic destination (ip address) from kubernetes. I checked Can Zuul Edge Server be used without Eureka / Ribbon which is helpful, but I don't want to specify lists-of-servers.
What I have now is a simpleRouteFilter extends ZuulFilter based on spring-boot. In the filter, it will change the destination ip address according to what I get from kubernetes. And I also turn off the eureka stuff by using ribbon.eureka.enabled=false.
The problem is that it looks good in the local environment, but after I deploy the project into kubernetes, it will show Load balancer does not have available server for client: sample-all-services, but it indeed works. The reason why I put a sample-all-service (service id) there is that when I remove zuul config in the properties, the zuul function doesn't work properly. And I know that I didn't put any server for that id because it's dynamic.
Question:
(1) Is Zuul fit in my scenario?
(2) if yes, how to tune Zuul confguration to accept all the http requests without showing load balancer not available warn.
(3) Is that something related to the kubernetes?
The yaml file is:
zuul:
routes:
sample-all-services:
path: /**
server:
port: 8080
ribbon:
eureka:
enabled: false
sample-all-services:
ribbon:
ReadTimeout: 15000
Thanks.