diff --git a/deployments/README.md b/deployments/README.md new file mode 100644 index 0000000..9e62db0 --- /dev/null +++ b/deployments/README.md @@ -0,0 +1,359 @@ +# Telecom Platform Deployment Guide + +This guide provides comprehensive instructions for deploying the Telecom Platform with all infrastructure components including GitOps, multi-environment support, service mesh, backup, logging, secrets management, and compliance. + +## Architecture Overview + +The Telecom Platform deployment consists of the following components: + +### Core Platform Services +- **API Server**: Main REST API service +- **Charging Engine**: Billing and payment processing +- **Packet Gateway**: Network packet processing +- **Web Dashboard**: React-based admin interface + +### Infrastructure Components +- **GitOps**: ArgoCD for continuous deployment +- **Service Mesh**: Istio for traffic management and security +- **Monitoring**: Prometheus + Grafana stack +- **Logging**: ELK stack (Elasticsearch, Logstash, Kibana) +- **Backup**: Velero for disaster recovery +- **Secrets**: HashiCorp Vault for secure secret management +- **Certificates**: cert-manager for automated TLS +- **Compliance**: GDPR compliance framework +- **Autoscaling**: HPA and VPA for dynamic scaling + +## Prerequisites + +### Kubernetes Cluster +- Kubernetes 1.24+ with RBAC enabled +- Minimum 8 CPU cores, 32GB RAM for production +- Storage class provisioned (e.g., standard, gp2) + +### Required Tools +- kubectl 1.24+ +- helm 3.8+ +- argocd CLI (optional) +- vault CLI (optional) + +### External Dependencies +- S3 bucket for backups +- Domain names for TLS certificates +- Email for Let's Encrypt certificates + +## Deployment Steps + +### 1. Install Infrastructure Components + +#### 1.1 Install Istio Service Mesh +```bash +# Install Istio +kubectl apply -f deployments/istio/istio-install.yaml + +# Wait for Istio to be ready +kubectl wait --for=condition=ready pod -l app=istio-ingressgateway -n istio-system --timeout=300s +``` + +#### 1.2 Install Cert-Manager +```bash +# Install cert-manager +kubectl apply -f deployments/cert-manager/cert-manager-install.yaml + +# Wait for cert-manager to be ready +kubectl wait --for=condition=ready pod -l app.kubernetes.io/name=cert-manager -n cert-manager --timeout=300s +``` + +#### 1.3 Install HashiCorp Vault +```bash +# Install Vault +kubectl apply -f deployments/vault/vault-install.yaml + +# Initialize Vault +kubectl apply -f deployments/vault/vault-secrets-config.yaml + +# Wait for Vault to be ready +kubectl wait --for=condition=ready pod -l app.kubernetes.io/name=vault -n vault --timeout=300s +``` + +#### 1.4 Install ELK Stack +```bash +# Install Elasticsearch +kubectl apply -f deployments/elk-stack/elasticsearch.yaml + +# Wait for Elasticsearch to be ready +kubectl wait --for=condition=ready pod -l app.kubernetes.io/name=elasticsearch -n elasticsearch --timeout=600s + +# Install Logstash +kubectl apply -f deployments/elk-stack/logstash.yaml + +# Install Kibana +kubectl apply -f deployments/elk-stack/kibana.yaml +``` + +#### 1.5 Install Velero for Backup +```bash +# Install Velero +kubectl apply -f deployments/backup/velero-install.yaml + +# Configure AWS credentials (update with your actual credentials) +kubectl patch secret velero-aws-credentials -n velero --patch '{"data":{"cloud":"[base64-encoded-aws-credentials]"}}' +``` + +#### 1.6 Install ArgoCD +```bash +# Install ArgoCD +kubectl apply -f deployments/argocd/argocd-install.yaml + +# Wait for ArgoCD to be ready +kubectl wait --for=condition=ready pod -l app.kubernetes.io/name=argocd -n argocd --timeout=300s +``` + +### 2. Deploy Platform Services + +#### 2.1 Deploy Core Services +```bash +# Deploy namespace and core services +kubectl apply -f deployments/kubernetes/00-namespace.yaml +kubectl apply -f deployments/kubernetes/01-mongodb.yaml +kubectl apply -f deployments/kubernetes/02-redis.yaml +kubectl apply -f deployments/kubernetes/03-api-server.yaml +kubectl apply -f deployments/kubernetes/04-charging-engine.yaml +kubectl apply -f deployments/kubernetes/05-packet-gateway.yaml +kubectl apply -f deployments/kubernetes/06-web-dashboard.yaml +``` + +#### 2.2 Deploy Monitoring Stack +```bash +# Deploy monitoring components +kubectl apply -f deployments/kubernetes/monitoring/ +``` + +#### 2.3 Deploy Ingress and Gateway +```bash +# Deploy Istio gateway +kubectl apply -f deployments/istio/telecom-platform-gateway.yaml +``` + +### 3. Configure GitOps + +#### 3.1 Apply ArgoCD Applications +```bash +# Deploy ArgoCD applications +kubectl apply -f deployments/argocd/argocd-app-of-apps.yaml +kubectl apply -f deployments/argocd/apps/ +``` + +#### 3.2 Configure ArgoCD Access +```bash +# Get ArgoCD admin password +kubectl get secret argocd-initial-admin-secret -n argocd -o jsonpath='{.data.password}' | base64 -d + +# Port forward to ArgoCD UI +kubectl port-forward svc/argocd-server -n argocd 8080:443 +``` + +### 4. Configure Autoscaling +```bash +# Deploy HPA and VPA configurations +kubectl apply -f deployments/autoscaling/hpa.yaml +kubectl apply -f deployments/autoscaling/vpa.yaml +``` + +### 5. Configure Compliance +```bash +# Deploy GDPR compliance +kubectl apply -f deployments/gdpr/gdpr-compliance.yaml +``` + +### 6. Configure Certificates +```bash +# Deploy certificate configurations +kubectl apply -f deployments/cert-manager/certificates.yaml +``` + +## Multi-Environment Deployment + +### Development Environment +```bash +# Deploy to dev environment +kubectl apply -k deployments/environments/dev +``` + +### Staging Environment +```bash +# Deploy to staging environment +kubectl apply -k deployments/environments/staging +``` + +### Production Environment +```bash +# Deploy to production environment +kubectl apply -k deployments/environments/prod +``` + +## Monitoring and Observability + +### Access Grafana +```bash +# Port forward to Grafana +kubectl port-forward svc/grafana -n monitoring 3000:3000 + +# Default credentials: admin/admin +``` + +### Access Kibana +```bash +# Port forward to Kibana +kubectl port-forward svc/kibana -n elasticsearch 5601:5601 +``` + +### Access Prometheus +```bash +# Port forward to Prometheus +kubectl port-forward svc/prometheus -n monitoring 9090:9090 +``` + +## Backup and Recovery + +### Manual Backup +```bash +# Create manual backup +kubectl create backup telecom-platform-manual-$(date +%Y%m%d) \ + --from-namespaces=telecom-platform \ + --include-cluster-resources=true \ + --storage-location=default \ + --wait +``` + +### Restore from Backup +```bash +# Restore from backup +kubectl create restore telecom-platform-restore \ + --from-backup=telecom-platform-manual-20231201 \ + --include-namespaces=telecom-platform \ + --wait +``` + +## Security Configuration + +### Vault Secrets Management +```bash +# Access Vault UI +kubectl port-forward svc/vault -n vault 8200:8200 + +# Login with root token (from initialization) +vault login + +# Add new secrets +vault kv put kv/telecom-platform/database url="postgresql://user:pass@postgres:5432/db" +``` + +### Certificate Management +```bash +# Check certificate status +kubectl get certificates -n telecom-platform + +# Renew certificates (automatic with cert-manager) +kubectl annotate certificate telecom-platform-tls cert-manager.io/renew=true -n telecom-platform +``` + +## Troubleshooting + +### Common Issues + +#### Pod Not Starting +```bash +# Check pod status and logs +kubectl describe pod -n +kubectl logs -n +``` + +#### Service Not Accessible +```bash +# Check service and endpoints +kubectl get svc -n +kubectl get endpoints -n + +# Check Istio configuration +kubectl get virtualservices -n +kubectl get gateways -n +``` + +#### Certificate Issues +```bash +# Check certificate status +kubectl describe certificate -n +kubectl get certificate -n -o yaml +``` + +#### Backup Issues +```bash +# Check Velero status +kubectl get backups -n velero +kubectl describe backup -n velero +``` + +### Performance Tuning + +#### Resource Limits +- Adjust CPU/memory limits based on actual usage +- Monitor HPA/VPA recommendations +- Consider node affinity for critical services + +#### Database Optimization +- Configure connection pooling +- Enable query caching +- Set up read replicas for scaling + +#### Logging Optimization +- Configure log retention policies +- Implement log sampling for high-volume services +- Use structured logging format + +## Security Best Practices + +### Network Security +- Use Istio mTLS for service-to-service communication +- Implement network policies +- Regularly review security group rules + +### Secrets Management +- Rotate secrets regularly +- Use Vault for dynamic secrets +- Enable audit logging for secret access + +### Compliance +- Regular GDPR compliance audits +- Data retention policy enforcement +- Privacy by design principles + +## Maintenance + +### Regular Tasks +- Weekly: Review backup status +- Monthly: Update certificates and secrets +- Quarterly: Security audit and compliance review +- Annually: Disaster recovery testing + +### Scaling Considerations +- Monitor resource utilization +- Plan for peak traffic patterns +- Implement auto-scaling policies +- Consider multi-region deployment + +## Support + +For issues and questions: +1. Check the troubleshooting section +2. Review logs and metrics +3. Consult the documentation +4. Contact the platform team + +## Version History + +- v1.0.0: Initial deployment with core services +- v1.1.0: Added Istio service mesh +- v1.2.0: Added ELK stack logging +- v1.3.0: Added Vault secrets management +- v1.4.0: Added GDPR compliance +- v1.5.0: Added auto-scaling and monitoring diff --git a/deployments/argocd/apps/telecom-platform-dev.yaml b/deployments/argocd/apps/telecom-platform-dev.yaml new file mode 100644 index 0000000..f294009 --- /dev/null +++ b/deployments/argocd/apps/telecom-platform-dev.yaml @@ -0,0 +1,32 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: telecom-platform-dev + namespace: argocd + labels: + app.kubernetes.io/name: telecom-platform-dev + app.kubernetes.io/component: platform + app.kubernetes.io/environment: dev + app.kubernetes.io/part-of: telecom-platform +spec: + project: default + source: + repoURL: https://github.com/nutcas3/telecom-platform.git + targetRevision: main + path: deployments/environments/dev + destination: + server: https://kubernetes.default.svc + namespace: telecom-platform-dev + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + - PrunePropagationPolicy=foreground + retry: + limit: 5 + backoff: + duration: 5s + factor: 2 + maxDuration: 3m diff --git a/deployments/argocd/apps/telecom-platform-prod.yaml b/deployments/argocd/apps/telecom-platform-prod.yaml new file mode 100644 index 0000000..5b03648 --- /dev/null +++ b/deployments/argocd/apps/telecom-platform-prod.yaml @@ -0,0 +1,32 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: telecom-platform-prod + namespace: argocd + labels: + app.kubernetes.io/name: telecom-platform-prod + app.kubernetes.io/component: platform + app.kubernetes.io/environment: prod + app.kubernetes.io/part-of: telecom-platform +spec: + project: default + source: + repoURL: https://github.com/nutcas3/telecom-platform.git + targetRevision: main + path: deployments/environments/prod + destination: + server: https://kubernetes.default.svc + namespace: telecom-platform-prod + syncPolicy: + automated: + prune: false # Manual sync for production + selfHeal: false + syncOptions: + - CreateNamespace=true + - PrunePropagationPolicy=foreground + retry: + limit: 3 + backoff: + duration: 10s + factor: 2 + maxDuration: 5m diff --git a/deployments/argocd/apps/telecom-platform-staging.yaml b/deployments/argocd/apps/telecom-platform-staging.yaml new file mode 100644 index 0000000..8742495 --- /dev/null +++ b/deployments/argocd/apps/telecom-platform-staging.yaml @@ -0,0 +1,32 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: telecom-platform-staging + namespace: argocd + labels: + app.kubernetes.io/name: telecom-platform-staging + app.kubernetes.io/component: platform + app.kubernetes.io/environment: staging + app.kubernetes.io/part-of: telecom-platform +spec: + project: default + source: + repoURL: https://github.com/nutcas3/telecom-platform.git + targetRevision: main + path: deployments/environments/staging + destination: + server: https://kubernetes.default.svc + namespace: telecom-platform-staging + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + - PrunePropagationPolicy=foreground + retry: + limit: 5 + backoff: + duration: 5s + factor: 2 + maxDuration: 3m diff --git a/deployments/argocd/apps/telecom-platform.yaml b/deployments/argocd/apps/telecom-platform.yaml new file mode 100644 index 0000000..64e19d9 --- /dev/null +++ b/deployments/argocd/apps/telecom-platform.yaml @@ -0,0 +1,31 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: telecom-platform + namespace: argocd + labels: + app.kubernetes.io/name: telecom-platform + app.kubernetes.io/component: platform + app.kubernetes.io/part-of: telecom-platform +spec: + project: default + source: + repoURL: https://github.com/nutcas3/telecom-platform.git + targetRevision: main + path: deployments/kubernetes + destination: + server: https://kubernetes.default.svc + namespace: telecom-platform + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + - PrunePropagationPolicy=foreground + retry: + limit: 5 + backoff: + duration: 5s + factor: 2 + maxDuration: 3m diff --git a/deployments/argocd/argocd-app-of-apps.yaml b/deployments/argocd/argocd-app-of-apps.yaml new file mode 100644 index 0000000..9188652 --- /dev/null +++ b/deployments/argocd/argocd-app-of-apps.yaml @@ -0,0 +1,31 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: telecom-platform-root + namespace: argocd + labels: + app.kubernetes.io/name: telecom-platform-root + app.kubernetes.io/component: gitops + app.kubernetes.io/part-of: telecom-platform +spec: + project: default + source: + repoURL: https://github.com/nutcas3/telecom-platform.git + targetRevision: main + path: deployments/argocd/apps + destination: + server: https://kubernetes.default.svc + namespace: argocd + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + - PrunePropagationPolicy=foreground + retry: + limit: 5 + backoff: + duration: 5s + factor: 2 + maxDuration: 3m diff --git a/deployments/argocd/argocd-install.yaml b/deployments/argocd/argocd-install.yaml new file mode 100644 index 0000000..fe7ada1 --- /dev/null +++ b/deployments/argocd/argocd-install.yaml @@ -0,0 +1,36 @@ +apiVersion: argoproj.io/v1alpha1 +kind: ArgoCD +metadata: + name: argocd + namespace: argocd +spec: + server: + route: + enabled: true + controller: + processors: {} + resourceTrackingMethod: annotation + repo: + mtls: {} + sso: + provider: dex + dex: + config: | + connectors: + - type: oidc + id: oidc + name: OpenID Connect + config: + issuer: https://your-oidc-provider.com + clientID: argocd + clientSecret: $oidc.clientSecret + requestedScopes: ["openid", "profile", "email", "groups"] +--- +apiVersion: v1 +kind: Secret +metadata: + name: argocd-secret + namespace: argocd +type: Opaque +stringData: + oidc.clientSecret: "your-oidc-client-secret" diff --git a/deployments/argocd/argocd-namespace.yaml b/deployments/argocd/argocd-namespace.yaml new file mode 100644 index 0000000..a2b5058 --- /dev/null +++ b/deployments/argocd/argocd-namespace.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: argocd + labels: + name: argocd + app.kubernetes.io/part-of: telecom-platform + app.kubernetes.io/component: gitops + annotations: + telecom-platform.io/managed-by: "gitops" diff --git a/deployments/autoscaling/hpa.yaml b/deployments/autoscaling/hpa.yaml new file mode 100644 index 0000000..5a01a44 --- /dev/null +++ b/deployments/autoscaling/hpa.yaml @@ -0,0 +1,218 @@ +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: api-server-hpa + namespace: telecom-platform + labels: + app.kubernetes.io/name: api-server-hpa + app.kubernetes.io/component: autoscaling + app.kubernetes.io/part-of: telecom-platform +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: api-server + minReplicas: 2 + maxReplicas: 10 + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 70 + - type: Resource + resource: + name: memory + target: + type: Utilization + averageUtilization: 80 + - type: Pods + pods: + metric: + name: http_requests_per_second + target: + type: AverageValue + averageValue: "100" + - type: Object + object: + metric: + name: queue_messages + describedObject: + apiVersion: v1 + kind: Service + name: api-server + target: + type: Value + value: "1000" + behavior: + scaleDown: + stabilizationWindowSeconds: 300 + policies: + - type: Percent + value: 10 + periodSeconds: 60 + - type: Pods + value: 2 + periodSeconds: 60 + selectPolicy: Min + scaleUp: + stabilizationWindowSeconds: 60 + policies: + - type: Percent + value: 50 + periodSeconds: 60 + - type: Pods + value: 4 + periodSeconds: 60 + selectPolicy: Max +--- +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: charging-engine-hpa + namespace: telecom-platform + labels: + app.kubernetes.io/name: charging-engine-hpa + app.kubernetes.io/component: autoscaling + app.kubernetes.io/part-of: telecom-platform +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: charging-engine + minReplicas: 2 + maxReplicas: 8 + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 75 + - type: Resource + resource: + name: memory + target: + type: Utilization + averageUtilization: 85 + - type: Pods + pods: + metric: + name: billing_events_per_second + target: + type: AverageValue + averageValue: "50" + behavior: + scaleDown: + stabilizationWindowSeconds: 300 + policies: + - type: Percent + value: 10 + periodSeconds: 60 + scaleUp: + stabilizationWindowSeconds: 60 + policies: + - type: Percent + value: 100 + periodSeconds: 60 +--- +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: packet-gateway-hpa + namespace: telecom-platform + labels: + app.kubernetes.io/name: packet-gateway-hpa + app.kubernetes.io/component: autoscaling + app.kubernetes.io/part-of: telecom-platform +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: packet-gateway + minReplicas: 2 + maxReplicas: 12 + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 60 + - type: Resource + resource: + name: memory + target: + type: Utilization + averageUtilization: 75 + - type: Pods + pods: + metric: + name: packets_per_second + target: + type: AverageValue + averageValue: "1000" + behavior: + scaleDown: + stabilizationWindowSeconds: 300 + policies: + - type: Percent + value: 15 + periodSeconds: 60 + scaleUp: + stabilizationWindowSeconds: 30 + policies: + - type: Percent + value: 200 + periodSeconds: 60 +--- +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: web-dashboard-hpa + namespace: telecom-platform + labels: + app.kubernetes.io/name: web-dashboard-hpa + app.kubernetes.io/component: autoscaling + app.kubernetes.io/part-of: telecom-platform +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: web-dashboard + minReplicas: 1 + maxReplicas: 6 + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 70 + - type: Resource + resource: + name: memory + target: + type: Utilization + averageUtilization: 80 + - type: Pods + pods: + metric: + name: active_sessions + target: + type: AverageValue + averageValue: "50" + behavior: + scaleDown: + stabilizationWindowSeconds: 300 + policies: + - type: Percent + value: 20 + periodSeconds: 60 + scaleUp: + stabilizationWindowSeconds: 60 + policies: + - type: Percent + value: 100 + periodSeconds: 60 diff --git a/deployments/autoscaling/vpa.yaml b/deployments/autoscaling/vpa.yaml new file mode 100644 index 0000000..33ec727 --- /dev/null +++ b/deployments/autoscaling/vpa.yaml @@ -0,0 +1,107 @@ +apiVersion: autoscaling.k8s.io/v1 +kind: VerticalPodAutoscaler +metadata: + name: api-server-vpa + namespace: telecom-platform + labels: + app.kubernetes.io/name: api-server-vpa + app.kubernetes.io/component: autoscaling + app.kubernetes.io/part-of: telecom-platform +spec: + targetRef: + apiVersion: apps/v1 + kind: Deployment + name: api-server + updatePolicy: + updateMode: "Auto" + resourcePolicy: + containerPolicies: + - containerName: api-server + minAllowed: + cpu: 100m + memory: 128Mi + maxAllowed: + cpu: 2000m + memory: 2Gi + controlledResources: ["cpu", "memory"] +--- +apiVersion: autoscaling.k8s.io/v1 +kind: VerticalPodAutoscaler +metadata: + name: charging-engine-vpa + namespace: telecom-platform + labels: + app.kubernetes.io/name: charging-engine-vpa + app.kubernetes.io/component: autoscaling + app.kubernetes.io/part-of: telecom-platform +spec: + targetRef: + apiVersion: apps/v1 + kind: Deployment + name: charging-engine + updatePolicy: + updateMode: "Auto" + resourcePolicy: + containerPolicies: + - containerName: charging-engine + minAllowed: + cpu: 100m + memory: 128Mi + maxAllowed: + cpu: 1500m + memory: 1.5Gi + controlledResources: ["cpu", "memory"] +--- +apiVersion: autoscaling.k8s.io/v1 +kind: VerticalPodAutoscaler +metadata: + name: packet-gateway-vpa + namespace: telecom-platform + labels: + app.kubernetes.io/name: packet-gateway-vpa + app.kubernetes.io/component: autoscaling + app.kubernetes.io/part-of: telecom-platform +spec: + targetRef: + apiVersion: apps/v1 + kind: Deployment + name: packet-gateway + updatePolicy: + updateMode: "Auto" + resourcePolicy: + containerPolicies: + - containerName: packet-gateway + minAllowed: + cpu: 100m + memory: 128Mi + maxAllowed: + cpu: 3000m + memory: 3Gi + controlledResources: ["cpu", "memory"] +--- +apiVersion: autoscaling.k8s.io/v1 +kind: VerticalPodAutoscaler +metadata: + name: web-dashboard-vpa + namespace: telecom-platform + labels: + app.kubernetes.io/name: web-dashboard-vpa + app.kubernetes.io/component: autoscaling + app.kubernetes.io/part-of: telecom-platform +spec: + targetRef: + apiVersion: apps/v1 + kind: Deployment + name: web-dashboard + updatePolicy: + updateMode: "Auto" + resourcePolicy: + containerPolicies: + - containerName: web-dashboard + minAllowed: + cpu: 50m + memory: 64Mi + maxAllowed: + cpu: 1000m + memory: 1Gi + controlledResources: ["cpu", "memory"] diff --git a/deployments/backup/velero-install.yaml b/deployments/backup/velero-install.yaml new file mode 100644 index 0000000..f72cf2e --- /dev/null +++ b/deployments/backup/velero-install.yaml @@ -0,0 +1,146 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: velero + labels: + app.kubernetes.io/name: velero + app.kubernetes.io/component: backup + app.kubernetes.io/part-of: telecom-platform +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: velero + namespace: velero + labels: + app.kubernetes.io/name: velero + app.kubernetes.io/component: backup + app.kubernetes.io/part-of: telecom-platform +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: velero + labels: + app.kubernetes.io/name: velero + app.kubernetes.io/component: backup + app.kubernetes.io/part-of: telecom-platform +rules: +- apiGroups: + - '*' + resources: + - '*' + verbs: + - '*' +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: velero + labels: + app.kubernetes.io/name: velero + app.kubernetes.io/component: backup + app.kubernetes.io/part-of: telecom-platform +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: velero +subjects: +- kind: ServiceAccount + name: velero + namespace: velero +--- +apiVersion: v1 +kind: Secret +metadata: + name: velero-aws-credentials + namespace: velero + labels: + app.kubernetes.io/name: velero + app.kubernetes.io/component: backup + app.kubernetes.io/part-of: telecom-platform +type: Opaque +stringData: + cloud: | + [default] + aws_access_key_id = YOUR_AWS_ACCESS_KEY_ID + aws_secret_access_key = YOUR_AWS_SECRET_ACCESS_KEY +--- +apiVersion: velero.io/v1 +kind: BackupStorageLocation +metadata: + name: default + namespace: velero + labels: + app.kubernetes.io/name: velero + app.kubernetes.io/component: backup + app.kubernetes.io/part-of: telecom-platform +spec: + provider: aws + objectStorage: + bucket: telecom-platform-backups + prefix: "" + config: + region: us-east-1 + profile: default +--- +apiVersion: velero.io/v1 +kind: VolumeSnapshotLocation +metadata: + name: default + namespace: velero + labels: + app.kubernetes.io/name: velero + app.kubernetes.io/component: backup + app.kubernetes.io/part-of: telecom-platform +spec: + provider: aws + config: + region: us-east-1 + profile: default +--- +apiVersion: velero.io/v1 +kind: Schedule +metadata: + name: telecom-platform-daily-backup + namespace: velero + labels: + app.kubernetes.io/name: velero + app.kubernetes.io/component: backup + app.kubernetes.io/part-of: telecom-platform +spec: + schedule: "0 2 * * *" # Daily at 2 AM + template: + includedNamespaces: + - telecom-platform + - telecom-platform-prod + storageLocation: default + volumeSnapshotLocations: + - default + ttl: "720h" # 30 days + csiSnapshotTimeout: 10m + itemOperationTimeout: 10m + useOwnerReferencesInBackup: true +--- +apiVersion: velero.io/v1 +kind: Schedule +metadata: + name: telecom-platform-weekly-backup + namespace: velero + labels: + app.kubernetes.io/name: velero + app.kubernetes.io/component: backup + app.kubernetes.io/part-of: telecom-platform +spec: + schedule: "0 3 * * 0" # Weekly on Sunday at 3 AM + template: + includedNamespaces: + - telecom-platform + - telecom-platform-prod + storageLocation: default + volumeSnapshotLocations: + - default + ttl: "2160h" # 90 days + csiSnapshotTimeout: 10m + itemOperationTimeout: 10m + useOwnerReferencesInBackup: true diff --git a/deployments/cert-manager/cert-manager-install.yaml b/deployments/cert-manager/cert-manager-install.yaml new file mode 100644 index 0000000..aaada8f --- /dev/null +++ b/deployments/cert-manager/cert-manager-install.yaml @@ -0,0 +1,263 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: cert-manager + labels: + app.kubernetes.io/name: cert-manager + app.kubernetes.io/component: certificates + app.kubernetes.io/part-of: telecom-platform +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: cert-manager + namespace: cert-manager + labels: + app.kubernetes.io/name: cert-manager + app.kubernetes.io/component: certificates + app.kubernetes.io/part-of: telecom-platform +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: cert-manager + labels: + app.kubernetes.io/name: cert-manager + app.kubernetes.io/component: certificates + app.kubernetes.io/part-of: telecom-platform +rules: +- apiGroups: + - "" + resources: + - secrets + - events + verbs: + - create + - update + - patch + - get + - list + - watch +- apiGroups: + - "" + resources: + - serviceaccounts + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - services + verbs: + - get + - list + - watch +- apiGroups: + - apps + resources: + - deployments + verbs: + - get + - list + - watch +- apiGroups: + - networking.k8s.io + resources: + - ingresses + verbs: + - get + - list + - watch + - update + - patch +- apiGroups: + - networking.k8s.io + resources: + - ingresses/status + verbs: + - update + - patch +- apiGroups: + - cert-manager.io + resources: + - certificates + - certificaterequests + - issuers + - clusterissuers + verbs: + - create + - update + - patch + - delete + - get + - list + - watch +- apiGroups: + - cert-manager.io + resources: + - certificates/status + - certificaterequests/status + - issuers/status + - clusterissuers/status + verbs: + - update + - patch +- apiGroups: + - acme.cert-manager.io + resources: + - challenges + - orders + verbs: + - create + - update + - patch + - delete + - get + - list + - watch +- apiGroups: + - acme.cert-manager.io + resources: + - challenges/status + - orders/status + verbs: + - update + - patch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: cert-manager + labels: + app.kubernetes.io/name: cert-manager + app.kubernetes.io/component: certificates + app.kubernetes.io/part-of: telecom-platform +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: cert-manager +subjects: +- kind: ServiceAccount + name: cert-manager + namespace: cert-manager +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: cert-manager + namespace: cert-manager + labels: + app.kubernetes.io/name: cert-manager + app.kubernetes.io/component: certificates + app.kubernetes.io/part-of: telecom-platform +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: cert-manager + app.kubernetes.io/component: certificates + template: + metadata: + labels: + app.kubernetes.io/name: cert-manager + app.kubernetes.io/component: certificates + spec: + serviceAccountName: cert-manager + containers: + - name: cert-manager + image: quay.io/jetstack/cert-manager-controller:v1.12.0 + ports: + - containerPort: 9402 + name: metrics + env: + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: SERVICE_ACCOUNT_NAME + valueFrom: + fieldRef: + fieldPath: spec.serviceAccountName + args: + - --v=2 + - --cluster-resource-namespace=$(POD_NAMESPACE) + - --leader-election-namespace=$(POD_NAMESPACE) + - --default-issuer-name=telecom-platform-ca + - --default-issuer-kind=ClusterIssuer + resources: + requests: + cpu: 10m + memory: 32Mi + limits: + cpu: 100m + memory: 128Mi +--- +apiVersion: v1 +kind: Service +metadata: + name: cert-manager + namespace: cert-manager + labels: + app.kubernetes.io/name: cert-manager + app.kubernetes.io/component: certificates + app.kubernetes.io/part-of: telecom-platform +spec: + ports: + - port: 9402 + name: metrics + targetPort: 9402 + selector: + app.kubernetes.io/name: cert-manager + app.kubernetes.io/component: certificates +--- +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: telecom-platform-ca + labels: + app.kubernetes.io/name: telecom-platform-ca + app.kubernetes.io/component: certificates + app.kubernetes.io/part-of: telecom-platform +spec: + ca: + secretName: telecom-platform-ca-secret +--- +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: letsencrypt-staging + labels: + app.kubernetes.io/name: letsencrypt-staging + app.kubernetes.io/component: certificates + app.kubernetes.io/part-of: telecom-platform +spec: + acme: + server: https://acme-staging-v02.api.letsencrypt.org/directory + email: admin@telecom-platform.com + privateKeySecretRef: + name: letsencrypt-staging-account-key + solvers: + - http01: + ingress: + class: istio +--- +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: letsencrypt-prod + labels: + app.kubernetes.io/name: letsencrypt-prod + app.kubernetes.io/component: certificates + app.kubernetes.io/part-of: telecom-platform +spec: + acme: + server: https://acme-v02.api.letsencrypt.org/directory + email: admin@telecom-platform.com + privateKeySecretRef: + name: letsencrypt-prod-account-key + solvers: + - http01: + ingress: + class: istio diff --git a/deployments/cert-manager/certificates.yaml b/deployments/cert-manager/certificates.yaml new file mode 100644 index 0000000..fbb7d00 --- /dev/null +++ b/deployments/cert-manager/certificates.yaml @@ -0,0 +1,123 @@ +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: telecom-platform-tls + namespace: telecom-platform + labels: + app.kubernetes.io/name: telecom-platform-tls + app.kubernetes.io/component: certificates + app.kubernetes.io/part-of: telecom-platform +spec: + secretName: telecom-platform-tls + issuerRef: + name: letsencrypt-prod + kind: ClusterIssuer + dnsNames: + - api.telecom.local + - dashboard.telecom.local + - grafana.telecom.local + - prometheus.telecom.local + - kibana.telecom.local + - vault.telecom.local +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: telecom-platform-api-tls + namespace: telecom-platform + labels: + app.kubernetes.io/name: telecom-platform-api-tls + app.kubernetes.io/component: certificates + app.kubernetes.io/part-of: telecom-platform +spec: + secretName: telecom-platform-api-tls + issuerRef: + name: letsencrypt-prod + kind: ClusterIssuer + dnsNames: + - api.telecom.local +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: telecom-platform-dashboard-tls + namespace: telecom-platform + labels: + app.kubernetes.io/name: telecom-platform-dashboard-tls + app.kubernetes.io/component: certificates + app.kubernetes.io/part-of: telecom-platform +spec: + secretName: telecom-platform-dashboard-tls + issuerRef: + name: letsencrypt-prod + kind: ClusterIssuer + dnsNames: + - dashboard.telecom.local +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: telecom-platform-grafana-tls + namespace: telecom-platform + labels: + app.kubernetes.io/name: telecom-platform-grafana-tls + app.kubernetes.io/component: certificates + app.kubernetes.io/part-of: telecom-platform +spec: + secretName: telecom-platform-grafana-tls + issuerRef: + name: letsencrypt-prod + kind: ClusterIssuer + dnsNames: + - grafana.telecom.local +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: telecom-platform-prometheus-tls + namespace: telecom-platform + labels: + app.kubernetes.io/name: telecom-platform-prometheus-tls + app.kubernetes.io/component: certificates + app.kubernetes.io/part-of: telecom-platform +spec: + secretName: telecom-platform-prometheus-tls + issuerRef: + name: letsencrypt-prod + kind: ClusterIssuer + dnsNames: + - prometheus.telecom.local +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: telecom-platform-kibana-tls + namespace: telecom-platform + labels: + app.kubernetes.io/name: telecom-platform-kibana-tls + app.kubernetes.io/component: certificates + app.kubernetes.io/part-of: telecom-platform +spec: + secretName: telecom-platform-kibana-tls + issuerRef: + name: letsencrypt-prod + kind: ClusterIssuer + dnsNames: + - kibana.telecom.local +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: telecom-platform-vault-tls + namespace: vault + labels: + app.kubernetes.io/name: telecom-platform-vault-tls + app.kubernetes.io/component: certificates + app.kubernetes.io/part-of: telecom-platform +spec: + secretName: telecom-platform-vault-tls + issuerRef: + name: letsencrypt-prod + kind: ClusterIssuer + dnsNames: + - vault.telecom.local diff --git a/deployments/elk-stack/elasticsearch.yaml b/deployments/elk-stack/elasticsearch.yaml new file mode 100644 index 0000000..810d366 --- /dev/null +++ b/deployments/elk-stack/elasticsearch.yaml @@ -0,0 +1,141 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: elasticsearch + labels: + app.kubernetes.io/name: elasticsearch + app.kubernetes.io/component: logging + app.kubernetes.io/part-of: telecom-platform +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: elasticsearch-master + namespace: elasticsearch + labels: + app.kubernetes.io/name: elasticsearch + app.kubernetes.io/component: master + app.kubernetes.io/part-of: telecom-platform +spec: + serviceName: elasticsearch-master + replicas: 3 + selector: + matchLabels: + app.kubernetes.io/name: elasticsearch + app.kubernetes.io/component: master + template: + metadata: + labels: + app.kubernetes.io/name: elasticsearch + app.kubernetes.io/component: master + app.kubernetes.io/part-of: telecom-platform + spec: + securityContext: + fsGroup: 1000 + runAsUser: 1000 + initContainers: + - name: increase-vm-max-map + image: busybox:1.35.0 + command: ["sysctl", "-w", "vm.max_map_count=262144"] + securityContext: + privileged: true + - name: increase-fd-limit + image: busybox:1.35.0 + command: ["sh", "-c", "ulimit -n 65536"] + securityContext: + privileged: true + containers: + - name: elasticsearch + image: docker.elastic.co/elasticsearch/elasticsearch:8.10.0 + ports: + - containerPort: 9200 + name: rest + - containerPort: 9300 + name: inter-node + env: + - name: cluster.name + value: telecom-platform-logs + - name: node.name + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: discovery.seed_hosts + value: "elasticsearch-master" + - name: cluster.initial_master_nodes + value: "elasticsearch-master-0,elasticsearch-master-1,elasticsearch-master-2" + - name: ES_JAVA_OPTS + value: "-Xms1g -Xmx1g" + - name: xpack.security.enabled + value: "false" + - name: xpack.monitoring.collection.enabled + value: "true" + resources: + requests: + cpu: 500m + memory: 1Gi + limits: + cpu: 1000m + memory: 2Gi + volumeMounts: + - name: data + mountPath: /usr/share/elasticsearch/data + - name: config + mountPath: /usr/share/elasticsearch/config + volumes: + - name: config + configMap: + name: elasticsearch-config + volumeClaimTemplates: + - metadata: + name: data + labels: + app.kubernetes.io/name: elasticsearch + app.kubernetes.io/component: master + app.kubernetes.io/part-of: telecom-platform + spec: + accessModes: ["ReadWriteOnce"] + storageClassName: "standard" + resources: + requests: + storage: 20Gi +--- +apiVersion: v1 +kind: Service +metadata: + name: elasticsearch-master + namespace: elasticsearch + labels: + app.kubernetes.io/name: elasticsearch + app.kubernetes.io/component: master + app.kubernetes.io/part-of: telecom-platform +spec: + ports: + - port: 9200 + name: rest + - port: 9300 + name: inter-node + selector: + app.kubernetes.io/name: elasticsearch + app.kubernetes.io/component: master + clusterIP: None +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: elasticsearch-config + namespace: elasticsearch + labels: + app.kubernetes.io/name: elasticsearch + app.kubernetes.io/component: master + app.kubernetes.io/part-of: telecom-platform +data: + elasticsearch.yml: | + cluster.name: telecom-platform-logs + node.name: ${HOSTNAME} + network.host: 0.0.0.0 + discovery.seed_hosts: ["elasticsearch-master"] + cluster.initial_master_nodes: ["elasticsearch-master-0", "elasticsearch-master-1", "elasticsearch-master-2"] + xpack.security.enabled: false + xpack.monitoring.collection.enabled: true + xpack.monitoring.elasticsearch.collection.enabled: true + indices.lifecycle.poll_interval: 1m diff --git a/deployments/elk-stack/kibana.yaml b/deployments/elk-stack/kibana.yaml new file mode 100644 index 0000000..3fc902a --- /dev/null +++ b/deployments/elk-stack/kibana.yaml @@ -0,0 +1,106 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: kibana + namespace: elasticsearch + labels: + app.kubernetes.io/name: kibana + app.kubernetes.io/component: logging + app.kubernetes.io/part-of: telecom-platform +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: kibana + app.kubernetes.io/component: logging + app.kubernetes.io/part-of: telecom-platform + template: + metadata: + labels: + app.kubernetes.io/name: kibana + app.kubernetes.io/component: logging + app.kubernetes.io/part-of: telecom-platform + spec: + containers: + - name: kibana + image: docker.elastic.co/kibana/kibana:8.10.0 + ports: + - containerPort: 5601 + name: ui + env: + - name: ELASTICSEARCH_HOSTS + value: "http://elasticsearch-master:9200" + - name: SERVER_NAME + value: kibana + - name: SERVER_HOST + value: "0.0.0.0" + - name: SERVER_PORT + value: "5601" + - name: SERVER_PUBLICBASEURL + value: "http://kibana.telecom.local:5601" + - name: LOGGING_ROOT_LEVEL + value: "info" + resources: + requests: + cpu: 100m + memory: 256Mi + limits: + cpu: 500m + memory: 512Mi + livenessProbe: + httpGet: + path: /api/status + port: ui + initialDelaySeconds: 30 + periodSeconds: 10 + readinessProbe: + httpGet: + path: /api/status + port: ui + initialDelaySeconds: 5 + periodSeconds: 5 +--- +apiVersion: v1 +kind: Service +metadata: + name: kibana + namespace: elasticsearch + labels: + app.kubernetes.io/name: kibana + app.kubernetes.io/component: logging + app.kubernetes.io/part-of: telecom-platform +spec: + ports: + - port: 5601 + name: ui + targetPort: 5601 + selector: + app.kubernetes.io/name: kibana + app.kubernetes.io/component: logging + app.kubernetes.io/part-of: telecom-platform + type: ClusterIP +--- +apiVersion: networking.istio.io/v1beta1 +kind: VirtualService +metadata: + name: kibana + namespace: elasticsearch + labels: + app.kubernetes.io/name: kibana + app.kubernetes.io/component: logging + app.kubernetes.io/part-of: telecom-platform +spec: + hosts: + - kibana.telecom.local + gateways: + - telecom-platform-gateway + http: + - match: + - uri: + prefix: / + route: + - destination: + host: kibana + port: + number: 5601 + timeout: 30s diff --git a/deployments/elk-stack/logstash.yaml b/deployments/elk-stack/logstash.yaml new file mode 100644 index 0000000..bd910f4 --- /dev/null +++ b/deployments/elk-stack/logstash.yaml @@ -0,0 +1,204 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: logstash + namespace: elasticsearch + labels: + app.kubernetes.io/name: logstash + app.kubernetes.io/component: logging + app.kubernetes.io/part-of: telecom-platform +spec: + replicas: 2 + selector: + matchLabels: + app.kubernetes.io/name: logstash + app.kubernetes.io/component: logging + app.kubernetes.io/part-of: telecom-platform + template: + metadata: + labels: + app.kubernetes.io/name: logstash + app.kubernetes.io/component: logging + app.kubernetes.io/part-of: telecom-platform + spec: + containers: + - name: logstash + image: docker.elastic.co/logstash/logstash:8.10.0 + ports: + - containerPort: 5044 + name: beats + - containerPort: 9600 + name: http + env: + - name: LS_JAVA_OPTS + value: "-Xmx512m -Xms512m" + - name: ELASTICSEARCH_HOSTS + value: "http://elasticsearch-master:9200" + - name: LOG_LEVEL + value: "info" + resources: + requests: + cpu: 200m + memory: 512Mi + limits: + cpu: 1000m + memory: 1Gi + volumeMounts: + - name: config + mountPath: /usr/share/logstash/pipeline + - name: settings + mountPath: /usr/share/logstash/config + livenessProbe: + httpGet: + path: / + port: http + initialDelaySeconds: 60 + periodSeconds: 10 + readinessProbe: + httpGet: + path: / + port: http + initialDelaySeconds: 30 + periodSeconds: 5 + volumes: + - name: config + configMap: + name: logstash-config + - name: settings + configMap: + name: logstash-settings +--- +apiVersion: v1 +kind: Service +metadata: + name: logstash + namespace: elasticsearch + labels: + app.kubernetes.io/name: logstash + app.kubernetes.io/component: logging + app.kubernetes.io/part-of: telecom-platform +spec: + ports: + - port: 5044 + name: beats + targetPort: 5044 + - port: 9600 + name: http + targetPort: 9600 + selector: + app.kubernetes.io/name: logstash + app.kubernetes.io/component: logging + app.kubernetes.io/part-of: telecom-platform + type: ClusterIP +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: logstash-config + namespace: elasticsearch + labels: + app.kubernetes.io/name: logstash + app.kubernetes.io/component: logging + app.kubernetes.io/part-of: telecom-platform +data: + logstash.conf: | + input { + beats { + port => 5044 + } + http { + port => 8080 + codec => json + } + } + + filter { + # Parse JSON logs + if [message] { + json { + source => "message" + } + } + + # Add environment tag + mutate { + add_field => { "environment" => "production" } + } + + # Parse timestamp + if [timestamp] { + date { + match => [ "timestamp", "ISO8601" ] + } + } + + # Add telecom platform specific fields + if [service] { + mutate { + add_field => { "[@metadata][service]" => "%{service}" } + } + } + + # GDPR compliance - anonymize sensitive data + if [phone] { + mutate { + replace => { "phone" => "XXX-XXX-XXXX" } + } + } + + if [email] { + mutate { + replace => { "email" => "XXXX@XXXX.com" } + } + } + } + + output { + elasticsearch { + hosts => ["elasticsearch-master:9200"] + index => "telecom-platform-logs-%{+YYYY.MM.dd}" + template_name => "telecom-platform" + template_pattern => "telecom-platform-*" + template => { + "index_patterns" => ["telecom-platform-*"], + "settings" => { + "number_of_shards" => 3, + "number_of_replicas" => 1, + "index.lifecycle.name" => "telecom-platform-policy", + "index.lifecycle.rollover_alias" => "telecom-platform-logs" + }, + "mappings" => { + "properties" => { + "@timestamp" => { "type" => "date" }, + "level" => { "type" => "keyword" }, + "service" => { "type" => "keyword" }, + "environment" => { "type" => "keyword" }, + "message" => { "type" => "text" }, + "user_id" => { "type" => "keyword" }, + "request_id" => { "type" => "keyword" }, + "duration_ms" => { "type" => "long" }, + "status_code" => { "type" => "integer" } + } + } + } + } + } +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: logstash-settings + namespace: elasticsearch + labels: + app.kubernetes.io/name: logstash + app.kubernetes.io/component: logging + app.kubernetes.io/part-of: telecom-platform +data: + logstash.yml: | + http.host: "0.0.0.0" + xpack.monitoring.elasticsearch.hosts: [ "http://elasticsearch-master:9200" ] + xpack.monitoring.enabled: true + path.config: /usr/share/logstash/pipeline + pipeline.workers: 2 + pipeline.batch.size: 125 + pipeline.batch.delay: 50 diff --git a/deployments/environments/dev/kustomization.yaml b/deployments/environments/dev/kustomization.yaml new file mode 100644 index 0000000..2220481 --- /dev/null +++ b/deployments/environments/dev/kustomization.yaml @@ -0,0 +1,40 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +metadata: + name: telecom-platform-dev +resources: +- ../../kubernetes/00-namespace.yaml +- ../../kubernetes/01-mongodb.yaml +- ../../kubernetes/02-redis.yaml +- ../../kubernetes/03-api-server.yaml +- ../../kubernetes/04-charging-engine.yaml +- ../../kubernetes/manifests/ +patchesStrategicMerge: +- api-server-dev-patch.yaml +- charging-engine-dev-patch.yaml +namespace: telecom-platform-dev +commonLabels: + app.kubernetes.io/environment: dev + app.kubernetes.io/managed-by: kustomize +configMapGenerator: +- name: telecom-platform-config + literals: + - LOG_LEVEL=debug + - ENVIRONMENT=dev + - RATE_LIMIT_REQUESTS=100 + - RATE_LIMIT_WINDOW=60 +secretGenerator: +- name: telecom-platform-secrets + literals: + - DATABASE_URL=postgresql://postgres:dev123@postgres:5432/telecom_dev + - REDIS_URL=redis://redis:6379 + - JWT_SECRET=dev-jwt-secret-key +replicas: +- name: api-server + count: 1 +- name: charging-engine + count: 1 +- name: packet-gateway + count: 1 +- name: web-dashboard + count: 1 diff --git a/deployments/environments/prod/kustomization.yaml b/deployments/environments/prod/kustomization.yaml new file mode 100644 index 0000000..7329c28 --- /dev/null +++ b/deployments/environments/prod/kustomization.yaml @@ -0,0 +1,49 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +metadata: + name: telecom-platform-prod +resources: +- ../../kubernetes/00-namespace.yaml +- ../../kubernetes/01-mongodb.yaml +- ../../kubernetes/02-redis.yaml +- ../../kubernetes/03-api-server.yaml +- ../../kubernetes/04-charging-engine.yaml +- ../../kubernetes/manifests/ +- ../istio/ +- ../backup/ +- ../monitoring/ +- ../elk-stack/ +patchesStrategicMerge: +- api-server-prod-patch.yaml +- charging-engine-prod-patch.yaml +- mongodb-prod-patch.yaml +namespace: telecom-platform-prod +commonLabels: + app.kubernetes.io/environment: prod + app.kubernetes.io/managed-by: kustomize +configMapGenerator: +- name: telecom-platform-config + literals: + - LOG_LEVEL=warn + - ENVIRONMENT=production + - RATE_LIMIT_REQUESTS=1000 + - RATE_LIMIT_WINDOW=60 + - METRICS_ENABLED=true + - GDPR_ENABLED=true + - AUDIT_ENABLED=true +secretGenerator: +- name: telecom-platform-secrets + literals: + - DATABASE_URL=postgresql://postgres:prod123@postgres:5432/telecom_prod + - REDIS_URL=redis://redis:6379 + - JWT_SECRET=prod-jwt-secret-key + - ENCRYPTION_KEY=prod-encryption-key-256bits +replicas: +- name: api-server + count: 3 +- name: charging-engine + count: 2 +- name: packet-gateway + count: 2 +- name: web-dashboard + count: 2 diff --git a/deployments/environments/staging/kustomization.yaml b/deployments/environments/staging/kustomization.yaml new file mode 100644 index 0000000..89f74a2 --- /dev/null +++ b/deployments/environments/staging/kustomization.yaml @@ -0,0 +1,41 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +metadata: + name: telecom-platform-staging +resources: +- ../../kubernetes/00-namespace.yaml +- ../../kubernetes/01-mongodb.yaml +- ../../kubernetes/02-redis.yaml +- ../../kubernetes/03-api-server.yaml +- ../../kubernetes/04-charging-engine.yaml +- ../../kubernetes/manifests/ +patchesStrategicMerge: +- api-server-staging-patch.yaml +- charging-engine-staging-patch.yaml +namespace: telecom-platform-staging +commonLabels: + app.kubernetes.io/environment: staging + app.kubernetes.io/managed-by: kustomize +configMapGenerator: +- name: telecom-platform-config + literals: + - LOG_LEVEL=info + - ENVIRONMENT=staging + - RATE_LIMIT_REQUESTS=500 + - RATE_LIMIT_WINDOW=60 + - METRICS_ENABLED=true +secretGenerator: +- name: telecom-platform-secrets + literals: + - DATABASE_URL=postgresql://postgres:staging123@postgres:5432/telecom_staging + - REDIS_URL=redis://redis:6379 + - JWT_SECRET=staging-jwt-secret-key +replicas: +- name: api-server + count: 2 +- name: charging-engine + count: 2 +- name: packet-gateway + count: 2 +- name: web-dashboard + count: 2 diff --git a/deployments/gdpr/gdpr-compliance.yaml b/deployments/gdpr/gdpr-compliance.yaml new file mode 100644 index 0000000..2981dcd --- /dev/null +++ b/deployments/gdpr/gdpr-compliance.yaml @@ -0,0 +1,258 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: gdpr-compliance-config + namespace: telecom-platform + labels: + app.kubernetes.io/name: gdpr-compliance + app.kubernetes.io/component: compliance + app.kubernetes.io/part-of: telecom-platform +data: + gdpr-policy.yaml: | + + dataRetention: + logs: "30d" + metrics: "90d" + audit: "365d" + billing: "7y" + personalData: "5y" + consent: "3y" + + privacy: + encryption: + enabled: true + algorithm: "AES-256-GCM" + keyRotation: "90d" + anonymization: + enabled: true + fields: ["phone", "email", "name", "address"] + method: "hash" + consent: + required: true + ageVerification: true + withdrawalPeriod: "30d" + + audit: + enabled: true + logAccess: true + logModifications: true + logExports: true + retentionDays: 365 + + dataSubjectRights: + access: true + rectification: true + erasure: true + portability: true + objection: true + restriction: true + + breachNotification: + enabled: true + timeframe: "72h" + authorities: ["dpa@telecom-platform.com"] + template: "gdpr-breach-notification" +--- +apiVersion: v1 +kind: Secret +metadata: + name: gdpr-compliance-secrets + namespace: telecom-platform + labels: + app.kubernetes.io/name: gdpr-compliance + app.kubernetes.io/component: compliance + app.kubernetes.io/part-of: telecom-platform +type: Opaque +data: + encryption-key: "c3VwZXItc2VjcmV0LWVuY3J5cHRpb24ta2V5LTI1Ni1iaXRz" # base64 encoded + dpa-contact: "ZHBhQHRlbGVjb20tcGxhdGZvcm0uY29t" # base64 encoded +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: gdpr-compliance-service + namespace: telecom-platform + labels: + app.kubernetes.io/name: gdpr-compliance-service + app.kubernetes.io/component: compliance + app.kubernetes.io/part-of: telecom-platform +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: gdpr-compliance-service + app.kubernetes.io/component: compliance + template: + metadata: + labels: + app.kubernetes.io/name: gdpr-compliance-service + app.kubernetes.io/component: compliance + annotations: + gdpr.telecom-platform/data-retention: "30d" + gdpr.telecom-platform/encryption: "true" + gdpr.telecom-platform/audit: "true" + spec: + containers: + - name: gdpr-compliance + image: telecom-platform/gdpr-compliance:latest + ports: + - containerPort: 8080 + name: http + env: + - name: ENCRYPTION_KEY + valueFrom: + secretKeyRef: + name: gdpr-compliance-secrets + key: encryption-key + - name: DPA_CONTACT + valueFrom: + secretKeyRef: + name: gdpr-compliance-secrets + key: dpa-contact + - name: LOG_LEVEL + value: "info" + - name: DATA_RETENTION_DAYS + value: "30" + - name: AUDIT_ENABLED + value: "true" + resources: + requests: + cpu: 100m + memory: 128Mi + limits: + cpu: 500m + memory: 512Mi + livenessProbe: + httpGet: + path: /health + port: http + initialDelaySeconds: 30 + periodSeconds: 10 + readinessProbe: + httpGet: + path: /ready + port: http + initialDelaySeconds: 5 + periodSeconds: 5 + volumeMounts: + - name: config + mountPath: /config + volumes: + - name: config + configMap: + name: gdpr-compliance-config +--- +apiVersion: v1 +kind: Service +metadata: + name: gdpr-compliance-service + namespace: telecom-platform + labels: + app.kubernetes.io/name: gdpr-compliance-service + app.kubernetes.io/component: compliance + app.kubernetes.io/part-of: telecom-platform + annotations: + gdpr.telecom-platform/data-retention: "30d" + gdpr.telecom-platform/encryption: "true" +spec: + ports: + - port: 8080 + name: http + targetPort: 8080 + selector: + app.kubernetes.io/name: gdpr-compliance-service + app.kubernetes.io/component: compliance + type: ClusterIP +--- +apiVersion: networking.istio.io/v1beta1 +kind: VirtualService +metadata: + name: gdpr-compliance-service + namespace: telecom-platform + labels: + app.kubernetes.io/name: gdpr-compliance-service + app.kubernetes.io/component: compliance + app.kubernetes.io/part-of: telecom-platform +spec: + hosts: + - gdpr.telecom.local + gateways: + - telecom-platform-gateway + http: + - match: + - uri: + prefix: / + route: + - destination: + host: gdpr-compliance-service + port: + number: 8080 + timeout: 30s +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: gdpr-data-cleanup + namespace: telecom-platform + labels: + app.kubernetes.io/name: gdpr-data-cleanup + app.kubernetes.io/component: compliance + app.kubernetes.io/part-of: telecom-platform +spec: + schedule: "0 2 * * *" # Daily at 2 AM + jobTemplate: + spec: + template: + metadata: + labels: + app.kubernetes.io/name: gdpr-data-cleanup + app.kubernetes.io/component: compliance + spec: + containers: + - name: data-cleanup + image: telecom-platform/gdpr-cleanup:latest + env: + - name: RETENTION_DAYS + value: "30" + - name: ENCRYPTION_KEY + valueFrom: + secretKeyRef: + name: gdpr-compliance-secrets + key: encryption-key + - name: DRY_RUN + value: "false" + command: + - /app/cleanup + - --retention-days=30 + - --encrypt-deleted=true + - --audit-log=/var/log/cleanup.log + resources: + requests: + cpu: 100m + memory: 128Mi + limits: + cpu: 500m + memory: 512Mi + volumeMounts: + - name: audit-log + mountPath: /var/log + volumes: + - name: audit-log + emptyDir: {} + restartPolicy: OnFailure +--- +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: gdpr-compliance-service-pdb + namespace: telecom-platform + labels: + app.kubernetes.io/name: gdpr-compliance-service + app.kubernetes.io/component: compliance + app.kubernetes.io/part-of: telecom-platform +spec: + minAvailable: 1 + selector: + matchLabels: + app.kubernetes.io/name: gdpr-compliance-service + app.kubernetes.io/component: compliance diff --git a/deployments/helm/telecom-platform/Chart.yaml b/deployments/helm/telecom-platform/Chart.yaml new file mode 100644 index 0000000..3477452 --- /dev/null +++ b/deployments/helm/telecom-platform/Chart.yaml @@ -0,0 +1,52 @@ +apiVersion: v2 +name: telecom-platform +description: A Helm chart for Telecom Platform - Complete telecommunications management solution +type: application +version: 1.0.0 +appVersion: "1.0.0" +home: https://github.com/nutcas3/telecom-platform +sources: + - https://github.com/nutcas3/telecom-platform +maintainers: + - name: Telecom Platform Team + email: team@telecom-platform.com +keywords: + - telecom + - platform + - kubernetes + - monitoring + - billing + - charging + - subscriber-management +annotations: + category: Infrastructure + licenses: MIT +dependencies: + - name: postgresql + version: 12.1.9 + repository: https://charts.bitnami.com/bitnami + condition: postgresql.enabled + - name: redis + version: 17.3.7 + repository: https://charts.bitnami.com/bitnami + condition: redis.enabled + - name: prometheus + version: 23.1.0 + repository: https://prometheus-community.github.io/helm-charts + condition: prometheus.enabled + - name: grafana + version: 6.58.9 + repository: https://grafana.github.io/helm-charts + condition: grafana.enabled + - name: elasticsearch + version: 19.5.0 + repository: https://helm.elastic.co + condition: elasticsearch.enabled + - name: kibana + version: 10.2.0 + repository: https://helm.elastic.co + condition: kibana.enabled + - name: logstash + version: 8.5.1 + repository: https://helm.elastic.co + condition: logstash.enabled diff --git a/deployments/helm/telecom-platform/values.yaml b/deployments/helm/telecom-platform/values.yaml new file mode 100644 index 0000000..8f817c3 --- /dev/null +++ b/deployments/helm/telecom-platform/values.yaml @@ -0,0 +1,585 @@ +# Default values for telecom-platform. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +# Global configuration +global: + imageRegistry: "" + imagePullSecrets: [] + storageClass: "" + # Environment: dev, staging, prod + environment: "dev" + +# Platform configuration +platform: + # Domain configuration + domain: "telecom.local" + tls: + enabled: false + secretName: "telecom-tls" + certManager: + enabled: false + issuerName: "letsencrypt-prod" + + # API configuration + api: + replicas: 3 + image: + repository: telecom-platform/api-server + tag: "1.0.0" + pullPolicy: IfNotPresent + resources: + requests: + cpu: 100m + memory: 256Mi + limits: + cpu: 500m + memory: 512Mi + autoscaling: + enabled: true + minReplicas: 3 + maxReplicas: 10 + targetCPUUtilizationPercentage: 70 + targetMemoryUtilizationPercentage: 80 + service: + type: ClusterIP + port: 8000 + ingress: + enabled: true + className: "nginx" + annotations: {} + hosts: + - host: api.telecom.local + paths: + - path: / + pathType: Prefix + tls: [] + + # Charging Engine configuration + charging: + replicas: 2 + image: + repository: telecom-platform/charging-engine + tag: "1.0.0" + pullPolicy: IfNotPresent + resources: + requests: + cpu: 100m + memory: 256Mi + limits: + cpu: 500m + memory: 512Mi + autoscaling: + enabled: true + minReplicas: 2 + maxReplicas: 8 + targetCPUUtilizationPercentage: 75 + service: + type: ClusterIP + port: 8080 + config: + databaseUrl: "postgresql://postgres:password@postgres:5432/telecom" + redisUrl: "redis://redis:6379" + + # Packet Gateway configuration + gateway: + replicas: 2 + image: + repository: telecom-platform/packet-gateway + tag: "1.0.0" + pullPolicy: IfNotPresent + resources: + requests: + cpu: 200m + memory: 512Mi + limits: + cpu: 1000m + memory: 1Gi + autoscaling: + enabled: true + minReplicas: 2 + maxReplicas: 6 + targetCPUUtilizationPercentage: 80 + service: + type: ClusterIP + port: 9090 + privileged: true + hostNetwork: false + + # Web Dashboard configuration + dashboard: + replicas: 2 + image: + repository: telecom-platform/web-dashboard + tag: "1.0.0" + pullPolicy: IfNotPresent + resources: + requests: + cpu: 50m + memory: 128Mi + limits: + cpu: 200m + memory: 256Mi + autoscaling: + enabled: true + minReplicas: 2 + maxReplicas: 4 + targetCPUUtilizationPercentage: 70 + service: + type: ClusterIP + port: 3000 + ingress: + enabled: true + className: "nginx" + annotations: {} + hosts: + - host: dashboard.telecom.local + paths: + - path: / + pathType: Prefix + tls: [] + +# PostgreSQL configuration +postgresql: + enabled: true + auth: + postgresPassword: "telecom123" + database: "telecom" + primary: + persistence: + enabled: true + size: 20Gi + storageClass: "" + resources: + requests: + cpu: 100m + memory: 256Mi + limits: + cpu: 500m + memory: 1Gi + service: + ports: + postgresql: 5432 + +# Redis configuration +redis: + enabled: true + auth: + enabled: false + password: "" + master: + persistence: + enabled: true + size: 8Gi + storageClass: "" + resources: + requests: + cpu: 50m + memory: 128Mi + limits: + cpu: 200m + memory: 256Mi + service: + ports: + redis: 6379 + +# Prometheus configuration +prometheus: + enabled: true + server: + replicaCount: 1 + resources: + requests: + cpu: 100m + memory: 512Mi + limits: + cpu: 500m + memory: 2Gi + persistentVolume: + enabled: true + size: 20Gi + service: + type: ClusterIP + port: 9090 + ingress: + enabled: true + ingressClassName: "nginx" + hosts: + - prometheus.telecom.local + paths: + - path: / + pathType: Prefix + alertmanager: + enabled: true + replicaCount: 1 + resources: + requests: + cpu: 50m + memory: 128Mi + limits: + cpu: 200m + memory: 256Mi + service: + type: ClusterIP + port: 9093 + ingress: + enabled: true + ingressClassName: "nginx" + hosts: + - alertmanager.telecom.local + paths: + - path: / + pathType: Prefix + +# Grafana configuration +grafana: + enabled: true + replicaCount: 1 + resources: + requests: + cpu: 50m + memory: 128Mi + limits: + cpu: 200m + memory: 256Mi + persistence: + enabled: true + size: 10Gi + service: + type: ClusterIP + port: 3000 + ingress: + enabled: true + ingressClassName: "nginx" + hosts: + - grafana.telecom.local + paths: + - path: / + pathType: Prefix + adminPassword: "admin123" + sidecar: + datasources: + enabled: true + dashboards: + enabled: true + +# ELK Stack configuration +elasticsearch: + enabled: true + master: + replicaCount: 1 + resources: + requests: + cpu: 100m + memory: 1Gi + limits: + cpu: 500m + memory: 2Gi + persistence: + enabled: true + size: 20Gi + data: + replicaCount: 2 + resources: + requests: + cpu: 100m + memory: 1Gi + limits: + cpu: 500m + memory: 2Gi + persistence: + enabled: true + size: 30Gi + +kibana: + enabled: true + replicaCount: 1 + resources: + requests: + cpu: 50m + memory: 256Mi + limits: + cpu: 200m + memory: 512Mi + service: + type: ClusterIP + port: 5601 + ingress: + enabled: true + ingressClassName: "nginx" + hosts: + - kibana.telecom.local + paths: + - path: / + pathType: Prefix + +logstash: + enabled: true + replicaCount: 1 + resources: + requests: + cpu: 100m + memory: 512Mi + limits: + cpu: 500m + memory: 1Gi + service: + type: ClusterIP + ports: + - port: 5044 + name: beats + - port: 9600 + name: http + +# Monitoring configuration +monitoring: + serviceMonitor: + enabled: true + namespace: telecom-platform + labels: + release: prometheus + interval: 30s + scrapeTimeout: 10s + + prometheusRule: + enabled: true + namespace: telecom-platform + labels: + release: prometheus + groups: + - name: telecom-platform + rules: + - alert: APIHighErrorRate + expr: rate(http_requests_total{status=~"5.."}[5m]) > 0.1 + for: 5m + labels: + severity: critical + annotations: + summary: "API error rate is high" + description: "API error rate is {{ $value }} errors per second" + + - alert: HighMemoryUsage + expr: container_memory_usage_bytes / container_spec_memory_limit_bytes > 0.9 + for: 5m + labels: + severity: warning + annotations: + summary: "High memory usage" + description: "Memory usage is above 90%" + + - alert: HighCPUUsage + expr: rate(container_cpu_usage_seconds_total[5m]) > 0.8 + for: 5m + labels: + severity: warning + annotations: + summary: "High CPU usage" + description: "CPU usage is above 80%" + +# Service Mesh (Istio) configuration +istio: + enabled: false + namespace: "istio-system" + injectionPolicy: enabled + gateway: + enabled: true + selectors: + - istio: ingressgateway + virtualService: + enabled: true + hosts: + - api.telecom.local + - dashboard.telecom.local + - grafana.telecom.local + - prometheus.telecom.local + - kibana.telecom.local + destinationRule: + enabled: true + trafficPolicy: + loadBalancer: + simple: ROUND_ROBIN + connectionPool: + tcp: + maxConnections: 100 + http: + http1MaxPendingRequests: 50 + maxRequestsPerConnection: 10 + +# Backup configuration +backup: + enabled: true + schedule: "0 2 * * *" # Daily at 2 AM + retention: "30d" + storage: + type: "s3" + s3: + bucket: "telecom-platform-backups" + region: "us-east-1" + endpoint: "" + accessKey: "" + secretKey: "" + databases: + postgresql: + enabled: true + host: "postgres" + port: 5432 + database: "telecom" + username: "postgres" + password: "telecom123" + + # Velero configuration for Kubernetes backups + velero: + enabled: true + namespace: "velero" + version: "v1.9.0" + serviceAccount: + server: + create: true + name: "velero" + configuration: + provider: "aws" + backupStorageLocation: + name: "default" + bucket: "velero-backups" + config: + region: "us-east-1" + volumeSnapshotLocation: + name: "default" + config: + region: "us-east-1" + +# Secrets management +secrets: + vault: + enabled: false + namespace: "vault" + version: "1.14.0" + ha: + enabled: true + replicas: 3 + ui: + enabled: true + serviceType: "ClusterIP" + injector: + enabled: true + auth: + enabled: true + method: "kubernetes" + kubernetes: + host: "https://kubernetes.default.svc" + role: "telecom-platform" + + certManager: + enabled: false + namespace: "cert-manager" + version: "v1.13.0" + installCRDs: true + webhook: + timeout: "30s" + +# GDPR compliance configuration +gdpr: + enabled: true + dataRetention: + logs: "90d" + metrics: "365d" + userProfiles: "2555d" # 7 years + billing: "3650d" # 10 years + + privacy: + anonymization: + enabled: true + fields: + - phone + - email + - address + encryption: + enabled: true + algorithm: "AES-256" + keyRotation: "90d" + + audit: + enabled: true + retention: "2555d" + events: + - user.login + - user.logout + - data.access + - data.modification + - admin.actions + +# Auto-scaling configuration +autoscaling: + enabled: true + clusterAutoscaler: + enabled: true + version: "1.28.0" + scaleDownDelayAfterAdd: "10m" + scaleDownUnneededTime: "10m" + maxNodesTotal: 100 + resourceLimits: + maxCPU: 100 + maxMemory: 500Gi + + metricsServer: + enabled: true + version: "v0.6.4" + resources: + requests: + cpu: 50m + memory: 100Mi + limits: + cpu: 100m + memory: 200Mi + +# Multi-environment configuration +environments: + dev: + replicas: + api: 1 + charging: 1 + gateway: 1 + dashboard: 1 + resources: + requests: + cpu: 50m + memory: 128Mi + limits: + cpu: 200m + memory: 256Mi + domain: "dev.telecom.local" + + staging: + replicas: + api: 2 + charging: 2 + gateway: 2 + dashboard: 2 + resources: + requests: + cpu: 100m + memory: 256Mi + limits: + cpu: 500m + memory: 512Mi + domain: "staging.telecom.local" + + prod: + replicas: + api: 3 + charging: 2 + gateway: 2 + dashboard: 2 + resources: + requests: + cpu: 200m + memory: 512Mi + limits: + cpu: 1000m + memory: 2Gi + domain: "telecom.platform" + tls: + enabled: true + certManager: + enabled: true + issuerName: "letsencrypt-prod" diff --git a/deployments/istio/istio-install.yaml b/deployments/istio/istio-install.yaml new file mode 100644 index 0000000..66cc7a4 --- /dev/null +++ b/deployments/istio/istio-install.yaml @@ -0,0 +1,91 @@ +apiVersion: install.istio.io/v1alpha1 +kind: IstioOperator +metadata: + name: telecom-platform-istio + namespace: istio-system +spec: + profile: default + components: + base: + enabled: true + pilot: + enabled: true + k8s: + env: + PILOT_TRACE_SAMPLING: "100" + ingressGateways: + - name: istio-ingressgateway + enabled: true + k8s: + service: + type: LoadBalancer + ports: + - name: http2 + port: 80 + targetPort: 8080 + - name: https + port: 443 + targetPort: 8443 + resources: + requests: + cpu: 100m + memory: 128Mi + limits: + cpu: 500m + memory: 512Mi + egressGateways: + - name: istio-egressgateway + enabled: true + k8s: + resources: + requests: + cpu: 50m + memory: 64Mi + limits: + cpu: 200m + memory: 256Mi + meshConfig: + defaultConfig: + trafficPolicy: + connectionPool: + tcp: + maxConnections: 100 + http: + http1MaxPendingRequests: 50 + maxRequestsPerConnection: 10 + loadBalancer: + simple: ROUND_ROBIN + accessLogFile: /dev/stdout + accessLogEncoding: JSON + accessLogFormat: '{"source":"%SOURCE_WORKLOAD%","destination":"%DESTINATION_WORKLOAD%","protocol":"%REQ(:)%","method":"%REQ(:METHOD)%","path":"%REQ(:PATH)%","code":"%RESPONSE_CODE%","duration":"%DURATION%","bytesSent":"%BYTES_SENT%","bytesReceived":"%BYTES_RECEIVED%"}' + tracing: + sampling: 100.0 + zipkin: + address: zipkin.istio-system:9411 + values: + global: + controlPlaneSecurityEnabled: true + mtls: + enabled: true + gateways: + istio-ingressgateway: + type: LoadBalancer + autoscaleMin: 1 + autoscaleMax: 5 + resources: + requests: + cpu: 100m + memory: 128Mi + limits: + cpu: 500m + memory: 512Mi + pilot: + autoscaleMin: 1 + autoscaleMax: 3 + resources: + requests: + cpu: 100m + memory: 128Mi + limits: + cpu: 500m + memory: 512Mi diff --git a/deployments/istio/telecom-platform-gateway.yaml b/deployments/istio/telecom-platform-gateway.yaml new file mode 100644 index 0000000..9b6b18d --- /dev/null +++ b/deployments/istio/telecom-platform-gateway.yaml @@ -0,0 +1,126 @@ +apiVersion: networking.istio.io/v1beta1 +kind: Gateway +metadata: + name: telecom-platform-gateway + namespace: telecom-platform + labels: + app.kubernetes.io/name: telecom-platform-gateway + app.kubernetes.io/component: istio + app.kubernetes.io/part-of: telecom-platform +spec: + selector: + istio: ingressgateway + servers: + - port: + number: 80 + name: http + protocol: HTTP + hosts: + - api.telecom.local + - dashboard.telecom.local + - grafana.telecom.local + - prometheus.telecom.local + - kibana.telecom.local + tls: + httpsRedirect: true + - port: + number: 443 + name: https + protocol: HTTPS + hosts: + - api.telecom.local + - dashboard.telecom.local + - grafana.telecom.local + - prometheus.telecom.local + - kibana.telecom.local + tls: + mode: SIMPLE + credentialName: telecom-platform-tls + minProtocolVersion: TLSV1_2 +--- +apiVersion: networking.istio.io/v1beta1 +kind: VirtualService +metadata: + name: telecom-platform-api + namespace: telecom-platform + labels: + app.kubernetes.io/name: telecom-platform-api + app.kubernetes.io/component: istio + app.kubernetes.io/part-of: telecom-platform +spec: + hosts: + - api.telecom.local + gateways: + - telecom-platform-gateway + http: + - match: + - uri: + prefix: / + route: + - destination: + host: api-server + port: + number: 8000 + timeout: 30s + retries: + attempts: 3 + perTryTimeout: 10s + retryOn: 5xx,connect-failure,refused-stream + fault: + delay: + percentage: + value: 0.1 + fixedDelay: 5s +--- +apiVersion: networking.istio.io/v1beta1 +kind: VirtualService +metadata: + name: telecom-platform-dashboard + namespace: telecom-platform + labels: + app.kubernetes.io/name: telecom-platform-dashboard + app.kubernetes.io/component: istio + app.kubernetes.io/part-of: telecom-platform +spec: + hosts: + - dashboard.telecom.local + gateways: + - telecom-platform-gateway + http: + - match: + - uri: + prefix: / + route: + - destination: + host: web-dashboard + port: + number: 3000 + timeout: 30s +--- +apiVersion: networking.istio.io/v1beta1 +kind: DestinationRule +metadata: + name: telecom-platform-api + namespace: telecom-platform + labels: + app.kubernetes.io/name: telecom-platform-api + app.kubernetes.io/component: istio + app.kubernetes.io/part-of: telecom-platform +spec: + host: api-server + trafficPolicy: + loadBalancer: + simple: ROUND_ROBIN + connectionPool: + tcp: + maxConnections: 100 + http: + http1MaxPendingRequests: 50 + maxRequestsPerConnection: 10 + outlierDetection: + consecutiveErrors: 3 + interval: 30s + baseEjectionTime: 30s + maxEjectionPercent: 50 + tls: + mode: ISTIO_MUTUAL diff --git a/deployments/kubernetes/README.md b/deployments/kubernetes/README.md new file mode 100644 index 0000000..414f182 --- /dev/null +++ b/deployments/kubernetes/README.md @@ -0,0 +1,409 @@ +# Telecom Platform Kubernetes Deployment + +This directory contains the complete Kubernetes deployment configuration for the Telecom Platform, including all applications and monitoring stack. + +## Architecture Overview + +``` +telecom-platform Namespace + api-server (3 replicas) - Main GraphQL API server + charging-engine (2 replicas) - Rust charging engine + packet-gateway (2 replicas) - eBPF packet gateway + web-dashboard (2 replicas) - Next.js admin dashboard + postgres (1 replica) - PostgreSQL database + redis (1 replica) - Redis cache + postgres-exporter (1 replica) - PostgreSQL metrics + redis-exporter (1 replica) - Redis metrics + +telecom-monitoring Namespace + prometheus (1 replica) - Metrics collection + grafana (1 replica) - Visualization dashboards + influxdb (1 replica) - Time-series storage + alertmanager (1 replica) - Alert management + node-exporter (1 replica) - System metrics +``` + +## Prerequisites + +### Required Tools +- **kubectl** - Kubernetes CLI +- **Docker** - Container runtime +- **Helm** (optional) - For advanced deployments + +### Kubernetes Requirements +- **Kubernetes 1.25+** - For modern API support +- **Ingress Controller** - nginx-ingress recommended +- **Persistent Storage** - 50GB+ total for databases and monitoring +- **LoadBalancer** - For external service access (or NodePort) + +### Resource Requirements +- **CPU**: 4+ cores minimum +- **Memory**: 8GB+ minimum +- **Storage**: 50GB+ persistent storage + +## Quick Start + +### 1. Deploy Everything +```bash +cd deployments/kubernetes +./deploy.sh +``` + +### 2. Access Services +After deployment, access services via: +- **Web Dashboard**: http://localhost:3000 +- **API Server**: http://localhost:8000 +- **Grafana**: http://localhost:3001 (admin/admin123) +- **Prometheus**: http://localhost:9090 + +### 3. Port Forwarding (if needed) +```bash +# Applications +kubectl port-forward svc/api-server-service 8000:8000 -n telecom-platform +kubectl port-forward svc/web-dashboard-service 3000:3000 -n telecom-platform + +# Monitoring +kubectl port-forward svc/grafana 3001:3000 -n telecom-monitoring +kubectl port-forward svc/prometheus 9090:9090 -n telecom-monitoring +``` + +## Deployment Components + +### Namespaces +- **telecom-platform** - Main application services +- **telecom-monitoring** - Monitoring and observability + +### Applications + +#### API Server +- **Replicas**: 3 (auto-scalable to 10) +- **Ports**: 8000 (HTTP), 9090 (Metrics) +- **Resources**: 256Mi-512Mi memory, 250m-500m CPU +- **Features**: GraphQL API, REST endpoints, metrics export + +#### Charging Engine +- **Replicas**: 2 (auto-scalable to 6) +- **Port**: 3001 (HTTP + Metrics) +- **Resources**: 128Mi-256Mi memory, 100m-200m CPU +- **Features**: Real-time credit control, usage tracking + +#### Packet Gateway +- **Replicas**: 2 (auto-scalable to 4) +- **Port**: 9000 (Metrics) +- **Resources**: 256Mi-512Mi memory, 250m-500m CPU +- **Features**: eBPF packet processing, network isolation +- **Privileges**: NET_ADMIN, SYS_ADMIN for eBPF + +#### Web Dashboard +- **Replicas**: 2 (auto-scalable to 6) +- **Port**: 3000 (HTTP) +- **Resources**: 128Mi-256Mi memory, 100m-200m CPU +- **Features**: React admin interface, real-time updates + +### Databases + +#### PostgreSQL +- **Version**: 15 +- **Storage**: 10Gi persistent volume +- **Features**: Primary database, metrics export +- **Exporter**: postgres-exporter on port 9187 + +#### Redis +- **Version**: 7-alpine +- **Storage**: 256Mi memory limit +- **Features**: Caching, session storage, real-time data +- **Exporter**: redis-exporter on port 9121 + +### Monitoring Stack + +#### Prometheus +- **Version**: v2.45.0 +- **Storage**: 20Gi persistent volume +- **Port**: 9090 +- **Features**: Metrics collection, alerting rules +- **Targets**: Auto-discovery of all services + +#### Grafana +- **Version**: 10.2.0 +- **Storage**: 10Gi persistent volume +- **Port**: 3000 +- **Features**: Dashboards, alerting, user management +- **Data Sources**: Prometheus, InfluxDB + +#### InfluxDB +- **Version**: 2.7 +- **Storage**: 20Gi persistent volume +- **Port**: 8086 +- **Features**: Time-series data, long-term storage +- **Organization**: telecom, Bucket: telecom + +#### Alertmanager +- **Version**: v0.25.0 +- **Storage**: 5Gi persistent volume +- **Port**: 9093 +- **Features**: Alert routing, notifications, silencing + +## Configuration + +### Environment Variables +Key configuration in `configmaps.yaml`: +- Database connections +- Redis configuration +- Monitoring endpoints +- Service URLs + +### Secrets +Sensitive data in `secrets.yaml`: +- Database passwords +- API keys +- Authentication tokens +- TLS certificates + +### Customization +To customize the deployment: + +1. **Modify ConfigMaps**: Update `configmaps.yaml` +2. **Update Secrets**: Modify `secrets.yaml` with real values +3. **Adjust Resources**: Update resource limits in deployment files +4. **Change Replicas**: Modify replica counts +5. **Update Ingress**: Configure hostnames and TLS + +## Auto-scaling + +### Horizontal Pod Autoscalers (HPA) +All applications have HPA configured: +- **API Server**: 3-10 replicas, 70% CPU, 80% memory +- **Charging Engine**: 2-6 replicas, 70% CPU, 80% memory +- **Packet Gateway**: 2-4 replicas, 75% CPU, 85% memory +- **Web Dashboard**: 2-6 replicas, 70% CPU, 80% memory + +### Scaling Behavior +- **Scale Up**: 50% increase, 60s stabilization +- **Scale Down**: 10% decrease, 300s stabilization + +## Ingress Configuration + +### Hostnames +Default ingress configuration: +- **API**: api.telecom.example.com +- **Dashboard**: dashboard.telecom.example.com +- **Grafana**: grafana.telecom.example.com +- **Prometheus**: prometheus.telecom.example.com + +### TLS +- Automatic TLS with cert-manager +- Custom certificates supported +- HTTP to HTTPS redirection + +### Rate Limiting +- 100 requests per minute per IP +- Configurable per service + +## Monitoring and Alerting + +### Prometheus Metrics +All services export metrics on dedicated endpoints: +- HTTP request metrics +- Business metrics (subscribers, usage) +- System metrics (CPU, memory) +- Custom application metrics + +### Grafana Dashboards +Pre-configured dashboards: +- **Telecom Platform Overview** - System-wide metrics +- **Subscriber Metrics** - Detailed subscriber analytics +- **Infrastructure** - Resource utilization +- **Applications** - Service-specific metrics + +### Alerting Rules +Critical alerts configured: +- High error rates (>10%) +- Service down events +- Resource exhaustion +- Database connection failures + +### Alert Routing +- **Critical**: Email + webhook notifications +- **Warning**: Webhook notifications only +- **Silencing**: Configurable maintenance windows + +## Storage + +### Persistent Volumes +- **PostgreSQL**: 10Gi, ReadWriteOnce +- **Redis**: emptyDir (in-memory) +- **Prometheus**: 20Gi, ReadWriteOnce +- **Grafana**: 10Gi, ReadWriteOnce +- **InfluxDB**: 20Gi, ReadWriteOnce +- **Alertmanager**: 5Gi, ReadWriteOnce + +### Storage Classes +Uses default storage class. Customize for your environment: +- AWS: gp2/gp3 +- GCP: standard-ssd +- Azure: Premium SSD +- On-prem: Local SSD/NVMe + +## Security + +### Network Policies +Default policies allow: +- Intra-namespace communication +- Cross-namespace for monitoring +- External access via Ingress only + +### RBAC +Service accounts with minimal permissions: +- Database access only for applications +- Monitoring access for Prometheus +- ConfigMap/Secret access as needed + +### Secrets Management +- Kubernetes native secrets +- Encrypted at rest +- Environment variable injection +- Rotation policies recommended + +## Troubleshooting + +### Common Issues + +#### Pods Not Starting +```bash +# Check pod status +kubectl get pods -n telecom-platform -o wide + +# Check pod logs +kubectl logs -f deployment/api-server -n telecom-platform + +# Describe pod for detailed info +kubectl describe pod -n telecom-platform +``` + +#### Service Not Accessible +```bash +# Check service endpoints +kubectl get endpoints -n telecom-platform + +# Test service connectivity +kubectl exec -it -n telecom-platform -- curl http://api-server-service:8000/health +``` + +#### Monitoring Issues +```bash +# Check Prometheus targets +kubectl port-forward svc/prometheus 9090:9090 -n telecom-monitoring +# Visit http://localhost:9090/targets + +# Check Grafana data sources +kubectl port-forward svc/grafana 3001:3000 -n telecom-monitoring +# Visit http://localhost:3001/datasources +``` + +#### Storage Issues +```bash +# Check PVC status +kubectl get pvc -n telecom-platform +kubectl get pvc -n telecom-monitoring + +# Check storage class +kubectl get storageclass +``` + +### Debug Commands +```bash +# Full cluster status +kubectl get all -n telecom-platform +kubectl get all -n telecom-monitoring + +# Resource usage +kubectl top pods -n telecom-platform +kubectl top nodes + +# Events +kubectl get events -n telecom-platform --sort-by='.lastTimestamp' +kubectl get events -n telecom-monitoring --sort-by='.lastTimestamp' +``` + +## Maintenance + +### Updates +```bash +# Update images +kubectl set image deployment/api-server api-server=telecom/api-server:v2.0.0 -n telecom-platform + +# Rolling restart +kubectl rollout restart deployment/api-server -n telecom-platform + +# Check rollout status +kubectl rollout status deployment/api-server -n telecom-platform +``` + +### Backup +```bash +# Backup databases +kubectl exec -it postgres-0 -n telecom-platform -- pg_dump telecom_platform > backup.sql + +# Backup configurations +kubectl get all -n telecom-platform -o yaml > platform-backup.yaml +kubectl get all -n telecom-monitoring -o yaml > monitoring-backup.yaml +``` + +### Cleanup +```bash +# Remove everything +./deploy.sh cleanup + +# Remove specific components +kubectl delete -f manifests/applications.yaml +kubectl delete -f manifests/monitoring.yaml +``` + +## Production Considerations + +### High Availability +- Use multiple replicas for stateless services +- Configure database replication +- Implement backup and disaster recovery +- Use anti-affinity rules for pod distribution + +### Performance +- Enable resource limits and requests +- Use appropriate storage classes +- Configure network policies +- Monitor and optimize based on metrics + +### Security +- Enable Pod Security Policies +- Use network segmentation +- Implement secret rotation +- Regular security scanning + +### Compliance +- Enable audit logging +- Implement data retention policies +- Use encrypted storage +- Regular compliance checks + +## Next Steps + +1. **Customize Configuration**: Update for your environment +2. **Set Up DNS**: Configure hostnames in your DNS +3. **Configure TLS**: Update certificates for production +4. **Set Up Monitoring**: Configure alert recipients +5. **Implement Backup**: Set up automated backups +6. **Performance Tuning**: Optimize based on actual usage + +## Support + +For deployment issues: +1. Check the troubleshooting section +2. Review pod logs and events +3. Verify resource availability +4. Test with smaller deployments first + +For application issues: +1. Check the application documentation +2. Review service health endpoints +3. Verify database connectivity +4. Check monitoring dashboards diff --git a/deployments/kubernetes/manifests/applications.yaml b/deployments/kubernetes/manifests/applications.yaml new file mode 100644 index 0000000..c307482 --- /dev/null +++ b/deployments/kubernetes/manifests/applications.yaml @@ -0,0 +1,355 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: api-server + namespace: telecom-platform + labels: + app: api-server + component: backend +spec: + replicas: 3 + selector: + matchLabels: + app: api-server + template: + metadata: + labels: + app: api-server + component: backend + annotations: + prometheus.io/scrape: "true" + prometheus.io/port: "9090" + prometheus.io/path: "/metrics" + spec: + containers: + - name: api-server + image: telecom/api-server:latest + ports: + - containerPort: 8000 + name: http + - containerPort: 9090 + name: metrics + env: + - name: DATABASE_HOST + valueFrom: + configMapKeyRef: + name: telecom-config + key: DATABASE_HOST + - name: DATABASE_PORT + valueFrom: + configMapKeyRef: + name: telecom-config + key: DATABASE_PORT + - name: DATABASE_NAME + valueFrom: + configMapKeyRef: + name: telecom-config + key: DATABASE_NAME + - name: DATABASE_PASSWORD + valueFrom: + secretKeyRef: + name: telecom-secrets + key: DATABASE_PASSWORD + - name: REDIS_HOST + valueFrom: + configMapKeyRef: + name: telecom-config + key: REDIS_HOST + - name: REDIS_PORT + valueFrom: + configMapKeyRef: + name: telecom-config + key: REDIS_PORT + - name: CHARGING_ENGINE_URL + valueFrom: + configMapKeyRef: + name: telecom-config + key: CHARGING_ENGINE_URL + - name: ES2_URL + valueFrom: + configMapKeyRef: + name: telecom-config + key: ES2_URL + - name: INFLUXDB_URL + valueFrom: + configMapKeyRef: + name: telecom-config + key: INFLUXDB_URL + - name: INFLUXDB_TOKEN + valueFrom: + secretKeyRef: + name: telecom-secrets + key: INFLUXDB_TOKEN + - name: INFLUXDB_ORG + valueFrom: + configMapKeyRef: + name: telecom-config + key: INFLUXDB_ORG + - name: INFLUXDB_BUCKET + valueFrom: + configMapKeyRef: + name: telecom-config + key: INFLUXDB_BUCKET + - name: METRICS_PORT + valueFrom: + configMapKeyRef: + name: telecom-config + key: METRICS_PORT + - name: LOG_LEVEL + valueFrom: + configMapKeyRef: + name: telecom-config + key: LOG_LEVEL + resources: + requests: + memory: "256Mi" + cpu: "250m" + limits: + memory: "512Mi" + cpu: "500m" + livenessProbe: + httpGet: + path: /health + port: 8000 + initialDelaySeconds: 30 + periodSeconds: 10 + readinessProbe: + httpGet: + path: /health + port: 8000 + initialDelaySeconds: 5 + periodSeconds: 5 +--- +apiVersion: v1 +kind: Service +metadata: + name: api-server-service + namespace: telecom-platform + labels: + app: api-server +spec: + selector: + app: api-server + ports: + - name: http + port: 8000 + targetPort: 8000 + - name: metrics + port: 9090 + targetPort: 9090 + type: ClusterIP +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: charging-engine + namespace: telecom-platform + labels: + app: charging-engine + component: backend +spec: + replicas: 2 + selector: + matchLabels: + app: charging-engine + template: + metadata: + labels: + app: charging-engine + component: backend + annotations: + prometheus.io/scrape: "true" + prometheus.io/port: "3001" + prometheus.io/path: "/metrics" + spec: + containers: + - name: charging-engine + image: telecom/charging-engine:latest + ports: + - containerPort: 3001 + name: http + env: + - name: REDIS_URL + value: "redis://redis-service:6379" + - name: LOG_LEVEL + value: "info" + resources: + requests: + memory: "128Mi" + cpu: "100m" + limits: + memory: "256Mi" + cpu: "200m" + livenessProbe: + httpGet: + path: /health + port: 3001 + initialDelaySeconds: 30 + periodSeconds: 10 + readinessProbe: + httpGet: + path: /health + port: 3001 + initialDelaySeconds: 5 + periodSeconds: 5 +--- +apiVersion: v1 +kind: Service +metadata: + name: charging-engine-service + namespace: telecom-platform + labels: + app: charging-engine +spec: + selector: + app: charging-engine + ports: + - name: http + port: 3001 + targetPort: 3001 + type: ClusterIP +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: packet-gateway + namespace: telecom-platform + labels: + app: packet-gateway + component: network +spec: + replicas: 2 + selector: + matchLabels: + app: packet-gateway + template: + metadata: + labels: + app: packet-gateway + component: network + annotations: + prometheus.io/scrape: "true" + prometheus.io/port: "9000" + prometheus.io/path: "/metrics" + spec: + containers: + - name: packet-gateway + image: telecom/packet-gateway:latest + ports: + - containerPort: 9000 + name: metrics + env: + - name: REDIS_URL + value: "redis://redis-service:6379" + - name: INTERFACE + value: "eth0" + - name: LOG_LEVEL + value: "info" + securityContext: + privileged: true + capabilities: + add: + - NET_ADMIN + - SYS_ADMIN + resources: + requests: + memory: "256Mi" + cpu: "250m" + limits: + memory: "512Mi" + cpu: "500m" + livenessProbe: + httpGet: + path: /health + port: 9000 + initialDelaySeconds: 30 + periodSeconds: 10 + readinessProbe: + httpGet: + path: /health + port: 9000 + initialDelaySeconds: 5 + periodSeconds: 5 +--- +apiVersion: v1 +kind: Service +metadata: + name: packet-gateway-service + namespace: telecom-platform + labels: + app: packet-gateway +spec: + selector: + app: packet-gateway + ports: + - name: metrics + port: 9000 + targetPort: 9000 + type: ClusterIP +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: web-dashboard + namespace: telecom-platform + labels: + app: web-dashboard + component: frontend +spec: + replicas: 2 + selector: + matchLabels: + app: web-dashboard + template: + metadata: + labels: + app: web-dashboard + component: frontend + spec: + containers: + - name: web-dashboard + image: telecom/web-dashboard:latest + ports: + - containerPort: 3000 + name: http + env: + - name: NEXT_PUBLIC_API_URL + value: "http://api-server-service:8000" + - name: NEXT_PUBLIC_WS_URL + value: "ws://api-server-service:8000" + resources: + requests: + memory: "128Mi" + cpu: "100m" + limits: + memory: "256Mi" + cpu: "200m" + livenessProbe: + httpGet: + path: / + port: 3000 + initialDelaySeconds: 30 + periodSeconds: 10 + readinessProbe: + httpGet: + path: / + port: 3000 + initialDelaySeconds: 5 + periodSeconds: 5 +--- +apiVersion: v1 +kind: Service +metadata: + name: web-dashboard-service + namespace: telecom-platform + labels: + app: web-dashboard +spec: + selector: + app: web-dashboard + ports: + - name: http + port: 3000 + targetPort: 3000 + type: ClusterIP diff --git a/deployments/kubernetes/manifests/configmaps.yaml b/deployments/kubernetes/manifests/configmaps.yaml new file mode 100644 index 0000000..73ae77c --- /dev/null +++ b/deployments/kubernetes/manifests/configmaps.yaml @@ -0,0 +1,159 @@ +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: telecom-config + namespace: telecom-platform +data: + DATABASE_HOST: "postgres-service" + DATABASE_PORT: "5432" + DATABASE_NAME: "telecom_platform" + REDIS_HOST: "redis-service" + REDIS_PORT: "6379" + CHARGING_ENGINE_URL: "http://charging-engine-service:3001" + ES2_URL: "https://smdp.example.com" + INFLUXDB_URL: "http://influxdb-service:8086" + INFLUXDB_ORG: "telecom" + INFLUXDB_BUCKET: "telecom" + METRICS_PORT: "9090" + LOG_LEVEL: "info" +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: postgres-config + namespace: telecom-platform +data: + POSTGRES_DB: "telecom_platform" + POSTGRES_USER: "postgres" + POSTGRES_INIT_SCRIPT: | + CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; + CREATE EXTENSION IF NOT EXISTS "pg_stat_statements"; +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: redis-config + namespace: telecom-platform +data: + redis.conf: | + maxmemory 256mb + maxmemory-policy allkeys-lru + save 900 1 + save 300 10 + save 60 10000 +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: grafana-config + namespace: telecom-monitoring +data: + GF_SECURITY_ADMIN_USER: "admin" + GF_INSTALL_PLUGINS: "grafana-clock-panel,grafana-simple-json-datasource" + GF_FEATURE_TOGGLES_ENABLE: "publicDashboards" +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: prometheus-config + namespace: telecom-monitoring +data: + prometheus.yml: | + global: + scrape_interval: 15s + evaluation_interval: 15s + + rule_files: + - "/etc/prometheus/rules/*.yml" + + alerting: + alertmanagers: + - static_configs: + - targets: + - alertmanager:9093 + + scrape_configs: + - job_name: 'telecom-api-server' + static_configs: + - targets: ['api-server-service:8000'] + metrics_path: '/metrics' + scrape_interval: 5s + + - job_name: 'telecom-charging-engine' + static_configs: + - targets: ['charging-engine-service:3001'] + metrics_path: '/metrics' + scrape_interval: 5s + + - job_name: 'telecom-packet-gateway' + static_configs: + - targets: ['packet-gateway-service:9000'] + metrics_path: '/metrics' + scrape_interval: 5s + + - job_name: 'postgres' + static_configs: + - targets: ['postgres-exporter:9187'] + + - job_name: 'redis' + static_configs: + - targets: ['redis-exporter:9121'] + + - job_name: 'kubernetes-pods' + kubernetes_sd_configs: + - role: pod + relabel_configs: + - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape] + action: keep + regex: true + - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path] + action: replace + target_label: __metrics_path__ + regex: (.+) +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: influxdb-config + namespace: telecom-monitoring +data: + influxdb.conf: | + [meta] + dir = "/var/lib/influxdb/meta" + + [data] + dir = "/var/lib/influxdb/data" + engine = "tsm1" + wal-dir = "/var/lib/influxdb/wal" + + [coordinator] + write-timeout = "10s" + max-concurrent-queries = 0 + query-timeout = "0s" + log-queries-after = "0" + max-select-point = 0 + max-select-series = 0 + max-select-buckets = 0 + + [retention] + enabled = true + check-interval = "30m" + + [shard-precreation] + enabled = true + check-interval = "10m" + advance-period = "30m" + + [monitor] + store-enabled = true + store-database = "_internal" + store-interval = "10s" + + [subscriber] + enabled = true + http-timeout = "30s" + insecure-skip-verify = false + ca-certs = "" + write-consistency = "any" + write-buffer-size = 1000 diff --git a/deployments/kubernetes/manifests/database.yaml b/deployments/kubernetes/manifests/database.yaml new file mode 100644 index 0000000..ae45b94 --- /dev/null +++ b/deployments/kubernetes/manifests/database.yaml @@ -0,0 +1,236 @@ +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: postgres + namespace: telecom-platform + labels: + app: postgres +spec: + serviceName: postgres-service + replicas: 1 + selector: + matchLabels: + app: postgres + template: + metadata: + labels: + app: postgres + spec: + containers: + - name: postgres + image: postgres:15 + ports: + - containerPort: 5432 + env: + - name: POSTGRES_DB + valueFrom: + configMapKeyRef: + name: postgres-config + key: POSTGRES_DB + - name: POSTGRES_USER + valueFrom: + configMapKeyRef: + name: postgres-config + key: POSTGRES_USER + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: postgres-secret + key: POSTGRES_PASSWORD + - name: PGDATA + value: /var/lib/postgresql/data/pgdata + volumeMounts: + - name: postgres-storage + mountPath: /var/lib/postgresql/data + - name: postgres-config + mountPath: /docker-entrypoint-initdb.d + resources: + requests: + memory: "256Mi" + cpu: "250m" + limits: + memory: "512Mi" + cpu: "500m" + volumes: + - name: postgres-config + configMap: + name: postgres-config + volumeClaimTemplates: + - metadata: + name: postgres-storage + spec: + accessModes: ["ReadWriteOnce"] + resources: + requests: + storage: 10Gi +--- +apiVersion: v1 +kind: Service +metadata: + name: postgres-service + namespace: telecom-platform + labels: + app: postgres +spec: + selector: + app: postgres + ports: + - port: 5432 + targetPort: 5432 + type: ClusterIP +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: postgres-exporter + namespace: telecom-platform + labels: + app: postgres-exporter +spec: + replicas: 1 + selector: + matchLabels: + app: postgres-exporter + template: + metadata: + labels: + app: postgres-exporter + spec: + containers: + - name: postgres-exporter + image: prometheuscommunity/postgres-exporter:v0.11.1 + ports: + - containerPort: 9187 + env: + - name: DATA_SOURCE_NAME + value: "postgresql://postgres:password123@postgres-service:5432/telecom_platform?sslmode=disable" + resources: + requests: + memory: "64Mi" + cpu: "50m" + limits: + memory: "128Mi" + cpu: "100m" +--- +apiVersion: v1 +kind: Service +metadata: + name: postgres-exporter + namespace: telecom-platform + labels: + app: postgres-exporter +spec: + selector: + app: postgres-exporter + ports: + - port: 9187 + targetPort: 9187 + type: ClusterIP +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: redis + namespace: telecom-platform + labels: + app: redis +spec: + replicas: 1 + selector: + matchLabels: + app: redis + template: + metadata: + labels: + app: redis + spec: + containers: + - name: redis + image: redis:7-alpine + ports: + - containerPort: 6379 + command: + - redis-server + - /etc/redis/redis.conf + volumeMounts: + - name: redis-config + mountPath: /etc/redis + - name: redis-storage + mountPath: /data + resources: + requests: + memory: "128Mi" + cpu: "100m" + limits: + memory: "256Mi" + cpu: "200m" + volumes: + - name: redis-config + configMap: + name: redis-config + - name: redis-storage + emptyDir: {} +--- +apiVersion: v1 +kind: Service +metadata: + name: redis-service + namespace: telecom-platform + labels: + app: redis +spec: + selector: + app: redis + ports: + - port: 6379 + targetPort: 6379 + type: ClusterIP +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: redis-exporter + namespace: telecom-platform + labels: + app: redis-exporter +spec: + replicas: 1 + selector: + matchLabels: + app: redis-exporter + template: + metadata: + labels: + app: redis-exporter + spec: + containers: + - name: redis-exporter + image: oliver006/redis_exporter:v1.48.0 + ports: + - containerPort: 9121 + env: + - name: REDIS_ADDR + value: "redis://redis-service:6379" + resources: + requests: + memory: "64Mi" + cpu: "50m" + limits: + memory: "128Mi" + cpu: "100m" +--- +apiVersion: v1 +kind: Service +metadata: + name: redis-exporter + namespace: telecom-platform + labels: + app: redis-exporter +spec: + selector: + app: redis-exporter + ports: + - port: 9121 + targetPort: 9121 + type: ClusterIP diff --git a/deployments/kubernetes/manifests/hpa.yaml b/deployments/kubernetes/manifests/hpa.yaml new file mode 100644 index 0000000..edd1a9a --- /dev/null +++ b/deployments/kubernetes/manifests/hpa.yaml @@ -0,0 +1,181 @@ +--- +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: api-server-hpa + namespace: telecom-platform + labels: + app: api-server +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: api-server + minReplicas: 3 + maxReplicas: 10 + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 70 + - type: Resource + resource: + name: memory + target: + type: Utilization + averageUtilization: 80 + behavior: + scaleDown: + stabilizationWindowSeconds: 300 + policies: + - type: Percent + value: 10 + periodSeconds: 60 + scaleUp: + stabilizationWindowSeconds: 60 + policies: + - type: Percent + value: 50 + periodSeconds: 60 +--- +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: charging-engine-hpa + namespace: telecom-platform + labels: + app: charging-engine +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: charging-engine + minReplicas: 2 + maxReplicas: 6 + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 70 + - type: Resource + resource: + name: memory + target: + type: Utilization + averageUtilization: 80 +--- +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: packet-gateway-hpa + namespace: telecom-platform + labels: + app: packet-gateway +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: packet-gateway + minReplicas: 2 + maxReplicas: 4 + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 75 + - type: Resource + resource: + name: memory + target: + type: Utilization + averageUtilization: 85 +--- +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: web-dashboard-hpa + namespace: telecom-platform + labels: + app: web-dashboard +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: web-dashboard + minReplicas: 2 + maxReplicas: 6 + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 70 + - type: Resource + resource: + name: memory + target: + type: Utilization + averageUtilization: 80 +--- +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: prometheus-hpa + namespace: telecom-monitoring + labels: + app: prometheus +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: prometheus + minReplicas: 1 + maxReplicas: 3 + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 80 + - type: Resource + resource: + name: memory + target: + type: Utilization + averageUtilization: 85 +--- +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: grafana-hpa + namespace: telecom-monitoring + labels: + app: grafana +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: grafana + minReplicas: 1 + maxReplicas: 2 + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 70 + - type: Resource + resource: + name: memory + target: + type: Utilization + averageUtilization: 80 diff --git a/deployments/kubernetes/manifests/ingress.yaml b/deployments/kubernetes/manifests/ingress.yaml new file mode 100644 index 0000000..431a3db --- /dev/null +++ b/deployments/kubernetes/manifests/ingress.yaml @@ -0,0 +1,91 @@ +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: telecom-ingress + namespace: telecom-platform + annotations: + kubernetes.io/ingress.class: "nginx" + nginx.ingress.kubernetes.io/rewrite-target: / + nginx.ingress.kubernetes.io/ssl-redirect: "true" + cert-manager.io/cluster-issuer: "letsencrypt-prod" + nginx.ingress.kubernetes.io/rate-limit: "100" + nginx.ingress.kubernetes.io/rate-limit-window: "1m" +spec: + tls: + - hosts: + - api.telecom.example.com + - dashboard.telecom.example.com + secretName: telecom-tls + rules: + - host: api.telecom.example.com + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: api-server-service + port: + number: 8000 + - host: dashboard.telecom.example.com + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: web-dashboard-service + port: + number: 3000 +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: monitoring-ingress + namespace: telecom-monitoring + annotations: + kubernetes.io/ingress.class: "nginx" + nginx.ingress.kubernetes.io/rewrite-target: / + nginx.ingress.kubernetes.io/ssl-redirect: "true" + cert-manager.io/cluster-issuer: "letsencrypt-prod" + nginx.ingress.kubernetes.io/auth-type: "basic" + nginx.ingress.kubernetes.io/auth-secret: "monitoring-auth" +spec: + tls: + - hosts: + - grafana.telecom.example.com + - prometheus.telecom.example.com + secretName: monitoring-tls + rules: + - host: grafana.telecom.example.com + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: grafana + port: + number: 3000 + - host: prometheus.telecom.example.com + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: prometheus + port: + number: 9090 +--- +apiVersion: v1 +kind: Secret +metadata: + name: monitoring-auth + namespace: telecom-monitoring + annotations: + nginx.ingress.kubernetes.io/auth-type: "basic" +type: Opaque +data: + auth: YWRtaW46JGEw1JHJlZzUkN2U4JDQ= # admin:$a1$rezE$7e8$D (admin/admin123) diff --git a/deployments/kubernetes/manifests/monitoring-configmaps.yaml b/deployments/kubernetes/manifests/monitoring-configmaps.yaml new file mode 100644 index 0000000..8526881 --- /dev/null +++ b/deployments/kubernetes/manifests/monitoring-configmaps.yaml @@ -0,0 +1,325 @@ +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: alertmanager-config + namespace: telecom-monitoring +data: + alertmanager.yml: | + global: + smtp_smarthost: 'localhost:587' + smtp_from: 'alerts@telecom.example.com' + + route: + group_by: ['alertname'] + group_wait: 10s + group_interval: 10s + repeat_interval: 1h + receiver: 'web.hook' + routes: + - match: + severity: critical + receiver: 'critical-alerts' + - match: + severity: warning + receiver: 'warning-alerts' + + receivers: + - name: 'web.hook' + webhook_configs: + - url: 'http://api-server-service:8000/webhooks/alertmanager' + send_resolved: true + - name: 'critical-alerts' + webhook_configs: + - url: 'http://api-server-service:8000/webhooks/critical-alerts' + send_resolved: true + email_configs: + - to: 'admin@telecom.example.com' + subject: '[CRITICAL] Telecom Platform Alert' + body: | + {{ range .Alerts }} + Alert: {{ .Annotations.summary }} + Description: {{ .Annotations.description }} + Labels: {{ range .Labels.SortedPairs }}{{ .Name }}={{ .Value }} {{ end }} + {{ end }} + - name: 'warning-alerts' + webhook_configs: + - url: 'http://api-server-service:8000/webhooks/warning-alerts' + send_resolved: true + + inhibit_rules: + - source_match: + severity: 'critical' + target_match: + severity: 'warning' + equal: ['alertname', 'instance'] +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: grafana-provisioning + namespace: telecom-monitoring +data: + datasources.yml: | + apiVersion: 1 + + datasources: + - name: Prometheus + type: prometheus + access: proxy + url: http://prometheus:9090 + isDefault: true + editable: true + + - name: InfluxDB + type: influxdb + access: proxy + url: http://influxdb-service:8086 + database: telecom + user: admin + jsonData: + version: Flux + organization: telecom + defaultBucket: telecom + tlsSkipVerify: true + secureJsonData: + token: telecom-super-secret-auth-token + editable: true + + dashboards.yml: | + apiVersion: 1 + + providers: + - name: 'telecom-dashboards' + orgId: 1 + folder: '' + type: file + disableDeletion: false + updateIntervalSeconds: 10 + allowUiUpdates: true + options: + path: /var/lib/grafana/dashboards +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: grafana-dashboards + namespace: telecom-monitoring +data: + telecom-overview.json: | + { + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "description": "Telecom Platform Overview Dashboard", + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": "shared_crosshair", + "id": null, + "links": [], + "liveNow": false, + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "Total number of subscribers", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "vis": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 1, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "expr": "telecom_subscribers_total", + "interval": "", + "legendFormat": "Total Subscribers", + "refId": "A" + } + ], + "title": "Total Subscribers", + "type": "timeseries" + } + ], + "refresh": "5s", + "schemaVersion": 38, + "style": "dark", + "tags": ["telecom"], + "templating": { + "list": [] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "Telecom Platform Overview", + "uid": "telecom-overview", + "version": 1, + "weekStart": "" + } +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: prometheus-rules + namespace: telecom-monitoring +data: + alert_rules.yml: | + groups: + - name: telecom_alerts + rules: + - alert: HighErrorRate + expr: rate(telecom_http_requests_total{status_code=~"5.."}[5m]) > 0.1 + for: 5m + labels: + severity: critical + annotations: + summary: "High error rate detected" + description: "Error rate is {{ $value }} errors per second" + + - alert: LowCreditBalance + expr: telecom_credit_balance < 5 + for: 2m + labels: + severity: warning + annotations: + summary: "Subscriber has low credit balance" + description: "Subscriber {{ $labels.subscriber_id }} has balance {{ $value }}" + + - alert: HighMemoryUsage + expr: (container_memory_usage_bytes / container_spec_memory_limit_bytes) * 100 > 90 + for: 5m + labels: + severity: warning + annotations: + summary: "High memory usage" + description: "Container {{ $labels.container }} memory usage is {{ $value }}%" + + - alert: HighCPUUsage + expr: rate(container_cpu_usage_seconds_total[5m]) * 100 > 80 + for: 5m + labels: + severity: warning + annotations: + summary: "High CPU usage" + description: "Container {{ $labels.container }} CPU usage is {{ $value }}%" + + - alert: DatabaseConnectionFailure + expr: up{job="postgres"} == 0 + for: 1m + labels: + severity: critical + annotations: + summary: "Database connection failure" + description: "PostgreSQL database is down" + + - alert: RedisConnectionFailure + expr: up{job="redis"} == 0 + for: 1m + labels: + severity: critical + annotations: + summary: "Redis connection failure" + description: "Redis cache is down" + + - alert: ChargingEngineDown + expr: up{job="telecom-charging-engine"} == 0 + for: 2m + labels: + severity: critical + annotations: + summary: "Charging engine is down" + description: "Rust charging engine service is not responding" + + - alert: PacketGatewayDown + expr: up{job="telecom-packet-gateway"} == 0 + for: 2m + labels: + severity: critical + annotations: + summary: "Packet gateway is down" + description: "eBPF packet gateway service is not responding" diff --git a/deployments/kubernetes/manifests/monitoring.yaml b/deployments/kubernetes/manifests/monitoring.yaml new file mode 100644 index 0000000..405cbf5 --- /dev/null +++ b/deployments/kubernetes/manifests/monitoring.yaml @@ -0,0 +1,474 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: prometheus + namespace: telecom-monitoring + labels: + app: prometheus + component: monitoring +spec: + replicas: 1 + selector: + matchLabels: + app: prometheus + template: + metadata: + labels: + app: prometheus + component: monitoring + spec: + containers: + - name: prometheus + image: prom/prometheus:v2.45.0 + ports: + - containerPort: 9090 + name: http + command: + - /bin/prometheus + - --config.file=/etc/prometheus/prometheus.yml + - --storage.tsdb.path=/prometheus + - --storage.tsdb.retention.time=30d + - --web.console.libraries=/etc/prometheus/console_libraries + - --web.console.templates=/etc/prometheus/consoles + - --web.enable-lifecycle + volumeMounts: + - name: prometheus-config + mountPath: /etc/prometheus + - name: prometheus-storage + mountPath: /prometheus + resources: + requests: + memory: "512Mi" + cpu: "500m" + limits: + memory: "1Gi" + cpu: "1000m" + livenessProbe: + httpGet: + path: /-/healthy + port: 9090 + initialDelaySeconds: 30 + periodSeconds: 10 + readinessProbe: + httpGet: + path: /-/ready + port: 9090 + initialDelaySeconds: 5 + periodSeconds: 5 + volumes: + - name: prometheus-config + configMap: + name: prometheus-config + - name: prometheus-storage + persistentVolumeClaim: + claimName: prometheus-storage +--- +apiVersion: v1 +kind: Service +metadata: + name: prometheus + namespace: telecom-monitoring + labels: + app: prometheus +spec: + selector: + app: prometheus + ports: + - name: http + port: 9090 + targetPort: 9090 + type: ClusterIP +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: prometheus-storage + namespace: telecom-monitoring +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 20Gi +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: grafana + namespace: telecom-monitoring + labels: + app: grafana + component: monitoring +spec: + replicas: 1 + selector: + matchLabels: + app: grafana + template: + metadata: + labels: + app: grafana + component: monitoring + spec: + containers: + - name: grafana + image: grafana/grafana:10.2.0 + ports: + - containerPort: 3000 + name: http + env: + - name: GF_SECURITY_ADMIN_USER + valueFrom: + configMapKeyRef: + name: grafana-config + key: GF_SECURITY_ADMIN_USER + - name: GF_SECURITY_ADMIN_PASSWORD + valueFrom: + secretKeyRef: + name: grafana-secret + key: GF_SECURITY_ADMIN_PASSWORD + - name: GF_INSTALL_PLUGINS + valueFrom: + configMapKeyRef: + name: grafana-config + key: GF_INSTALL_PLUGINS + - name: GF_FEATURE_TOGGLES_ENABLE + valueFrom: + configMapKeyRef: + name: grafana-config + key: GF_FEATURE_TOGGLES_ENABLE + - name: GF_SECURITY_ADMIN_USER + valueFrom: + configMapKeyRef: + name: grafana-config + key: GF_SECURITY_ADMIN_USER + volumeMounts: + - name: grafana-storage + mountPath: /var/lib/grafana + - name: grafana-config + mountPath: /etc/grafana/provisioning + - name: grafana-dashboards + mountPath: /var/lib/grafana/dashboards + resources: + requests: + memory: "256Mi" + cpu: "250m" + limits: + memory: "512Mi" + cpu: "500m" + livenessProbe: + httpGet: + path: /api/health + port: 3000 + initialDelaySeconds: 30 + periodSeconds: 10 + readinessProbe: + httpGet: + path: /api/health + port: 3000 + initialDelaySeconds: 5 + periodSeconds: 5 + volumes: + - name: grafana-storage + persistentVolumeClaim: + claimName: grafana-storage + - name: grafana-config + configMap: + name: grafana-provisioning + - name: grafana-dashboards + configMap: + name: grafana-dashboards +--- +apiVersion: v1 +kind: Service +metadata: + name: grafana + namespace: telecom-monitoring + labels: + app: grafana +spec: + selector: + app: grafana + ports: + - name: http + port: 3000 + targetPort: 3000 + type: ClusterIP +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: grafana-storage + namespace: telecom-monitoring +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: influxdb + namespace: telecom-monitoring + labels: + app: influxdb + component: monitoring +spec: + replicas: 1 + selector: + matchLabels: + app: influxdb + template: + metadata: + labels: + app: influxdb + component: monitoring + spec: + containers: + - name: influxdb + image: influxdb:2.7 + ports: + - containerPort: 8086 + name: http + env: + - name: DOCKER_INFLUXDB_INIT_MODE + value: "setup" + - name: DOCKER_INFLUXDB_INIT_USERNAME + valueFrom: + secretKeyRef: + name: influxdb-secret + key: INFLUXDB_ADMIN_USER + - name: DOCKER_INFLUXDB_INIT_PASSWORD + valueFrom: + secretKeyRef: + name: influxdb-secret + key: INFLUXDB_ADMIN_PASSWORD + - name: DOCKER_INFLUXDB_INIT_ORG + value: "telecom" + - name: DOCKER_INFLUXDB_INIT_BUCKET + value: "telecom" + - name: DOCKER_INFLUXDB_INIT_ADMIN_TOKEN + valueFrom: + secretKeyRef: + name: influxdb-secret + key: INFLUXDB_ADMIN_TOKEN + volumeMounts: + - name: influxdb-storage + mountPath: /var/lib/influxdb2 + resources: + requests: + memory: "512Mi" + cpu: "500m" + limits: + memory: "1Gi" + cpu: "1000m" + livenessProbe: + httpGet: + path: /health + port: 8086 + initialDelaySeconds: 30 + periodSeconds: 10 + readinessProbe: + httpGet: + path: /health + port: 8086 + initialDelaySeconds: 5 + periodSeconds: 5 + volumes: + - name: influxdb-storage + persistentVolumeClaim: + claimName: influxdb-storage +--- +apiVersion: v1 +kind: Service +metadata: + name: influxdb-service + namespace: telecom-monitoring + labels: + app: influxdb +spec: + selector: + app: influxdb + ports: + - name: http + port: 8086 + targetPort: 8086 + type: ClusterIP +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: influxdb-storage + namespace: telecom-monitoring +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 20Gi +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: alertmanager + namespace: telecom-monitoring + labels: + app: alertmanager + component: monitoring +spec: + replicas: 1 + selector: + matchLabels: + app: alertmanager + template: + metadata: + labels: + app: alertmanager + component: monitoring + spec: + containers: + - name: alertmanager + image: prom/alertmanager:v0.25.0 + ports: + - containerPort: 9093 + name: http + command: + - /bin/alertmanager + - --config.file=/etc/alertmanager/alertmanager.yml + - --storage.path=/alertmanager + - --web.external-url=http://alertmanager:9093 + volumeMounts: + - name: alertmanager-config + mountPath: /etc/alertmanager + - name: alertmanager-storage + mountPath: /alertmanager + resources: + requests: + memory: "128Mi" + cpu: "100m" + limits: + memory: "256Mi" + cpu: "200m" + livenessProbe: + httpGet: + path: /-/healthy + port: 9093 + initialDelaySeconds: 30 + periodSeconds: 10 + readinessProbe: + httpGet: + path: /-/ready + port: 9093 + initialDelaySeconds: 5 + periodSeconds: 5 + volumes: + - name: alertmanager-config + configMap: + name: alertmanager-config + - name: alertmanager-storage + persistentVolumeClaim: + claimName: alertmanager-storage +--- +apiVersion: v1 +kind: Service +metadata: + name: alertmanager + namespace: telecom-monitoring + labels: + app: alertmanager +spec: + selector: + app: alertmanager + ports: + - name: http + port: 9093 + targetPort: 9093 + type: ClusterIP +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: alertmanager-storage + namespace: telecom-monitoring +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 5Gi +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: node-exporter + namespace: telecom-monitoring + labels: + app: node-exporter + component: monitoring +spec: + replicas: 1 + selector: + matchLabels: + app: node-exporter + template: + metadata: + labels: + app: node-exporter + component: monitoring + spec: + containers: + - name: node-exporter + image: prom/node-exporter:v1.6.1 + ports: + - containerPort: 9100 + name: http + command: + - /bin/node_exporter + - --path.procfs=/host/proc + - --path.rootfs=/rootfs + - --path.sysfs=/host/sys + - --collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/) + volumeMounts: + - name: proc + mountPath: /host/proc + - name: sys + mountPath: /host/sys + - name: root + mountPath: /rootfs + readOnly: true + resources: + requests: + memory: "64Mi" + cpu: "50m" + limits: + memory: "128Mi" + cpu: "100m" + volumes: + - name: proc + hostPath: + path: /proc + - name: sys + hostPath: + path: /sys + - name: root + hostPath: + path: / +--- +apiVersion: v1 +kind: Service +metadata: + name: node-exporter + namespace: telecom-monitoring + labels: + app: node-exporter +spec: + selector: + app: node-exporter + ports: + - name: http + port: 9100 + targetPort: 9100 + type: ClusterIP diff --git a/deployments/kubernetes/manifests/namespace.yaml b/deployments/kubernetes/manifests/namespace.yaml new file mode 100644 index 0000000..bb70a6e --- /dev/null +++ b/deployments/kubernetes/manifests/namespace.yaml @@ -0,0 +1,16 @@ +--- +apiVersion: v1 +kind: Namespace +metadata: + name: telecom-platform + labels: + name: telecom-platform + environment: production +--- +apiVersion: v1 +kind: Namespace +metadata: + name: telecom-monitoring + labels: + name: telecom-monitoring + environment: production diff --git a/deployments/kubernetes/manifests/secrets.yaml b/deployments/kubernetes/manifests/secrets.yaml new file mode 100644 index 0000000..469b2c3 --- /dev/null +++ b/deployments/kubernetes/manifests/secrets.yaml @@ -0,0 +1,45 @@ +--- +apiVersion: v1 +kind: Secret +metadata: + name: telecom-secrets + namespace: telecom-platform +type: Opaque +data: + DATABASE_PASSWORD: cGFzc3dvcmQxMjM= # password123 + REDIS_PASSWORD: "" + STRIPE_API_KEY: "" + STRIPE_WEBHOOK_SECRET: "" + ES2_API_KEY: "" + INFLUXDB_TOKEN: dGVsZWNvbS1zdXBlci1zZWNyZXQtYXV0aC10b2tlbg== # telecom-super-secret-auth-token +--- +apiVersion: v1 +kind: Secret +metadata: + name: postgres-secret + namespace: telecom-platform +type: Opaque +data: + POSTGRES_PASSWORD: cGFzc3dvcmQxMjM= # password123 +--- +apiVersion: v1 +kind: Secret +metadata: + name: grafana-secret + namespace: telecom-monitoring +type: Opaque +data: + GF_SECURITY_ADMIN_PASSWORD: YWRtaW4xMjM= # admin123 +--- +apiVersion: v1 +kind: Secret +metadata: + name: influxdb-secret + namespace: telecom-monitoring +type: Opaque +data: + INFLUXDB_ADMIN_USER: YWRtaW4= # admin + INFLUXDB_ADMIN_PASSWORD: cGFzc3dvcmQxMjM= # password123 + INFLUXDB_USER: dGVsZWNvbQ== # telecom + INFLUXDB_PASSWORD: dGVsZWNvbXBhc3M= # telecompass + INFLUXDB_ADMIN_TOKEN: dGVsZWNvbS1zdXBlci1zZWNyZXQtYXV0aC10b2tlbg== # telecom-super-secret-auth-token diff --git a/deployments/vault/vault-install.yaml b/deployments/vault/vault-install.yaml new file mode 100644 index 0000000..b166f5c --- /dev/null +++ b/deployments/vault/vault-install.yaml @@ -0,0 +1,198 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: vault + labels: + app.kubernetes.io/name: vault + app.kubernetes.io/component: secrets + app.kubernetes.io/part-of: telecom-platform +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: vault + namespace: vault + labels: + app.kubernetes.io/name: vault + app.kubernetes.io/component: secrets + app.kubernetes.io/part-of: telecom-platform +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: vault + app.kubernetes.io/component: secrets + template: + metadata: + labels: + app.kubernetes.io/name: vault + app.kubernetes.io/component: secrets + spec: + containers: + - name: vault + image: hashicorp/vault:1.14.0 + ports: + - containerPort: 8200 + name: vault + - containerPort: 8201 + name: cluster + env: + - name: VAULT_ADDR + value: "http://localhost:8200" + - name: VAULT_CLUSTER_ADDR + value: "http://localhost:8201" + - name: VAULT_LOCAL_CONFIG + valueFrom: + configMapKeyRef: + name: vault-config + key: vault.hcl + - name: VAULT_LOCAL_CONFIG_SKIP_BACKEND_CONFIG + value: "true" + - name: VAULT_SKIP_VERIFY + value: "true" + - name: SKIP_CHOWN + value: "true" + - name: VAULT_CACERT + value: "/vault/tls/ca.crt" + - name: VAULT_TLSCERT + value: "/vault/tls/server.crt" + - name: VAULT_TLSKEY + value: "/vault/tls/server.key" + command: + - vault + - server + - -config=/vault/config/vault.hcl + resources: + requests: + cpu: 100m + memory: 256Mi + limits: + cpu: 500m + memory: 512Mi + securityContext: + capabilities: + add: + - IPC_LOCK + volumeMounts: + - name: vault-config + mountPath: /vault/config + - name: vault-tls + mountPath: /vault/tls + livenessProbe: + httpGet: + path: /v1/sys/health + port: vault + initialDelaySeconds: 60 + periodSeconds: 10 + readinessProbe: + httpGet: + path: /v1/sys/health + port: vault + initialDelaySeconds: 30 + periodSeconds: 5 + volumes: + - name: vault-config + configMap: + name: vault-config + - name: vault-tls + emptyDir: + medium: Memory +--- +apiVersion: v1 +kind: Service +metadata: + name: vault + namespace: vault + labels: + app.kubernetes.io/name: vault + app.kubernetes.io/component: secrets + app.kubernetes.io/part-of: telecom-platform +spec: + ports: + - port: 8200 + name: vault + targetPort: 8200 + - port: 8201 + name: cluster + targetPort: 8201 + selector: + app.kubernetes.io/name: vault + app.kubernetes.io/component: secrets + type: ClusterIP +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: vault-config + namespace: vault + labels: + app.kubernetes.io/name: vault + app.kubernetes.io/component: secrets + app.kubernetes.io/part-of: telecom-platform +data: + vault.hcl: | + ui = true + + listener "tcp" { + address = "0.0.0.0:8200" + cluster_address = "0.0.0.0:8201" + tls_disable = 1 + } + + storage "consul" { + address = "consul:8500" + path = "vault/" + } + + api_addr = "http://vault:8200" + cluster_addr = "http://vault:8201" + + default_lease_ttl = "168h" + max_lease_ttl = "720h" + + disable_mlock = true + + telemetry { + prometheus_retention_time = "24h" + disable_hostname = true + } +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: vault + namespace: vault + labels: + app.kubernetes.io/name: vault + app.kubernetes.io/component: secrets + app.kubernetes.io/part-of: telecom-platform +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: vault + labels: + app.kubernetes.io/name: vault + app.kubernetes.io/component: secrets + app.kubernetes.io/part-of: telecom-platform +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:auth-delegator +subjects: +- kind: ServiceAccount + name: vault + namespace: vault +--- +apiVersion: v1 +kind: Secret +metadata: + name: vault-token + namespace: vault + labels: + app.kubernetes.io/name: vault + app.kubernetes.io/component: secrets + app.kubernetes.io/part-of: telecom-platform +type: Opaque +data: + token: cm9vdA== # root diff --git a/deployments/vault/vault-secrets-config.yaml b/deployments/vault/vault-secrets-config.yaml new file mode 100644 index 0000000..d61db13 --- /dev/null +++ b/deployments/vault/vault-secrets-config.yaml @@ -0,0 +1,182 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: vault-secrets-config + namespace: vault + labels: + app.kubernetes.io/name: vault + app.kubernetes.io/component: secrets + app.kubernetes.io/part-of: telecom-platform +data: + init-secrets.sh: | + #!/bin/sh + + # Wait for Vault to be ready + until vault status; do + echo "Waiting for Vault to be ready..." + sleep 2 + done + + # Initialize Vault + vault operator init -key-shares=5 -key-threshold=3 > /tmp/vault-init.txt + + # Unseal Vault (in production, this should be done manually) + VAULT_TOKEN=$(grep 'Initial Root Token:' /tmp/vault-init.txt | awk '{print $4}') + export VAULT_TOKEN + + # Unseal with 3 keys + vault operator unseal $(grep 'Key 1:' /tmp/vault-init.txt | awk '{print $3}') + vault operator unseal $(grep 'Key 2:' /tmp/vault-init.txt | awk '{print $3}') + vault operator unseal $(grep 'Key 3:' /tmp/vault-init.txt | awk '{print $3}') + + # Enable auth methods + vault auth enable kubernetes + vault auth enable oidc + vault auth enable userpass + + # Enable secrets engines + vault secrets enable kv-v2 + vault secrets enable database + vault secrets enable transit + + # Configure Kubernetes auth + vault write auth/kubernetes/config \ + token_reviewer_jwt="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \ + kubernetes_host="https://${KUBERNETES_PORT_443_TCP_ADDR}:443" \ + kubernetes_ca_cert="$(cat /var/run/secrets/kubernetes.io.serviceaccount/ca.crt)" + + # Create policies + vault policy write telecom-platform - <