DEV Community

Wycliffe A. Onyango
Wycliffe A. Onyango

Posted on

100 Days of DevOps: Day 63

Application Deployment on Kubernetes

I have successfully completed the deployment of a customized Iron Gallery application on a Kubernetes cluster. This deployment involved setting up a dedicated namespace, two distinct deployments for the frontend gallery and the backend database, and corresponding services to expose these components. All steps were executed meticulously, resulting in a fully operational setup.

Deployment Overview

The deployment plan was structured to ensure clear separation of concerns and robust connectivity:

  1. Namespace Creation: A dedicated namespace, iron-namespace-datacenter, was established to house all related resources, ensuring environmental isolation.
  2. Iron Gallery Deployment: The iron-gallery-deployment-datacenter deployment was created to manage the frontend application, configured with specific resource limits and volume mounts for configuration and image uploads.
  3. Iron DB Deployment: The iron-db-deployment-datacenter deployment was set up for the MariaDB database, including environment variables for database credentials and a volume mount for persistent data.
  4. Iron DB Service: A ClusterIP service, iron-db-service-datacenter, was created to expose the database internally within the cluster.
  5. Iron Gallery Service: A NodePort service, iron-gallery-service-datacenter, was configured to expose the frontend application externally on a specific node port.

Kubernetes Manifests

Here are the complete YAML manifests used for the deployment:

1. Namespace: iron-namespace-datacenter

apiVersion: v1
kind: Namespace
metadata:
  name: iron-namespace-datacenter
Enter fullscreen mode Exit fullscreen mode

2. Deployment: iron-gallery-deployment-datacenter

apiVersion: apps/v1
kind: Deployment
metadata:
  name: iron-gallery-deployment-datacenter
  namespace: iron-namespace-datacenter
  labels:
    run: iron-gallery
spec:
  replicas: 1
  selector:
    matchLabels:
      run: iron-gallery
  template:
    metadata:
      labels:
        run: iron-gallery
    spec:
      containers:
      - name: iron-gallery-container-datacenter
        image: kodekloud/irongallery:2.0
        resources:
          limits:
            memory: "100Mi"
            cpu: "50m"
        volumeMounts:
        - name: config
          mountPath: /usr/share/nginx/html/data
        - name: images
          mountPath: /usr/share/nginx/html/uploads
      volumes:
      - name: config
        emptyDir: {}
      - name: images
        emptyDir: {}
Enter fullscreen mode Exit fullscreen mode

3. Deployment: iron-db-deployment-datacenter

(Note: Placeholders for sensitive information like passwords should be replaced with actual, secure values in a real-world scenario, ideally using Kubernetes Secrets.)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: iron-db-deployment-datacenter
  namespace: iron-namespace-datacenter
  labels:
    db: mariadb
spec:
  replicas: 1
  selector:
    matchLabels:
      db: mariadb
  template:
    metadata:
      labels:
        db: mariadb
    spec:
      containers:
      - name: iron-db-container-datacenter
        image: kodekloud/irondb:2.0
        env:
        - name: MYSQL_DATABASE
          value: database_blog
        - name: MYSQL_ROOT_PASSWORD
          value: <COMPLEX_ROOT_PASSWORD> # Replace with a complex password
        - name: MYSQL_PASSWORD
          value: <COMPLEX_USER_PASSWORD> # Replace with a complex password
        - name: MYSQL_USER
          value: <CUSTOM_USER> # Replace with a non-root custom user
        volumeMounts:
        - name: db
          mountPath: /var/lib/mysql
      volumes:
      - name: db
        emptyDir: {}
Enter fullscreen mode Exit fullscreen mode

4. Service: iron-db-service-datacenter

apiVersion: v1
kind: Service
metadata:
  name: iron-db-service-datacenter
  namespace: iron-namespace-datacenter
spec:
  selector:
    db: mariadb
  type: ClusterIP
  ports:
  - protocol: TCP
    port: 3306
    targetPort: 3306
