systemd-nspawn으로 컨테이너를 사용한다면 컨테이너 안으로 파일을 복사하거나 호스트로 가져와야 할 일이 생길 것이다. 컨테이너마다 ssh를 설치해서 sftp를 통해 접근하는 방법도 있지만 보안 상의 이유로 ssh를 설치하지 않았거나 네트워크로 접근할 수 없을 때는 사용할 수 없다.
systemd 패키지에 들어있는 machinectl 명령을 사용하면 쉽게 파일을 보내고 가져올 수 있다. 여기서는 machinectl의 copy-to, copy-from 명령을 사용한다.
먼저 호스트에서 컨테이너로 파일을 보내는 방법은 아래와 같다:
# machinectl copy-to <컨테이너 이름> <호스트의 파일 경로> <컨테이너의 파일 경로>
제대로 실행했다면 호스트의 파일이 컨테이너의 파일 경로로 복사되었을 것이다. 여기서 중요한건 컨테이너의 파일 경로는 절대경로를 사용해야 한다는 점이다. 참고로 마지막 인자인 컨테이너 파일 경로를 생략하면 현재 호스트 상의 경로와 동일한 위치에 복사한다.
컨테이너에서 호스트로 가져오는 방법은 아래와 같다:
# machinectl copy-from <컨테이너 이름> <컨테이너의 파일 경로> <호스트의 파일 경로>
여기서도 컨테이너의 파일 경로는 절대경로를 사용해야한다.
machinectl이 조금 고지식해서 목적지 경로가 /로 끝나면 cp처럼 알아서 이름을 그대로 써서 복사하지 않고 에러가 난다. 꼭 경로를 명확하게 적어줘야 한다.
그냥 컨테이너의 디렉토리에 바로 파일을 복사해버리면 되지 않느냐는 생각을 하는 사람도 있을 것이다. 하지만 이렇게되면 소유자가 꼬이는 문제가 발생할 수 있다. 보통 systemd-nspawn 컨테이너는 --private-users 옵션으로 인해 그 컨테이너 안에서 쓰이는 UID와 GID가 호스트의 임의의 범위에 매핑된다. 컨테이너 속에서 UID 0인 root가 실제로는 다른 번호로 할당되어 있다는 뜻이다. 이 상태로 호스트에서 root 권한으로 컨테이너 디렉토리에 파일을 그대로 복사해버리면 파일시스템에서는 소유권이 UID,GID가 0인 호스트의 root로 되고 컨테이너 안에서는 매핑이 되지 않는 숫자라 권한이 없어 삭제도 못한다.