Skip to content
Permalink
Browse files

Merge pull request #25 from microsoft/master

Pulling changes from master
  • Loading branch information...
sabbour committed Oct 10, 2019
2 parents 23947b4 + bcb404c commit f12e228432801f4725d94c3fd23ee4b778653ae4
@@ -5,7 +5,7 @@ title: Deploy Kubernetes with Azure Kubernetes Service (AKS)
parent-id: upandrunning
---

Azure has a managed Kubernetes service, AKS (Azure Kubernetes Service).
Azure has a managed Kubernetes service, AKS (Azure Kubernetes Service), we'll use this to easily deploy and standup a Kubernetes cluster.

### Tasks

@@ -35,9 +35,13 @@ az group create --name <resource-group> --location <region>

#### Create the AKS cluster

**Task Hints**
* It's recommended to use the Azure CLI and the `az aks create` command to deploy your cluster. Refer to the docs linked in the Resources section, or run `az aks create -h` for details
* The size and number of nodes in your cluster is not critical but two or more nodes of `DS2_v2` or larger is recommended

> **Note** You can create AKS clusters that support the [cluster autoscaler](https://docs.microsoft.com/en-us/azure/aks/cluster-autoscaler#about-the-cluster-autoscaler). However, please note that the AKS cluster autoscaler is a preview feature, and enabling it is a more involved process. AKS preview features are self-service and opt-in. Previews are provided to gather feedback and bugs from our community. However, they are not supported by Azure technical support. If you create a cluster, or add these features to existing clusters, that cluster is unsupported until the feature is no longer in preview and graduates to general availability (GA).
##### **Option 1:** Create an AKS cluster without the cluster autoscaler
##### **Option 1:** Create an AKS cluster without the cluster autoscaler (recommended)

> **Note** If you're using the provided lab environment, you'll not be able to create the Log Analytics workspace required to enable monitoring while creating the cluster from the Azure Portal unless you manually create the workspace in your assigned resource group.
@@ -61,30 +65,12 @@ az group create --name <resource-group> --location <region>
{% collapsible %}

AKS clusters that support the cluster autoscaler must use virtual machine scale sets and run Kubernetes version *1.12.4* or later. This scale set support is in preview. To opt in and create clusters that use scale sets, first install the *aks-preview* Azure CLI extension using the `az extension add` command, as shown in the following example:
AKS clusters that support the cluster autoscaler must use virtual machine scale sets and run Kubernetes version *1.12.4* or later. Cluster autoscaler support is in preview. To opt in and create clusters that use this feature, first install the *aks-preview* Azure CLI extension using the `az extension add` command, as shown in the following example:

```sh
az extension add --name aks-preview
```

To create an AKS cluster that uses scale sets, you must also enable a feature flag on your subscription. To register the *VMSSPreview* feature flag, use the `az feature register` command as shown in the following example:

```sh
az feature register --name VMSSPreview --namespace Microsoft.ContainerService
```

It takes a few minutes for the status to show *Registered*. You can check on the registration status using the `az feature list` command:

```sh
az feature list -o table --query "[?contains(name, 'Microsoft.ContainerService/VMSSPreview')].{Name:name,State:properties.state}"
```

When ready, refresh the registration of the *Microsoft.ContainerService* resource provider using the `az provider register` command:

```sh
az provider register --namespace Microsoft.ContainerService
```

Use the `az aks create` command specifying the `--enable-cluster-autoscaler` parameter, and a node `--min-count` and `--max-count`.

> **Note** During preview, you can't set a higher minimum node count than is currently set for the cluster. For example, if you currently have min count set to *1*, you can't update the min count to *3*.
@@ -95,7 +81,7 @@ az group create --name <resource-group> --location <region>
--location <region> \
--kubernetes-version $version \
--generate-ssh-keys \
--enable-vmss \
--vm-set-type VirtualMachineScaleSets \
--enable-cluster-autoscaler \
--min-count 1 \
--max-count 3
@@ -105,6 +91,12 @@ az group create --name <resource-group> --location <region>

#### Ensure you can connect to the cluster using `kubectl`

**Task Hints**
* `kubectl` is the main command line tool you will using for working with Kubernetes and AKS. It is already installed in the Azure Cloud Shell
* Refer to the AKS docs which includes [a guide for connecting kubectl to your cluster](https://docs.microsoft.com/en-us/azure/aks/kubernetes-walkthrough#connect-to-the-cluster) (Note. using the cloud shell you can skip the `install-cli` step).
* A good sanity check is listing all the nodes in your cluster `kubectl get nodes`.
* [This is a good cheat sheet](https://linuxacademy.com/site-content/uploads/2019/04/Kubernetes-Cheat-Sheet_07182019.pdf) for kubectl.

{% collapsible %}

> **Note** `kubectl`, the Kubernetes CLI, is already installed on the Azure Cloud Shell.
@@ -126,4 +118,6 @@ kubectl get nodes
> **Resources**
> * <https://docs.microsoft.com/en-us/azure/aks/kubernetes-walkthrough>
> * <https://docs.microsoft.com/en-us/cli/azure/aks?view=azure-cli-latest#az-aks-create>
> * <https://docs.microsoft.com/en-us/azure/aks/kubernetes-walkthrough-portal>
> * <https://docs.microsoft.com/en-us/azure/aks/kubernetes-walkthrough-portal>
> * <https://docs.microsoft.com/en-us/azure/aks/kubernetes-walkthrough#connect-to-the-cluster>
> * <https://linuxacademy.com/site-content/uploads/2019/04/Kubernetes-Cheat-Sheet_07182019.pdf>
@@ -8,24 +8,28 @@ 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 redeploy 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`.
**Task Hints**
* Use Helm and a standard provided Helm chart to deploy MongoDB.
* Be careful with the authentication settings when creating MongoDB. It is recommended that you create a standalone username/password. The username and password can be anything you like, but make a note of them for the next task.

> **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 redeploy 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
#### Setup Helm

> **Note** The application expects a database called `akschallenge`. Please DO NOT modify it.
Helm is an application package manager for Kubernetes, and way to easily deploy applications and services into Kubernetes, via what are called charts. To use Helm you will need the `helm` command (already installed in the Azure Cloud Shell), the Tiller component in your cluster which is created with the `helm init` command and a chart to deploy.

{% 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.
#### Initialize the Helm components on the AKS cluster

> **Note** Helm is installed on the Azure Cloud Shell.
**Task Hints**
* Refer to the AKS docs which includes [a guide for setting up Helm in your cluster](https://docs.microsoft.com/en-us/azure/aks/kubernetes-helm)
* You *will* have RBAC enabled in your AKS cluster, unless you specifically disabled it when creating it (very unlikely)
* You can ignore the instructions regarding TLS

##### Initialize the Helm components on the AKS cluster (RBAC enabled AKS cluster, default behaviour of CLI, optional behavior from the Azure Portal)
{% collapsible %}

If the cluster is RBAC enabled, you have to create the appropriate `ServiceAccount` for Tiller (the server side Helm component) to use.
Unless you specified otherwise your cluster will be RBAC enabled, so 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)

@@ -61,8 +65,21 @@ Initialize Tiller (omit the ``--service-account`` flag if your cluster is **not*
```sh
helm init --history-max 200 --service-account tiller --node-selectors "beta.kubernetes.io/os=linux"
```
{% endcollapsible %}


#### Deploy an instance of MongoDB to your cluster

Helm provides a standard repository of charts for many different software packages, and it has one for [MongoDB](https://github.com/helm/charts/tree/master/stable/mongodb) that is easily replicated and horizontally scalable.

##### Install the MongoDB Helm chart
**Task Hints**
* When installing a chart Helm uses a concept called a "release", and this release needs a name. You should give your release a name (using `--name`), it is strongly recommend you use `orders-mongo` as the name, as we'll need to refer to it later
* When deploying a chart you provide parameters with the `--set` switch and a comma separated list of `key=value` pairs. There are MANY parameters you can provide to the MongoDB chart, but pay attention to the `mongodbUsername`, `mongodbPassword` and `mongodbDatabase` parameters

> **Note** The application expects a database called `akschallenge`. Please DO NOT modify it.
{% collapsible %}
The recommended way to deploy MongoDB would be to use Helm.

After you have 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`**

@@ -78,20 +95,36 @@ You'll need to use the user created in the command above when configuring the de

#### Create a Kubernetes secret to hold the MongoDB details

In the previous step, you installed MongoDB using Helm, with a specified username, password and a hostname where the database is accessible. You'll now create a Kubernetes secret called `mongodb` to hold those details, so that you don't need to hard-code them in the YAML files.

In the previous step, you installed MongoDB using Helm, with a specified username, password and a hostname where the database is accessible. You'll now create a Kubernetes secret called mongodb to hold those details, so that you don't need to hard-code them in the YAML files.

**Task Hints**
* A Kubernetes secret can hold several items, indexed by key. The name of the secret isn't critical, but you'll need three keys stored your secret:
* `mongoHost`
* `mongoUser`
* `mongoPassword`
* The values for the username & password will be what you used on the `helm install` command when deploying MongoDB.
* Run `kubectl create secret generic -h` for help on how to create a secret, clue: use the `--from-literal` parameter to allow you to provide the secret values directly on the command in plain text.
* The value of `mongoHost`, will be dependant on the name of the MongoDB service. The service was created by the Helm chart and will start with the release name you gave. Run `kubectl get service` and you should see it listed, e.g. `orders-mongo-mongodb`
* All services in Kubernetes get DNS names, this is assigned automatically by Kubernetes, there's no need for you to configure it. You can use the short form which is simply the service name, e.g. `orders-mongo-mongodb` or better to use the "fully qualified" form `orders-mongo-mongodb.default.svc.cluster.local`

{% collapsible %}

```sh
kubectl create secret generic mongodb --from-literal=mongoHost="orders-mongo-mongodb.default.svc.cluster.local" --from-literal=mongoUser="orders-user" --from-literal=mongoPassword="orders-password"
```

> **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://www.digitalocean.com/community/tutorials/an-introduction-to-helm-the-package-manager-for-kubernetes>
> * <https://docs.microsoft.com/en-us/azure/aks/kubernetes-helm>
> * <https://github.com/helm/charts/tree/master/stable/mongodb#replication>
> * <https://helm.sh/docs/helm/#helm-install>
> * <https://github.com/helm/charts/tree/master/stable/mongodb>
> * <https://kubernetes.io/docs/concepts/configuration/secret/>
### Architecture Diagram
If you want a picture of how the system should look at the end of this challenge click below

<a href="media/architecture/mongo.png" target="_blank"><img src="media/architecture/mongo.png" style="width:500px"></a>
@@ -18,20 +18,27 @@ In the table below, you will find the Docker container images provided by the de

### Environment variables

The Order Capture API requires certain environment variables to properly run and track your progress. Make sure you set those environment variables.
The Order Capture API requires certain environment variables to properly run and track your progress. Make sure you set those environment variables in your deployment (you don't need to set these locally in your shell).

* `MONGOHOST="<hostname of mongodb>"`
* MongoDB hostname. Read from a Kubernetes secret called **mongodb**.
* MongoDB hostname. Read from the Kubernetes secret you created.
* `MONGOUSER="<mongodb username>"`
* MongoDB username. Read from a Kubernetes secret called **mongodb**.
* MongoDB username. Read from the Kubernetes secret you created.
* `MONGOPASSWORD="<mongodb password>"`
* MongoDB password. Read from a Kubernetes secret called **mongodb**.
* MongoDB password. Read from the Kubernetes secret you created.

> **Hint:** The Order Capture API exposes the following endpoint for health-checks once you have completed the tasks below: `http://[PublicEndpoint]:[port]/healthz`
### Tasks

#### Provision the `captureorder` deployment and expose a public endpoint
#### Provision the `captureorder` deployment

**Task Hints**
* Read the Kubernetes docs in the resources section below for details on how to create a deployment, you should create a YAML file and use the `kubectl apply -f` command to deploy it to your cluster
* You provide environmental variables to your container using the `env` key in your container spec. By using `valueFrom` and `secretRef` you can reference values stored in a Kubernetes secret (i.e. the one you created holding the MongoDB host, username and password)
* The container listens on port 8080
* If your pods are not starting, not ready or are crashing, you can view their logs using `kubectl logs <pod name>` and/or `kubectl describe pod <pod name>`
* Advanced: You can define a `readinessProbe` and `livenessProbe` using the `/healthz` endpoint exposed by the container and the port `8080`, this is optional

{% collapsible %}

@@ -109,6 +116,18 @@ Wait until you see pods are in the `Running` state.

> **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>`.
{% endcollapsible %}

#### Expose the `captureorder` deployment with a service

**Task Hints**
* Read the Kubernetes docs in the resources section below for details on how to create a service, you should create a YAML file and use the `kubectl apply -f` command to deploy it to your cluster
* Pay attention to the `port`, `targetPort` and the `selector`
* Kubernetes has several types of services (described in the docs), specified in the `type` field. You will need to create a service of type `LoadBlancer`
* The service should export port 80

{% collapsible %}

##### Service

Save the YAML below as `captureorder-service.yaml` or download it from [captureorder-service.yaml](yaml-solutions/01. challenge-02/captureorder-service.yaml)
@@ -146,6 +165,12 @@ kubectl get service captureorder -o jsonpath="{.status.loadBalancer.ingress[*].i

#### Ensure orders are successfully written to MongoDB

**Task Hints**
* The IP of your service will be publicly available on the internet
* The service has a Swagger/OpenAPI definition: `http://[Your Service Public LoadBalancer IP]/swagger`
* The service has an orders endpoint which accepts GET and POST: `http://[Your Service Public LoadBalancer IP]/v1/order`
* Orders take the form `{"EmailAddress": "email@domain.com", "Product": "prod-1", "Total": 100}` (The values are not validated)

{% collapsible %}

> **Hint:** You can test your deployed API either by using Postman or Swagger with the following endpoint : `http://[Your Service Public LoadBalancer IP]/swagger/`
@@ -170,4 +195,13 @@ You can expect the order ID returned by API once your order has been written int
> **Resources**
> * <https://kubernetes.io/docs/concepts/workloads/controllers/deployment/>
> * <https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/>
> * <https://kubernetes.io/docs/tasks/inject-data-application/distribute-credentials-secure/#define-container-environment-variables-using-secret-data>
> * <https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/>
> * <https://kubernetes.io/docs/concepts/services-networking/service/>
> * <https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#configuration-file>
### Architecture Diagram
If you want a picture of how the system should look at the end of this challenge click below

<a href="media/architecture/captureorder.png" target="_blank"><img src="media/architecture/captureorder.png" style="width:500px"></a>

0 comments on commit f12e228

Please sign in to comment.
You can’t perform that action at this time.