Giter Club home page Giter Club logo

diy-container's Introduction

Create a container from scratch

Host machine setup

Alternate 1. Install directly on a Linux machine

You can use any Ubuntu machine, with version >= 16.04. Use this script to install the dependencies. For any other distro, the installation steps would be similar, but the package names might be different.

Alternate 2. Use vagrant

The Vagrantfile is present here. I am using a vagrant box spox/ubuntu-arm because my physical machine has apple silicon chip. You can use hashicorp/bionic64 or any other boxes in case your CPU is Intel x86/64.

cd vagrant
vagrant up
vagrant ssh

Filesystem

  1. Create a directory for images and containers
mkdir -p ~/ship/{images,containers}
  1. Get some rootfs image

Alternate 1. Copy from host machine

host-fs

Alternate 2. Get an OCI Bundle

docker pull alpine
CID=$(docker run -d alpine true)
docker export $CID > alpine.tar
mkdir -p ~/ship/images/alpine
tar -xf alpine.tar -C ~/ship/images/alpine

Overlay2 Storage Driver (Union File System)

Ref

Docker actually uses overlay file-systems for containers at /var/lib/docker/overlay2/. We can watch changes on docker's FS when we modify files on containers

sudo apt install inotify-tools
sudo inotifywait -m -r -e modify,create,delete,move /var/lib/docker/overlay2/

# Another terminal
docker pull hello-world
docker inspect --format='{{json .GraphDriver.Data}}' hello-world | jq
sudo tree -a /var/lib/docker/overlay2/ -I 'merged'

You can also create a new overlayFS

Use this script to create an overlayFS.

Then, run the following commands to see how it works.

sudo find . -type f -printf "\n%p\n" -exec cat {} \;

pushd /home/vagrant/ship/overlay/
# Create a new file in merged
echo "_new_" > /home/vagrant/ship/overlay/merged/new.txt
ls -l /home/vagrant/ship/overlay/{lower,merged,upper}

# Delete a common file in merged
rm /home/vagrant/ship/overlay/merged/in_both.txt
ls -l /home/vagrant/ship/overlay/{lower,merged,upper}

sudo umount /home/vagrant/ship/overlay/merged
popd

Docker Storage Drivers Docker Storage Driver Types

Create a Container from the Image

mkdir -p ~/ship/containers
cp -r ~/ship/images/alpine ~/ship/containers/bottle
touch ~/ship/containers/bottle/made_of_glass

Chroot

Chroot restricts the filesystem view of a process to some subdirectory.

sudo chroot ~/ship/containers/bottle /bin/sh

# In the container
env # Inherited from the host

ps
mount -t proc proc /proc # Mount namespace is shared
ps
ip a # Network namespace is shared
pkill top # PID namespace is shared
exit

# Alternatively, We can mount the host's procfs during chroot
sudo chroot ~/ship/containers/bottle /bin/sh --mount-proc
exit

# Only difference is /etc/mtab keeps track of the mount.
sudo umount ~/ship/containers/bottle/proc

Namespaces

sudo unshare --mount --uts --ipc --net --pid --fork bash

# In the container
pstree
mount -t proc proc /proc
pstree
ip a

chroot /home/vagrant/ship/containers/bottle sh
mount -t proc proc /proc

Network

Naming the network namespace of a process

Ref

sudo ip netns add dummy && sudo ip netns delete dummy
sudo touch /run/netns/bottle
sudo chmod 0 /run/netns/bottle
sudo mount --bind /proc/$(pidof unshare)/ns/net /run/netns/bottle

Setting up the network connection

BRIDGE_IP="172.17.0.1"
CON_IP="172.17.0.100"
BRIDGE_NAME="docker0"
PREFIX_LEN="/24"

# Let's check the network configuration of a container created using docker
docker run -d --name moby alpine sleep 100000
docker exec -it moby sh
cat /etc/resolv.conf

# Let's create a veth pair, and do the wiring.
sudo ip link add c-bottle type veth peer name h-bottle

sudo ip link set c-bottle netns bottle

sudo ip link set h-bottle master ${BRIDGE_NAME}

# Bring the interfaces up
sudo ip netns exec bottle ip link set lo up
sudo ip netns exec bottle ip link set c-bottle up
sudo ip link set h-bottle up

# Assign IP addresses, and configure route
sudo ip netns exec bottle ip addr add ${CON_IP}${PREFIX_LEN} dev c-bottle
sudo ip netns exec bottle ip route add default via ${BRIDGE_IP}

# At this point everything other than name resolution should work inside the container.
ping -c 1 8.8.8.8 # In the container

# Get the DNS information from the host
systemd-resolve --status | grep "DNS Server"

# replace 192.168.1.1 with the DNS server from the output above. 
echo 'nameserver 192.168.1.1' > /etc/resolv.conf # In the container

# Alternatively, copy the DNS configuration from a docker container (/etc/resolv.conf) to our container

Cgroups

# Get the PID of the sh running in the container.
pstree -p $(pidof unshare)
CON_SH_PID=$(pidof sh | tail -n 1)

# Create a new cgroup for controlling the max number of processes in the container
sudo mkdir -p /sys/fs/cgroup/pids/bottle

# Cleanup the cgroup when the container exits
echo 1 | sudo tee /sys/fs/cgroup/pids/bottle/notify_on_release

# Set a pids limit
echo 8 | sudo tee /sys/fs/cgroup/pids/bottle/pids.max

# Add the container process to the cgroup
echo $CON_SH_PID | sudo tee /sys/fs/cgroup/pids/bottle/cgroup.procs

# Check the number of processes that are currently running in the container
sudo cat /sys/fs/cgroup/pids/bottle/pids.current

# Spawn some new processes inside the container
sleep 10000 &
sleep 10000 &
sleep 10000 &
sleep 10000 &

# Check the number of processes that are currently running in the container
sudo cat /sys/fs/cgroup/pids/bottle/pids.current

Viewing cgroups and namespaces

# View the cgroup tree
systemd-cgls
sudo tree /sys/fs/cgroup

# View the namespaces of a process
ls -l /proc/$(pidof unshare)/ns

diy-container's People

Contributors

nascarsayan avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.