Deploying Your Application

With the Kubernetes cluster fully operational and validated in previous parts of this series, it's time to deploy a custom application. This article focuses on building a Docker image for a Spring Boot REST API (named myapp.war for didactic purposes), pushing it to a registry, deploying it onto the cluster, and managing its lifecycle through updates, rollbacks, and scaling.

Building the Docker Image

The first step involves creating a Dockerfile for your application. For efficiency, a lightweight base image like alpine is recommended, along with the necessary Java version (Java 11 in this example) to run the application. The Dockerfile specifies the base image, sets the working directory, copies the application artifact (e.g., myapp.war), and defines the command to run the application. This process ensures your application is containerized and ready for deployment.

A typical Dockerfile might look like this:

FROM alpine:latest
WORKDIR /app
COPY myapp.war .
RUN apk add --no-cache openjdk11-jre
EXPOSE 8080
CMD ["java", "-jar", "myapp.war"]

Publishing the Docker Image

Once the Docker image is built locally, it needs to be accessible by your Kubernetes cluster. This typically involves pushing the image to a container registry. You can use a public registry like Docker Hub or a private registry for greater control and security. Ensure your Kubernetes nodes have the necessary credentials to pull images from your chosen registry.

The commands to build and push the image are:

docker build -t your-registry/myapp:v1 .
docker push your-registry/myapp:v1

Kubernetes Manifests for Deployment

To deploy your application on Kubernetes, you'll create several YAML manifest files. These define the desired state of your application within the cluster.

Deployment

A Deployment object manages stateless applications. It describes the desired number of replicas and the pod template, including the container image to use. Kubernetes ensures that the specified number of pods are running and handles updates and rollbacks.

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      -
        name: myapp
        image: your-registry/myapp:v1
        ports:
        - containerPort: 8080

Service

A Service object provides a stable IP address and DNS name for a set of pods, enabling network access to your application. It acts as an internal load balancer.

---
apiVersion: v1
kind: Service
metadata:
  name: myapp-service
spec:
  selector:
    app: myapp
  ports:
  -
    protocol: TCP
    port: 80
    targetPort: 8080
  type: ClusterIP

Applying Manifests

Save these manifests into separate YAML files (e.g., deployment.yaml, service.yaml) and apply them to your cluster using kubectl:

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

You can then check the status of your deployment and pods:

kubectl get deployments
kubectl get pods

Updating the Application

To update your application, build a new Docker image with the updated code (e.g., your-registry/myapp:v2), push it to the registry, and then update the image tag in your deployment.yaml file. Apply the updated deployment manifest:

kubectl apply -f deployment.yaml

Kubernetes will perform a rolling update, gradually replacing old pods with new ones to ensure zero downtime. You can monitor the progress with kubectl rollout status deployment/myapp-deployment.

Rollback

If an update causes issues, you can easily roll back to a previous version. Use kubectl rollout history deployment/myapp-deployment to see the revision history, and then kubectl rollout undo deployment/myapp-deployment --to-revision= to revert.

Scaling

You can scale your application manually by changing the replicas count in your deployment.yaml and reapplying it. For automatic scaling, Kubernetes offers the Horizontal Pod Autoscaler (HPA). HPA automatically scales the number of pods in a deployment based on observed CPU utilization or other selected metrics.

To set up an HPA, you would typically define an HorizontalPodAutoscaler resource:

---
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
  name: myapp-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: myapp-deployment
  minReplicas: 2
  maxReplicas: 10
  metrics:
  -
    type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70

Ensure that your cluster has the Kubernetes Metrics Server installed for HPA to function correctly. This setup provides a robust framework for managing your custom applications on an on-premise Kubernetes cluster.