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