Microservices
on
Azure
The good, the bad and the ugly
Before we start
Survey
Who am I?
Piotr Stapp
- Unique name - just sing a song: "Don't Stapp me know" ;)
- CEO @ Dotnetomaniak
- VP @ devWarsztaty
- ex-Head architect @FinAi
- "Top secret" @ Allegro (Pay)
- M.Sc (distction) Oxford Brooks University in Web Tech
- M.Sc. Warsaw University of Technology in Computer Science
- And ......
What about microservices experience?
- mBank - a lot of (micro)services
- FinAi - 100% microservices on Azure
- Allegro - again 100% microservies on Azure
The app
Microservices
- Shiny UI in Angular/React/Vue
- REST / gRPC
- MongoDB/Cassandra/SQL?
- RabbitMQ/Kafka
- Kubernetes/Hosting
Microservices
- Shiny UI in Angular/React/Vue
- REST / gRPC
- RabbitMQ/Kafka
- MongoDB/Cassandra/SQL?
- Hosting/Kubernetes
- API Gateway!
Survey result
Database
Options (built-in)
-
SQL
- Azure SQL
-
Azure Database for PostgreSQL
-
Azure Database for MySQL
-
Azure Database for MariaDB
- NoSQL
- Azure Cosmos DB
- Azure Cache for Redis
- Table storage (simple key value)
- Self-hosted :)
Where is MongoDB or Cassandra?
Azure Cosmos DB
Using
Azure CLI
- Creating is easy :)
- 5-15 minutes :(
- I will cheat a bit
az cosmosdb create \
--name $COSMOS_DB_NAME \
--resource-group $group \
--kind MongoDB
Making it cheap
- Use Free Tier when possible :)
- Use shared throughput on database level
- Think about indexes:
- default is the strings with hash, numbers by value
- up to the third level
- Apply dynamic scaling - manual or automatic :)
- It offers 99.999% SLA for both read and write availability
- Use calculator to plan proper RU before start https://cosmos.azure.com/capacitycalculator/
Funny error
var query = _dbClient.Where<UserDocument>( _collectionUri,
d =>d.User.Email.ToLower() == criteria.SearchString);
SELECT * FROM c
WHERE LOWER(c.User.Email) = "{search}"
------------------------------
var query = _dbClient.Where<UserDocument>( _collectionUri,
d => d.User.Email.Equals(originalSearchString,
StringComparison.OrdinalIgnoreCase));
SELECT * FROM c
WHERE STRINGEQUALS(c.User.Email, "{search}", true)
Build our app
Options
- CI/CD
- GitHub
- Azure DevOps
- Any other :)
- Fast and semi-CI/CD
- Azure Container Instances for Docker
- Manual
- Your own machine
Container registry
- Public
- docker hub
- ...
- Private:
- any
- Azure Container Registry
- ...
Create Azure Container Registry
with Azure CLI
az acr create \
-n $ACR_NAME \
-g $group -l westeurope \
--sku Standard \
--admin-enabled true
Build an App
with Azure CLI
# build data-api
az acr build \
--registry $ACR_NAME \
-g $group \
--file node/data-api/Dockerfile \
--image smilr/data-api $GIT_URL
# build frontend
az acr build \
--registry $ACR_NAME \
-g $group \
--file node/frontend/Dockerfile \
--image smilr/frontend $GIT_URL
# get logs
az acr task logs \
--registry $ACR_NAME \
-g $group
Hosting simple
Azure Web App
- .NET, Java, Node.js, PHP, and Python on Windows
- .NET Core, Node.js, PHP or Ruby on Linux
- Docker on Linux
More:
App Plan
Something to host apps :)
az appservice plan create \
-n appPlan \
-g $group \
--sku B1 --is-linux
Prepare deployment
To deploy demo app we need:
- Cosmos (Mongo) connection string
- Azure Container Registry Credentials
export COSMOS_CONN_STR=$(az cosmosdb keys list \
-n $COSMOS_DB_NAME -g $group \
--type connection-strings \
--query 'connectionStrings[0].connectionString' -o tsv)
DOCKER_PASS=$(az acr credential show -n $ACR_NAME -g $group \
--query 'passwords[0].value' -o tsv)
DOCKER_USER=$(az acr credential show -n $ACR_NAME -g $group \
--query 'username' -o tsv)
Deploy
data-api
with CLI
# Create
az webapp create --plan appPlan \
-n $APP_DATA -g $group \
--deployment-container-image-name \
$ACR_NAME.azurecr.io/smilr/data-api \
--docker-registry-server-user \
$DOCKER_USER \
--docker-registry-server-password \
$DOCKER_PASS
# Database connection
az webapp config appsettings set \
-g $group -n $APP_DATA \
--settings \
MONGO_CONNSTR=$COSMOS_CONN_STR
# curl
curl $APP_DATA.azurewebsites.net
Deploy frontend
# Create
az webapp create --plan appPlan -n $APP_FRONT -g $group \
--deployment-container-image-name \
$ACR_NAME.azurecr.io/smilr/frontend \
--docker-registry-server-user $DOCKER_USER \
--docker-registry-server-password $DOCKER_PASS
# App settings
az webapp config appsettings set -g $group -n $APP_FRONT \
--settings \
API_ENDPOINT=https://$APP_DATA.azurewebsites.net/api
# browser
open https://$APP_FRONT.azurewebsites.net
Sum up
- We can host multiple apps on one app plan
- App plan shares CPU and RAM across all running instances.
- Putting it in private VLAN is very expensive - it is called Application Service Environment
- You don't have to think about security updates and patches.
- Scaling up&down is rather minutes not seconds.
- It supports Windows hosting without virtual machine.
Hosting advanced
Azure Kubernetes Service
Create
with Azure CLI
- 10-15 minutes
- machine size is important
az aks create \
-g $group -n $AKS_NAME \
--node-vm-size Standard_DS2_v2 \
--node-count 2 \
--generate-ssh-keys
# Attach ACR
az aks update \
-n $AKS_NAME \
-g $group \
--attach-acr $ACR_NAME
Get kubectl credentials
- use it as any other Kubernetes cluster
# Get kubectl credentials
az aks get-credentials \
-n $AKS_NAME \
-g $group --admin
Demo app
K8s deploy
- envsubst is a nice util to substitute env variables in text files
- rest is normal k8s deployment
# deploy ingress
k apply -f ingress/ingress.yaml
k apply -f ingress/ingress-ip.yaml
# deploy data api
envsubst < data-api.yaml | \
kubectl apply -f -
# deploy frontend
envsubst < frontend.yaml | \
kubectl apply -f -
# deploy ingress rules
k apply -f ingress-rules.yaml
AKS - sum up
- Magic of K8s: write one - use everywhere
- Windows nodes are supported as GA
- Good (not great just good) integration with other Azure services
- Pricing similar to GKE or EKS
- Logs can be rather expensive, so be careful
Making it secure
Normal way
- Use DNS Zone
- Use Let's Encrypt
- Attach public IP to DNS
- Install cert-manager
- ...
Let's hack a bit
- Use Cloudflare
- Fill only IP address (can be done with code)
Queue
Options
- Azure Service Bus
- Azure Event Hub
- Azure Event Grid
Service | Purpose | Type | When to use |
---|---|---|---|
Event Grid | Reactive programming | Event distribution (discrete) | React to status changes |
Event Hubs | Big data pipeline | Event streaming (series) | Telemetry and distributed data streaming |
Service Bus | High-value enterprise messaging | Message | Order processing and financial transactions |
What? When? Why?
What about RabbitMQ?
AMPQ 1.0 protocol is supported by:
- Azure Service Bus Messaging
- Azure Event Hubs
What about Kafka?
- Azure Event Hubs for Apache Kafka
- Use Kafka Connect or MirrorMaker to talk to Event Hubs without changing a line of code
The end?
Not yet :)
Poznaj Azure
"Poznaj Azure" next project:
- Design system for motorway toll
- All cars in Poland
- No "funny" device in the car
- HA for data
- Money & money & money
- Only in Polish
- + All "emails" from previous project
Q&A
MicroservicesOnAzure - v3
By Piotr Stapp
MicroservicesOnAzure - v3
- 91