Multiple Guest Executable in one Service Fabric node - azure-service-fabric

I want to deploy multiple guest executables in one node but I'm not sure how does it works behind the screens? How are the VMs resources divided between each executable? Is it done in an efficient way? Do I need to configure something for getting all the executable well packed in the VM to save memory? How can I know how many executables can be run on the same VM?

In order to understand how Service Fabric allocates services inside nodes you need to understand its hosting model.
Service Fabric hosting model is very powerful when using the Service Fabric programming model (Stateless and Stateful services and Actors), but more limited with Guest Executables and Containers, although it's still efficient.
Basically, Service Fabric will activate a ServicePackage (a process) for each Guest Executable (service). Depending on the configured number of instances for each service, Service Fabric will either run one instance of each service per node (if InstanceCount = -1) or it will distribute the instances across all the nodes (if InstanceCount is a number lower than the number of nodes).
There is no limitation on the number of services you can run on a single node, but each service will consume resources (CPU, RAM, ports, etc) and it can become a problem. In that case, you have several options:
Increase the size of the VM for that node type
Scale out the node type (add more nodes) and specify a lower number of instances per service (so that not every node has all services)
Create more node types and organize the services accordingly using Placement Constraints (for example, you could have High Compute nodes, High Ram nodes, Public Nodes, Backend Nodes, Financial Nodes, Analytics Nodes... it depends on what makes sense for your scenario).
How can I know how many executables can be run on the same VM?
As I mentioned before, this does not depend on the quantity, but in the resources used by these executables and the size of the VM. Depending on your services, you might be able to estimate the resources they need, but you'll definitely need to test and monitor your cluster because no amount of calculations beats reality.
Update: add interesting links
You can help Service Fabric manage your cluster more efficiently by making your services report dynamic metrics and also by providing limits to what resources a single service can take (to avoid a service from consuming all the memory of a node for example):
Custom Metrics
Resource Governance

Related

Does kubernetes support non distributed applications?

