Compute Module 볼륨
볼륨은 한 복제본 안의 여러 컨테이너가 파일을 공유하는 공간입니다. 컨테이너 root 파일시스템과 독립적으로 크기를 구성할 수 있습니다. 서로 다른 복제본 사이에는 공유되지 않습니다.
모든 볼륨은 복제본 수명에 연결된 임시 저장소입니다. 복제본 재시작이나 종료 뒤에도 남아야 하는 데이터는 Foundry 데이터셋 등 영구 저장소에 보관합니다.
볼륨 종류
| 종류 | 초기 상태 | 접근 |
|---|---|---|
| Empty directory | 복제본 시작 시 빈 디렉터리 | 마운트한 모든 컨테이너가 같은 파일 읽기/쓰기 |
| Content directory | 시작 전에 정의한 파일을 미리 넣음 | 읽기 전용. 전체 내용 최대 100 KB |
Empty directory는 같은 복제본의 컨테이너 간 실행 중 데이터 교환에 사용합니다. Content directory는 환경별 설정 파일을 앱 이미지와 분리할 때 사용합니다. 볼륨 데이터는 복제본 종료 시 사라집니다.
생성
Configuration의 Volumes에서 Add Volume을 선택합니다.
이름은 문자로 시작하고 소문자, 숫자와 하이픈만 포함하며 최대 63자입니다. 기본으로 Empty directory를 만듭니다.
Content directory로 바꾸려면 볼륨 설정을 열고 종류를 변경합니다.
+ Add로 파일을 추가하고 Name에 파일명, Content에 평문 내용을 입력한 뒤 Save합니다. 모듈을 시작하기 전에 내용을 정의해야 합니다.
컨테이너에 마운트
- Containers에서 대상 컨테이너를 엽니다.
- Volume mounts에서 Add를 선택하고 볼륨을 고릅니다.
- 절대 경로를 지정합니다.
/mnt/data같은 경로를 사용할 수 있으며 루트/는 허용하지 않습니다. - Save합니다.
볼륨을 생성하는 것만으로 컨테이너에서 접근할 수 있지는 않으므로 실제 읽고 쓸 컨테이너마다 마운트를 설정합니다.
온톨로지 객체 스냅샷 재사용
다음 예제는 복제본 시작 시 Employee 한 개를 실제 OSDK로 읽고, 이후 함수 호출은 볼륨 파일을 읽습니다. demo_python_sdk와 Employee는 가상 생성 SDK 이름입니다. Employee의 문자열 기본 키 속성 employee_id 및 이름 속성 full_name을 가진 스키마를 가정합니다.
필요한 구성은 다음과 같습니다.
- Python OSDK와 foundry-compute-modules를 설치합니다.
- Functions 모드의 Application permissions에서 해당 Developer Console 앱의 client ID와 secret을 설정합니다.
- 서비스 사용자에게 Employee를 읽을 권한을 주고 Foundry 호스트의 소스를 연결합니다.
- 쓰기 가능한 Empty directory를
/mnt/data에 마운트합니다. - FOUNDRY_HOST에는 프로토콜을 제외한 호스트, EMPLOYEE_ID에는 실제 조회할 기본 키를 설정합니다.
import json
import os
from pathlib import Path
import tempfile
from compute_modules import add_functions, start_compute_module
from demo_python_sdk import FoundryClient, ConfidentialClientAuth
CACHE_FILE = Path("/mnt/data/employee.json")
def prepare_snapshot() -> None:
host = os.environ["FOUNDRY_HOST"]
auth = ConfidentialClientAuth(
client_id=os.environ["CLIENT_ID"],
client_secret=os.environ["CLIENT_SECRET"],
hostname=host,
should_refresh=True,
scopes=["api:ontologies-read"],
)
client = FoundryClient(auth=auth, hostname=host)
employee = client.ontology.objects.Employee.get(os.environ["EMPLOYEE_ID"])
snapshot = {
"employeeId": employee.employee_id,
"fullName": employee.full_name,
}
temporary = None
try:
with tempfile.NamedTemporaryFile(
mode="w", encoding="utf-8", dir=CACHE_FILE.parent, delete=False
) as output:
temporary = Path(output.name)
json.dump(snapshot, output, ensure_ascii=False)
os.replace(temporary, CACHE_FILE)
finally:
if temporary is not None:
temporary.unlink(missing_ok=True)
def get_employee_snapshot(context, event) -> str:
return CACHE_FILE.read_text(encoding="utf-8")
if __name__ == "__main__":
prepare_snapshot()
add_functions(get_employee_snapshot)
start_compute_module()
스냅샷은 볼륨의 employee.json에 저장합니다. 초기 조회나 파일 기록이 실패하면 함수를 시작하지 않습니다. 명시적 시작 방식을 사용하므로 별도로 @function을 붙이지 않습니다.
함수는 저장한 JSON 문서를 문자열로 반환하며 매번 객체를 다시 읽지는 않습니다. 파일은 복제본에서 공유하는 서비스 사용자 범위의 스냅샷이므로 이 함수를 호출하도록 허용할 사용자도 그 데이터 공개 범위에 맞춰야 합니다. 사용자별 권한으로 조회한 결과를 공용 캐시에 섞어 보관하지 않습니다.
원본 객체가 변경되면 이 파일이 자동 갱신되지는 않습니다. 새 복제본은 시작 시 새로 조회하고 기존 복제본의 파일을 이어받지 않습니다.
수명 제한
영구 볼륨은 지원하지 않습니다. 복제본의 최대 수명은 22시간이며 플랫폼은 그보다 일찍 교체할 수도 있습니다. 볼륨을 영구 상태나 복제본 간 공통 데이터베이스로 사용하지 않습니다. 상태와 교체 이력은 복제본 진단과 이력에서 확인합니다.