Fix edge1 Ollama IP (.15->.17), add monitoring ingress, add init container

This commit is contained in:
Claude Code
2026-04-08 17:30:22 +00:00
parent f3919cf728
commit c9f07108bd

View File

@@ -1,325 +1,368 @@
# ============================================================================= # =============================================================================
# Agent Zero AI Stack — NUC Deployment (RKE2 Bare-Metal) # Agent Zero AI Stack — NUC Deployment (RKE2 Bare-Metal)
# ============================================================================= # =============================================================================
# Deploys: AgentZero (agent UI) on RKE2 cluster # Deploys: AgentZero (agent UI) on RKE2 cluster
# Ollama: edge1 Pi 5 at 10.0.57.15:11434 (qwen2.5-coder:7b, CPU) # Ollama: edge1 Pi 5 at 10.0.57.17:11434 (qwen2.5-coder:7b, CPU)
# Target: RKE2 bare-metal cluster, namespace: agent-zero # Target: RKE2 bare-metal cluster, namespace: agent-zero
# #
# Differences from LOCAL (WSL K3s): # Differences from LOCAL (WSL K3s):
# - Uses Longhorn StorageClass (not local-path) # - Uses Longhorn StorageClass (not local-path)
# - Connects to edge1 Pi 5 Ollama (not workstation R9700) # - Connects to edge1 Pi 5 Ollama (not workstation R9700)
# - NO Anthropic API key (free/local models only) # - NO Anthropic API key (free/local models only)
# - NO Piper TTS or Kiwix (edge1 handles TTS, no Wikipedia needed) # - NO Piper TTS or Kiwix (edge1 handles TTS, no Wikipedia needed)
# - NO hostPath volumes (no access to Windows filesystem) # - NO hostPath volumes (no access to Windows filesystem)
# - Traefik IngressRoute for LAN access at agent-zero.iamworkin.lan # - Traefik IngressRoute for LAN access at agent-zero.iamworkin.lan
# - Knowledge base loaded via ConfigMap (not hostPath) # - Knowledge base loaded via ConfigMap (not hostPath)
# #
# Available Ollama models on edge1: # Available Ollama models on edge1:
# - qwen2.5-coder:7b ~4.7 GB Code generation (CPU, Q4_K_M) # - qwen2.5-coder:7b ~4.7 GB Code generation (CPU, Q4_K_M)
# #
# Apply: KUBECONFIG=~/.kube/rke2.yaml kubectl apply -f agent-zero-nuc.yaml # Apply: KUBECONFIG=~/.kube/rke2.yaml kubectl apply -f agent-zero-nuc.yaml
# ============================================================================= # =============================================================================
--- ---
apiVersion: v1 apiVersion: v1
kind: Namespace kind: Namespace
metadata: metadata:
name: agent-zero name: agent-zero
labels: labels:
app.kubernetes.io/part-of: agent-zero-stack app.kubernetes.io/part-of: agent-zero-stack
# ============================================================================= # =============================================================================
# Persistent Volume Claims (Longhorn) # Persistent Volume Claims (Longhorn)
# ============================================================================= # =============================================================================
--- ---
apiVersion: v1 apiVersion: v1
kind: PersistentVolumeClaim kind: PersistentVolumeClaim
metadata: metadata:
name: agent-zero-data name: agent-zero-data
namespace: agent-zero namespace: agent-zero
spec: spec:
accessModes: [ReadWriteOnce] accessModes: [ReadWriteOnce]
storageClassName: longhorn storageClassName: longhorn
resources: resources:
requests: requests:
storage: 5Gi storage: 5Gi
--- ---
apiVersion: v1 apiVersion: v1
kind: PersistentVolumeClaim kind: PersistentVolumeClaim
metadata: metadata:
name: agent-zero-knowledge name: agent-zero-knowledge
namespace: agent-zero namespace: agent-zero
spec: spec:
accessModes: [ReadWriteOnce] accessModes: [ReadWriteOnce]
storageClassName: longhorn storageClassName: longhorn
resources: resources:
requests: requests:
storage: 1Gi storage: 1Gi
# ============================================================================= # =============================================================================
# RBAC — Give Agent Zero kubectl access to the cluster # RBAC — Give Agent Zero kubectl access to the cluster
# ============================================================================= # =============================================================================
--- ---
apiVersion: v1 apiVersion: v1
kind: ServiceAccount kind: ServiceAccount
metadata: metadata:
name: agent-zero name: agent-zero
namespace: agent-zero namespace: agent-zero
--- ---
apiVersion: rbac.authorization.k8s.io/v1 apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding kind: ClusterRoleBinding
metadata: metadata:
name: agent-zero-cluster-admin name: agent-zero-cluster-admin
roleRef: roleRef:
apiGroup: rbac.authorization.k8s.io apiGroup: rbac.authorization.k8s.io
kind: ClusterRole kind: ClusterRole
name: cluster-admin name: cluster-admin
subjects: subjects:
- kind: ServiceAccount - kind: ServiceAccount
name: agent-zero name: agent-zero
namespace: agent-zero namespace: agent-zero
# ============================================================================= # =============================================================================
# Agent Zero — AI Agent Web UI (NUC Edition) # Agent Zero — AI Agent Web UI (NUC Edition)
# ============================================================================= # =============================================================================
# Connects to edge1 Pi 5 Ollama (free, local models only) # Connects to edge1 Pi 5 Ollama (free, local models only)
# No paid API keys — uses qwen2.5-coder:7b for everything # No paid API keys — uses qwen2.5-coder:7b for everything
--- ---
apiVersion: apps/v1 apiVersion: apps/v1
kind: Deployment kind: Deployment
metadata: metadata:
name: agent-zero name: agent-zero
namespace: agent-zero namespace: agent-zero
labels: labels:
app: agent-zero app: agent-zero
annotations: annotations:
agent-zero/deployment: "nuc" agent-zero/deployment: "nuc"
agent-zero/ollama: "edge1 Pi 5 (10.0.57.15:11434)" agent-zero/ollama: "edge1 Pi 5 (10.0.57.17:11434)"
spec: spec:
replicas: 1 replicas: 1
selector: selector:
matchLabels: matchLabels:
app: agent-zero app: agent-zero
strategy: strategy:
type: Recreate type: Recreate
template: template:
metadata: metadata:
labels: labels:
app: agent-zero app: agent-zero
spec: spec:
serviceAccountName: agent-zero serviceAccountName: agent-zero
containers: initContainers:
- name: agent-zero # Wait for edge1 Pi 5 Ollama to be reachable before starting Agent Zero.
image: agent0ai/agent-zero:latest # Without this, the FAISS memory system crashes on embed_query()
command: ["/bin/bash", "-c"] # and Agent Zero enters a broken state on every message.
args: - name: wait-for-ollama
- | image: busybox:1.37
# Install kubectl if not cached command: ["sh", "-c"]
if [ -f /a0/work/kubectl ]; then args:
cp /a0/work/kubectl /usr/local/bin/kubectl - |
else echo "Waiting for Ollama at edge1 (10.0.57.17:11434)..."
curl -sLO "https://dl.k8s.io/release/v1.32.0/bin/linux/amd64/kubectl" && \ until wget -qO- --timeout=2 http://10.0.57.17:11434/api/tags >/dev/null 2>&1; do
chmod +x kubectl && mv kubectl /usr/local/bin/kubectl && \ echo "edge1 Ollama not ready, retrying in 5s..."
cp /usr/local/bin/kubectl /a0/work/kubectl sleep 5
fi done
# Run the original entrypoint echo "edge1 Ollama is reachable!"
exec /exe/initialize.sh $BRANCH containers:
ports: - name: agent-zero
- containerPort: 80 image: agent0ai/agent-zero:latest
env: command: ["/bin/bash", "-c"]
# Agent identity args:
- name: AGENT_NAME - |
value: "Blue Jay (NUC)" # Install kubectl if not cached
# Chat model — qwen2.5-coder:7b on edge1 Pi 5 if [ -f /a0/work/kubectl ]; then
- name: A0_SET_chat_model_provider cp /a0/work/kubectl /usr/local/bin/kubectl
value: "ollama" else
- name: A0_SET_chat_model_name curl -sLO "https://dl.k8s.io/release/v1.32.0/bin/linux/amd64/kubectl" && \
value: "qwen2.5-coder:7b" chmod +x kubectl && mv kubectl /usr/local/bin/kubectl && \
- name: A0_SET_chat_model_api_base cp /usr/local/bin/kubectl /a0/work/kubectl
value: "http://10.0.57.15:11434" fi
- name: A0_SET_chat_model_ctx_length # Run the original entrypoint
value: "32768" exec /exe/initialize.sh $BRANCH
- name: A0_SET_chat_model_kwargs ports:
value: '{"temperature": 0, "num_ctx": 32768}' - containerPort: 80
# Utility model — same as chat (only one model available) env:
- name: A0_SET_util_model_provider # Agent identity
value: "ollama" - name: AGENT_NAME
- name: A0_SET_util_model_name value: "Blue Jay (NUC)"
value: "qwen2.5-coder:7b" # Chat model — qwen2.5-coder:7b on edge1 Pi 5
- name: A0_SET_util_model_api_base - name: A0_SET_chat_model_provider
value: "http://10.0.57.15:11434" value: "ollama"
- name: A0_SET_util_model_kwargs - name: A0_SET_chat_model_name
value: '{"num_ctx": 8192}' value: "qwen2.5-coder:7b"
# Embedding model — nomic on edge1 (if installed, fallback to none) - name: A0_SET_chat_model_api_base
- name: A0_SET_embed_model_provider value: "http://10.0.57.17:11434"
value: "ollama" - name: A0_SET_chat_model_ctx_length
- name: A0_SET_embed_model_name value: "32768"
value: "nomic-embed-text" - name: A0_SET_chat_model_kwargs
- name: A0_SET_embed_model_api_base value: '{"temperature": 0, "num_ctx": 32768}'
value: "http://10.0.57.15:11434" # Utility model — same as chat (only one model available)
# Browser model — disabled (no vision model on Pi) - name: A0_SET_util_model_provider
- name: A0_SET_browser_model_provider value: "ollama"
value: "ollama" - name: A0_SET_util_model_name
- name: A0_SET_browser_model_name value: "qwen2.5-coder:7b"
value: "qwen2.5-coder:7b" - name: A0_SET_util_model_api_base
- name: A0_SET_browser_model_api_base value: "http://10.0.57.17:11434"
value: "http://10.0.57.15:11434" - name: A0_SET_util_model_kwargs
- name: A0_SET_browser_model_vision value: '{"num_ctx": 8192}'
value: "false" # Embedding model — nomic on edge1 (if installed, fallback to none)
# Agent profile - name: A0_SET_embed_model_provider
- name: A0_SET_agent_profile value: "ollama"
value: "default" - name: A0_SET_embed_model_name
# Memory settings value: "nomic-embed-text"
- name: A0_SET_memory_memorize_enabled - name: A0_SET_embed_model_api_base
value: "true" value: "http://10.0.57.17:11434"
- name: A0_SET_memory_memorize_consolidation # Browser model — disabled (no vision model on Pi)
value: "true" - name: A0_SET_browser_model_provider
- name: A0_SET_memory_memorize_replace_threshold value: "ollama"
value: "0.85" - name: A0_SET_browser_model_name
- name: A0_SET_memory_recall_enabled value: "qwen2.5-coder:7b"
value: "true" - name: A0_SET_browser_model_api_base
# Speech-to-text disabled (no GPU for Whisper) value: "http://10.0.57.17:11434"
- name: A0_SET_stt_model_size - name: A0_SET_browser_model_vision
value: "tiny" value: "false"
# Kubernetes # Agent profile
- name: KUBERNETES_SERVICE_HOST - name: A0_SET_agent_profile
value: "kubernetes.default.svc" value: "default"
- name: KUBERNETES_SERVICE_PORT # Memory settings
value: "443" - name: A0_SET_memory_memorize_enabled
volumeMounts: value: "true"
- name: workspace - name: A0_SET_memory_memorize_consolidation
mountPath: /a0/work value: "true"
- name: knowledge - name: A0_SET_memory_memorize_replace_threshold
mountPath: /a0/knowledge/custom/main value: "0.85"
resources: - name: A0_SET_memory_recall_enabled
requests: value: "true"
memory: "2Gi" # Speech-to-text disabled (no GPU for Whisper)
cpu: "1000m" - name: A0_SET_stt_model_size
limits: value: "tiny"
memory: "3Gi" # Kubernetes
cpu: "2000m" - name: KUBERNETES_SERVICE_HOST
volumes: value: "kubernetes.default.svc"
- name: workspace - name: KUBERNETES_SERVICE_PORT
persistentVolumeClaim: value: "443"
claimName: agent-zero-data volumeMounts:
- name: knowledge - name: workspace
persistentVolumeClaim: mountPath: /a0/work
claimName: agent-zero-knowledge - name: knowledge
mountPath: /a0/knowledge/custom/main
--- startupProbe:
apiVersion: v1 httpGet:
kind: Service path: /
metadata: port: 80
name: agent-zero initialDelaySeconds: 15
namespace: agent-zero periodSeconds: 10
spec: failureThreshold: 18
type: ClusterIP livenessProbe:
selector: httpGet:
app: agent-zero path: /
ports: port: 80
- port: 80 periodSeconds: 30
targetPort: 80 failureThreshold: 3
readinessProbe:
# ============================================================================= exec:
# Traefik IngressRoute — LAN access at agent-zero.iamworkin.lan command:
# ============================================================================= - /bin/bash
- -c
--- - "curl -sf http://localhost:80/ > /dev/null && curl -sf --connect-timeout 3 http://10.0.57.17:11434/api/tags > /dev/null"
apiVersion: traefik.io/v1alpha1 periodSeconds: 30
kind: IngressRoute failureThreshold: 2
metadata: resources:
name: agent-zero requests:
namespace: agent-zero memory: "2Gi"
spec: cpu: "1000m"
entryPoints: limits:
- websecure memory: "3Gi"
routes: cpu: "2000m"
- match: Host(`agent-zero.iamworkin.lan`) volumes:
kind: Rule - name: workspace
services: persistentVolumeClaim:
- name: agent-zero claimName: agent-zero-data
port: 80 - name: knowledge
tls: persistentVolumeClaim:
secretName: agent-zero-tls claimName: agent-zero-knowledge
# ============================================================================= ---
# TLS Certificate via cert-manager (step-ca ACME) apiVersion: v1
# ============================================================================= kind: Service
metadata:
--- name: agent-zero
apiVersion: cert-manager.io/v1 namespace: agent-zero
kind: Certificate spec:
metadata: type: ClusterIP
name: agent-zero-tls selector:
namespace: agent-zero app: agent-zero
spec: ports:
secretName: agent-zero-tls - port: 80
issuerRef: targetPort: 80
name: step-ca-acme
kind: ClusterIssuer # =============================================================================
dnsNames: # Traefik IngressRoute — LAN access at agent-zero.iamworkin.lan
- agent-zero.iamworkin.lan # =============================================================================
duration: 720h
renewBefore: 240h ---
apiVersion: traefik.io/v1alpha1
# ============================================================================= kind: IngressRoute
# NetworkPolicy — Restrict traffic metadata:
# ============================================================================= name: agent-zero
namespace: agent-zero
--- spec:
apiVersion: networking.k8s.io/v1 entryPoints:
kind: NetworkPolicy - websecure
metadata: routes:
name: agent-zero-netpol - match: Host(`agent-zero.iamworkin.lan`)
namespace: agent-zero kind: Rule
spec: services:
podSelector: - name: agent-zero
matchLabels: port: 80
app: agent-zero tls:
policyTypes: secretName: agent-zero-tls
- Ingress
- Egress # =============================================================================
ingress: # TLS Certificate via cert-manager (step-ca ACME)
# Allow from Traefik # =============================================================================
- from:
- namespaceSelector: ---
matchLabels: apiVersion: cert-manager.io/v1
kubernetes.io/metadata.name: traefik-system kind: Certificate
ports: metadata:
- port: 80 name: agent-zero-tls
egress: namespace: agent-zero
# DNS spec:
- to: secretName: agent-zero-tls
- namespaceSelector: issuerRef:
matchLabels: name: step-ca-acme
kubernetes.io/metadata.name: kube-system kind: ClusterIssuer
ports: dnsNames:
- port: 53 - agent-zero.iamworkin.lan
protocol: UDP duration: 720h
- port: 53 renewBefore: 240h
protocol: TCP
# Ollama on edge1 # =============================================================================
- to: # NetworkPolicy — Restrict traffic
- ipBlock: # =============================================================================
cidr: 10.0.57.15/32
ports: ---
- port: 11434 apiVersion: networking.k8s.io/v1
# K8s API kind: NetworkPolicy
- to: metadata:
- ipBlock: name: agent-zero-netpol
cidr: 10.0.56.11/32 namespace: agent-zero
ports: spec:
- port: 6443 podSelector:
# Allow internet (for kubectl image pull, etc) matchLabels:
- to: app: agent-zero
- ipBlock: policyTypes:
cidr: 0.0.0.0/0 - Ingress
except: - Egress
- 10.0.0.0/8 ingress:
- 172.16.0.0/12 # Allow from Traefik
- 192.168.0.0/16 - from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: traefik-system
ports:
- port: 80
# Allow from monitoring (blackbox probe)
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: monitoring
ports:
- port: 80
egress:
# DNS
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
ports:
- port: 53
protocol: UDP
- port: 53
protocol: TCP
# Ollama on edge1
- to:
- ipBlock:
cidr: 10.0.57.17/32
ports:
- port: 11434
# K8s API
- to:
- ipBlock:
cidr: 10.0.56.11/32
ports:
- port: 6443
# Allow internet (for kubectl image pull, etc)
- to:
- ipBlock:
cidr: 0.0.0.0/0
except:
- 10.0.0.0/8
- 172.16.0.0/12
- 192.168.0.0/16