ALEX C. GODWIN | Cloud & DevOps Engineer
DEVOPS PROJECT

Kubernetes Container Platform

Built and operated a containerized application platform on Amazon EKS with Kubernetes workloads, NGINX Ingress, health probes, resource controls, autoscaling, security controls, and separate deployment environments.

KubernetesDockerAmazon EKSKustomizeNGINX Ingress

Project Overview

I built and validated a Kubernetes application platform on Amazon EKS for a multi-service containerized application. The platform combined a frontend, API, authentication service, background worker, PostgreSQL and Redis with Kubernetes networking, health management, autoscaling, resource controls and workload security.

The Kubernetes desired state is version-controlled and environment-specific configuration is maintained with Kustomize. The platform was verified from the cluster layer through ingress and the application workflow before the temporary AWS environment was later decommissioned.

Engineering Problem

The application consisted of several independently managed services that needed reliable scheduling, networking, health checks, scaling and controlled deployment across multiple environments. Running containers alone would not provide the operational controls needed to manage failures, traffic routing, resource usage or release consistency.

  • Run frontend, API, authentication and worker services as independently managed workloads.
  • Provide stable service discovery and external ingress routing.
  • Prevent unhealthy workloads from receiving traffic.
  • Allow Kubernetes to recover failed application processes automatically.
  • Scale API capacity based on resource demand rather than relying only on a fixed replica count.
  • Apply CPU and memory controls to reduce uncontrolled resource consumption.
  • Harden workloads for restricted Kubernetes security requirements.
  • Maintain separate development, staging and production-style desired state through Git.

Solution Architecture

Amazon EKS provided the managed Kubernetes control plane. During validation, EC2 worker nodes supplied workload capacity and application images were pulled from private Amazon ECR repositories. The NGINX Ingress Controller provided the external application entry point and routed traffic to Kubernetes Services, which in turn exposed the appropriate application pods.

Kubernetes container platform architecture
Internet / Client
        ↓
AWS Load Balancer
        ↓
NGINX Ingress
   ├── /      → Frontend
   ├── /api   → API
   └── /auth  → Authentication
        ↓
Kubernetes Services
        ↓
Application Pods
        ↓
PostgreSQL + Redis + Worker

What I Built

  • Amazon EKS cluster portfolio-dev.
  • During validation, Kubernetes 1.36 ran on four t3.medium worker nodes.
  • Frontend workload served through an unprivileged NGINX container.
  • Application API with multiple replicas and Horizontal Pod Autoscaling.
  • Independent authentication service.
  • Background worker consuming queued application work.
  • PostgreSQL relational database workload.
  • Redis queue/cache workload.
  • Kubernetes Services for stable internal service discovery.
  • NGINX Ingress Controller backed by an AWS load balancer.
  • Kustomize-managed environment configuration.

Kubernetes Deployments maintained the desired application state and recreated failed pods when required. Services kept application endpoints stable even when individual pod IP addresses changed.

Availability, Scaling & Security

Health-Aware Deployments

Readiness and liveness probes were configured so Kubernetes could distinguish between a running container and an application that was actually ready to serve traffic. Readiness removed unhealthy instances from request handling, while liveness allowed failed application processes to be restarted.

  • Readiness and liveness probes on application workloads.
  • Rolling updates for progressive application replacement.
  • Replica management through Kubernetes Deployments.
  • PodDisruptionBudget controls where appropriate.

Horizontal Pod Autoscaling

The API used a Horizontal Pod Autoscaler instead of depending entirely on a fixed replica count.

API HPA
minReplicas: 2
maxReplicas: 10
CPU target: 60%

Kubernetes Metrics Server supplied utilization data for the HPA. CPU and memory requests and limits were also configured to provide scheduling guidance and reduce the risk of uncontrolled resource consumption.

