광대 컨테이너용

광대 컨테이너용

권한 있는 LXC(1.0.3) 컨테이너(내가 알고 있는 부분)를 빌드한 다음 권한 없는 실행을 위해 성공적으로 마이그레이션하려면 어떻게 해야 합니까? 즉, 템플릿(보통 아래 )을 직접 debootstrap수정하거나 조정하여 제대로 작동하도록 하고 싶습니다 .lxc-ubuntu/usr/share/lxc/templates

그래서 내가 이 질문을 하는 것이다. lxc-ubuntu템플릿을 보면 다음과 같은 사실을 알 수 있습니다.

# Detect use under userns (unsupported)
for arg in "$@"; do
    [ "$arg" = "--" ] && break
    if [ "$arg" = "--mapped-uid" -o "$arg" = "--mapped-gid" ]; then
        echo "This template can't be used for unprivileged containers." 1>&2
        echo "You may want to try the \"download\" template instead." 1>&2
        exit 1
    fi
done

그러나 참조된 템플릿에서 및 이후를 사용하는 LXC_MAPPED_GID데는 특별한 내용이 없는 것 같습니다 . 실제로 하는 일은 파일 소유권( + )을 조정하는 것뿐입니다. 그러나 템플릿의 확장 속성은 원하는 "마법"을 달성하기 위해 미세 조정되었을 수 있습니다.LXC_MAPPED_UIDlxc-downloadchgrpchowndownload

댓글에서Stéphane Graber의 블로그 게시물스티븐은 한 평론가에게 이렇게 말했습니다.

불행하게도 이를 수행할 수 있는 쉬운 방법은 없습니다. 권한이 없는 컨테이너의 구성과 일치하도록 컨테이너 구성을 업데이트하고 컨테이너의 디렉터리를 실행하려는 권한이 없는 사용자로 이동한 다음 Serge의 uidshift 프로그램을 사용하여 소유권을 변경해야 합니다. 모든 파일.

... 그리고:

그러나 더 이상의 지시는 없었다.

그래서 내 질문은: root내가 직접 구축한(소유 및 전체) 일반(권한이 있는) LXC 컨테이너를 권한이 없는 컨테이너로 어떻게 마이그레이션할 수 있습니까?스크립트 등을 제공할 수 없더라도 고려해야 할 사항과 권한이 없는 LXC 컨테이너를 실행하는 기능에 어떤 영향을 미치는지 알아두면 좋을 것입니다. 스크립트를 직접 작성하고 해결책을 찾으면 이 질문에 대한 답변으로 게시하겠다고 약속할 수 있습니다. :)

노트:Ubuntu 14.04를 사용하고 있지만 이것은일반적인질문.

답변1

방금 KVM 가상 머신을 권한이 없는 LXC로 옮기는 것과 매우 유사한 작업을 수행했습니다.

이를 위해 시스템 컨테이너를 사용하고 있지만(부팅 시 자동으로 시작할 수 있도록) 매핑된 UID/GID(사용자 네임스페이스)를 사용합니다.

  1. /etc/subuid,subgid를 편집합니다(uid/gids 10M-100M을 루트에 매핑하고 컨테이너당 100K를 사용했습니다).
  2. 첫 번째 컨테이너의 경우 /var/lib/lxc/CTNAME/config에서 u/gid 10000000-10099999를 사용하십시오.
  3. /var/lib/lxc/CTNAME/rootfs에 컨테이너 스토리지 마운트(또는 별도의 볼륨/데이터 세트/컨테이너당 무엇이든 사용하지 않는 경우 아무것도 수행하지 않음)
  4. chown 10000000:10000000 /var/lib/lxc/CTNAME/rootfs
  5. setfacl -mu:10000000:x /var/lib/lxc (또는 간단히 chmod o+x /var/lib/lxc)
  6. lxc-usernsexec -mb:0:10000000:100000 --/bin/bash

이제 첫 번째 컨테이너 사용자 네임스페이스에 있습니다. 모든 것이 동일하지만 프로세스에서는 uid가 0이라고 생각하지만 실제로 호스트 네임스페이스에서는 uid가 10000000입니다. /proc/self/uid_map을 확인하여 uid가 매핑되었는지 확인하세요. 더 이상 /root에서 읽을 수 없으며 아무도/어떤 그룹도 소유하지 않은 것처럼 보입니다.

사용자 네임스페이스에서는 원래 호스트에서 rsync합니다.

