Docker Certified Associate Exam Course

Kubernetes

Demo Deploy voting app on Kubernetes

In this tutorial, we’ll walk through deploying a multi-tier voting application on a Minikube cluster. You’ll define Pods for each component, expose them via Services, and verify end-to-end functionality.

1. Overview of Pod Definitions

All Pods use the label app: demo-voting-app to simplify grouping and service discovery.

Pod NameImagePort
voting-app-podkodekloud/examplevotingapp_vote:v180
result-app-podkodekloud/examplevotingapp_result:v180
redis-podredis:latest6379
postgres-podpostgres:latest5432
worker-app-podkodekloud/examplevotingapp_worker:v1

Note

Ensure you have Minikube running and kubectl configured to use the Minikube context before applying these manifests.

1.1 voting-app-pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: voting-app-pod
  labels:
    name: voting-app-pod
    app: demo-voting-app
spec:
  containers:
    - name: voting-app
      image: kodekloud/examplevotingapp_vote:v1
      ports:
        - containerPort: 80

The image shows a GitHub repository page for "dockersamples/example-voting-app," displaying folders, files, and commit information. The interface includes options for code, issues, pull requests, and more.


1.2 result-app-pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: result-app-pod
  labels:
    name: result-app-pod
    app: demo-voting-app
spec:
  containers:
    - name: result-app
      image: kodekloud/examplevotingapp_result:v1
      ports:
        - containerPort: 80
  • Grouped by app: demo-voting-app.
  • Exposes port 80 for the results UI.

1.3 redis-pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: redis-pod
  labels:
    name: redis-pod
    app: demo-voting-app
spec:
  containers:
    - name: redis
      image: redis:latest
      ports:
        - containerPort: 6379
  • Uses the official Redis image from Docker Hub.
  • Default Redis listens on port 6379.

1.4 postgres-pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: postgres-pod
  labels:
    name: postgres-pod
    app: demo-voting-app
spec:
  containers:
    - name: postgres
      image: postgres:latest
      ports:
        - containerPort: 5432
      env:
        - name: POSTGRES_USER
          value: "postgres"
        - name: POSTGRES_PASSWORD
          value: "postgres"

Warning

These credentials are hard-coded for demo purposes only. Do not use plaintext passwords in production.

  • Exposes port 5432.
  • Environment variables set POSTGRES_USER and POSTGRES_PASSWORD.

1.5 worker-app-pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: worker-app-pod
  labels:
    name: worker-app-pod
    app: demo-voting-app
spec:
  containers:
    - name: worker-app
      image: kodekloud/examplevotingapp_worker:v1
  • This background worker polls Redis for new votes and writes results to PostgreSQL.
  • No ports exposed.

2. Service Definitions

Define Services to enable intra-cluster communication and external access for frontends.

Service NameTypePortTargetPortNodePort
redisClusterIP63796379
dbClusterIP54325432
voting-serviceNodePort808030004
result-serviceNodePort808030005

2.1 redis-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: redis
  labels:
    name: redis-service
    app: demo-voting-app
spec:
  ports:
    - port: 6379
      targetPort: 6379
  selector:
    name: redis-pod
    app: demo-voting-app
  • Internal ClusterIP service for Redis.

2.2 postgres-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: db
  labels:
    name: postgres-service
    app: demo-voting-app
spec:
  ports:
    - port: 5432
      targetPort: 5432
  selector:
    name: postgres-pod
    app: demo-voting-app
  • Named db so the worker can connect using db:5432.

2.3 voting-app-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: voting-service
  labels:
    name: voting-service
    app: demo-voting-app
spec:
  type: NodePort
  ports:
    - port: 80
      targetPort: 80
      nodePort: 30004
  selector:
    name: voting-app-pod
    app: demo-voting-app
  • Exposes the voting UI externally on port 30004.

2.4 result-app-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: result-service
  labels:
    name: result-service
    app: demo-voting-app
spec:
  type: NodePort
  ports:
    - port: 80
      targetPort: 80
      nodePort: 30005
  selector:
    name: result-app-pod
    app: demo-voting-app
  • Exposes results UI externally on port 30005.

3. Applying Manifests

From the project root (e.g., voting-app/), create all Pods and Services:

kubectl apply -f voting-app-pod.yaml
kubectl apply -f result-app-pod.yaml
kubectl apply -f redis-pod.yaml
kubectl apply -f postgres-pod.yaml
kubectl apply -f worker-app-pod.yaml

kubectl apply -f redis-service.yaml
kubectl apply -f postgres-service.yaml
kubectl apply -f voting-app-service.yaml
kubectl apply -f result-app-service.yaml

Verify that everything is running:

kubectl get pods,svc

4. Accessing the Application

Retrieve the external URLs for the frontends:

minikube service voting-service --url
minikube service result-service --url
# e.g.: http://192.168.99.101:30005

Open the voting UI in your browser to cast votes, then navigate to the results page.

5. Testing the Voting Workflow

After submitting your first vote for “Dogs” you’ll see a 50/50 split:

The image shows a split screen with a blue section labeled "CATS" and a teal section labeled "DOGS," each with 50.0% in the center.

Viewing results immediately after one vote:

The image shows a voting result with "CATS" at 0.0% and "DOGS" at 100.0% on a turquoise background.

Casting another vote for “Cats” updates the results in real time:

The image shows a voting result with "CATS" at 100.0% and "DOGS" at 0.0% against a blue background.


Congratulations! You’ve successfully deployed and tested a complete multi-tier application on Kubernetes. For more details, refer to the Kubernetes Documentation and Minikube Guides.

Watch Video

Watch video content

Previous
Deploy voting app on Kubernetes