약 100줄의 Bash로 구현된 Docker, Bocker (2015)
(github.com/p8952)- Bocker는 Docker를 약 100줄의 Bash로 구현한 프로젝트로, 이미지 pull, 컨테이너 run, 로그 확인, commit, 삭제 같은 Docker 유사 흐름을 제공함
- 실행에는 btrfs-progs, curl, iproute2, iptables, libcgroup-tools, util-linux 2.25.2 이상, coreutils 7.5 이상이 필요하며,
/var/bocker아래 btrfs 파일시스템과bridge0네트워크 구성이 필요함 - README 예시는
centos:7이미지를 pull한 뒤 컨테이너에서 명령을 실행하고,yum install -y wget결과를 commit해 이후 실행에서/usr/bin/wget을 확인하는 흐름을 보여줌 - Bocker는 root로 실행되며 네트워크 인터페이스, 라우팅 테이블, 방화벽 규칙을 변경하므로 가상 머신에서 실행하는 것이 권장되고, 시스템 손상 가능성에 대한 보장은 없음
- 현재
docker pull,images,ps,run,exec,logs,commit,rm/rmi, 네트워킹, CGroups 기반 쿼터를 구현했지만 데이터 볼륨, 데이터 볼륨 컨테이너, 포트 포워딩은 아직 구현되지 않음
Bocker의 목적과 범위
- Bocker는 Docker를 약 100줄의 Bash로 구현한 프로젝트임
- README는 Docker와 유사한 명령 흐름을 Bash 기반으로 보여주며, 이미지 관리, 컨테이너 실행, 로그 조회, 변경사항 commit, 리소스 제한 같은 기능을 포함함
실행 요구사항
- 실행에 필요한 패키지는 다음과 같음
-
btrfs-progs
- curl
- iproute2
- iptables
- libcgroup-tools
- util-linux 2.25.2 이상
- coreutils 7.5 이상
- 대부분의 배포판은 충분히 최신 util-linux를 포함하지 않으므로, util-linux 2.25 소스를 받아 직접 컴파일해야 할 가능성이 있음
- 시스템에는 다음 구성이 필요함
/var/bocker아래에 마운트된 btrfs 파일시스템bridge0라는 네트워크 브리지와10.0.0.1/24IP/proc/sys/net/ipv4/ip_forward에서 IP 포워딩 활성화bridge0에서 물리 인터페이스로 트래픽을 라우팅하는 방화벽 설정- 필요한 환경을 쉽게 만들 수 있도록 Vagrantfile이 포함돼 있음
-
실행 시 주의사항
- 요구사항을 충족해도 Bocker는 가상 머신에서 실행하는 것이 권장됨
- Bocker는 root로 실행되며 다음 항목을 변경해야 함
- 네트워크 인터페이스
- 라우팅 테이블
- 방화벽 규칙
- README는 Bocker가 시스템을 망가뜨리지 않는다는 보장을 할 수 없다고 명시함
예시 사용 흐름
bocker pull centos 7로centos:7이미지를 가져오면img_42150같은 이미지 ID가 생성됨bocker images는 이미지 ID와 소스를 표시함- 예시 출력:
img_42150,centos:7
- 예시 출력:
bocker run img_42150 cat /etc/centos-release는 컨테이너에서 CentOS 릴리스 정보를 출력함- 예시 출력:
CentOS Linux release 7.1.1503 (Core)
- 예시 출력:
bocker ps는 실행된 컨테이너 ID와 명령을 보여줌bocker logs ps_42045는 해당 컨테이너의 출력 로그를 보여줌bocker rm ps_42045는 컨테이너를 제거함bocker run img_42150 which wget실행 시 처음에는wget이 없다는 결과가 나옴bocker run img_42150 yum install -y wget로wget을 설치한 뒤,bocker commit ps_42018 img_42150으로 변경사항을 이미지에 반영함- 이후
bocker run img_42150 which wget는/usr/bin/wget을 출력함
리소스 제한과 CGroups
- Bocker 실행 예시는 컨테이너가 CGroups 아래에 배치되는 것을 보여줌
/proc/1/cgroup에memory:/ps_42152,cpuacct,cpu:/ps_42152같은 항목이 나타남
- 기본 CPU share와 메모리 제한 예시는 다음과 같음
/sys/fs/cgroup/cpu/ps_42152/cpu.shares:512/sys/fs/cgroup/memory/ps_42152/memory.limit_in_bytes:512000000
- 환경 변수로 리소스 제한을 바꿀 수 있음
BOCKER_CPU_SHARE=1024BOCKER_MEM_LIMIT=1024
- 변경 후 예시는 다음 값을 보여줌
- CPU shares:
1024 - memory limit:
1024000000
- CPU shares:
구현된 기능과 미구현 기능
- 현재 구현된 기능은 다음과 같음
docker build†docker pulldocker imagesdocker psdocker rundocker execdocker logsdocker commitdocker rm/docker rmi-
Networking
- Quota Support / CGroups
- †
bocker init은docker build의 매우 제한적인 구현을 제공함 - 아직 구현되지 않은 기능은 다음과 같음
- Data Volume Containers
- Data Volumes
- Port Forwarding
라이선스
- Bocker는 GNU General Public License 조건에 따라 재배포 및 수정할 수 있는 자유 소프트웨어임
- 라이선스 버전은 Free Software Foundation이 공개한 GPL v3 또는 그 이후 버전을 선택할 수 있음
- 프로그램은 유용하기를 바라며 배포되지만, 상품성이나 특정 목적 적합성에 대한 묵시적 보증도 없음
댓글과 토론
Hacker News 의견들
-
proot로 비슷한 걸 만든 적이 있는데, 이름은 Bag [1]였고 Docker 대안이라고 설명하진 않았을 것임
cgroups와는 관련이 없고, 명령줄 인터페이스도 Docker와 다름. 배경은 인터넷 검열과 심층 패킷 검사를 우회하려고 일반 HTML 트래픽처럼 보이는 프록시 체인을 만들었고, 어디서든 계속 실행해야 했지만 Android 네이티브 앱으로 포팅하고 싶지는 않았다는 것임
Termux에서 돌리고 싶었는데 당시 Termux에는 JDK/JRE가 없었고, proot로 Arch Linux 환경을 띄우면 JDK를 쓸 수 있었음. Termux 안의 Arch 환경은 전반적으로 더 유용했고, 서로 다른 설정의 일회성 환경을 만들고 지운 뒤 proot로 들어가 단일 명령만 실행하는 것도 스크립트로 쉽게 자동화됐음. 그래서 선적 컨테이너보다 훨씬 작은 형태라는 뜻으로 bag.sh라고 이름 붙였음
재미있게도 bag.sh에는 5년 동안 건드리지 않은 로드맵/TODO도 남아 있음. 모바일 화면에서 작성해서 스크롤 없이 보려고 대부분 40열 줄맞춤으로 되어 있음
[1]: https://github.com/hkoosha/bag- 이런 사연은 꽤 많았을 것 같음. VM이 맞지 않는 상황에서 여러 구성요소를 하나의 환경으로 패키징해야 해서, chroot와 deb-bootstrap을 쓰고 makeself로 설치 프로그램을 만든 적이 있음
/opt 안에 필요한 소프트웨어와 MySQL 같은 의존성을 담은 작은 Debian을 만들었고, 꽤 잘 동작해서 이걸 만들어준 회사가 2016년쯤 인수될 때까지 사용했음. 더 일반적으로는 큰 애플리케이션의 조잡한 버전을 직접 구현해보는 게 내부 동작을 배우는 최고의 방법 중 하나라고 봄 - 스크립트에서 중요한 따옴표 몇 개를 빠뜨린 것 같음. shellcheck를 돌려보면 좋겠음
mkdir -p $(dirname "$2") - 8인치 태블릿을 가로로 돌려서 실제로 읽을 만한 크기로 80x22 정도를 겨우 만들 수 있었음
가죽 재킷 안주머니에 편하게 들어가는 10인치쯤 되는 Bluetooth 키보드와 조합하면, 가방 없이 집을 나와도 근처 비어가든 구석에 앉아 코드를 쓸 수 있음. 의외로 생산적이기도 한데, 노트북보다 평소 방해 요소로 전환하는 데 마찰이 조금 더 있어서인지 맥주를 한 모금 마시며 계속 코드를 노려보게 됨
- 이런 사연은 꽤 많았을 것 같음. VM이 맞지 않는 상황에서 여러 구성요소를 하나의 환경으로 패키징해야 해서, chroot와 deb-bootstrap을 쓰고 makeself로 설치 프로그램을 만든 적이 있음
-
이런 것들이 좋음. 최소한의 Bash로 만든 것들을 좋아해 왔음
약 10년 전 Docker, Mesos 같은 분산 인프라를 알리려고 주최한 해커톤에서 만든 40줄 Bash짜리 클러스터 내부 부하 분산기 개념 증명도 있음: https://github.com/cell-os/metal-cell/blob/master/discovery/...
아마 잃어버렸지만, 중복성과 분산성을 갖춘 역방향 SSH 터널 기반 colo-to-cloud 전송 도구도 있었음. Shell Fu 등에는 이런 모음이 잘 정리되어 있음: https://www.shell-fu.org/- shell-fu.org는 훌륭한데, 다른 사용자들의 댓글도 보고 싶음
-
Docker의 큰 부분을 이렇게 간단히 다시 구현할 수 있다는 사실이 Docker라는 회사가 직면했고 여전히 직면한 가장 큰 문제임. 근본적으로는 커널 기능을 이어 붙이는 접착 코드에 가깝기 때문임
Docker가 실제 가치를 더하는 곳은 Docker Hub만이 아니라 Docker for Windows와 Mac임. 개발 머신에서 Docker를 돌리려고 VirtualBox와 Vagrant를 직접 만지는 것보다 통합 경험이 훨씬 낫다는 점이 큼- Rancher Desktop도 실용적인 선택지고 무료임. Docker의 새 라이선스가 적용된 뒤 내 직장을 포함해 많은 곳이 그쪽으로 옮겼음
개인적으로 Docker의 진짜 마법은 Docker/OCI 이미지 형식이었다고 봄. 캐싱과 컨테이너 이미지 배포를 훌륭하게 처리하는 방식이고, 여전히 “전체” VM과 워크플로를 구분해주는 핵심임 - Mac의 Docker Desktop은 제약 많고 권한도 부족한 엉망진창임. Mac에서 Docker CLI와 Colima를 쓰는 것도 권한 제약은 있지만, 적어도 말도 안 되는 라이선스와 Docker GUI는 피할 수 있음
Windows에서는 WSL에서 Docker를 쓸 수 있고 아주 잘 동작함. 왜 Docker Desktop을 쓰는지 이해하기 어려움 - macOS에서는 그냥 Colima를 쓰는데, 훨씬 나은 경험이고 훨씬 가벼움
- 아니, Docker는 CloudRun, Render, Fly 같은 PaaS를 우선해서 만들어 기업에 비싸게 팔았어야 했음
대신 제대로 신뢰성 있게 동작하지 않던 어설픈 Docker Swarm을 만들었고, Kubernetes에 빠르게 밀렸음 - 인기 있고 돈이 되는 시스템 중에는 “쉽게” 다시 구현할 수 있는 것이 많음. Docker의 가치는 Docker 이미지에 있다고 생각했는데, Docker가 그렇게 쓰이는 게 아닌가 싶음
내가 쓴 방식은 몇 년 전 소프트웨어를 빌드하려고 누군가의 가상 빌드 환경을 가져오는 용도뿐이었음
- Rancher Desktop도 실용적인 선택지고 무료임. Docker의 새 라이선스가 적용된 뒤 내 직장을 포함해 많은 곳이 그쪽으로 옮겼음
-
저장소에 “아직 구현 안 됨”, “TODO”, “작업 중” 같은 문구가 있는데 마지막 커밋이 몇 년 전인 걸 보면 좋음
내 코드에 흩뿌려둔 TODO를 다시 보러 가지 않는 것에 대해 마음이 좀 편해짐. 작성자를 깎아내리려는 건 아니고 그냥 위안이 됨- 좋은 포인트임. 전혀 깎아내리는 게 아니라 이런 상태를 정상화하려는 거라서 좋음
무급, 자원봉사, 취미 코드에서 공개되어 있다는 이유만으로 해야 한다는 부담을 느끼면 코딩이 덜 즐거워지고, 원래 공개했을 코드도 공개하지 않게 될 수 있음 - 대부분의 프로젝트, 어쩌면 모든 프로젝트는 끝나지 않는다고 느낌. 멈출 때를 아는 것이 중요함
- 좋다고 봄. 무언가가 그냥 완성될 수도 있고, 항상 다음 아이디어가 잔뜩 있어야 하는 건 아니지만 보통은 늘 다음 아이디어가 있음
항상 다음 아이디어가 있다면 정의상 끝내지 못한 TODO도 항상 남을 수밖에 없음. 사실 모든 프로젝트의 정상 상태가 그래야 함 - 프로젝트를 시작할 때는 “비목표”, 즉 떠오르지만 의도적으로 구현하지 않을 기능을 생각해보는 데 시간을 쓰는 게 좋음
범위 경계를 명확히 두는 건 완전히 괜찮고 자주 도움이 됨. 그래야 샛길을 쫓다가 프로젝트가 영원히 “완성”되지 않은 느낌에 빠지지 않음 - 전혀 괜찮음. 프로그램이 내가 원하는 일을 하고 내 작업이 끝나면 개발을 멈춤. 소프트웨어는 내 취미가 아님
- 좋은 포인트임. 전혀 깎아내리는 게 아니라 이런 상태를 정상화하려는 거라서 좋음
-
lazydocker가 Docker Desktop의 훌륭한 대안으로 아직 언급되지 않은 게 놀라움. Linux/macOS/Windows에서 쓸 수 있음 [1]
꽤 기능이 풍부한 터미널 UI이고, SSH 너머로 실행할 수 있다는 장점도 있음
[1] https://github.com/jesseduffield/lazydocker- 말 그대로 며칠 전에 올라왔음: https://news.ycombinator.com/item?id=42214873
- Lazydocker는 확실히 흥미로워 보이지만, 오픈소스 프로젝트의 README.md에 완전히 다른 영역의 제품을 위한 자기 홍보 광고가 들어가는 건 좀 심함
적어도 나는 이런 걸 처음 봤음. 이런 광고가 GitHub의 서비스 약관이나 허용 사용 정책에서 허용되는지도 궁금함
-
Bocker가 왜 이렇게 자주 첫 페이지에 오르는지 궁금함. 2024년에도 Docker가 여전히 그렇게 논쟁적인가?
Docker가 실제로 유용한 것, 주로 소프트웨어 배포와 “어디서나 쉽게 실행”을 가져왔다는 걸 왜 인정하지 않는지 모르겠음- 이건 Docker가 어떻게 동작하는지 보기 위한 학습 도구일 뿐임
Docker는 이미 존재하던 커널 기술의 조합임. 네임스페이스, cgroups, 유니언 파일 시스템, 그리고 아마 몇 가지가 더 있음 - 자주 첫 페이지에 오르는 이유는 Docker가 엄청 복잡한 것이라고 생각하는 사람들이 많지만, 가장 근본적인 수준에서는 실제로 꽤 우아하고 이해 가능하기 때문임
그래서 흥미롭고, 사실상 완벽한 HN식 이야기임 - Docker를 깎아내리려고 첫 페이지에 오르는 게 아니라, Docker가 유용하다는 걸 보고 어떻게 동작하는지 알고 싶어 하는 것일 수 있음. Bocker는 그 기술들로 들어가는 입구가 될 수 있음
- 회사에서 긴 CI 과정을 줄이려고 overlayfs를 가져가 보여줬는데, 속도 향상에 다들 놀랐음
몇 명에게 시연하고 나서야 그들이 그냥/를 쓸 수도 있고, 아니면 내가 Docker를 가져다줬어도 됐겠다는 걸 깨달았음
- 이건 Docker가 어떻게 동작하는지 보기 위한 학습 도구일 뿐임
-
다른 어머니에게서 난 형제 같은 존재로 https://bastillebsd.org/가 있음
Bastille은 Docker에서 볼 법한 많은 구조를 shell로 사용해 FreeBSD jail을 관리함. 의존성이 아주 적어서 BSD의 다른 jail 관리 소프트웨어보다 마음에 듦- cbsd도 꽤 인상적임: shttps://www.bsdstore.ru/en/about.html
다만 CLI/TUI 기반 도구임에도 “최대 과잉”에 가까운 해법임. 요즘은 FreeBSD 기본 구성만으로 jail을 만들고 관리하는 단계를 거치는 중인데, 이건 어디까지나 일시적인 단계임
전체가 어떻게 맞물리는지 머릿속에 충분히 새겨져 디버깅에 자신이 생길 때까지만 그렇게 하고, 그 뒤에는 분별 있는 사람처럼 돌끼리 두드리는 짓을 멈추고 더 높은 수준의 도구로 돌아갈 생각임 - 맞음. 약 100줄짜리 shell 스크립트치고는 가치를 많이 더해줌
그런데 왜 이름이 Bastille인지 이해하는 데 시간이 좀 걸렸음. La Bastille은 백년전쟁 때 영국의 공격으로부터 Paris를 방어하기 위해 지어진 성이었고, 나중에 감옥으로 바뀌었음
- cbsd도 꽤 인상적임: shttps://www.bsdstore.ru/en/about.html
-
“대부분의 배포판은 충분히 최신 버전의 util-linux를 제공하지 않으므로 여기서 소스를 받아 직접 컴파일해야 할 것이다”라는 부분은 조심해야 함
기본 설치 접두사가/usr/bin이라서, 설치 과정이 기존 mount 명령을 존재하지 않는 라이브러리를 요구하는 버전으로 덮어쓸 수 있음. 그러면 다음 부팅 때 커널이 파일 시스템을 읽기 전용으로 마운트하게 됨/usr/local/bin이어야 함
-
일상적으로 쓰기엔 좋지 않지만, Docker가 무엇이고 어떻게 동작하는지 감을 줌
Linux에서 Docker는 기본적으로 화려한 chroot임- macOS/Windows 등에서 Docker는 기본적으로 Linux VM 안의 화려한 chroot임
-
재미있는 사실: Docker는 Bash로 시작했고, 이후 Python으로 옮겼다가 결국 Go에 정착했음
또 2013년 Docker 밋업에서는 누군가가 Bash로 Docker 클론을 작성했음. 사람들은 배우고 싶어 하고, 이런 것들이 도움이 되면 좋겠음