Skip to content
 
 

Latest commit

 

History

22 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Cloudemy — Kubernetes 기반 온라인 코딩 실습 자동 채점 플랫폼

클라우드시스템 팀프로젝트 7조 | 임소정 · 남민서 · 위지우


프로젝트 개요

기존 코딩 실습 채점 프로세스는 학생과 조교 모두가 로컬 PC와 Snowboard를 오가며 코드를 수동으로 업로드·다운로드·실행해야 하는 6단계의 비효율적인 구조였습니다.

Cloudemy는 이를 Kubernetes 위에서 2단계로 단축합니다.

AS-IS (6단계) TO-BE (2단계)
로컬 PC 작성 → Snowboard 제출 → 코드 다운 → 로컬 실행·채점 → 결과 입력 → 피드백 확인 코드 작성·테스트·제출 → 점수·피드백·대시보드 확인

학생이 코드를 제출하면 Kubernetes Job이 자동으로 생성되어 채점을 수행하고, 결과를 즉시 학생과 조교에게 전달합니다. 모든 컴포넌트(Backend, Scheduler, Runner, DB, Cache)는 K8s 클러스터 위에서 선언적으로 관리됩니다.


주요 기능

  • 온라인 코드 에디터 — 브라우저에서 코드 작성 및 실행
  • K8s Job 기반 자동 채점 — 제출마다 독립된 Runner Pod가 Job으로 생성되어 채점 수행
  • Scheduler — Redis 큐를 감시하며 K8s API로 Job을 동적으로 생성·관리
  • HPA 자동 스케일링 — CPU/Memory 임계치 초과 시 Backend Pod 자동 확장 (min 1 / max 10)
  • RBAC — Scheduler에 Job 생성 최소 권한만 부여
  • Secret 관리 — API Key·인증 토큰을 K8s Secret으로 분리하여 보안 관리
  • 실시간 피드백 — 채점 완료 후 학생에게 즉시 점수·피드백 제공
  • 조교 대시보드 — 전체 제출 현황 및 채점 결과 한눈에 확인

아키텍처

Cloudemy Architecture

                        User
                          |
                       Ingress (cloudemy.local)
                    /              \
           Frontend (React)    Backend (FastAPI)
               :3000                :8000
                                /    |    \
                           Redis  MongoDB  Scheduler
                           :6379  :27017      |
                                          K8s Job
                                             |
                                         Runner Pod → OpenAI

K8s 클러스터 구성

  • 노드 3개 — Master / Worker1 / Worker2로 Pod 분산 배치
  • Frontend Pod → Backend Service를 호출하여 통신
  • MongoDB — 영구 데이터 저장 (프로토타입: emptyDir, 이후 PVC 전환 예정)
  • Redis — 인메모리 제출 큐 (queue:submissions)
  • Scheduler — Redis 큐를 감시하고 Kubernetes Job 생성·관리
  • Runner Pod — Job으로 생성되어 OpenAI API 호출 후 채점 결과를 Backend에 콜백

채점 플로우

Job 동작

학생 코드 제출
    → Backend가 Redis 큐(queue:submissions)에 submission_id 적재
    → Scheduler가 큐를 감시하다 submission_id 수신
    → create_runner_job()으로 Kubernetes Job 스펙 생성
    → Runner Pod 자동 생성 (runner.py 실행)
    → OpenAI API로 코드 채점
    → Backend(http://backend:8000/internal)에 결과 콜백
    → 학생 화면에 점수·피드백 표시

기술 스택

레이어 기술
Backend FastAPI (Python 3.11), Docker Hub: withya61/cloudemy-backend
Scheduler Python 3.11, Docker Hub: withya61/cloudemy-scheduler
Runner Python 3.11, Docker Hub: withya61/cloudemy-runner
Database MongoDB 6 (port 27017)
Cache / Queue Redis 7 (port 6379)
Orchestration Kubernetes (K8s) — Deployment, Service, Job, HPA, Secret, RBAC, Ingress
AI OpenAI API (LLM 기반 채점)

프로젝트 구조

Backend-Cloudemy/
├── backend/            # FastAPI 서버
│   ├── app/
│   ├── dockerfile
│   └── requirements.txt
├── scheduler/          # Redis 큐 감시 + K8s Job 생성
│   ├── scheduler.py
│   ├── dockerfile
│   └── requirements.txt
├── runner/             # 채점 실행 (K8s Job으로 동작)
│   ├── runner.py
│   ├── dockerfile
│   └── requirements.txt
├── k8s/                # Kubernetes 매니페스트
│   ├── backend.yaml    # Backend Deployment + Service + HPA
│   ├── mongo.yaml      # MongoDB Deployment + Service
│   ├── redis.yaml      # Redis Deployment + Service
│   ├── scheduler.yaml  # Scheduler Deployment
│   ├── secret.yaml     # LLM API Key + 내부 인증 토큰
│   └── rbac-scheduler.yaml
└── docker-compose.db.yml

K8s 리소스 상세

Backend

리소스 내용
kind: Deployment replicas: 1, 포트 8000
kind: Service ClusterIP, 포트 8000
kind: HPA CPU 70% / Memory 80% 초과 시 자동 스케일 (min: 1, max: 10)

환경 변수로 MongoDB URI, Redis URL, K8s Namespace, Runner 이미지, Backend 내부 URL 주입.
cloudemy-secret에서 LLM_API_KEY, INTERNAL_RESULT_TOKEN 참조.

HPA (HorizontalPodAutoscaler)

HPA 구성

  • backend-deploy를 대상으로 Pod 수 자동 조절
  • CPU 사용률 70% 또는 메모리 사용률 80% 초과 시 자동으로 Pod 확장
  • 최소 1개 ~ 최대 10개까지 자동 스케일 아웃

Ingress

  • 도메인: cloudemy.local (nginx Ingress Controller)
  • /frontend-service:80
  • /apibackend-service:8000

MongoDB

  • 공식 이미지 mongo:6, 포트 27017
  • ClusterIP Service로 내부 통신 (mongodb://mongo:27017)
  • 현재 emptyDir 볼륨 사용 (향후 PVC 전환 예정)

Redis

  • 공식 이미지 redis:7, 포트 6379
  • ClusterIP Service (redis://redis:6379)

Scheduler

Scheduler 동작

  • Redis 큐 queue:submissions 감시
  • K8s API 호출로 Runner Job 동적 생성
  • cloudemy-secret에서 LLM_API_KEY, INTERNAL_RESULT_TOKEN 참조

Secret

# secret.yaml
LLM_API_KEY: <base64>
INTERNAL_RESULT_TOKEN: <base64>

Backend / Scheduler / Runner에 envFrom으로 주입.


Docker Hub 이미지

컴포넌트 이미지
Backend withya61/cloudemy-backend:latest
Scheduler withya61/cloudemy-scheduler:latest
Runner withya61/cloudemy-runner:latest

배포 방법

1. Secret 생성

kubectl apply -f k8s/secret.yaml

2. RBAC 설정 (Scheduler용)

kubectl apply -f k8s/rbac-scheduler.yaml

3. 전체 리소스 배포

kubectl apply -f k8s/mongo.yaml
kubectl apply -f k8s/redis.yaml
kubectl apply -f k8s/backend.yaml
kubectl apply -f k8s/scheduler.yaml

4. Ingress 설정

/etc/hosts에 다음 추가 후 cloudemy.local로 접속:

<NODE_IP>  cloudemy.local

About

Kubernetes 기반 온라인 코딩 실습 자동 채점 플랫폼

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages