Browse Source

Merge pull request #26 from dotnet-architecture/dev

upd fork
pull/1934/head
Taras Kovalenko 6 years ago
committed by GitHub
parent
commit
2059d9c2c7
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 151 additions and 50 deletions
  1. +3
    -2
      README.md
  2. +37
    -0
      build/acr-build/queue-all.ps1
  3. +1
    -18
      docker-compose.override.yml
  4. +0
    -8
      docker-compose.yml
  5. +11
    -4
      k8s/README.k8s.md
  6. +72
    -0
      k8s/build-push-images.ps1
  7. +0
    -0
      k8s/conf_cloud.yaml
  8. +0
    -0
      k8s/conf_local.yaml
  9. +7
    -1
      k8s/deploy.ps1
  10. +5
    -0
      k8s/deployments.yaml
  11. +8
    -5
      k8s/gen-k8s-env-aks.ps1
  12. +2
    -0
      k8s/internalurls.yaml
  13. +2
    -2
      k8s/services.yaml
  14. +2
    -2
      src/ApiGateways/ApiGw-Base/Program.cs
  15. +0
    -7
      src/Services/Ordering/Ordering.SignalrHub/Startup.cs
  16. +1
    -1
      src/Web/WebSPA/package.json

+ 3
- 2
README.md View File

