@ -0,0 +1,27 @@ | |||
parameters: | |||
image: '' | |||
branch: '' | |||
registryEndpoint: '' | |||
jobs: | |||
- job: manifest | |||
pool: | |||
vmImage: 'Ubuntu 16.04' | |||
steps: | |||
- task: Docker@1 | |||
displayName: Docker Login | |||
inputs: | |||
command: login | |||
containerregistrytype: 'Container Registry' | |||
dockerRegistryEndpoint: ${{ parameters.registryEndpoint }} | |||
- bash: | | |||
mkdir -p ~/.docker | |||
echo '{ "experimental": "enabled" }' > ~/.docker/config.json | |||
docker --config ~/.docker manifest create eshop/${{ parameters.image }}:${{ parameters.branch }} eshop/${{ parameters.image }}:linux-${{ parameters.branch }} eshop/${{ parameters.image }}:win-${{ parameters.branch }} | |||
docker --config ~/.docker manifest create eshop/${{ parameters.image }}:latest eshop/${{ parameters.image }}:linux-latest eshop/${{ parameters.image }}:win-latest | |||
docker --config ~/.docker push eshop/${{ parameters.image }}:${{ parameters.branch }} | |||
docker --config ~/.docker push eshop/${{ parameters.image }}:latest | |||
displayName: 'Create Manifest' | |||
dependsOn: | |||
- BuildWindows | |||
- BuildLinux |
@ -0,0 +1,26 @@ | |||
Param( | |||
[parameter(Mandatory=$true)][string]$registry | |||
) | |||
if ([String]::IsNullOrEmpty($registry)) { | |||
Write-Host "Registry must be set to docker registry to use" -ForegroundColor Red | |||
exit 1 | |||
} | |||
Write-Host "This script creates the local manifests, for pushing the multi-arch manifests" -ForegroundColor Yellow | |||
Write-Host "Tags used are linux-master, win-master, linux-dev, win-dev, linux-latest, win-latest" -ForegroundColor Yellow | |||
Write-Host "Multiarch images tags will be master, dev, latest" -ForegroundColor Yellow | |||
$services = "identity.api", "basket.api", "catalog.api", "ordering.api", "ordering.backgroundtasks", "marketing.api", "payment.api", "locations.api", "webhooks.api", "ocelotapigw", "mobileshoppingagg", "webshoppingagg", "ordering.signalrhub", "webstatus", "webspa", "webmvc", "webhooks.client" | |||
foreach ($svc in $services) { | |||
Write-Host "Creating manifest for $svc and tags :latest, :master, and :dev" | |||
docker manifest create $registry/${svc}:master $registry/${svc}:linux-master $registry/${svc}:win-master | |||
docker manifest create $registry/${svc}:dev $registry/${svc}:linux-dev $registry/${svc}:win-dev | |||
docker manifest create $registry/${svc}:latest $registry/${svc}:linux-latest $registry/${svc}:win-latest | |||
Write-Host "Pushing manifest for $svc and tags :latest, :master, and :dev" | |||
docker manifest push $registry/${svc}:latest | |||
docker manifest push $registry/${svc}:dev | |||
docker manifest push $registry/${svc}:master | |||
} |
@ -0,0 +1,2 @@ | |||
#Requires -RunAsAdministrator | |||
Get-NetConnectionProfile | Where-Object { $_.InterfaceAlias -match "(DockerNAT)" } | ForEach-Object { Set-NetConnectionProfile -InterfaceIndex $_.InterfaceIndex -NetworkCategory Private } |
@ -0,0 +1,37 @@ | |||
version: '3.4' | |||
services: | |||
elasticsearch: | |||
build: | |||
context: elk/elasticsearch/ | |||
volumes: | |||
- ./elk/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml:ro | |||
ports: | |||
- "9200:9200" | |||
- "9300:9300" | |||
environment: | |||
ES_JAVA_OPTS: "-Xmx256m -Xms256m" | |||
logstash: | |||
build: | |||
context: elk/logstash/ | |||
volumes: | |||
- ./elk/logstash/config/logstash.yml:/usr/share/logstash/config/logstash.yml:ro | |||
- ./elk/logstash/pipeline:/usr/share/logstash/pipeline:ro | |||
ports: | |||
- "8080:8080" | |||
environment: | |||
LS_JAVA_OPTS: "-Xmx256m -Xms256m" | |||
depends_on: | |||
- elasticsearch | |||
kibana: | |||
build: | |||
context: elk/kibana/ | |||
volumes: | |||
- ./elk/kibana/config/:/usr/share/kibana/config:ro | |||
ports: | |||
- "5601:5601" | |||
depends_on: | |||
- elasticsearch |
@ -1,8 +0,0 @@ | |||
#!/bin/sh | |||
export NODE_DOWNLOAD_SHA 0e20787e2eda4cc31336d8327556ebc7417e8ee0a6ba0de96a09b0ec2b841f60 | |||
curl -SL "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.gz" --output nodejs.tar.gz \ | |||
&& echo "$NODE_DOWNLOAD_SHA nodejs.tar.gz" | sha256sum -c - \ | |||
&& tar -xzf "nodejs.tar.gz" -C /usr/local --strip-components=1 \ | |||
&& rm nodejs.tar.gz \ | |||
&& ln -s /usr/local/bin/node /usr/local/bin/nodejs |
@ -1,4 +0,0 @@ | |||
set NODE_VERSION=8.11.1 | |||
curl -SL "https://nodejs.org/dist/v%NODE_VERSION%/node-v%NODE_VERSION%-win-x64.zip" --output nodejs.zip | |||
tar -xf nodejs.zip -C c:\ | |||
setx PATH "%PATH%;c:\node-v%NODE_VERSION%-win-x64" |
@ -0,0 +1,88 @@ | |||
This article contains a brief introduction to centralized structured logging with [Serilog](https://serilog.net/) and event viewing with [ELK](https://www.elastic.co/elk-stack) in eShopOnContainers. ELK is an acronym of ElasticSearch, LogStash and Kibana. This is one of the most used tools in the industry standards. | |||
![](img/elk/kibana-working.png) | |||
## Wiring eshopOnContainers with ELK in Localhost | |||
eshopOnContainers is ready for work with ELK, you only need to setup the configuration parameter **LogstashUrl**, in **Serilog** Section, for achieve this, you can do it modifing this parameter in every appsettings.json of every service, or via Environment Variable **Serilog:LogstashUrl**. | |||
There is another option, a zero-configuration environment for testing the integration launching via ```docker-compose``` command, on the root directory of eshopOnContainers: | |||
```sh | |||
docker-compose -f docker-compose.yml -f docker-compose.override.yml -f docker-compose.elk.yml build | |||
docker-compose -f docker-compose.yml -f docker-compose.override.yml -f docker-compose.elk.yml up | |||
``` | |||
### Configuring Logstash index on Kibana | |||
Once time you have started and configured your application, you only need to configure the logstash index on kibana. | |||
You can address to Kibana, with docker-compose setup is at [http://localhost:5601](http://localhost:5601) | |||
If you have accessed to kibana too early, you can see this error. It's normal, depending of your machine the kibana stack needs a bit of time to startup. | |||
![](img/elk/kibana_startup.png) | |||
You can wait a bit and refresh the page, the first time you enter, you need to configure and index pattern, in the ```docker-compose``` configuration, the index pattern name is **eshops-\***. | |||
![](img/elk/kibana_eshops_index.png) | |||
With the index pattern configured, you can enter in the discover section and start viewing how the tool is recollecting the logging information. | |||
![](img/elk/kibana_result.png) | |||
## Configuring ELK on Azure VM | |||
Another option is to use a preconfigured virtual machine with Logstash, ElasticSearch and Kibana and point the configuration parameter **LogstashUrl**. For doing this you can address to Microsoft Azure, and start searching a Certified ELK Virtual Machine | |||
![](img/elk/create-vm-elk-azure.png) | |||
This options it have a certified preconfigured options (Network, VirtualMachine type, OS, RAM, Disks) for having a good starting point of ELK with good performance. | |||
![](img/elk/create-vm-elk-azure-summary.png) | |||
When you have configured the main aspects of your virtual machine, you will have a "review & create" last step like this: | |||
![](img/elk/create-vm-elk-azure-last-step.png) | |||
### Configuring the bitnami environment | |||
This virtual machine has a lot of configuration pipeing done. If you want to change something of the default configuration you can address this documentation: | |||
[https://docs.bitnami.com/virtual-machine/apps/elk/get-started/](https://docs.bitnami.com/virtual-machine/apps/elk/get-started/) | |||
The only thing you have to change is the logstash configuration inside the machine. This configuration is at the file ```/opt/bitnami/logstash/conf/logstash.conf``` | |||
You must edit the file and overwrite with this configuration: | |||
```conf | |||
input { | |||
http { | |||
#default host 0.0.0.0:8080 | |||
codec => json | |||
} | |||
} | |||
## Add your filters / logstash plugins configuration here | |||
filter { | |||
split { | |||
field => "events" | |||
target => "e" | |||
remove_field => "events" | |||
} | |||
} | |||
output { | |||
elasticsearch { | |||
hosts => "elasticsearch:9200" | |||
index=>"eshops-%{+xxxx.ww}" | |||
} | |||
} | |||
``` | |||
For doing this you can connect via ssh to the vm and edit the file using the vi editor for example. | |||
When the file will be edited, check there are Inbound Port Rules created for the logstash service. You can do it going to Networking Menu on your ELK Virtual Machine Resource in Azure. | |||
![](img/elk/azure-nsg-inboundportsConfig.png) | |||
The only thing that remains is to connect to your vm vía browser. And check the bitnami splash page is showing. | |||
![](img/elk/bitnami_splash.png) | |||
You can get the password for accessing going to your virtual machine in azure and check the boot diagnostics, theres a message that shows to you which is your password. | |||
When you have the user and password you can access to the kibana tool, and create the ```eshops-*``` index pattern that is well documented at the beggining of this documentation and then start to discover. | |||
![](img/elk/) |
@ -0,0 +1,5 @@ | |||
# https://github.com/elastic/elasticsearch-docker | |||
FROM docker.elastic.co/elasticsearch/elasticsearch-oss:6.0.0 | |||
# Add your elasticsearch plugins setup here | |||
# Example: RUN elasticsearch-plugin install analysis-icu |
@ -0,0 +1,16 @@ | |||
--- | |||
## Default Elasticsearch configuration from elasticsearch-docker. | |||
## from https://github.com/elastic/elasticsearch-docker/blob/master/build/elasticsearch/elasticsearch.yml | |||
# | |||
cluster.name: "docker-cluster" | |||
network.host: 0.0.0.0 | |||
# minimum_master_nodes need to be explicitly set when bound on a public IP | |||
# set to 1 to allow single node clusters | |||
# Details: https://github.com/elastic/elasticsearch/pull/17288 | |||
discovery.zen.minimum_master_nodes: 1 | |||
## Use single node discovery in order to disable production mode and avoid bootstrap checks | |||
## see https://www.elastic.co/guide/en/elasticsearch/reference/current/bootstrap-checks.html | |||
# | |||
discovery.type: single-node |
@ -0,0 +1,5 @@ | |||
# https://github.com/elastic/kibana-docker | |||
FROM docker.elastic.co/kibana/kibana-oss:6.0.0 | |||
# Add your kibana plugins setup here | |||
# Example: RUN kibana-plugin install <name|url> |
@ -0,0 +1,7 @@ | |||
--- | |||
## Default Kibana configuration from kibana-docker. | |||
## from https://github.com/elastic/kibana-docker/blob/master/build/kibana/config/kibana.yml | |||
# | |||
server.name: kibana | |||
server.host: "0" | |||
elasticsearch.url: http://elasticsearch:9200 |
@ -0,0 +1,6 @@ | |||
# https://github.com/elastic/logstash-docker | |||
FROM docker.elastic.co/logstash/logstash-oss:6.0.0 | |||
# Add your logstash plugins setup here | |||
# Example: RUN logstash-plugin install logstash-filter-json | |||
RUN logstash-plugin install logstash-input-http |
@ -0,0 +1,6 @@ | |||
--- | |||
## Default Logstash configuration from logstash-docker. | |||
## from https://github.com/elastic/logstash-docker/blob/master/build/logstash/config/logstash-oss.yml | |||
# | |||
http.host: "0.0.0.0" | |||
path.config: /usr/share/logstash/pipeline |
@ -0,0 +1,22 @@ | |||
input { | |||
http { | |||
#default host 0.0.0.0:8080 | |||
codec => json | |||
} | |||
} | |||
## Add your filters / logstash plugins configuration here | |||
filter { | |||
split { | |||
field => "events" | |||
target => "e" | |||
remove_field => "events" | |||
} | |||
} | |||
output { | |||
elasticsearch { | |||
hosts => "elasticsearch:9200" | |||
index=>"eshops-%{+xxxx.ww}" | |||
} | |||
} |
@ -0,0 +1,37 @@ | |||
{{- if .Values.ingress.enabled -}} | |||
{{- $ingressPath := include "pathBase" . -}} | |||
{{- $serviceName := .Values.app.svc.basket -}} | |||
apiVersion: extensions/v1beta1 | |||
kind: Ingress | |||
metadata: | |||
name: {{ template "basket-api.fullname" . }} | |||
labels: | |||
app: {{ template "basket-api.name" . }} | |||
chart: {{ template "basket-api.chart" . }} | |||
release: {{ .Release.Name }} | |||
heritage: {{ .Release.Service }} | |||
{{- with .Values.ingress.annotations }} | |||
annotations: | |||
{{ toYaml . | indent 4 }} | |||
{{- end }} | |||
spec: | |||
{{- if .Values.ingress.tls }} | |||
tls: | |||
{{- range .Values.ingress.tls }} | |||
- hosts: | |||
- {{ .Values.inf.k8s.dns }} | |||
secretName: {{ .secretName }} | |||
{{- end }} | |||
{{- end }} | |||
rules: | |||
{{- range .Values.ingress.hosts }} | |||
- host: {{ . }} | |||
http: | |||
paths: | |||
- path: {{ $ingressPath }} | |||
backend: | |||
serviceName: {{ $serviceName }} | |||
servicePort: http | |||
{{- end }} | |||
{{- end }} |
@ -0,0 +1,37 @@ | |||
{{- if .Values.ingress.enabled -}} | |||
{{- $ingressPath := include "pathBase" . -}} | |||
{{- $serviceName := .Values.app.svc.catalog -}} | |||
apiVersion: extensions/v1beta1 | |||
kind: Ingress | |||
metadata: | |||
name: {{ template "catalog-api.fullname" . }} | |||
labels: | |||
app: {{ template "catalog-api.name" . }} | |||
chart: {{ template "catalog-api.chart" . }} | |||
release: {{ .Release.Name }} | |||
heritage: {{ .Release.Service }} | |||
{{- with .Values.ingress.annotations }} | |||
annotations: | |||
{{ toYaml . | indent 4 }} | |||
{{- end }} | |||
spec: | |||
{{- if .Values.ingress.tls }} | |||
tls: | |||
{{- range .Values.ingress.tls }} | |||
- hosts: | |||
- {{ .Values.inf.k8s.dns }} | |||
secretName: {{ .secretName }} | |||
{{- end }} | |||
{{- end }} | |||
rules: | |||
{{- range .Values.ingress.hosts }} | |||
- host: {{ . }} | |||
http: | |||
paths: | |||
- path: {{ $ingressPath }} | |||
backend: | |||
serviceName: {{ $serviceName }} | |||
servicePort: http | |||
{{- end }} | |||
{{- end }} |
@ -0,0 +1,36 @@ | |||
{{- if .Values.ingress.enabled -}} | |||
{{- $ingressPath := include "pathBase" . -}} | |||
{{- $serviceName := .Values.app.svc.locations }} | |||
apiVersion: extensions/v1beta1 | |||
kind: Ingress | |||
metadata: | |||
name: {{ template "locations-api.fullname" . }} | |||
labels: | |||
app: {{ template "locations-api.name" . }} | |||
chart: {{ template "locations-api.chart" . }} | |||
release: {{ .Release.Name }} | |||
heritage: {{ .Release.Service }} | |||
{{- with .Values.ingress.annotations }} | |||
annotations: | |||
{{ toYaml . | indent 4 }} | |||
{{- end }} | |||
spec: | |||
{{- if .Values.ingress.tls }} | |||
tls: | |||
{{- range .Values.ingress.tls }} | |||
- hosts: | |||
- {{ .Values.inf.k8s.dns }} | |||
secretName: {{ .secretName }} | |||
{{- end }} | |||
{{- end }} | |||
rules: | |||
{{- range .Values.ingress.hosts }} | |||
- host: {{ . }} | |||
http: | |||
paths: | |||
- path: {{ $ingressPath }} | |||
backend: | |||
serviceName: {{ $serviceName }} | |||
servicePort: http | |||
{{- end }} | |||
{{- end }} |
@ -0,0 +1,36 @@ | |||
{{- if .Values.ingress.enabled -}} | |||
{{- $ingressPath := include "pathBase" . -}} | |||
{{- $serviceName := .Values.app.svc.marketing }} | |||
apiVersion: extensions/v1beta1 | |||
kind: Ingress | |||
metadata: | |||
name: {{ template "marketing-api.fullname" . }} | |||
labels: | |||
app: {{ template "marketing-api.name" . }} | |||
chart: {{ template "marketing-api.chart" . }} | |||
release: {{ .Release.Name }} | |||
heritage: {{ .Release.Service }} | |||
{{- with .Values.ingress.annotations }} | |||
annotations: | |||
{{ toYaml . | indent 4 }} | |||
{{- end }} | |||
spec: | |||
{{- if .Values.ingress.tls }} | |||
tls: | |||
{{- range .Values.ingress.tls }} | |||
- hosts: | |||
- {{ .Values.inf.k8s.dns }} | |||
secretName: {{ .secretName }} | |||
{{- end }} | |||
{{- end }} | |||
rules: | |||
{{- range .Values.ingress.hosts }} | |||
- host: {{ . }} | |||
http: | |||
paths: | |||
- path: {{ $ingressPath }} | |||
backend: | |||
serviceName: {{ $serviceName }} | |||
servicePort: http | |||
{{- end }} | |||
{{- end }} |
@ -0,0 +1,36 @@ | |||
{{- if .Values.ingress.enabled -}} | |||
{{- $ingressPath := include "pathBase" . -}} | |||
{{- $serviceName := .Values.app.svc.mobileshoppingagg }} | |||
apiVersion: extensions/v1beta1 | |||
kind: Ingress | |||
metadata: | |||
name: {{ template "mobileshoppingagg.fullname" . }} | |||
labels: | |||
app: {{ template "mobileshoppingagg.name" . }} | |||
chart: {{ template "mobileshoppingagg.chart" . }} | |||
release: {{ .Release.Name }} | |||
heritage: {{ .Release.Service }} | |||
{{- with .Values.ingress.annotations }} | |||
annotations: | |||
{{ toYaml . | indent 4 }} | |||
{{- end }} | |||
spec: | |||
{{- if .Values.ingress.tls }} | |||
tls: | |||
{{- range .Values.ingress.tls }} | |||
- hosts: | |||
- {{ .Values.inf.k8s.dns }} | |||
secretName: {{ .secretName }} | |||
{{- end }} | |||
{{- end }} | |||
rules: | |||
{{- range .Values.ingress.hosts }} | |||
- host: {{ . }} | |||
http: | |||
paths: | |||
- path: {{ $ingressPath }} | |||
backend: | |||
serviceName: {{ $serviceName }} | |||
servicePort: http | |||
{{- end }} | |||
{{- end }} |
@ -0,0 +1,36 @@ | |||
{{- if .Values.ingress.enabled -}} | |||
{{- $ingressPath := include "pathBase" . -}} | |||
{{- $serviceName := .Values.app.svc.webshoppingagg }} | |||
apiVersion: extensions/v1beta1 | |||
kind: Ingress | |||
metadata: | |||
name: {{ template "webshoppingagg.fullname" . }} | |||
labels: | |||
app: {{ template "webshoppingagg.name" . }} | |||
chart: {{ template "webshoppingagg.chart" . }} | |||
release: {{ .Release.Name }} | |||
heritage: {{ .Release.Service }} | |||
{{- with .Values.ingress.annotations }} | |||
annotations: | |||
{{ toYaml . | indent 4 }} | |||
{{- end }} | |||
spec: | |||
{{- if .Values.ingress.tls }} | |||
tls: | |||
{{- range .Values.ingress.tls }} | |||
- hosts: | |||
- {{ .Values.inf.k8s.dns }} | |||
secretName: {{ .secretName }} | |||
{{- end }} | |||
{{- end }} | |||
rules: | |||
{{- range .Values.ingress.hosts }} | |||
- host: {{ . }} | |||
http: | |||
paths: | |||
- path: {{ $ingressPath }} | |||
backend: | |||
serviceName: {{ $serviceName }} | |||
servicePort: http | |||
{{- end }} | |||
{{- end }} |
@ -0,0 +1 @@ | |||
for /R %%f in (*.csproj) do dotnet restore --no-dependencies %%f |
@ -0,0 +1 @@ | |||
echo RESTORING ALL PACKAGES...; for f in /src/csproj-files/*.csproj; do dotnet restore $f; done |
@ -0,0 +1 @@ | |||
for %%p in (csproj-files\*.csproj) do dotnet restore %%p |