{"id":87987,"date":"2020-09-01T20:36:13","date_gmt":"2020-09-01T20:36:13","guid":{"rendered":"https:\/\/www.red-gate.com\/simple-talk\/?p=87987"},"modified":"2022-04-24T21:26:27","modified_gmt":"2022-04-24T21:26:27","slug":"running-container-workloads-in-microsoft-azure","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/devops\/containers-and-virtualization\/running-container-workloads-in-microsoft-azure\/","title":{"rendered":"Running Container Workloads in Microsoft Azure"},"content":{"rendered":"<p>In the past decade, the software development processes and application and infrastructure architectures and technologies have gone through many innovations and changes. Organizations that started with on-premises data centers have moved to hardware virtualization, private and public clouds, containers, and now serverless applications. With this transition, many organizations are moving away from the monolithic architectures to microservices and serverless models. This article focuses on running container workloads in Microsoft Azure.<\/p>\n<h2>Brief background about containers<\/h2>\n<p>After hardware virtualization became commonplace, the question was raised about how much faster and more efficient application development and deployment could be made. The container was an obvious solution. A container is a virtualization on top of the operating system layer. Containers do not need to boot up another operating system to run an application. All you need is your application code and its dependent libraries packaged into a single image. The important advantage of containers is that you do not need to boot up another operating system with all the software packages needed for your application on top of the host machine.<\/p>\n<p>Figure 1 shows the virtualization of containers:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"860\" height=\"436\" class=\"wp-image-87988\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/09\/word-image.png\" \/><\/p>\n<p><strong>Figure 1<\/strong><\/p>\n<h2>Microsoft Azure\u2019s Options to run the container workloads<\/h2>\n<p>Microsoft Azure provides many options to build the container infrastructure and run the container applications quickly. Here is a list of the container services offered by Microsoft Azure:<\/p>\n<ul>\n<li>Azure Container Instances<\/li>\n<li>Azure Kubernetes Service (AKS)<\/li>\n<li>Azure Batch<\/li>\n<li>Azure Service Fabric<\/li>\n<li>Azure Functions<\/li>\n<li>Azure App Service<\/li>\n<\/ul>\n<p>This article focuses on Azure Container Instances (ACI) and Azure Kubernetes Services (AKS).<\/p>\n<h2>Azure Cloud Shell<\/h2>\n<p>Before starting to explore containers in Azure, I\u2019ll provide some brief detail about the Cloud Shell. The Cloud Shell is a browser-accessible interactive shell. It automatically authenticates you once you login to the Azure Portal and launch it. You can choose between Bash and PowerShell. All the required packages are already installed, so you do not need to go through the struggle of installing the Azure command-line tools and packages on your local machine. To access Cloud Shell, click on the Cloud Shell icon after you log in to the Azure Portal, as shown in Figure 2.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1282\" height=\"386\" class=\"wp-image-87989\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/09\/word-image-1.png\" \/><\/p>\n<p><strong>Figure 2<\/strong><\/p>\n<p>You could also open the full cloud shell window by accessing <a href=\"https:\/\/shell.azure.com\/\">https:\/\/shell.azure.com\/<\/a>. You can use both Azure Command-Line Interface (CLI) or Azure PowerShell. This article uses <a href=\"https:\/\/docs.microsoft.com\/en-us\/cli\/azure\/reference-index?view=azure-cli-latest\">CLI commands<\/a> throughout.<\/p>\n<p>If you have multiple subscriptions, you may want to ensure you are in the correct one. Use this command to see the default Azure subscription:<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">$az account show<\/pre>\n<p>Use this command to change subscriptions:<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">$az account set --subscription 'my azure subscription or ID'<\/pre>\n<h2>Azure Container Registry<\/h2>\n<p>Before moving on to discuss the container services in Azure, you should understand the Azure Container Registry (ACR). The Azure Container Registry is the private registry used to store the docker images which gets deployed to your environment. This is built based on the open-source Docker Registry 2.0. The Docker images can be pushed to the Container Registry as part of the development workflow (CICD Pipeline). It is secure, and the access can be controlled by service principal and role-based access control (RBAC). It supports both Windows and Linux images. Azure Container Registry Tasks can be used to streamline the CICD pipeline. The typical CI workflow can be described, as shown in Figure 3.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"770\" height=\"373\" class=\"wp-image-87990\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/09\/word-image-2.png\" \/><\/p>\n<p><strong> Figure 3<\/strong><\/p>\n<p>Apart from Azure Container Registry, you can also use the Docker Hub as your container repository. In the enterprise level, using the private container registry service offered by the cloud provider is preferred considering factors like security, easy administration, and cost management. As the goal of this article is to explain the container services offered by Azure, I am going to use the Docker images available in the Docker Hub public repository.<\/p>\n<h2>Azure Container Instances<\/h2>\n<p>Azure container instances are suitable to run isolated containers for use cases like simple applications, task automation and build jobs. Full container orchestration is not possible with Azure Container Instances. However, creating a multi-container group is still possible. That means your main application container can be combined with other supporting containers like logging or monitoring containers. This is achieved by sharing the host machine, local network, and storage.<\/p>\n<h3>Container Instance Deployment<\/h3>\n<p>You can create the Container instances through the Command Line Interface, Azure Portal, PowerShell, or Azure Resource Manager (ARM) templates. Choosing the appropriate deployment method depends on your CICD pipeline requirements. PowerShell, ARM templates, or Terraform would be preferable methods to achieve full automation. An ARM template is nothing more than the JSON file that defines the infrastructure and configuration for your Azure resources. It uses declarative syntax. The deployment process to create the container instances and deploy the images can be described as shown below in Figure 4.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"922\" height=\"631\" class=\"wp-image-87991\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/09\/word-image-3.png\" \/><\/p>\n<p><strong>Figure 4<\/strong><\/p>\n<h4>Create and run a container instance<\/h4>\n<p>The first step is to create a resource group. All the resources created in this article will be assigned to this resource group named <em>mycontainerrg<\/em>.<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">$az group create --name mycontainerrg --location westus<\/pre>\n<p>If running the above command is successful, you should see the below output and the new resource-group should be created.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"660\" height=\"201\" class=\"wp-image-87992\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/09\/word-image-4.png\" \/><\/p>\n<p>Now create the container instance. In this example, you deploy the container instances which creates the public IP address with DNS name and allows access to the container from the internet. As I mentioned before, you can use images either from the Docker Hub or from the Azure container registry. If you do not mention the full link for the Azure container registry, it pulls the images from the Docker Hub. On the other hand, if you would like to use an image from your private Azure container registry, you should use a value for the \u201c&#8211;image\u201d option that will be something like \u201c$FQDN-FOR-AZURE-CONTAINER-REGISTORY\/$repositoryname:$tag\u201d (Example &#8211; mycontrreg01.azurecr.io\/mynginximage\/nginx:v1).<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">$az container create --resource-group mycontainerrg --name mynginxv1 --image dockdemorepo\/myacirepo:nginx-helloworld --ports 80 --dns-name-label mynginxv1 --location westus\r\n# The value for \u2013dns-name-label should be unique. If the name you are trying is taken by someone else in the same location (westus), it will error out. <\/pre>\n<p>&nbsp;<\/p>\n<p>Once the container is successfully created, you should see the below output \u2013<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1662\" height=\"853\" class=\"wp-image-87993\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/09\/word-image-5.png\" \/><\/p>\n<p>To start and stop the container, you can use the below commands<\/p>\n<pre class=\"lang:ps theme:powershell-ise \">$az container stop --name mynginxv1 --resource-group mycontainerrg\r\n$az container start --name mynginxv1 --resource-group mycontainerrg<\/pre>\n<p>To view the container-related logs, you can use this command:<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">$az container logs --name mynginxv1 --resource-group mycontainerrg<\/pre>\n<p>To execute the shell commands inside the container, you can use the command below:<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">az container exec --exec-command \/bin\/bash --container-name mynginxv1 --resource-group mycontainerrg --name mynginxv1<\/pre>\n<p>You can access the web page served by the NGINX by using the FQDN provided in the container creation output.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"591\" height=\"89\" class=\"wp-image-87994\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/09\/word-image-6.png\" \/><\/p>\n<p>The page should look like Figure 5.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1486\" height=\"282\" class=\"wp-image-87995\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/09\/word-image-7.png\" \/><\/p>\n<p><strong>Figure 5<\/strong><\/p>\n<h4>Container Group<\/h4>\n<p>An Azure container group provides the capability to run multiple containers on the same host machine. All the containers in the container group share the resources, network, and storage volumes, and Azure supports two methods of container groups.<\/p>\n<p>You can create multiple containers in the container group, and those containers can connect to each other using the localhost and the ports each container listens. One container port can be exposed to the internet through public IP address and DNS name. However, this does not serve the purpose of multi-service architectures. In other words, you cannot deploy mass production workloads with hundreds of services connecting each other.<\/p>\n<p>The second method is to create multiple containers on the Azure virtual network, but there are limitations on this, too. Only Linux containers are supported, and Windows is not yet supported. The next limitation is that these containers cannot be accessed through the internet. They neither allow assigning a public IP address nor placing the load balancers in front of the containers (It is a limitation from load balancers). The last one is that global virtual network peering is not possible, which limits the container access to only within the virtual network.<\/p>\n<p>In this section, you\u2019ll create a container group with two containers running on two different ports that connect to each other. This is method 1 mentioned above. Figure 6 shows the architecture diagram describing the configuration.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"950\" height=\"475\" class=\"wp-image-87996\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/09\/word-image-8.png\" \/><\/p>\n<p><strong>Figure 6<\/strong><\/p>\n<p>The container groups can be created using two methods.<\/p>\n<ol>\n<li>Azure Resource Manager Template<\/li>\n<li>Yaml file<\/li>\n<\/ol>\n<p>This example uses the yaml method to create the container group. The easiest way is to export the existing container configuration to the yaml file and update that yaml file with the extra container configuration.<\/p>\n<p>Below is the command to export the existing containers yaml file. It exports the configuration of the container instance (mynginxv1) created in the previous section of this article.<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">$az container export --output yaml --name mynginxv1 --resource-group mycontainerrg --file mynginxv1.yaml<\/pre>\n<p>The above command should create a file named \u201cmynginxv1.yml\u201d.<\/p>\n<p>Now edit the yaml file created in step 3 and add the new container\u2019s configuration. I highlighted the changes below (See the image after the code for the changes). You can use any editors which you are familiar with. I used vi editor to edit the yaml file.<\/p>\n<pre class=\"theme:powershell-ise lang:ps decode:true \">additional_properties: {}\r\napiVersion: '2018-10-01'\r\nidentity: null\r\nlocation: westus\r\nname: mynginxv1\r\nproperties:\r\n  containers:\r\n  - name: mynginxv1\r\n    properties:\r\n      environmentVariables: []\r\n      image: dockdemorepo\/myacirepo:nginx-acg\r\n      ports:\r\n      # Port 80 is NGINX container\u2019s port. Port 8081 is springboot App\u2019s Port. \r\n      - port: 80\r\n      - port: 8081\r\n      resources:\r\n        requests:\r\n          cpu: 1.0\r\n          memoryInGB: 1.5\r\n  - name: myspringbootappv1\r\n    properties:\r\n      environmentVariables: []\r\n      image: dockdemorepo\/myacirepo:myappv1\r\n      resources:\r\n        requests:\r\n          cpu: 1.0\r\n          memoryInGB: 1.5\r\n  ipAddress:\r\n    dnsNameLabel: mynginxv1\r\n    #fqdn: mynginxv1.westus.azurecontainer.io\r\n    #ip: 40.81.4.187\r\n    ports:\r\n    - port: 80\r\n      protocol: TCP\r\n    type: Public\r\n  osType: Linux\r\n  restartPolicy: Always\r\ntags: {}\r\ntype: Microsoft.ContainerInstance\/containerGroups\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-88052\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/09\/yamlimage.jpg\" alt=\"\" width=\"623\" height=\"747\" \/><\/p>\n<p>\n<\/p>\n<p>Before creating the container group, be sure to delete the container you created in the previous section using this command:<\/p>\n<pre class=\"theme:powershell-ise lang:ps decode:true \">az container delete --name mynginxv1 --resource-group mycontainerrg<\/pre>\n<p>The next step is to create the container group using the below command.<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">az container create --resource-group mycontainerrg --file mynginxv1.yaml<\/pre>\n<p>The containers creation can be verified through the Azure Portal, as shown in Figures 7 and 8.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1057\" height=\"578\" class=\"wp-image-87997\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/09\/word-image-9.png\" \/><\/p>\n<p><strong>Figure 7<\/strong><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1345\" height=\"610\" class=\"wp-image-87998\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/09\/word-image-10.png\" \/><\/p>\n<p><strong>Figure 8<br \/>\n<\/strong><\/p>\n<p>You can access both these container\u2019s as shown in Figure 9 and Figure 10.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1233\" height=\"495\" class=\"wp-image-87999\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/09\/word-image-11.png\" \/><\/p>\n<p><strong>Figure 9<\/strong><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1224\" height=\"382\" class=\"wp-image-88000\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/09\/word-image-12.png\" \/><\/p>\n<p><strong>Figure 10<\/strong><\/p>\n<p>As shown in the previous pictures, you can see that both container\u2019s IPs are the same, and that confirm multiple containers can be run on the same container instance and can connect to each other.<\/p>\n<h2>Azure Kubernetes Service (AKS)<\/h2>\n<p>Azure Kubernetes Service (AKS) offers managed Kubernetes services. It enables easy deployment and management of Kubernetes clusters in Azure. Azure handles the monitoring and maintenance of the Kubernetes clusters for you. The Kubernetes master nodes are managed by Azure and leave the management of worker nodes to you. The Kubernetes service itself is free, and you pay only for the worker nodes that run the PODs ( In Kubernetes, a POD is a group of one or more containers). The Azure cluster can be created through the CLI, Resource Manager templates\/Terraform or through Azure Portal.<\/p>\n<p>Azure Kubernetes Service is suitable to run production container workloads which demand the full orchestration capabilities like scheduling, failover, service discovery, scaling, health monitoring, advanced networking\/routing, security, and easy application upgrades. Azure Kubernetes service supports both Linux and Windows containers.<\/p>\n<p>To learn more, next you\u2019ll create a Kubernetes cluster and deploy the same docker image built earlier (which was deployed to Azure Container Instances) to the AKS cluster. This example uses Azure CLI to create the cluster and deploy the application.<\/p>\n<h3>Create an Azure Kubernetes Cluster with 3 Nodes<\/h3>\n<pre class=\"lang:ps theme:powershell-ise\">$az aks create --resource-group mycontainerrg --name myakscluster01 --node-count 3 --generate-ssh-keys --enable-addons http_application_routing<\/pre>\n<p><a href=\"https:\/\/github.com\/Azure\/azure-cli-extensions\/issues\/1187\">https:\/\/github.com\/Azure\/azure-cli-extensions\/issues\/1187<\/a><\/p>\n<p>If the above command is successful, you should see the below output and successful cluster creation.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1524\" height=\"492\" class=\"wp-image-88001\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/09\/word-image-13.png\" \/><\/p>\n<p>Please note \u2013 I ran into the below error, and the reason is the azure AKS CLI version. The Azure CLI on my cloud-shell had the bug related to this error. So, I had to add the \u201caks-preview\u201d extension to resolve the error.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1662\" height=\"64\" class=\"wp-image-88002\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/09\/word-image-14.png\" \/><\/p>\n<p>You can add the aks-preview extension by using the below command<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">$ az extension add --name aks-preview<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"743\" height=\"65\" class=\"wp-image-88003\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/09\/word-image-15.png\" \/><\/p>\n<p>You can list the extensions by using the below command<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">$ az extension list<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"889\" height=\"327\" class=\"wp-image-88004\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/09\/word-image-16.png\" \/><\/p>\n<p>After creating the cluster, execute the following command to configure the kubectl on your cloud-shell (Or if you are running from your local machine).<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">$az aks get-credentials --resource-group mycontainerrg --name myakscluster01<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"964\" height=\"156\" class=\"wp-image-88005\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/09\/word-image-17.png\" \/><\/p>\n<p>Now, create a new namespace for the application to deploy. Namespaces are used in environments with many users spread across multiple teams or projects. It is used to logically group the cluster resources in Kubernetes.<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">$kubectl create namespace mynginxapp<\/pre>\n<p>You can set this namespace in the kubectl config level so that all the future kubectl commands will execute under this namespace<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">$ kubectl config set-context \u2013-namespace=mynginxapp<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"644\" height=\"92\" class=\"wp-image-88006\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/09\/word-image-18.png\" \/><\/p>\n<p>Now, you can use the kubectl commands to interact and manage the Kubernetes cluster.<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">$ kubectl get nodes<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"626\" height=\"108\" class=\"wp-image-88007\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/09\/word-image-19.png\" \/><\/p>\n<p>Below are the commands to stop\/start the Worker nodes in the AKS cluster. The az vmss list command lists the Virtual Machine scale set information, and you can grab the resource group and vmss name from this output and use it in the next command<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">$az vmss list \r\n$az vmss stop --resource-group MC_MYCONTAINERRG_MYAKSCLUSTER01_WESTUS --name aks-nodepool1-35851458-vmss\r\n$az vmss start --resource-group MC_MYCONTAINERRG_MYAKSCLUSTER01_WESTUS --name aks-nodepool1-35851458-vmss<\/pre>\n<p>The next step is to deploy the application to Kubernetes cluster. The first step is to create the deployment yaml file and then apply that yaml to the Kubernetes cluster using kubectl command. The POD deployment flow can be described as shown below (Figure 11)<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"916\" height=\"591\" class=\"wp-image-88008\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/09\/word-image-20.png\" \/><\/p>\n<p>Figure 11<\/p>\n<p>The diagram if Figure 12 describes the architecture pattern of the application.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1239\" height=\"624\" class=\"wp-image-88009\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/09\/word-image-21.png\" \/><\/p>\n<p>Figure 12<\/p>\n<p>The yaml file below (save it as mynginxapp01.yaml) is used to deploy the application to the Kubernetes, Create the Cluster IP, and to Create the Ingress Service to enable the external access to the application. Before saving the file, look for the Host value. Replace part of the value by looking for HTTApplicationRoutingZoneName (i.e., <strong><em>c2dc921a42db48bcbab4.westus.aksapp.io)<\/em><\/strong> from the output of the cluster creation. You can also execute the command \u201c$az aks list\u201d, and that output should show this value.<\/p>\n<pre class=\"lang:none theme:none\">apiVersion: apps\/v1\r\nkind: Deployment\r\nmetadata:\r\n name: mynginx-deployment\r\nspec:\r\n selector:\r\n   matchLabels:\r\n     app: mynginxapp01\r\n replicas: 2\r\n template:\r\n   metadata:\r\n     labels:\r\n       app: mynginxapp01\r\n   spec:\r\n      containers:\r\n      # If you need to deploy multiple containers on the same POD, you can add the container configs below. This POD contains one container.  \r\n        - name: mycluster01\r\n          image: dockdemorepo\/myacirepo:nginx-helloworld \r\n          ports:\r\n          - containerPort: 80\r\n          resources:\r\n            requests:\r\n             cpu: 1\r\n             memory: 250Mi\r\n            limits:\r\n             cpu: 1\r\n             memory: 250Mi\r\n          livenessProbe:\r\n            httpGet:\r\n               path: \/myhtml.html\r\n               port: 80\r\n            initialDelaySeconds: 10\r\n            periodSeconds: 5\r\n          readinessProbe:\r\n            httpGet:\r\n               path: \/myhtml.html\r\n               port: 80\r\n            initialDelaySeconds: 10\r\n            periodSeconds: 5\r\n---\r\napiVersion: v1\r\nkind: Service\r\nmetadata:\r\n  name: my-external-lb\r\nspec:\r\n ports:\r\n  - port: 80\r\n    protocol: TCP\r\n    targetPort: 80\r\n selector:\r\n   app: mynginxapp01\r\n type: ClusterIP\r\n---\r\napiVersion: extensions\/v1beta1\r\nkind: Ingress\r\nmetadata:\r\n  name: mynginxapp01\r\n  annotations:\r\n     kubernetes.io\/ingress.class: addon-http-application-routing\r\nspec:\r\n  rules:\r\n  - host: mynginxapp01.c2dc921a42db48bcbab4.westus.aksapp.io\r\n    http:\r\n      paths:\r\n      - backend:\r\n          serviceName: my-external-lb\r\n          servicePort: 80\r\n        path: \/<\/pre>\n<p>After creating this file, use the below command to create the Kubernetes resources.<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">$kubectl apply -f mynginxapp01.yaml<\/pre>\n<p>This command should create the resources listed below on your AKS cluster.<\/p>\n<ol>\n<li>Deploys 3 PODs<\/li>\n<li>Creates the ClusterIP service to route the traffic from Ingress Controller to the PODs.<\/li>\n<li>Ingress Controller Service.<\/li>\n<\/ol>\n<p>You can get the details of these resources using the below commands.<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">$kubectl get pods -o wide<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1443\" height=\"87\" class=\"wp-image-88010\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/09\/word-image-22.png\" \/><\/p>\n<pre class=\"lang:ps theme:powershell-ise\">$kubectl get services<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"664\" height=\"112\" class=\"wp-image-88011\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/09\/word-image-23.png\" \/><\/p>\n<pre class=\"lang:ps theme:powershell-ise\">$kubectl get ingress<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"935\" height=\"88\" class=\"wp-image-88012\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/09\/word-image-24.png\" \/><\/p>\n<p>Now, you can access the deployed application, as shown in Figure 13.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1475\" height=\"295\" class=\"wp-image-88013\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/09\/word-image-25.png\" \/><\/p>\n<p><a id=\"post-87987-_Ref48276809\"><\/a> Figure 13<\/p>\n<h3>Virtual Nodes<\/h3>\n<p>Azure provides the capability to extend the Kubernetes service into the container instance service through the Virtual Nodes. Using virtual nodes, you can quickly launch the PODs without spending extra effort to scale up or scale out your Kubernetes worker nodes (virtual machine scale sets). To enable this feature, you should use the advanced Kubernetes networking provided by Azure CNI. However, using virtual nodes has its own limitations:<\/p>\n<ul>\n<li>Host aliases cannot be used.<\/li>\n<li>Cannot deploy DaemonSets to the virtual nodes.<\/li>\n<li>Cannot use a service principal to pull ACR images. You must use Kubernetes secrets for this.<\/li>\n<\/ul>\n<h2>Summary<\/h2>\n<p>Azure container instances can be used to run light workloads and simple applications like build jobs or task automation. The mass production workloads with hundreds of services connecting to each other and developed and managed by a large number of service teams must choose the Azure Kubernetes service.<\/p>\n<p>This article walked you through creating both solutions using the Azure Cloud Shell and Azure CLI commands.<\/p>\n<h2>References<\/h2>\n<p><a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/containers\/\">https:\/\/docs.microsoft.com\/en-us\/azure\/containers\/<\/a><\/p>\n<p><a href=\"https:\/\/spring.io\/\">https:\/\/spring.io\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Containers are being used by more and more organizations to automate build pipelines in their CICD processes. In this article, Mahendran Purushothaman shows how to automate the creation of Docker containers and a Kubernetes cluster in Azure.&hellip;<\/p>\n","protected":false},"author":333672,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[137091,143513],"tags":[95506],"coauthors":[124088],"class_list":["post-87987","post","type-post","status-publish","format-standard","hentry","category-azure","category-containers-and-virtualization","tag-automate"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/87987","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/333672"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=87987"}],"version-history":[{"count":16,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/87987\/revisions"}],"predecessor-version":[{"id":88060,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/87987\/revisions\/88060"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=87987"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=87987"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=87987"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=87987"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}