Day 10:Voting App with Traefik Ingress Controller

"Hello, I'm Kiran Pawar, a passionate Cloud and Devops Engineer with a strong background in cloud automation, configuration, and deployment. My journey in the world of technology has been a thrilling adventure, where I've had the privilege to work with cutting-edge tools and practices.
🚀 As a DevOps Engineer:
I specialize in automating, configuring, and deploying instances in cloud environments and data centers. My expertise extends to DevOps, GitOps, CI/CD pipeline management, HashiCorp Terraform, and containerization. I'm proficient in AWS and Linux/Unix administration, ensuring robust infrastructure and application performance.
🔧 My Tech Stack:
Front-end skills: HTML, CSS, SCSS, Tailwind CSS, Bootstrap, React, Material-UI, JavaScript DevOps toolbox: GIT, OWASP,Nexus,Trivy, Github, Gitlab, Terraform, Ansible, Docker, Kubernetes, Helm, Jenkins, Prometheus, Grafana, Argo CD, AWS EKS.
🌐 My Cloud Expertise:
I have hands-on experience managing AWS services, including EC2, S3, EBS, VPC, ELB, RDS, IAM, Route53, and more.
🔒 Networking and Security:
My skills include managing networking concepts such as TCP/IP protocols, security policies, and subnet interfacing. I have a strong understanding of infrastructure and networking, covering topics like firewalls, IP addressing, DNS, and more.
💡 What Sets Me Apart:
I bring a positive attitude, a strong work ethic, and a collaborative spirit to every project. I'm a self-starter, a fast learner, and an effective team player with strong interpersonal skills. In addition to my DevOps skills, I've developed shell scripts (Bash) for automating tasks and have proficiency in Python scripting. My ability to communicate and manage projects, along with a track record of resolving client issues, adds value to every team I work with. If you're looking for a DevOps engineer who is also well-versed in front-end technologies, feel free to connect with me. Let's explore new possibilities and create exceptional technical solutions together!"
This repository demonstrates the setup of a voting application using Docker Swarm, Traefik as an Ingress controller, and AWS services like Route 53 and Network Load Balancer (NLB).
Architecture Overview
Route 53: Manages DNS routing for the domain.
Network Load Balancer (NLB): Balances incoming traffic.
Traefik: Acts as an Ingress controller.
Handles HTTP to HTTPS redirection.
Manages SSL decryption and offloading.
Voting and Result Services:
Vote Service: Listens on TCP port 80.
Result Service: Listens on TCP port 80.
Setup Instructions
Prerequisites
Docker and Docker Swarm installed
AWS CLI configured
Traefik configured with Docker Swarm
Steps
Deploy Swarm Cluster


