LXCFS는 Linux 컨테이너가 가상 머신처럼 느껴지도록하는 작은 퓨즈 파일 시스템입니다. LXC 의 측면 프로젝트로 시작했지만 모든 런타임으로 사용할 수 있습니다.
LXCFS는 다음과 같은 procfs 의 중요한 파일에서 제공 한 정보를 다음과 같이 관리합니다.
/proc/cpuinfo
/proc/diskstats
/proc/meminfo
/proc/stat
/proc/swaps
/proc/uptime
/proc/slabinfo
/sys/devices/system/cpu/online
컨테이너는 표시된 값 (예 : /proc/uptime )이 실제로 컨테이너가 실행중인 시간과 호스트가 실행되는 기간이 아니라 실제로 반영되도록 알고 있습니다.
Serge Hallyn LXCFS 의 CGroup 네임 스페이스를 구현하기 전에 cgroupfs 트리 컨테이너 인식을 제공했습니다. 컨테이너는 자체 CGROUP 아래의 CGROUP에만 접근 할 수 있었기 때문에 추가 안전을 제공했습니다. CGROUP 네임 스페이스에 대한 지원이없는 시스템의 경우 LXCFS 여전히이 기능을 제공하지만 대부분은 이상한 것으로 간주됩니다.
LXCFS 업그레이드합니다 LXCFS 는 공유 라이브러리 (Libtool 모듈, 정확한) liblxcfs 및 간단한 이진 lxcfs 로 분할됩니다. 최신 버전의 LXCFS 로 업그레이드 할 때 lxcfs 바이너리는 다시 시작되지 않습니다. 대신 새 버전의 공유 라이브러리를 사용할 수 있고 dlclose(3) 및 dlopen(3) 사용하여 다시로드 할 것입니다. 이 설계는 LXCFS 사용하는 퓨즈 메인 루프를 다시 시작할 필요가 없도록 선택되었습니다. LXCFS 사용하는 모든 컨테이너 인 경우 퓨즈 마운트가 부러지기 때문에 다시 시작해야합니다.
다음 가능한 인스턴스에서 공유 라이브러리를 다시로드하려면 실행중인 LXCFS 프로세스의 PID로 SIGUSR1 보냅니다. 이것은하는 것만 큼 간단 할 수 있습니다.
rm /usr/lib64/lxcfs/liblxcfs.so # MUST to delete the old library file first
cp liblxcfs.so /usr/lib64/lxcfs/liblxcfs.so # to place new library file
kill -s USR1 $(pidof lxcfs) # reload
공유 라이브러리 재 장전을 통한 원활한 업그레이드를 달성하려면 LXCFS dlclose(3) 가 떨어지면 공유 라이브러리 소멸자에 대한 마지막 참조가 실행되고 dlopen(3) 생성자라고한다는 사실에 의존합니다. 이것은 glibc 에게는 사실이지만 musl 에는 사실이 아닙니다 (언로드 라이브러리 섹션 참조). 따라서 musl 에있는 LXCFS 사용자는 LXCFS 완전히 다시 시작하고 모든 컨테이너를 사용하는 것이 좋습니다.
LXCF를 구축하기 위해 배포판에 따라 퓨즈 및 퓨즈 개발 헤더를 설치하십시오. LXCFS는 fuse3 선호하지만 새로운 fuse2 버전에서 작동합니다.
git clone git://github.com/lxc/lxcfs
cd lxcfs
meson setup -Dinit-script=systemd --prefix=/usr build/
meson compile -C build/
sudo meson install -C build/
소독제로 빌드하려면 -Db_sanitize=... meson setup 옵션을 지정해야합니다. 예를 들어 ASAN 및 UBSAN을 활성화합니다.
meson setup -Dinit-script=systemd --prefix=/usr build/ -Db_sanitize=address,undefined
meson compile -C build/
LXCFS를 실행하는 권장 명령은 다음과 같습니다.
sudo mkdir -p /var/lib/lxcfs
sudo lxcfs /var/lib/lxcfs
LXCFS 사용하려는 컨테이너 런타임은 컨테이너 스타트 업의 올바른 장소에 과제 파일을 마운트해야합니다.
Systemd 기반 컨테이너와 함께 LXCF를 사용하려면 LXC 1.1을 사용하여 자동으로 작동하거나 lxc.mount.hook 및 lxc.reboot.hook 파일 (한 번 제작)을 /usr/share/lxcfs 로 복사 할 수 있습니다.
lxc.mount.auto = cgroup:mixed
lxc.autodev = 1
lxc.kmsg = 0
lxc.include = /usr/share/lxc/config/common.conf.d/00-lxcfs.conf
docker run -it -m 256m --memory-swap 256m
-v /var/lib/lxcfs/proc/cpuinfo:/proc/cpuinfo:rw
-v /var/lib/lxcfs/proc/diskstats:/proc/diskstats:rw
-v /var/lib/lxcfs/proc/meminfo:/proc/meminfo:rw
-v /var/lib/lxcfs/proc/stat:/proc/stat:rw
-v /var/lib/lxcfs/proc/swaps:/proc/swaps:rw
-v /var/lib/lxcfs/proc/uptime:/proc/uptime:rw
-v /var/lib/lxcfs/proc/slabinfo:/proc/slabinfo:rw
-v /var/lib/lxcfs/sys/devices/system/cpu:/sys/devices/system/cpu:rw
ubuntu:18.04 /bin/bash
스왑이 활성화 된 시스템에서 매개 변수 "-u"를 사용하여 스왑을 0으로 표시하는 "meminfo"의 모든 값을 설정할 수 있습니다.
sudo lxcfs -u/var/lib/lxcfs
시스템에 스왑이 있어도 LXCFS가 컨테이너에 스왑이 표시되지 않는 경우이 섹션을주의 깊게 읽고 배포에 대한 스왑 계정을 활성화하는 방법에 대한 지침을 찾으십시오.
Linux에서 CGROUP 처리를 스왑하는 것은 매우 혼란스럽고 LXCF가 처리 할 수있는 완벽한 방법은 없습니다.
아래에 사용 된 용어 :
memory.usage_in_bytes 및 memory.limit_in_bytes 를 나타냅니다memory.memsw.usage_in_bytes 및 memory.memsw.limit_in_bytes 를 나타냅니다주요 문제는 다음과 같습니다.
스왑 계정은 종종 옵트 인이며, 특수 커널 부팅 시간 옵션 ( swapaccount=1 ) 및/또는 특수 커널 빌드 옵션 ( CONFIG_MEMCG_SWAP )이 필요합니다.
RAM 제한과 RAM+스왑 한계를 모두 설정할 수 있습니다. 그러나 델타는 커널이 여전히 많은 RAM을 자유롭게 교체 할 수 있기 때문에 사용 가능한 스왑 공간이 아닙니다. 이로 인해 RAM과 RAM+SWAP 사이의 델타를 사용하여 스왑 장치 크기를 렌더링 할 수 없습니다.
주어진 컨테이너에서 스왑을 비활성화하는 것은 불가능합니다. 할 수있는 가장 가까운 것은 스왑 니스를 0으로 설정하는 것입니다. 이는 페이지 교환 위험을 크게 제한하지만 제거하지는 않습니다.
결과적으로 LXCFS는 다음과 같이 타협해야했습니다.
스왑 계정이 활성화되지 않으면 스왑 공간이 전혀보고되지 않습니다. 스왑 소비를 알 수있는 방법이 없기 때문입니다. 컨테이너는 약간의 스왑을 사용하고있을 수 있지만, 그 스왑을 알 수있는 방법은 없으며 스왑 장치를 보여주는 데 어떤 종류의 스왑 사용이 필요합니다. 호스트 값을 보여주는 것이 완전히 잘못 될 것이므로 0 값이 동일하게 잘못 될 것입니다.
주어진 컨테이너의 스왑 사용이 RAM과 RAM+스왑 사이의 델타를 초과 할 수 있기 때문에 스왑 크기는 항상 RAM+스왑 한계 또는 호스트 스왑 장치 자체의 작은 것으로보고됩니다. 이렇게하면 스왑 사용이 스왑 크기를 초과 할 수 없습니다.
Swappiness가 0으로 설정되고 스왑 사용이 없으면 스왑이보고되지 않습니다. 그러나 스왑 사용이 있으면 사용 크기의 스왑 장치 (100% 전체) 가보고됩니다. 이는 메모리 소비에 대한 적절한보고를 제공하면서 응용 프로그램이 더 많은 스왑을 사용할 수 있다고 가정하지 않도록합니다.
LXCFS 충돌의 경우 LXCFS 프로세스 메모리의 핵심 덤프를 갖는 것이 매우 유용 할 수 있습니다.
/var/crash 및 coredumpctl list 확인하십시오.lxcfs를 실행하는 기계에서 루트로 실행하십시오.
# save an old core_pattern setting value:
cat /proc/sys/kernel/core_pattern > /root/core_pattern.old_value.bak
# set a new one to collect all core dumps:
echo '|/bin/sh -c $@ -- eval exec gzip --fast > /var/crash/core-%e.%p.gz' > /proc/sys/kernel/core_pattern
# wait for the next LXCFS crash and check
ls -lah /var/crash
# there should be a file with a name like "core-lxcfs.80581.gz". Please, upload it somewhere and share with us.
# restore the old "core_pattern" value:
cat /root/core_pattern.old_value.bak > /proc/sys/kernel/core_pattern