Skip to content

Kubernetes Deployment

Last Updated: 2025-01-22

Deploy AccessALI to Kubernetes for production-grade container orchestration, scaling, and high availability.


Overview

Kubernetes provides:

  • Container orchestration - Automated deployment and scaling
  • High availability - Self-healing and load balancing
  • Service discovery - Built-in DNS and networking
  • Rolling updates - Zero-downtime deployments
  • Resource management - CPU and memory limits

Architecture

graph TB
    Ingress[Ingress<br/>NGINX] --> Service[Service<br/>accessali-app]
    Service --> Pod1[Pod 1<br/>Next.js]
    Service --> Pod2[Pod 2<br/>Next.js]
    Service --> Pod3[Pod 3<br/>Next.js]

    Pod1 --> PGService[Service<br/>PostgreSQL]
    Pod2 --> PGService
    Pod3 --> PGService

    PGService --> PGPod[Pod<br/>PostgreSQL]

    Pod1 --> RedisService[Service<br/>Redis]
    Pod2 --> RedisService
    Pod3 --> RedisService

    RedisService --> RedisPod[Pod<br/>Redis]

Manifests

Namespace

# k8s/namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: accessali

ConfigMap

# k8s/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: accessali-config
  namespace: accessali
data:
  NODE_ENV: "production"
  USE_MOCK_SAP: "false"

Secrets

# k8s/secrets.yaml
apiVersion: v1
kind: Secret
metadata:
  name: accessali-secrets
  namespace: accessali
type: Opaque
stringData:
  DATABASE_URL: postgresql://user:password@postgres:5432/accessali
  NEXTAUTH_SECRET: your-production-secret
  JWT_SECRET: your-jwt-secret

PostgreSQL Deployment

# k8s/postgres-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: postgres
  namespace: accessali
spec:
  replicas: 1
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
      - name: postgres
        image: postgres:16-alpine
        ports:
        - containerPort: 5432
        env:
        - name: POSTGRES_USER
          value: accessali
        - name: POSTGRES_PASSWORD
          valueFrom:
            secretKeyRef:
              name: accessali-secrets
              key: POSTGRES_PASSWORD
        - name: POSTGRES_DB
          value: accessali
        volumeMounts:
        - name: postgres-data
          mountPath: /var/lib/postgresql/data
      volumes:
      - name: postgres-data
        persistentVolumeClaim:
          claimName: postgres-pvc
---
apiVersion: v1
kind: Service
metadata:
  name: postgres
  namespace: accessali
spec:
  selector:
    app: postgres
  ports:
  - port: 5432
    targetPort: 5432

Application Deployment

# k8s/app-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: accessali-app
  namespace: accessali
spec:
  replicas: 3
  selector:
    matchLabels:
      app: accessali-app
  template:
    metadata:
      labels:
        app: accessali-app
    spec:
      containers:
      - name: app
        image: accessali:latest
        ports:
        - containerPort: 3000
        env:
        - name: DATABASE_URL
          valueFrom:
            secretKeyRef:
              name: accessali-secrets
              key: DATABASE_URL
        - name: NEXTAUTH_SECRET
          valueFrom:
            secretKeyRef:
              name: accessali-secrets
              key: NEXTAUTH_SECRET
        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
---
apiVersion: v1
kind: Service
metadata:
  name: accessali-app
  namespace: accessali
spec:
  selector:
    app: accessali-app
  ports:
  - port: 80
    targetPort: 3000
  type: LoadBalancer

Ingress

# k8s/ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: accessali-ingress
  namespace: accessali
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  ingressClassName: nginx
  tls:
  - hosts:
    - accessali.example.com
    secretName: accessali-tls
  rules:
  - host: accessali.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: accessali-app
            port:
              number: 80

Deployment

1. Create Namespace

kubectl apply -f k8s/namespace.yaml

2. Create Secrets

# Create secret from file
kubectl create secret generic accessali-secrets \
  --from-env-file=.env.production \
  -n accessali

# Or apply manifest
kubectl apply -f k8s/secrets.yaml

3. Deploy Services

# Deploy PostgreSQL
kubectl apply -f k8s/postgres-deployment.yaml

# Deploy application
kubectl apply -f k8s/app-deployment.yaml

# Deploy ingress
kubectl apply -f k8s/ingress.yaml

4. Verify Deployment

# Check pods
kubectl get pods -n accessali

# Check services
kubectl get svc -n accessali

# Check logs
kubectl logs -f -l app=accessali-app -n accessali

Scaling

Manual Scaling

# Scale to 5 replicas
kubectl scale deployment accessali-app --replicas=5 -n accessali

Horizontal Pod Autoscaling

# k8s/hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: accessali-app-hpa
  namespace: accessali
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: accessali-app
  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
kubectl apply -f k8s/hpa.yaml

Updates

Rolling Update

# Update image
kubectl set image deployment/accessali-app \
  app=accessali:v2 \
  -n accessali

# Check rollout status
kubectl rollout status deployment/accessali-app -n accessali

Rollback

# Rollback to previous version
kubectl rollout undo deployment/accessali-app -n accessali

# Rollback to specific revision
kubectl rollout undo deployment/accessali-app --to-revision=2 -n accessali

Monitoring

# View logs
kubectl logs -f deployment/accessali-app -n accessali

# Get pod details
kubectl describe pod <pod-name> -n accessali

# Execute commands in pod
kubectl exec -it <pod-name> -n accessali -- sh

# Port forward for debugging
kubectl port-forward deployment/accessali-app 3000:3000 -n accessali

Best Practices

  • Use namespaces for environment isolation
  • Set resource limits on all containers
  • Implement health checks (liveness/readiness probes)
  • Use ConfigMaps for configuration
  • Store secrets in Kubernetes Secrets or external vault
  • Enable horizontal pod autoscaling
  • Use persistent volumes for stateful services
  • Implement network policies for security
  • Monitor with Prometheus and Grafana
  • Use RBAC for access control


Next Steps

  1. Set up CI/CD pipeline for automated deployments
  2. Configure monitoring and alerting
  3. Implement backup strategy
  4. Review Production Checklist