---
title: "Kubernetes Installation"
description: "Deploy TracerTM on Kubernetes with Helm charts or raw manifests"
---

# Kubernetes Installation

Deploy TracerTM on Kubernetes for production-grade requirements management with high availability, scalability, and resilience.

## Overview

This guide covers deploying TracerTM on Kubernetes using either:
- **Helm Charts** (recommended): Simplified deployment and upgrades
- **Raw Manifests**: Fine-grained control over resources

## Prerequisites

### Required Tools

Ensure you have the following tools installed:

```bash
# kubectl (v1.25+)
kubectl version --client

# Helm (v3.10+) - for Helm deployment
helm version

# Optional: k9s for cluster management
k9s version
```

### Cluster Requirements

- Kubernetes cluster v1.25 or higher
- At least 2 worker nodes (for high availability)
- Storage class for persistent volumes
- Ingress controller (nginx, traefik, or similar)

### Minimum Resource Requirements

- **CPU**: 2 cores per pod
- **Memory**: 4Gi per pod
- **Storage**: 20Gi persistent volume for database

### Verify Cluster Access

```bash
# Check cluster connection
kubectl cluster-info

# Verify you have admin permissions
kubectl auth can-i create deployments --all-namespaces
```

## Namespace Setup

Create a dedicated namespace for TracerTM:

```bash
# Create namespace
kubectl create namespace tracertm

# Set as default context (optional)
kubectl config set-context --current --namespace=tracertm
```

Or using a manifest:

```yaml
# namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: tracertm
  labels:
    name: tracertm
    environment: production
```

```bash
kubectl apply -f namespace.yaml
```

## Deploying with Helm Charts

### Add Helm Repository

```bash
# Add TracerTM Helm repository
helm repo add tracertm https://charts.tracertm.com

# Update repository
helm repo update

# Search for available charts
helm search repo tracertm
```

### Create Values File

Create a `values.yaml` file to customize your deployment:

```yaml
# values.yaml
replicaCount: 2

image:
  repository: tracertm/tracertm
  tag: "latest"
  pullPolicy: IfNotPresent

service:
  type: ClusterIP
  port: 8000
  annotations: {}

ingress:
  enabled: true
  className: nginx
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
  hosts:
    - host: tracertm.example.com
      paths:
        - path: /
          pathType: Prefix
  tls:
    - secretName: tracertm-tls
      hosts:
        - tracertm.example.com

persistence:
  enabled: true
  storageClass: standard
  accessMode: ReadWriteOnce
  size: 20Gi

database:
  type: postgresql
  host: postgres.tracertm.svc.cluster.local
  port: 5432
  name: tracertm
  user: tracertm
  # Reference to secret containing password
  passwordSecret:
    name: tracertm-db-credentials
    key: password

redis:
  enabled: true
  host: redis.tracertm.svc.cluster.local
  port: 6379

resources:
  limits:
    cpu: 2000m
    memory: 4Gi
  requests:
    cpu: 1000m
    memory: 2Gi

autoscaling:
  enabled: true
  minReplicas: 2
  maxReplicas: 10
  targetCPUUtilizationPercentage: 70
  targetMemoryUtilizationPercentage: 80

livenessProbe:
  httpGet:
    path: /health
    port: 8000
  initialDelaySeconds: 30
  periodSeconds: 10
  timeoutSeconds: 5
  failureThreshold: 3

readinessProbe:
  httpGet:
    path: /ready
    port: 8000
  initialDelaySeconds: 20
  periodSeconds: 5
  timeoutSeconds: 3
  failureThreshold: 3

env:
  - name: ENVIRONMENT
    value: production
  - name: LOG_LEVEL
    value: info

securityContext:
  runAsNonRoot: true
  runAsUser: 1000
  fsGroup: 1000
  capabilities:
    drop:
      - ALL

podSecurityContext:
  fsGroup: 2000
```

### Install with Helm

```bash
# Install TracerTM
helm install tracertm tracertm/tracertm \
  --namespace tracertm \
  --values values.yaml \
  --create-namespace

# Check installation status
helm status tracertm -n tracertm

# View deployed resources
kubectl get all -n tracertm
```

### Upgrade with Helm

```bash
# Upgrade to new version
helm upgrade tracertm tracertm/tracertm \
  --namespace tracertm \
  --values values.yaml \
  --reuse-values

# Rollback if needed
helm rollback tracertm -n tracertm
```