사용자 네임스페이스 외부에서 /var/lib/lxc/CTNAME/rootfs의 파일이 이제 원래 설치와 동일한 예상 uid에 속하지 않고 10000000+remote_uid에 속해 있음을 알 수 있습니다. 이것이 당신이 원하는 것입니다.

그게 다야. 데이터를 동기화할 때 컨테이너의 /etc/fstab에서 모든 항목을 제거하여 마운트를 시도하지 않고 시작해야 합니다. 변경해야 할 다른 사항이 있을 수 있습니다. 컨테이너화된 배포에 대해 LXC 템플릿이 수행하는 작업을 확인하세요. 커널, grub, ntp 및 컨테이너의 모든 하드웨어 프로브 패키지를 완전히 제거할 수 있습니다(실행할 필요도 없으며 사용자 네임스페이스에서 컨테이너로 chroot할 수 있음).

실행 중인 원격 VM이 없는 경우 원시 VM 스토리지를 호스트 네임스페이스에 마운트하고 rsync/SSH를 다시 ​​로컬 호스트에 마운트할 수도 있습니다. 효과는 동일합니다.

권한 있는 컨테이너를 권한 없는 컨테이너로 변경하려는 경우 uid/gid 매핑을 추가하고 위 매핑을 컨테이너 구성에 추가한 후 다음을 수행할 수도 있습니다.

for i in `seq 0 65535`; do
  find /var/lib/lxc/CTNAME/rootfs -uid $i -exec chown $((10000000+i)) \{\} \;
  find /var/lib/lxc/CTNAME/rootfs -gid $i -exec chgrp $((10000000+i)) \{\} \;
done

이것이 완료되어야 하는 모든 작업이며 이제 권한 없는 방식으로 컨테이너를 실행할 수 있어야 합니다. 위의 예는 매우 비효율적입니다. uidshift가 더 나은 작업을 수행할 수 있습니다(그러나 아직 사용하지 않았습니다).

HTH.

답변2

Borut Mrak의 예제 코드는 심볼릭 링크가 컨테이너에 있는 파일을 가리킬 때 호스트 시스템에 있는 파일의 소유권도 변경한다는 점을 경고하고 싶습니다. 당신이 원하는 것은 전혀 아닙니다!

전용 파일 시스템이 있는 경우 chown/chgrp에 -h 플래그를 사용하고 검색에 -mount를 사용해야 합니다.

더 빠르고 스마트한 버전은 다음과 같습니다.

find "/var/lib/lxc/$name/rootfs" -mount -uid '-65536' -printf '%U\n'|sort -n|uniq|while read i; do
        find "/var/lib/lxc/$name/rootfs" -mount -uid "$i" -exec chown -h "$((200000+i))" \{\} \;
done

find "/var/lib/lxc/$name/rootfs" -mount -gid '-65536' -printf '%G\n'|sort -n|uniq|while read i; do
        find "/var/lib/lxc/$name/rootfs" -mount -gid "$i" -exec chgrp -h "$((200000+i))" \{\} \;
done

답변3

알파인 리눅스지금 사용uidmapshift로 변환됨lua도착하다권한 있는 컨테이너를 권한 없는 컨테이너로 변환. 보세요initd스크립트설정/생성된 추가 폴더 권한 및 요구 사항을 검토합니다. ( /etc/subuid& /etc/subgid)

답변4

광대 컨테이너용

SUBUID_OFFSET=-65536
SUBGID_OFFSET=-65536
cd rootfs || exit 1
find .|while read i; do SUBUID=$(stat --format=%u $i); SUBGID=$(stat --format=%g $i); NEW_SUBUID=$((SUBUID+SUBUID_OFFSET)); NEW_SUBGID=$((SUBGID+SUBGID_OFFSET)); echo "chown -h $NEW_SUBUID.$NEW_SUBGID $i"; done

Linux 시스템을 마이그레이션하는 데 사용됩니다.

SUBUID=100000
SUBGID=100000
cd rootfs || exit 1
find .|while read i; do CURRENT_UID=$(stat --format=%u $i); CURRENT_GID=$(stat --format=%g $i); NEW_SUBUID=$((CURRENT_UID+SUBUID)); NEW_SUBGID=$((CURRENT_GID+SUBGID)); echo "chown -h $NEW_SUBUID.$NEW_SUBGID $i"; done

관련 정보