공식 Jupyter 이미지(jupyter/base-notebook 계열)를 올리면 기동 로그에 경고가 찍히고, 노트북에서 파일을 저장할 수 없다.
Running hooks in: /usr/local/bin/start-notebook.d as uid: 1000 gid: 100
WARNING: no write access to /home/jovyan.
Try starting the container with group 'users' (100), e.g. using "--group-add=users".
이 이미지들은 jovyan 이라는 계정으로 도는데 UID 는 1000, 주 GID 는 100(users) 이다. 컨테이너 안의 /home/jovyan 에 호스트 디렉터리나 PVC 를 마운트하면, 그 볼륨의 소유자와 권한이 그대로 보인다. 호스트에서 root 소유로 만들어 둔 디렉터리라면 UID 1000 은 쓸 수 없다.
경고 문구가 --group-add=users 를 제안하는 이유는, 볼륨이 GID 100 그룹에 쓰기 권한을 주고 있는 경우가 흔하기 때문이다. 근본 해결은 아니다.
mkdir -p /srv/jupyter/work
chown -R 1000:100 /srv/jupyter/work
chmod -R 775 /srv/jupyter/work
docker-compose 예시는 다음과 같다.
services:
notebook:
image: quay.io/jupyter/base-notebook:latest
user: "1000:100"
volumes:
- /srv/jupyter/work:/home/jovyan/work
ports:
- "8888:8888"
작업 파일은 /home/jovyan 전체가 아니라 /home/jovyan/work 에 마운트하는 편이 낫다. 홈 전체를 덮으면 이미지가 미리 넣어 둔 설정과 커널 등록 파일이 가려진다.
볼륨이 GID 100 에 쓰기를 허용한다면 이것만으로 풀린다.
services:
notebook:
image: quay.io/jupyter/base-notebook:latest
group_add:
- "100"
이미지에는 시작 시점에 계정을 바꾸는 환경변수가 있다. 호스트 쪽 UID 를 고칠 수 없을 때 쓴다.
environment:
NB_UID: "1001"
NB_GID: "100"
CHOWN_HOME: "yes"
CHOWN_HOME_OPTS: "-R"
user: root
NB_UID 를 바꾸려면 컨테이너가 root 로 시작해야 한다. 시작 스크립트가 계정을 고친 뒤 스스로 권한을 내려놓는다. CHOWN_HOME 은 홈 전체의 소유자를 바꾸므로 파일이 많으면 기동이 느려진다.
fsGroup 을 주면 kubelet 이 볼륨의 그룹 소유자를 바꿔 준다.
spec:
securityContext:
runAsUser: 1000
runAsGroup: 100
fsGroup: 100
fsGroup 은 블록 볼륨과 대부분의 CSI 볼륨에는 먹지만, NFS 처럼 서버가 권한을 정하는 볼륨에는 적용되지 않는다. 이 경우 NFS export 쪽에서 소유자를 맞춘다.
JupyterHub 헬름 차트를 쓴다면 singleuser.storage 와 singleuser.uid · singleuser.fsGid 값을 함께 맞춘다.
docker exec -it notebook id
docker exec -it notebook touch /home/jovyan/work/.probe && echo ok
jupyter/* 에서 quay.io/jupyter/* 로 옮겨졌다. 새로 구성한다면 새 경로를 쓴다.user: root 로 계속 돌리는 것은 피한다. 노트북에서 실행하는 코드가 그대로 root 권한을 갖는다.