...it was working on my machine...
- When we are creating a program, we solve problems until we see it working on our development workstation.
- When deploying it to other machines (servers), things may fail, because some things are different there.
What could be the difference?
Address Space separation
- A program running in a modern computer using O.S like Linux or Windows is running in a memory space of its own.
This is part of a feature that is called
virtual memory.
- This achevement is based on a special hardware called
MMU (memory management unit), that modern CPU's are already equipped with.
- If my program will try to write to memory location 0 (address zero), I'm going to (try to) write to my own process memory space.
- So we can say that processes in modern O.S are already running within some "memory containers".
File system, environment vars, networking..
- Most programs will access files, located in local file systems.
- Programs may rely on directories being already created, dynamic library file (.so or dll) that should be there, permissions for file and directories, etc.
- Some environment variables may affect my program (think PATH for example)
- Networking:
I may need to make sure a specific port number is available, an interface is UP, etc.
- How can we make sure all of these are the same for my program, wherever I run it?
Linux namespaces
- The linux kernel has some solutions for that for some years now:
linux namespaces can create an environment where:
- a process sees a specific file system environment
- there is a 'space' for process IDs (so PID 1 is not systemd in this environment)
- networking details are taken from another 'pool': different interfaces, different routing table, IP addresses etc.
- the same goes for users, inter-process-communications..etc.
- Namespaces are a building block of containers.
Programs that manage containers (like docker or Podman) are making use of namespaces.
A demo of a container
- Here's a demo of a container, using docker:
1osboxes@osboxes:~$ docker run -it busybox sh
2Unable to find image 'busybox:latest' locally
3latest: Pulling from library/busybox
4ea6255c5eee6: Pull complete
5Digest: sha256:6776a33c72b3af7582a5b301e3a08186f2c21a3409f0d2b52dfddbdbe24a5b04
6Status: Downloaded newer image for busybox:latest
7/ #
8/ # pwd
9/
10/ # ls -l
11total 40
12drwxr-xr-x 2 root root 12288 May 18 2023 bin
13drwxr-xr-x 5 root root 360 May 1 09:51 dev
14drwxr-xr-x 1 root root 4096 May 1 09:51 etc
15drwxr-xr-x 2 nobody nobody 4096 May 18 2023 home
16drwxr-xr-x 2 root root 4096 May 18 2023 lib
17lrwxrwxrwx 1 root root 3 May 18 2023 lib64 -> lib
18dr-xr-xr-x 288 root root 0 May 1 09:51 proc
19drwx------ 1 root root 4096 May 1 09:51 root
20dr-xr-xr-x 13 root root 0 May 1 09:51 sys
21drwxrwxrwt 2 root root 4096 May 18 2023 tmp
22drwxr-xr-x 4 root root 4096 May 18 2023 usr
23drwxr-xr-x 4 root root 4096 May 18 2023 var
24/ #
25/ # ip a s
261: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
27 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
28 inet 127.0.0.1/8 scope host lo
29 valid_lft forever preferred_lft forever
30 inet6 ::1/128 scope host
31 valid_lft forever preferred_lft forever
328: eth0@if9: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
33 link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
34 inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
35 valid_lft forever preferred_lft forever
36/ #
37/ #
38/ # ps -e
39PID USER TIME COMMAND
40 1 root 0:00 sh
41 9 root 0:00 ps -e
42/ #
43/ #
44osboxes@osboxes:~$