Sahan Serasinghe

Software Engineer | Data Enthusiast

Deploying Multi-Container Services on Azure Service Fabric

2020-04-13microservices 7 min read

To give you a bit of context on what we will be looking at today, we will have one goal - to deploy a microservices application to Azure with Service Fabric. My preferred choice of a cloud these days would be Azure since I have been working on it for a while now.

To keep things simple, we will be looking at the deployment of a multi-container application rather than worrying too much about what the application does.

Prerequisites

If you followed my previous post, you would already have the below mentioned installed on your developer workstation.

  1. Docker Desktop
  2. Azure account
  3. Azure Service Fabric SDK and tooling

Creating a demo app

Now that we have some basic understanding of what Azure Sevice Fabric is capable of, let’s look at what we are going to building today

  1. Create a containersed React app
  2. Create a containerised .NET Core service
  3. Create a Service Fabric project
  4. Wrap our above mentioned service in the Service Fabric project
  5. Build a CI/CD pipeline in Azure DevOps

At a glance, this will be the architecture of our demo project.

Scaffolding our multi-container application

You can clone my Github repository to get started.

git clone https://github.com/sahan91/deploying-containers-on-service-fabric.git

The folder structure is as follows:

ProjectStructure.jpg

For each project, I have created a Dockerfile. What they basically do is, build each project and expose a port from their respective containers.

Web - Dockerfile

# Stage 1 - the build process
FROM node as build-deps
WORKDIR /usr/src/app
COPY web-client/package.json web-client/yarn.lock ./
RUN yarn --no-bin-links
COPY ./web-client/. ./
RUN yarn build

# Stage 2 - the deploy process
FROM nginx
COPY --from=build-deps /usr/src/app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

The reason for having stages here is because we don’t want to include the source code in the container since we only need to copy the executable or the build output over to the container.

ProductCatalog - Dockerfile

For the .NET Core project, we have a bit more involved since we need to have the .NET Core 3.1 SDK to build the project and .NET Core 3.1 runtime to run the project.

FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build-env
WORKDIR /app

# Copy csproj and restore as distinct layers
COPY ./*.sln .
COPY ./ProductCatalog/*.csproj ./ProductCatalog/
RUN dotnet restore

# Copy everything else and build
COPY ./ProductCatalog/. ./ProductCatalog
WORKDIR /app/ProductCatalog
RUN dotnet publish -c Release -o app

# Build runtime image
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 AS runtime
WORKDIR /app
COPY --from=build-env /app/ProductCatalog/app .
ENTRYPOINT ["dotnet", "ProductCatalog.dll"]

Building and tagging images

We can run the following command to test out our images locally.

If you haven’t used Docker Hub before. Here’s a quick intro to creating a repository and pushing images.

In a terminal, navigate to ProductCatalog/ folder and run the following command

docker build -f . -t <your_docker_hub_username>/service-fab:product-catalog-img

Now change directory to Web/ folder, let’s build and tag backend service’s Docker image

docker build -f . <your_docker_hub_username>/service-fab:web-shop-img

Pushing the images to Docker Hub

In order for Service Fabric to fetch and build our container images, we need to first push them to a container registry. I’m using Docker Hub here as an example. But you can use any other registry such as GCR, ACR etc. These repositories can be either public or private.

Make sure you are already logged in to Docker service from the command line,

docker login --username=yourhubusername --email=youremail@company.com

Check the image ID using,

docker images

This will come in handy in the following command.

Now let’s push the images with,

docker push <image_name>

We need to run this command twice for both frontend and backend images we created.

Configuring Service Fabric project

Let’s open up WebShop solution in Visual Studio. You can configure the credentials in your Service Fabric project.

Frontend configuration WebShopClientPkg/ServiceManifest.xml

<!-- Code package is your service executable. -->
<CodePackage Name="Code" Version="1.0.0">
  <EntryPoint>
    <!-- Follow this link for more information about deploying Windows containers to Service Fabric: https://aka.ms/sfguestcontainers -->
    <ContainerHost>
      <ImageName>**index.docker.io/sahan/service-fab:web-shop-img**</ImageName>
    </ContainerHost>
  </EntryPoint>
  <!-- Pass environment variables to your container: -->
  <!--
  <EnvironmentVariables>
    <EnvironmentVariable Name="VariableName" Value="VariableValue"/>
  </EnvironmentVariables>
  -->
</CodePackage>

Backend service configuration WebShopApiPkg/ServiceManifest.xml

<!-- Code package is your service executable. -->
<CodePackage Name="Code" Version="1.0.0">
  <EntryPoint>
    <!-- Follow this link for more information about deploying Windows containers to Service Fabric: https://aka.ms/sfguestcontainers -->
    <ContainerHost>
      <ImageName>**index.docker.io/sahan/service-fab:product-catalog-img**</ImageName>
    </ContainerHost>
  </EntryPoint>
  <!-- Pass environment variables to your container: -->
  <!--
  <EnvironmentVariables>
    <EnvironmentVariable Name="VariableName" Value="VariableValue"/>
  </EnvironmentVariables>
  -->
</CodePackage>

Note how I have replaced the path to the Docker Hub registry in both configs.

Creating a Service Fabric cluster

Before deploying our services, we need to create a Service Fabric cluster in Azure. In the Azure portal, just type in service fabric and click on Create service fabric cluster.

Now, fill in the cluster info as shown below.

service-fabric.png

In the cluster configuration step, you will be asked to set the Node type count. Just set it to 2 to denote frontend and backend services. In the same page, you will be asked how many nodes you want to create for each node type. Select Single node cluster, for now, otherwise, you will be charged for the total number of VMs. However, this is not recommended for production-grade apps.

In order to expose our frontend and backend services let’s enter endpoints as port 80 and 81 respectively.

service-fabric-1.png

Next up, we need to create a key vault for our service fabric cluster. This is a very important step and make sure to select the Azure Virtual Machines for deployment checkbox. You will also need to enter a name for the certificate. We will cover this in a bit. Give it some time to create the key vault and proceed to the next step.

service-fabric-2.png

service-fabric-3.png

Once it’s up, you will see you cluster like so,

service-fabric-4.png

It may take up to 15 minutes until your VMs start to appear under the Nodes list.

Installing client certificate

In order to be able to access the Service Fabric dashboard, you need to install the client certificate from the key vault.

  1. Head over to Azure Portal → ’Key Vault’ → Select the key vault we created in the previous step’s Certificates
  2. Select the certificate (there should be only 1 at this stage)
  3. Click Download PFX/PEM format

service-fabric-5.png

Once downloaded double click the certificate. You don’t need to enter anything in the Password field and click Next and complete the wizard.

service-fabric-6.png

Now, you should be able to access the dashboard of your cluster. The link will be in Service Fabric home page in Azure Portal.

service-fabric-7.png

Deploying to Azure

The fast and the quickest way to deploy your app is by using Visual Studio. Just right click on the service fabric project and select Publish

service-fabric-8.png

service-fabric-9.png

After about 5 minutes you should be able to see that our services have got deploy to the cluster. You can check that from the following URL:

http://<yourclustername>.<yourclusterregion>.cloudapp.azure.com/

Or, you can get the URL from service fabric portal and remember to delete the port number and revert it to http://

Our frontend running at port 80

service-fabric-10.png

Our backend service running at port 81

service-fabric-11.png

In my next post, we will look at how to set up an Azure DevOps build pipeline to deploy your services to a designated Service Fabric cluster. ✌

References

  1. https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-overview