Skip to content

Gateway Stack (Ingress)

Overview

The Gateway Stack provides the entry point for all external traffic into the Kubernetes cluster. It handles SSL/TLS termination, load balancing, routing, and provides a management interface.

Stack Architecture

Components

1. Traefik Ingress Controller

Purpose: Edge router and reverse proxy with automatic HTTPS

Features:

  • Automatic SSL/TLS with Let's Encrypt
  • HTTP/2 and HTTP/3 support
  • WebSocket support
  • Load balancing algorithms
  • Rate limiting and circuit breakers
  • Middleware chain processing
  • Prometheus metrics export

Key Configuration:

yaml
# Static Configuration
entryPoints:
  web:
    address: ":80"
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https
  
  websecure:
    address: ":443"
    http:
      tls:
        certResolver: letsencrypt

certificatesResolvers:
  letsencrypt:
    acme:
      email: devops@healthflow.eg
      storage: /certificates/acme.json
      httpChallenge:
        entryPoint: web

providers:
  kubernetesIngress: {}
  kubernetesCRD: {}

api:
  dashboard: true
  insecure: false

metrics:
  prometheus:
    addEntryPointsLabels: true
    addServicesLabels: true

2. Portainer

Purpose: Web-based Kubernetes management interface

Features:

  • Visual stack deployment
  • Resource monitoring
  • Log viewing
  • User/team management
  • RBAC integration
  • Helm chart management

3. Portainer Agent

Purpose: Collects data from each cluster node

Deployment: DaemonSet (runs on all nodes)

Kubernetes Manifests

Namespace

yaml
apiVersion: v1
kind: Namespace
metadata:
  name: gateway-stack
  labels:
    name: gateway-stack
    stack: infrastructure

Traefik Deployment

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: traefik
  namespace: gateway-stack
  labels:
    app: traefik
spec:
  replicas: 3
  selector:
    matchLabels:
      app: traefik
  template:
    metadata:
      labels:
        app: traefik
    spec:
      serviceAccountName: traefik
      containers:
      - name: traefik
        image: traefik:v3.2
        args:
          - --configFile=/config/traefik.yml
        ports:
        - name: web
          containerPort: 80
          protocol: TCP
        - name: websecure
          containerPort: 443
          protocol: TCP
        - name: metrics
          containerPort: 8082
          protocol: TCP
        - name: dashboard
          containerPort: 8080
          protocol: TCP
        resources:
          limits:
            cpu: "2"
            memory: 2Gi
          requests:
            cpu: "500m"
            memory: 512Mi
        volumeMounts:
        - name: config
          mountPath: /config
        - name: certificates
          mountPath: /certificates
        livenessProbe:
          httpGet:
            path: /ping
            port: 8080
          initialDelaySeconds: 10
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /ping
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 5
      volumes:
      - name: config
        configMap:
          name: traefik-config
      - name: certificates
        persistentVolumeClaim:
          claimName: traefik-certificates

Traefik Service (LoadBalancer)

yaml
apiVersion: v1
kind: Service
metadata:
  name: traefik
  namespace: gateway-stack
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-type: nlb
spec:
  type: LoadBalancer
  selector:
    app: traefik
  ports:
  - name: web
    port: 80
    targetPort: 80
    protocol: TCP
  - name: websecure
    port: 443
    targetPort: 443
    protocol: TCP

Traefik Ingress (Dashboard)

yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: traefik-dashboard
  namespace: gateway-stack
spec:
  entryPoints:
    - websecure
  routes:
  - match: Host(`traefik.healthflow.eg`)
    kind: Rule
    services:
    - name: api@internal
      kind: TraefikService
    middlewares:
    - name: dashboard-auth
    - name: security-headers
  tls:
    certResolver: letsencrypt

Middleware Configurations

yaml
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: security-headers
  namespace: gateway-stack
spec:
  headers:
    customResponseHeaders:
      X-Content-Type-Options: "nosniff"
      X-Frame-Options: "SAMEORIGIN"
      X-XSS-Protection: "1; mode=block"
      Referrer-Policy: "strict-origin-when-cross-origin"
    stsSeconds: 31536000
    stsIncludeSubdomains: true
    stsPreload: true
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: rate-limit
  namespace: gateway-stack
spec:
  rateLimit:
    average: 100
    burst: 200
    period: 1s
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: cors-all
  namespace: gateway-stack
