AI-powered Kubernetes Learning Platformμ μΈνλΌ μ€μ λ° μ€μΌμ€νΈλ μ΄μ λ ν¬μ§ν 리μ λλ€.
μ¬μ©μλ₯Ό μν μ 체 μ€μ κ°μ΄λμ λλ€.
# kubectl μ€μΉ νμΈ
kubectl version --client
# μ€μΉλμ΄ μμ§ μλ€λ©΄
# macOS
brew install kubectl
# Linux
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
chmod +x kubectl && sudo mv kubectl /usr/local/bin/k3s ν΄λ¬μ€ν°λ μ¬μ©μκ° μ§μ ꡬμ±ν΄μΌ ν©λλ€. κ΅¬μ± ν λ Έλ μνλ₯Ό νμΈνμΈμ:
# λ§μ€ν° λ
Έλμμ μ€ν
kubectl get nodes
# μμ μΆλ ₯
# NAME STATUS ROLES AGE VERSION
# master Ready control-plane,master 1d v1.28.x+k3s1git clone https://github.com/next-gen-dist-sys/aklp-infra.git
cd aklp-infra
kubectl apply -k k8s/
# λ°°ν¬ μν νμΈ
kubectl get pods -n aklp -waklp-agentλ₯Ό μ μΈν λͺ¨λ Podκ° Running μνκ° λ λκΉμ§ κΈ°λ€λ¦½λλ€.
Note:
aklp-agentλCreateContainerConfigErrorμνλ‘ νμλ©λλ€. μ΄λ OPENAI_API_KEY Secretμ΄ μμ§ μμ±λμ§ μμκΈ° λλ¬Έμ΄λ©°, μ μμ μΈ μνμ λλ€. CLI μ΄κΈ° μ€μ (5λ¨κ³) μλ£ μ Secretμ΄ μλμΌλ‘ μμ±λκ³ Agentκ° μ¬μμλ©λλ€.
ip addr show
# λλ
hostname -ICLIλ₯Ό μ¬μ©ν νκ²½(λ‘컬 PC λ±)μμ λ€μμ μ€νν©λλ€:
# λ§μ€ν° λ
Έλμμ kubeconfig 볡μ¬
scp user@MASTER_IP:/etc/rancher/k3s/k3s.yaml ~/.kube/config
# server μ£Όμλ₯Ό λ§μ€ν° λ
Έλ IPλ‘ λ³κ²½
# Linux
sed -i 's/127.0.0.1/MASTER_IP/g' ~/.kube/config
# macOS
sed -i '' 's/127.0.0.1/MASTER_IP/g' ~/.kube/config
# KUBECONFIG νκ²½λ³μ μ€μ (.bashrc λλ .zshrcμ μΆκ°)
echo 'export KUBECONFIG=~/.kube/config' >> ~/.zshrc # λλ ~/.bashrc
# νκ²½λ³μ μ¦μ μ μ©
source ~/.zshrc # λλ source ~/.bashrc
# μ°κ²° νμΈ
kubectl get nodesμμ (μ μ μ΄λ¦μ΄ konkuk, λ§μ€ν° IPκ° 192.168.118.128μΈ κ²½μ°):
scp [email protected]:/etc/rancher/k3s/k3s.yaml ~/.kube/config
sed -i 's/127.0.0.1/192.168.118.128/g' ~/.kube/config # Linux# μ€μΉ μ€ν¬λ¦½νΈ μ€ν (Linux, macOS, Windows μ§μ)
curl -sSL https://raw.githubusercontent.com/next-gen-dist-sys/aklp-cli/main/install.sh | sh
# μ€μΉ μ€ν¨ μ μ§μ λ€μ΄λ‘λ
# https://github.com/next-gen-dist-sys/aklp-cli/releases
# CLI μ€ν
aklp첫 μ€ν μ ν΄λ¬μ€ν° μ£Όμμ OpenAI API Keyλ₯Ό μ λ ₯νλ μ€μ λ§λ²μ¬κ° μμλ©λλ€. ν΄λ¬μ€ν° ν¬μ€μ²΄ν¬μ kubernetes secret λ±λ‘μ μ±κ³΅ν΄μΌ μλΉμ€λ₯Ό μ΄μ©ν μ μμ΅λλ€.
β― λͺ¨λ λ€μμ€νμ΄μ€μ νλ 보μ¬μ€
β― default λ€μμ€νμ΄μ€μ nginx λ°°ν¬ν΄μ€
β― μλΉμ€ λͺ©λ‘ μ‘°νν΄μ€CLI μμΈ μ¬μ©λ²: aklp-cli README
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β User (CLI) β
ββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β aklp-agent (NodePort: 30001) β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β’ νμ΅ κ°μ΄λ μ 곡 β β
β β β’ YAML νμΌ μμ±/κ²ν β β
β β β’ kubectl λͺ
λ Ή μ€ν λ° κ²°κ³Ό λΆμ β β
β β β’ νμ΅ μλ£ λ° λ
ΈνΈ μλ μμ± β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
ββββββββββ¬ββββββββββββββββββββββ¬ββββββββββββββββββββββ¬ββββββββββββββββββββββ
β β β
βΌ βΌ βΌ
βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ
β aklp-note β β aklp-task β β aklp-file β
β(NodePort: 30002)β β(NodePort: 30003)β β(NodePort: 30004)β
β β β β β β
β β’ νμ΅ λ
ΈνΈ β β β’ νμ΅ κ³Όμ β β β’ YAML νμΌ β
β β’ μΈμ
μμ½ β β β’ Batch κ΄λ¦¬ β β β’ μ
λ‘λ & λ€μ΄λ‘λβ
β β’ λͺ
λ Ήμ΄ κΈ°λ‘ β β β’ μ§ν μν β β β’ λ¬Έμ κ΄λ¦¬ β
ββββββββββ¬βββββββββ ββββββββββ¬βββββββββ ββββββββββ¬βββββββββ
β β β
βββββββββββββββββββββββ΄ββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββ
β aklp-postgres β
β (ν¬νΈ 5432) β
β β
β β’ aklp_note DB β
β β’ aklp_task DB β
β β’ aklp_file DB β
β β’ aklp_agent DB β
βββββββββββββββββββββββ
Note: Docker Composeλ κ°λ¨ν μλΉμ€ κ°λ°/ν μ€νΈ μ©λλ‘λ§ μ¬μ©ν©λλ€. kubectl λͺ λ Ήμ΄ μ€ν κΈ°λ₯μ k3s ν΄λ¬μ€ν° νκ²½μμλ§ λμν©λλ€.
# μμ
λλ ν 리 μμ±
mkdir aklp && cd aklp
# μΈνλΌ λ ν¬μ§ν 리
git clone https://github.com/next-gen-dist-sys/aklp-infra.git
# μλΉμ€ λ ν¬μ§ν λ¦¬λ€ (κ°μ λ 벨μ ν΄λ‘ )
git clone https://github.com/next-gen-dist-sys/aklp-postgres.git
git clone https://github.com/next-gen-dist-sys/aklp-note.git
git clone https://github.com/next-gen-dist-sys/aklp-task.git
git clone https://github.com/next-gen-dist-sys/aklp-file.git
git clone https://github.com/next-gen-dist-sys/aklp-agent.gitaklp/
βββ aklp-infra/ # μ΄ λ ν¬μ§ν 리 (Docker Compose, K8s λ§€λνμ€νΈ)
βββ aklp-postgres/ # PostgreSQL μλΉμ€
βββ aklp-note/ # Note μλΉμ€ (νμ΅ λ
ΈνΈ κ΄λ¦¬)
βββ aklp-task/ # Task μλΉμ€ (ν μΌ κ΄λ¦¬)
βββ aklp-file/ # File μλΉμ€ (νμΌ κ΄λ¦¬)
βββ aklp-agent/ # Agent μλΉμ€ (AI μ€μΌμ€νΈλ μ΄μ
)
cd aklp-infra
docker compose upλλ λ°±κ·ΈλΌμ΄λ μ€ν:
docker compose up -d| μλΉμ€ | ν¬νΈ | λ°μ΄ν°λ² μ΄μ€ | μ©λ |
|---|---|---|---|
| aklp-postgres | 5432 | - | λͺ¨λ μλΉμ€μ κ³΅μ© λ°μ΄ν°λ² μ΄μ€ |
| aklp-agent | 8001 | aklp_agent | AI μ€μΌμ€νΈλ μ΄μ |
| aklp-note | 8002 | aklp_note | νμ΅ λ ΈνΈ, μΈμ μμ½ |
| aklp-task | 8003 | aklp_task | νμ΅ κ³Όμ λ° Batch κ΄λ¦¬ |
| aklp-file | 8004 | aklp_file | νμΌ μ λ‘λ/λ€μ΄λ‘λ |
- Agent Service: Agent μλΉμ€ μ€μ¨κ±°
- Note Service: Note μλΉμ€ μ€μ¨κ±°
- Task Service: Task μλΉμ€ μ€μ¨κ±°
- File Service: File μλΉμ€ μ€μ¨κ±°
λͺ¨λ Backend μλΉμ€λ session_idλ‘ λ°μ΄ν°λ₯Ό κ·Έλ£Ήνν©λλ€. Agentλ μΈμ
μμ μ UUIDλ₯Ό μμ±νκ³ λͺ¨λ API νΈμΆμ λμΌν κ°μ μ¬μ©ν΄μΌ ν©λλ€.
import uuid
SESSION_ID = str(uuid.uuid4()) # μΈμ
λΉ ν λ²λ§ μμ±1. μΈμ
μμ
βββ Agent: session_id μμ±
2. νμ΅ μ£Όμ μ ν (μ: "Kubernetes Pod κΈ°μ΄")
βββ Agent: POST /api/v1/batches (νμ΅ κ³Όμ μμ±)
3. νμ΅ μλ£ μ 곡
βββ Agent: POST /api/v1/files (YAML νμΌ μ
λ‘λ)
βββ Agent: POST /api/v1/notes (κ°λ
μ€λͺ
λ
ΈνΈ μμ±)
4. μ€μ΅ μ§ν
βββ User: νμΌ λ€μ΄λ‘λ β kubectl apply
βββ Agent: λͺ
λ Ήμ΄ κΈ°λ‘ β POST /api/v1/notes
5. κ³Όμ μλ£
βββ Agent: PUT /api/v1/tasks/{id} (status: completed)
6. μΈμ
μ’
λ£
βββ Agent: POST /api/v1/notes (νμ΅ μμ½ μμ±)
| μν© | API | λ©μλ |
|---|---|---|
| μ μ£Όμ νμ΅ μμ | /api/v1/batches |
POST |
| μΆκ° κ³Όμ μμ± | /api/v1/tasks |
POST |
| κ³Όμ μλ£ μ²λ¦¬ | /api/v1/tasks/{id} |
PUT |
| μ§ν μν© νμΈ | /api/v1/batches/latest |
GET |
| μ¬λ¬ κ³Όμ μλ£ | /api/v1/tasks/bulk |
PUT |
| μν© | API | λ©μλ |
|---|---|---|
| νμ΅ λ΄μ© κΈ°λ‘ | /api/v1/notes |
POST |
| λͺ λ Ήμ΄ κΈ°λ‘ μ μ₯ | /api/v1/notes |
POST |
| μΈμ μμ½ μμ± | /api/v1/notes |
POST |
| λ ΈνΈ μ λ°μ΄νΈ | /api/v1/notes/{id} |
PUT |
| μΈμ λ ΈνΈ μ‘°ν | /api/v1/notes?session_id=... |
GET |
| μν© | API | λ©μλ |
|---|---|---|
| YAML νμΌ μμ± | /api/v1/files |
POST |
| kubectl μΆλ ₯ μ μ₯ | /api/v1/files |
POST |
| νμΌ λ€μ΄λ‘λ | /api/v1/files/{id}/download |
GET |
| νμΌ κ΅μ²΄ | /api/v1/files/{id} |
PUT |
| μΈμ νμΌ λͺ©λ‘ | /api/v1/files?session_id=... |
GET |
{
"items": [...],
"total": 25,
"page": 1,
"limit": 10,
"total_pages": 3,
"has_next": true,
"has_prev": false
}{
"detail": "Resource not found"
}κ° μλΉμ€μ .env νμΌμ νμΈνκ³ νμμ λ°λΌ μμ νμΈμ:
# κ° μλΉμ€ λλ ν 리μμ
cp .env.example .envdocker compose restart aklp-note
docker compose restart aklp-task
docker compose restart aklp-file# μ 체 λ‘κ·Έ
docker compose logs -f
# νΉμ μλΉμ€ λ‘κ·Έ
docker compose logs -f aklp-task# λͺ¨λ 컨ν
μ΄λμ λ³Όλ₯¨ μμ
docker compose down -v
# λ€μ μμ
docker compose up# λͺ¨λ μλΉμ€ μν νμΈ
curl http://localhost:8001/health # agent
curl http://localhost:8002/health # note
curl http://localhost:8003/health # task
curl http://localhost:8004/health # filek3s ν΄λ¬μ€ν°μ λ°°ν¬νλ €λ©΄ k8s/README.md λ₯Ό μ°Έκ³ νμΈμ.
# μ 체 λ°°ν¬
kubectl apply -k k8s/
# μν νμΈ
kubectl get all -n aklp| νλͺ© | κΈ°μ |
|---|---|
| 컨ν μ΄λ | Docker & Docker Compose |
| λ°μ΄ν°λ² μ΄μ€ | PostgreSQL 17 |
| λ°±μλ μΈμ΄ | Python 3.12 |
| μΉ νλ μμν¬ | FastAPI |
| ORM | SQLAlchemy 2.0 (async) |
| ν¨ν€μ§ κ΄λ¦¬ | uv |
| λ ν¬μ§ν 리 | μ€λͺ | λ΄λΉ |
|---|---|---|
| aklp-postgres | PostgreSQL μλΉμ€ | λνμ§ |
| aklp-note | Note μλΉμ€ | λνμ§ |
| aklp-task | Task μλΉμ€ | λνμ§ |
| aklp-file | File μλΉμ€ | λνμ§ |
| aklp-agent | Agent μλΉμ€ | κΉμλ―Ό |
| aklp-cli | CLI μ ν리μΌμ΄μ | λ°λ²μ |
MIT