HypLab

Kubernetes Deployment

Deploy HypLab to Kubernetes (EKS, GKE, AKS, or self-hosted).

Kubernetes Deployment

This guide covers deploying HypLab to Kubernetes clusters (EKS, GKE, AKS, or self-hosted).

Prerequisites

  • Kubernetes cluster (1.24+)
  • kubectl configured
  • Helm 3.0+ (optional, for easier deployment)
  • MongoDB Atlas or managed MongoDB
  • Redis Cloud or managed Redis
  • Domain name and DNS access

Step 1: Create Namespace

kubectl create namespace hyplab
kubectl config set-context --current --namespace=hyplab

Step 2: Create Secrets

API Secrets

kubectl create secret generic hyplab-secrets \
  --from-literal=jwt-secret=your-jwt-secret \
  --from-literal=session-secret=your-session-secret \
  --from-literal=mongodb-url=mongodb+srv://user:password@cluster.mongodb.net/hyplab \
  --from-literal=redis-url=redis://user:password@redis-host:6379 \
  -n hyplab

Frontend Secrets

kubectl create secret generic app-secrets \
  --from-literal=api-url=https://api.yourdomain.com \
  -n hyplab

Step 3: Deployments

Gateway Deployment

Create k8s/gateway-deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api
  namespace: hyplab
spec:
  replicas: 3
  selector:
    matchLabels:
      app: api
  template:
    metadata:
      labels:
        app: api
    spec:
      containers:
        - name: gateway
          image: your-registry/api:latest
          ports:
            - containerPort: 4096
          env:
            - name: NODE_ENV
              value: 'production'
            - name: PORT
              value: '4096'
            - name: MONGODB_URL
              valueFrom:
                secretKeyRef:
                  name: hyplab-secrets
                  key: mongodb-url
            - name: REDIS_URL
              valueFrom:
                secretKeyRef:
                  name: hyplab-secrets
                  key: redis-url
            - name: JWT_SECRET
              valueFrom:
                secretKeyRef:
                  name: hyplab-secrets
                  key: jwt-secret
          resources:
            requests:
              memory: '512Mi'
              cpu: '500m'
            limits:
              memory: '2Gi'
              cpu: '2000m'
          livenessProbe:
            httpGet:
              path: /health
              port: 4096
            initialDelaySeconds: 30
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: /health
              port: 4096
            initialDelaySeconds: 10
            periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
  name: api
  namespace: hyplab
spec:
  selector:
    app: api
  ports:
    - port: 80
      targetPort: 4096
  type: ClusterIP

Web Deployment

Create k8s/web-deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app
  namespace: hyplab
spec:
  replicas: 2
  selector:
    matchLabels:
      app: app
  template:
    metadata:
      labels:
        app: app
    spec:
      containers:
        - name: web
          image: your-registry/app:latest
          ports:
            - containerPort: 3000
          env:
            - name: NODE_ENV
              value: 'production'
            - name: NEXT_PUBLIC_API_URL
              valueFrom:
                secretKeyRef:
                  name: app-secrets
                  key: api-url
          resources:
            requests:
              memory: '1Gi'
              cpu: '500m'
            limits:
              memory: '2Gi'
              cpu: '2000m'
          livenessProbe:
            httpGet:
              path: /
              port: 3000
            initialDelaySeconds: 30
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: /
              port: 3000
            initialDelaySeconds: 10
            periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
  name: app
  namespace: hyplab
spec:
  selector:
    app: app
  ports:
    - port: 80
      targetPort: 3000
  type: ClusterIP

Step 4: Ingress Configuration

Using NGINX Ingress

Create k8s/ingress.yaml:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: hyplab-ingress
  namespace: hyplab
  annotations:
    kubernetes.io/ingress.class: nginx
    cert-manager.io/cluster-issuer: letsencrypt-prod
    nginx.ingress.kubernetes.io/ssl-redirect: 'true'
spec:
  tls:
    - hosts:
        - yourdomain.com
        - api.yourdomain.com
      secretName: hyplab-tls
  rules:
    - host: yourdomain.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: app
                port:
                  number: 80
    - host: api.yourdomain.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: api
                port:
                  number: 80