@ -25,8 +25,9 @@ For a list on the new .NET Core 2.0 related implemented features, see this [blog
However, this sample application should not be considered as an "eCommerce reference model", at all. The implemented business domain might not be ideal from an eCommerce business point of view. It is neither trying to solve all the problems in a large, scalable and mission-critical distributed system. It is just a bootstrap for developers to easily get started in the world of Docker containers and microservices with .NET Core.
> <p>For example, the next step after running the solution in the local dev PC and understanding Docker containers and microservices development with .NET Core, is to select a microservice cluster/orchestrator like Kubernetes in Azure (AKS) or Azure Service Fabric, both environments tested and supported by this solution.
> Additional steps would be to move your databases to HA cloud services (like Azure SQL Database), or switch your EventBus to use Azure Service Bus (instead of bare-bone RabbitMQ) or any other production ready Service Bus in the market.
> <p>
> <img src="img/exploring-to-production-ready.png">
![image](https://user-images.githubusercontent.com/1712635/40397331-059a7ec6-5de7-11e8-8542-a597eca16fef.png)
> Read the planned <a href='https://github.com/dotnet/eShopOnContainers/wiki/01.-Roadmap-and-Milestones-for-future-releases'>Roadmap and Milestones for future releases of eShopOnContainers</a> within the Wiki for further info about possible new implementations and provide feedback at the <a href='https://github.com/dotnet/eShopOnContainers/issues'>ISSUES section</a> if you'd like to see any specific scenario implemented or improved. Also, feel free to discuss on any current issue.
### Architecture overview


+ 37
- 0
build/acr-build/queue-all.ps1 View File

@ -0,0 +1,37 @@
Param(
[parameter(Mandatory=$false)][string]$acrName,
[parameter(Mandatory=$false)][string]$gitUser,
[parameter(Mandatory=$false)][string]$repoName="eShopOnContainers",
[parameter(Mandatory=$false)][string]$gitBranch="dev",
[parameter(Mandatory=$true)][string]$patToken
)
$gitContext = "https://github.com/$gitUser/$repoName"
$services = @(
@{ Name="eshopbasket"; Image="eshop/basket.api"; File="src/Services/Basket/Basket.API/Dockerfile" },
@{ Name="eshopcatalog"; Image="eshop/catalog.api"; File="src/Services/Catalog/Catalog.API/Dockerfile" },
@{ Name="eshopidentity"; Image="eshop/identity.api"; File="src/Services/Identity/Identity.API/Dockerfile" },
@{ Name="eshopordering"; Image="eshop/ordering.api"; File="src/Services/Ordering/Ordering.API/Dockerfile" },
@{ Name="eshoporderingbg"; Image="eshop/ordering.backgroundtasks"; File="src/Services/Ordering/Ordering.BackgroundTasks/Dockerfile" },
@{ Name="eshopmarketing"; Image="eshop/marketing.api"; File="src/Services/Marketing/Marketing.API/Dockerfile" },
@{ Name="eshopwebspa"; Image="eshop/webspa"; File="src/Web/WebSPA/Dockerfile" },
@{ Name="eshopwebmvc"; Image="eshop/webmvc"; File="src/Web/WebMVC/Dockerfile" },
@{ Name="eshopwebstatus"; Image="eshop/webstatus"; File="src/Web/WebStatus/Dockerfile" },
@{ Name="eshoppayment"; Image="eshop/payment.api"; File="src/Services/Payment/Payment.API/Dockerfile" },
@{ Name="eshoplocations"; Image="eshop/locations.api"; File="src/Services/Location/Locations.API/Dockerfile" },
@{ Name="eshopocelotapigw"; Image="eshop/ocelotapigw"; File="src/ApiGateways/ApiGw-Base/Dockerfile" },
@{ Name="eshopmobileshoppingagg"; Image="eshop/mobileshoppingagg"; File="src/ApiGateways/Mobile.Bff.Shopping/aggregator/Dockerfile" },
@{ Name="eshopwebshoppingagg"; Image="eshop/webshoppingagg"; File="src/ApiGateways/Web.Bff.Shopping/aggregator/Dockerfile" },
@{ Name="eshoporderingsignalrhub"; Image="eshop/ordering.signalrhub"; File="src/Services/Ordering/Ordering.SignalrHub/Dockerfile" }
)
$services |% {
$bname = $_.Name
$bimg = $_.Image
$bfile = $_.File
Write-Host "Setting ACR build $bname ($bimg)"
az acr build-task create --registry $acrName --name $bname --image ${bimg}:$gitBranch --context $gitContext --branch $gitBranch --git-access-token $patToken --file $bfile
}
# Basket.API

+ 1
- 18
docker-compose.override.yml View File

@ -224,24 +224,7 @@ services:
ports:
- "5109:80" # Important: In a production environment your should remove the external port (5109) kept here for microservice debugging purposes.
# The API Gateway redirects and access through the internal port (80).
ordering.backgroundtasks:
environment:
- ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=http://0.0.0.0:80
- ConnectionString=${ESHOP_AZURE_ORDERING_DB:-Server=sql.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word}
- EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq}
- EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME}
- EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD}
- UseCustomizationData=True
- AzureServiceBusEnabled=False
- CheckUpdateTime=30000
- GracePeriodTime=1
- ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY}
- OrchestratorType=${ORCHESTRATOR_TYPE}
- UseLoadTest=${USE_LOADTEST:-False}
ports:
- "5111:80"
sql.data:
environment:


+ 0
- 8
docker-compose.yml View File

@ -153,14 +153,6 @@ services:
context: .
dockerfile: src/ApiGateways/Web.Bff.Shopping/aggregator/Dockerfile
ordering.backgroundtasks:
image: eshop/ordering.backgroundtasks:${TAG:-latest}
build:
context: .
dockerfile: src/Services/Ordering/Ordering.BackgroundTasks/Dockerfile
depends_on:
- sql.data
- rabbitmq
ordering.signalrhub:
image: eshop/ordering.signalrhub:${TAG:-latest}
build:


+ 11
- 4
k8s/README.k8s.md View File

