Small architecture and design question please.
Question:
Should Kubernetes Ingress lives together with Spring Cloud Gateway? If not, which one should be preferred?
First, with a Spring Webflux / Spring Cloud Gateway project, I managed to have working route-based forwarding. Meaning, all my clients only need to know this one and only Spring Cloud Gateway endpoint, and the Spring Cloud Gateway will forward to serviceA if the URL contains serviceA, to serviceB if serviceB, etc, straightforward.
I added some more “software level features” such as dynamic configuration (to change the routes at runtime), circuit breaker, rate limit, bulkhead, and few others features, very cool, but really, I ended up using the route forwarding as a main feature.
Then couple of weeks back, I spent time studying Kubernetes, and more precisely Kubernetes Ingress.
I managed to learn Kubernetes Ingress is a very cool and strong thing. I managed to perform at least the route based forwarding.
Meaning, clients needs to only know this one and only Ingress endpoint, and the Ingress will forward to underlying services within the Kubernetes cluster. Where as of now, it forwards everything to Spring Cloud Gateway, which will forward to everything else. I tried, and it could have forwarded to the real business services in the first place).
And this is the moment where I am having doubts.
Did I just duplicate work? (I mean in terms on functionally, I had fun learning both).
Should I consider an architecture where the Spring Cloud Gateway (only him) is really doing the gating?
Should I consider an architecture where both the Ingress and the Software Gateway have full importance, configuring features in both? (Accept the duplicated work?)
Should I remove the Spring Cloud Gateway entirely?
Thank you
In my opinion, Kubernetes must lives together with Spring Cloud Gateway.
Reverse proxies has capabilities like central logging, security, caching, routing, traffic management features etc, but there are also things they cannot do. API Gateways come into play at this point. They have all the features of reverse proxies, plus they have extra capabilities that they can't. For this reason, API Gateways are called enhanced reverse proxies.
So Kubernetes ingress acts like reverse proxy, while Spring Cloud Gateway is implementation of API Gateway pattern. As I mentioned in the definition above, I can say few things you can't do with Kubernetes.
Can you implement API composition? No
Can you implement JWT authentication by Kubernetes? If so, Can you carry JWTs more than 8 KB to downstream service by Kubernetes? No
Can you combine all Swagger/Open API documentation by Kubernetes? No
Related
I'm having a really tough time with this one. We want to move our legacy app to Microservice application(Spring-boot, Java 8) .
As per Architect, we do-not need Service Disvovery and API Gateway is enough for the doing Service Discovery and Routing.
Note that currently , deployments are On premise server and we will have fixed number of nodes and F5/load balancer will be able to route the request to API gateway and then to the microservices.
Can we survive with Spring Cloud API Gateway and no Service Discovery?
A short answer Yes, you can survive with Spring Cloud API Gateway and no Service Discovery.
But it's really dependent on the size of your application and the amount of traffic it will be handling.
You can start migration to microservices without Service discovery.
For internal service-to-service communication just use real hardcoded IP addresses and ports.
Regarding to the API Gateway doing Service Discovery. I can be wrong, but you won't be able to communicate through Api Gateway because it also has no clue about the location of the targets (services locations have to be hardcoded as well).
Once you begin feeling that you need scaling out you won't avoid using Service Registry tool. If you start considering which one to take I can suggest using HashiCorp Consul.
Anyway, it's most likely that you finally will have to inject Service discovery mechanism to your infrastructure. You can either do it from the beginning or take care of it later if the new architecture will be beneficial to you and there will be a plan of extending it further.
If you have plans of migration to the clouds then you can think about Kubernetes for your infrastructure in advance. It provides you with Service discovery mechanism out of the box.
Kubernetes is a great platform for this, if you can opt.
It can handle parts ranging from service discovery to deployment.
You just need to make a cloud ready docker image (preferably) and deploy it to kubernetes, Kubernetes will map an internal endpoint to this, based on your configuration and your services will be registered with it ( if I talk in terms of spring-cloud and eureka server).
If there is no Service-Registry-backed DiscoveryClient then you can configure spring.cloud.discovery.client.simple.instances.userservice[0].uri=http://s11:8080
You can host this userservice on kubernetes cluster .For further details go to this docs
https://cloud.spring.io/spring-cloud-commons/2.2.x/reference/html/
Like wise to have communcation between sevices ,suppose userservice wants to communicate to password service easily configure via ribbon
passwordservice.ribbon.listOfServers:${PASSWORDSERIVCE}:http://localhost:8081
I do not see any problem with this strcuture .
i've been using Zuul in my micro-services based application for a while now, and it's been working perfectly.
now i've been asked a question by someone that made me think that micro-services world is not all rainbows and flowers after all.
so the question was " you have Zuul as the sole entrypoint to you app, isn't that some sort of centralization ? what if zuul is down ? "
i just wanted to gather some opinions, and get an answer to that question.
thank you.
Yes it is entry point and it serves many pros having single entry point in your micro service architecture.
Pros:
I can think of on top of mind
Single point of contact for all you API users(Apps). Zuul running at api.yoursite.com and calling it every time is better than calling individual services(service1.yoursite.com, service2.yoursite.com) from you api consumers.
Security point of view, you have to deal with only one server's security and you can hide all the other servers running your services in network and not exposing them on public internet. Amazon AWS and many other providers provides such facility.
You can leverage routing benefits using zuul as your entry point you can route 80% traffic to service1 old version while 20% to your same service1 new version.
Cons:
Great power comes with great responsibility.
If your main zuul server is down your whole app is down.(Edit: only if you have one zuul setup). Please check #lahiru's answer how you can have multiple zuul cluster using eureka registry configuration.
If your Zuul instance is down. You might not be able to direct to other services through the api gateway.
As a solution i would suggest you to go for a clustered solution with two zuul instances.
There you need two client side service registry services (Eureka Servers) .
If you are planning to manage fault tolerance, you can apply sentinel.
Your micro services become eureka clients.
You have to register your micro services in both of the eureka servers and make a eureka server cluster. You can refer to below diagram as a design /architecture diagram for implementation.
Note : You have to maintain two end points for both of the zuul servers. If zuul 1 is down , client can request to zuul 2.
This will help you to achieve zero down time .(You need to make sure that your VM platform is reliable and no unplanned downtimes).
Since Spring Cloud team has abandoned development of Zuul module, we are moving to Spring Cloud Gateway or Zuul2 but I believe Zuul2 needs a lot of changes in the architecture and needs big changes in the microservices(correct me if i'm wrong), can anyone gives a recommendation on zuul2 or Spring-Cloud-Gateway, has anyone or you know any big player in tech using Spring-Cloud-Gateway?
Zuul1 is blocking whereas Zuul2 and spring cloud gateway are non-blocking and this is a major performance factor for a gateway, as a non-blocking model requires less resources to serve the same amount of requests as compared to a blocking gateway.
Now, coming to spring cloud gateway and Zuul2 - Spring Cloud does not provide any out of the box integration with Zuul2. Gateway has many features that are not available in the public version of Zuul2 such as Rate limiting, etc. Also, with the gateway you can have custom filters defined per route and there are tons of built-in filters defined as well, which helps a lot to get started.
Actually, there are many things which are not possible to explain here. You can follow the gateway documentation here - https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.0.2.RELEASE/single/spring-cloud-gateway.html
I think SCG is the way to go due to the agreements between Netflix and Pivotal, with the former leaning more toward the spring boot/cloud ecosystem as stated in https://medium.com/netflix-techblog/netflix-oss-and-spring-boot-coming-full-circle-4855947713a0
Performance-wise it also seems like a good bet: https://www.bytesville.com/zuul-spring-cloud-gateway-comparison-benchmarks-loadtesting/
They both are replacements, but Spring Cloud will only support Gateway, not zuul 2
I have a cloud-native application, which is implemented using Spring Cloud Netflix.
So, in my application, I'm using Eureka service discovery to manage all instances of different services of the application. When each service instance wants to talk to another one, it uses Eureka to fetch the required information about the target service (IP and port for example).
The service orchestration can also be achieved using tools like Docker Swarm and Kubernetes, and it looks there are some overlaps between what Eureka does and what Docker Swarm and Kubernetes can do.
For example, Imagine I create a service in Docker Swarm with 5 instances. So, swarm insures that those 5 instances are always up and running. Additionally, each services of the application is sending a periodic heartbeat to the Eureka internally, to show that it's still alive. It seems we have two layers of health check here, one for Docker and another inside the Spring Cloud itself.
Or for example, you can expose a port for a service across the entire swarm, which eliminates some of the needs to have a service discovery (the ports are always apparent). Another example could be load balancing performed by the routing mesh inside the docker, and the load balancing happening internally by Ribbon component or Eureka itself. In this case, having a hardware load balancer, leads us to a 3-layered load balancing functionality.
So, I want to know is it rational to use these tools together? It seems using a combination of these technologies increases the complexity of the application very much and may be redundant.
Thank you for reading!
If you already have the application working then there's presumably more effort and risk in removing the netflix components than keeping them. There's an argument that if you could remove e.g. eureka then you wouldn't need to maintain it and it would be one less thing to upgrade. But that might not justify the effort and it also depends on whether you are using it for anything that might not be fulfilled by the orchestration tool.
For example, if you're connecting to services that are not set up as load-balanced ('headless services') then you might want ribbon within your services. (You could do this using tools in the spring cloud kubernetes incubator project or its fabric8 equivalent.) Another situation to be mindful of is when you're connecting to external services (i.e. services outside the kubernetes cluster) - then you might want to add load-balancing or rate limiting and ribbon/hystrix would be an option. It will depend on how nuanced your requirements for load-balancing or rate-limiting are.
You've asked specifically about netflix but it's worth stating clearly that spring cloud includes other components and not just netflix ones. And that there's other areas of overlap where you would need to make choices.
I've focused on Kubernetes rather than docker swarm partly because that's what I know best and partly because that's what I believe to be the current direction of travel for the industry - on this you should note that kubernetes is available within docker EE. I guess you've read many comparison articles but https://hackernoon.com/a-kubernetes-guide-for-docker-swarm-users-c14c8aa266cc might be particularly interesting to you.
You are correct in that it does seem redundant. From personal observations, I think that each layer of that architecture should handle load balancing in its' own specific way. It ends up giving you a lot more flexibility for not much more cost. If you want to take advantage of client side load balancing and any failover features, it makes sense to have Eureka. The major benefit is that if you don't want to take advantage of all of the features, you don't have to.
The container orchestration level load balancing has a place for any applications or services that do not conform to your service discovery piece that resides at the application level (Eureka).
The hardware load balancer provides another level that allows for load balancing outside of your container orchestrator.
The specific use case that I ran into was on AWS for a Kubernetes cluster with Traefik and Eureka with Spring Cloud.
Yes, you are correct. We have a similar Spring Cloud Netflix application deployed on Oracle cloud platform and Predix Cloud Foundry. If you use multiple Kubernetes clusters then you have to use Ribbon load balancing because you have multiple instance for services.
I cannot tell you which is better Kubernetes or Docker Swarm. We use Kubernetes for service orchestration as it provides more flexibility.
For a project I'd like to set up a small microservice scenario using Spring Boot with an API gateway exposing REST and GraphQL to the clients, a Eureka service registry and three services. I want all services behind the API gateway to talk gRPC because of performance reasons, but at the same time still expose an additional REST API. Is there a clean way to implement both types of interfaces on top of the same business logic? And how would the gateway proxy the clients' HTTP requests to gRPC ones?
You can look into LogNet grpc-spring-boot-starter to see how to integrate gRPC into Spring Boot, it also has a section about Eureka.
As per Eureka example, make sure you don't create new connection over gRPC for each call.
Depending on the implementation of the API gateway, it should also talk to Eureka, and access downstream services by logical names via gRPC.
As per second part, simply implement your business logic in Spring Services, and forward calls to them from the transport related abstractions (Controllers and gRPC services).
Optionally, you can go even further, and define all messages in Protobuf only. And then register Spring's Protobuf Converter for HTTP.