Our store applications are not distributed applications. We deploy on each node and then configured to store specific details. So, it is tightly coupled to node. Can I use kubernetes for this test case? Would I get benefits from it?
Our store applications are not distributed applications. We deploy on each node and then configured to store specific details. So, it is tightly coupled to node. Can I use kubernetes for this test case?
Based on only this information, it is hard to tell. But Kubernetes is designed so that it should be easy to migrate existing applications. E.g. you can use a PersistentVolumeClaim for the directories that your application store information.
That said, it will probably be challenging. A cluster administrator want to treat the Nodes in the cluster as "cattles" and throw them away when its time to upgrade. If your app only has one instance, it will have some downtime and your PersistentVolume should be backed by a storage system over the network - otherwise the data will be lost when the node is thrown away.
If you want to run more than one instance for fault tolerance, it need to be stateless - but it is likely not stateless if it stores local data on disk.
There are several ways to have applications running on fixed nodes of the cluster. It really depends on how those applications behave and why do they need to run on a fixed node of the cluster.
Usually such applications are Stateful and may require interacting with a specific node's resources, or writing directly on a mounted volume on specific nodes for performance reasons and so on.
It can be obtained with a simple nodeSelector or with affinity to nodes ( https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/ )
Or with local persistent volumes ( https://kubernetes.io/blog/2019/04/04/kubernetes-1.14-local-persistent-volumes-ga/ )
With this said, if all the applications that needs to be executed on the Kubernetes cluster are apps that needs to run on a single node, you lose a lot of benefits as Kubernetes works really well with stateless applications, which may be moved between nodes to obtain high availability and a strong resilience to nodes failure.
The thing is that Kubernetes is complex and brings you a lot of tools to work with, but if you end up using a small amount of them, I think it's an overkill.
I would weight the benefits you could get with adopting Kubernetes (easy way to check the whole cluster health, easy monitoring of logs, metrics and resources usage. Strong resilience to node failure for stateless applications, load balancing of requests and a lot more) with the cons and complexity that it may brings (especially migrating to it can require a good amount of effort, if you weren't using containers to host your applications and so on)

Kubernetes can I use two servers for one application?

I want to create kubernetes cluster, and what I need to do is, I have two servers. (Nodes) with 10x Intel Xeon and 32gb ram each. Can I run one application on both of them, so the application can use 20 cores, and 64gb of ram?
Of course you can't. If you run application in kubernetes, then kubernetes will create a structure called pod to help run it. Each of your server will be a node in kubernetes. There can be many pods running this application ,but for each pod it can only use the resource of one node where the pods assigned.( a pod is like a container, but I don't know how it works)
If your application really needs 20 cores and 64gb, then you need a node that actually has 20 cores and 64gb.
But if you just want to make the full use of the resource, you can check the resource limit of your application (or calculate it by your own) and calculate how many copies you need to fully use your resource. For example, if your application needs at least 1 core and 1gb to run, then you can use a replicas and make 20 copy(may be less).
No, it is not possible to span a single pod across 2 different physical/virtual nodes. One single application running inside your pod(minimal object in K8s) can only utilize the maximum capacity(virtually) of the underlying node on which the pod is scheduled.
As #youth Wu said, try to check the resource limit of your application and start with the minimal one and if your application really needs resources more then the available resources on a node then, you have to scale your nodes vertically without any choice.

Question about 100 pods per node limitation

I'm trying to build a web app where each user gets their own instance of the app, running in its own container. I'm new to kubernetes so I'm probably not understanding something correctly.
I will have a few physical servers to use, which in kubernetes as I understand are called nodes. For each node, there is a limitation of 100 pods. So if I am building the app so that each user gets their own pod, will I be limited to 100 users per physical server? (If I have 10 servers, I can only have 500 users?) I suppose I could run multiple VMs that act as nodes on each physical server but doesn't that defeat the purpose of containerization?
The main issue in having too many pods in a node is because it will degrade the node performance and makes is slower(and sometimes unreliable) to manage the containers, each pod is managed individually, increasing the amount will take more time and more resources.
When you create a POD, the runtime need to keep a constant track, doing probes (readiness and Liveness), monitoring, Routing rules many other small bits that adds up to the load in the node.
Containers also requires processor time to run properly, even though you can allocate fractions of a CPU, adding too many containers\pod will increase the context switch and degrade the performance when the PODs are consuming their quota.
Each platform provider also set their own limits to provide a good quality of service and SLAs, overloading the nodes is also a risk, because a node is a single point of failure, and any fault in high density nodes might have a huge impact in the cluster and applications.
You should either consider:
Smaller nodes and add more nodes to the cluster or
Use Actors instead, where each client will be one Actor. And many actor will be running in a single container. To make it more balanced around the cluster, you partition the actors into multiple containers instances.
Regarding the limits, this thread has a good discussion about the concerns
Because of the hard limit if you have 10 servers you're limited to 1000 pods.
You might want to count also control plane pods in your 1000 available pods. Usually located in the namespace kube-system it can include (but is not limited to) :
node log exporters (1 per node)
metrics exporters
kube proxy (usually 1 per node)
kubernetes dashboard
DNS (scaling according to the number of nodes)
controllers like certmanager
A pretty good rule of thumb could be 80-90 application pods per node, so 10 nodes will be able to handle 800-900 clients considering you don't have any other big deployment on those nodes.
If you're using containers in order to gain perfs, creating node VMs will be against your goal. But if you're using containers as a way to deploy coherent environments and scale stateless applications then using VMs as node can make sense.
There are no magic rules and your context will dictate what to do.
As managing a virtualization cluster and a kubernetes cluster may skyrocket your infrastructure complexity, maybe kubernetes is not the most efficient tool to manage your workload.
You may also want to take a look at Nomad wich does not seem to have those kind of limitations and may provide features that are closer to your needs.

Kubernetes - Single Cluster or Multiple Clusters

I'm migrating a number of applications from AWS ECS to Azure AKS and being the first production deployment for me in Kubernetes I'd like to ensure that it's set up correctly from the off.
The applications being moved all use resources at varying degrees with some being more memory intensive and others being more CPU intensive, and all running at different scales.
After some research, I'm not sure which would be the best approach out of running a single large cluster and running them all in their own Namespace, or running a single cluster per application with Federation.
I should note that I'll need to monitor resource usage per application for cost management (amongst other things), and communication is needed between most of the applications.
I'm able to set up both layouts and I'm sure both would work, but I'm not sure of the pros and cons of each approach, whether I should be avoiding one altogether, or whether I should be considering other options?
Because you are at the beginning of your kubernetes journey I would go with separate clusters for each stage you have (or at least separate dev and prod). You can very easily take your cluster down (I did it several times with resource starvation). Also not setting correctly those network policies you might find that services from different stages/namespaces (like test and sandbox) communicate with each other. Or pipelines that should deploy dev to change something in other namespace.
Why risk production being affected by dev work?
Even if you don't have to upgrade the control plane yourself, aks still has its versions and flags and it is better to test them before moving to production on a separate cluster.
So my initial decision would be to set some hard boundaries: different clusters. Later once you get more knowledge with aks and kubernetes you can review your decision.
As you said that communication is need among the applications I suggest you go with one cluster. Application isolation can be achieved by Deploying each application in a separate namespace. You can collect metrics at namespace level and can set resources quota at namespace level. That way you can take action at application level
A single cluster (with namespaces and RBAC) is easier to setup and manage. A single k8s cluster does support high load.
If you really want multiple clusters, you could try istio multi-cluster (istio service mesh for multiple cluster) too.
Depends... Be aware AKS still doesn't support multiple node pools (On the short-term roadmap), so you'll need to run those workloads in single pool VM type. Also when thinking about multiple clusters, think about multi-tenancy requirements and the blast radius of a single cluster. I typically see users deploying multiple clusters even though there is some management overhead, but good SCM and configuration management practices can help with this overhead.

How to deploy multi - tier application with Kubernetes

If I have a multi - tier application (say web / logic / database), where each tier having it's own container, and I need to deploy all of these en - bloc, do they all have to go into the same pod?
And if they are in the same pod, does this have any implications in terms of the maximum size of application that can be run?
Or is there some higher level abstraction that I can use to start all three layers, but have them running on different minions?
Why do you need to deploy all of the components together? In a micro services architecture, you would want to reduce the dependencies between each layer to a clean interface and then allow each layer to be deployed and scaled separately from the others.
If you need to deploy them together (e.g. they share local disk or localhost networking) then you need to deploy them as a single pod. A single pod is an atomic scheduling unit, so it will be deployed onto a single host machine. Since it lands on a single host, this limits the scalability of your application to the size of a single host (not allowing you to scale out as your traffic increases).
If your three layers are not tightly coupled, then you can run them in different pods, which allows them to be scheduled across multiple hosts (or on the same host if, for example, you are doing local development). To connect the pods together, you can define services.
You should take a look at the guestbook example which illustrates how to define pods and services for a simple multi-tier web application running on Kubernetes.