@ -4,16 +4,23 @@ The k8s directory contains Kubernetes configuration for the eShopOnContainers ap
## Prerequisites
* A Kubernetes cluster. Follow Azure Container Service's [walkthrough](https://docs.microsoft.com/en-us/azure/container-service/container-service-kubernetes-walkthrough) to create one.
* A private Docker registry. Follow Azure Container Registry's [guide](https://docs.microsoft.com/en-us/azure/container-registry/container-registry-get-started-portal) to create one.
* Optionally, previous steps can be skipped if you run gen-k8s-env.ps1 (or gen-k8s-env-aks.ps1 if you would like to use AKS instead of ACS) script to automatically create the azure environment needed for kubernetes deployment. Azure cli 2.0 must be previously installed [installation guide](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli). For example:
* Optionally, previous steps can be skipped if you run the **gen-k8s-env-aks.ps1** script to create an AKS cluster environment or gen-k8s-env.ps1 script to create an ACS for Kuberentes cluster environment including the creation of additional Azure environment needed like an Azure Resource Manager and ACR registry.
Azure cli 2.0 must be previously installed [installation guide](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli). For example:
**Important**: Note the parameter "-createAcr true". If you are creating the K8s cluster but you want to re-use and existing ACR, say "-createAcr false".
For AKS:
>```
>./gen-k8s-env -resourceGroupName k8sGroup -location westeurope -registryName k8sregistry -createAcr true -orchestratorName k8s-cluster -dnsName k8s-dns
>./gen-k8s-env-aks -resourceGroupName YoureShopAksResgroup -location centralus -serviceName YoureShopAksCluster -dnsNamePrefix youreshopaks -registryName YoureShopAcrRegistry -createAcr true -nodeCount 3 -nodeVMSize Standard_D2_v2
>```
or using AKS instead of ACS
For ACS:
>```
>./gen-k8s-env-aks -resourceGroupName k8sGroup -location westeurope -registryName k8sregistry -dnsName k8s-dns -serviceName k8s-cluster -createAcr true -nodeCount 3 -nodeVMSize Standard_D2_v2
>./gen-k8s-env -resourceGroupName k8sGroup -location westeurope -registryName k8sregistry -createAcr true -orchestratorName k8s-cluster -dnsName k8s-dns
>```
* A Docker development environment with `docker` and `docker-compose`.


+ 72
- 0
k8s/build-push-images.ps1 View File

@ -0,0 +1,72 @@
Param(
[parameter(Mandatory=$false)][string]$registry,
[parameter(Mandatory=$false)][string]$dockerUser,
[parameter(Mandatory=$false)][string]$dockerPassword,
[parameter(Mandatory=$false)][string]$imageTag,
[parameter(Mandatory=$false)][bool]$buildImages=$true,
[parameter(Mandatory=$false)][bool]$pushImages=$true,
[parameter(Mandatory=$false)][string]$dockerOrg="eshop"
)
# Initialization
$useDockerHub = [string]::IsNullOrEmpty($registry)
# Check required commands (only if not in CI environment)
$requiredCommands = ("docker", "docker-compose")
foreach ($command in $requiredCommands) {
if ((Get-Command $command -ErrorAction SilentlyContinue) -eq $null) {
Write-Host "$command must be on path" -ForegroundColor Red
exit
}
}
# Get tag to use from current branch if no tag is passed
if ([string]::IsNullOrEmpty($imageTag)) {
$imageTag = $(git rev-parse --abbrev-ref HEAD)
}
Write-Host "Docker image Tag: $imageTag" -ForegroundColor Yellow
# Build docker images if needed
if ($buildImages) {
Write-Host "Building Docker images tagged with '$imageTag'" -ForegroundColor Yellow
$env:TAG=$imageTag
docker-compose -p .. -f ../docker-compose.yml build
}
# Login to Docker registry
if (-not [string]::IsNullOrEmpty($dockerUser)) {
$registryFDQN = if (-not $useDockerHub) {$registry} else {"index.docker.io/v1/"}
Write-Host "Logging in to $registryFDQN as user $dockerUser" -ForegroundColor Yellow
if ($useDockerHub) {
docker login -u $dockerUser -p $dockerPassword
}
else {
docker login -u $dockerUser -p $dockerPassword $registryFDQN
}
if (-not $LastExitCode -eq 0) {
Write-Host "Login failed" -ForegroundColor Red
exit
}
}
# Push images to Docker registry
if ($pushImages) {
Write-Host "Pushing images to $registry/$dockerOrg..." -ForegroundColor Yellow
$services = ("basket.api", "catalog.api", "identity.api", "ordering.api", "ordering.backgroundtasks", "marketing.api","payment.api","locations.api", "webmvc", "webspa", "webstatus", "ocelotapigw", "mobileshoppingagg", "webshoppingagg", "ordering.signalrhub")
foreach ($service in $services) {
$imageFqdn = if ($useDockerHub) {"$dockerOrg/${service}"} else {"$registry/$dockerOrg/${service}"}
docker tag eshop/${service}:$imageTag ${imageFqdn}:$imageTag
docker push ${imageFqdn}:$imageTag
}
}

