lakeFS Mount
everest 명령줄 도구를 사용하면 원격 lakeFS 저장소를 로컬 디렉터나 Kubernetes 환경에 가상으로 마운트할 수 있어요. 마운트되면 데이터가 로컬 파일시스템에 있는 것처럼 어떤 도구·라이브러리·프레임워크로든 접근할 수 있죠. GPU 활용 최적화와 성능 민감 작업에 적합한 지연 로딩(lazy fetching)과 캐시 기능도 갖추고 있어요.
출처: 문서
본문
lakeFS Team과 lakeFS Enterprise에서 사용할 수 있어요. 무료 체험을 시작하거나 문의하기를 이용하세요.
lakeFS Mount는 everest 명령줄 도구로 원격 lakeFS 저장소를 로컬 디렉터나 Kubernetes 환경에 가상으로 마운트하게 해줘요. 마운트되면 데이터가 로컬 파일시스템에 있는 것처럼, 어떤 도구·라이브러리·프레임워크를 써서든 접근할 수 있어요.
사용 사례
-
간소화된 데이터 로딩: 커스텀 데이터 로더나 SDK 없이, 기존 도구로 파일시스템에서 바로 파일을 읽고 쓸 수 있어요.
-
매끄러운 확장성: 도구나 워크플로를 바꾸지 않고 몇 개의 로컬 파일에서 수십억 개 규모로 확장할 수 있어요. 실험부터 프로덕션까지 같은 코드를 쓰면 돼요.
-
향상된 성능: lakeFS Mount는 수십억 개의 파일을 지원하고 빠른 지연 데이터 페칭을 제공해요. GPU 활용 최적화 등 성능에 민감한 작업에 이상적이에요.
시작하기
이 가이드는 lakeFS 저장소를 여러분의 로컬 머신에 마운트하도록 lakeFS Mount를 설정하고 사용하는 과정을 안내해요.
lakeFS Mount가 처음인가요?
이 시작 가이드를 마친 뒤에는, 캐싱·일관성·성능 특성을 이해하려고 Core Concepts 섹션을 읽어 보길 권해요.
필수 조건
-
lakeFS Cloud 계정 또는 lakeFS Enterprise 버전
1.25.0이상. -
지원 OS: macOS(NFS V3 사용), Linux, Windows(CFAPI 사용).
-
lakeFS Mount 바이너리 확보: lakeFS Mount는 설치가 필요 없는 자체 완결형(self-contained) 바이너리예요. 접근 권한을 받으려면 문의하기를 이용하세요.
Windows 지원
lakeFS Mount for Windows가 이제 제공돼요. 현재는 읽기 작업만 지원돼요. lakeFS Mount for Windows 문서를 참고하세요.
인증 & 설정
lakeFS Mount는 lakectl과 같은 설정·인증 방법을 사용해요. 자격 증명과 서버 엔드포인트는 다음 순서로 찾아요:
-
명령줄 플래그:
--lakectl-access-key-id,--lakectl-secret-access-key,--lakectl-server-url. -
환경 변수:
LAKECTL_*또는EVEREST_LAKEFS_*접두사 변수. -
설정 파일:
~/.lakectl.yaml(또는--lakectl-config가 지정한 파일).
인증 방법
lakeFS Mount는 다음 순서로 인증을 시도해요:
-
세션 토큰:
EVEREST_LAKEFS_CREDENTIALS_SESSION_TOKEN또는LAKECTL_CREDENTIALS_SESSION_TOKEN에서 가져와요. 토큰이 만료됐으면 인증이 실패해요. -
lakeFS 키 페어: 표준 액세스 키 ID와 시크릿 액세스 키(lakeFS Mount 전용 자격 증명이 주어지지 않으면 lakectl 설정에서 자격 증명을 가져와요).
-
IAM 인증: lakeFS 환경이 AWS IAM Role Login으로 구성되어 있다면, lakeFS Mount(≥ v0.4.0)는 여러분의 AWS 환경(예:
AWS_PROFILE)으로 인증할 수 있어요. IAM 인증은 정적 자격 증명이 설정되지 않았을 때만 시도돼요. 이를 활성화하려면 .lakectl.yaml에provider_type: aws_iam을 설정하세요. AWS 세션이 유효한 동안 토큰은 매끄럽게 새로 고쳐져요. 환경 변수로 IAM 인증을 설정하려면EVEREST_LAKEFS_*또는LAKECTL_*접두사를 사용하세요:
export EVEREST_LAKEFS_CREDENTIALS_PROVIDER_TYPE=aws_iam
# or
export LAKECTL_CREDENTIALS_PROVIDER_TYPE=aws_iam
lakectl 버전 호환성
lakectl CLI에 쓰는 것과 같은
lakectl.yaml파일로 IAM 프로바이더를 설정한다면, lakectl을≥ v1.57.0으로 업그레이드해야 해요. 그렇지 않으면 lakectl 사용 시 오류가 발생해요.
IAM Presign 요청 문제 해결
IAM 인증의 presign 요청 문제를 디버깅하려면 다음 환경 변수로 presign 요청의 디버그 로깅을 활성화할 수 있어요:
export EVEREST_LAKEFS_CREDENTIALS_PROVIDER_AWS_IAM_CLIENT_LOG_PRE_SIGNING_REQUEST=true
첫 마운트 만들기
lakeFS 저장소의 프리픽스를 로컬 디렉터로 마운트해 볼게요. 읽기 전용 모드에서 lakeFS Mount는 특정 커밋 ID를 고정(pinning)해요. 브랜치 이름을 주면 마운트 시점의 HEAD 커밋으로 해석돼요.
- 저장소 마운트하기:
이 명령은
image-repo저장소의main브랜치에서datasets/pets/프리픽스를./pets라는 새 로컬 디렉터로 마운트해요.
everest mount "lakefs://image-repo/main/datasets/pets/" "./pets"
- 데이터 탐색하기: 이제 표준 파일시스템 명령으로 데이터와 상호작용할 수 있어요. 파일은 콘텐츠에 접근할 때만 지연 다운로드돼요.
# List files - this only fetches metadata
ls -l "./pets/dogs/"
# Find files
find ./pets -name "*.small.jpg"
# Open a file - this triggers a download
open -a Preview "./pets/dogs/golden_retrievers/cute.jpg"
- 디렉터 언마운트하기: 작업이 끝나면 디렉터를 언마운트하세요.
everest umount "./pets"
핵심 개념
이 섹션은 로컬과 Kubernetes 배포 모두에서 lakeFS Mount가 성능·일관성·캐싱을 어떻게 관리하는지 이해하도록 돕는 거예요.
캐시 동작
lakeFS Mount는 lakeFS에서 파일에 접근할 때의 성능을 높이려고 로컬 캐시를 사용해요. 캐시가 어떻게 동작하는지 이해하면 자신의 사용 사례에 맞게 성능을 최적화하는 데 도움이 돼요.
캐싱이 동작하는 방식
마운트된 lakeFS 경로로 파일에 접근하면 lakeFS Mount는 다음 과정을 거쳐요:
-
지연 페칭(Lazy Fetching): 파일은 콘텐츠에 접근할 때만 다운로드돼요(예:
ls로 나열하는 게 아니라 파일을 실제로 읽을 때). -
캐시 저장: 오브젝트가 로컬 캐시에 없으면 lakeFS Mount가 오브젝트 스토어에서 데이터를 가져와 이후 접근을 위해 캐시에 저장해요.
-
캐시 재사용: 같은 파일을 다시 읽으면 네트워크 요청 없이 캐시에서 바로 제공돼요. 성능이 좋아지죠. 캐시는 서로 다른 mount 인스턴스 간에 공유될 수 없어요.
기본 캐시 동작
기본적으로 everest mount를 실행하면 lakeFS Mount가 임시 캐시 디렉터를 만들어요. 이 디렉터는 everest umount로 마운트가 종료될 때 자동으로 비워져요.
핵심 포인트:
-
새 마운트마다 새로운 캐시 디렉터가 만들어져요.
-
기본적으로 캐시 위치는 lakeFS Mount가 관리하고 자동으로 정리해요.
-
캐시는 임시적이고 마운트 세션 사이에 유지되지 않아요. 캐시 디렉터를 직접 지정하지 않는 한요.
영구 캐시
여러 마운트 세션에 걸쳐 캐시 데이터를 재사용하려면 --cache-dir 플래그로 커스텀 캐시 디렉터를 지정할 수 있어요:
everest mount lakefs://image-repo/main/datasets/ ./datasets --cache-dir ~/.everest-cache
영구 캐시의 이점:
-
같은 데이터를 다시 마운트할 때 시작 시간이 빨라져요.
-
이전에 다운로드한 파일을 재사용해 대역폭 사용이 줄어들어요.
-
같은 저장소를 반복해서 마운트/언마운트하는 반복적 워크플로에 유용해요.
캐시 관리
lakeFS Mount는 마운트된 참조의 커밋 ID를 기준으로 캐시된 데이터를 관리해요:
-
커밋 기반 캐싱: 커밋 ID마다 자체 캐시 네임스페이스가 있어요. 덕분에 캐시된 데이터가 항상 파일의 올바른 버전에 대응해요.
-
커밋 시 캐시 무효화:
everest commit으로 쓰기 모드에서 변경을 커밋하면, 마운트 지점의 소스 커밋 ID가 브랜치의 새 HEAD로 갱신돼요. 그 결과 이전 커밋 ID와 연관된 캐시는 더 이상 사용되지 않고, 새 데이터는 새 커밋 ID 아래 캐시돼요.
캐시 크기 최적화
--cache-size를 읽거나 쓸 데이터 양에 맞춰 설정하세요. 더 큰 캐시는 파일 축출(eviction)과 재페칭을 줄여, 많은 파일에 접근하는 워크로드의 성능을 높여줘요.
일관성 & 데이터 동작
파일시스템 일관성
lakeFS Mount는 단일 마운트 지점 안에서 강력한 read-after-write 일관성을 제공해요. 쓰기 작업이 완료되면, 그 데이터가 같은 마운트의 이후 읽기 작업에서 사용 가능하다는 게 보장돼요.
lakeFS 일관성
로컬 변경은 everest commit 명령으로 커밋된 후에야 lakeFS에 반영돼요. 그 전까지는:
-
변경은 여러분의 로컬 마운트 지점 안에서만 보여요
-
다른 사용자나 마운트는 여러분의 변경을 볼 수 없어요
-
두 사용자가 같은 브랜치를 마운트하면, 변경이 커밋되기 전까지 서로의 변경을 볼 수 없어요
Sync 작업
everest diff나 everest commit을 실행하면 lakeFS Mount가 sync 작업을 수행해서 모든 로컬 변경을 lakeFS의 임시 위치로 업로드해 처리해요. 이 덕분에 변경이 브랜치에 커밋되기 전에 안전하게 전송돼요.
쓰기 가능한 마운트 작업에 대한 자세한 내용은 Write-Mode Operations 섹션을 참고하세요.
성능 고려사항
lakeFS Mount는 다음 방식으로 고성능 데이터 접근을 달성해요:
-
오브젝트 스토어 직접 접근: 기본적으로 lakeFS Mount는 pre-signed URL을 사용해 데이터 전송을 lakeFS 서버를 거치지 않고 기반 오브젝트 스토어와 직접 주고받아요. 메타데이터 작업만 lakeFS 서버를 통과해요.
-
지연 메타데이터 로딩: 디렉터 목록은 필요할 때 가져와요. 그래서 사전 비용 없이 수십억 개 파일이 담긴 저장소에서 작업할 수 있어요.
-
캐시 크기 설정: 적절한
--cache-size설정은 잦은 축출과 재페칭을 막아줘요. 경험칙으로는 워킹 세트(working set)를 담을 수 있게 캐시 크기를 정하세요. -
네트워크 대역폭: 데이터가 오브젝트 스토리지에서 직접 페치되므로, 네트워크 연결이 워크로드에 충분한 대역폭을 지니는지 확인하세요.
ML 워크로드 최적화
학습 잡에는 영구 캐시 디렉터(
--cache-dir)를 쓰고, 캐시 크기를 전체 데이터셋에 맞춰 보세요. 학습 에포크마다 반복 다운로드하는 일이 사라져요.
데이터 다루기 (로컬 마운트)
읽기 전용 작업
읽기 전용 모드가 기본이고, 데이터 탐색·분석·로컬 애플리케이션에 데이터 공급을 실수로 변경할 위험 없이 하기에 이상적이에요.
데이터가 캐시되고 접근되는 방식에 대한 정보는 Cache Behavior 섹션을 보세요.
데이터를 로컬에서 다루기
저장소를 마운트하고 좋아하는 도구를 데이터에 바로 쓰세요.
everest mount lakefs://image-repo/main/datasets/pets/ ./pets
# Run a python script
pytorch_train.py --input ./pets
# Query data with DuckDB
duckdb "SELECT * FROM read_parquet('pets/labels.parquet')"
everest umount ./pets
쓰기 모드 작업
쓰기 모드(--write-mode)를 활성화하면 파일을 로컬에서 수정·추가·삭제하고, 그 변경을 lakeFS 브랜치로 다시 커밋할 수 있어요. 쓰기 모드에서 실행할 때 lakeFS URI는 커밋 ID나 태그가 아니라 브랜치를 가리켜야 해요.
로컬에서 데이터를 변경하는 예제
- 쓰기 모드로 마운트:
--write-mode플래그로 쓰기를 활성화하세요.
everest mount lakefs://image-repo/main/datasets/pets/ ./pets --write-mode
- 파일 수정: 표준 셸 명령으로 필요한 변경을 하세요.
# Add a new file
echo "new data" > ./pets/birds/parrot/cute.jpg
# Update an existing file
echo "new data" >> ./pets/dogs/golden_retrievers/cute.jpg
# Delete a file
rm ./pets/cats/persian/cute.jpg
- 변경 검토:
diff명령은 마운트 시점의 브랜치 상태와 로컬 상태의 차이를 보여줘요.
everest diff ./pets
# Output:
# + added datasets/pets/birds/parrot/cute.jpg
# ~ modified datasets/pets/dogs/golden_retrievers/cute.jpg
# - removed datasets/pets/cats/persian/cute.jpg
- 변경 커밋:
commit명령은 로컬 변경을 업로드하고 lakeFS의 소스 브랜치에 커밋해요.
everest commit ./pets -m "Updated pet images"
커밋 후에는 로컬 마운트가 브랜치의 새 HEAD와 동기화돼요. diff를 다시 실행하면 변경이 없다고 나올 거예요.
- 끝나면 언마운트:
everest umount ./pets
쓰기 모드 제약
쓰기 모드는 지원되는 작업에 몇 가지 제약이 있어요. 지원되지 않는 작업과 변경된 동작에 대한 자세한 내용은 Write Mode Limitations를 참고하세요.
POSIX 권한
마운트는 lakeFS가 각 오브젝트에 기록해 둔 POSIX 파일 모드와 소유권을 제공할 수 있어요. 그래서 오브젝트가 lakeFS와 그것을 읽는 머신 사이를 오가는 동안 권한이 유지되죠. --include-perm으로 마운트를 실행하면 마운트된 트리의 모든 파일과 디렉터가 lakeFS 오브젝트에 저장된 모드를 사용하고, chmod는 그 모드를 바꾸며, 쓰기 모드 마운트는 다음 commit 때 변경을 lakeFS에 기록해요. --include-uid나 --include-gid를 추가하면 각 항목을 소유하는 사용자와 그룹에 대해서도 같은 일이 일어나요.
이 플래그 없이는 마운트가 고정 값을 제공해요. 모든 파일은 0666, 모든 디렉터는 0755로 보이고, 둘 다 마운트를 실행하는 사용자가 소유하며, chmod와 chown은 받아들여지지만 아무것도 바꾸지 않아요. --include-perm 아래에서도, 메타데이터에 자체 권한을 기록하지 않은 오브젝트에는 같은 고정 값이 대신 쓰여요. 권한을 저장하지 않는 클라이언트가 쓴 것은 모두 이 경우에 해당해요.
everest mount lakefs://image-repo/main/datasets/pets/ ./pets --write-mode \
--include-perm --include-uid --include-gid
기록된 권한 없이 도착한 오브젝트는 고정 기본값으로 시작하고, chmod는 즉시 적용되면서 커밋을 통과해서 살아남아요:
$ ls -l ./pets/labels.csv
-rw-rw-rw- 1 alice data 4096 Sep 14 10:22 ./pets/labels.csv
$ chmod 640 ./pets/labels.csv
$ ls -l ./pets/labels.csv
-rw-r----- 1 alice data 4096 Sep 14 10:22 ./pets/labels.csv
$ everest commit ./pets -m "Restrict labels.csv"
| 플래그 | 하는 일 |
|---|---|
| --include-perm | 고정 기본값 대신 오브젝트 메타데이터에 기록된 POSIX 파일 모드를 사용해요. |
| --include-uid | 고정 기본값 대신 기록된 UID를 각 항목의 소유자로 사용해요. --include-perm이 필요해요. |
| --include-gid | 고정 기본값 대신 기록된 GID를 각 항목의 그룹으로 사용해요. --include-perm이 필요해요. |
세 플래그 모두 읽기 전용 마운트에도 적용되며, 그 경우 각 항목이 표시되는 모드와 소유권을 결정해요. 변경을 lakeFS에 기록하려면 --write-mode가 필요해요.
Note
--include-perm은 Windows 마운트에 사용되는 CFAPI 프로토콜에서는 지원되지 않고, 둘을 결합한 마운트는 시작 시 실패해요.
권한이 저장되는 방식
권한은 오브젝트의 사용자 메타데이터에 ::lakefs::posix-permissions 키로 저장돼요. 그 값은 파일 모드와 소유 UID, GID를 함께 기록해요. 이는 lakectl local이 읽고 쓰는 것과 같은 키, 같은 형식이라서, 오브젝트가 로컬 디렉터로 체크아웃되든 마운트를 통해 쓰이든 모드와 소유권이 유지돼요.
디렉터 마커
--include-perm 아래에서 Mount는 디렉터 메타데이터를 저장하려고 디렉터 마커(directory marker) 오브젝트를 써요. 디렉터 경로 뒤에 /가 붙은 위치의 0바이트 오브젝트로, 메타데이터에 디렉터의 권한을 담고 있어요.
Note
디렉터 마커도 다른 오브젝트와 마찬가지의 오브젝트예요. 그래서 마커가 있는 디렉터는 그 아래 내용이 모두 삭제된 후에도 lakeFS에 계속 존재해요. 마커는 다른 오브젝트를 지우듯 지우면 돼요.
lakeFS Mount for Windows
lakeFS Mount는 Windows에서도, 읽기 전용 모드로 제공돼요.
Windows 운영체제에서의 lakeFS Mount 동작
CFAPI는 클라우드 스토리지에 최적화된 OS 관리 캐싱 시스템을 사용해요:
-
플레이스홀더 파일: 파일은 처음에 실제 콘텐츠 없이 메타데이터만 담은 스텁(stub)으로 나타나요
-
온디맨드 하이드레이션: 접근하면 파일이 "하이드레이션"돼요 — 콘텐츠가 lakeFS에서 페치돼요
-
로컬 캐시: 이후 읽기는 lakeFS까지 가지 않고 로컬 캐시에서 바로 제공돼요
-
전체 다운로드: 현재로서는 파일의 어느 부분에 접근하든 전체 다운로드가 트리거돼요
-
자동 축출: 스토리지 압박 상황에서 OS가 "디하이드레이션"(콘텐츠 비움)해요. 언마운트 후에는 모든 데이터가 삭제돼요
요구 사항
-
lakeFS Mount는 Windows의 네이티브 Cloud Filter API를 지원해요. 추가 설치가 필요 없어요.
-
CFAPI 지원은 Windows 10, 버전 1709부터 시작돼요.
-
lakeFS Mount 버전이
0.6.0보다 큰지 확인하세요
Microsoft 보호 설정의 스캔 건너뛰기(Windows Defender)
백신(AV)은 모든 파일 내용을 전부 스캔하려고 해요. 마운트된 경로에 대해 방화벽을 반드시 비활성화하세요. UI로 할 수도 있고, 관리자 사용자로 PowerShell에서 할 수도 있어요:
Add-MpPreference -ExclusionPath "Path\To\Mount-Dir"
제외 확인:
Get-MpPreference | Select-Object -ExpandProperty ExclusionPath
Windows 검색 인덱싱에서 마운트 디렉터 제외하기
Windows Search는 새로 생긴 파일들을 디렉터 구조를 재귀적으로 순회하며 자동으로 인덱싱하려고 해요. 대형 저장소에서는 시간이 오래 걸리고 성능에 영향을 줄 수 있어서, 마운트 디렉터를 인덱싱 대상에서 제외하는 걸 권장해요.
마운트 폴더를 제외하는 방법 (권장)
-
설정 > 개인 정보 및 보안 > Windows 검색 열기
-
"제외된 폴더" 아래에서 "제외 폴더 추가" 클릭
-
마운트 디렉터 선택 (예: C:\Users\me\mounted)
-
인덱서가 그 위치의 인덱싱을 시도하지 않게 돼요
Kubernetes에서의 lakeFS Mount (CSI 드라이버)
Private Preview
CSI 드라이버는 프라이빗 프리뷰 상태예요. 접근 권한은 문의하기를 이용하세요.
lakeFS CSI(Container Storage Interface) 드라이버는 Kubernetes Pod가 lakeFS 저장소의 데이터를 로컬 파일시스템처럼 마운트하고 상호작용하게 해줘요. 마운트는 로컬 머신에서와 마찬가지로 읽기 전용이거나 쓰기 가능할 수 있고, 드라이버는 노드의 권한 없는(unprivileged) Pod에서 볼륨별로 lakeFS 자격 증명을 읽어 이를 제공해요. ReadWriteMany 구성과 쓰기가 lakeFS에 도달하는 방식은 writable mount 예제를 보세요.
이 섹션의 내용:
-
How it Works - CSI 드라이버 아키텍처 이해하기
-
Status and Limitations - 지원 플랫폼과 현재 제약
-
Prerequisites - CSI 드라이버 배포 요건
-
Deploy the CSI Driver - Helm을 사용한 설치 안내
-
Authenticate to lakeFS - 자격 증명 소스 선택과 설정
-
Use in Pods - Kubernetes 워크로드에서 lakeFS URI 마운트하기
-
Troubleshooting - 흔한 문제와 디버깅 단계
동작 방식
드라이버에는 세 가지 움직이는 부품이 있어요. 컨트롤러 Deployment는 lakeFS 볼륨을 쓰는 워크로드 Pod를 감시하고, 같은 노드에 그들을 위한 Mount Pod를 스케줄하고, 어떤 워크로드가 어떤 Mount Pod에 붙었는지 클러스터 범위 커스텀 리소스에 기록해요. 노드 DaemonSet은 CSI 노드 서비스를 구현하고, 커널 FUSE 디바이스를 열고, 파일 디스크립터를 Unix 소켓으로 Mount Pod에 넘겨요. 그러면 Mount Pod는 everest-lakefs-csi 네임스페이스 안에서 권한 없는 비-루트 프로세스로 그 디스크립터에 대해 everest mount-server를 실행하고, 노드 컴포넌트는 그 결과를 요청한 각 워크로드 Pod에 bind mount해요.
Mount Pod는 공유되기 때문에, 노드에서 마운트당 FUSE 프로세스가 하나씩만 있으면 돼요(워크로드마다 하나가 아님). 두 워크로드는 마운트에 관한 모든 것이 일치할 때만 Mount Pod를 공유해요: 노드, PersistentVolume, 볼륨 ID, 마운트 옵션, 인증 소스, 워크로드의 fsGroup, 그리고 pod 인증 모드에서는 서비스 계정·네임스페이스·역할 ARN까지요. 마운트를 쓰는 마지막 워크로드가 사라지면 컨트롤러는 Mount Pod에 깔끔한 종료를 표시하고, 노드 컴포넌트는 볼륨을 언마운트하고 자신이 쓴 자격 증명 자료를 제거해요.
상태와 제약
-
Kubernetes: 버전
>=1.30.1.30과1.31에서는 드라이버의 커스텀 리소스가 필드 셀렉터 없이 설치되는데, 컨트롤러의 효율이 다소 떨어지지만 동작은 해요. -
노드: 커널 FUSE 디바이스(
/dev/fuse)를 노출하고 읽을 수 있는 kubelet 경로를 지닌 Linux 노드. everest는 노드가 아니라 드라이버 이미지 안에서 실행되므로 호스트 배포판은 영향 요인이 아니에요. Amazon Linux 2023, Bottlerocket, RHEL 계열 모두 동작해요. -
아키텍처:
linux/amd64, 그리고 차트1.3.0부터는linux/arm64. -
프로비저닝: 정적 프로비저닝만 지원해요.
-
액세스 모드: 읽기 전용 마운트는
ReadOnlyMany, 쓰기 가능 마운트는ReadWriteMany. -
쓰기: 쓰기는 Mount Pod에 스테이징되고, 마운트 디렉터에 대해
everest commit을 실행할 때만 lakeFS에 도착해요. 커밋은 숨겨진 임시(ephemeral) 브랜치로 업로드하고, 그것을 커밋한 다음, 결과를 소스 브랜치로 머지해요. 언마운트 때는 아무것도 동기화하거나 커밋하지 않고, 임시 브랜치는 마운트가 종료될 때 삭제되므로 커밋하지 않은 것은 사라져요. 스테이징된 쓰기는cache가 설정됐을 때 Mount Pod의 캐시 볼륨을, 아니면 컨테이너의 쓰기 가능 레이어를 차지하며,cacheEmptyDirSizeLimit이나 Pod의 임시 스토리지 예산에 포함되지만 everest의cache-size읽기 캐시에는 절대 포함되지 않아요. -
보안 컨텍스트: 드라이버가
allow_other로 마운트하므로, 워크로드 Pod는runAsUser를 포함해 자체securityContext를 설정할 수 있어요. 파일은root:root로 제공되므로 컨테이너가 보는 소유권은 마운트 옵션이 아니라 자기 보안 컨텍스트를 따라요. Mount Pod의 보안 컨텍스트는 드라이버가 관리하며 설정할 수 없어요.
필수 조건
-
lakeFS Cloud 계정 또는 lakeFS Enterprise 버전
1.25.0이상(lakeFS Mount의 필수 조건과 동일). -
Helm이 설치되고 클러스터 관리자 권한이 있는 Kubernetes 클러스터(
>=1.30). 차트가 네임스페이스, 우선순위 클래스, 클러스터 역할, 클러스터 범위 CRD를 만들기 때문이에요. -
클러스터 Pod에서 lakeFS 서버로의 네트워크 접근.
-
lakeFS 자격 증명 소스. lakeFS 액세스 키 페어 또는 AWS IAM 신원(Authenticate to lakeFS에서 설명).
CSI 드라이버 배포하기
드라이버는 Helm 차트로 배포돼요.
- lakeFS Helm 저장소 추가:
helm repo add lakefs https://charts.lakefs.io
helm repo update lakefs
차트가 사용 가능한지 확인하고 최신 버전을 보세요:
helm search repo lakefs/everest-lakefs-csi-driver
사용 가능한 모든 차트 버전을 보려면 `-l` 플래그를 쓰세요:
helm search repo lakefs/everest-lakefs-csi-driver -l
values.yaml설정:
values.yaml 예제
# Optional: only if you mirror the driver image to a registry that
# requires authentication. The public image needs no credentials.
# imagePullSecret:
# registry: https://index.docker.io/v1/
# username: <registry-user>
# token: <registry-token>
node:
# Logging verbosity (0-4 is normal, 5 is most verbose)
logLevel: 4
# Only set if your nodes use a non-standard kubelet directory
# kubeletPath: /var/lib/kubelet
mountpointPod:
# Namespace the driver creates and runs Mount Pods in
namespace: everest-lakefs-csi
- 차트 설치:
helm install everest-lakefs-csi-driver lakefs/everest-lakefs-csi-driver \
--namespace kube-system --version <chart-version>
이전 단계에서 values 파일을 만들었다면 명령에 `-f values.yaml`을 추가하세요.
- 롤아웃 확인:
kubectl rollout status daemonset/everest-lakefs-csi-node -n kube-system
kubectl get pods -n kube-system -l app=everest-lakefs-csi-node
lakeFS에 인증하기
각 볼륨은 authenticationSource 볼륨 속성으로 lakeFS 자격 증명의 출처를 선언해요. 그래서 같은 클러스터에서 서로 다른 저장소를 서로 다른 lakeFS 신원으로 마운트할 수 있어요. 속성을 비워 둔 볼륨은 driver로 폴백해요.
SecretAWS IAM (드라이버 또는 pod)
authenticationSource: secret은 PersistentVolume이 nodePublishSecretRef로 참조하는 Kubernetes Secret에서 lakeFS 액세스 키 페어를 읽어요. 이 Secret에는 lakeFS 엔드포인트도 담겨 있어서, 이 모드의 볼륨은 serverEndpointUrl 속성을 설정하지 않아요. 정확히 이 세 키를 담아야 하고, 키 페어는 AWS 키 페어가 아니라 Administration → Credentials에서 lakeFS가 발급한 것이어야 해요:
kubectl create secret generic lakefs-creds \
--namespace default \
--from-literal=access_key_id=<lakefs-key-id> \
--from-literal=secret_access_key=<lakefs-secret-key> \
--from-literal=server_endpoint_url=https://lakefs.example.com
authenticationSource: driver는 CSI 드라이버의 서비스 계정에 붙은 신원을, authenticationSource: pod는 여러분의 워크로드 Pod 서비스 계정에 붙은 신원을 사용해요. 둘 다 IRSA나 EKS Pod Identity를 통해서요. lakeFS는 AWS 신원을 외부 프린시펄로 검증하므로, IAM 역할에는 자체 S3 권한이 필요 없어요.
이 모드들은 lakeFS 서버에서 AWS IAM Role Login이 활성화되어 있고, auth.external_aws_auth.required_headers.X-LakeFS-Server-ID가 lakeFS 엔드포인트의 호스트 부분으로 설정되어 있어야 해요. 서버에는 iam_role_authentication이 포함된 lakeFS Enterprise 라이선스가 필요하고, 그렇지 않으면 external_aws_auth.enabled: true인 채로 시작을 거부해요. EKS Pod Identity를 쓰는 클러스터는 eks-pod-identity-agent 애드온이 설치되어 있어야 해요.
역할을 세션 이름 없이 역할 ARN으로 lakeFS 사용자에 붙이세요. IRSA와 EKS Pod Identity는 Pod마다 새 세션을 만들므로, 하나의 세션에 고정된 프린시펄은 단일 Pod만 승인하고 그 Pod가 재시작하는 순간 동작을 멈춰요:
lakectl auth users aws-iam attach --id <lakefs-user> \
--principal-id 'arn:aws:sts::<account>:assumed-role/<role>'
이 모드를 쓰는 모든 PersistentVolume은 serverEndpointUrl 볼륨 속성도 설정해야 해요. 그렇지 않으면 마운트가 InvalidArgument로 실패해요. Pod 모드는 STS 호출을 위한 AWS 리전이 추가로 필요하고, 드라이버는 그것을 stsRegion 볼륨 속성, 평범한 AWS 환경 변수, IMDS 순서로 찾으며, 어느 것도 결정되지 않으면 같은 방식으로 실패해요.
Pod에서 사용하기
드라이버를 사용하려면 lakeFS URI를 Pod에 마운트하는 PersistentVolume(PV)과 PersistentVolumeClaim(PVC)을 만들어요.
-
정적 프로비저닝: PV와 PVC 양쪽에
storageClassName: ""을 설정해야 해요. PVC가 특정 PV에 묶이게 하려면 PV 정의에claimRef를 써서 1:1 매핑을 만드세요. -
마운트 URI:
lakeFSMountUri볼륨 속성은 필수이고 저장소, ref, 선택적 경로를 가리켜요. 예:lakefs://my-repo/main/data/. -
볼륨 핸들: 각 PV에는 고유한
volumeHandle이 필요해요. Kubernetes는 핸들당 볼륨을 한 번만 처리하고, 중복은 Pod를ContainerCreating에 붙잡아 두거든요. -
액세스 모드:
ReadOnlyMany는 읽기 전용으로,ReadWriteMany는 읽기-쓰기로 마운트해요. PV, PVC, 또는 Pod의 볼륨에readOnly: true를 설정하면 액세스 모드가ReadWriteMany여도 강제로 읽기 전용이 되니, 쓰기를 원하면 비워 두세요. -
마운트 옵션:
mountOptions의 항목은 선행 대시가 제거된everest mount-server플래그예요. 예:cache-size 1500000000또는log-level debug. Command-Line Reference의everest mount-server아래에 전체 목록이 있어요. 드라이버가 대신 설정해 주는 플래그는 빼세요: 프로토콜, 리슨 주소, 캐시 디렉터, 자격 증명, 읽기 전용/쓰기 모드 선택. everest는 인식 못 하는 플래그를 만나면 종료되고, Mount Pod는 crash-loop에 빠져요. -
StatefulSet: 정적 프로비저닝은 볼륨을 요청에 따라 만들지 않으므로, StatefulSet은 레플리카마다 하나의
PersistentVolume을 사전에 준비해야 해요. 그 PVC들은 StatefulSet 자체보다 오래 살아남으므로 손으로 삭제해야 해요.
예제
다음 예제들은 다양한 Kubernetes 시나리오에서 lakeFS URI를 마운트하는 방법을 보여줘요. pod-identity 예제를 제외하고는 모두 Authenticate to lakeFS에서 만든 lakefs-creds Secret을 참조하고, 모두 default 네임스페이스에 오브젝트를 둬요.
Single Pod and MountWritable MountMultiple Pods, One Mount (Deployment)Multiple Mounts, Single PodPod-Level AWS IdentityNon-Root PodCaching
이 예제는 단일 lakeFS URI를 하나의 Pod에 읽기 전용으로 마운트해요.
apiVersion: v1
kind: PersistentVolume
metadata:
name: everest-pv
spec:
capacity:
storage: 100Gi # Required by Kubernetes, but ignored by lakeFS Mount
accessModes:
- ReadOnlyMany
storageClassName: "" # Required for static provisioning
claimRef:
namespace: default
name: everest-claim
csi:
driver: csi.everest.lakefs.io
volumeHandle: everest-csi-driver-volume-1 # Must be unique
nodePublishSecretRef:
name: lakefs-creds
namespace: default
volumeAttributes:
# Replace with your lakeFS mount URI
lakeFSMountUri: lakefs://<repo>/<ref>/<path>
authenticationSource: secret
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: everest-claim
namespace: default
spec:
accessModes:
- ReadOnlyMany
storageClassName: "" # Required for static provisioning
resources:
requests:
storage: 5Gi # Required by Kubernetes, but ignored by lakeFS Mount
volumeName: everest-pv
---
apiVersion: v1
kind: Pod
metadata:
name: everest-app
namespace: default
spec:
containers:
- name: app
image: rockylinux/rockylinux
command: ["/bin/sh", "-c", "ls /data/; tail -f /dev/null"]
volumeMounts:
- name: my-lakefs-data
mountPath: /data
volumes:
- name: my-lakefs-data
persistentVolumeClaim:
claimName: everest-claim
쓰기 가능한 마운트는 PV와 PVC 양쪽에서 ReadWriteMany를 사용하며, 추가 마운트 옵션이 필요 없어요.
Pod가 사라지기 전에 커밋하세요
쓰기는 워크로드 컨테이너 안에서 마운트 디렉터에 대해
everest commit을 실행할 때까지 Mount Pod에 머물러요. 그 커밋은 숨겨진 임시 브랜치로 업로드하고 그 브랜치를 소스 브랜치로 머지해요.lakectl commit과 lakeFS UI는 커밋이 실행되기 전까지 소스 브랜치에 변화가 없어서 이 쓰기를 영속화할 수 없어요. 언마운트는 동기화도 커밋도 하지 않고, 임시 브랜치는 마운트와 함께 삭제되므로 커밋되지 않은 쓰기는 사라져요. 이 명령을 실행하려면 워크로드 이미지에everest바이너리가 필요해요.
apiVersion: v1
kind: PersistentVolume
metadata:
name: everest-rw-pv
spec:
capacity:
storage: 100Gi
accessModes:
- ReadWriteMany # Writable mount
storageClassName: ""
claimRef:
namespace: default
name: everest-rw-claim
csi:
driver: csi.everest.lakefs.io
volumeHandle: everest-csi-driver-volume-2 # Must be unique
nodePublishSecretRef:
name: lakefs-creds
namespace: default
volumeAttributes:
lakeFSMountUri: lakefs://<repo>/<branch>/<path>
authenticationSource: secret
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: everest-rw-claim
namespace: default
spec:
accessModes:
- ReadWriteMany
storageClassName: ""
resources:
requests:
storage: 5Gi
volumeName: everest-rw-pv
---
apiVersion: v1
kind: Pod
metadata:
name: everest-rw-app
namespace: default
spec:
containers:
- name: app
image: rockylinux/rockylinux
command: ["/bin/sh", "-c", "echo hello > /data/hello.txt; cat /data/hello.txt; tail -f /dev/null"]
volumeMounts:
- name: my-lakefs-data
mountPath: /data
volumes:
- name: my-lakefs-data
persistentVolumeClaim:
claimName: everest-rw-claim
하나의 lakeFS 마운트를 레플리카들이 공유하는 Deployment예요. 같은 노드에 스케줄된 레플리카는 단일 Mount Pod를 공유하고, 다른 노드의 레플리카는 자기만의 Mount Pod를 얻어요.
apiVersion: v1
kind: PersistentVolume
metadata:
name: multiple-pods-one-pv
spec:
capacity:
storage: 100Gi
accessModes:
- ReadOnlyMany
storageClassName: ""
claimRef:
namespace: default
name: multiple-pods-one-claim
csi:
driver: csi.everest.lakefs.io
volumeHandle: everest-csi-driver-volume-3 # Must be unique
nodePublishSecretRef:
name: lakefs-creds
namespace: default
volumeAttributes:
lakeFSMountUri: lakefs://<repo>/<ref>/<path>
authenticationSource: secret
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: multiple-pods-one-claim
namespace: default
spec:
accessModes:
- ReadOnlyMany
storageClassName: ""
resources:
requests:
storage: 5Gi
volumeName: multiple-pods-one-pv
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: multi-pod-app
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: multi-pod-app
template:
metadata:
labels:
app: multi-pod-app
spec:
containers:
- name: app
image: rockylinux/rockylinux
command: ["/bin/sh", "-c", "ls /data/; tail -f /dev/null"]
volumeMounts:
- name: lakefs-storage
mountPath: /data
volumes:
- name: lakefs-storage
persistentVolumeClaim:
claimName: multiple-pods-one-claim
서로 다른 두 lakeFS URI를 서로 다른 두 경로에 마운트하는 단일 Pod예요. 각각 자체 PV, PVC, 고유한 volumeHandle을 가져요.
# PV 1
apiVersion: v1
kind: PersistentVolume
metadata:
name: multi-mount-pv-1
spec:
capacity:
storage: 100Gi
accessModes:
- ReadOnlyMany
storageClassName: ""
claimRef:
namespace: default
name: multi-mount-claim-1
csi:
driver: csi.everest.lakefs.io
volumeHandle: everest-csi-driver-volume-4 # Must be unique
nodePublishSecretRef:
name: lakefs-creds
namespace: default
volumeAttributes:
lakeFSMountUri: lakefs://<repo>/<ref>/<path1>
authenticationSource: secret
---
# PVC 1
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: multi-mount-claim-1
namespace: default
spec:
accessModes:
- ReadOnlyMany
storageClassName: ""
resources:
requests:
storage: 5Gi
volumeName: multi-mount-pv-1
---
# PV 2
apiVersion: v1
kind: PersistentVolume
metadata:
name: multi-mount-pv-2
spec:
capacity:
storage: 100Gi
accessModes:
- ReadOnlyMany
storageClassName: ""
claimRef:
namespace: default
name: multi-mount-claim-2
csi:
driver: csi.everest.lakefs.io
volumeHandle: everest-csi-driver-volume-5 # Must be unique
nodePublishSecretRef:
name: lakefs-creds
namespace: default
volumeAttributes:
lakeFSMountUri: lakefs://<repo>/<ref>/<path2>
authenticationSource: secret
---
# PVC 2
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: multi-mount-claim-2
namespace: default
spec:
accessModes:
- ReadOnlyMany
storageClassName: ""
resources:
requests:
storage: 5Gi
volumeName: multi-mount-pv-2
---
# Pod
apiVersion: v1
kind: Pod
metadata:
name: multi-mount-pod
namespace: default
spec:
containers:
- name: app
image: rockylinux/rockylinux
command: ["/bin/sh", "-c", "echo 'Path 1:'; ls /data1; echo 'Path 2:'; ls /data2; tail -f /dev/null"]
volumeMounts:
- name: lakefs-data-1
mountPath: /data1
- name: lakefs-data-2
mountPath: /data2
volumes:
- name: lakefs-data-1
persistentVolumeClaim:
claimName: multi-mount-claim-1
- name: lakefs-data-2
persistentVolumeClaim:
claimName: multi-mount-claim-2
Secret 대신 워크로드 자신의 AWS 신원으로 인증하는 마운트예요. PV에는 nodePublishSecretRef가 없고, 리전을 환경에서 결정할 수 없을 때는 serverEndpointUrl과 stsRegion이 필요해요. serverEndpointUrl의 호스트는 lakeFS 서버가 요구하는 X-LakeFS-Server-ID 헤더와 일치해야 하고, Pod의 서비스 계정 역할은 Authenticate to lakeFS에서 설명한 대로 lakeFS 사용자에 붙어 있어야 해요.
apiVersion: v1
kind: ServiceAccount
metadata:
name: lakefs-app-sa
namespace: default
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::<account>:role/<role>
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: everest-pod-identity-pv
spec:
capacity:
storage: 100Gi
accessModes:
- ReadOnlyMany
storageClassName: ""
claimRef:
namespace: default
name: everest-pod-identity-claim
csi:
driver: csi.everest.lakefs.io
volumeHandle: everest-csi-driver-volume-7 # Must be unique
volumeAttributes:
lakeFSMountUri: lakefs://<repo>/<ref>/<path>
authenticationSource: pod
serverEndpointUrl: https://lakefs.example.com
stsRegion: us-east-1
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: everest-pod-identity-claim
namespace: default
spec:
accessModes:
- ReadOnlyMany
storageClassName: ""
resources:
requests:
storage: 5Gi
volumeName: everest-pod-identity-pv
---
apiVersion: v1
kind: Pod
metadata:
name: everest-pod-identity-app
namespace: default
spec:
serviceAccountName: lakefs-app-sa
containers:
- name: app
image: rockylinux/rockylinux
command: ["/bin/sh", "-c", "ls /data/; tail -f /dev/null"]
volumeMounts:
- name: my-lakefs-data
mountPath: /data
volumes:
- name: my-lakefs-data
persistentVolumeClaim:
claimName: everest-pod-identity-claim
워크로드 Pod는 비-루트 사용자로 실행될 수 있어요. everest는 마운트된 파일을 root:root로 제공하고 드라이버가 allow_other로 마운트하므로, 컨테이너가 보는 소유권은 자기 securityContext를 따라요. fsGroup은 Mount Pod 공유 키의 일부라서, 이를 설정한 Pod는 마운트의 다른 모든 요소가 일치하더라도 이를 생략한 워크로드와는 Mount Pod를 공유하지 않는다는 점에 유의하세요.
apiVersion: v1
kind: Pod
metadata:
name: everest-non-root-app
namespace: default
spec:
securityContext:
runAsUser: 1000
runAsGroup: 2000
fsGroup: 2000
containers:
- name: app
image: rockylinux/rockylinux
command: ["/bin/sh", "-c", "id; ls -la /data/; tail -f /dev/null"]
volumeMounts:
- name: my-lakefs-data
mountPath: /data
volumes:
- name: my-lakefs-data
persistentVolumeClaim:
claimName: everest-claim
모든 마운트는 캐싱해요. 아래 볼륨 속성들이 캐시의 위치와 볼륨이 얼마나 커질 수 있는지를 결정해요. cache-size 마운트 옵션은 everest가 그 공간을 얼마나 채울지를 결정하구요. cache 속성을 설정하지 않은 PV도 여전히 캐싱하는데, Mount Pod 자체의 임시 스토리지에, 어떤 한계도 없이요.
cache-size는 cacheEmptyDirSizeLimit 아래로 두세요. everest는 첫 번째 한계에 도달하면 캐시된 청크를 축출하고, Kubernetes는 볼륨이 두 번째 한계에 도달하면 Mount Pod 전체를 축출해요. 쓰기 가능한 마운트에서는 스테이징된 쓰기가 그 둘 사이의 간격을 채워요.
apiVersion: v1
kind: PersistentVolume
metadata:
name: options-demo-pv
spec:
capacity:
storage: 100Gi # ignored, required
accessModes:
- ReadOnlyMany
storageClassName: ""
mountOptions:
# cap everest's read cache, below the volume limit set further down
- cache-size 1500000000
- log-level debug
csi:
driver: csi.everest.lakefs.io
volumeHandle: everest-csi-driver-volume-6 # Must be unique
nodePublishSecretRef:
name: lakefs-creds
namespace: default
volumeAttributes:
lakeFSMountUri: lakefs://<repo>/<ref>/<path>
authenticationSource: secret
# Local data cache backed by an emptyDir volume on the node
cache: emptyDir
cacheEmptyDirSizeLimit: 2Gi
# Optional: back the cache with a tmpfs ramdisk instead of node storage
# cacheEmptyDirMedium: Memory
# Alternative: back the cache with a generic ephemeral volume instead
# of an emptyDir. Both attributes are required with this cache type.
# cache: ephemeral
# cacheEphemeralStorageClassName: gp2
# cacheEphemeralStorageResourceRequest: 2Gi
# Optional: size the Mount Pod for heavy workloads
# mountpointContainerResourcesRequestsMemory: 1Gi
---
# PVC and Pod definitions follow...
문제 해결
마운트 실패는 워크로드 Pod에서 먼저 드러나고, 상세 오류는 대응하는 Mount Pod가 갖고 있으니 그 순서로 진행하세요.
- 워크로드 Pod,
PV,PVC의 이벤트와 상태를 확인하세요:
kubectl describe pod <workload-pod> -n <namespace>
kubectl get pv,pvc
- 볼륨을 서빙하는 Mount Pod를 찾아 로그를 읽으세요:
kubectl get pods -n everest-lakefs-csi
kubectl logs <mount-pod> -n everest-lakefs-csi
- Mount Pod가 아예 만들어지지 않았다면 드라이버 구성요소를 확인하세요:
kubectl logs -n kube-system -l app=everest-lakefs-csi-node
kubectl logs -n kube-system -l app=everest-lakefs-csi-controller
- 컨트롤러가 만든 마운트 할당을 검토하면 어떤 워크로드가 어떤 Mount Pod에 묶였는지 알 수 있어요:
kubectl get mountpoints3podattachments # or: kubectl get s3pa
흔한 실패와 의미:
-
**
Secret is missing required key(s)**는 Secret의 키 오탈자를, **authenticationSource: secret requires a K8s Secret referenced via the PV's nodePublishSecretRef**는 PV에nodePublishSecretRef가 아예 없다는 뜻이에요. 세 키는 정확히access_key_id,secret_access_key,server_endpoint_url이에요. -
lakeFS가 돌려준 **
could not find access key**는 키가 lakeFS 발급이 아니라는 뜻이에요. lakeFS UI의 Administration → Credentials에서 생성하세요. -
lakeFS 볼륨 여럿을 쓰는 워크로드 Pod가
ContainerCreating에 멈춤은 보통 두 PV가 같은volumeHandle을 공유한다는 뜻이에요. Kubernetes는 핸들당 한 번만 처리하거든요. -
Mount Pod가
Pending에 멈춤은 보통 노드에서의 스케줄링 문제(테인트, 노드 셀렉터, 용량 부족 등)이고,kubectl describe pod <mount-pod> -n everest-lakefs-csi가 이유를 알려줘요. -
**
driver name csi.everest.lakefs.io not found in the list of registered CSI drivers**는 새 노드에서 드라이버가 kubelet에 등록을 마치기 전에 워크로드가 스케줄됐다는 뜻이에요. 노드를csi.everest.lakefs.io/agent-not-ready:NoExecute로 테인트하세요. 드라이버가 준비되면 테인트를 제거해요.
명령줄 레퍼런스
이 섹션은 lakeFS Mount CLI의 모든 명령에 대한 상세 문서를 제공해요. lakeFS Mount의 동작 방식에 대한 개념적 정보는 Core Concepts 섹션을 보세요.
everest mount
lakeFS URI를 로컬 디렉터로 마운트해요.
everest mount <lakefs_uri> <mount_directory> [flags]
팁:
-
서버는 백그라운드에서 실행되므로, 로그를 보려면
--log-output /path/to/file을 사용하세요. -
최적 캐시 크기는 여러분이 읽고 쓸 데이터의 크기예요.
-
같은 마운트의 재시작 사이에 캐시를 재사용하려면
--cache-dir플래그를 설정하세요. -
읽기 전용 모드에서 브랜치나 태그를 지정하면 lakeFS Mount는 HEAD 커밋을 해석해 마운트해요. 안정적인 마운트를 원하면 URI에 특정 커밋 ID를 사용하세요.
플래그:
-
--write-mode: 쓰기 모드 활성화(기본값:false). -
--cache-dir: 파일을 캐시할 디렉터. -
--cache-size: 로컬 캐시 크기(바이트). -
--cache-create-provided-dir:cache-dir이 제공됐는데 존재하지 않으면 생성. -
--listen: 마운트 서버가 리슨할 주소. -
--no-spawn: 새 서버를 띄우지 않고 이미 실행 중이라고 가정. -
--protocol: 사용할 프로토콜(기본값:nfs), Windows에서는 --cfapi 사용. -
--log-level: 로깅 레벨 설정. -
--log-format: 로깅 출력 형식 설정. -
--log-output: 로깅 출력 대상 설정. -
--presign: 오브젝트 스토어 직접 접근에 pre-signed URL 사용(기본값:true). -
--include-perm: 고정 기본값 대신 오브젝트 메타데이터에 기록된 POSIX 파일 모드 사용(기본값:false).--protocol=cfapi와 함께 사용 불가. POSIX Permissions 참고. -
--include-uid: 고정 기본값 대신 기록된 UID 사용.--include-perm필요. -
--include-gid: 고정 기본값 대신 기록된 GID 사용.--include-perm필요.
everest umount
lakeFS 디렉터를 언마운트해요.
everest umount <mount_directory>
everest diff (쓰기 모드 전용)
로컬 마운트 디렉터와 소스 브랜치의 차이를 보여줘요.
everest diff [mount_directory]
everest commit (쓰기 모드 전용)
로컬 변경을 소스 lakeFS 브랜치에 커밋해요. 새 커밋은 source-wins 전략으로 원본 브랜치에 머지돼요. 커밋이 성공하면 마운트된 디렉터의 소스 커밋이 브랜치의 새 HEAD로 갱신돼요.
Warning
커밋 작업 중에 마운트 디렉터에 수행한 쓰기는 유실될 수 있어요.
everest commit [mount_directory] -m <commit_message>
everest mount-server (고급)
OS 수준 마운트를 수행하지 않고 마운트 서버를 시작해요. 서버 프로세스와 OS 마운트 명령을 따로 관리하고 싶은 고급 사용 사례를 위한 거예요.
everest mount-server <remote_mount_uri> [flags]
플래그:
-
--cache-dir: 읽은 파일과 메타데이터를 캐시할 디렉터. -
--cache-create-provided-dir: 캐시 디렉터가 없으면 생성. -
--listen: 리슨할 주소. -
--protocol: 사용할 프로토콜(nfs | fuse | cfapi). -
--callback-addr: 보고할 콜백 주소. -
--log-level: 로깅 레벨 설정. -
--log-format: 로깅 출력 형식 설정. -
--log-output: 로깅 출력 대상 설정. -
--cache-size: 로컬 캐시 크기(바이트). -
--parallelism: 메타데이터 병렬 다운로드 수. -
--presign: 다운로드에 presign 사용. -
--write-mode: 쓰기 모드 활성화(기본값: false). -
--root: 파일시스템에 마운트할 디렉터(Windows 전용) -
--include-perm,--include-uid,--include-gid:everest mount에서 설명한 것과 동일.
고급 주제
쓰기 모드 제약
Windows 지원
현재 lakeFS Mount for Windows는 읽기 모드 작업만 지원해요
쓰기 모드(--write-mode)를 사용할 때는 다음 제약과 변경된 동작에 유의하세요. 쓰기 모드 작업에 대한 자세한 내용은 Write-Mode Operations 섹션을 보세요.
지원되지 않는 작업
-
이름 바꾸기(Rename): 파일과 디렉터 이름 바꾸기 작업은 지원되지 않아요.
-
임시 파일: 임시 파일은 지원되지 않아요.
-
하드/심볼릭 링크: 하드 링크와 심볼릭 링크는 지원되지 않아요.
-
POSIX 파일 잠금: POSIX 파일 잠금(
lockf)은 지원되지 않아요. -
POSIX 권한: 마운트가
--include-perm으로 실행되지 않는 한 파일과 디렉터에 기본 권한이 부여돼요. POSIX Permissions를 참고하세요.
변경된 동작
-
메타데이터 작업: 파일 메타데이터 수정(
chmod,chown,chgrp, 시간 속성)은 no-op으로 처리돼요. 단,--include-perm아래의chmod와--include-uid/--include-gid아래의chown/chgrp는 예외예요. POSIX Permissions를 참고하세요. -
디렉터 삭제: 디렉터에
remove를 호출하는 것은 지원되지 않아요. 대신 적절한 디렉터 삭제 명령(예:rm -r)을 사용하고, 다음 커밋에서 디렉터가 삭제돼요.
기능 제약
-
빈 디렉터: 새로 만든 빈 디렉터는 lakeFS에서 디렉터 마커로 반영되지 않아요. 단, 마운트가
--include-perm으로 실행되면 커밋이 건드리는 모든 디렉터에 디렉터 마커를 써요. -
경로 충돌: lakeFS는 한 경로 키가 다른 키의 "디렉터" 프리픽스인 경우를 허용해요(예:
animals/cat.png와 빈 오브젝트로서의animals둘 다 lakeFS에서 유효). 하지만 파일시스템은 같은 이름의 파일과 디렉터를 동시에 담을 수 없어서, 파일시스템 종류에 따라 정의되지 않은 동작으로 이어질 수 있어요.
Git과의 통합
lakeFS 경로를 Git 저장소 안에 마운트하는 것은 안전해요. lakeFS Mount는 마운트 디렉터에 가상 .gitignore 파일을 자동으로 만들어요. 이 파일은 Git에게 마운트된 모든 내용을 무시하되, 단 하나의 파일 — .everest/source — 만은 예외로 두라고 지시해요.
lakefs:// URI를 담고 있는 .everest/source 파일을 커밋하면, 여러분의 Git 저장소를 클론하고 lakeFS Mount를 사용하는 누구나 정확히 같은 버전의 데이터를 마운트하게 돼요. 프로젝트가 완전히 재현 가능해지는 거죠.
재현 가능한 데이터 사이언스 프로젝트
이 기능은 코드(Git)와 데이터(lakeFS)를 둘 다 버전 관리하고 싶은 데이터 사이언스 프로젝트에 특히 유용해요. 팀원들이 저장소를 클론하면 올바른 데이터 버전이 자동으로 마운트돼요.
FAQ
데이터 접근은 어떻게 동작하나요? lakeFS 서버를 스트리밍하나요?
아니요. 기본값(--presign=true)에서 lakeFS Mount는 pre-signed URL을 사용해 기반 오브젝트 스토어와 데이터를 직접 읽고 써서 고성능을 보장해요. 메타데이터 작업만 lakeFS 서버를 통과해요.
자세한 내용은 Performance Considerations를 참고하세요.
마운트한 뒤 lakeFS 브랜치가 업데이트되면 어떻게 되나요?
읽기 전용 모드에서 마운트는 마운트 시점에 브랜치 HEAD였던 커밋을 가리켜요. 그 브랜치에 이후 커밋되는 내용은 언마운트 후 재마운트하기 전까지 반영되지 않아요. 쓰기 모드에서는 commit이 성공한 후 마운트가 브랜치의 새 HEAD로 갱신돼요.
파일은 언제 다운로드되나요?
lakeFS Mount는 지연 페칭 전략을 사용해요. 파일은 콘텐츠에 접근할 때만(cat, open, 스크립트에서 읽기 등) 다운로드돼요. ls 같은 메타데이터 전용 작업은 다운로드를 트리거하지 않아요.
다운로드된 파일은 성능을 위해 로컬에 캐시돼요. 캐싱 동작과 설정 방법은 Cache Behavior를 참고하세요.
마운트에 필요한 RBAC 권한은 무엇인가요?
lakeFS의 Role-Based Access Control로 접근을 관리할 수 있어요.
최소 읽기 전용 권한:
{
"id": "MountReadOnlyPolicy",
"statement": [
{
"action": ["fs:ReadObject"],
"effect": "allow",
"resource": "arn:lakefs:fs:::repository/<repo>/object/<prefix>/*"
},
{
"action": ["fs:ListObjects", "fs:ReadCommit", "fs:ReadBranch", "fs:ReadTag", "fs:ReadRepository"],
"effect": "allow",
"resource": "arn:lakefs:fs:::repository/<repo>"
},
{ "action": ["fs:ReadConfig"], "effect": "allow", "resource": "*" }
]
}
최소 쓰기 모드 권한:
{
"id": "MountWritePolicy",
"statement": [
{
"action": ["fs:ReadObject", "fs:WriteObject", "fs:DeleteObject"],
"effect": "allow",
"resource": "arn:lakefs:fs:::repository/<repo>/object/<prefix>/*"
},
{
"action": [
"fs:ListObjects", "fs:ReadCommit", "fs:ReadBranch", "fs:ReadRepository",
"fs:CreateCommit", "fs:CreateBranch", "fs:DeleteBranch", "fs:RevertBranch"
],
"effect": "allow",
"resource": "arn:lakefs:fs:::repository/<repo>"
},
{ "action": ["fs:ReadConfig"], "effect": "allow", "resource": "*" }
]
}
lakectl local 대신 lakeFS Mount를 쓰는 이유는?
두 도구 모두 로컬 데이터로 동작하지만, 서로 다른 필요를 채워요. 디렉터 전체를 pull하고 push해야 하는 Git 스타일 워크플로에는 lakectl local을 쓰세요. 먼저 다운로드하지 않고도 대형 저장소에 즉시, 온디맨드로 접근해야 할 때는 lakeFS Mount를 쓰세요. 탐색이나 ML 모델 학습처럼 지연 로딩의 이점을 받는 작업에 이상적이에요.
더 알아보기 (Learn more)
공식 문서의 자세한 내용은 https://docs.lakefs.io/mount/에서 확인하실 수 있어요.