# Kubernetes Deployment

Guide for deploying NCN Network on Kubernetes for production scale.

***

## Prerequisites

* Kubernetes cluster (1.25+)
* kubectl configured
* Helm 3.x installed
* Container registry access

***

## Architecture on Kubernetes

```
┌─────────────────────────────────────────────────────────────────────────────┐
│                         Kubernetes Cluster                                   │
│                                                                             │
│   ┌───────────────────────────────────────────────────────────────────┐     │
│   │                         Ingress                                    │     │
│   │                    (nginx/traefik)                                │     │
│   └───────────────────────────────┬───────────────────────────────────┘     │
│                                   │                                         │
│   ┌───────────────────────────────▼───────────────────────────────────┐     │
│   │                     Gateway Service                                │     │
│   │   ┌─────────────┐   ┌─────────────┐   ┌─────────────┐            │     │
│   │   │ Gateway Pod │   │ Gateway Pod │   │ Gateway Pod │            │     │
│   │   │  (replica)  │   │  (replica)  │   │  (replica)  │            │     │
│   │   └─────────────┘   └─────────────┘   └─────────────┘            │     │
│   └───────────────────────────────────────────────────────────────────┘     │
│                                                                             │
│   ┌───────────────────────────────────────────────────────────────────┐     │
│   │                    Registry StatefulSet                            │     │
│   │   ┌─────────────┐   ┌─────────────┐   ┌─────────────┐            │     │
│   │   │Registry Pod │   │Registry Pod │   │Registry Pod │            │     │
│   │   │    + PVC    │   │    + PVC    │   │    + PVC    │            │     │
│   │   └─────────────┘   └─────────────┘   └─────────────┘            │     │
│   └───────────────────────────────────────────────────────────────────┘     │
│                                                                             │
│   ┌───────────────────────────────────────────────────────────────────┐     │
│   │                     Compute DaemonSet/Deployment                   │     │
│   │   ┌─────────────┐   ┌─────────────┐   ┌─────────────┐            │     │
│   │   │Compute Pod  │   │Compute Pod  │   │Compute Pod  │            │     │
│   │   │   (GPU)     │   │   (GPU)     │   │   (CPU)     │            │     │
│   │   └─────────────┘   └─────────────┘   └─────────────┘            │     │
│   └───────────────────────────────────────────────────────────────────┘     │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘
```

***

## Namespace Setup

```yaml
# namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: ncn-network
  labels:
    name: ncn-network
```

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

***

## Secrets

```yaml
# secrets.yaml
apiVersion: v1
kind: Secret
metadata:
  name: ncn-secrets
  namespace: ncn-network
type: Opaque
stringData:
  gateway-private-key: "0x..."
  compute-private-key: "0x..."
  validator-private-key: "0x..."
```

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

***

## ConfigMaps

```yaml
# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: ncn-config
  namespace: ncn-network
data:
  RPC_URL: "https://testnet-rpc-1.forknet.io"
  CHAIN_ID: "828"
  CONTRACT_ADDRESS: "0x4361115359E5C0a25c9b2f8Bb71184F010b768ea"
  RUST_LOG: "info"
  REQUIRE_PAYMENT: "true"
  SANDBOX_MODE: "strict"
```

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

***

## P2P Registry StatefulSet

```yaml
# registry-statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: ncn-registry
  namespace: ncn-network
spec:
  serviceName: ncn-registry
  replicas: 3
  selector:
    matchLabels:
      app: ncn-registry
  template:
    metadata:
      labels:
        app: ncn-registry
    spec:
      containers:
      - name: registry
        image: your-registry/ncn-registry:latest
        ports:
        - containerPort: 50050
          name: grpc
        - containerPort: 8828
          name: p2p
        env:
        - name: GRPC_LISTEN_ADDR
          value: "0.0.0.0:50050"
        - name: P2P_LISTEN_ADDR
          value: "/ip4/0.0.0.0/tcp/8828"
        - name: VALIDATOR_PRIVATE_KEY
          valueFrom:
            secretKeyRef:
              name: ncn-secrets
              key: validator-private-key
        envFrom:
        - configMapRef:
            name: ncn-config
        volumeMounts:
        - name: data
          mountPath: /data
        resources:
          requests:
            memory: "2Gi"
            cpu: "500m"
          limits:
            memory: "4Gi"
            cpu: "2000m"
        livenessProbe:
          tcpSocket:
            port: 50050
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          tcpSocket:
            port: 50050
          initialDelaySeconds: 5
          periodSeconds: 5
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes: ["ReadWriteOnce"]
      resources:
        requests:
          storage: 10Gi
---
apiVersion: v1
kind: Service
metadata:
  name: ncn-registry
  namespace: ncn-network
spec:
  selector:
    app: ncn-registry
  ports:
  - port: 50050
    name: grpc
  - port: 8828
    name: p2p
  clusterIP: None  # Headless service for StatefulSet
```

***

## Gateway Deployment

