We are trying to migrate our microservices architecture to K8s and Istio. We will have two k8s different clusters. One per frontend applications and the another for backend apps. Our initial idea is to configure each cluster as a separated Istio Mesh.
My doubt is;
Can we keep the locality-aware routing between clusters when a frontend app do a request against a backend app?
I have read it is possible when you have one mesh distributed among K8s clusters but I'm not sure if this feature keeps working when a mesh federation architecture is implemented.
Thanks!
There is a functionality with something like that with istio multicluster configuration.
Depending on Your requirements there can be different types of multicluster models.
According to istio documentation:
When configuring a production deployment of Istio, you need to answer a number of questions. Will the mesh be confined to a single cluster or distributed across multiple clusters? Will all the services be located in a single fully connected network, or will gateways be required to connect services across multiple networks? Is there a single control plane, potentially shared across clusters, or are there multiple control planes deployed to ensure high availability (HA)? If there is more than one cluster being deployed, and more specifically in isolated networks, are they going to be connected into a single multicluster service mesh or will they be federated into a multi-mesh deployment?
All of these questions, among others, represent independent dimensions of configuration for an Istio deployment.
single or multiple cluster
single or multiple network
single or multiple control plane
single or multiple mesh
All combinations are possible, although some are more common than others and some are clearly not very interesting (for example, multiple mesh in a single cluster).
As for mesh functionality:
Single mesh
The simplest Istio deployment is a single mesh. Within a mesh, service names are unique. For example, only one service can have the name mysvc in the foo namespace. Additionally, workload instances share a common identity since service account names are unique within a namespace, just like service names.
A single mesh can span one or more clusters and one or more networks. Within a mesh, namespaces are used for tenancy.
Multiple meshes
Multiple mesh deployments result from mesh federation.
Multiple meshes afford the following capabilities beyond that of a single mesh:
Organizational boundaries: lines of business
Service name or namespace reuse: multiple distinct uses of the default namespace
Stronger isolation: isolating test workloads from production workloads
You can enable inter-mesh communication with mesh federation. When federating, each mesh can expose a set of services and identities, which all participating meshes can recognize.
To avoid service naming collisions, you can give each mesh a globally unique mesh ID, to ensure that the fully qualified domain name (FQDN) for each service is distinct.
When federating two meshes that do not share the same trust domain, you must federate identity and trust bundles between them. See the section on Multiple Trust Domains for an overview.
So I suggest applying multicluster model to Your needs. The simplest solution is usually the best. Single mesh multicluster does allow for naming locality for Your multicluster environment.
There is also advanced example of multicluster istio with use of Admiral which allows to have custom naming possibilities.
Hope it helps.
Related
Given that Kubernetes doesn’t offer full visibility into how services interact with each other I want to derive and map services automatically. For eg as shown in the below diagram, how can we derive that the payment service interacts with the cart service and cart service interacts with catalogue and redis.
So far what I had tried is,
kubectl get services command - This command only gives the list of services but does not hint on any communication happening between the services.
Tried Kubeview -> This plots only the deployment architecture and gives a graphical representation but mapping between various services is not derived.
So what is the easiest way to derive information about services interacting with each other and what could be the data source for this information in Kubernetes?
We faced this as well when we were building Otterize -- we needed something to map "who is talking to who" in order to bootstrap our solution, but every tool seemed to be ill suited for the task of simply creating a "network map" without all sorts of stuff we didn't want. We ended up rolling our own, and open sourced it: https://github.com/otterize/network-mapper .
It's based on combining information from DNS queries (actually just query responses) as well as detecting open connections, which gives you an IP-level network map, and then adding a simple resolution heuristic to derive a logical name-level map. You can read more details in this blog post, by one of the guys who built the tool: https://otterize.com/blog/kubernetes-traffic-discovery .
Hope this helps!
You can consider linkerd or other similar tools which offer service Observability
A service mesh like Linkerd is a tool for adding observability, security, and reliability features to “cloud native” applications by transparently inserting this functionality at the platform layer rather than the application layer.
service-mesh
For example, in below screenshot you can see how gate-way service interact with another service
It will also show how the request is going, amount of request with inbound and outbound
So in your case,if payment app is part of mesh you will able to see the inbound and outbound for the service along with requests info.
linkerd-install-helm
Service meshes have three main goals around interservice communication:
Connectivity
Security
Observability
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
I want to deploy a traditional monolithic application in Kubernetes.
Thousands of customers use this application and each customer has its own instance of application. if we have 5 customers we should run 5 separate instances of this application.
The application also calls Kubernetes API for running some jobs.
I want to make sure that everything is isolated, Is it a good idea to create a separate namespace for each customer? Does it cause some performance issues? Is there any better solution for it?
I think you should create multi-tenant cluster.
Such clusters shared by multiple users and/or workloads which are referred to as "tenants". The operators of multi-tenant clusters must isolate tenants from each other to avoid the damage that a compromised. You should know that cluster resources must be fairly allocated among tenants.
When you plan a multi-tenant architecture you should consider the layers of resource isolation in Kubernetes: cluster, namespace, node, pod, and container. You should also consider the security aspects of sharing different types of resources among specific tenants.
Although Kubernetes cannot guarantee perfectly secure isolation between tenants, it does offer features that may be sufficient for specific solutions. For example you can separate each tenant and their Kubernetes resources into their own separate namespaces. Then use policies to enforce tenant isolation. Policies are usually scoped by namespace and can be used to restrict API access, to constrain resource usage, and to restrict what containers are allowed to do.
Read more: multi-tenant-cluster.
However while implementing multi-tenancy with Kubernetes, you need to decide if you need soft multi-tenancy (is focused on minimising accidents and managing the fallout) or hard multi-tenancy(assumes tenants to be malicious and therefore advocates zero trust between them). In any case, you have to answer questions: how to limit their resource usage, how to manage the users/tenants and how to isolate them from each other. There are many tools, for example: loft which can help you to get multi-tenancy with Kubernetes.
See: multi-tenant-loft.
Take a look: best-practices-multitenant.
I found the following documentation on istio on how to create an API Key
https://istio.io/docs/reference/config/policy-and-telemetry/templates/apikey/
But i am unable to find any documentation or examples on how to use the thing to secure a service.
Can anyone help?
Istio represents Mixer configuration Model in terms of propagating authorization policies within the service mesh. Policy and telemetry features are actually based on configuring such kind of CRD resources as:
Handlers - define appropriate Adapters and a communication way between Mixer and some external infrastructure software;
Instances - introduce the source data set across particular attributes being afforded with related Adapter.
Rules - bind specific Handler to Instance, matching rule expressions.
You may also find predefined templates for individual adapters, the link mentioned above in the origin question reflects the particular template for generic API key, but it doesn't describe any process for authorization policy enforcement.
In context, to leverage using authentication requests with API keys, you will probably require to implement Analytics or Authorization templates, using i.e. Apigee adapter. You can visit Apigee's Istio Mixer Adapter repository with a quite good tutorial securing mesh service authentication within API key header.
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.