Category Archives: Microservices by LJ

Microservices – notes from Les Jackson course

Here I have some short notes made while watching microservice course.

The original video:

Building ASP.NET API

Just create dbContext with entities, after that repository which takes this dbContext. Add DTOs, automapper and it’s profiles to map DTO<->Entities. Add controller which uses repository and automapper to handle actions.

Dockerize ASP.NET application

Generally follow these instructions.

Example dockerfile:

# base on .net sdk image to build your app
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /source

# copy your csproj(s) and restore nuget packages
COPY *.sln .
COPY aspnetapp/*.csproj ./aspnetapp/
RUN dotnet restore

# copy everything else and build and publish app
COPY aspnetapp/. ./aspnetapp/
WORKDIR /source/aspnetapp
RUN dotnet publish -c release -o /app --no-restore

# final stage/image; here base on image without sdk to make it smaller
# just copy and run your .net library (API project)
FROM mcr.microsoft.com/dotnet/aspnet:6.0
WORKDIR /app
COPY --from=build /app ./
ENTRYPOINT ["dotnet", "aspnetapp.dll"]

Most used docker commands:

docker build -t dockerhubname/myappname . # builds image from dockerfile

docker run -p 8080:80 -d dockerhubname/myappname # runs a new container using given image, after that you can hit you API on port 8080

docker stop containerId #stops running container

docker start containerId #starts existing stopped container

docker push dockerhubname/myappname #pushes image to docker hub

Kubernetes

Kubernetes (K8S) is orchestrating docker containers. There is simpler option to achieve this – docker compose.

In our simple case we have single cluster with single node in it. In node we have pods. Pods can run containers (again in our case in one pod we have one container, so one pod – one API project). Each Pod has got it’s Cluster IP.

Node port – is a service used in dev env to test whether everything works. Not used on prod.

Load balancer – is a service for load balancing. It will hit Pod with Ingress Nginx Container (proxy/gateway).

In K8S you can set things imperative (write commands) and declarative way (write config file).

Create myapp-depl.yaml to create POD declarative way. K8S uses REST API under the hood to create and destroy services. In ‘spec’ part of yaml file you configure your pod (dockerimage name, how many replicas/instances).

In the same file you can later define clusterIP (protocol, ports mapping) to communicate between PODs. While defining clusterIP you define a name. This name should be copied into you api config ‘appsettings.{Production}.json’ as you can need it for communiction between API services. I.e. appsettings.Development.json you can have ‘CommandsServiceUrl: http://localhost/api/&#8217; and in appsettings.Production.json you can have ‘CommandsServiceUrl: http://commands-clusterip-srv:80/api/&#8217;

To enable kubernetes, go to docker hub and in options set enable kubernetes.

To see it running in cmd: kubectl version

To create POD in cmd: kubectl apply -f myapp-deploy.yaml

To check it in cmd: kubectl get deployments (or kubectl get pods)

You can list namespaces: kubectl get namespace

After a moment you can also check in docker that there is running container (cmd or desktop app).

Create myapp -np-srv.yaml to create Node Port (to allow access from outside to a POD) and define port mapping (internal node port – container; you don’t define external port clients use to reach your API).

To create Node Port in cmd: kubectl apply -f myapp-np-srv.yaml

To check it in cmd: kubectl get services

Synchronous Messaging

We use HTTP REST API in this course. There are two API services (Platforms and Commands). When PlatformService creates new platform we want to send this info to CommandsService. We create HttpCommandDataClient using HttpClient and IConfiguration. We implement method SendPlatformToCommand(PlatformReadDto p). In ConfigureServices we register it: services.AddHttpClient<IHttpCommandDataClient, …>()

API Gateway

We use ingress nginx container for kubernetes. Go to it’s github’s installation page and just execute kubectl apply command. It will create pod and load balancer (but not in default namespace).

You need to create routing file for ingress-nginx to route to our API services: ingress-srv.yaml Generally we map here hostname (you can put any host name here and configure your machine hosts file to redirect it to localhost) and specific paths (i.e. /api/platforms) to specific clusterIp and port. It means if somebody hits this path, route him to specific service on defined clusterIP.

Then kubectl apply -f ingress-srv.yaml

Persistent Volume Claim

PVC is needed to put db there, outside of a container which can be restarted and all it’s data is lost. We create here local-pvc.yaml (define size and access mode), then kubectl apply -f local-pvs.yaml and check it by kubectl get pvc and kubectl get storageclass.

To create secret in K8S: kubectl create secret generic mssql –from-literal=SA_PASSWORD=”pwd”. Then secret name is ‘mssql’ and value is ‘pwd’.

MessageBroker – RabbitMQ

RabbitMQ exchanges:

  • Direct – based on routing key, unicast, to specific queue
  • Fanout – broadcast, to all queues
  • Topic
  • Header

To be continued:

.https://youtu.be/DgVjEo3OGBI?t=26910