```yaml
# gateway-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ncn-gateway
  namespace: ncn-network
spec:
  replicas: 3
  selector:
    matchLabels:
      app: ncn-gateway
  template:
    metadata:
      labels:
        app: ncn-gateway
    spec:
      containers:
      - name: gateway
        image: your-registry/ncn-gateway:latest
        ports:
        - containerPort: 50051
          name: grpc
        - containerPort: 8080
          name: http
        - containerPort: 9000
          name: websocket
        env:
        - name: GRPC_ADDR
          value: "0.0.0.0:50051"
        - name: HTTP_ADDR
          value: "0.0.0.0:8080"
        - name: WS_ADDR
          value: "0.0.0.0:9000"
        - name: REGISTRY_GRPC_ADDR
          value: "http://ncn-registry:50050"
        - name: GATEWAY_WALLET_PRIVATE_KEY
          valueFrom:
            secretKeyRef:
              name: ncn-secrets
              key: gateway-private-key
        envFrom:
        - configMapRef:
            name: ncn-config
        resources:
          requests:
            memory: "2Gi"
            cpu: "500m"
          limits:
            memory: "4Gi"
            cpu: "2000m"
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
  name: ncn-gateway
  namespace: ncn-network
spec:
  selector:
    app: ncn-gateway
  ports:
  - port: 50051
    name: grpc
  - port: 8080
    name: http
  - port: 9000
    name: websocket
```

***

## Compute Node Deployment

```yaml
# compute-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ncn-compute
  namespace: ncn-network
spec:
  replicas: 5
  selector:
    matchLabels:
      app: ncn-compute
  template:
    metadata:
      labels:
        app: ncn-compute
    spec:
      containers:
      - name: compute
        image: your-registry/ncn-compute:latest
        env:
        - name: GATEWAY_ADDR
          value: "http://ncn-gateway:50051"
        - name: MODEL_PATH
          value: "/models"
        - name: COMPUTE_NODE_PRIVATE_KEY
          valueFrom:
            secretKeyRef:
              name: ncn-secrets
              key: compute-private-key
        envFrom:
        - configMapRef:
            name: ncn-config
        volumeMounts:
        - name: models
          mountPath: /models
        resources:
          requests:
            memory: "8Gi"
            cpu: "2000m"
            nvidia.com/gpu: 1  # For GPU nodes
          limits:
            memory: "16Gi"
            cpu: "4000m"
            nvidia.com/gpu: 1
        securityContext:
          privileged: true  # Required for sandbox
      volumes:
      - name: models
        persistentVolumeClaim:
          claimName: ncn-models
      nodeSelector:
        gpu: "true"  # Schedule on GPU nodes
      tolerations:
      - key: nvidia.com/gpu
        operator: Exists
        effect: NoSchedule
```

***

## Ingress

```yaml
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ncn-ingress
  namespace: ncn-network
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/proxy-body-size: "100m"
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
  tls:
  - hosts:
    - api.ncn-network.io
    secretName: ncn-tls
  rules:
  - host: api.ncn-network.io
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: ncn-gateway
            port:
              number: 8080
      - path: /grpc
        pathType: Prefix
        backend:
          service:
            name: ncn-gateway
            port:
              number: 50051
```

***

## Horizontal Pod Autoscaler

```yaml
# hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: ncn-gateway-hpa
  namespace: ncn-network
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: ncn-gateway
  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
```

***

## Deploy All Resources

```bash
# Apply all manifests
kubectl apply -f namespace.yaml
kubectl apply -f secrets.yaml
kubectl apply -f configmap.yaml
kubectl apply -f registry-statefulset.yaml
kubectl apply -f gateway-deployment.yaml
kubectl apply -f compute-deployment.yaml
kubectl apply -f ingress.yaml
kubectl apply -f hpa.yaml

# Check status
kubectl get pods -n ncn-network
kubectl get services -n ncn-network
kubectl get ingress -n ncn-network
```

***

## Monitoring

### Prometheus ServiceMonitor

```yaml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: ncn-gateway
  namespace: ncn-network
spec:
  selector:
    matchLabels:
      app: ncn-gateway
  endpoints:
  - port: http
    path: /metrics
    interval: 30s
```

***

## Helm Chart (Alternative)

If a Helm chart is available:

```bash
# Add repository
helm repo add ncn https://charts.ncn-network.io
helm repo update

# Install
helm install ncn-network ncn/ncn-network \
  --namespace ncn-network \
  --create-namespace \
  --values values.yaml
```

***

## Troubleshooting

### View Logs

```bash
kubectl logs -f deployment/ncn-gateway -n ncn-network
kubectl logs -f statefulset/ncn-registry -n ncn-network
```

### Exec into Pod

```bash
kubectl exec -it deployment/ncn-gateway -n ncn-network -- /bin/bash
```

### Check Events

```bash
kubectl get events -n ncn-network --sort-by='.lastTimestamp'
```

***

## Next Steps

* [Production Deployment](/nc/neurochainai-guides/deployment/production.md) - Production hardening
* [Monitoring](/nc/neurochainai-guides/operators/monitoring.md) - Set up monitoring


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.neurochain.ai/nc/neurochainai-guides/deployment/kubernetes.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