## Deploying with Raw Manifests

### ConfigMap Configuration

```yaml
# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: tracertm-config
  namespace: tracertm
data:
  DATABASE_HOST: "postgres.tracertm.svc.cluster.local"
  DATABASE_PORT: "5432"
  DATABASE_NAME: "tracertm"
  REDIS_HOST: "redis.tracertm.svc.cluster.local"
  REDIS_PORT: "6379"
  LOG_LEVEL: "info"
  ENVIRONMENT: "production"
  API_WORKERS: "4"
```

### Secrets Configuration

```bash
# Create secrets (never commit these!)
kubectl create secret generic tracertm-secrets \
  --namespace tracertm \
  --from-literal=database-password='your-secure-password' \
  --from-literal=secret-key='your-secret-key' \
  --from-literal=jwt-secret='your-jwt-secret' \
  --dry-run=client -o yaml | kubectl apply -f -
```

Or using a manifest:

```yaml
# secrets.yaml (DO NOT commit to git)
apiVersion: v1
kind: Secret
metadata:
  name: tracertm-secrets
  namespace: tracertm
type: Opaque
stringData:
  database-password: "your-secure-password"
  secret-key: "your-secret-key"
  jwt-secret: "your-jwt-secret"
```

### Persistent Volume Setup

```yaml
# pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: tracertm-data
  namespace: tracertm
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: standard
  resources:
    requests:
      storage: 20Gi
```

### Deployment Manifest

```yaml
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: tracertm
  namespace: tracertm
  labels:
    app: tracertm
spec:
  replicas: 2
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  selector:
    matchLabels:
      app: tracertm
  template:
    metadata:
      labels:
        app: tracertm
        version: v1.0.0
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "8000"
        prometheus.io/path: "/metrics"
    spec:
      serviceAccountName: tracertm
      securityContext:
        fsGroup: 1000
        runAsNonRoot: true
        runAsUser: 1000
      containers:
      - name: tracertm
        image: tracertm/tracertm:latest
        imagePullPolicy: IfNotPresent
        ports:
        - name: http
          containerPort: 8000
          protocol: TCP
        envFrom:
        - configMapRef:
            name: tracertm-config
        env:
        - name: DATABASE_PASSWORD
          valueFrom:
            secretKeyRef:
              name: tracertm-secrets
              key: database-password
        - name: SECRET_KEY
          valueFrom:
            secretKeyRef:
              name: tracertm-secrets
              key: secret-key
        - name: JWT_SECRET
          valueFrom:
            secretKeyRef:
              name: tracertm-secrets
              key: jwt-secret
        resources:
          limits:
            cpu: 2000m
            memory: 4Gi
          requests:
            cpu: 1000m
            memory: 2Gi
        livenessProbe:
          httpGet:
            path: /health
            port: 8000
            scheme: HTTP
          initialDelaySeconds: 30
          periodSeconds: 10
          timeoutSeconds: 5
          failureThreshold: 3
          successThreshold: 1
        readinessProbe:
          httpGet:
            path: /ready
            port: 8000
            scheme: HTTP
          initialDelaySeconds: 20
          periodSeconds: 5
          timeoutSeconds: 3
          failureThreshold: 3
          successThreshold: 1
        startupProbe:
          httpGet:
            path: /health
            port: 8000
          initialDelaySeconds: 0
          periodSeconds: 10
          timeoutSeconds: 3
          failureThreshold: 30
        volumeMounts:
        - name: data
          mountPath: /app/data
        - name: tmp
          mountPath: /tmp
        securityContext:
          allowPrivilegeEscalation: false
          readOnlyRootFilesystem: true
          capabilities:
            drop:
            - ALL
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: tracertm-data
      - name: tmp
        emptyDir: {}
```

### Service Configuration

```yaml
# service.yaml
apiVersion: v1
kind: Service
metadata:
  name: tracertm
  namespace: tracertm
  labels:
    app: tracertm
spec:
  type: ClusterIP
  ports:
  - port: 8000
    targetPort: http
    protocol: TCP
    name: http
  selector:
    app: tracertm
```

### Ingress Configuration

