xAdded solutions for getting up and running.
This commit is contained in:
Родитель
b1e4541626
Коммит
dfba1001e6
|
@ -8,19 +8,4 @@ is-parent: yes
|
||||||
|
|
||||||
Welcome to the Azure Kubernetes Challenge. In this workshop, you'll go through increasingly robust challenges that will help you master the basic and more advanced topics required to deploy your applications to Kubernetes on Azure Kubernetes Service.
|
Welcome to the Azure Kubernetes Challenge. In this workshop, you'll go through increasingly robust challenges that will help you master the basic and more advanced topics required to deploy your applications to Kubernetes on Azure Kubernetes Service.
|
||||||
|
|
||||||
The format of this workshop is a bit different. You'll notice that you won't find step-by-step instructions on how to do each task. You'll need to find out some of the steps yourself, but rest assured you'll have the hints and links to the relevant documentation in each task.
|
For most of the challenges, you won't find step-by-step instructions on how to do each task. You'll need to find out some of the steps yourself, but rest assured you'll have the hints and links to the relevant documentation in each task. For the really challenging tasks, you'll find a possible solution that you can peek at.
|
||||||
|
|
||||||
> **Hint** If you are new to Kubernetes, the following documentation can take you quickly through the basic concepts required to understand how it works <https://docs.microsoft.com/en-us/azure/aks/concepts-clusters-workloads>
|
|
||||||
|
|
||||||
We kindly ask you not to share this content outside of the challenge so as not to give it away for future participants :)
|
|
||||||
|
|
||||||
Enjoy and have fun!
|
|
||||||
|
|
||||||
{% collapsible %}
|
|
||||||
This is hidden
|
|
||||||
|
|
||||||
```
|
|
||||||
This is hidden code
|
|
||||||
```
|
|
||||||
|
|
||||||
{% endcollapsible %}
|
|
|
@ -1,69 +0,0 @@
|
||||||
---
|
|
||||||
|
|
||||||
sectionclass: h2
|
|
||||||
title: Application Overview
|
|
||||||
parent-id: intro
|
|
||||||
---
|
|
||||||
|
|
||||||
You will be deploying a customer-facing order placement and fulfilment application that is containerised and is architected for a microservice implementation.
|
|
||||||
|
|
||||||
![Application diagram](media/overview.png)
|
|
||||||
|
|
||||||
The application consists of 5 components, namely:
|
|
||||||
|
|
||||||
* A public facing Order Capture swagger enabled API
|
|
||||||
* A messaging queue to provide reliable message delivery
|
|
||||||
* An event listener that picks up events from the messaging queue and brokers requests to a 'legacy application'
|
|
||||||
* An internal Order Fulfill legacy API.
|
|
||||||
* A MongoDB database
|
|
||||||
|
|
||||||
> **Hint:** The Order Capture API and the Fulfill Order API both expose the following endpoint for health-checks: `http://[PublicEndpoint]:[port]/healthz`
|
|
||||||
|
|
||||||
In the table below, you will find the Docker container images provided by the development team on Docker Hub as well as their corresponding source code on GitHub.
|
|
||||||
|
|
||||||
### Container images and source code
|
|
||||||
|
|
||||||
| Component | Docker Image | Source Code | Build Status |
|
|
||||||
|------------------------------|------------------------------------------------------------------|-------------------------------------------------------------------|--------------|
|
|
||||||
| Order Capture API | [azch/captureorder](https://hub.docker.com/r/azch/captureorder/) | [source-code](https://github.com/Azure/azch-captureorder) | [![Build Status](https://dev.azure.com/theazurechallenge/Kubernetes/_apis/build/status/Code/Azure.azch-captureorder)](https://dev.azure.com/theazurechallenge/Kubernetes/_build/latest?definitionId=10) |
|
|
||||||
| Order Fulfillment API | [azch/fulfillorder](https://hub.docker.com/r/azch/fulfillorder/) | [source-code](https://github.com/Azure/azch-fulfillorder) | [![Build Status](https://dev.azure.com/theazurechallenge/Kubernetes/_apis/build/status/Code/Azure.azch-fulfillorder)](https://dev.azure.com/theazurechallenge/Kubernetes/_build/latest?definitionId=11) |
|
|
||||||
| Event Listener | [azch/sblistener](https://hub.docker.com/r/azch/sblistener/) | [source-code](https://github.com/Azure/azch-sblistener) | [![Build Status](https://dev.azure.com/theazurechallenge/Kubernetes/_apis/build/status/Code/Azure.azch-sblistener)](https://dev.azure.com/theazurechallenge/Kubernetes/_build/latest?definitionId=15) |
|
|
||||||
|
|
||||||
### Environment variables
|
|
||||||
|
|
||||||
Each container image requires certain environment variables to properly run and track your progress.
|
|
||||||
|
|
||||||
Make sure you set those environment variables.
|
|
||||||
|
|
||||||
* **All Containers**
|
|
||||||
* `TEAMNAME="[YourTeamName]"`
|
|
||||||
* Track your team's progress. Use your assigned team name
|
|
||||||
* `CHALLENGEAPPINSIGHTS_KEY="[AsSpecifiedAtTheEvent]"`
|
|
||||||
* Application Insights key provided by proctors
|
|
||||||
* `APPINSIGHTS_KEY="[YourOwnKey]"`
|
|
||||||
* Your own Application Insights key, if you want to track application metrics
|
|
||||||
* **Order Capture API**
|
|
||||||
* `MONGOHOST="<hostname of mongodb>"`
|
|
||||||
* MongoDB hostname.
|
|
||||||
* `MONGOUSER="<mongodb username>"`
|
|
||||||
* MongoDB username.
|
|
||||||
* `MONGOPASSWORD="<mongodb password>"`
|
|
||||||
* MongoDB password.
|
|
||||||
* `AMQPURL="amqps://[policy name]:[policy key]@[youreventhub].servicebus.windows.net/[queuename]`"
|
|
||||||
* Azure Service Bus Queue connection endpoint.
|
|
||||||
* **Make sure your policy key is URL Encoded. Use a tool like: <https://www.url-encode-decode.com/>**
|
|
||||||
* **Order Fulfillment API**
|
|
||||||
* `MONGOHOST="<hostname of mongodb>"`
|
|
||||||
* MongoDB hostname.
|
|
||||||
* `MONGOUSER="<mongodb username>"`
|
|
||||||
* MongoDB username.
|
|
||||||
* `MONGOPASSWORD="<mongodb password>"`
|
|
||||||
* MongoDB password.
|
|
||||||
* **Event Listener**
|
|
||||||
* `SERVICEBUSCONNECTIONSTRING="Endpoint=sb://[yourservicebus].servicebus.windows.net/;SharedAccessKeyName=[keyname];SharedAccessKey=[key]"`
|
|
||||||
* Azure Service Bus namespace connection endpoint.
|
|
||||||
* **Make sure your policy key is URL Encoded. Use a tool like: <https://www.url-encode-decode.com/>**
|
|
||||||
* `SERVICEBUSQUEUENAME="[YourServiceBusQueueName]"`
|
|
||||||
* Azure Service Bus queue name
|
|
||||||
* `PROCESSENDPOINT="http://[yourfulfillordername].[namespace]:8080/v1/order"`
|
|
||||||
* Order Fulfillment API endpoint
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
sectionclass: h2
|
||||||
|
title: Kubernetes basics
|
||||||
|
parent-id: intro
|
||||||
|
---
|
||||||
|
|
||||||
|
There is an assumption of some prior knowledge of Kubernetes and its concepts. If you are new to Kubernetes, the following documentation can take you quickly through the basic concepts required to understand how it works <https://docs.microsoft.com/en-us/azure/aks/concepts-clusters-workloads>
|
|
@ -0,0 +1,15 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
sectionclass: h2
|
||||||
|
title: Application Overview
|
||||||
|
parent-id: intro
|
||||||
|
---
|
||||||
|
|
||||||
|
You will be deploying a customer-facing order placement and fulfilment application that is containerised and is architected for a microservice implementation.
|
||||||
|
|
||||||
|
![Application diagram](media/overview.png)
|
||||||
|
|
||||||
|
The application consists of 2 components:
|
||||||
|
|
||||||
|
* A public facing Order Capture swagger enabled API
|
||||||
|
* A MongoDB database
|
|
@ -1,33 +0,0 @@
|
||||||
---
|
|
||||||
sectionid: 4
|
|
||||||
sectionclass: h2
|
|
||||||
title: Challenges
|
|
||||||
parent-id: intro
|
|
||||||
---
|
|
||||||
|
|
||||||
The challenges are intended to be a challenge! Useful resources are provided to help you work through each challenge but step by step instructions are not provided. To ensure you progress at a good pace ensure workload is divided between team members where possible. This may mean anticipating work that might be required in a later challenge.
|
|
||||||
|
|
||||||
Each team is made of a Microsoft representative, a Microsoft partner representative and customer(s) members. The Microsoft/Microsoft Partners representatives were not, initially, exposed to the challenges but they come with Advanced knowledge of Azure services.
|
|
||||||
|
|
||||||
The challenge consists of core tasks plus extra advanced sections. You are expected to conclude the core component, and perform as much extra sections as you can to cumulate the highest score.
|
|
||||||
|
|
||||||
The first few sections are focused on speed and simplicity. We will leverage Azure to get up and running with Kubernetes with minimal effort. The objective is to create an end to end minimal viable product. More specifically, we will focus on:
|
|
||||||
|
|
||||||
- Deploying Kubernetes cluster as a managed service (AKS)
|
|
||||||
- Deploying the different micro-services of our application, using public Docker images and Helm charts
|
|
||||||
- Migrate some IaaS components to Azure managed services, to reduce the operational overhead
|
|
||||||
|
|
||||||
The following sections will put more attention on the operational requirements such as monitoring, security, DevOps, redundancy...
|
|
||||||
|
|
||||||
At the end of the day, each team will be given 10mn to present its work. Topics you might cover during your presentation include:
|
|
||||||
|
|
||||||
- Solution architecture
|
|
||||||
- Key learnings, mistakes, challenges
|
|
||||||
- Innovation, what makes your solution unique?
|
|
||||||
- What could you do in day 2?
|
|
||||||
|
|
||||||
The first 3 challenges, under section 2, involve getting Kubernetes and the application provisioned and **must be carried out sequentially**. After this there is flexibility as to how you proceed.
|
|
||||||
|
|
||||||
> A Microsoft/Microsoft Partner team member will arrange for you to be added to `theazurechallenge` Azure Active Directory. When logging into Azure from the Azure CLI we recommend using ```az login --tenant YOUR-SUBSCRIPTION``` where your subscription is your corporate one, to ensure you are connected to the appropriate subscription.
|
|
||||||
|
|
||||||
If you feel you need assistance at any time, please ask a proctor.
|
|
|
@ -6,18 +6,25 @@ parent-id: intro
|
||||||
|
|
||||||
To add an element of competitiveness to the challenge your solutions will be evaluated using both remote monitoring and objective assessments. At the end of the challenge we will announce a winner. You will be scored under the following areas:
|
To add an element of competitiveness to the challenge your solutions will be evaluated using both remote monitoring and objective assessments. At the end of the challenge we will announce a winner. You will be scored under the following areas:
|
||||||
|
|
||||||
### Availability (30% of the total score)
|
### Availability
|
||||||
|
|
||||||
Application uptime over period of the hack. We will be continuously making HTTP requests to your API.
|
Application uptime over period of the workshop. We will be continuously making HTTP requests to your API.
|
||||||
|
|
||||||
### Throughput (30% of the total score)
|
### Throughput
|
||||||
|
|
||||||
Ability to cope with periodic load tests, through the number of processed requests. These will be order submissions to `http://<your endpoint>:80/v1/order/`. We will be directing up to 2000 users to your application.
|
Ability to cope with periodic load tests, through the number of processed requests. These will be order submissions to `http://<your endpoint>:80/v1/order/`. We will be directing up to 2000 users to your application.
|
||||||
|
|
||||||
### Extra challenges (30% of the total score)
|
You can run Docker image below to send off a number of POST requests and get the results.
|
||||||
|
|
||||||
There will be a list of extra challenges, intermediate and advanced level. Each challenge, successfully accomplished, counts for extra bonus points.
|
```sh
|
||||||
|
export URL=http://<public ip of capture order service>/v1/order
|
||||||
|
export DURATION=1m
|
||||||
|
export CONCURRENT=300
|
||||||
|
docker run --rm -it azch/loadtest -z $DURATION -c $CONCURRENT -d '{"EmailAddress": "email@domain.com", "Product": "prod-1", "Total": 100}' -H "Content-Type: application/json" -m POST $URL
|
||||||
|
```
|
||||||
|
|
||||||
### Innovation (10% of the total score)
|
You may also use Azure DevOps to do load testing.
|
||||||
|
|
||||||
At the end of the challenge, each team will have a chance to present the work accomplished, and will be rated by the other teams. The average score will be added to the total number of points.
|
### Extra challenges
|
||||||
|
|
||||||
|
There will be a list of extra challenges, intermediate and advanced level. Each challenge, successfully accomplished, counts for extra bonus points.
|
|
@ -0,0 +1,22 @@
|
||||||
|
---
|
||||||
|
sectionid: 4
|
||||||
|
sectionclass: h2
|
||||||
|
title: Challenges
|
||||||
|
parent-id: intro
|
||||||
|
---
|
||||||
|
|
||||||
|
The challenges are intended to be a challenge! Useful resources are provided to help you work through each challenge. To ensure you progress at a good pace ensure workload is divided between team members where possible. This may mean anticipating work that might be required in a later challenge.
|
||||||
|
|
||||||
|
> **Hint**: If you get stuck, you can ask for help from the proctors. You may also choose to peek at the solutions.
|
||||||
|
|
||||||
|
### Core tasks
|
||||||
|
|
||||||
|
You are expected to at least complete the **Getting up and running** section. This involves setting up a Kubernetes cluster, deploying the application containers from Docker Hub, setting up monitoring and scaling your application.
|
||||||
|
|
||||||
|
### DevOps tasks
|
||||||
|
|
||||||
|
Once you're done with the above, next would be to include some DevOps flair. You'll be moving to a private container repository on Azure Container Registry, setting up a Continuous Integration and Continuous Delivery pipeline for your application and then using Helm to deploy.
|
||||||
|
|
||||||
|
### Optional tasks
|
||||||
|
|
||||||
|
If you're not out of breath yet, you can take a stab at some challenges from this section. You'll find a variety between setting up Role Based Access Control, using Azure Key Vault to store secrets or using Terraform to deploy your cluster and application.
|
|
@ -5,16 +5,67 @@ title: Deploy Kubernetes with Azure Kubernetes Service (AKS)
|
||||||
parent-id: upandrunning
|
parent-id: upandrunning
|
||||||
---
|
---
|
||||||
|
|
||||||
Your organisation requires that the application is deployed to Kubernetes running on Azure. **You will need to use features available in Kubernetes 1.11.**
|
Azure has a managed Kubernetes service, AKS (Azure Kubernetes Service).
|
||||||
|
|
||||||
You have found out that Azure has a managed Kubernetes service, AKS (Azure Kubernetes Service).
|
**You will need to use features available in Kubernetes 1.11.**
|
||||||
|
|
||||||
> **Hint** Enable Kubernetes Role-based access cntrol (RBAC) which provides fine-grained control over cluster resources when creating the cluster because **you can't enable it post cluster creation**. RBAC enabled clusters by default have degraded Kubernetes Dashboard functionality. This is a good security practice because it avoids unintended privelage escalation.
|
> **Hint** Enable Kubernetes Role-based access control (RBAC) which provides fine-grained control over cluster resources when creating the cluster because **you can't enable it post cluster creation**. RBAC enabled clusters by default have degraded Kubernetes Dashboard functionality. This is a good security practice because it avoids unintended privelage escalation.
|
||||||
|
|
||||||
### Tasks
|
### Tasks
|
||||||
|
|
||||||
1. Deploy Kubernetes to Azure, using CLI or Azure portal using the latest Kubernetes version available in AKS
|
#### Deploy Kubernetes to Azure, using CLI or Azure portal using the latest Kubernetes version available in AKS
|
||||||
2. Ensure you and your colleagues can connect to the cluster using `kubectl`
|
|
||||||
|
{% collapsible %}
|
||||||
|
|
||||||
|
Login to the Azure subscription
|
||||||
|
|
||||||
|
```sh
|
||||||
|
az login
|
||||||
|
```
|
||||||
|
|
||||||
|
Get the latest available Kubernetes version
|
||||||
|
|
||||||
|
```sh
|
||||||
|
az aks get-versions -l eastus -o table
|
||||||
|
```
|
||||||
|
|
||||||
|
Create a Resource Group
|
||||||
|
|
||||||
|
```sh
|
||||||
|
az group create --name akschallenge --location eastus
|
||||||
|
```
|
||||||
|
|
||||||
|
Create AKS using the latest version, using the Azure network plugin into a custom Virtual Network and enable the monitoring addon
|
||||||
|
|
||||||
|
```sh
|
||||||
|
az aks create --resource-group akschallenge --name <unique-aks-cluster-name> --enable-addons monitoring --kubernetes-version 1.11.3 --generate-ssh-keys --location eastus
|
||||||
|
```
|
||||||
|
|
||||||
|
Install the Kubernetes CLI
|
||||||
|
|
||||||
|
```sh
|
||||||
|
az aks install-cli
|
||||||
|
```
|
||||||
|
|
||||||
|
{% endcollapsible %}
|
||||||
|
|
||||||
|
#### Ensure you and your colleagues can connect to the cluster using `kubectl`
|
||||||
|
|
||||||
|
{% collapsible %}
|
||||||
|
|
||||||
|
Authenticate
|
||||||
|
|
||||||
|
```sh
|
||||||
|
az aks get-credentials --resource-group akschallenge --name <unique-aks-cluster-name>
|
||||||
|
```
|
||||||
|
|
||||||
|
List the available nodes
|
||||||
|
|
||||||
|
```sh
|
||||||
|
kubectl get nodes
|
||||||
|
```
|
||||||
|
|
||||||
|
{% endcollapsible %}
|
||||||
|
|
||||||
> **Resources**
|
> **Resources**
|
||||||
> * <https://docs.microsoft.com/en-us/azure/aks/kubernetes-walkthrough?wt.mc_id=CSE_(433127)>
|
> * <https://docs.microsoft.com/en-us/azure/aks/kubernetes-walkthrough?wt.mc_id=CSE_(433127)>
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
sectionid: apidb
|
||||||
|
sectionclass: h2
|
||||||
|
parent-id: upandrunning
|
||||||
|
title: Deploy MongoDB
|
||||||
|
---
|
||||||
|
|
||||||
|
You need to deploy MongoDB in a way that is scalable and production ready. There are a couple of ways to do so.
|
||||||
|
|
||||||
|
> **Hints**
|
||||||
|
> * Be careful with the authentication settings when creating MongoDB. It is recommended that you create a standalone username/password and database.
|
||||||
|
> * **Important**: If you install using Helm and then delete the release, the MongoDB data and configuration persists in a Persistent Volume Claim. You may face issues if you redploy again using the same release name because the authentication configuration will not match. If you need to delete the Helm deployment and start over, make sure you delete the Persistent Volume Claims created otherwise you'll run into issues with authentication due to stale configuration. Find those claims using `kubectl get pvc`.
|
||||||
|
|
||||||
|
### Tasks
|
||||||
|
|
||||||
|
#### Deploy an instance of MongoDB to your cluster. The application expects a database called `akschallenge`
|
||||||
|
|
||||||
|
{% collapsible %}
|
||||||
|
The recommended way to deploy MongoDB would be to use Helm. Helm is a Kubernetes application package manager and it has a [MongoDB Helm chart](https://github.com/helm/charts/tree/master/stable/mongodb#production-settings-and-horizontal-scaling) that is replicated and horizontally scalable.
|
||||||
|
|
||||||
|
##### Install Helm on your developer machine
|
||||||
|
|
||||||
|
Follow the instructions here <https://docs.helm.sh/using_helm/#from-the-binary-releases>
|
||||||
|
|
||||||
|
##### Initialize the Helm components on the AKS cluster (RBAC enabled AKS cluster, default behaviour of CLI, optional behavior from the Azure Portal)
|
||||||
|
|
||||||
|
If the cluster is RBAC enabled, you have to create the appropriate `ServiceAccount` for Tiller (the server side Helm component) to use.
|
||||||
|
|
||||||
|
Save the YAML below as `helm-rbac.yaml` or download it from [helm-rbac.yaml](yaml-solutions/01. challenge-02/helm-rbac.yaml)
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ServiceAccount
|
||||||
|
metadata:
|
||||||
|
name: tiller
|
||||||
|
namespace: kube-system
|
||||||
|
---
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: ClusterRoleBinding
|
||||||
|
metadata:
|
||||||
|
name: tiller
|
||||||
|
roleRef:
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
||||||
|
kind: ClusterRole
|
||||||
|
name: cluster-admin
|
||||||
|
subjects:
|
||||||
|
- kind: ServiceAccount
|
||||||
|
name: tiller
|
||||||
|
namespace: kube-system
|
||||||
|
```
|
||||||
|
|
||||||
|
And deploy it using
|
||||||
|
|
||||||
|
```sh
|
||||||
|
kubectl apply -f helm-rbac.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
Initialize Tiller (ommit the ``--service-account`` flag if your cluster is **not** RBAC enabled)
|
||||||
|
|
||||||
|
```sh
|
||||||
|
helm init --service-account tiller
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Install the MongoDB Helm chart
|
||||||
|
|
||||||
|
After you Tiller initialized in the cluster, wait for a short while then install the MongoDB chart, **then take note of the username, password and endpoints created. The command below creates a user called `orders-user` and a password of `orders-password`**
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl -O https://raw.githubusercontent.com/kubernetes/charts/master/stable/mongodb/values-production.yaml
|
||||||
|
helm install --name orders-mongo -f ./values-production.yaml stable/mongodb --set mongodbUsername=orders-user,mongodbPassword=orders-password,mongodbDatabase=akschallenge
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Hint** By default, the service load balancing the MongoDB cluster would be accessible at ``orders-mongo-mongodb.default.svc.cluster.local``
|
||||||
|
You'll need to use the user created in the command above when configuring the deployment environment variables.
|
||||||
|
{% endcollapsible %}
|
||||||
|
|
||||||
|
> **Resources**
|
||||||
|
> * <https://docs.microsoft.com/en-us/azure/aks/kubernetes-helm>
|
||||||
|
> * <https://github.com/helm/charts/tree/master/stable/mongodb#production-settings-and-horizontal-scaling>
|
|
@ -1,30 +0,0 @@
|
||||||
---
|
|
||||||
|
|
||||||
sectionid: apidb
|
|
||||||
sectionclass: h2
|
|
||||||
parent-id: upandrunning
|
|
||||||
title: Deploy the Order Capture API and MongoDB
|
|
||||||
---
|
|
||||||
|
|
||||||
You need to deploy the **Order Capture API** ([azch/captureorder](https://hub.docker.com/r/azch/captureorder/)). This requires an external endpoint, exposing the API on port 80 and needs to write to MongoDB.
|
|
||||||
|
|
||||||
> **Hints**
|
|
||||||
> * Take a few minutes to discuss with your team mates how are you going share the YAML files amongst yourselves. Git? OneDrive? Email (!)
|
|
||||||
> * Consider deploying MongoDB in a way that is scalable and production ready.
|
|
||||||
> * Be careful with the authentication settings when creating MongoDB. It is recommended that you create a standalone username/password and database.
|
|
||||||
> * **Important**: If you install using Helm and then delete the release, the MongoDB data and configuration persists in a Persistent Volume Claim. You may face issues if you redploy again using the same release name because the authentication configuration will not match.
|
|
||||||
|
|
||||||
![Application components](media/captureorder.png)
|
|
||||||
|
|
||||||
### Tasks
|
|
||||||
|
|
||||||
1. Deploy an instance of MongoDB to your cluster. The application expects a database called `akschallenge`
|
|
||||||
1. Provision the `captureorder` deployment and expose a public endpoint
|
|
||||||
1. Ensure orders are successfully written to MongoDB
|
|
||||||
|
|
||||||
> **Resources**
|
|
||||||
> * <https://kubernetes.io/docs/concepts/workloads/controllers/deployment/>
|
|
||||||
> * <https://kubernetes.io/docs/concepts/services-networking/service/>
|
|
||||||
> * <https://docs.microsoft.com/en-us/azure/aks/kubernetes-helm>
|
|
||||||
> * <https://github.com/helm/charts/tree/master/stable/mongodb#production-settings-and-horizontal-scaling>
|
|
||||||
> * <https://kubernetes.io/docs/concepts/configuration/secret/>
|
|
|
@ -0,0 +1,167 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
sectionid: apidb
|
||||||
|
sectionclass: h2
|
||||||
|
parent-id: upandrunning
|
||||||
|
title: Deploy the Order Capture API
|
||||||
|
---
|
||||||
|
|
||||||
|
You need to deploy the **Order Capture API** ([azch/captureorder](https://hub.docker.com/r/azch/captureorder/)). This requires an external endpoint, exposing the API on port 80 and needs to write to MongoDB.
|
||||||
|
|
||||||
|
### Container images and source code
|
||||||
|
|
||||||
|
In the table below, you will find the Docker container images provided by the development team on Docker Hub as well as their corresponding source code on GitHub.
|
||||||
|
|
||||||
|
| Component | Docker Image | Source Code | Build Status |
|
||||||
|
|------------------------------|------------------------------------------------------------------|-------------------------------------------------------------------|--------------|
|
||||||
|
| Order Capture API | [azch/captureorder](https://hub.docker.com/r/azch/captureorder/) | [source-code](https://github.com/Azure/azch-captureorder) | [![Build Status](https://dev.azure.com/theazurechallenge/Kubernetes/_apis/build/status/Code/Azure.azch-captureorder)](https://dev.azure.com/theazurechallenge/Kubernetes/_build/latest?definitionId=10) |
|
||||||
|
|
||||||
|
### Environment variables
|
||||||
|
|
||||||
|
The Order Capture API requires certain environment variables to properly run and track your progress. Make sure you set those environment variables.
|
||||||
|
|
||||||
|
* `TEAMNAME="[YourTeamName]"`
|
||||||
|
* Track your team's progress. Use your assigned team name
|
||||||
|
* `CHALLENGEAPPINSIGHTS_KEY="[AsSpecifiedAtTheEvent]"`
|
||||||
|
* Application Insights key provided by proctors
|
||||||
|
* `APPINSIGHTS_KEY="[YourOwnKey]"`
|
||||||
|
* Your own Application Insights key, if you want to track application metrics
|
||||||
|
* `MONGOHOST="<hostname of mongodb>"`
|
||||||
|
* MongoDB hostname.
|
||||||
|
* `MONGOUSER="<mongodb username>"`
|
||||||
|
* MongoDB username.
|
||||||
|
* `MONGOPASSWORD="<mongodb password>"`
|
||||||
|
* MongoDB password.
|
||||||
|
|
||||||
|
> **Hint:** The Order Capture API exposes the following endpoint for health-checks: `http://[PublicEndpoint]:[port]/healthz`
|
||||||
|
|
||||||
|
### Tasks
|
||||||
|
|
||||||
|
#### Provision the `captureorder` deployment and expose a public endpoint
|
||||||
|
|
||||||
|
{% collapsible %}
|
||||||
|
|
||||||
|
##### Deployment
|
||||||
|
|
||||||
|
Save the YAML below as `captureorder-deployment.yaml` or download it from [captureorder-deployment.yaml](yaml-solutions/01. challenge-02/captureorder-deployment.yaml)
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: captureorder
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: captureorder
|
||||||
|
replicas: 2
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: captureorder
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: captureorder
|
||||||
|
image: azch/captureorder
|
||||||
|
imagePullPolicy: Always
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
port: 8080
|
||||||
|
path: /healthz
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
port: 8080
|
||||||
|
path: /healthz
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
memory: "64Mi"
|
||||||
|
cpu: "100m"
|
||||||
|
limits:
|
||||||
|
memory: "128Mi"
|
||||||
|
cpu: "500m"
|
||||||
|
env:
|
||||||
|
- name: TEAMNAME
|
||||||
|
value: "team-azch"
|
||||||
|
- name: APPINSIGHTS_KEY
|
||||||
|
value: ""
|
||||||
|
- name: MONGOHOST
|
||||||
|
value: "orders-mongo-mongodb.default.svc.cluster.local"
|
||||||
|
- name: MONGOUSER
|
||||||
|
value: "orders-user"
|
||||||
|
- name: MONGOPASSWORD
|
||||||
|
value: "orders-password"
|
||||||
|
ports:
|
||||||
|
- containerPort: 80
|
||||||
|
```
|
||||||
|
|
||||||
|
And deploy it using
|
||||||
|
|
||||||
|
```sh
|
||||||
|
kubectl apply -f captureorder-deployment.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Verify that the pods are up and running
|
||||||
|
|
||||||
|
```sh
|
||||||
|
kubectl get pods -l app=captureorder
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Hint** If the pods are not starting, not ready or are crashing, you can view their logs using `kubectl logs <pod name>` and `kubectl describe pod <pod name>`.
|
||||||
|
|
||||||
|
##### Service
|
||||||
|
|
||||||
|
Save the YAML below as `captureorder-service.yaml` or download it from [captureorder-service.yaml](yaml-solutions/01. challenge-02/captureorder-service.yaml)
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: captureorder
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: captureorder
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 80
|
||||||
|
targetPort: 8080
|
||||||
|
type: LoadBalancer
|
||||||
|
```
|
||||||
|
|
||||||
|
And deploy it using
|
||||||
|
|
||||||
|
```sh
|
||||||
|
kubectl apply -f captureorder-service.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Retrieve the External-IP of the Service
|
||||||
|
|
||||||
|
Use the command below. Make sure to allow a couple of minutes for the Azure Load Balancer to assign a public IP.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
kubectl get service captureorder -o jsonpath="{.status.loadBalancer.ingress[*].ip}"
|
||||||
|
```
|
||||||
|
|
||||||
|
{% endcollapsible %}
|
||||||
|
|
||||||
|
#### Ensure orders are successfully written to MongoDB
|
||||||
|
|
||||||
|
{% collapsible %}
|
||||||
|
Send a `POST` request using [Postman](https://www.getpostman.com/) or curl to the IP of the service you got from the previous command
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl -d '{"EmailAddress": "email@domain.com", "Product": "prod-1", "Total": 100}' -H "Content-Type: application/json" -X POST http://[Your Service Public LoadBalancer IP]/v1/order
|
||||||
|
```
|
||||||
|
|
||||||
|
You should get back the created order ID
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"orderId": "5beaa09a055ed200016e582f"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
{% endcollapsible %}
|
||||||
|
|
||||||
|
> **Resources**
|
||||||
|
> * <https://kubernetes.io/docs/concepts/workloads/controllers/deployment/>
|
||||||
|
> * <https://kubernetes.io/docs/concepts/services-networking/service/>
|
|
@ -1,32 +0,0 @@
|
||||||
---
|
|
||||||
sectionid: orderfulfilment
|
|
||||||
sectionclass: h2
|
|
||||||
title: Deploy the Order Fulfilment components
|
|
||||||
parent-id: upandrunning
|
|
||||||
---
|
|
||||||
|
|
||||||
The Order Fulfilment process needs to be deployed. This includes:
|
|
||||||
|
|
||||||
* An **messaging bus** to broker messages. The application is configured to use [Azure Service Bus Queues](https://docs.microsoft.com/en-us/azure/service-bus-messaging/service-bus-queues-topics-subscriptions) as the message bus. You'll need to provision this and configure the application accordingly.
|
|
||||||
* An **event processor** ([azch/sblistener](https://hub.docker.com/r/azch/sblistener/)). This process listens to messages coming to the Service Bus Queues.
|
|
||||||
* The **order fulfillment service** ([azch/fulfillorder](https://hub.docker.com/r/azch/fulfillorder/)). This container will fulfill orders and output orders for future batch processing. The order transaction files from all instances of order fulfillment must be written to a single location that also enables staff to inspect the log files without interacting with Kubernetes.
|
|
||||||
|
|
||||||
![Application components](/media/fulfillorder.png)
|
|
||||||
|
|
||||||
> **Hint** Refer to the [container images and source code](#container-images-and-source-code) and [environment variables](#environment-variables) sections to properly configure the application.
|
|
||||||
|
|
||||||
### Tasks
|
|
||||||
|
|
||||||
1. Create an Azure Service Bus Queue
|
|
||||||
1. Configure `captureorder` to connect to the Azure Service Bus Queue
|
|
||||||
1. Provision `fulfillorder` deployment, it **should not** be exposed to the internet
|
|
||||||
1. Provision `sblistener` deployment
|
|
||||||
1. Configure `fulfillorder` to store data to Azure Files. You need to write files in the `/orders` path
|
|
||||||
1. Verify that the orders are written in the Azure File Share
|
|
||||||
|
|
||||||
> **Resources**
|
|
||||||
> * <https://docs.microsoft.com/en-us/azure/service-bus-messaging/service-bus-dotnet-get-started-with-queues>
|
|
||||||
> * <https://kubernetes.io/docs/concepts/storage/persistent-volumes/>
|
|
||||||
> * <https://docs.microsoft.com/gl-es/azure/aks/azure-files-dynamic-pv?wt.mc_id=CSE_(606698)>
|
|
||||||
> * <https://kubernetes.io/docs/concepts/storage/storage-classes/#azure-file>
|
|
||||||
> * <https://kubernetes.io/docs/concepts/configuration/secret/>
|
|
|
@ -1,23 +0,0 @@
|
||||||
---
|
|
||||||
sectionid: monitoring
|
|
||||||
sectionclass: h2
|
|
||||||
parent-id: upandrunning
|
|
||||||
title: Monitoring
|
|
||||||
---
|
|
||||||
|
|
||||||
You would like to monitor the performance of different components in your application, view logs and get alerts whenever your application availability goes down or some components fail.
|
|
||||||
|
|
||||||
Use a combination of the available tools to setup alerting capabilities for your application.
|
|
||||||
|
|
||||||
### Tasks
|
|
||||||
|
|
||||||
1. Instrument the application with Azure Application Insights to track how requests move within the application
|
|
||||||
|
|
||||||
> **Hint** The application compoments are provisioned to send telemetry to Azure Application Insights. You can create your own Azure Application Insights service and provide the instrumentation key as an environment variable named `APPINSIGHTS_KEY`.
|
|
||||||
|
|
||||||
1. Leverage integrated Azure Kubernetes Service monitoring to figure out why requests are failing, inspect logs and monitor your cluster health
|
|
||||||
|
|
||||||
> **Resources**
|
|
||||||
> * <https://docs.microsoft.com/en-us/azure/application-insights/app-insights-alerts?wt.mc_id=CSE_(606698)>
|
|
||||||
> * <https://docs.microsoft.com/en-us/azure/monitoring/monitoring-container-insights-overview>
|
|
||||||
> * <https://coreos.com/operators/prometheus/docs/latest/>
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
---
|
||||||
|
sectionid: monitoring
|
||||||
|
sectionclass: h2
|
||||||
|
parent-id: upandrunning
|
||||||
|
title: Monitoring
|
||||||
|
---
|
||||||
|
|
||||||
|
You would like to monitor the performance of different components in your application, view logs and get alerts whenever your application availability goes down or some components fail.
|
||||||
|
|
||||||
|
Use a combination of the available tools to setup alerting capabilities for your application.
|
||||||
|
|
||||||
|
### Tasks
|
||||||
|
|
||||||
|
#### Instrument the application with Azure Application Insights to track how requests move within the application
|
||||||
|
|
||||||
|
> **Hint** The application compoments are provisioned to send telemetry to Azure Application Insights. You can create your own Azure Application Insights service and provide the instrumentation key as an environment variable named `APPINSIGHTS_KEY`.
|
||||||
|
|
||||||
|
{% collapsible %}
|
||||||
|
|
||||||
|
- Create a new Application Insights resource <https://docs.microsoft.com/en-us/azure/application-insights/app-insights-create-new-resource>
|
||||||
|
- Provide the instrumentation key as an environment variable named `APPINSIGHTS_KEY` to all deployments.
|
||||||
|
- View how your application is performing on the Application Map
|
||||||
|
![Application map](media/applicationmap.png)
|
||||||
|
|
||||||
|
{% endcollapsible %}
|
||||||
|
|
||||||
|
#### Leverage integrated Azure Kubernetes Service monitoring to figure out why requests are failing, inspect logs and monitor your cluster health
|
||||||
|
|
||||||
|
{% collapsible %}
|
||||||
|
|
||||||
|
- Check the cluster utilization under load
|
||||||
|
![Cluster utilization](media/clusterutilization.png)
|
||||||
|
|
||||||
|
- Identify which pods are causing trouble
|
||||||
|
![Pod utilization](media/podmetrics.png)
|
||||||
|
|
||||||
|
{% endcollapsible %}
|
||||||
|
|
||||||
|
> **Resources**
|
||||||
|
> * <https://docs.microsoft.com/en-us/azure/application-insights/app-insights-alerts?wt.mc_id=CSE_(606698)>
|
||||||
|
> * <https://docs.microsoft.com/en-us/azure/monitoring/monitoring-container-insights-overview>
|
||||||
|
> * <https://coreos.com/operators/prometheus/docs/latest/>
|
|
@ -1,24 +0,0 @@
|
||||||
---
|
|
||||||
sectionid: scaling
|
|
||||||
sectionclass: h2
|
|
||||||
parent-id: upandrunning
|
|
||||||
title: Scaling
|
|
||||||
---
|
|
||||||
|
|
||||||
As popularity of the application grows the application needs to scale appropriately as demand changes.
|
|
||||||
Ensure the application remains responsive as the number of order submissions increases. Consider the cost impact of scaling your infrastructure.
|
|
||||||
|
|
||||||
> **Hint** The `eventlistener` utilises a competing/compensating consumers routing pattern. This means that you can have more than one eventlistener instance listening to a specific queue.
|
|
||||||
> Also make sure as you increase the number of replicas that your cluster has enough capacity to handle this load.
|
|
||||||
|
|
||||||
### Tasks
|
|
||||||
|
|
||||||
1. Configure the `captureorder` and `fulfillorder` to scale as load increases
|
|
||||||
1. Scale up the number of `eventlistener` replicas
|
|
||||||
1. Check if your cluster nodes needs to scale/auto-scale
|
|
||||||
1. Scale other parts of the application as required
|
|
||||||
|
|
||||||
> **Resources**
|
|
||||||
> * <https://docs.microsoft.com/en-us/azure/aks/tutorial-kubernetes-scale>
|
|
||||||
> * <https://docs.microsoft.com/en-us/azure/aks/autoscaler>
|
|
||||||
> * <https://docs.microsoft.com/en-gb/vsts/load-test/get-started-simple-cloud-load-test?wt.mc_id=CSE_(433127)>
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
---
|
||||||
|
sectionid: scaling
|
||||||
|
sectionclass: h2
|
||||||
|
parent-id: upandrunning
|
||||||
|
title: Scaling
|
||||||
|
---
|
||||||
|
|
||||||
|
As popularity of the application grows the application needs to scale appropriately as demand changes.
|
||||||
|
Ensure the application remains responsive as the number of order submissions increases.
|
||||||
|
|
||||||
|
### Tasks
|
||||||
|
|
||||||
|
#### Create Horizontal Pod Autoscaler
|
||||||
|
|
||||||
|
Horizontal Pod Autoscaler allows Kubernetes to detect when your deployed pods need more resources and then it schedules more pods onto the cluster to cope with the demand.
|
||||||
|
|
||||||
|
{% collapsible %}
|
||||||
|
|
||||||
|
Save the YAML below as `captureorder-hpa.yaml` or download it from [captureorder-hpa.yaml](yaml-solutions/01. challenge-04/captureorder-hpa.yaml)
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: autoscaling/v1
|
||||||
|
kind: HorizontalPodAutoscaler
|
||||||
|
metadata:
|
||||||
|
name: captureorder
|
||||||
|
spec:
|
||||||
|
scaleTargetRef:
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
name: captureorder
|
||||||
|
minReplicas: 4
|
||||||
|
maxReplicas: 10
|
||||||
|
targetCPUUtilizationPercentage: 50
|
||||||
|
```
|
||||||
|
|
||||||
|
And deploy it using
|
||||||
|
|
||||||
|
```sh
|
||||||
|
kubectl apply -f captureorder-deployment.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
{% endcollapsible %}
|
||||||
|
|
||||||
|
> **Important** For the Horizontal Pod Autoscaler to work, you **MUST** remove the explicit `replicas: 2` count from your `captureorder` deployment and redeploy it and your pods must define resource requests and resource limits.
|
||||||
|
|
||||||
|
#### Scale MongoDB
|
||||||
|
|
||||||
|
{% collapsible %}
|
||||||
|
|
||||||
|
If you used the replicated MongoDB Helm chart, you can scale the secondaries using the command below.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
kubectl scale statefulset orders-mongo-mongodb-secondary --replicas=3
|
||||||
|
```
|
||||||
|
|
||||||
|
{% endcollapsible %}
|
||||||
|
|
||||||
|
#### Check if your cluster nodes needs to scale/auto-scale (optional)
|
||||||
|
|
||||||
|
{% collapsible %}
|
||||||
|
|
||||||
|
Scale the cluster nodes using the command below to the required number of nodes
|
||||||
|
|
||||||
|
```sh
|
||||||
|
az aks scale --resource-group akschallenge --name <unique-aks-cluster-name> --node-count 4
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also optionally configure the AKS cluster-autoscaler <https://docs.microsoft.com/en-us/azure/aks/autoscaler>.
|
||||||
|
|
||||||
|
{% endcollapsible %}
|
||||||
|
|
||||||
|
> **Resources**
|
||||||
|
> * <https://docs.microsoft.com/en-us/azure/aks/tutorial-kubernetes-scale>
|
||||||
|
> * <https://docs.microsoft.com/en-us/azure/aks/autoscaler>
|
||||||
|
> * <https://docs.microsoft.com/en-gb/vsts/load-test/get-started-simple-cloud-load-test?wt.mc_id=CSE_(433127)>
|
|
@ -1,26 +0,0 @@
|
||||||
---
|
|
||||||
sectionclass: h2
|
|
||||||
sectionid: cosmos
|
|
||||||
parent-id: upandrunning
|
|
||||||
title: Swap out MongoDB for CosmosDB
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
Your organisation has decided it wants to reduce the management overhead, needs to introduce global replication and improve the availability of MongoDB. To do this you will take advantage of CosmosDB.
|
|
||||||
|
|
||||||
CosmosDB has a Mongo API driver so that you do not need to change any application code to port a MongoDB application to CosmosDB.
|
|
||||||
|
|
||||||
> **Hint** Pay attention to the Cosmos DB metrics, especially around throttling, and scale up as needed. Use the capacity planner <https://www.documentdb.com/capacityplanner>
|
|
||||||
|
|
||||||
![Application components](media/cosmosdb.png)
|
|
||||||
|
|
||||||
### Tasks
|
|
||||||
|
|
||||||
1. Deploy CosmosDB
|
|
||||||
1. Configure application to connect to CosmosDB
|
|
||||||
1. Verify that the orders are making into your CosmosDB collection
|
|
||||||
|
|
||||||
> **Resources**
|
|
||||||
> * <https://docs.microsoft.com/en-us/azure/cosmos-db/mongodb-introduction?wt.mc_id=CSE_(433127)>
|
|
||||||
> * <https://docs.microsoft.com/en-us/azure/cosmos-db/connect-mongodb-account>
|
|
||||||
> * <https://docs.microsoft.com/en-us/azure/cosmos-db/request-units>
|
|
|
@ -4,17 +4,24 @@ module Jekyll
|
||||||
def render(context)
|
def render(context)
|
||||||
@text = super
|
@text = super
|
||||||
|
|
||||||
# pipe param through liquid to make additional replacements possible
|
site = context.registers[:site]
|
||||||
@parsedText = Liquid::Template.parse(text).render context
|
converter = site.find_converter_instance(::Jekyll::Converters::Markdown)
|
||||||
#{@context.registers[:site].find_converter_instance(::Jekyll::Converters::Markdown).convert(@text)}
|
@parsedText = converter.convert(@text)
|
||||||
|
|
||||||
<<~COLLAPSIBLEBLOCK
|
<<~COLLAPSIBLEBLOCK
|
||||||
<div>
|
<!-- Begin collapsible container div -->
|
||||||
<button class='toggle-collapsible'>Toggle solution</button>
|
<div class="collapsible-content-container">
|
||||||
<div class="collapsible-content">
|
<!-- Begin collapsible container button -->
|
||||||
#{@parsedText}
|
<button class="toggle-collapsible">Toggle solution</button>
|
||||||
</div>
|
<!-- Begin collapsible container content div -->
|
||||||
</div>
|
<div class="collapsible-content">
|
||||||
|
<!-- Begin parsedText -->
|
||||||
|
#{@parsedText}
|
||||||
|
<!-- End parsedText -->
|
||||||
|
</div>
|
||||||
|
<!-- End collapsible container content div -->
|
||||||
|
</div>
|
||||||
|
<!-- End collapsible container div -->
|
||||||
COLLAPSIBLEBLOCK
|
COLLAPSIBLEBLOCK
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -127,9 +127,9 @@ h3{
|
||||||
text-align: left;
|
text-align: left;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
|
|
||||||
&:before {
|
/*&:before {
|
||||||
content: counter(h1-counter) "." counter(h2-counter) "." counter(h3-counter) " ";
|
content: counter(h1-counter) "." counter(h2-counter) "." counter(h3-counter) " ";
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
h3.nocount:before {
|
h3.nocount:before {
|
||||||
|
@ -148,9 +148,9 @@ h4{
|
||||||
text-align: left;
|
text-align: left;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
|
|
||||||
&:before {
|
/*&:before {
|
||||||
content: counter(h1-counter) "." counter(h2-counter) "." counter(h3-counter) "." counter(h4-counter) " ";
|
content: counter(h1-counter) "." counter(h2-counter) "." counter(h3-counter) "." counter(h4-counter) " ";
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
.h4{
|
.h4{
|
||||||
|
@ -165,9 +165,9 @@ h5{
|
||||||
text-align: left;
|
text-align: left;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
|
|
||||||
&:before {
|
/*&:before {
|
||||||
content: counter(h1-counter) "." counter(h2-counter) "." counter(h3-counter) "." counter(h4-counter) "." counter(h5-counter) " ";
|
content: counter(h1-counter) "." counter(h2-counter) "." counter(h3-counter) "." counter(h4-counter) "." counter(h5-counter) " ";
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -256,9 +256,17 @@ button.active, button.toggle-collapsible:hover {
|
||||||
background-color: #555;
|
background-color: #555;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.collapsible-content-container {
|
||||||
|
margin-bottom: 18px;
|
||||||
|
}
|
||||||
.collapsible-content {
|
.collapsible-content {
|
||||||
padding: 0 18px;
|
padding: 18px 18px 0px 18px;
|
||||||
display: none;
|
display: none;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background-color: #f1f1f1;
|
border: 0.25em solid#555;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.collapsible-content pre.highlight {
|
||||||
|
margin: 0;
|
||||||
}
|
}
|
|
@ -269,6 +269,7 @@
|
||||||
.markdown-body h2 {
|
.markdown-body h2 {
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
|
margin-top: 48px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.markdown-body h3 {
|
.markdown-body h3 {
|
||||||
|
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 153 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 234 KiB |
Двоичные данные
media/overview.png
Двоичные данные
media/overview.png
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 179 KiB После Ширина: | Высота: | Размер: 93 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 126 KiB |
|
@ -0,0 +1,46 @@
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: captureorder
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: captureorder
|
||||||
|
replicas: 2
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: captureorder
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: captureorder
|
||||||
|
image: azch/captureorder
|
||||||
|
imagePullPolicy: Always
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
port: 8080
|
||||||
|
path: /healthz
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
port: 8080
|
||||||
|
path: /healthz
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
memory: "64Mi"
|
||||||
|
cpu: "100m"
|
||||||
|
limits:
|
||||||
|
memory: "128Mi"
|
||||||
|
cpu: "500m"
|
||||||
|
env:
|
||||||
|
- name: TEAMNAME
|
||||||
|
value: "team-azch"
|
||||||
|
- name: APPINSIGHTS_KEY
|
||||||
|
value: ""
|
||||||
|
- name: MONGOHOST
|
||||||
|
value: "orders-mongo-mongodb.default.svc.cluster.local"
|
||||||
|
- name: MONGOUSER
|
||||||
|
value: "orders-user"
|
||||||
|
- name: MONGOPASSWORD
|
||||||
|
value: "orders-password"
|
||||||
|
ports:
|
||||||
|
- containerPort: 80
|
|
@ -0,0 +1,12 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: captureorder
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: captureorder
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 80
|
||||||
|
targetPort: 8080
|
||||||
|
type: LoadBalancer
|
|
@ -0,0 +1,18 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ServiceAccount
|
||||||
|
metadata:
|
||||||
|
name: tiller
|
||||||
|
namespace: kube-system
|
||||||
|
---
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: ClusterRoleBinding
|
||||||
|
metadata:
|
||||||
|
name: tiller
|
||||||
|
roleRef:
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
||||||
|
kind: ClusterRole
|
||||||
|
name: cluster-admin
|
||||||
|
subjects:
|
||||||
|
- kind: ServiceAccount
|
||||||
|
name: tiller
|
||||||
|
namespace: kube-system
|
|
@ -0,0 +1,12 @@
|
||||||
|
apiVersion: autoscaling/v1
|
||||||
|
kind: HorizontalPodAutoscaler
|
||||||
|
metadata:
|
||||||
|
name: captureorder
|
||||||
|
spec:
|
||||||
|
scaleTargetRef:
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
name: captureorder
|
||||||
|
minReplicas: 4
|
||||||
|
maxReplicas: 10
|
||||||
|
targetCPUUtilizationPercentage: 50
|
|
@ -0,0 +1,259 @@
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: captureorder
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: captureorder
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: captureorder
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: captureorder
|
||||||
|
image: azch/captureorder
|
||||||
|
imagePullPolicy: Always
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
port: 8080
|
||||||
|
path: /healthz
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
port: 8080
|
||||||
|
path: /healthz
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
memory: "64Mi"
|
||||||
|
cpu: "100m"
|
||||||
|
limits:
|
||||||
|
memory: "128Mi"
|
||||||
|
cpu: "500m"
|
||||||
|
env:
|
||||||
|
- name: TEAMNAME
|
||||||
|
value: "team-azch"
|
||||||
|
- name: APPINSIGHTS_KEY
|
||||||
|
value: "5d44bbd0-87c0-4b73-8e35-e16a07583ba2"
|
||||||
|
- name: AMQPURL
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: service-bus-connection
|
||||||
|
key: amqp-url
|
||||||
|
- name: MONGOHOST
|
||||||
|
value: "orders-mongo-mongodb.default.svc.cluster.local"
|
||||||
|
- name: MONGOUSER
|
||||||
|
value: "orders-user"
|
||||||
|
- name: MONGOPASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: orders-mongo-mongodb
|
||||||
|
key: mongodb-password
|
||||||
|
ports:
|
||||||
|
- containerPort: 80
|
||||||
|
---
|
||||||
|
apiVersion: autoscaling/v1
|
||||||
|
kind: HorizontalPodAutoscaler
|
||||||
|
metadata:
|
||||||
|
name: captureorder
|
||||||
|
spec:
|
||||||
|
scaleTargetRef:
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
name: captureorder
|
||||||
|
minReplicas: 4
|
||||||
|
maxReplicas: 10
|
||||||
|
targetCPUUtilizationPercentage: 50
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: captureorder
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: captureorder
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 80
|
||||||
|
targetPort: 8080
|
||||||
|
type: LoadBalancer
|
||||||
|
---
|
||||||
|
apiVersion: storage.k8s.io/v1
|
||||||
|
kind: StorageClass
|
||||||
|
metadata:
|
||||||
|
name: azurefile
|
||||||
|
provisioner: kubernetes.io/azure-file
|
||||||
|
mountOptions:
|
||||||
|
- dir_mode=0777
|
||||||
|
- file_mode=0777
|
||||||
|
- uid=1000
|
||||||
|
- gid=1000
|
||||||
|
parameters:
|
||||||
|
skuName: Standard_LRS
|
||||||
|
storageAccount: akschallenge
|
||||||
|
---
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: ClusterRole
|
||||||
|
metadata:
|
||||||
|
name: system:azure-cloud-provider
|
||||||
|
rules:
|
||||||
|
- apiGroups: [""]
|
||||||
|
resources: ["secrets"]
|
||||||
|
verbs: ["get", "create"]
|
||||||
|
---
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: ClusterRoleBinding
|
||||||
|
metadata:
|
||||||
|
name: system:azure-cloud-provider
|
||||||
|
roleRef:
|
||||||
|
kind: ClusterRole
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
||||||
|
name: system:azure-cloud-provider
|
||||||
|
subjects:
|
||||||
|
- kind: ServiceAccount
|
||||||
|
name: persistent-volume-binder
|
||||||
|
namespace: kube-system
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolumeClaim
|
||||||
|
metadata:
|
||||||
|
name: ordersfiles
|
||||||
|
spec:
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteMany
|
||||||
|
storageClassName: azurefile
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: 5Gi
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: fulfillorder
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: fulfillorder
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: fulfillorder
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: fulfillorder
|
||||||
|
image: azch/fulfillorder
|
||||||
|
imagePullPolicy: Always
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
port: 8080
|
||||||
|
path: /healthz
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
port: 8080
|
||||||
|
path: /healthz
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
memory: "64Mi"
|
||||||
|
cpu: "100m"
|
||||||
|
limits:
|
||||||
|
memory: "128Mi"
|
||||||
|
cpu: "500m"
|
||||||
|
env:
|
||||||
|
- name: TEAMNAME
|
||||||
|
value: "team-azch"
|
||||||
|
- name: APPINSIGHTS_KEY
|
||||||
|
value: "5d44bbd0-87c0-4b73-8e35-e16a07583ba2"
|
||||||
|
- name: MONGOHOST
|
||||||
|
value: "orders-mongo-mongodb.default.svc.cluster.local"
|
||||||
|
- name: MONGOUSER
|
||||||
|
value: "orders-user"
|
||||||
|
- name: MONGOPASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: orders-mongo-mongodb
|
||||||
|
key: mongodb-password
|
||||||
|
ports:
|
||||||
|
- containerPort: 80
|
||||||
|
volumeMounts:
|
||||||
|
- mountPath: "/orders"
|
||||||
|
name: orders
|
||||||
|
volumes:
|
||||||
|
- name: orders
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: ordersfiles
|
||||||
|
---
|
||||||
|
apiVersion: autoscaling/v1
|
||||||
|
kind: HorizontalPodAutoscaler
|
||||||
|
metadata:
|
||||||
|
name: fulfillorder
|
||||||
|
spec:
|
||||||
|
scaleTargetRef:
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
name: fulfillorder
|
||||||
|
minReplicas: 4
|
||||||
|
maxReplicas: 10
|
||||||
|
targetCPUUtilizationPercentage: 50
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: fulfillorder
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: fulfillorder
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 80
|
||||||
|
targetPort: 8080
|
||||||
|
type: ClusterIP
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: eventlistener
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: eventlistener
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: eventlistener
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: eventlistener
|
||||||
|
image: azch/sblistener
|
||||||
|
imagePullPolicy: Always
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
memory: "64Mi"
|
||||||
|
cpu: "100m"
|
||||||
|
limits:
|
||||||
|
memory: "128Mi"
|
||||||
|
cpu: "500m"
|
||||||
|
env:
|
||||||
|
- name: TEAMNAME
|
||||||
|
value: "team-azch"
|
||||||
|
- name: APPINSIGHTS_KEY
|
||||||
|
value: "5d44bbd0-87c0-4b73-8e35-e16a07583ba2"
|
||||||
|
- name: SERVICEBUSCONNSTRING
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: service-bus-connection
|
||||||
|
key: sb-endpoint
|
||||||
|
- name: PROCESSENDPOINT
|
||||||
|
value: "http://fulfillorder.default.svc.cluster.local/v1/order/"
|
||||||
|
---
|
||||||
|
apiVersion: autoscaling/v1
|
||||||
|
kind: HorizontalPodAutoscaler
|
||||||
|
metadata:
|
||||||
|
name: eventlistener
|
||||||
|
spec:
|
||||||
|
scaleTargetRef:
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
name: eventlistener
|
||||||
|
minReplicas: 3
|
||||||
|
maxReplicas: 10
|
||||||
|
targetCPUUtilizationPercentage: 30
|
|
@ -0,0 +1,37 @@
|
||||||
|
#! /bin/bash
|
||||||
|
ID=`az account show --query id -o json`
|
||||||
|
SUBSCRIPTION_ID=`echo $ID | tr -d '"' `
|
||||||
|
|
||||||
|
TENANT=`az account show --query tenantId -o json`
|
||||||
|
TENANT_ID=`echo $TENANT | tr -d '"' | base64`
|
||||||
|
|
||||||
|
read -p "What's your cluster name? " cluster_name
|
||||||
|
read -p "Resource group name? " resource_group
|
||||||
|
|
||||||
|
CLUSTER_NAME=`echo $cluster_name | base64`
|
||||||
|
RESOURCE_GROUP=`echo $resource_group | base64`
|
||||||
|
|
||||||
|
PERMISSIONS=`az ad sp create-for-rbac --role="Contributor" --scopes="/subscriptions/$SUBSCRIPTION_ID" -o json`
|
||||||
|
CLIENT_ID=`echo $PERMISSIONS | sed -e 's/^.*"appId"[ ]*:[ ]*"//' -e 's/".*//' | base64`
|
||||||
|
CLIENT_SECRET=`echo $PERMISSIONS | sed -e 's/^.*"password"[ ]*:[ ]*"//' -e 's/".*//' | base64`
|
||||||
|
|
||||||
|
SUBSCRIPTION_ID=`echo $ID | tr -d '"' | base64 `
|
||||||
|
|
||||||
|
NODE_RESOURCE_GROUP=`az aks show --name $cluster_name --resource-group $resource_group -o tsv --query 'nodeResourceGroup' | base64`
|
||||||
|
|
||||||
|
echo "---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: cluster-autoscaler-azure
|
||||||
|
namespace: kube-system
|
||||||
|
data:
|
||||||
|
ClientID: $CLIENT_ID
|
||||||
|
ClientSecret: $CLIENT_SECRET
|
||||||
|
ResourceGroup: $RESOURCE_GROUP
|
||||||
|
SubscriptionID: $SUBSCRIPTION_ID
|
||||||
|
TenantID: $TENANT_ID
|
||||||
|
VMType: QUtTCg==
|
||||||
|
ClusterName: $CLUSTER_NAME
|
||||||
|
NodeResourceGroup: $NODE_RESOURCE_GROUP
|
||||||
|
---"
|
|
@ -0,0 +1,259 @@
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: captureorder
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: captureorder
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: captureorder
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: captureorder
|
||||||
|
image: azch/captureorder
|
||||||
|
imagePullPolicy: Always
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
port: 8080
|
||||||
|
path: /healthz
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
port: 8080
|
||||||
|
path: /healthz
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
memory: "64Mi"
|
||||||
|
cpu: "100m"
|
||||||
|
limits:
|
||||||
|
memory: "128Mi"
|
||||||
|
cpu: "500m"
|
||||||
|
env:
|
||||||
|
- name: TEAMNAME
|
||||||
|
value: "team-azch"
|
||||||
|
- name: APPINSIGHTS_KEY
|
||||||
|
value: "5d44bbd0-87c0-4b73-8e35-e16a07583ba2"
|
||||||
|
- name: AMQPURL
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: service-bus-connection
|
||||||
|
key: amqp-url
|
||||||
|
- name: MONGOHOST
|
||||||
|
value: "akschallengecosmos.documents.azure.com"
|
||||||
|
- name: MONGOUSER
|
||||||
|
value: "akschallengecosmos"
|
||||||
|
- name: MONGOPASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: cosmosdb-connection
|
||||||
|
key: primarykey
|
||||||
|
ports:
|
||||||
|
- containerPort: 80
|
||||||
|
---
|
||||||
|
apiVersion: autoscaling/v1
|
||||||
|
kind: HorizontalPodAutoscaler
|
||||||
|
metadata:
|
||||||
|
name: captureorder
|
||||||
|
spec:
|
||||||
|
scaleTargetRef:
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
name: captureorder
|
||||||
|
minReplicas: 4
|
||||||
|
maxReplicas: 10
|
||||||
|
targetCPUUtilizationPercentage: 50
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: captureorder
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: captureorder
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 80
|
||||||
|
targetPort: 8080
|
||||||
|
type: LoadBalancer
|
||||||
|
---
|
||||||
|
apiVersion: storage.k8s.io/v1
|
||||||
|
kind: StorageClass
|
||||||
|
metadata:
|
||||||
|
name: azurefile
|
||||||
|
provisioner: kubernetes.io/azure-file
|
||||||
|
mountOptions:
|
||||||
|
- dir_mode=0777
|
||||||
|
- file_mode=0777
|
||||||
|
- uid=1000
|
||||||
|
- gid=1000
|
||||||
|
parameters:
|
||||||
|
skuName: Standard_LRS
|
||||||
|
storageAccount: akschallenge
|
||||||
|
---
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: ClusterRole
|
||||||
|
metadata:
|
||||||
|
name: system:azure-cloud-provider
|
||||||
|
rules:
|
||||||
|
- apiGroups: [""]
|
||||||
|
resources: ["secrets"]
|
||||||
|
verbs: ["get", "create"]
|
||||||
|
---
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: ClusterRoleBinding
|
||||||
|
metadata:
|
||||||
|
name: system:azure-cloud-provider
|
||||||
|
roleRef:
|
||||||
|
kind: ClusterRole
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
||||||
|
name: system:azure-cloud-provider
|
||||||
|
subjects:
|
||||||
|
- kind: ServiceAccount
|
||||||
|
name: persistent-volume-binder
|
||||||
|
namespace: kube-system
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolumeClaim
|
||||||
|
metadata:
|
||||||
|
name: ordersfiles
|
||||||
|
spec:
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteMany
|
||||||
|
storageClassName: azurefile
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: 5Gi
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: fulfillorder
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: fulfillorder
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: fulfillorder
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: fulfillorder
|
||||||
|
image: azch/fulfillorder
|
||||||
|
imagePullPolicy: Always
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
port: 8080
|
||||||
|
path: /healthz
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
port: 8080
|
||||||
|
path: /healthz
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
memory: "64Mi"
|
||||||
|
cpu: "100m"
|
||||||
|
limits:
|
||||||
|
memory: "128Mi"
|
||||||
|
cpu: "500m"
|
||||||
|
env:
|
||||||
|
- name: TEAMNAME
|
||||||
|
value: "team-azch"
|
||||||
|
- name: APPINSIGHTS_KEY
|
||||||
|
value: "5d44bbd0-87c0-4b73-8e35-e16a07583ba2"
|
||||||
|
- name: MONGOHOST
|
||||||
|
value: "akschallengecosmos.documents.azure.com"
|
||||||
|
- name: MONGOUSER
|
||||||
|
value: "akschallengecosmos"
|
||||||
|
- name: MONGOPASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: cosmosdb-connection
|
||||||
|
key: primarykey
|
||||||
|
ports:
|
||||||
|
- containerPort: 80
|
||||||
|
volumeMounts:
|
||||||
|
- mountPath: "/orders"
|
||||||
|
name: orders
|
||||||
|
volumes:
|
||||||
|
- name: orders
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: ordersfiles
|
||||||
|
---
|
||||||
|
apiVersion: autoscaling/v1
|
||||||
|
kind: HorizontalPodAutoscaler
|
||||||
|
metadata:
|
||||||
|
name: fulfillorder
|
||||||
|
spec:
|
||||||
|
scaleTargetRef:
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
name: fulfillorder
|
||||||
|
minReplicas: 4
|
||||||
|
maxReplicas: 10
|
||||||
|
targetCPUUtilizationPercentage: 50
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: fulfillorder
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: fulfillorder
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 80
|
||||||
|
targetPort: 8080
|
||||||
|
type: ClusterIP
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: eventlistener
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: eventlistener
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: eventlistener
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: eventlistener
|
||||||
|
image: azch/sblistener
|
||||||
|
imagePullPolicy: Always
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
memory: "64Mi"
|
||||||
|
cpu: "100m"
|
||||||
|
limits:
|
||||||
|
memory: "128Mi"
|
||||||
|
cpu: "500m"
|
||||||
|
env:
|
||||||
|
- name: TEAMNAME
|
||||||
|
value: "team-azch"
|
||||||
|
- name: APPINSIGHTS_KEY
|
||||||
|
value: "5d44bbd0-87c0-4b73-8e35-e16a07583ba2"
|
||||||
|
- name: SERVICEBUSCONNSTRING
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: service-bus-connection
|
||||||
|
key: sb-endpoint
|
||||||
|
- name: PROCESSENDPOINT
|
||||||
|
value: "http://fulfillorder.default.svc.cluster.local/v1/order/"
|
||||||
|
---
|
||||||
|
apiVersion: autoscaling/v1
|
||||||
|
kind: HorizontalPodAutoscaler
|
||||||
|
metadata:
|
||||||
|
name: eventlistener
|
||||||
|
spec:
|
||||||
|
scaleTargetRef:
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
name: eventlistener
|
||||||
|
minReplicas: 3
|
||||||
|
maxReplicas: 10
|
||||||
|
targetCPUUtilizationPercentage: 30
|
|
@ -0,0 +1,259 @@
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: captureorder
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: captureorder
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: captureorder
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: captureorder
|
||||||
|
image: akschallengeregistry.azurecr.io/captureorder
|
||||||
|
imagePullPolicy: Always
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
port: 8080
|
||||||
|
path: /healthz
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
port: 8080
|
||||||
|
path: /healthz
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
memory: "64Mi"
|
||||||
|
cpu: "100m"
|
||||||
|
limits:
|
||||||
|
memory: "128Mi"
|
||||||
|
cpu: "500m"
|
||||||
|
env:
|
||||||
|
- name: TEAMNAME
|
||||||
|
value: "team-azch"
|
||||||
|
- name: APPINSIGHTS_KEY
|
||||||
|
value: "5d44bbd0-87c0-4b73-8e35-e16a07583ba2"
|
||||||
|
- name: AMQPURL
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: service-bus-connection
|
||||||
|
key: amqp-url
|
||||||
|
- name: MONGOHOST
|
||||||
|
value: "akschallengecosmos.documents.azure.com"
|
||||||
|
- name: MONGOUSER
|
||||||
|
value: "akschallengecosmos"
|
||||||
|
- name: MONGOPASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: cosmosdb-connection
|
||||||
|
key: primarykey
|
||||||
|
ports:
|
||||||
|
- containerPort: 80
|
||||||
|
---
|
||||||
|
apiVersion: autoscaling/v1
|
||||||
|
kind: HorizontalPodAutoscaler
|
||||||
|
metadata:
|
||||||
|
name: captureorder
|
||||||
|
spec:
|
||||||
|
scaleTargetRef:
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
name: captureorder
|
||||||
|
minReplicas: 4
|
||||||
|
maxReplicas: 10
|
||||||
|
targetCPUUtilizationPercentage: 50
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: captureorder
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: captureorder
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 80
|
||||||
|
targetPort: 8080
|
||||||
|
type: LoadBalancer
|
||||||
|
---
|
||||||
|
apiVersion: storage.k8s.io/v1
|
||||||
|
kind: StorageClass
|
||||||
|
metadata:
|
||||||
|
name: azurefile
|
||||||
|
provisioner: kubernetes.io/azure-file
|
||||||
|
mountOptions:
|
||||||
|
- dir_mode=0777
|
||||||
|
- file_mode=0777
|
||||||
|
- uid=1000
|
||||||
|
- gid=1000
|
||||||
|
parameters:
|
||||||
|
skuName: Standard_LRS
|
||||||
|
storageAccount: akschallenge
|
||||||
|
---
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: ClusterRole
|
||||||
|
metadata:
|
||||||
|
name: system:azure-cloud-provider
|
||||||
|
rules:
|
||||||
|
- apiGroups: [""]
|
||||||
|
resources: ["secrets"]
|
||||||
|
verbs: ["get", "create"]
|
||||||
|
---
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: ClusterRoleBinding
|
||||||
|
metadata:
|
||||||
|
name: system:azure-cloud-provider
|
||||||
|
roleRef:
|
||||||
|
kind: ClusterRole
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
||||||
|
name: system:azure-cloud-provider
|
||||||
|
subjects:
|
||||||
|
- kind: ServiceAccount
|
||||||
|
name: persistent-volume-binder
|
||||||
|
namespace: kube-system
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolumeClaim
|
||||||
|
metadata:
|
||||||
|
name: ordersfiles
|
||||||
|
spec:
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteMany
|
||||||
|
storageClassName: azurefile
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: 5Gi
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: fulfillorder
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: fulfillorder
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: fulfillorder
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: fulfillorder
|
||||||
|
image: akschallengeregistry.azurecr.io/fulfillorder
|
||||||
|
imagePullPolicy: Always
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
port: 8080
|
||||||
|
path: /healthz
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
port: 8080
|
||||||
|
path: /healthz
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
memory: "64Mi"
|
||||||
|
cpu: "100m"
|
||||||
|
limits:
|
||||||
|
memory: "128Mi"
|
||||||
|
cpu: "500m"
|
||||||
|
env:
|
||||||
|
- name: TEAMNAME
|
||||||
|
value: "team-azch"
|
||||||
|
- name: APPINSIGHTS_KEY
|
||||||
|
value: "5d44bbd0-87c0-4b73-8e35-e16a07583ba2"
|
||||||
|
- name: MONGOHOST
|
||||||
|
value: "akschallengecosmos.documents.azure.com"
|
||||||
|
- name: MONGOUSER
|
||||||
|
value: "akschallengecosmos"
|
||||||
|
- name: MONGOPASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: cosmosdb-connection
|
||||||
|
key: primarykey
|
||||||
|
ports:
|
||||||
|
- containerPort: 80
|
||||||
|
volumeMounts:
|
||||||
|
- mountPath: "/orders"
|
||||||
|
name: orders
|
||||||
|
volumes:
|
||||||
|
- name: orders
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: ordersfiles
|
||||||
|
---
|
||||||
|
apiVersion: autoscaling/v1
|
||||||
|
kind: HorizontalPodAutoscaler
|
||||||
|
metadata:
|
||||||
|
name: fulfillorder
|
||||||
|
spec:
|
||||||
|
scaleTargetRef:
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
name: fulfillorder
|
||||||
|
minReplicas: 4
|
||||||
|
maxReplicas: 10
|
||||||
|
targetCPUUtilizationPercentage: 50
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: fulfillorder
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: fulfillorder
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 80
|
||||||
|
targetPort: 8080
|
||||||
|
type: ClusterIP
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: eventlistener
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: eventlistener
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: eventlistener
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: eventlistener
|
||||||
|
image: akschallengeregistry.azurecr.io/sblistener
|
||||||
|
imagePullPolicy: Always
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
memory: "64Mi"
|
||||||
|
cpu: "100m"
|
||||||
|
limits:
|
||||||
|
memory: "128Mi"
|
||||||
|
cpu: "500m"
|
||||||
|
env:
|
||||||
|
- name: TEAMNAME
|
||||||
|
value: "team-azch"
|
||||||
|
- name: APPINSIGHTS_KEY
|
||||||
|
value: "5d44bbd0-87c0-4b73-8e35-e16a07583ba2"
|
||||||
|
- name: SERVICEBUSCONNSTRING
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: service-bus-connection
|
||||||
|
key: sb-endpoint
|
||||||
|
- name: PROCESSENDPOINT
|
||||||
|
value: "http://fulfillorder.default.svc.cluster.local/v1/order/"
|
||||||
|
---
|
||||||
|
apiVersion: autoscaling/v1
|
||||||
|
kind: HorizontalPodAutoscaler
|
||||||
|
metadata:
|
||||||
|
name: eventlistener
|
||||||
|
spec:
|
||||||
|
scaleTargetRef:
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
name: eventlistener
|
||||||
|
minReplicas: 3
|
||||||
|
maxReplicas: 10
|
||||||
|
targetCPUUtilizationPercentage: 30
|
|
@ -0,0 +1,9 @@
|
||||||
|
pool:
|
||||||
|
vmImage: 'Ubuntu 16.04'
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- task: PublishBuildArtifacts@1
|
||||||
|
displayName: 'publish yaml folder as an artifact'
|
||||||
|
inputs:
|
||||||
|
artifactName: 'yaml'
|
||||||
|
pathToPublish: 'yaml'
|
|
@ -0,0 +1,16 @@
|
||||||
|
pool:
|
||||||
|
vmImage: 'Ubuntu 16.04'
|
||||||
|
|
||||||
|
variables:
|
||||||
|
imageName: 'captureorder:$(Build.BuildId)'
|
||||||
|
# define three more variables acrName, dockerId and dockerPassword in the build pipeline in UI
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- script: docker build -f Dockerfile -t $(acrName).azurecr.io/$(imageName) .
|
||||||
|
displayName: 'docker build'
|
||||||
|
|
||||||
|
- script: docker login -u $(dockerId) -p $(dockerPassword) $(acrName).azurecr.io
|
||||||
|
displayName: 'docker login'
|
||||||
|
|
||||||
|
- script: docker push $(acrName).azurecr.io/$(imageName)
|
||||||
|
displayName: 'docker push'
|
|
@ -0,0 +1,127 @@
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: captureorder
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: captureorder
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: captureorder
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: captureorder
|
||||||
|
image: akschallengeregistry.azurecr.io/captureorder:##BUILD_ID##
|
||||||
|
imagePullPolicy: Always
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
port: 8080
|
||||||
|
path: /healthz
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
port: 8080
|
||||||
|
path: /healthz
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
memory: "64Mi"
|
||||||
|
cpu: "100m"
|
||||||
|
limits:
|
||||||
|
memory: "128Mi"
|
||||||
|
cpu: "500m"
|
||||||
|
env:
|
||||||
|
- name: TEAMNAME
|
||||||
|
value: "team-azch"
|
||||||
|
- name: APPINSIGHTS_KEY
|
||||||
|
value: "5d44bbd0-87c0-4b73-8e35-e16a07583ba2"
|
||||||
|
- name: AMQPURL
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: service-bus-connection
|
||||||
|
key: amqp-url
|
||||||
|
- name: MONGOHOST
|
||||||
|
value: "akschallengecosmos.documents.azure.com"
|
||||||
|
- name: MONGOUSER
|
||||||
|
value: "akschallengecosmos"
|
||||||
|
- name: MONGOPASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: cosmosdb-connection
|
||||||
|
key: primarykey
|
||||||
|
ports:
|
||||||
|
- containerPort: 80
|
||||||
|
---
|
||||||
|
apiVersion: autoscaling/v1
|
||||||
|
kind: HorizontalPodAutoscaler
|
||||||
|
metadata:
|
||||||
|
name: captureorder
|
||||||
|
spec:
|
||||||
|
scaleTargetRef:
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
name: captureorder
|
||||||
|
minReplicas: 4
|
||||||
|
maxReplicas: 10
|
||||||
|
targetCPUUtilizationPercentage: 50
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: captureorder
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: captureorder
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 80
|
||||||
|
targetPort: 8080
|
||||||
|
type: LoadBalancer
|
||||||
|
---
|
||||||
|
apiVersion: storage.k8s.io/v1
|
||||||
|
kind: StorageClass
|
||||||
|
metadata:
|
||||||
|
name: azurefile
|
||||||
|
provisioner: kubernetes.io/azure-file
|
||||||
|
mountOptions:
|
||||||
|
- dir_mode=0777
|
||||||
|
- file_mode=0777
|
||||||
|
- uid=1000
|
||||||
|
- gid=1000
|
||||||
|
parameters:
|
||||||
|
skuName: Standard_LRS
|
||||||
|
storageAccount: akschallenge
|
||||||
|
---
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: ClusterRole
|
||||||
|
metadata:
|
||||||
|
name: system:azure-cloud-provider
|
||||||
|
rules:
|
||||||
|
- apiGroups: [""]
|
||||||
|
resources: ["secrets"]
|
||||||
|
verbs: ["get", "create"]
|
||||||
|
---
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: ClusterRoleBinding
|
||||||
|
metadata:
|
||||||
|
name: system:azure-cloud-provider
|
||||||
|
roleRef:
|
||||||
|
kind: ClusterRole
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
||||||
|
name: system:azure-cloud-provider
|
||||||
|
subjects:
|
||||||
|
- kind: ServiceAccount
|
||||||
|
name: persistent-volume-binder
|
||||||
|
namespace: kube-system
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolumeClaim
|
||||||
|
metadata:
|
||||||
|
name: ordersfiles
|
||||||
|
spec:
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteMany
|
||||||
|
storageClassName: azurefile
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: 5Gi
|
Загрузка…
Ссылка в новой задаче