Deploy Flask app to Kubernetes using Skaffold on Zarvis
In this post, we’ll deploy a simple Flask application.
- Create a simple Flask application.
- Build image and deploy to local kubernetes environment (minikube) using Skaffold.
- Deploy the project to free hosted Kubernetes service Z.A.R.V.I.S. and get public URL endpoint.
See complete example project here and follow the instructuions in README.md
‘Hello world’ Flask application
Flask is a lightweight web application framework for Python.
Let’s create a simple Hello world Flask application.
from flask import Flask app = Flask(__name__) @app.route('/') def hello(): return 'Hello world!'
Save it in
hello.py and let’s run locally.
FLASK_APP=hello.py flask run
The application will run on port 5000. Open your web browser and conncet http://localhost:5000. Let’s remember this port number to define Kubernetes Service later.
We’ll not go deep into Flask here while tons of good tutorials are on the internet.
To deploy Hello world application on Kubernetes, we need to create a docker image. Let’s create a
Dockerfile as follows.
FROM ubuntu:latest RUN apt-get update -y RUN apt-get install -y python-pip python-dev build-essential RUN pip install Flask==1.0.2 ENV FLASK_APP hello.py COPY . /app WORKDIR /app ENTRYPOINT ["flask"] CMD ["run", "--host=0.0.0.0"]
The Dockerfile above is basically baking hello.py into the image and run
flask run command.
When this docker image is running on the container, Flask app will listen the default port 5000.
Create Kubernetes manifests
Let’s create a Deployment manifest yaml.
apiVersion: extensions/v1beta1 kind: Deployment metadata: name: flask-hello-world-deployment spec: selector: matchLabels: app: flask-hello-world-app replicas: 2 template: metadata: labels: app: flask-hello-world-app spec: containers: - name: flask-hello-world image: flask-hello-world-img
and save it in
Create a Service manifest. This file defines how kubernetes expose service ports of
kind: Service apiVersion: v1 metadata: name: service # Zarvis ingress looking for name 'service' by default spec: ports: - name: http port: 8080 # Zarvis ingress looking for port '8080' by default targetPort: 5000 # Flask application default port selector: app: flask-hello-world-app
and save it in
targetPort is 5000, because our Flask app is running on port 5000 inside the container.
port is 8080, because Zarvis ingress connect ‘8080’ port of the Service by default.
Service name and port number that Zarvis ingress connect is configurable through zarvis.yaml. But we’ll use ‘service’ and ‘8080’ to use default configuration.
Now, we can create a
skaffold.yaml file as follows
apiVersion: skaffold/v1beta13 kind: Config build: artifacts: - image: flask-hello-world-img # the same image name that is used in Deployment manifest deploy: kubectl: manifests: - k8s-*
Run everything locally.
First, install and start minikube. And then, run
$ skaffold dev --port-forward
This command will build docker image, deploy it to local kubernetes cluster (minikube) and port forward to connect Service.
It’ll take some time for the first time to build image. After few minutes you’ll see outputs such as
Port forwarding service/flask-service in namespace default, remote port 8080 -> local port 8080 Watching for changes... [flask-hello-world-deployment-5c59fcf987-pv5nl flask-hello-world] * Serving Flask app "hello.py" [flask-hello-world-deployment-5c59fcf987-pv5nl flask-hello-world] * Environment: production [flask-hello-world-deployment-5c59fcf987-pv5nl flask-hello-world] WARNING: Do not use the development server in a production environment. [flask-hello-world-deployment-5c59fcf987-pv5nl flask-hello-world] Use a production WSGI server instead. [flask-hello-world-deployment-5c59fcf987-pv5nl flask-hello-world] * Debug mode: off [flask-hello-world-deployment-5c59fcf987-pv5nl flask-hello-world] * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
Let’s check Pods are deployed in the minikube. You’ll see two Pods are running, something similar to
$ kubectl get pods NAME READY STATUS RESTARTS AGE flask-hello-world-deployment-6845c6b646-bns6b 1/1 Running 0 11m flask-hello-world-deployment-6845c6b646-lnpzx 1/1 Running 0 11m
Also check Service. You’ll see something like
$ kubectl get services NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE flask-service ClusterIP 10.107.185.136 <none> 8080/TCP 16m
Looks like everything is up and running. Let’s browse http://localhost:8080.
Update your code
Skaffold automatically detect changes, rebuild and deploy.
Hello world! to
Hello Skaffold! in
hello.py and save.
You’ll see Skaffold rebuild docker image and deploy to minikube again. This time, rebuilding docker image is much faster.
To terminate, press
<Ctrl> + C. Skaffold will delete Pods and Sevice from minikube.
Deploy to Zarvis.
Zarvis provides free Kubernetes namespace for all Github projects.
Zarvis automatically deploys project with
First, let’s create a github repository and push all the files.
hello.py Dockerfile k8s-deployment.yaml k8s-service.yaml skaffold.yaml
And then sign in https://zarvis.ai
Press “Connect” button to connect the repository.
Deploy to Staging
Once your project is connected, select your project and click ‘Deploy’ button in the ‘Deploy’ tab.
Select branch (‘master’ in our case) and click ‘Deploy to Staging’ button. You’ll see Zarvis is building selected branch in Staging area.
Staging area is accessible only from Github members who has access to the repository. This is useful for development versions and release candidates.
In this step, Zarvis clone and build the docker image, push image to private registry hosted in Zarvis, and deploy the project to Kubernetes cluster hosted in Zarvis. After build & deploy complete, Zarvis removes cloned repository from its system.
Once the project is successfully deployed, you’ll see green check icon. Zarvis provides unique URL for each branch in the project. Click Then you can click the url and see your application running. Great!
Promote to production
You can promote multiple branches to productino area and get production URL. Requests to the production URL are distributed to branches in Production area.
To promote, click ‘Promote to production’ icon next to your branch name in Staging area.
You can get production URL from “Endpoints” section. Note that this production URL is still accessible only from Github members.
Make service public
To make production URL publicly accessible, select ‘Anonymous’ in ‘settings’ tab.
Your proudction URL is now publicly accessible!
Example code in this article is in following github repository. Please fork and deploy to Zarvis!