```yaml
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: tracertm
  namespace: tracertm
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/proxy-body-size: "50m"
    nginx.ingress.kubernetes.io/rate-limit: "100"
spec:
  ingressClassName: nginx
  tls:
  - hosts:
    - tracertm.example.com
    secretName: tracertm-tls
  rules:
  - host: tracertm.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: tracertm
            port:
              number: 8000
```

### ServiceAccount and RBAC

```yaml
# rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: tracertm
  namespace: tracertm
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: tracertm
  namespace: tracertm
rules:
- apiGroups: [""]
  resources: ["configmaps", "secrets"]
  verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: tracertm
  namespace: tracertm
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: tracertm
subjects:
- kind: ServiceAccount
  name: tracertm
  namespace: tracertm
```

### Deploy All Manifests

```bash
# Apply all manifests in order
kubectl apply -f namespace.yaml
kubectl apply -f configmap.yaml
kubectl apply -f secrets.yaml
kubectl apply -f pvc.yaml
kubectl apply -f rbac.yaml
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
kubectl apply -f ingress.yaml

# Verify deployment
kubectl get all -n tracertm
kubectl get pvc -n tracertm
kubectl get ingress -n tracertm
```

## Scaling Considerations

### Horizontal Pod Autoscaling

```yaml
# hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: tracertm
  namespace: tracertm
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: tracertm
  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
  behavior:
    scaleDown:
      stabilizationWindowSeconds: 300
      policies:
      - type: Percent
        value: 50
        periodSeconds: 60
    scaleUp:
      stabilizationWindowSeconds: 0
      policies:
      - type: Percent
        value: 100
        periodSeconds: 30
      - type: Pods
        value: 2
        periodSeconds: 60
      selectPolicy: Max
```

```bash
kubectl apply -f hpa.yaml
kubectl get hpa -n tracertm
```

### Pod Disruption Budget

```yaml
# pdb.yaml
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: tracertm
  namespace: tracertm
spec:
  minAvailable: 1
  selector:
    matchLabels:
      app: tracertm
```

## Monitoring Integration

### Prometheus ServiceMonitor

```yaml
# servicemonitor.yaml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: tracertm
  namespace: tracertm
  labels:
    app: tracertm
spec:
  selector:
    matchLabels:
      app: tracertm
  endpoints:
  - port: http
    path: /metrics
    interval: 30s
    scrapeTimeout: 10s
```

### Grafana Dashboard

```bash
# Import TracerTM dashboard
kubectl create configmap tracertm-dashboard \
  --namespace monitoring \
  --from-file=dashboard.json \
  --dry-run=client -o yaml | kubectl apply -f -
```

### Logging with Fluentd

```yaml
# Add logging annotations to deployment
metadata:
  annotations:
    fluentd.io/parser: json
    fluentd.io/exclude: "false"
```

## Troubleshooting

### Check Pod Status

```bash
# View pod status
kubectl get pods -n tracertm

# Describe pod for events
kubectl describe pod <pod-name> -n tracertm

# View pod logs
kubectl logs <pod-name> -n tracertm

# Follow logs in real-time
kubectl logs -f <pod-name> -n tracertm

# View previous container logs (if crashed)
kubectl logs <pod-name> -n tracertm --previous
```

### Common Issues

**Pods in CrashLoopBackOff:**
```bash
# Check logs
kubectl logs <pod-name> -n tracertm --previous

# Check resource constraints
kubectl describe pod <pod-name> -n tracertm | grep -A 5 Resources

# Verify database connectivity
kubectl exec -it <pod-name> -n tracertm -- curl postgres:5432
```

**Persistent Volume Issues:**
```bash
# Check PVC status
kubectl get pvc -n tracertm

# Describe PVC for errors
kubectl describe pvc tracertm-data -n tracertm

# Check storage class
kubectl get storageclass
```

**Service Not Accessible:**
```bash
# Check service endpoints
kubectl get endpoints tracertm -n tracertm

# Test service from within cluster
kubectl run -it --rm debug --image=busybox --restart=Never -- wget -O- http://tracertm.tracertm.svc.cluster.local:8000/health

# Check ingress
kubectl describe ingress tracertm -n tracertm
```

**Database Connection Errors:**
```bash
# Verify secret exists
kubectl get secret tracertm-secrets -n tracertm

# Check configmap
kubectl get configmap tracertm-config -n tracertm -o yaml

# Test database connection
kubectl run -it --rm psql --image=postgres:15 --restart=Never -- \
  psql -h postgres.tracertm.svc.cluster.local -U tracertm -d tracertm
```

