Deploying a web application on Kubernetes(K8s) involves a series of steps that ensure your application is containerized, orchestrated, and managed efficiently. Below the key points for create and deploy a web application on k8s.

Create container image

K8s is a and orchestrator that works managing container image.  So as first step a your application need to be containerized, Docker is the most common tool for this, but other tools can be used, like Podman or other open source alternatives. Below is a simple python application and an example Dockrifle that permit to create the container image:


Make sure you have app.py and requirements.txt in the same directory as your Dockerfile. Here's a simple app.py example for a Flask application:

import os
from flask import Flask
app = Flask(__name__)

# Use os.environ.get() to read the environment variable 'NAME'. 
# Provide a default value in case 'NAME' is not set.
name = os.environ.get('NAME', 'World')

@app.route('/')
def hello():
    # Use the 'name' variable in your application's response
    return f"Hello {name}!"

if __name__ == '__main__':
    # Run the app on all available interfaces on port 80
    app.run(host='0.0.0.0', port=80)

And your requirements.txt should at least contain Flask, like so:

Flask

this below is the docker file used for create a container version of the test application

# Use an official Python runtime as a parent image
FROM python:3.9-slim

# Set the working directory in the container
WORKDIR /usr/src/app

# Copy the current directory contents into the container at /usr/src/app
COPY . .

# Install any needed packages specified in requirements.txt
RUN pip install --no-cache-dir -r requirements.txt

# Make port 80 available to the world outside this container
EXPOSE 80

# Define environment variable
ENV NAME World

# Run app.py when the container launches
CMD ["python", "app.py"]

Here's a brief explanation of each command in the Dockerfile:

You can then build and run your Docker image with:

docker build -t your-application-name:tag .
docker run -p 4000:80 your-application-name:tag

this is the link to the test application: app-test.zip

The application now need to pushed to a docker registry (Docker, Github, etc...)

docker tag your-application-name:tag registry-url/your-application-name:tag
docker push registry-url/your-application-name:tag

Set Up Kubernetes Environment

Usually one of the most used k8s test environment can be built using Minikube, or other open source alternatives.

Create k8s object

To deploy the created container on k8s we need to create the following k8s resources:

Deployment Resource (deploy.yaml)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: your-application-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: your-application
  template:
    metadata:
      labels:
        app: your-application
    spec:
      containers:
      - name: your-application
        image: registry-url/your-application-name:tag
        ports:
        - containerPort: 80

This Kubernetes resource is a Deployment configuration, which provides declarative updates for Pods and ReplicaSets. Let's break down its components:

this Deployment configuration named your-application-deployment is designed to ensure that three replicas of a Pod are running at all times. Each Pod runs a container based on the specified Docker image registry-url/your-application-name:tag and exposes port 80. The Deployment manages Pods that are labeled with app: your-application, ensuring that the desired state of having three replicas is maintained, handling scaling and updates as defined by the Deployment configuration.

Service resource (service.yaml)

apiVersion: v1
kind: Service
metadata:
  name: your-application-service
spec:
  type: LoadBalancer
  ports:
  - port: 80
    targetPort: 80
  selector:
    app: your-application

This Kubernetes Service resource is a configuration that defines how to expose an application running on a set of Pods as a network service. Let's break down its components:

this Service resource configuration creates a LoadBalancer type Service named your-application-service. It exposes the application on port 80 to the internet through a load balancer provided by the cloud platform. The Service forwards traffic arriving at this port to port 80 on Pods labeled with app: your-application. This setup is commonly used for applications that need to be accessible from outside the Kubernetes cluster, providing an easy way to expose services to the internet with minimal configuration.

Ingress resource (ingress.yaml)

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: your-application-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
    nginx.ingress.kubernetes.io/enable-cors: "true"
  labels:
    name: your-application-ingress
spec:
  rules:
  - host: "hostname.slac.stanford.edu"
    http:
      paths:
      - pathType: Prefix
        path: /uri/prefix(/|$)(.*)
        backend:
          service:
            name: elog-plus-backend-service
            port: 
              number: 80

This Ingress resource configuration effectively routes HTTP traffic coming to hostname.slac.stanford.edu/uri/prefix and any subpath (/uri/prefix/anything-here) to the elog-plus-backend-service on port 80. The path rewrite and CORS settings further customize how the incoming requests are handled and forwarded to the backend service.


Use other Kubernetes resources as needed (ConfigMaps, Secrets, Volumes) to manage configurations, sensitive information, and persistent data.

The relationship between Deployment, Service, and Ingress resources in Kubernetes is a fundamental aspect of how applications are deployed, exposed, and accessed within a Kubernetes cluster. Each of these resources serves a specific role in the application deployment and access workflow. Here’s how they interrelate:

Summary of the relationship between the above describe resources

Deployment

Service

Ingress

Workflow Summary

  1. Deployment: You define a Deployment to manage your application’s Pods. The Deployment ensures the desired number of Pods are always running and manages updates to your application.
  2. Service: To expose the Pods managed by the Deployment internally within the cluster or externally, you define a Service. The Service provides a stable endpoint (DNS name or IP address) that routes traffic to the Pods.
  3. Ingress: For more advanced routing needs (e.g., path-based routing, SSL termination, domain name-based access), you define an Ingress. The Ingress controls access to the Services from outside the Kubernetes cluster, routing external requests to the appropriate Services based on the defined rules.

Deploy Your Application

When the resources are ready and the k8s is accessible with the kubectl CLI, the resources can be created in this way.

kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
kubectl apply -f ingress.yaml



Related issues