> For the complete documentation index, see [llms.txt](https://docs.qpoint.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.qpoint.io/getting-started/qscan/installation/kubernetes.md).

# Kubernetes

## CPU Deployment

Create a Kubernetes Secret for your registration token and any S3 credentials:

```bash
kubectl create secret generic qscan-secrets \
  --from-literal=REGISTRATION_TOKEN=your-registration-token \
  --from-literal=AWS_ACCESS_KEY_ID=your-access-key \
  --from-literal=AWS_SECRET_ACCESS_KEY=your-secret-key
```

Deploy QScan using the following manifest:

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: qscan
  labels:
    app: qscan
spec:
  replicas: 1
  selector:
    matchLabels:
      app: qscan
  template:
    metadata:
      labels:
        app: qscan
    spec:
      containers:
        - name: qscan
          image: us-docker.pkg.dev/qpoint-edge/public/qscan:latest
          env:
            - name: REGISTRATION_TOKEN
              valueFrom:
                secretKeyRef:
                  name: qscan-secrets
                  key: REGISTRATION_TOKEN
            - name: AWS_ACCESS_KEY_ID
              valueFrom:
                secretKeyRef:
                  name: qscan-secrets
                  key: AWS_ACCESS_KEY_ID
            - name: AWS_SECRET_ACCESS_KEY
              valueFrom:
                secretKeyRef:
                  name: qscan-secrets
                  key: AWS_SECRET_ACCESS_KEY
            - name: S3_ENDPOINT_URL
              value: "http://your-s3-endpoint:3900"
            - name: S3_BUCKET_NAME
              value: "qpoint"
            - name: S3_REGION_NAME
              value: "us-east-1"
            - name: NUM_POLLERS
              value: "2"
            - name: NUM_SCANNERS
              value: "2"
            - name: LOG_LEVEL
              value: "info"
            - name: METRICS_PORT
              value: "8080"
          ports:
            - containerPort: 8080
              name: metrics
          resources:
            requests:
              cpu: "2"
              memory: "12Gi"
            limits:
              cpu: "6"
              memory: "24Gi"
          livenessProbe:
            httpGet:
              path: /
              port: 8080
            initialDelaySeconds: 5
            periodSeconds: 10
          startupProbe:
            httpGet:
              path: /
              port: 8080
            initialDelaySeconds: 5
            periodSeconds: 30
            failureThreshold: 5
```

## GPU Deployment

For GPU-accelerated scanning, schedule the pod on a node with an NVIDIA GPU and adjust the resource limits:

```yaml
          resources:
            requests:
              cpu: "4"
              memory: "16Gi"
            limits:
              cpu: "4"
              memory: "16Gi"
              nvidia.com/gpu: "1"
```

{% hint style="info" %}
GPU nodes must have the NVIDIA device plugin installed. On managed Kubernetes services, this typically means using a GPU-enabled node pool (e.g., GKE GPU node pools, EKS with `p3` or `g5` instances, AKS with NC-series VMs).
{% endhint %}

## Scaling

To scale horizontally, increase the number of replicas. Each replica operates independently, polling Pulse for scan jobs:

```bash
kubectl scale deployment qscan --replicas=3
```

You can also adjust `NUM_POLLERS` and `NUM_SCANNERS` per replica to control concurrency within each instance. See the [Configuration](/getting-started/qscan/configuration.md) guide for details.