### Debug Mode

```bash
# Enable debug logging
kubectl set env deployment/tracertm LOG_LEVEL=debug -n tracertm

# Exec into running pod
kubectl exec -it <pod-name> -n tracertm -- /bin/sh

# Port-forward for local testing
kubectl port-forward svc/tracertm 8000:8000 -n tracertm
```

## Upgrading TracerTM

### Helm Upgrade

```bash
# Update chart repository
helm repo update

# Check new versions
helm search repo tracertm --versions

# Upgrade to specific version
helm upgrade tracertm tracertm/tracertm \
  --namespace tracertm \
  --version 2.0.0 \
  --values values.yaml \
  --reuse-values

# Monitor rollout
kubectl rollout status deployment/tracertm -n tracertm
```

### Manual Upgrade

```bash
# Update image tag
kubectl set image deployment/tracertm \
  tracertm=tracertm/tracertm:2.0.0 \
  -n tracertm

# Watch rollout progress
kubectl rollout status deployment/tracertm -n tracertm

# Rollback if issues occur
kubectl rollout undo deployment/tracertm -n tracertm
```

### Database Migrations

```bash
# Run migrations as a Job
kubectl apply -f - <<EOF
apiVersion: batch/v1
kind: Job
metadata:
  name: tracertm-migrate
  namespace: tracertm
spec:
  template:
    spec:
      containers:
      - name: migrate
        image: tracertm/tracertm:2.0.0
        command: ["python", "-m", "tracertm.cli", "db", "migrate"]
        envFrom:
        - configMapRef:
            name: tracertm-config
        env:
        - name: DATABASE_PASSWORD
          valueFrom:
            secretKeyRef:
              name: tracertm-secrets
              key: database-password
      restartPolicy: OnFailure
  backoffLimit: 3
EOF

# Monitor migration job
kubectl logs -f job/tracertm-migrate -n tracertm
```

### Zero-Downtime Upgrades

```yaml
# deployment.yaml - ensure these settings
spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  minReadySeconds: 10
```

## Backup and Disaster Recovery

### Backup Strategy

```bash
# Backup database using CronJob
kubectl apply -f - <<EOF
apiVersion: batch/v1
kind: CronJob
metadata:
  name: tracertm-backup
  namespace: tracertm
spec:
  schedule: "0 2 * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: backup
            image: postgres:15
            command:
            - /bin/sh
            - -c
            - pg_dump -h postgres -U tracertm tracertm | gzip > /backup/tracertm-\$(date +%Y%m%d-%H%M%S).sql.gz
            env:
            - name: PGPASSWORD
              valueFrom:
                secretKeyRef:
                  name: tracertm-secrets
                  key: database-password
            volumeMounts:
            - name: backup
              mountPath: /backup
          volumes:
          - name: backup
            persistentVolumeClaim:
              claimName: tracertm-backup
          restartPolicy: OnFailure
EOF
```

## Security Best Practices

1. **Use secrets for sensitive data**: Never hardcode passwords
2. **Enable RBAC**: Limit service account permissions
3. **Network policies**: Restrict pod-to-pod communication
4. **Pod security standards**: Use restricted security context
5. **Regular updates**: Keep images and charts updated
6. **TLS everywhere**: Use cert-manager for automatic certificates

## Performance Tuning

### Resource Optimization

```yaml
# Set appropriate resource limits
resources:
  requests:
    cpu: 1000m      # Guaranteed CPU
    memory: 2Gi     # Guaranteed memory
  limits:
    cpu: 2000m      # Maximum CPU (throttled if exceeded)
    memory: 4Gi     # Maximum memory (OOMKilled if exceeded)
```

### Connection Pooling

```yaml
# Add to configmap
API_WORKERS: "4"
DB_POOL_SIZE: "20"
DB_MAX_OVERFLOW: "10"
```

## Next Steps

- [Configuration Guide](/docs/getting-started/configuration)
- [Database Setup](/docs/getting-started/installation/database)
- [Monitoring and Observability](/docs/development/architecture/observability)
- [Security Configuration](/docs/deployment/security)

## Additional Resources

- [Kubernetes Documentation](https://kubernetes.io/docs/)
- [Helm Documentation](https://helm.sh/docs/)
- [TracerTM Helm Chart Repository](https://github.com/tracertm/helm-charts)
