this repo has no description
1# BSPDS Production Kubernetes Deployment
2> **Warning**: These instructions are untested and theoretical, written from the top of Lewis' head. They may contain errors or omissions. This warning will be removed once the guide has been verified.
3This guide covers deploying BSPDS on a production multi-node Kubernetes cluster with high availability, auto-scaling, and proper secrets management.
4## Architecture Overview
5```
6 ┌─────────────────────────────────────────────────┐
7 │ Kubernetes Cluster │
8 │ │
9 Internet ──────►│ Ingress Controller (nginx/traefik) │
10 │ │ │
11 │ ▼ │
12 │ ┌─────────────┐ │
13 │ │ Service │◄── HPA (2-10 replicas) │
14 │ └──────┬──────┘ │
15 │ │ │
16 │ ┌────┴────┐ │
17 │ ▼ ▼ │
18 │ ┌─────┐ ┌─────┐ │
19 │ │BSPDS│ │BSPDS│ ... (pods) │
20 │ └──┬──┘ └──┬──┘ │
21 │ │ │ │
22 │ ▼ ▼ │
23 │ ┌──────────────────────────────────────┐ │
24 │ │ PostgreSQL │ MinIO │ Valkey │ │
25 │ │ (HA/Operator)│ (StatefulSet) │ (Sentinel) │
26 │ └──────────────────────────────────────┘ │
27 └─────────────────────────────────────────────────┘
28```
29## Prerequisites
30- Kubernetes cluster (1.30+) with at least 3 nodes (1.34 is current stable)
31- `kubectl` configured to access your cluster
32- `helm` 3.x installed
33- Storage class that supports `ReadWriteOnce` (for databases)
34- Ingress controller installed (nginx-ingress or traefik)
35- cert-manager installed for TLS certificates
36### Quick Prerequisites Setup
37If you need to install prerequisites:
38```bash
39# Install nginx-ingress (chart v4.14.1 - December 2025)
40helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
41helm repo update
42helm install ingress-nginx ingress-nginx/ingress-nginx \
43 --namespace ingress-nginx --create-namespace \
44 --version 4.14.1
45# Install cert-manager (v1.19.2 - December 2025)
46helm repo add jetstack https://charts.jetstack.io
47helm repo update
48helm install cert-manager jetstack/cert-manager \
49 --namespace cert-manager --create-namespace \
50 --version v1.19.2 \
51 --set installCRDs=true
52```
53---
54## 1. Create Namespace
55```bash
56kubectl create namespace bspds
57kubectl config set-context --current --namespace=bspds
58```
59## 2. Create Secrets
60Generate secure passwords and secrets:
61```bash
62# Generate secrets
63DB_PASSWORD=$(openssl rand -base64 32)
64MINIO_PASSWORD=$(openssl rand -base64 32)
65JWT_SECRET=$(openssl rand -base64 48)
66DPOP_SECRET=$(openssl rand -base64 48)
67MASTER_KEY=$(openssl rand -base64 48)
68# Create Kubernetes secrets
69kubectl create secret generic bspds-db-credentials \
70 --from-literal=username=bspds \
71 --from-literal=password="$DB_PASSWORD"
72kubectl create secret generic bspds-minio-credentials \
73 --from-literal=root-user=minioadmin \
74 --from-literal=root-password="$MINIO_PASSWORD"
75kubectl create secret generic bspds-secrets \
76 --from-literal=jwt-secret="$JWT_SECRET" \
77 --from-literal=dpop-secret="$DPOP_SECRET" \
78 --from-literal=master-key="$MASTER_KEY"
79# Save secrets locally (KEEP SECURE!)
80echo "DB_PASSWORD=$DB_PASSWORD" > secrets.txt
81echo "MINIO_PASSWORD=$MINIO_PASSWORD" >> secrets.txt
82echo "JWT_SECRET=$JWT_SECRET" >> secrets.txt
83echo "DPOP_SECRET=$DPOP_SECRET" >> secrets.txt
84echo "MASTER_KEY=$MASTER_KEY" >> secrets.txt
85chmod 600 secrets.txt
86```
87## 3. Deploy PostgreSQL
88### Option A: CloudNativePG Operator (Recommended for HA)
89```bash
90# Install CloudNativePG operator (v1.28.0 - December 2025)
91kubectl apply --server-side -f \
92 https://raw.githubusercontent.com/cloudnative-pg/cloudnative-pg/release-1.28/releases/cnpg-1.28.0.yaml
93# Wait for operator
94kubectl wait --for=condition=available --timeout=120s \
95 deployment/cnpg-controller-manager -n cnpg-system
96```
97```bash
98cat <<EOF | kubectl apply -f -
99apiVersion: postgresql.cnpg.io/v1
100kind: Cluster
101metadata:
102 name: bspds-db
103 namespace: bspds
104spec:
105 instances: 3
106 postgresql:
107 parameters:
108 max_connections: "200"
109 shared_buffers: "256MB"
110 bootstrap:
111 initdb:
112 database: pds
113 owner: bspds
114 secret:
115 name: bspds-db-credentials
116 storage:
117 size: 20Gi
118 storageClass: standard # adjust for your cluster
119 resources:
120 requests:
121 memory: "512Mi"
122 cpu: "250m"
123 limits:
124 memory: "1Gi"
125 cpu: "1000m"
126 affinity:
127 podAntiAffinityType: required
128EOF
129```
130### Option B: Simple StatefulSet (Single Instance)
131```bash
132cat <<EOF | kubectl apply -f -
133apiVersion: v1
134kind: PersistentVolumeClaim
135metadata:
136 name: bspds-db-pvc
137 namespace: bspds
138spec:
139 accessModes:
140 - ReadWriteOnce
141 resources:
142 requests:
143 storage: 20Gi
144---
145apiVersion: apps/v1
146kind: StatefulSet
147metadata:
148 name: bspds-db
149 namespace: bspds
150spec:
151 serviceName: bspds-db
152 replicas: 1
153 selector:
154 matchLabels:
155 app: bspds-db
156 template:
157 metadata:
158 labels:
159 app: bspds-db
160 spec:
161 containers:
162 - name: postgres
163 image: postgres:18-alpine
164 ports:
165 - containerPort: 5432
166 env:
167 - name: POSTGRES_DB
168 value: pds
169 - name: POSTGRES_USER
170 valueFrom:
171 secretKeyRef:
172 name: bspds-db-credentials
173 key: username
174 - name: POSTGRES_PASSWORD
175 valueFrom:
176 secretKeyRef:
177 name: bspds-db-credentials
178 key: password
179 - name: PGDATA
180 value: /var/lib/postgresql/data/pgdata
181 volumeMounts:
182 - name: data
183 mountPath: /var/lib/postgresql/data
184 resources:
185 requests:
186 memory: "256Mi"
187 cpu: "100m"
188 limits:
189 memory: "1Gi"
190 cpu: "500m"
191 livenessProbe:
192 exec:
193 command: ["pg_isready", "-U", "bspds", "-d", "pds"]
194 initialDelaySeconds: 30
195 periodSeconds: 10
196 readinessProbe:
197 exec:
198 command: ["pg_isready", "-U", "bspds", "-d", "pds"]
199 initialDelaySeconds: 5
200 periodSeconds: 5
201 volumes:
202 - name: data
203 persistentVolumeClaim:
204 claimName: bspds-db-pvc
205---
206apiVersion: v1
207kind: Service
208metadata:
209 name: bspds-db-rw
210 namespace: bspds
211spec:
212 selector:
213 app: bspds-db
214 ports:
215 - port: 5432
216 targetPort: 5432
217EOF
218```
219## 4. Deploy MinIO
220```bash
221cat <<EOF | kubectl apply -f -
222apiVersion: v1
223kind: PersistentVolumeClaim
224metadata:
225 name: bspds-minio-pvc
226 namespace: bspds
227spec:
228 accessModes:
229 - ReadWriteOnce
230 resources:
231 requests:
232 storage: 50Gi
233---
234apiVersion: apps/v1
235kind: StatefulSet
236metadata:
237 name: bspds-minio
238 namespace: bspds
239spec:
240 serviceName: bspds-minio
241 replicas: 1
242 selector:
243 matchLabels:
244 app: bspds-minio
245 template:
246 metadata:
247 labels:
248 app: bspds-minio
249 spec:
250 containers:
251 - name: minio
252 image: minio/minio:RELEASE.2025-10-15T17-29-55Z
253 args:
254 - server
255 - /data
256 - --console-address
257 - ":9001"
258 ports:
259 - containerPort: 9000
260 name: api
261 - containerPort: 9001
262 name: console
263 env:
264 - name: MINIO_ROOT_USER
265 valueFrom:
266 secretKeyRef:
267 name: bspds-minio-credentials
268 key: root-user
269 - name: MINIO_ROOT_PASSWORD
270 valueFrom:
271 secretKeyRef:
272 name: bspds-minio-credentials
273 key: root-password
274 volumeMounts:
275 - name: data
276 mountPath: /data
277 resources:
278 requests:
279 memory: "256Mi"
280 cpu: "100m"
281 limits:
282 memory: "512Mi"
283 cpu: "500m"
284 livenessProbe:
285 httpGet:
286 path: /minio/health/live
287 port: 9000
288 initialDelaySeconds: 30
289 periodSeconds: 10
290 readinessProbe:
291 httpGet:
292 path: /minio/health/ready
293 port: 9000
294 initialDelaySeconds: 10
295 periodSeconds: 5
296 volumes:
297 - name: data
298 persistentVolumeClaim:
299 claimName: bspds-minio-pvc
300---
301apiVersion: v1
302kind: Service
303metadata:
304 name: bspds-minio
305 namespace: bspds
306spec:
307 selector:
308 app: bspds-minio
309 ports:
310 - port: 9000
311 targetPort: 9000
312 name: api
313 - port: 9001
314 targetPort: 9001
315 name: console
316EOF
317```
318### Initialize MinIO Bucket
319```bash
320kubectl run minio-init --rm -it --restart=Never \
321 --image=minio/mc:RELEASE.2025-07-16T15-35-03Z \
322 --env="MINIO_ROOT_USER=minioadmin" \
323 --env="MINIO_ROOT_PASSWORD=$(kubectl get secret bspds-minio-credentials -o jsonpath='{.data.root-password}' | base64 -d)" \
324 --command -- sh -c "
325 mc alias set local http://bspds-minio:9000 \$MINIO_ROOT_USER \$MINIO_ROOT_PASSWORD &&
326 mc mb --ignore-existing local/pds-blobs
327 "
328```
329## 5. Deploy Valkey
330```bash
331cat <<EOF | kubectl apply -f -
332apiVersion: v1
333kind: PersistentVolumeClaim
334metadata:
335 name: bspds-valkey-pvc
336 namespace: bspds
337spec:
338 accessModes:
339 - ReadWriteOnce
340 resources:
341 requests:
342 storage: 5Gi
343---
344apiVersion: apps/v1
345kind: StatefulSet
346metadata:
347 name: bspds-valkey
348 namespace: bspds
349spec:
350 serviceName: bspds-valkey
351 replicas: 1
352 selector:
353 matchLabels:
354 app: bspds-valkey
355 template:
356 metadata:
357 labels:
358 app: bspds-valkey
359 spec:
360 containers:
361 - name: valkey
362 image: valkey/valkey:9-alpine
363 args:
364 - valkey-server
365 - --appendonly
366 - "yes"
367 - --maxmemory
368 - "256mb"
369 - --maxmemory-policy
370 - allkeys-lru
371 ports:
372 - containerPort: 6379
373 volumeMounts:
374 - name: data
375 mountPath: /data
376 resources:
377 requests:
378 memory: "128Mi"
379 cpu: "50m"
380 limits:
381 memory: "300Mi"
382 cpu: "200m"
383 livenessProbe:
384 exec:
385 command: ["valkey-cli", "ping"]
386 initialDelaySeconds: 10
387 periodSeconds: 5
388 readinessProbe:
389 exec:
390 command: ["valkey-cli", "ping"]
391 initialDelaySeconds: 5
392 periodSeconds: 3
393 volumes:
394 - name: data
395 persistentVolumeClaim:
396 claimName: bspds-valkey-pvc
397---
398apiVersion: v1
399kind: Service
400metadata:
401 name: bspds-valkey
402 namespace: bspds
403spec:
404 selector:
405 app: bspds-valkey
406 ports:
407 - port: 6379
408 targetPort: 6379
409EOF
410```
411## 6. Build and Push BSPDS Image
412```bash
413# Build image
414cd /path/to/bspds
415docker build -t your-registry.com/bspds:latest .
416docker push your-registry.com/bspds:latest
417```
418If using a private registry, create an image pull secret:
419```bash
420kubectl create secret docker-registry regcred \
421 --docker-server=your-registry.com \
422 --docker-username=your-username \
423 --docker-password=your-password \
424 --docker-email=your-email
425```
426## 7. Run Database Migrations
427BSPDS runs migrations automatically on startup. However, if you want to run migrations separately (recommended for zero-downtime deployments), you can use a Job:
428```bash
429cat <<'EOF' | kubectl apply -f -
430apiVersion: batch/v1
431kind: Job
432metadata:
433 name: bspds-migrate
434 namespace: bspds
435spec:
436 ttlSecondsAfterFinished: 300
437 template:
438 spec:
439 restartPolicy: Never
440 containers:
441 - name: migrate
442 image: your-registry.com/bspds:latest
443 command: ["/usr/local/bin/bspds"]
444 args: ["--migrate-only"] # Add this flag to your app, or remove this Job
445 env:
446 - name: DB_PASSWORD
447 valueFrom:
448 secretKeyRef:
449 name: bspds-db-credentials
450 key: password
451 - name: DATABASE_URL
452 value: "postgres://bspds:$(DB_PASSWORD)@bspds-db-rw:5432/pds"
453EOF
454kubectl wait --for=condition=complete --timeout=120s job/bspds-migrate
455```
456> **Note**: If your BSPDS image doesn't have a `--migrate-only` flag, you can skip this step. The app will run migrations on first startup. Alternatively, build a separate migration image with `sqlx-cli` installed.
457## 8. Deploy BSPDS Application
458```bash
459cat <<EOF | kubectl apply -f -
460apiVersion: v1
461kind: ConfigMap
462metadata:
463 name: bspds-config
464 namespace: bspds
465data:
466 PDS_HOSTNAME: "pds.example.com"
467 SERVER_HOST: "0.0.0.0"
468 SERVER_PORT: "3000"
469 S3_ENDPOINT: "http://bspds-minio:9000"
470 AWS_REGION: "us-east-1"
471 S3_BUCKET: "pds-blobs"
472 VALKEY_URL: "redis://bspds-valkey:6379"
473 APPVIEW_URL: "https://api.bsky.app"
474 CRAWLERS: "https://bsky.network"
475 FRONTEND_DIR: "/app/frontend/dist"
476---
477apiVersion: apps/v1
478kind: Deployment
479metadata:
480 name: bspds
481 namespace: bspds
482spec:
483 replicas: 2
484 selector:
485 matchLabels:
486 app: bspds
487 template:
488 metadata:
489 labels:
490 app: bspds
491 spec:
492 imagePullSecrets:
493 - name: regcred # Remove if using public registry
494 affinity:
495 podAntiAffinity:
496 preferredDuringSchedulingIgnoredDuringExecution:
497 - weight: 100
498 podAffinityTerm:
499 labelSelector:
500 matchLabels:
501 app: bspds
502 topologyKey: kubernetes.io/hostname
503 containers:
504 - name: bspds
505 image: your-registry.com/bspds:latest
506 ports:
507 - containerPort: 3000
508 name: http
509 envFrom:
510 - configMapRef:
511 name: bspds-config
512 env:
513 - name: DB_PASSWORD
514 valueFrom:
515 secretKeyRef:
516 name: bspds-db-credentials
517 key: password
518 - name: DATABASE_URL
519 value: "postgres://bspds:$(DB_PASSWORD)@bspds-db-rw:5432/pds"
520 - name: AWS_ACCESS_KEY_ID
521 valueFrom:
522 secretKeyRef:
523 name: bspds-minio-credentials
524 key: root-user
525 - name: AWS_SECRET_ACCESS_KEY
526 valueFrom:
527 secretKeyRef:
528 name: bspds-minio-credentials
529 key: root-password
530 - name: JWT_SECRET
531 valueFrom:
532 secretKeyRef:
533 name: bspds-secrets
534 key: jwt-secret
535 - name: DPOP_SECRET
536 valueFrom:
537 secretKeyRef:
538 name: bspds-secrets
539 key: dpop-secret
540 - name: MASTER_KEY
541 valueFrom:
542 secretKeyRef:
543 name: bspds-secrets
544 key: master-key
545 resources:
546 requests:
547 memory: "256Mi"
548 cpu: "100m"
549 limits:
550 memory: "1Gi"
551 cpu: "1000m"
552 livenessProbe:
553 httpGet:
554 path: /xrpc/_health
555 port: 3000
556 initialDelaySeconds: 30
557 periodSeconds: 10
558 failureThreshold: 3
559 readinessProbe:
560 httpGet:
561 path: /xrpc/_health
562 port: 3000
563 initialDelaySeconds: 5
564 periodSeconds: 5
565 failureThreshold: 3
566 securityContext:
567 runAsNonRoot: true
568 runAsUser: 1000
569 allowPrivilegeEscalation: false
570---
571apiVersion: v1
572kind: Service
573metadata:
574 name: bspds
575 namespace: bspds
576spec:
577 selector:
578 app: bspds
579 ports:
580 - port: 80
581 targetPort: 3000
582 name: http
583EOF
584```
585## 9. Configure Horizontal Pod Autoscaler
586```bash
587cat <<EOF | kubectl apply -f -
588apiVersion: autoscaling/v2
589kind: HorizontalPodAutoscaler
590metadata:
591 name: bspds
592 namespace: bspds
593spec:
594 scaleTargetRef:
595 apiVersion: apps/v1
596 kind: Deployment
597 name: bspds
598 minReplicas: 2
599 maxReplicas: 10
600 metrics:
601 - type: Resource
602 resource:
603 name: cpu
604 target:
605 type: Utilization
606 averageUtilization: 70
607 - type: Resource
608 resource:
609 name: memory
610 target:
611 type: Utilization
612 averageUtilization: 80
613 behavior:
614 scaleDown:
615 stabilizationWindowSeconds: 300
616 policies:
617 - type: Pods
618 value: 1
619 periodSeconds: 60
620 scaleUp:
621 stabilizationWindowSeconds: 0
622 policies:
623 - type: Percent
624 value: 100
625 periodSeconds: 15
626 - type: Pods
627 value: 4
628 periodSeconds: 15
629 selectPolicy: Max
630EOF
631```
632## 10. Configure Pod Disruption Budget
633```bash
634cat <<EOF | kubectl apply -f -
635apiVersion: policy/v1
636kind: PodDisruptionBudget
637metadata:
638 name: bspds
639 namespace: bspds
640spec:
641 minAvailable: 1
642 selector:
643 matchLabels:
644 app: bspds
645EOF
646```
647## 11. Configure TLS with cert-manager
648```bash
649cat <<EOF | kubectl apply -f -
650apiVersion: cert-manager.io/v1
651kind: ClusterIssuer
652metadata:
653 name: letsencrypt-prod
654spec:
655 acme:
656 server: https://acme-v02.api.letsencrypt.org/directory
657 email: your-email@example.com
658 privateKeySecretRef:
659 name: letsencrypt-prod
660 solvers:
661 - http01:
662 ingress:
663 class: nginx
664EOF
665```
666## 12. Configure Ingress
667```bash
668cat <<EOF | kubectl apply -f -
669apiVersion: networking.k8s.io/v1
670kind: Ingress
671metadata:
672 name: bspds
673 namespace: bspds
674 annotations:
675 cert-manager.io/cluster-issuer: letsencrypt-prod
676 nginx.ingress.kubernetes.io/proxy-read-timeout: "86400"
677 nginx.ingress.kubernetes.io/proxy-send-timeout: "86400"
678 nginx.ingress.kubernetes.io/proxy-body-size: "100m"
679 nginx.ingress.kubernetes.io/proxy-buffering: "off"
680 nginx.ingress.kubernetes.io/websocket-services: "bspds"
681spec:
682 ingressClassName: nginx
683 tls:
684 - hosts:
685 - pds.example.com
686 secretName: bspds-tls
687 rules:
688 - host: pds.example.com
689 http:
690 paths:
691 - path: /
692 pathType: Prefix
693 backend:
694 service:
695 name: bspds
696 port:
697 number: 80
698EOF
699```
700## 13. Configure Network Policies (Optional but Recommended)
701```bash
702cat <<EOF | kubectl apply -f -
703apiVersion: networking.k8s.io/v1
704kind: NetworkPolicy
705metadata:
706 name: bspds-network-policy
707 namespace: bspds
708spec:
709 podSelector:
710 matchLabels:
711 app: bspds
712 policyTypes:
713 - Ingress
714 - Egress
715 ingress:
716 - from:
717 - namespaceSelector:
718 matchLabels:
719 kubernetes.io/metadata.name: ingress-nginx
720 ports:
721 - protocol: TCP
722 port: 3000
723 egress:
724 - to:
725 - podSelector:
726 matchLabels:
727 app: bspds-db
728 ports:
729 - protocol: TCP
730 port: 5432
731 - to:
732 - podSelector:
733 matchLabels:
734 app: bspds-minio
735 ports:
736 - protocol: TCP
737 port: 9000
738 - to:
739 - podSelector:
740 matchLabels:
741 app: bspds-valkey
742 ports:
743 - protocol: TCP
744 port: 6379
745 - to: # Allow DNS
746 - namespaceSelector: {}
747 podSelector:
748 matchLabels:
749 k8s-app: kube-dns
750 ports:
751 - protocol: UDP
752 port: 53
753 - to: # Allow external HTTPS (for federation)
754 - ipBlock:
755 cidr: 0.0.0.0/0
756 ports:
757 - protocol: TCP
758 port: 443
759EOF
760```
761## 14. Deploy Prometheus Monitoring (Optional)
762```bash
763cat <<EOF | kubectl apply -f -
764apiVersion: monitoring.coreos.com/v1
765kind: ServiceMonitor
766metadata:
767 name: bspds
768 namespace: bspds
769 labels:
770 release: prometheus
771spec:
772 selector:
773 matchLabels:
774 app: bspds
775 endpoints:
776 - port: http
777 path: /metrics
778 interval: 30s
779EOF
780```
781---
782## Verification
783```bash
784# Check all pods are running
785kubectl get pods -n bspds
786# Check services
787kubectl get svc -n bspds
788# Check ingress
789kubectl get ingress -n bspds
790# Check certificate
791kubectl get certificate -n bspds
792# Test health endpoint
793curl -s https://pds.example.com/xrpc/_health | jq
794# Test DID endpoint
795curl -s https://pds.example.com/.well-known/atproto-did
796```
797---
798## Maintenance
799### View Logs
800```bash
801# All BSPDS pods
802kubectl logs -l app=bspds -n bspds -f
803# Specific pod
804kubectl logs -f deployment/bspds -n bspds
805```
806### Scale Manually
807```bash
808kubectl scale deployment bspds --replicas=5 -n bspds
809```
810### Update BSPDS
811```bash
812# Build and push new image
813docker build -t your-registry.com/bspds:v1.2.3 .
814docker push your-registry.com/bspds:v1.2.3
815# Update deployment
816kubectl set image deployment/bspds bspds=your-registry.com/bspds:v1.2.3 -n bspds
817# Watch rollout
818kubectl rollout status deployment/bspds -n bspds
819```
820### Backup Database
821```bash
822# For CloudNativePG
823kubectl cnpg backup bspds-db -n bspds
824# For StatefulSet
825kubectl exec -it bspds-db-0 -n bspds -- pg_dump -U bspds pds > backup-$(date +%Y%m%d).sql
826```
827### Run Migrations
828If you have a migration Job defined, you can re-run it:
829```bash
830# Delete old job first (if exists)
831kubectl delete job bspds-migrate -n bspds --ignore-not-found
832# Re-apply the migration job from step 7
833# Or simply restart the deployment - BSPDS runs migrations on startup
834kubectl rollout restart deployment/bspds -n bspds
835```
836---
837## Troubleshooting
838### Pod Won't Start
839```bash
840kubectl describe pod -l app=bspds -n bspds
841kubectl logs -l app=bspds -n bspds --previous
842```
843### Database Connection Issues
844```bash
845# Test connectivity from a debug pod
846kubectl run debug --rm -it --restart=Never --image=postgres:18-alpine -- \
847 psql "postgres://bspds:PASSWORD@bspds-db-rw:5432/pds" -c "SELECT 1"
848```
849### Certificate Issues
850```bash
851kubectl describe certificate bspds-tls -n bspds
852kubectl describe certificaterequest -n bspds
853kubectl logs -l app.kubernetes.io/name=cert-manager -n cert-manager
854```
855### View Resource Usage
856```bash
857kubectl top pods -n bspds
858kubectl top nodes
859```