여러 노드에서 같은 계정이 서로 다른 UID 를 갖고 있으면 NFS 공유 홈이나 컨테이너 볼륨에서 권한이 어긋난다. 파일시스템은 이름이 아니라 숫자 UID 로 소유자를 기록하기 때문이다. 이를 맞추려면 UID 를 바꾸고 기존 파일의 소유자까지 같이 옮겨야 한다. 명령 하나로 끝나지 않는다.
id appuser
getent passwd appuser
getent group appgroup
# 바꾸려는 UID 가 이미 쓰이고 있지 않은지
getent passwd 2001
해당 계정으로 도는 프로세스가 있으면 바꿀 수 없다. 로그인 세션과 서비스를 모두 내린다.
ps -u appuser
sudo systemctl stop myapp
sudo pkill -u appuser
sudo loginctl terminate-user appuser
OLD_UID=1001
NEW_UID=2001
# 1. UID 변경. 홈 디렉터리 아래는 usermod 가 알아서 바꾼다
sudo usermod -u "${NEW_UID}" appuser
# 2. GID 도 바꿔야 한다면 그룹부터
sudo groupmod -g 2001 appgroup
# 3. 홈 밖에 남아 있는 옛 UID 소유 파일을 찾아 옮긴다
sudo find / -xdev -uid "${OLD_UID}" -exec chown -h "${NEW_UID}" {} +
sudo find / -xdev -gid 1001 -exec chgrp -h 2001 {} +
-xdev 는 다른 파일시스템으로 내려가지 않게 한다. 이것이 없으면 NFS 마운트나 원격 스토리지까지 따라 들어가 엉뚱한 서버의 파일 소유자를 바꾼다. 마운트된 볼륨이 여러 개면 각각에 대해 따로 돌린다.
-h 는 심볼릭 링크 자체의 소유자를 바꾼다. 링크를 따라가 대상을 바꾸지 않는다.
-exec ... + 는 여러 경로를 한 번에 넘겨 \; 보다 훨씬 빠르다.
id appuser
sudo find / -xdev -uid "${OLD_UID}" -print | head
ls -ln /home/appuser | head
ls -ln 은 이름 대신 숫자로 보여 주므로 남은 항목을 찾기 쉽다.
| 환경 | 주의 |
|---|---|
| NFS 홈 디렉터리 | 서버 쪽 파일 소유자도 같이 바꿔야 한다. 클라이언트에서만 바꾸면 접근이 막힌다 |
| LDAP · SSSD | UID 는 디렉터리 서버가 준다. 로컬 usermod 는 무의미하며 디렉터리에서 고친다 |
| 컨테이너 볼륨 | 이미지 안의 UID 와 호스트 UID 가 맞지 않으면 여전히 깨진다 |
| systemd 사용자 세션 | /run/user/<uid> 가 옛 번호로 남는다. 재로그인하거나 재부팅한다 |
| cron · at 작업 | 소유자 기준으로 동작하므로 목록을 확인한다 |
작업 후에는 재부팅해 서비스가 정상 기동하는지 확인하는 편이 안전하다.