8.2 KiB
Mailu Deployment Architecture for Bakery-IA Project
Executive Summary
This document outlines the recommended architecture for deploying Mailu email services across development and production environments for the Bakery-IA project. The solution addresses DNSSEC validation requirements while maintaining consistency across different Kubernetes platforms.
Environment Overview
Development Environment
- Platform: Kind (Kubernetes in Docker) or Colima
- Purpose: Local development and testing
- Characteristics: Ephemeral, single-node, resource-constrained
Production Environment
- Platform: MicroK8s on Ubuntu VPS
- Purpose: Production email services
- Characteristics: Single-node or small cluster, persistent storage, production-grade reliability
Core Requirements
- DNSSEC Validation: Mailu v1.9+ requires DNSSEC-validating resolver
- Cross-Environment Consistency: Unified approach for dev and prod
- Resource Efficiency: Optimized for constrained environments
- Reliability: Production-grade availability and monitoring
Architectural Solution
Unified DNS Resolution Strategy
Recommended Approach: Deploy Unbound as a dedicated DNSSEC-validating resolver pod in both environments
Benefits:
- ✅ Consistent behavior across dev and prod
- ✅ Meets Mailu's DNSSEC requirements
- ✅ Privacy-preserving (no external DNS queries)
- ✅ Avoids rate-limiting from public DNS providers
- ✅ Full control over DNS resolution
Implementation Components
1. Unbound Deployment Manifest
# unbound.yaml - Cross-environment compatible
apiVersion: apps/v1
kind: Deployment
metadata:
name: unbound-resolver
namespace: mailu
labels:
app: unbound
component: dns
spec:
replicas: 1 # Scale to 2+ in production with anti-affinity
selector:
matchLabels:
app: unbound
template:
metadata:
labels:
app: unbound
component: dns
spec:
containers:
- name: unbound
image: mvance/unbound:latest
ports:
- containerPort: 53
name: dns-udp
protocol: UDP
- containerPort: 53
name: dns-tcp
protocol: TCP
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "300m"
memory: "384Mi"
readinessProbe:
exec:
command: ["drill", "@127.0.0.1", "-p", "53", "+dnssec", "example.org"]
initialDelaySeconds: 10
periodSeconds: 30
securityContext:
capabilities:
add: ["NET_BIND_SERVICE"]
---
apiVersion: v1
kind: Service
metadata:
name: unbound-dns
namespace: mailu
spec:
selector:
app: unbound
ports:
- name: dns-udp
port: 53
targetPort: 53
protocol: UDP
- name: dns-tcp
port: 53
targetPort: 53
protocol: TCP
2. Mailu Configuration (values.yaml)
# Production-tuned Mailu configuration
dnsPolicy: None
dnsConfig:
nameservers:
- "10.152.183.x" # Replace with actual unbound service IP
# Component-specific DNS configuration
admin:
dnsPolicy: None
dnsConfig:
nameservers:
- "10.152.183.x"
rspamd:
dnsPolicy: None
dnsConfig:
nameservers:
- "10.152.183.x"
# Environment-specific configurations
persistence:
enabled: true
# Development: use default storage class
# Production: use microk8s-hostpath or longhorn
storageClass: "standard"
replicas: 1 # Increase in production as needed
# Security settings
secretKey: "generate-strong-key-here"
# Ingress configuration
# Use existing Bakery-IA ingress controller
Environment-Specific Adaptations
Development (Kind/Colima)
Optimizations:
- Use hostPath volumes for persistence
- Reduce resource requests/limits
- Disable or simplify monitoring
- Use NodePort for external access
Deployment:
# Apply unbound
kubectl apply -f unbound.yaml
# Get unbound service IP
UNBOUND_IP=$(kubectl get svc unbound-dns -n mailu -o jsonpath='{.spec.clusterIP}')
# Deploy Mailu with dev-specific values
helm upgrade --install mailu mailu/mailu \
--namespace mailu \
-f values-dev.yaml \
--set dnsConfig.nameservers[0]=$UNBOUND_IP
Production (MicroK8s/Ubuntu)
Enhancements:
- Use Longhorn or OpenEBS for storage
- Enable monitoring and logging
- Configure proper ingress with TLS
- Set up backup solutions
Deployment:
# Enable required MicroK8s addons
microk8s enable dns storage ingress metallb
# Apply unbound
kubectl apply -f unbound.yaml
# Get unbound service IP
UNBOUND_IP=$(kubectl get svc unbound-dns -n mailu -o jsonpath='{.spec.clusterIP}')
# Deploy Mailu with production values
helm upgrade --install mailu mailu/mailu \
--namespace mailu \
-f values-prod.yaml \
--set dnsConfig.nameservers[0]=$UNBOUND_IP
Verification Procedures
DNSSEC Validation Test
# From within a Mailu pod
kubectl exec -it -n mailu deploy/mailu-admin -- bash
# Test DNSSEC validation
dig @unbound-dns +short +dnssec +adflag example.org A
# Should show AD flag in response
Service Health Checks
# Check unbound service
kubectl get pods -n mailu -l app=unbound
kubectl logs -n mailu -l app=unbound
# Check Mailu components
kubectl get pods -n mailu
kubectl logs -n mailu -l app.kubernetes.io/name=mailu
Monitoring and Maintenance
Production Monitoring Setup
# Example monitoring configuration for production
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: unbound-monitor
namespace: mailu
spec:
selector:
matchLabels:
app: unbound
endpoints:
- port: dns-tcp
interval: 30s
path: /metrics
Backup Strategy
Production:
- Daily Velero backups of Mailu namespace
- Weekly database dumps
- Monthly full cluster snapshots
Development:
- On-demand backups before major changes
- Volume snapshots for critical data
Troubleshooting Guide
Common Issues and Solutions
Issue: DNSSEC validation failures
- Verify unbound pod logs
- Check network policies
- Test DNS resolution from within pods
Issue: Mailu pods failing to start
- Confirm DNS configuration in values.yaml
- Verify unbound service is reachable
- Check resource availability
Issue: Performance problems
- Monitor CPU/memory usage
- Adjust resource limits
- Consider scaling replicas
Migration Path
From Development to Production
-
Configuration Migration
- Update storage class from hostPath to production storage
- Adjust resource requests/limits
- Enable monitoring and logging
-
Data Migration
- Export development data
- Import into production environment
- Verify data integrity
-
DNS Configuration
- Update DNS records to point to production
- Verify TLS certificates
- Test email delivery
Security Considerations
Production Security Hardening
-
Network Security
- Implement network policies
- Restrict ingress/egress traffic
- Use TLS for all external communications
-
Access Control
- Implement RBAC for Mailu namespace
- Restrict admin access
- Use strong authentication
-
Monitoring and Alerting
- Set up anomaly detection
- Configure alert thresholds
- Implement log retention policies
Cost Optimization
Resource Management
Development:
- Use minimal resource allocations
- Scale down when not in use
- Clean up unused resources
Production:
- Right-size resource requests
- Implement auto-scaling where possible
- Monitor and optimize usage patterns
Conclusion
This architecture provides a robust, consistent solution for deploying Mailu across development and production environments. By using Unbound as a dedicated DNSSEC-validating resolver, we ensure compliance with Mailu's requirements while maintaining flexibility and reliability across different Kubernetes platforms.
The solution is designed to be:
- Consistent: Same core architecture across environments
- Reliable: Production-grade availability and monitoring
- Efficient: Optimized resource usage
- Maintainable: Clear documentation and troubleshooting guides
This approach aligns with the Bakery-IA project's requirements for a secure, reliable email infrastructure that can be consistently deployed across different environments.