Designing Helm charts for microservices based application - kubernetes-helm

I'm currently building an application that is composed of 4 microservices (a, b, c, d). We would like to make Kubernetes Helm part of our CI/CD pipeline.
We are at the point where we're discussing how best to define the charts and was wondering was the advice from the community.
Our current options appear to be:
a chart per microservice (so 4 charts)
a chart per "application flow" (service a calls b, service c calls d, so 2 charts in total)
a single chart that deploys all 4 microservices
some combination of 1. and 3. where we leverage the dependencies feature of Helm
It might be worth calling out that:
we currently don't have a requirement to deploy any microservice in isolation e.g. make it available to a separate application.
it is likely that we will need to have the ability to scale any microservice independently i.e. not simply replicate all 4 services.
I'm mentioning these requirements because I feel that they may be relevant to the chart design.

Might be a late answer, but FWIW, it depends on how and where you develop your microservices app. If each microservice has it's own repo and CI pipeline, then it makes sense to separate the charts as well (one per service). However, if all services are in the same repo and deployed with a single ci pipeline, then a single chart is a better fit.
All your 4 options will work. And whether you deploy your app with separate charts or with one won't make any difference as long as eventually all your services will be deployed.
As for scaling services independently, if you use separate deployments for your services in one big chart, you can scale them separately by using input values for each deployment in your values.yaml ... so it's not something which forces you to split your charts.
And for your image changing question in the comments, it only needs an upgrade for your installed release with the new image tag.
By the way, We use helmsman for deploying (and managing) helm charts from code in our CI/CD pipelines. Might be useful for you ;)

We have a similar problem, and we choose the lean way: first simple and functional, then evolve.
We started with a simple chart deploying all services because our main requirement it's to have one installer. But we know that in short time we are gonna to refactor to use 3rd party charts and even our own charts in our own repo to handle different deployment strategies and independent evolution of services.

Probably useful resource: https://medium.com/faun/dry-helm-charts-for-micro-services-db3a1d6ecb80
We’ll create a chart for each service, an Umbrella chart, and a Common chart.
The punch here is the Common chart. This chart will contain templates for all the common resources of our services, viz. Deployment, Service, Ingress, ConfigMap and more.
Each service chart will only include the common templates required for the service and supply service-specific values.
Finally, the Umbrella chart will (surprisingly) just unify the services charts.

Related

Horizontal Scalability with Drools

Knowing that drools work with in memory data. Is there a way to distribute horizontally on different drools instances to enhance performance when performing CRUD operations on rules, fact types, etc? I guess the instances would need to be on sync with each other in some way, so they all have the same data in memory or share in some way a knowledge base. I'm kinda new on drools and trying to research on a way to move a monolith on a cloud environment (gcp) so it can take advantage on load balancing, scaling, etc. Want to know if there is any feature on drools itself that supports this or if there is any way to implement this myself, thanks in advance for any information/documentation/use case on this matter.
Currently I haven't tried a way to do this, but my goal is to improve performance and availability by using automatic scaling or support multiple instances of my app.
I'm not sure what kind of "CRUD" you're doing on Drools (or how). But if you just want to deploy new rules (for example), then this is identical to pushing any data or application changes to your deployment in a distributed system -- either your nodes are gradually updated, so during the upgrade process you have some mix of old and new logic/code; or you deploy new instances with the new logic/code and then transition traffic to your new instances and away from the old ones -- either all at once or in a controlled blue/green (or similar) fashion.
If you want to split a monolith, I think the best approach for you would be to consider Kogito [1] and microservice architecture. With microservices, you could even consider using the Function as a service approach - having small immutable service instances, that are just executed and disposed. Kogito mainly targets Quarkus platform, but there are also some Spring Boot examples. There is also OpenShift operator available.
As far as sharing the working memory, there was a project in the KIE community called HACEP [2]. Unfortunately that is now deprecated and we are researching other solutions to make the working memory persisted.
[1] https://kogito.kie.org/
[2] https://github.com/kiegroup/openshift-drools-hacep
The term "entry point" is related to the fact that we have multiple partitions in a Working Memory and you can choose which one you are inserting into. If you can organize your business logic to work with different entry points you can process 'logical partitions' on different machines in parallel safely. At a glance drools entry points gives you something like table partitioning in Oracle which implies the same options.
Use load balancer with sticky sessions if you can (from business point of view) partition 'by client'
you question looks more like an architecture question.
As a start, I would have a look into the Kie Execution Server component provided with Drools that helps you to create microservice decisions based on Drools rulesets.
Kie Execution Server (used in stateless mode by clients) could be embedded in different pods/instances/servers to ensure horizontal scalability.
As mentioned by #RoddyoftheFrozenPeas , one of the problem you'll face will be the simultaneous hot deploy of new rulesets on the "swarm" of kieserver that hosts your services.
That would have to be handled using a proper devops strategy.
Best
Emmanuel

