이 스크립트가 사용자로 실행되면 제대로 작동하지만 rc.local에서 실행하면 실패하는 이유는 무엇입니까?

이 스크립트가 사용자로 실행되면 제대로 작동하지만 rc.local에서 실행하면 실패하는 이유는 무엇입니까?

데비안에서 lxc 권한이 없는 컨테이너를 사용하는 데 문제가 있습니다. 나는 다음 접근 방식을 따릅니다.

a) /var/lxcunpriv에 권한이 없는 사용자 홈을 생성합니다.

useradd -m -d /var/lxcunpriv lxcunpriv

b) 필요한 패키지를 설치합니다.

apt -y install lxc libvirt0 libpam-cgroup libpam-cgfs bridge-utils cgroupfs-mount

c) lxc-net vim /etc/default/lxc-net 파일을 변경합니다.

USE_LXC_BRIDGE="true"

d) lxc-net을 다시 시작합니다.

systemctl restart lxc-net

e) 확인, 모두 녹색(제대로 작동함)

lxc-checkconfig

f) 나는 이것을 적용한다

sh -c 'echo "kernel.unprivileged_userns_clone=1" > /etc/sysctl.d/80-lxc-userns.conf'
sysctl -w -p --system

g) 나는 루트가 아닌 사용자로서 이 작업을 수행했습니다.

cat /etc/s*id|grep $USER

h) 100000-165536을 반환하므로...

usermod --add-subuids 100000-165536 lxcunpriv
usermod --add-subgids 100000-165536 lxcunpriv

i) /var/lxcunpriv에 일부 권한을 부여했습니다.

cd /var/lxcunpriv
setfacl -m u:100000:x . .local .local/share

l) 사용자 네트워크를 구성합니다. bridge1은 내 브리지 이름입니다.

echo "lxcunpriv veth bridge1 10"| tee -i /etc/lxc/lxc-usernet

m) 디렉토리를 생성합니다

su - lxcunpriv
mkdir -p .config/lxc

n) 그럼...

echo \
'lxc.include = /etc/lxc/default.conf
# Subuids and subgids mapping
lxc.id_map = u 0 100000 65536
lxc.id_map = g 0 100000 65536
# "Secure" mounting
lxc.mount.auto = proc:mixed sys:ro cgroup:mixed
lxc.apparmor.profile = unconfined
 
# Network configuration
lxc.network.type = veth
lxc.network.link = bridge1
lxc.network.flags = up
lxc.network.hwaddr = 00:FF:xx:xx:xx:xx'>.config/lxc/default.conf

o) /etc/lxc/default.conf를 편집합니다.

lxc.network.type = veth
lxc.network.link = bridge1

p) .config/lxc/default.conf 업데이트

lxc-update-config -c .config/lxc/default.conf

q) 첫 번째 컨테이너를 만듭니다.

lxc-create --name mylinux -t download
lxc-start --name mylinux
lxc-attach --name mylinux

이제 문제는 컨테이너를 시작할 때...

lxc-start --name mylinux
lxc-start: mylinux: lxccontainer.c: wait_on_daemonized_start: 833 No such file or directory - Failed to receive the container state
lxc-start: mylinux: tools/lxc_start.c: main: 330 The container failed to start
lxc-start: mylinux: tools/lxc_start.c: main: 333 To get more details, run the container in foreground mode
lxc-start: mylinux: tools/lxc_start.c: main: 336 Additional information can be obtained by setting the --logfile and --logpriority options

포럼에서 검색해 보니 해결 방법이 나와 있습니다.

#!/bin/sh
printf '\n\033[42mCreating cgroup hierarchy\033[m\n\n' &&
for d in /sys/fs/cgroup/*; do
        f=$(basename $d)
        echo "looking at $f"
        if [ "$f" = "cpuset" ]; then
                echo 1 | sudo tee -a $d/cgroup.clone_children;
        elif [ "$f" = "memory" ]; then
                echo 1 | sudo tee -a $d/memory.use_hierarchy;
        fi
        sudo mkdir -p $d/$USER
        sudo chown -R $USER $d/$USER
        # add current process to cgroup
       echo $PPID > $d/$USER/tasks
done

sh workaround.sh

온라인에서는 "권한 거부" 메시지가 표시되지만 echo $PPID > $d/$USER/tasks 작동합니다.

lxc-start -n mylinux
echo $?
0

이제 문제가 발생합니다. 컨테이너가 부팅 시 시작되기를 원하므로(권한이 없음) lxc-autostart가 작동하지 않습니다. /etc/rc.local 파일을 생성했지만 실패했습니다. 이런 식으로 시도했습니다.

#!/bin/bash
# Action at boot

start() {
su - lxcunpriv -c "lxc-start -n mylinux"
su - lxcunpriv -c "lxc-start -n myothercontainer"
....
}

이 경우 오류와 함께 실패합니다.

  lxc-start: mylinux: lxccontainer.c: wait_on_daemonized_start: 833 No such file or directory - Failed to receive the container state
    lxc-start: mylinux: tools/lxc_start.c: main: 330 The container failed to start
    lxc-start: mylinux: tools/lxc_start.c: main: 333 To get more details, run the container in foreground mode
    lxc-start: mylinux: tools/lxc_start.c: main: 336 Additional information can be obtained by setting the --logfile and --logpriority options

이는 또한 rc.local의 "해결 방법" 스크립트를 실행합니다.

su - lxcunpriv <<EOF
sh workaround.sh
lxc-start -n myothercontainer
EOF

이 경우 해결 방법은 작동하지만 동일한 오류로 인해 lxc-start 명령이 실패합니다.

 lxc-start --name mylinux
    lxc-start: mylinux: lxccontainer.c: wait_on_daemonized_start: 833 No such file or directory - Failed to receive the container state...

물론 내가 그렇게 한다면

su - lxcunpriv
sh workaround.sh
lxc-start -n mylinux

작동하는데 왜 rc-local에서는 안되나요?

답변1

rc.local을 편집한 솔루션을 찾았습니다.

그 줄 대신에

su - lxcunpriv <<EOF
sh workaround.sh
lxc-start -n myothercontainer
EOF

올바른 줄은 무엇입니까?

start() {
su - lxcunpriv <<EOF
/var/lxcunpriv/workaround.sh
lxc-start --name mycontainer
lxc-start --name myothercontainer
...
EOF    
}

컨테이너가 시작됩니다. 문제는 스크립트 앞에 있는 단어 "sh"입니다. 이 단어는 다른 하위 쉘을 시작하고 해결 스크립트의 효과를 무효화합니다.

관련 정보