diff --git a/README.md b/README.md index 6b75ff7c9..4637f13ce 100644 --- a/README.md +++ b/README.md @@ -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. >
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. ->
->
+
+![image](https://user-images.githubusercontent.com/1712635/40397331-059a7ec6-5de7-11e8-8542-a597eca16fef.png)
+
> Read the planned Roadmap and Milestones for future releases of eShopOnContainers within the Wiki for further info about possible new implementations and provide feedback at the ISSUES section if you'd like to see any specific scenario implemented or improved. Also, feel free to discuss on any current issue.
### Architecture overview
diff --git a/build/acr-build/queue-all.ps1 b/build/acr-build/queue-all.ps1
new file mode 100644
index 000000000..aacffea95
--- /dev/null
+++ b/build/acr-build/queue-all.ps1
@@ -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
diff --git a/docker-compose.override.yml b/docker-compose.override.yml
index f55cf5025..d523b328a 100644
--- a/docker-compose.override.yml
+++ b/docker-compose.override.yml
@@ -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:
diff --git a/docker-compose.yml b/docker-compose.yml
index 8deef97c0..414d9a1ef 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -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:
diff --git a/k8s/README.k8s.md b/k8s/README.k8s.md
index 77acdf236..62841aba1 100644
--- a/k8s/README.k8s.md
+++ b/k8s/README.k8s.md
@@ -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`.
diff --git a/k8s/build-push-images.ps1 b/k8s/build-push-images.ps1
new file mode 100644
index 000000000..e2c8e06b6
--- /dev/null
+++ b/k8s/build-push-images.ps1
@@ -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
+ }
+}
+
+
+
+
+
diff --git a/k8s/conf_cloud.yml b/k8s/conf_cloud.yaml
similarity index 100%
rename from k8s/conf_cloud.yml
rename to k8s/conf_cloud.yaml
diff --git a/k8s/conf_local.yml b/k8s/conf_local.yaml
similarity index 100%
rename from k8s/conf_local.yml
rename to k8s/conf_local.yaml
diff --git a/k8s/deploy.ps1 b/k8s/deploy.ps1
index 443edb4a1..f0905096a 100644
--- a/k8s/deploy.ps1
+++ b/k8s/deploy.ps1
@@ -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 `
diff --git a/k8s/deployments.yaml b/k8s/deployments.yaml
index ca97df9eb..f362c319c 100644
--- a/k8s/deployments.yaml
+++ b/k8s/deployments.yaml
@@ -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:
diff --git a/k8s/gen-k8s-env-aks.ps1 b/k8s/gen-k8s-env-aks.ps1
index ef36a390d..727a9ca53 100644
--- a/k8s/gen-k8s-env-aks.ps1
+++ b/k8s/gen-k8s-env-aks.ps1
@@ -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
}
diff --git a/k8s/internalurls.yaml b/k8s/internalurls.yaml
index e42ef23ec..df317b5d5 100644
--- a/k8s/internalurls.yaml
+++ b/k8s/internalurls.yaml
@@ -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
diff --git a/k8s/services.yaml b/k8s/services.yaml
index 035f1c798..ad537eaf0 100644
--- a/k8s/services.yaml
+++ b/k8s/services.yaml
@@ -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
diff --git a/src/ApiGateways/ApiGw-Base/Program.cs b/src/ApiGateways/ApiGw-Base/Program.cs
index 782681901..effd5684e 100644
--- a/src/ApiGateways/ApiGw-Base/Program.cs
+++ b/src/ApiGateways/ApiGw-Base/Program.cs
@@ -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