[컴] rootless Podman 를 ‘sudo’, ‘su’ 로 사용하면 안되는 이유

 

rootless Podman 를 ‘sudo’, ‘su’ 로 사용하면 안되는 이유

ref.1 의 내용을 정리했다.

문제상황

  • 만약 user1 로 만들어진 podman container가 있다.
  • 이 상황에서 su user1으로 들어가서 image를 다시 build하면 error 가 난다.
    Error: error creating tmpdir: mkdir /run/user/1000: permission denied

podman이 temporary files directory

  • 이 디렉토리는 2가지 용도로 사용
    • directory 를 sentinel file 을 저장해서 restart 를 감지하는데 쓰고,
    • container가 재시작할 때 다시 생성되는 container content 를 저장, 예를 들면, /etc/resolv.conf
  • 그래서 podman 이 시작된 후에 이 directory 를 바꾸는 것은 심각한 문제를 일으킬 수 있다.

podman 이 restart 를 감지해야 하는 이유

재부팅되면, podman 은 refreshing the state 를 해야한다.

  • 재부팅이 되면
    • 모든 container들은 더 이상 running 하지 않는다.
    • 모든 container filesystem들은 unmount된다.
    • 모든 network interface들은 새롭게 만들어질 필요가 있다.
  • podman은 이것들을 반영하기 위해서 podman database를 update할 필요가 있다.
  • 그리고 container를 launch 할 준비가 됐다고 확신시켜주기 위한 per-boot setup 을 할 필요가 있다.
  • 이것을 ’refreshing the state’라고 한다.

‘refreshing the state’

다음의 동작을 ‘refreshing the state’ 라고 부른다.

  • podman은 reboot 될 때의 상태를 podman database에 update할 필요가 있다.
  • 그리고 container를 launch 할 준비가 됐다고 확신시켜주기 위해 per-boot setup 을 할 필요가 있다.

필요한 이유:

  • 이것은 podman 은 deamon 이 아니기 때문에 필요하다.(즉, podman이 항상 떠 있지 않아서?)
  • 각각의 podman command 는 새로운 process로 실행된다. 처음에 container들이 어떤 상태인지 모르는 상태로 실행된다.
  • 그래서 database를 보고, 모든 container의 정확한 현재 모습과 상태들을 알 수 있다.
  • 이 그림이 계속 정확하게 유지되기 위해서, reboot후에 ‘refreshing the state’ 는 필수다.

history

  • refresh 를 수행하려면, system이 reboot 됐는지를 알 수 있는 방법이 필요하다.
  • 개발초기, Podman team 은 tmpfs filesystem 에서 보초병 파일(sentinel file)을 만들어 사용하기로 정했다.
  • 이것은 in-memory filesystem 이다. 그래서 reboot 하면 이전 정보가 사라진다.
  • Podman 은 이 tmpfs 에 file 이 존재하는지 여부를 보고, 없으면 file을 만드는 것을 통해, 이 system reboot 이후 처음인지 여부를 알 수 있다.
  • 문제는 어디에 temporary files directory 를 넣어야 하는가를 결정하는 것이다.
  • 명확한 답은 /tmp 이다. 하지만 /tmp가 항상 tmpfs filesystem 이 라는 법은 없다.
  • 대신에, 기본적으로, Podman 은 /run을 이용한다. 이곳은 tmpfs 라는 것이 보장된다.
  • 다만 /run은 root 에 의해서만 write 이 가능하다.
  • 그래서 rootless podman 은 다른 곳을 찾았다. 그곳이 /run/user/$uid 이다. (/run/user/$uid 에 대한 이야기는 ref.2 를 참고)
  • 이 directory 가 만들어지려면, PAM 설정이 필요하다.(ref. 2 에 따르면 이 폴더는 pam_systemd에서 만든다.)
  • Rootless Podman 은 만약 시스템들이 이 directory 를 지원하지 않으면, /tmp를 사용하게 된다.
  • 물론 이것도 /tmp 가 tmpfs 가 아닐 가능성은 있지만, 더 나은 방법이 없다.

long-running container 사용할때

  • 이 디렉토리는 user session 이 만들어질때 만들어지고, user session 이 사라질때 자동으로 지워진다.
  • 이 때 문제는 user session 으로 들어와서 podman 을 실행하고, logout 을 해버리면, run/user/$uid가 사라지고, 이것은 Podman 이 refresh the state 를 하고, 현재 running 하고 있는 container들이 running 하지 않다고 표시하게 된다.
  • 그래서 logind-managed system에서는 persistent user session 을 만들 수 있는 option 이 있다.(login enable-linger)
  • login enable-linger 은 long-running container들을 실행하는 user들은 모두 이 것을 이용해야 한다.

su, sudo

  • su, sudo는 login session 을 만들지 않는다. 그래서 /run/user/$uid 를 만들지 않는다.
  • 그렇기 때문에, Rootless podman 을 사용할 때 su, sudo로 사용하면 안된다. Root container들은 문제가 없다.
  • 다만, loginctl enable-linger 를 사용해서 그 user에 대해서 영구적인 user session 을 만들면 가능하다.
  • sudo, su 대신에 user session 을 만들어주는, machinectl login 또는 ssh 를 사용해서 접근하면 된다.

susudo 를 사용해서 rootless podman 을 실행하는 법

  1. 처음 시작시에 sudo 또는 su로 Podman 을 실행하면, /tmp가 temporary files directory로 잡혀서 실행가능
  2. --runroot flag 를 이용해서 temporary files directory path 를 지정해서 사용할 수 있다.
  3. 다만 이것들은 cgroups v1 system에서만 가능. 그리고 정확한 환경변수를 위해 --login argument가 필요할 것이다.
  4. cgroups v2 system 에서 하려면, cgroup 들을 setup 하고, rootless container에 대한 resource limit 들을 setup 하기 위해 login session 의 다른 부분들이 더 필요

Reference

  1. Why can’t I use sudo with rootless Podman? | Enable Sysadmin
  2. linux - What is this folder /run/user/1000? - Unix & Linux Stack Exchange

댓글 없음:

댓글 쓰기