k8s/conf_cloud.yml → k8s/conf_cloud.yaml View File


k8s/conf_local.yml → k8s/conf_local.yaml View File


+ 7
- 1
k8s/deploy.ps1 View File

@ -8,6 +8,7 @@ Param(
[parameter(Mandatory=$false)][string]$imageTag,
[parameter(Mandatory=$false)][bool]$deployCI=$false,
[parameter(Mandatory=$false)][bool]$buildImages=$true,
[parameter(Mandatory=$false)][bool]$pushImages=$true,
[parameter(Mandatory=$false)][bool]$deployInfrastructure=$true,
[parameter(Mandatory=$false)][string]$dockerOrg="eshop"
)
@ -63,7 +64,9 @@ if ($buildImages) {
Write-Host "Building Docker images tagged with '$imageTag'" -ForegroundColor Yellow
$env:TAG=$imageTag
docker-compose -p .. -f ../docker-compose.yml build
}
if ($pushImages) {
Write-Host "Pushing images to $registry/$dockerOrg..." -ForegroundColor Yellow
$services = ("basket.api", "catalog.api", "identity.api", "ordering.api", "ordering.backgroundtasks", "marketing.api","payment.api","locations.api", "webmvc", "webspa", "webstatus", "ocelotapigw", "mobileshoppingagg", "webshoppingagg", "ordering.signalrhub")
@ -91,7 +94,10 @@ if (-not [string]::IsNullOrEmpty($dockerUser)) {
exit
}
# create registry key secret
# Try to delete the Docker registry key secret
ExecKube -cmd 'delete secret docker-registry registry-key'
# Create the Docker registry key secret
ExecKube -cmd 'create secret docker-registry registry-key `
--docker-server=$registryFDQN `
--docker-username=$dockerUser `


+ 5
- 0
k8s/deployments.yaml View File

@ -702,6 +702,11 @@ spec:
configMapKeyRef:
name: internalurls
key: ordering__hc
- name: OrderingBackgroundTasksUrl
valueFrom:
configMapKeyRef:
name: internalurls
key: ordering-background__hc
- name: LocationsUrl
valueFrom:
configMapKeyRef:


+ 8
- 5
k8s/gen-k8s-env-aks.ps1 View File

@ -1,15 +1,16 @@
Param(
[parameter(Mandatory=$true)][string]$resourceGroupName,
[parameter(Mandatory=$true)][string]$location,
[parameter(Mandatory=$false)][string]$registryName,
[parameter(Mandatory=$true)][string]$serviceName,
[parameter(Mandatory=$true)][string]$dnsNamePrefix,
[parameter(Mandatory=$false)][string]$registryName,
[parameter(Mandatory=$true)][string]$createAcr=$true,
[parameter(Mandatory=$false)][int]$nodeCount=3,
[parameter(Mandatory=$false)][string]$nodeVMSize="Standard_D2_v2"
)
# Create resource group
Write-Host "Creating resource group..." -ForegroundColor Yellow
Write-Host "Creating Azure Resource Group..." -ForegroundColor Yellow
az group create --name=$resourceGroupName --location=$location
if ($createAcr -eq $true) {
@ -18,14 +19,16 @@ if ($createAcr -eq $true) {
az acr create -n $registryName -g $resourceGroupName -l $location --admin-enabled true --sku Basic
}
# Create kubernetes orchestrator
Write-Host "Creating kubernetes orchestrator..." -ForegroundColor Yellow
az aks create --resource-group=$resourceGroupName --name=$serviceName --generate-ssh-keys --node-count=$nodeCount --node-vm-size=$nodeVMSize
# Create kubernetes cluster in AKS
Write-Host "Creating Kubernetes cluster in AKS..." -ForegroundColor Yellow
az aks create --resource-group=$resourceGroupName --name=$serviceName --dns-name-prefix=$dnsNamePrefix --generate-ssh-keys --node-count=$nodeCount --node-vm-size=$nodeVMSize
# Retrieve kubernetes cluster configuration and save it under ~/.kube/config
Write-Host "Getting Kubernetes config..." -ForegroundColor Yellow
az aks get-credentials --resource-group=$resourceGroupName --name=$serviceName
if ($createAcr -eq $true) {
# Show ACR credentials
Write-Host "ACR credentials" -ForegroundColor Yellow
az acr credential show -n $registryName
}

+ 2
- 0
k8s/internalurls.yaml View File

@ -14,6 +14,8 @@ data:
identity__hc: http://identity/hc
ordering: http://ordering
ordering__hc: http://ordering/hc
ordering-background: http://ordering-background
ordering-background__hc: http://ordering-background/hc
marketing: http://marketing
marketing__hc: http://marketing/hc
locations: http://locations


+ 2
- 2
k8s/services.yaml View File

@ -59,14 +59,14 @@ kind: Service
metadata:
labels:
app: eshop
component: ordering-background
component: ordering-backgroundtasks
name: ordering-background
spec:
ports:
- port: 80
selector:
app: eshop
component: ordering-background
component: ordering-backgroundtasks
---
apiVersion: v1
kind: Service


+ 2
- 2
src/ApiGateways/ApiGw-Base/Program.cs View File

@ -20,11 +20,11 @@ namespace OcelotApiGw
public static IWebHost BuildWebHost(string[] args)
{
var builder = WebHost.CreateDefaultBuilder(args);
IWebHostBuilder builder = WebHost.CreateDefaultBuilder(args);
builder.ConfigureServices(s => s.AddSingleton(builder))
.ConfigureAppConfiguration(ic => ic.AddJsonFile(Path.Combine("configuration", "configuration.json")))
.UseStartup<Startup>();
var host = builder.Build();
IWebHost host = builder.Build();
return host;
}
}


+ 0
- 7
src/Services/Ordering/Ordering.SignalrHub/Startup.cs View File

@ -46,13 +46,6 @@ namespace Ordering.SignalrHub
services
.AddSignalR()
.AddRedis(Configuration["SignalrStoreConnectionString"]);
//services
// .AddSignalR()
// .AddRedis(options => options.Factory = writer =>
// {
// return ConnectionMultiplexer.Connect(Configuration["SignalrStoreConnectionString"], writer);
// });
}
else
{


+ 1
- 1
src/Web/WebSPA/package.json View File

@ -36,7 +36,7 @@
"@angular/platform-browser": "^4.0.0",
"@angular/platform-browser-dynamic": "^4.0.0",
"@angular/router": "^4.0.0",
"@aspnet/signalr": "^1.0.0-preview2-final",
"@aspnet/signalr": "1.0.0-preview2-final",
"@ng-bootstrap/ng-bootstrap": "1.0.0-alpha.22",
"bootstrap": "4.0.0-alpha.5",
"core-js": "^2.4.1",


Loading…
Cancel
Save