Kubernetes Deployment

In this tutorial, you will learn how to deploy Alerta to a Kubernetes cluster using the official Docker image.

Contents

Overview

The Alerta Docker image contains the API server, web UI, housekeeping, plugins, and webhooks. Deploying to Kubernetes involves creating a database backend, configuring the application via ConfigMaps and Secrets, and exposing it through a Service and Ingress.

Prerequisites

Before you begin, you should have:

Step 1: Create a namespace

Create a dedicated namespace for the Alerta deployment:

$ kubectl create namespace alerta

Set it as the default for subsequent commands:

$ kubectl config set-context --current --namespace=alerta

Step 2: Deploy PostgreSQL

Deploy a simple PostgreSQL instance using a StatefulSet. Create a file called postgres.yaml:

apiVersion: v1
kind: Secret
metadata:
  name: postgres-secret
  namespace: alerta
type: Opaque
stringData:
  POSTGRES_USER: alerta
  POSTGRES_PASSWORD: ch4ng3m3
---
apiVersion: v1
kind: Service
metadata:
  name: postgres
  namespace: alerta
spec:
  selector:
    app: postgres
  ports:
    - port: 5432
  clusterIP: None
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: postgres
  namespace: alerta
spec:
  serviceName: postgres
  replicas: 1
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
        - name: postgres
          image: postgres:16
          envFrom:
            - secretRef:
                name: postgres-secret
          ports:
            - containerPort: 5432
          volumeMounts:
            - name: pgdata
              mountPath: /var/lib/postgresql/data
  volumeClaimTemplates:
    - metadata:
        name: pgdata
      spec:
        accessModes: ["ReadWriteOnce"]
        resources:
          requests:
            storage: 5Gi

Apply it:

$ kubectl apply -f postgres.yaml

Note

For production, consider using a PostgreSQL operator such as CloudNativePG or a managed database service.

Step 3: Create ConfigMap and Secret

Store the Alerta configuration in a ConfigMap and sensitive values in a Secret:

apiVersion: v1
kind: Secret
metadata:
  name: alerta-secret
  namespace: alerta
type: Opaque
stringData:
  DATABASE_URL: "postgres://alerta:ch4ng3m3@postgres:5432/alerta"
  ADMIN_PASSWORD: "Pa55w0rd"
  ADMIN_KEY: "k8s-admin-api-key"
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: alerta-config
  namespace: alerta
data:
  AUTH_REQUIRED: "True"
  ADMIN_USERS: "admin@example.com"
  PLUGINS: "reject,heartbeat,blackout"

Save as alerta-config.yaml and apply:

$ kubectl apply -f alerta-config.yaml

Step 4: Deploy the Alerta API

Create a Deployment and Service for the Alerta server. Save the following as alerta-deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: alerta
  namespace: alerta
spec:
  replicas: 2
  selector:
    matchLabels:
      app: alerta
  template:
    metadata:
      labels:
        app: alerta
    spec:
      containers:
        - name: alerta
          image: alerta/alerta-web:latest
          ports:
            - containerPort: 8080
          envFrom:
            - secretRef:
                name: alerta-secret
            - configMapRef:
                name: alerta-config
          readinessProbe:
            httpGet:
              path: /api/management/gtg
              port: 8080
            initialDelaySeconds: 10
            periodSeconds: 10
          livenessProbe:
            httpGet:
              path: /_
              port: 8080
            initialDelaySeconds: 15
            periodSeconds: 20
          resources:
            requests:
              cpu: 100m
              memory: 256Mi
            limits:
              cpu: 500m
              memory: 512Mi
---
apiVersion: v1
kind: Service
metadata:
  name: alerta
  namespace: alerta
spec:
  selector:
    app: alerta
  ports:
    - port: 8080
      targetPort: 8080

Apply it:

$ kubectl apply -f alerta-deployment.yaml

Step 5: Create an Ingress

Expose Alerta externally using an Ingress resource. This example assumes an nginx ingress controller is installed:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: alerta-ingress
  namespace: alerta
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
    - host: alerta.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: alerta
                port:
                  number: 8080

Save as alerta-ingress.yaml and apply:

$ kubectl apply -f alerta-ingress.yaml

Step 6: Verify the deployment

Check that all pods are running:

$ kubectl get pods -n alerta
NAME                      READY   STATUS    RESTARTS   AGE
alerta-6d8f9b7c4d-abc12   1/1     Running   0          2m
alerta-6d8f9b7c4d-def34   1/1     Running   0          2m
postgres-0                1/1     Running   0          5m

Test the health check endpoint:

$ kubectl port-forward svc/alerta 8080:8080 -n alerta &
$ curl http://localhost:8080/api/management/healthcheck
{"status": "ok"}

Send a test alert:

$ curl -X POST http://localhost:8080/api/alert \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Key k8s-admin-api-key' \
  -d '{
    "resource": "k8s-test",
    "event": "DeploymentTest",
    "environment": "Development",
    "service": ["Kubernetes"],
    "severity": "informational",
    "text": "Alerta is running on Kubernetes"
  }'

Browse to the web UI at http://localhost:8080 (via port-forward) or at your Ingress hostname to confirm everything is working.

Next Steps

  • Configure TLS on the Ingress for production use

  • Set up Horizontal Pod Autoscaling for the Alerta Deployment

  • Troubleshooting