Usage of Namespaces in Kubernetes

I got a question regarding namespaces and seeking your expertise to clear out my doubts.
What I understood about namespaces is that they are there to introduce logical boundaries among teams and projects.
Of course, I read somewhere namespaces can be used to introduce/define different environments within the same cluster.
E.g Test, UAT and PRODUCTION.
However, if an organization is developing a solution and that solution consists of X number of microservices and have dedicated teams to look after those services,
should we still need to use namespaces to separate them or are they gonna deploy in one single namespace reflecting the solution?
E.g if we are developing an e-commerce application:
Inventory, ShoppingCart, Payment, Orders etc. would be the microservices that I can think of. Should we deploy them under the namespace of sky-commerce for an instance? or should they need dedicated namespaces.?
My other question is. if we deploy services in different namespaces, is it possible for us to access them through APIGateway/ Ingress controller?
For an instance, I have the front-end SPA application and it has its BFF (Backend For Frontend). can the BFF access the other services through the APIGateway/Ingress controller?
Please help me to clear these doubts.
Thanks in advance for your prompt reply in this regard.
RSF
Namespaces are cheap, use lots of them. Only ever put two things in the same namespace if they are 100% a single unit (two daemons that are always updated at the same time and are functionally a single deployment) or if you must because a related object is used (such as a Service being in the same ns as Pods it references).
When creating a new Kubernetes namespace, a request is sent using the namespace API using the defined syscalls, and since Kubernetes has admin privileges, a new namespace will be created. The new namespace will contain specifications for the capabilities of a new process assigned under its domain.
In regards to your question above, yes you can keep services in different namespaces as long as they are able to talk together and render the services to the outside world as one piece.
Since all organizations are different, it is up to you to figure out how best to implement and manage Kubernetes Namespaces. In general, aim to:
Create an effective Kubernetes Namespace structure
Keep namespaces simple and application-specific
Label everything
Use cluster separation when necessary

Best practice to build & deploy Temporal workflows

I am using the GO SDK from Temporal, and I was wondering what is the best practice way to package and deploy Workflows.
Can I bundle all my workflows and activities into one Worker service? Is there any limitation by doing this, or is it recommended to deploy/build each workflow separately?
Also I would like to expose http endpoints to trigger the workflows. What is the best practice to do this if I deploy Temporal on Kubernetes (GKE), expose an ingress/service resource?
Thanks!
From the technical point of view, the Temporal doesn't impose any specific requirement on the packaging. It supports a single bundle that contains any number of workflows and activities and it supports deployment of a single activity or workflow type independently.
Treat workflows and activities as long-running operations. Then treat the unit of deployment as a microservice. Then the same logic that applies to microservices applies here. So if collocating workflows and activities together makes sense from the code and operational point of view do it.

How many namespace can a cluster k8s hold?

If I want to develop a SaaS system and want to use k8's namespace to do isolation, i.e., I will create a namespace for every user, it's a multi-tenancy system, then, how many namespaces can I have? Will k8s be slowdown when namespace increases?
To answer your question, namespace is a logical entity that is used to isolate the application environment from another application environment. It doesn't consume cluster resources like cpu and memory. Ideally you can create any number of namespaces. Am not sure if there is a limit on number of namespaces that is allowed in a custer
On the other hand it is not a good approach to have one namespace each for user. Applications multi tenancy should be better handled in the application code itself. Namespace is recommended to isolate the environment like one for Development, one for TEST, one for QA and Another one for production
This is a pretty good write-up on some best-practices around namespaces and how to organize things with them:
https://cloud.google.com/blog/products/containers-kubernetes/kubernetes-best-practices-organizing-with-namespaces
There are likely use-cases where you can have too many namespaces, but it is very unlikely that you will see this unless you have a custom application or controller that is doing something unwise and needs some of its logic reworked.

Best way to achieve feature flag based routing in Kubernetes

I would like to set up an infrastructure that enables easy experimentation in the production environment for developers in my team.
For example, let's assume that I have a HTML page that lists purchases for on online retail shop. The production version is implemented using React, but we would like to test out some alternative implementations, for example one written in Vue.js, and the other one that is not JS based and instead uses backend rendering.
In this scenario, I would like to flip a feature flag for all the developers who are working on the Vue.js implementation to see the Vue.js page, and for the backend rendering team to see their implementation.
In Kubernetes, each implementation would be a different pod/replication set/service.
What is the best pattern to implement the above routing scheme in Kubernetes? Is Istio based intelligent HTTP header based routing a good candidate for this task?
From my perspective, more clean way is to use different path/FQDN for each type of backend and manage all of them by any ingress controller. At least it will able your developers to access the new version without customization of requests.
But, if you want to use a header as a feature flag and manage routing based on it, then yes, content based routing in Istio will be OK, I think.