9 February 2019
Now that Kubernetes is on Azure, what is Service Fabric for?
Now that Kubernetes has gained traction in Azure there is some confusion over what Service Fabric is really for. Is it an orchestrator for microservices? A means of lifting and shifting legacy applications into the cloud? An application development framework?
Large areas of the Azure infrastructure have been built out using Service Fabric, but that doesn’t necessarily make it an ideal candidate for building modern, cloud-native applications. Microsoft may have eaten their own dogfood internally, but the recent popularity of Azure Kubernetes Service implies that Service Fabric is may not be an ideal choice for running container-based applications.
One of the sticking points of Service Fabric has always been the difficulty involved in managing a cluster with patchy documentation and a tendency towards unhelpful error messages. The recent public preview of Service Fabric Mesh offers a PaaS-based implementation of Service Fabric which may eliminate much of this operational baggage. However, it doesn’t change the experience of building applications using the underlying SDKs.
Building applications for Service Fabric
The main problem with targeting applications for Service Fabric is that they will lack portability. The Service Fabric SDK is incredibly opinionated. If you commit to Service Fabric, you will be tied into a specific SDK and application server for good. This is some way from the kind of cloud-native, twelve factor applications typically associated with container-based development.
Service Fabric isn’t directly comparable to container orchestrators such as Kubernetes as it is more of an application server that supports a specific style of distributed system. This is based on applications, which serve as the boundary for upgrades in that different application versions can be run on the same cluster. The Service Fabric runtime manages the individual nodes in the cluster, providing capabilities to deploy, scale and monitor individual applications.
These applications can be composed of any number of services. The SDK encourages application code to be combined with deployment details in a single Visual Studio solution which is deployed to the cluster. The overhead of setting up a new solution tends to encourage larger applications made up of several services, rather than more numerous, isolated microservices.
Native Service Fabric services are based on very specific styles of implementation. Reliable services can be either stateless where state is managed externally, or stateful where state is managed by the Service Fabric runtime. Both types of service require base classes such as StatelessService to define their entry points, coupling them to the underlying SDK.
Service Fabric also offers reliable actors, a pattern where state and behaviour are combined into small, isolated units. The runtime looks after the persistence and life-cycle and persistence of these actors. The approach can be a good fit for scenarios that require large numbers (i.e. thousands or more) of these units, such as shopping carts or user sessions.
The catch is that reliable actors tie services irrevocably to a very specific application server. They can also be abused in much the same way as any shared database, often being used to maintain global state, provide a cache or even acts as a queue. There are usually other ways to solve the problem that don’t involve such a strong platform lock-in.
Using Service Fabric as an orchestrator
Service Fabric also supports two other types of application: guest executables and containers. Guest executables provide a mechanism for running legacy windows applications in the context of a service orchestrator. Hey presto – instant microservices. Kind of.
Service Fabric’s container support provides a lifeline for those who have made a commitment to Service Fabric yet are looking to get into container-based services. The catch is that containers in Service Fabric do feel like second class citizens. The process of configuring and running containers in Service Fabric does not compare well with a “pure” container orchestrator like Kubernetes.
At the time of writing, it seems that Service Fabric’s external application support is geared more around lifting, shifting and modernising .Net applications using Windows containers. If you want to build container-based applications, Azure seems to be evolving several complimentary services targeted at different processing needs.
The Azure Kubernetes Service is evolving towards providing a PaaS-based implementation of Kubernetes, which is ideal if you want to orchestrate applications without operational overhead. You can run a single application based on one or more container images using the Azure App Service. Container Instances can be used to spin up single instances and can be a useful means of spinning up occasional jobs or providing burst capacity. Azure Batch is optimised more towards repetitive compute jobs.
Each of these services provide a more “container native” approach to development than Service Fabric. There really doesn’t seem to be much reason to adopt Service Fabric unless you have a bunch of legacy services kicking around that you want to run in the context of an orchestrator.
A shrinking set of use cases
You can see why Service Fabric happened. Microsoft didn’t have a story for running .Net applications as autonomous services in a flexible cluster-style arrangement. Genuine cloud native services in the.Net ecosystem were a long way off. It was difficult to foresee how the Docker ecosystem was going to mature and that Kubernetes would become so popular.
Service Fabric does seem to be getting squeezed out of a growing Azure container ecosystem. If you’ve already made the investment in building applications for Service Fabric there’s no compelling reason to abandon it immediately. However, the use cases that justify its adoption now are rapidly shrinking.