Written by Michael Haigh, Technical Marketing Engineer at Nutanix
Enterprises are increasingly shifting towards cloud native applications as they’re simple to deploy and scale, they’re highly available, and they’re space and resource efficient. Cloud Native applications and the public clouds enable developers to focus on developing applications rather than dealing with the underlying infrastructure.
On the Nutanix Enterprise Cloud OS, these benefits are no longer restricted to the public cloud, as they’re now available in your private datacenter with Nutanix Cloud Native. Nutanix Cloud Native enables developers and administrators with the Freedom to Invent and the Freedom to Run their applications with the following products:
Nutanix Karbon – an enterprise-grade Kubernetes distribution that simplifies the provisioning, operations and lifecycle management of Kubernetes.
Nutanix Era – a database management solution that that automates the provisioning and protection of Postgres, MySQL, Oracle, and other databases.
Nutanix Buckets – an S3 compatible object storage solution.
Additionally, all of these products are fully compatible with the public clouds, meaning no code or workflow changes are required.
In this blog post we’ll see how a developer or IT admin can quickly and easily deploy a cloud native application with Nutanix Cloud Native. If you’d like to follow along in your own environment, you’ll need the above products set up. For any that you do not have, please see:
Nutanix Karbon is in General Availability (GA) in Prism Central 5.10.1, please see our portal documentation for instructions on how to enable Karbon and quickly deploy a production ready Kubernetes cluster.
Nutanix Era is General Availability (GA), please see our portal documentation for information on how to get started.
Nutanix Buckets is currently Early Access, please reach out to your local Nutanix SE if you’re interested in trying it out.
The application we’ll be deploying today is a containerized version of Oscar, which is a popular e-commerce framework for Django. Here’s the overall architecture of the application:
Nutanix Karbon is the lifecycle manager of our Certified Kubernetes cluster, which in turn orchestrates our container based web application. Since containers are ephemeral, we’ll use Nutanix Buckets to store static images, and an Era provisioned database to store all other application data. Let’s get started!
To store our web application’s data, we’ll be using a PostgreSQL database that’s provisioned and managed by Nutanix Era. If you haven’t done so already, log in to your Era UI. Select the Dashboard dropdown in the upper left, and then select Databases. On that page that appears, click the blue + Provision button:
In the pop-up, select PostgreSQL and then click Next.
On the second page titled Database Server, select Create New Server and fill out the rest of the fields. The name and description fields can be anything meaningful to you. For the profile fields, you can select the sample profiles, or you can define your own under the Profiles section of Era. The SSH public key will be used in the event you need to SSH into the database VM. You can select the public key of your primary workstation, or generate and output one with the following commands:
Your screen should look something like this after all fields are completed:
Click Next. On the Database page, fill out the Name, Description, and Password fields to your liking. If you specify the name as oscar_django and password as Nutanix/4u! then there will be fewer fields to configure in the Kubernetes YAML files later, but this is not required. For the Profile field, either select the sample, or configure your own under Era > Profiles.
Leave the rest of the fields as default, and your page should look something like this:
Click Next. On the Time Machine page, add a Description, and fill out your database’s time machine SLA and schedule, or leave the defaults. For a production database, these fields would be governed by your business requirements.
Click Provision. You should see a blue banner appear at the top of the page, click on it to see the status of your database provisioning. The entire process should take under 10 minutes.
In your Prism Central instance where you have Nutanix Buckets deployed, navigate to Explore > Nutanix Buckets, and then select your Object Store.
On the page that appears, click the blue Create Bucket button. In the UI that appears, name your bucket, if you choose oscarstatic, there will be fewer configuration steps later when modifying the Kubernetes YAML files, but this is not required.
For the Object Versions and Lifecycle Policies, you’re welcome to choose whatever makes sense for your environment.
Click Create. You should see your bucket appear in the UI.
Ensure you have a Karbon Kubernetes cluster deployed, and you’re able to manage via kubectl. If you do not, please see our Nutanix Karbon Guide by going here, and selecting ‘Karbon’ from the Software Type dropdown.
From your workstation of choice, create three folders:
In each of these folders, we’ll be creating a number of Kubernetes YAML files that define our application. For each file outlined below, you’ll want to create a corresponding file in the specified directory. On some of them, we’ll call out certain fields that you’ll want to replace entries to match your environment.
First, in your buckets folder, create a file name buckets-secrets.yaml with the following contents:
This defines a set of credentials that our Oscar web application will use to PUT images into our Nutanix Buckets object storage. You’ll want to change the data: access and the data: secret fields to match your environment. These fields should be base64 encoded, so if your secret was MyBucketsSecret, you’d substitute TXlCdWNrZXRzU2VjcmV0:
Like the previous file, this defines a set of credentials that our Oscar web application will use to access our Era provisioned database. The data: user field should be left alone, as that is the base64 encoded value of our user, postgres. If you used a password of Nutanix/4u! in the previous step when provisioning a Postgres Database with Era, then you can leave the data: password field as is. If you used a custom password, base64 encode it as shown above, and substitute it in.
The second era file should be called era-service.yaml:
This file defines a kubernetes Service, of type ExternalName. This allows kubernetes objects to access an external service at the specified IP or hostname. You’ll want to substitute in the IP of your Era deployed database from the beginning of this guide. To find your IP, log in to the Era UI, and navigate to Databases > Sources. The IP is listed in the description column of the table presented.
In our django folder we’ll be creating four files and each of them will be described in details below.
Our first file is django-configmap.yaml:
ConfigMaps allow us to bind configuration settings to our containers at runtime, which makes our Oscar container image more portable. Without this ConfigMap, the above values would be set to their hardcoded value within the docker image, making the image just about useless for other environments.
At minimum, you’ll need to change the data: S3_ENDPOINT_URL field to match your Nutanix Buckets endpoint URL. If you’re not sure of your endpoint URL, you can find it in Prism Central > Explore > Nutanix Buckets.
If you used custom bucket and database names in the steps above, then you’ll need to change those fields as well. If not, then leave them as is.
Our second file is named django-deployment.yaml:
While this file can be left exactly as is, let’s go over it in a bit more detail:
The kind is a Deployment, which is a Kubernetes Controller that defines a set of Pods.
The replicas key indicates how many pods (which generally, but not always, contain a single container) to spin up.
The metadata labels allow us to tie in other Kubernetes objects, which will come in to play in an upcoming file
The containers name, image, and ports keys specify what we should name our pods once deployed, the image source of the container (stored on Docker Hub), and the port that the containers communicate on.
The env section contains many entries that should look familiar:
Our Era database user and password, which is sourced from our era-secrets.yaml file (named postgres-credentials).
Our Era database host, which is sourced from our era-service.yaml file (named postgres-service).
Our Nutanix Buckets Object Storage access and secret access keys, which is sourced from our buckets-secrets.yaml file (named object-credentials).
The envFrom entry ties in the django-configmap.yaml ConfigMap from the previous step to set the necessary environment variables in our application to our runtime values.
The third file in this folder is named django-migration.yaml:
You should notice that this file looks quite similar to the previous. The key difference is that this is a Kubernetes Job rather than a Deployment. Jobs create one or more pods to complete a particular task, and once that task is completed, the pods are cleaned up. In our app, this task is to seed the Postgres database and object storage with our sandbox data. Without that, we would have an empty, boring application. No modifications are needed to this file.
The fourth (and final) file of our application is named django-service.yaml:
This file creates a Kubernetes Service, of type NodePort, which means it exposes a particular port (8000 in our case) externally from the Kubernetes cluster. The selector field connects this service to our django web app pods that are deployed via our django-deployment.yaml file. This will be what allows us to access the app from a web browser once we have a running application. In a future blog post, we’ll see how we can improve upon the NodePort Service with a Kubernetes Ingress Controller.
We’re now ready to deploy our application. To do so, simply run the following three kubectl commands: