# 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 1. **DNSSEC Validation**: Mailu v1.9+ requires DNSSEC-validating resolver 2. **Cross-Environment Consistency**: Unified approach for dev and prod 3. **Resource Efficiency**: Optimized for constrained environments 4. **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 ```yaml # 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) ```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:** ```bash # 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:** ```bash # 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 ```bash # 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 ```bash # 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 ```yaml # 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 1. **Configuration Migration** - Update storage class from hostPath to production storage - Adjust resource requests/limits - Enable monitoring and logging 2. **Data Migration** - Export development data - Import into production environment - Verify data integrity 3. **DNS Configuration** - Update DNS records to point to production - Verify TLS certificates - Test email delivery ## Security Considerations ### Production Security Hardening 1. **Network Security** - Implement network policies - Restrict ingress/egress traffic - Use TLS for all external communications 2. **Access Control** - Implement RBAC for Mailu namespace - Restrict admin access - Use strong authentication 3. **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.