Natural editorial-style developer workspace showing production deployment monitoring and cloud operations screens
|

Real-Life Kubernetes Project: Production App Deployment

Kubernetes real-life project

Deploy a production-ready microservice on Kubernetes

This project walks through a realistic Kubernetes deployment pattern used by platform and DevOps teams: container image, namespace, deployment, service, ingress, config, secrets, autoscaling, monitoring, and GitOps-style delivery.

If you want to learn Kubernetes for real work, do not stop at creating a pod. In most companies, the useful skill is knowing how an application moves from code to a stable URL, how it scales during traffic, how it gets monitored, and how the team can roll it back when something goes wrong.

Project goalRun a small web API on Kubernetes with safe traffic routing, health checks, and autoscaling.
Real-world toolsDocker, Kubernetes, NGINX Ingress, HPA, ConfigMap, Secret, Prometheus-ready metrics, and Argo CD flow.
Best forDevOps learners, interview preparation, portfolio projects, and engineers preparing for CKAD/CKA-style work.

1. Architecture: what happens when a user opens the app?

The application follows a common production pattern. A user sends an HTTPS request to your domain. The ingress controller receives the request, routes it to a Kubernetes Service, and the Service load-balances traffic to healthy pods created by a Deployment. Configuration comes from ConfigMaps, sensitive values come from Secrets, and the Horizontal Pod Autoscaler adds more pods when CPU usage increases.

Production mindset: Kubernetes is not only about running containers. It is about repeatable deployments, predictable networking, health checks, scaling, and recovery.

2. Repository layout

A clean repository makes the project easier to understand in interviews and easier to automate in CI/CD.

k8s-real-life-project/
├── app/
│   ├── Dockerfile
│   └── src/
├── k8s/
│   ├── namespace.yaml
│   ├── configmap.yaml
│   ├── secret.yaml
│   ├── deployment.yaml
│   ├── service.yaml
│   ├── ingress.yaml
│   └── hpa.yaml
└── README.md

3. Kubernetes manifests

Start with a separate namespace so the application is isolated from default workloads.

apiVersion: v1
kind: Namespace
metadata:
  name: production-demo

Use a ConfigMap for non-sensitive application settings.

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
  namespace: production-demo
data:
  APP_ENV: "production"
  LOG_LEVEL: "info"

Use a Secret for sensitive values. In a real company, this usually comes from a secret manager, sealed secret, or external secrets operator.

apiVersion: v1
kind: Secret
metadata:
  name: app-secret
  namespace: production-demo
type: Opaque
stringData:
  DATABASE_URL: "postgres://user:password@postgres:5432/appdb"

The Deployment controls replicas, rolling updates, resource limits, and health checks.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-api
  namespace: production-demo
spec:
  replicas: 2
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 0
      maxSurge: 1
  selector:
    matchLabels:
      app: web-api
  template:
    metadata:
      labels:
        app: web-api
    spec:
      containers:
        - name: web-api
          image: ghcr.io/your-org/web-api:1.0.0
          ports:
            - containerPort: 8080
          envFrom:
            - configMapRef:
                name: app-config
            - secretRef:
                name: app-secret
          readinessProbe:
            httpGet:
              path: /ready
              port: 8080
            initialDelaySeconds: 10
            periodSeconds: 5
          livenessProbe:
            httpGet:
              path: /health
              port: 8080
            initialDelaySeconds: 20
            periodSeconds: 10
          resources:
            requests:
              cpu: 100m
              memory: 128Mi
            limits:
              cpu: 500m
              memory: 512Mi

The Service gives the pods a stable internal endpoint.

apiVersion: v1
kind: Service
metadata:
  name: web-api-service
  namespace: production-demo
spec:
  selector:
    app: web-api
  ports:
    - port: 80
      targetPort: 8080
  type: ClusterIP

The Ingress exposes the app through a real domain.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: web-api-ingress
  namespace: production-demo
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
    - host: api.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: web-api-service
                port:
                  number: 80

Finally, HPA lets Kubernetes add pods when the app gets busy.

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: web-api-hpa
  namespace: production-demo
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: web-api
  minReplicas: 2
  maxReplicas: 6
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 60

4. Deploy the project

Build and push the image

Build the application image and push it to a registry such as Docker Hub, Amazon ECR, GitHub Container Registry, or Google Artifact Registry.

docker build -t ghcr.io/your-org/web-api:1.0.0 ./app
docker push ghcr.io/your-org/web-api:1.0.0

Apply Kubernetes resources

Apply the manifests in order. Namespace first, then config, secret, deployment, service, ingress, and autoscaling.

kubectl apply -f k8s/namespace.yaml
kubectl apply -f k8s/configmap.yaml
kubectl apply -f k8s/secret.yaml
kubectl apply -f k8s/deployment.yaml
kubectl apply -f k8s/service.yaml
kubectl apply -f k8s/ingress.yaml
kubectl apply -f k8s/hpa.yaml

Verify the rollout

Do not just check whether pods exist. Check rollout status, endpoints, logs, and ingress routing.

kubectl -n production-demo rollout status deployment/web-api
kubectl -n production-demo get pods -o wide
kubectl -n production-demo get svc,ingress,hpa
kubectl -n production-demo logs deploy/web-api --tail=100

5. Monitoring and troubleshooting

A real project is not complete until you can see what the application is doing. At minimum, expose a health endpoint, readiness endpoint, and metrics endpoint. Then connect metrics to Prometheus and dashboards to Grafana.

  • Readiness failures: check app startup time, config values, and database connectivity.
  • CrashLoopBackOff: inspect logs with kubectl logs and describe the pod events.
  • Ingress returns 404: verify host name, path, ingress class, and service port.
  • HPA does not scale: confirm Metrics Server is installed and resource requests are defined.
kubectl -n production-demo describe pod <pod-name>
kubectl -n production-demo describe ingress web-api-ingress
kubectl top pods -n production-demo

6. Make it a GitOps project

In a real team, engineers should not manually run kubectl apply from their laptop for every production change. Store manifests in Git and let Argo CD or Flux sync the desired state into the cluster.

A simple GitOps flow looks like this:

  1. Developer pushes application code.
  2. CI builds and pushes a new container image.
  3. CI updates the image tag in the Kubernetes manifest repository.
  4. Argo CD detects the Git change and syncs the cluster.
  5. If the rollout fails, Argo CD shows drift and the team can revert the Git commit.

7. What to show in your portfolio

If you are using this as a portfolio or interview project, do not only show YAML files. Show the thinking behind them.

Architecture diagramShow traffic flow from user to ingress, service, pods, database, and monitoring.
README screenshotsAdd rollout status, HPA scaling output, ingress URL, and Grafana dashboard screenshots.
Failure recoveryExplain one rollback, one failed readiness probe, and one scaling test.

Final thoughts

This Kubernetes project is small enough to build in a weekend, but realistic enough to discuss in interviews. It proves you understand the important parts of Kubernetes: deployments, services, ingress, configuration, secrets, health checks, scaling, observability, and delivery workflow.

If you are preparing for a DevOps role, CKAD, CKA, or a Kubernetes-heavy interview, build this once manually and then rebuild it with GitOps. That second version is where the real learning starts.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *