339 lines
8.2 KiB
Markdown
339 lines
8.2 KiB
Markdown
# 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.
|