Install NGINX Ingress Controller

# For cloud providers
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.1/deploy/static/provider/cloud/deploy.yaml

# For bare metal
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.1/deploy/static/provider/baremetal/deploy.yaml

Install Cert-Manager (for SSL)

kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.0/cert-manager.yaml

Create ClusterIssuer:

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: your-email@example.com
    privateKeySecretRef:
      name: letsencrypt-prod
    solvers:
      - http01:
          ingress:
            class: nginx

Step 5: Horizontal Pod Autoscaler

Create k8s/hpa.yaml:

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: api-hpa
  namespace: hyplab
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: api
  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
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: app-hpa
  namespace: hyplab
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: app
  minReplicas: 2
  maxReplicas: 5
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70

Step 6: ConfigMaps

Create k8s/configmap.yaml:

apiVersion: v1
kind: ConfigMap
metadata:
  name: hyplab-config
  namespace: hyplab
data:
  LOG_LEVEL: 'info'
  TELEMETRY_ENABLED: 'true'
  OTEL_SERVICE_NAME: 'api'
  OTEL_SERVICE_VERSION: '1.0.0'

Update deployments to use ConfigMap:

envFrom:
  - configMapRef:
      name: hyplab-config

Step 7: Deploy

# Apply all manifests
kubectl apply -f k8s/

# Check status
kubectl get pods -n hyplab
kubectl get services -n hyplab
kubectl get ingress -n hyplab

# View logs
kubectl logs -f deployment/api -n hyplab
kubectl logs -f deployment/app -n hyplab

Step 8: DNS Configuration

Configure DNS records:

A Record: yourdomain.com -> Ingress LoadBalancer IP
A Record: api.yourdomain.com -> Ingress LoadBalancer IP

Get LoadBalancer IP:

kubectl get ingress hyplab-ingress -n hyplab

Step 9: Monitoring

Prometheus ServiceMonitor

Create k8s/service-monitor.yaml:

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: api
  namespace: hyplab
spec:
  selector:
    matchLabels:
      app: api
  endpoints:
    - port: http
      path: /metrics
      interval: 30s

Pod Disruption Budget

Create k8s/pdb.yaml:

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: api-pdb
  namespace: hyplab
spec:
  minAvailable: 2
  selector:
    matchLabels:
      app: api
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: app-pdb
  namespace: hyplab
spec:
  minAvailable: 1
  selector:
    matchLabels:
      app: app

Step 10: Backup Strategy

MongoDB Backup Job

Create k8s/backup-job.yaml:

apiVersion: batch/v1
kind: CronJob
metadata:
  name: mongodb-backup
  namespace: hyplab
spec:
  schedule: '0 2 * * *' # Daily at 2 AM
  jobTemplate:
    spec:
      template:
        spec:
          containers:
            - name: backup
              image: mongo:7
              command:
                - mongodump
                - --uri=$(MONGODB_URL)
                - --out=/backup/$(date +%Y-%m-%d)
              env:
                - name: MONGODB_URL
                  valueFrom:
                    secretKeyRef:
                      name: hyplab-secrets
                      key: mongodb-url
              volumeMounts:
                - name: backup-storage
                  mountPath: /backup
          volumes:
            - name: backup-storage
              persistentVolumeClaim:
                claimName: backup-pvc
          restartPolicy: OnFailure

Troubleshooting

Check Pod Status

kubectl get pods -n hyplab
kubectl describe pod <pod-name> -n hyplab

View Logs

kubectl logs -f deployment/api -n hyplab
kubectl logs -f deployment/app -n hyplab

Debug Pod

kubectl exec -it <pod-name> -n hyplab -- /bin/sh

Check Ingress

kubectl describe ingress hyplab-ingress -n hyplab

Scaling

Manual Scaling

kubectl scale deployment api --replicas=5 -n hyplab

Auto Scaling

HPA will automatically scale based on CPU/memory usage (configured in Step 5).

Next Steps

On this page