실습
해당 실습은 AWS 환경에서 Ubuntu Server 20.04 LTS 에서 실습을 진행하다고 가정하고 작성되었습니다.
Install Docker
sudo apt update && sudo apt install -y docker.ioChroot
루트 유저로 전환
sudo -i/tmp 디렉토리 하위에 새로운 루트 디렉토리로 사용할 디렉토리 생성
mkdir /tmp/new-root위에서 생성한 디렉토리를 루트 디렉토리로 변경 시도
chroot /tmp/new-root새로운 루트로 사용할 디렉토리 하위에 bin 디렉토리를 생성
mkdir /tmp/new-root/bin호스트에 있는 /bin/bash 파일을 새로운 루트 디렉토리로 사용할 디렉토리 하위의 bin 디렉토리로 복사
cp /bin/bash /tmp/new-root/bin루트 디렉토리 변경 재시도
chroot /tmp/new-rootbash 명령어 실행에 필요한 연관 라이브러리 파일 확인
ldd /bin/bash새로운 루트로 사용할 디렉토리로 Bash 프로세스 실행에 필요한 연관 라이브러리 복사
{ mkdir /tmp/new-root/lib/x86_64-linux-gnu -p mkdir /tmp/new-root/lib64 cp /lib/x86_64-linux-gnu/libtinfo.so.6 /tmp/new-root/lib/x86_64-linux-gnu cp /lib/x86_64-linux-gnu/libdl.so.2 /tmp/new-root/lib/x86_64-linux-gnu cp /lib/x86_64-linux-gnu/libc.so.6 /tmp/new-root/lib/x86_64-linux-gnu cp /lib64/ld-linux-x86-64.so.2 /tmp/new-root/lib64 }루트 디렉토리 변경 재시도
chroot /tmp/new-root현재 작업중인 디렉토리 확인
pwd아래의 명령어를 실행해서 새로운 루트 디렉토리로 실행된 Bash 프로세스 종료
exit새로운 루트로 사용할 디렉토리 하위에 텍스트 파일 생성
date > /tmp/new-root/date.txt새로운 루트로 사용할 디렉토리로 /bin/ls 파일 및 ls 프로세스 실행에 필요한 연관 라이브러리 복사
{ cp /bin/ls /tmp/new-root/bin cp /lib/x86_64-linux-gnu/libselinux.so.1 /tmp/new-root/lib/x86_64-linux-gnu cp /lib/x86_64-linux-gnu/libpcre2-8.so.0 /tmp/new-root/lib/x86_64-linux-gnu cp /lib/x86_64-linux-gnu/libpthread.so.0 /tmp/new-root/lib/x86_64-linux-gnu }루트 디렉토리 변경
chroot /tmp/new-root위에서 생성한 텍스트파일이 보이는지 확인
ls현재 작업중인 디렉토리 확인
pwd새로운 루트 디렉토리로 실행된 Bash 프로세스 종료
exit새로운 루트로 사용할 디렉토리로 /bin/cat 파일 및 cat 프로세스 실행에 필요한 연관 라이브러리 복사하고 루트 디렉토리를 변경하고 cat 명령어로 텍스트 파일 내용 확인
Docker Image
도커 허브에 있는 nginx 이미지로 컨테이너 생성
docker create --name nginx nginx로컬 호스트에 생성된 컨테이너 목록 확인
docker container ls -a/tmp/nginx 디렉토리 생성
mkdir /tmp/nginx/tmp/nginx 디렉토리로 nginx 컨테이너의 파일들을 복사
docker cp $(docker container ls -aq -f name=nginx):/ /tmp/nginxnginx 컨테이너가 실행될때 수행되는 명령어 확인
docker inspect $(docker container ls -aq -f name=nginx) --format='{{.Config.Cmd}}'/tmp/nginx 디렉토리로 루트 디렉토리로 변경
chroot /tmp/nginxNginx 웹서버 실행
nginx -g "daemon off;"새로운 SSH 세션을 열고 Nginx 웹서버 구동 확인
curl localhost위에서 새로 연결한 SSH 세션에서 ubuntu 이미지로 컨테이너를 생성하고 해당 컨테이너의 파일들을 /tmp/ubuntu 로 복사하고 /tmp/ubuntu 디렉토리로 루트 디렉토리로 변경. 단 /bin/bash가 아닌 /bin/sh 를 실행
Network Namespace
첫번째 세션에서 Ctrl+C를 입력해서 Nginx 프로세스 종료
새로운 루트 디렉토리로 실행된 Bash 프로세스 종료
exit새로운 네트워크 네임스페이스 생성
ip netns add nginx네트워크 네임스페이스 생성 확인
ip netns list위에서 생성한 네트워크 네임스페이스의 네트워크 디바이스 목록 확인
ip netns exec nginx ip -br link위에서 생성한 네트워크 네임스페이스의 루프백 인터페이스 구동
ip netns exec nginx ip link set dev lo up위에서 생성한 네트워크 네임스페이스를 사용하면서 /tmp/nginx 디렉토리로 루트 디렉토리로 변경
ip netns exec nginx chroot /tmp/nginxNginx 웹서버 실행
nginx -g "daemon off;"두번째 SSH 세션으로 이동해서 Nginx 웹서버 구동 확인
curl localhost위에서 생성한 네트워크 네임스페이스의 루프백 인터페이스를 통해서 접근 시도
sudo ip netns exec nginx curl localhost첫번째 SSH 세션으로 이동
Ctrl+C를 입력해서 Nginx 프로세스 종료
새로운 루트 디렉토리로 실행된 Bash 프로세스 종료
exit디폴트 네트워크 네임스페이스에 가상 네트워크 인터페이스 추가
ip link add veth0 type veth peer name veth1생성된 가상 네트워크 인터페이스 확인
ip -br link디폴트 네트워크 네임스페이스에 생성된 네트워크 디바이스 veth1를 nginx 네트워크 네임스페이스로 이동
ip link set veth1 netns nginx디폴트 네트워크 네임스페이스의 네트워크 디바이스 목록 확인
ip -br linknginx 네트워크 네임스페이스의 네트워크 디바이스 목록 확인
ip netns exec nginx ip -br link네트워크 디바이스 veth0에 IP 주소 할당
ip addr add 192.168.1.1/24 dev veth0네트워크 디바이스 veth1에 IP 주소 할당
ip netns exec nginx ip addr add 192.168.1.2/24 dev veth1네트워크 디바이스 veth0 구동
ip link set dev veth0 up네트워크 디바이스 veth1 구동
ip netns exec nginx ip link set dev veth1 up디폴트 네트워크 네임스페이스의 네트워크 디바이스 상태 확인
ip -br linknginx 네트워크 네임스페이스의 네트워크 디바이스 상태 확인
ip netns exec nginx ip -br link위에서 생성한 네트워크 네임스페이스를 사용하면서 /tmp/nginx 디렉토리로 루트 디렉토리로 변경
ip netns exec nginx chroot /tmp/nginxNginx 웹서버 실행
nginx -g "daemon off;"두번째 SSH 세션으로 이동해서 Nginx 웹서버 구동 확인
curl 192.168.1.2첫번째 SSH 세션으로 이동
Ctrl+C를 입력해서 Nginx 프로세스 종료
Nginx 접근 로그 확인
cat /var/log/nginx/access.log
PID Namespace
첫번째 SSH 세션에서 Nginx 웹서버 구동
nginx -g "daemon off;"두번째 SSH 세션에 /tmp/ubuntu를 루트 디렉토리로 사용하는 sh 프로세스 실행
sudo chroot /tmp/ubuntu /bin/sh새로운 SSH 세션을 열고 첫번째 세션에서 구동한 nginx 프로세스의 PID를 확인
ps aux | grep nginx두번째 SSH 세션에서 kill 명령어를 통해서 모든 nginx 프로세스 종료를 시도
kill -9 NGINX_PID첫번째 SSH 세션으로 이동해서 실제로 nginx 프로세스가 종료되었는지 확인
첫번째 SSH 세션으로 이동해서 종료된 nginx 프로세스를 재기동
nginx -g "daemon off;"세번째 SSH 세션으로 이동해서 리눅스 네임스페이스 목록 확인
lsnsnginx 프로세스의 PID를 확인
ps aux | grep nginxnginx 프로세스가 실행되는 PID 네임스페이스 확인
sudo ls -Li /proc/NGINX_PID/ns/pidsh 프로세스의 PID를 확인
ps aux | grep /bin/shsh 프로세스가 실행되는 PID 네임스페이스 확인
sudo ls -Li /proc/SH_PID/ns/pid두번째 SSH 세션으로 이동해서 /proc 파일시스템 마운트
mount -t proc proc /procnginx 프로세스의 PID를 확인
ps aux | grep nginx/tmp/ubuntu 디렉토리로 루트 디렉토리로 실행되고 있는 sh 프로세스 종료
exit새로운 PID 네임스페이스를 생성하고 /tmp/ubuntu 디렉토리로 루트 디렉토리로 하는 sh 프로세스 실행
sudo unshare --pid --fork chroot /tmp/ubuntu /bin/sh/proc 파일시스템 마운트
mount -t proc proc /proc실행중인 프로세스 목록 확인
ps aux세번째 세션으로 이동해서 첫번째 세션에서 구동중인 nginx 프로세스의 PID 확인
ps aux | grep nginx두번째 SSH 세션으로 (PID가 격리된 ubuntu 환경) 이동해서 nginx 프로세스 종료 시도
kill -9 NGINX_PID세번째 SSH 세션으로 이동해서 PID 네임스페이스 목록 확인
sudo lsns -t pidsh 프로세스의 PID를 확인
ps aux | grep /bin/shsh 프로세스 종료 시도
sudo kill -9 SH_PIDPID 네임스페이스 목록 확인
sudo lsns -t pid
Cgroup
두번째 SSH 세션으로 이동해서 새로운 PID 네임스페이스를 생성하고 /tmp/ubuntu 디렉토리로 루트 디렉토리로 하는 sh 프로세스 실행
sudo unshare --pid --fork chroot /tmp/ubuntu /bin/sh아래와 같은 명령어를 실행해서 CPU 부하를 발생
mknod /dev/null c 1 3 yes > /dev/null세번째 SSH 세션으로 이동해서 CPU 사용량 확인
topcgroup-tools 설치
sudo apt install cgroup-tools -y새로운 cgroup 생성
sudo cgcreate -g cpu,memory,blkio,devices,freezer:/ubuntu격리된 ubuntu 환경에서 실행중인 sh 프로세스의 PID를 확인
ps aux | grep /bin/shsh 프로세스에 위에서 생성한 cgroup 부여
sudo cgclassify -g cpu,memory,blkio,devices,freezer:ubuntu SH_PIDCPU 사용률을 30%로 제한
sudo cgset -r cpu.cfs_quota_us=30000 ubuntuCPU 사용량 확인
top두번째 SSH 세션으로 이동해서 실행중인 프로세스를 종료
CPU 부하를 다시 발생시키고 CPU 사용률이 30%로 제한되는지 확인
yes > /dev/null메모리 사용량을 100M로 제한하고 아래와 같은 명령어를 실행해서 확인
yes | tr \\n x | head -c 1048576000 | grep n
Last updated