Enter fullscreen mode Exit fullscreen mode

5. Service: iron-gallery-service-datacenter

apiVersion: v1
kind: Service
metadata:
  name: iron-gallery-service-datacenter
  namespace: iron-namespace-datacenter
spec:
  selector:
    run: iron-gallery
  type: NodePort
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
    nodePort: 32678
Enter fullscreen mode Exit fullscreen mode

Execution Log and Verification

The deployment process was executed on the jumphost using kubectl commands, applying each manifest sequentially. The terminal outputs confirm the successful creation of each resource.

1. Initial File Preparation:
I prepared the necessary YAML manifest files for each Kubernetes resource.

thor@jumphost ~$ ls
iron-db-deployment-datacenter.yaml   iron-gallery-deployment-datacenter.yaml   iron-namespace-datacenter.yaml
iron-db-service-datacenter.yaml      iron-gallery-service-datacenter.yaml
Enter fullscreen mode Exit fullscreen mode

2. Applying Kubernetes Manifests:
Each YAML file was applied to the cluster.

thor@jumphost ~$ kubectl apply -f iron-namespace-datacenter.yaml
namespace/iron-namespace-datacenter created
thor@jumphost ~$ kubectl apply -f iron-gallery-deployment-datacenter.yaml
deployment.apps/iron-gallery-deployment-datacenter created
thor@jumphost ~$ kubectl apply -f iron-db-deployment-datacenter.yaml
deployment.apps/iron-db-deployment-datacenter created
thor@jumphost ~$ kubectl apply -f iron-db-service-datacenter.yaml
service/iron-db-service-datacenter created
thor@jumphost ~$ kubectl apply -f iron-gallery-service-datacenter.yaml
service/iron-gallery-service-datacenter created
Enter fullscreen mode Exit fullscreen mode

3. Verifying Resource Status:
Post-application, kubectl get commands were used to verify the status of the created resources, confirming their active and running states.

  • Namespace Verification:

    thor@jumphost ~$ kubectl get ns iron-namespace-datacenter
    NAME                         STATUS   AGE
    iron-namespace-datacenter    Active   2m23s
    

    The iron-namespace-datacenter is active and ready.

  • Deployment Verification:

    thor@jumphost ~$ kubectl get deploy -n iron-namespace-datacenter
    NAME                                  READY   UP-TO-DATE   AVAILABLE   AGE
    iron-db-deployment-datacenter         1/1     1            1           99s
    iron-gallery-deployment-datacenter    1/1     1            1           2m3s
    

    Both deployments are showing 1/1 ready, indicating that the desired number of replicas are running and available.

  • Pod Verification:

    thor@jumphost ~$ kubectl get pods -n iron-namespace-datacenter
    NAME                                             READY   STATUS    RESTARTS   AGE
    iron-db-deployment-datacenter-7c779567c5-jpnxw   1/1     Running   0          115s
    iron-gallery-deployment-datacenter-5d55db5c6c-5pbxm   1/1     Running   0          2m19s
    

    Both the database and gallery pods are in a Running state with no restarts, confirming application stability.

  • Service Verification:

    thor@jumphost ~$ kubectl get svc -n iron-namespace-datacenter
    NAME                               TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)         AGE
    iron-db-service-datacenter         ClusterIP   10.96.52.216    <none>        3306/TCP        107s
    iron-gallery-service-datacenter    NodePort    10.96.110.44    <none>        80:32678/TCP    64s
    

    The database service is correctly configured as ClusterIP, and the gallery service is a NodePort service, exposing port 80 of the application via node port 32678.

Conclusion

The Iron Gallery application and its database backend have been successfully deployed and verified on the Kubernetes cluster. All components are running as expected within the iron-namespace-datacenter. The frontend application is now accessible externally via NodePort 32678, ready for further configuration or testing.

Top comments (0)