Archived | Deploy a simple Python application with Kubernetes

Archived content

Archive date: 2021-01-07

This content is no longer being updated or maintained. The content is provided “as is.” Given the rapid evolution of technology, some content, steps, or illustrations may have changed.

Want to try Kubernetes but don’t know where to start? The wealth of Kubernetes resources can make it difficult to find the basics for building and deploying an application to Kubernetes. In this tutorial, I simplify Kubernetes development and show you how to build a Python application with Docker and deploy it to a Kubernetes service.

Learning objectives

After completing this tutorial, you’ll be able to:

  • Containerize a Flask application by using Docker and deploy it to the IBM Cloud Kubernetes Service.


To complete this tutorial, you need the following prerequisites:

Estimated time

It should take around 45 minutes to complete this tutorial.


Create a Kubernetes cluster


  • Click Create Cluster.


  • Select the Region where you want to deploy the cluster, type in a name for your cluster, then click Create Cluster.
  • Select the appropriate cluster type depending on your account.
  • It takes some time for the cluster to get ready (around 30 minutes).


  • Once the cluster is ready, click on your cluster’s name and you will be redirected to a new page with information about your cluster and worker node.


  • Click on the Worker Nodes tab to note the cluster’s Public IP.


Containerize your Flask application

  • In your project directory, create a file named “Dockerfile.” Suggestion: Name your file exactly “Dockerfile,” nothing else.


A “Dockerfile” is used to indicate to Docker a base image, the Docker settings you need, and a list of commands you would like to have executed to prepare and start your new container.

  • In the file, paste this code:

      FROM python:2.7
      LABEL maintainer="Kunal Malhotra,"
      RUN apt-get update
      RUN mkdir /app
      WORKDIR /app
      COPY . /app
      RUN pip install -r requirements.txt
      EXPOSE 5000
      ENTRYPOINT [ "python" ]
      CMD [ "" ]

Explanation and breakdown of the above Dockerfile code

  1. The first part of the code above is:

     FROM python:2.7

    Because this Flask application uses Python 2.7, we want an environment that supports it and already has it installed. Fortunately, DockerHub has an official image that’s installed on top of Ubuntu. In one line, we will have a base Ubuntu image with Python 2.7, virtualenv, and pip. There are tons of images on DockerHub, but if you would like to start off with a fresh Ubuntu image and build on top of it, you could do that.

  2. Let’s look at the next part of the code:

     LABEL maintainer="Kunal Malhotra,"
     RUN apt-get update
  3. Note the maintainer and update the Ubuntu package index. The command is RUN, which is a function that runs the command after it.

     RUN mkdir /app
     WORKDIR /app
     COPY . /app
  4. Now it’s time to add the Flask application to the image. For simplicity, copy the application under the /app directory on our Docker Image.

    WORKDIR is essentially a cd in bash, and COPY copies a certain directory to the provided directory in an image. ADD is another command that does the same thing as COPY, but it also allows you to add a repository from a URL. Thus, if you want to clone your git repository instead of copying it from your local repository (for staging and production purposes), you can use that. COPY, however, should be used most of the time unless you have a URL.

  5. Now that we have our repository copied to the image, we will install all of our dependencies, which is defined in the requirements.txt part of the code.

     RUN pip install --no-cache-dir -r requirements.txt
  6. We want to expose the port(5000) the Flask application runs on, so we use EXPOSE.

     EXPOSE 5000
  7. ENTRYPOINT specifies the entrypoint of your application.
     ENTRYPOINT [ "python" ]
     CMD [ "" ]

Build an image from the Dockerfile

Open the terminal and type this command to build an image from your Dockerfile: docker build -t <image_name>:<tag> . (note the period to indicate we’re in our apps top level directory). For example: docker build -t app:latest .


Run your container locally and test

After you build your image succesfully, type: docker run -d -p 5000:5000 app

This command will create a container that contains all the application code and dependencies from the image and runs it locally.