Restricted Runtime Security

  • API, authentication and worker containers are configured to run with numeric non-root UID 10001.
  • The frontend is configured with nginxinc/nginx-unprivileged:alpine and container port 8080.
  • Redis and PostgreSQL are configured with non-root security contexts.
  • RuntimeDefault seccomp profiles are configured for restricted workloads.
  • Workload security contexts disable privilege escalation where applicable.
  • Workload security contexts drop unnecessary Linux capabilities.
  • NetworkPolicy reduces unnecessary workload communication.
  • Real secret values are kept out of the public Git repository.

Environment Strategy

Development, staging and production-style application state was separated into dedicated Kubernetes namespaces:

platform
platform-staging
platform-prod

Kustomize and Git-managed desired state allowed environment-specific configuration to be maintained and reviewed without manually rebuilding each environment inside the cluster.

Challenges & How I Solved Them

Restricted Pod Security Broke Default Container Assumptions

Several workloads initially depended on container defaults that were incompatible with restricted pod-security requirements. I changed the application services to explicit non-root numeric user IDs, moved the frontend to an unprivileged NGINX image, and tightened the Redis and PostgreSQL security contexts.

Changing the Frontend Image Changed Its Listening Port

The unprivileged NGINX image listens on port 8080 rather than the privileged port configuration previously used. I updated the Kubernetes Service target port and the health probes so routing and health validation remained aligned with the container.

Fixed Replicas Conflicted with Autoscaling Ownership

A fixed API replica value would compete with the Horizontal Pod Autoscaler. I removed the conflicting replica setting from the relevant base/environment configuration and allowed the HPA to control capacity between its configured minimum and maximum.

Ingress Paths Needed Correct Backend Routing

The frontend, API and authentication services exposed different application paths. I adjusted the ingress routing so /api and /auth requests reached the correct backend services without forwarding incompatible path prefixes.

End-to-End Validation

I verified the platform beyond simply checking that Kubernetes pods were present. Validation followed the application path from the external load balancer through ingress and the API to the data and worker layers.

Client
  ↓
AWS Load Balancer
  ↓
NGINX Ingress
  ↓
API
  ↓
PostgreSQL + Redis
  ↓
Worker Processing
  ↓
Verified Application Flow
  • Kubernetes worker nodes were verified Ready during platform validation.
  • Application workloads were verified running successfully.
  • The API HPA was verified with a 60% CPU target and a 2-to-10 replica range.
  • The frontend returned HTML successfully through the AWS load balancer.
  • A POST /api/items request succeeded through the external application path.
  • Worker logs confirmed that the submitted item was processed.
  • Development, staging and production-style deployments were verified using the same versioned application release.

The AWS runtime was later decommissioned after the project evidence was captured, so these results describe the validated platform state rather than claiming the EKS environment remains permanently online.

Production Considerations

The portfolio implementation already demonstrates health checks, autoscaling, resource controls, environment separation, workload security hardening, NetworkPolicy and Git-managed desired state. For a larger production estate I would extend the platform with:

  • Managed TLS certificates and production DNS for public application endpoints.
  • External secrets management rather than Kubernetes secrets being the final secret-management layer.
  • Container image signing and admission verification.
  • Additional topology and disruption controls across failure domains.
  • Policy-as-code checks for Kubernetes manifests before deployment.
  • Formal capacity planning and service-level objectives.

Source Code & Evidence

The implementation is separated across application, GitOps and infrastructure repositories so software source, Kubernetes desired state and cloud infrastructure remain independently maintainable.

Engineering Value

This project demonstrates how I approach Kubernetes as an application platform rather than as a collection of manifests. I connected workload orchestration, networking, ingress, health management, autoscaling, resource governance, runtime security and environment separation into one validated operating model.

It also demonstrates practical troubleshooting across layers: changing container runtime assumptions to satisfy security requirements, keeping Service and probe configuration aligned with container ports, resolving ownership conflicts between fixed replicas and the HPA, and correcting ingress routing so external requests reached the intended backend services.