spec:
  headers:
    accessControlAllowMethods:
      - GET
      - POST
      - PUT
      - DELETE
      - PATCH
      - OPTIONS
    accessControlAllowOriginList:
      - https://healthflow.eg
      - https://*.healthflow.eg
    accessControlAllowHeaders:
      - Authorization
      - Content-Type
    accessControlMaxAge: 3600

Portainer Deployment

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: portainer
  namespace: gateway-stack
spec:
  replicas: 1
  selector:
    matchLabels:
      app: portainer
  template:
    metadata:
      labels:
        app: portainer
    spec:
      containers:
      - name: portainer
        image: portainer/portainer-ce:latest
        args:
          - --http-enabled
        ports:
        - containerPort: 9000
          name: http
        - containerPort: 8000
          name: edge
        volumeMounts:
        - name: data
          mountPath: /data
        resources:
          limits:
            cpu: "1"
            memory: 1Gi
          requests:
            cpu: "250m"
            memory: 256Mi
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: portainer-data

Service Dependencies

Environment Variables

Traefik

VariableDescriptionDefaultRequired
TRAEFIK_LOG_LEVELLog verbosityINFONo
TRAEFIK_ACCESS_LOGEnable access logstrueNo
TRAEFIK_METRICS_PROMETHEUSEnable Prometheus metricstrueNo
LETSENCRYPT_EMAILEmail for SSL certificates-Yes

Portainer

VariableDescriptionDefaultRequired
PORTAINER_ADMIN_PASSWORDAdmin user password hash-Yes
PORTAINER_SNAPSHOT_INTERVALEnvironment snapshot interval5mNo
PORTAINER_SSL_CERT_PATHCustom SSL certificate path-No

Persistent Volumes

Traefik Certificates

yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: traefik-certificates
  namespace: gateway-stack
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: nfs-client
  resources:
    requests:
      storage: 1Gi

Portainer Data

yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: portainer-data
  namespace: gateway-stack
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: gp3
  resources:
    requests:
      storage: 10Gi

Deployment Instructions

1. Create Namespace and Secrets

bash
# Create namespace
kubectl create namespace gateway-stack

# Create basic auth secret for Traefik dashboard
htpasswd -nb admin <password> | kubectl create secret generic traefik-auth \
  --from-literal=users=$(cat -) \
  --namespace gateway-stack

# Create Portainer admin password
kubectl create secret generic portainer-admin \
  --from-literal=password='<strong-password>' \
  --namespace gateway-stack

2. Deploy Traefik

bash
kubectl apply -f traefik/rbac.yaml
kubectl apply -f traefik/config.yaml
kubectl apply -f traefik/pvc.yaml
kubectl apply -f traefik/deployment.yaml
kubectl apply -f traefik/service.yaml
kubectl apply -f traefik/middleware.yaml
kubectl apply -f traefik/ingress.yaml

3. Deploy Portainer

bash
kubectl apply -f portainer/pvc.yaml
kubectl apply -f portainer/deployment.yaml
kubectl apply -f portainer/service.yaml
kubectl apply -f portainer/agent-daemonset.yaml
kubectl apply -f portainer/ingress.yaml

4. Verify Deployment

bash
# Check pod status
kubectl get pods -n gateway-stack

# Check services
kubectl get svc -n gateway-stack

# Check ingress routes
kubectl get ingressroute -n gateway-stack

# View Traefik logs
kubectl logs -n gateway-stack -l app=traefik -f

Monitoring & Health Checks

Traefik Health Endpoints

  • Ping: http://traefik:8080/ping
  • Dashboard: https://traefik.healthflow.eg/dashboard/
  • Metrics: http://traefik:8082/metrics

Portainer Access

  • UI: https://portainer.healthflow.eg
  • API: https://portainer.healthflow.eg/api

Troubleshooting

Traefik Not Getting Certificates

bash
# Check ACME storage
kubectl exec -n gateway-stack deployment/traefik -- cat /certificates/acme.json

# Verify DNS points to load balancer
nslookup traefik.healthflow.eg

# Check Let's Encrypt rate limits
# https://letsencrypt.org/docs/rate-limits/

Portainer Can't Connect to Agent

bash
# Verify agent is running on all nodes
kubectl get pods -n gateway-stack -l app=portainer-agent -o wide

# Check agent logs
kubectl logs -n gateway-stack -l app=portainer-agent

Next Steps