Push the image to the IBM Cloud Registry

  1. From your account dashboard, go to IBM Cloud Kubernetes Service.
  2. From the left navigation menu, select Private Repositories.


  3. Install the Container Registry plug-in.

     ibmcloud plugin install container-registry -r "IBM Cloud"
  4. Log in to your IBM Cloud account.

     ibmcloud login -a <cloud_foundary_end_point_for_the_region>
  5. Name and create your namespace. Use this namespace for the rest of the Quick Start.

     ibmcloud cr namespace-add <namespace>
  6. Log your local Docker daemon into the IBM Cloud Container Registry.

     ibmcloud cr login
  7. Choose a repository and tag by which you can identify the image.

     docker tag <image_name> <region_url>/<namespace>/<image_name>:<tag>
  8. Push the image.

     docker push <region_url>/<namespace>/<image_name>:<tag>


  9. Verify that your image is in your private registry.

     ibmcloud cr image-list


Create configuration files for Kubernetes

Once the image is successfully uploaded to the private registry, go to your project directory and create two files: deployment.yaml and service.yaml.


  1. In the deployment.yaml file, paste this code:

     apiVersion: extensions/v1beta1
     kind: Deployment
       name: flask-node-deployment
       replicas: 1
           app: flasknode
             app: flasknode
           - name: flasknode
             imagePullPolicy: Always
             - containerPort: 5000
  2. In the service.yaml file, paste this code:

     apiVersion: v1
     kind: Service
       name: flask-node-deployment
       - port: 5000
         targetPort: 5000
         app: flasknode

Explanation and breakdown of the deployment.yaml code

  1. A deployment named flask-node-deployment is created, indicated by the field.
  2. The deployment creates one replicated pod, indicated by the replicas field.
  3. The selector field defines how the Deployment finds which Pods to manage. In this case, we simply select on one label defined in the Pod template (app: flasknode). However, more sophisticated selection rules are possible, as long as the Pod template itself satisfies the rule.
  4. The pod template’s specification, .template.spec, indicates that the pods run one container, flasknode, which runs the app private registry image.
  5. The deployment opens port 5000 for use by the Pods.

Explanation and breakdown of the service.yaml code

  1. The service.yaml‘s specification will create a new service object named flask-node-deployment which targets TCP port 5000 on any Pod with the “app=flasknode” label. This Service will also be assigned an IP address (sometimes called the cluster IP), which is used by the service proxies (see below). The Service’s selector will be evaluated continuously and the results will be POSTed to an Endpoints object also named flask-node-deployment.

  2. Note that a service can map an incoming port to any targetPort. By default the targetPort will be set to the same value as the port field. Perhaps more interesting is that targetPort can be a string, referring to the name of a port in the backend Pods. The actual port number assigned to that name can be different in each backend Pod. This offers a lot of flexibility for deploying and evolving your Services. For example, you can change the port number that pods expose in the next version of your backend software, without breaking clients.

Deploy your application to Kubernetes

  1. Target the IBM Cloud Kubernetes Service region where you want to work.

     ibmcloud cs region-set us-south
  2. Set the context for the cluster in your CLI.

    a. Get the command to set the environment variable and download the Kubernetes configuration files.

     ibmcloud cs cluster-config cluster_kunal

    b. Set the KUBECONFIG environment variable. Copy the output from the previous command and paste it in your terminal. The command output should look similar to the following.

    > export KUBECONFIG=/Users/$USER/.bluemix/plugins/container-service/clusters/< cluster_name >/< cluster_configuration_file.yaml>
  3. Verify that you can connect to your cluster by listing your worker nodes.

     kubectl get nodes
  4. Create the deployment.

     kubectl create -f deployment.yaml


  5. Create the service.

     kubectl create -f service.yaml


  6. Look at the Kubernetes dashboard from the IBM Kubernetes Service overview page.


  7. Finally, go to your browser and ping the Public IP of your worker node.


Resources and references

  1. Kubernetes Documentation
  2. Deploy a microservices app on IBM Cloud by using Kubernetes
  3. Tutorial: Deploying apps into clusters