Configure Traefik
Ensure Traefik is configured correctly in
traefik.tomlortraefik.yml. This setup should handle:HTTP to HTTPS redirection
SSL certificate configuration
Routing rules for the
voteandresultservices```bash version: '3.3'
services:
traefik:
Use the latest v2.2.x Traefik image available
image: traefik:v2.9 ports:
Listen on port 80, default for HTTP, necessary to redirect to HTTPS
- 80:80
Listen on port 443, default for HTTPS
- 443:443
deploy:
placement:
constraints:
Make the traefik service run only on the node with this label
as the node with it has the volume for the certificates
- node.labels.traefik-public.traefik-public-certificates == true
labels:
Enable Traefik for this service, to make it available in the public network
- traefik.enable=true
Use the traefik-public network (declared below)
- traefik.docker.network=traefik-public
Use the custom label "traefik.constraint-label=traefik-public"
This public Traefik will only use services with this label
That way you can add other internal Traefik instances per stack if needed
- traefik.constraint-label=traefik-public
admin-auth middleware with HTTP Basic auth
Using the environment variables USERNAME and HASHED_PASSWORD
- traefik.http.middlewares.admin-auth.basicauth.users=${USERNAME?Variable not set}:${HASHED_PASSWORD?Variable not set}
https-redirect middleware to redirect HTTP to HTTPS
It can be re-used by other stacks in other Docker Compose files
- traefik.http.middlewares.https-redirect.redirectscheme.scheme=https
- traefik.http.middlewares.https-redirect.redirectscheme.permanent=true
traefik-http set up only to use the middleware to redirect to https
Uses the environment variable DOMAIN
- traefik.http.routers.traefik-public-http.rule=Host(
${DOMAIN?Variable not set}) - traefik.http.routers.traefik-public-http.entrypoints=http
- traefik.http.routers.traefik-public-http.middlewares=https-redirect
traefik-https the actual router using HTTPS
Uses the environment variable DOMAIN
- traefik.http.routers.traefik-public-https.rule=Host(
${DOMAIN?Variable not set}) - traefik.http.routers.traefik-public-https.entrypoints=https
- traefik.http.routers.traefik-public-https.tls=true
Use the special Traefik service api@internal with the web UI/Dashboard
- traefik.http.routers.traefik-public-https.service=api@internal
Use the "le" (Let's Encrypt) resolver created below
- traefik.http.routers.traefik-public-https.tls.certresolver=le
Enable HTTP Basic auth, using the middleware created above
- traefik.http.routers.traefik-public-https.middlewares=admin-auth
Define the port inside of the Docker service to use
- traefik.http.services.traefik-public.loadbalancer.server.port=8080
volumes:
Add Docker as a mounted volume, so that Traefik can read the labels of other services
- traefik.enable=true
- node.labels.traefik-public.traefik-public-certificates == true
labels:
- /var/run/docker.sock:/var/run/docker.sock:ro
Mount the volume to store the certificates
- traefik-public-certificates:/certificates
command:
Enable Docker in Traefik, so that it reads labels from Docker services
- --providers.docker
Add a constraint to only use services with the label "traefik.constraint-label=traefik-public"
- --providers.docker.constraints=Label(
traefik.constraint-label,traefik-public)Do not expose all Docker services, only the ones explicitly exposed
- --providers.docker.exposedbydefault=false
Enable Docker Swarm mode
- --providers.docker.swarmmode
Create an entrypoint "http" listening on port 80
- --entrypoints.http.address=:80
Create an entrypoint "https" listening on port 443
- --entrypoints.https.address=:443
Create the certificate resolver "le" for Let's Encrypt, uses the environment variable EMAIL
- --certificatesresolvers.le.acme.email=${EMAIL?Variable not set}
Store the Let's Encrypt certificates in the mounted volume
- --certificatesresolvers.le.acme.storage=/certificates/acme.json
Use the TLS Challenge for Let's Encrypt
- --certificatesresolvers.le.acme.tlschallenge=true
Enable the access log, with HTTP requests
- --accesslog
Enable the Traefik log, for configurations and errors
- --log
Enable the Dashboard and API
- --api
networks:
Use the public network created to be shared between Traefik and
any other service that needs to be publicly available with HTTPS
- traefik-public
- 80:80
volumes:
Create a volume to store the certificates, there is a constraint to make sure
Traefik is always deployed to the same Docker node with the same volume containing
the HTTPS certificates
traefik-public-certificates:
networks:
Use the previously created public network "traefik-public", shared with other
services that need to be publicly available via this Traefik
traefik-public: external: true
Follow below commands to deploy :
### Steps:
1. **Create an overlay network**:
```css
docker network create --driver=overlay traefik-public

Ensures that services across multiple nodes in the Swarm can communicate.
- Label the Swarm node (where Traefik will store certificates):
export NODE_ID=$(docker info -f '{{.Swarm.NodeID}}') docker node update --label-add traefik-public.traefik-public-certificates=true $NODE_ID
- Set environment variables:
export EMAIL=kiranpawar3255@gmail.com export DOMAIN=traefik.cloudmantra.xyz export TRAEFIK_REPLICAS=1 export USERNAME=adminkiran export PASSWORD=India123456 export HASHED_PASSWORD=$(openssl passwd -apr1 $PASSWORD)
EMAIL: Used for Let's Encrypt SSL.DOMAIN: Your domain for Traefik.TRAEFIK_REPLICAS: Number of Traefik instances.USERNAME & PASSWORD: Basic authentication for the Traefik dashboard.HASHED_PASSWORD: Generates a secure hash of the password.- Deploy Traefik stack:
docker stack deploy -c traefik.yml traefik
Deploys Traefik as a service using
traefik.yml.
Set up Route 53 and NLB
Configure your Route 53 DNS to point to the NLB

Create hosted zone with your own domain

create simple routing record

copy master public ip

Add simple routing record


Create A record in with master node IP in your domain for eg.Godaddy
Ensure the NLB forwards traffic to Traefik.
Create 2 target groups one for TCP 443 and TCP 80

For TCP-80 target group
Choose a target type: instances
Target group name: TCP-80
Protocol : Port: TCP-443
Health checks; TCP
For TCP-80 target group




Create target group for TCP-443






Create Network Load Balancer
Go to Route53
Add two more simple routing records for vote and result respectively




Access the Application
Open your browser and navigate to your domain to access the voting and result services


This is our Trafik dashboard
Deploy voting application
create file name votingapp.yml:
version: "3" services: redis: image: redis:alpine networks: - traefik-public deploy: replicas: 1 update_config: parallelism: 2 delay: 10s restart_policy: condition: on-failure db: image: postgres:9.4 environment: POSTGRES_USER: "postgres" POSTGRES_PASSWORD: "postgres" volumes: - db-data:/var/lib/postgresql/data networks: - traefik-public deploy: resources: limits: cpus: "0.50" memory: 512M reservations: cpus: "0.25" memory: 128M placement: constraints: [node.role == manager] vote: image: kiran2361993/testing:latestappvote ports: - 5000:80 networks: - traefik-public depends_on: - redis deploy: replicas: 2 labels: - traefik.enable=true - traefik.docker.network=traefik-public - traefik.constraint-label=traefik-public - traefik.http.middlewares.vote-https-redirect.redirectscheme.scheme=https - traefik.http.middlewares.vote-https-redirect.redirectscheme.permanent=true - traefik.http.routers.vote-public-http.rule=Host(`vote.cloudvishwakarma.in`) || Host(`www.cloudvishwakarma.in`) - traefik.http.routers.vote-public-http.entrypoints=http - traefik.http.routers.vote-public-http.middlewares=https-redirect - traefik.http.routers.vote-public-https.rule=Host(`vote.cloudvishwakarma.in`) || Host(`www.cloudvishwakarma.in`) - traefik.http.routers.vote-public-https.entrypoints=https - traefik.http.routers.vote-public-https.tls=true - traefik.http.routers.vote-public-https.tls.certresolver=le - traefik.http.services.vote-public.loadbalancer.server.port=80 update_config: parallelism: 2 restart_policy: condition: on-failure result: image: kiran2361993/testing:latestappresults ports: - 5001:80 networks: - traefik-public depends_on: - db deploy: replicas: 1 #Multiple Replicas is causing delay in result. labels: - traefik.enable=true - traefik.docker.network=traefik-public - traefik.constraint-label=traefik-public - traefik.http.middlewares.result-https-redirect.redirectscheme.scheme=https - traefik.http.middlewares.result-https-redirect.redirectscheme.permanent=true - traefik.http.routers.result-public-http.rule=Host(`result.cloudvishwakarma.in`) - traefik.http.routers.result-public-http.entrypoints=http - traefik.http.routers.result-public-http.middlewares=https-redirect - traefik.http.routers.result-public-https.rule=Host(`result.cloudvishwakarma.in`) - traefik.http.routers.result-public-https.entrypoints=https - traefik.http.routers.result-public-https.tls=true - traefik.http.routers.result-public-https.tls.certresolver=le - traefik.http.services.result-public.loadbalancer.server.port=80 update_config: parallelism: 2 delay: 10s restart_policy: condition: on-failure worker: image: kiran2361993/testing:latestappworker networks: - traefik-public depends_on: - db - redis deploy: mode: replicated replicas: 1 labels: [APP=VOTING] restart_policy: condition: on-failure delay: 10s max_attempts: 3 window: 120s networks: traefik-public: external: true volumes: db-data:Deploy voting application stack:
docker stack deploy -c votingapp.yml votingapp

Conclusion
This setup demonstrates how to use Traefik as an Ingress controller with Docker Swarm, Route 53, and NLB to manage a simple voting application. For more details, refer to the accompanying video.








