Containers & Docker Images
Containers are getting more popular year by year and more companies are adopting containers as their default development environment.
One of the primary reasons for the rapid adoption are the flexibility to package the application code, share it and running anywhere regardless of the operating system host. Another reason is the mass adoption of Microservices Architectures.
A Hello World container
The busybox images contain the basic UNIX tools like echo
, ls
and so on.
Behind the scenes
- Docker checked if the busybox:latest image was present in your local computer.
- If not, docker pulled the image from the Docker Hub registry (docker.io).
- After the image was downloaded, Docker created a container from that image and ran the command
echo Hello World
inside it. - The echo command sends the text to STDOUT, the process terminated and the container stopped.
Creating a python server
The following code creates a simple socket listening in the port 8000
#!/usr/bin/python
import SimpleHTTPServer
import SocketServer
PORT = 8000
Handler = SimpleHTTPServer.SimpleHTTPRequestHandler
httpd = SocketServer.TCPServer(("", PORT), Handler)
print "serving at port", PORT
httpd.serve_forever()
Next, we need to dockerize the code using a Dockerfile
FROM python:2.7-alpine
ADD server.py /server.py
ENTRYPOINT ["python","server.py"]
Building the container image
Build Process
How the image is built?
The build process is not performed by the Docker client, instead is performed by the Docker daemon
- The client and the daemon don’t need to be in the same machine
- If you are running Docker in a non-Linux OS, the docker client runs in your host OS and the docker daemon runs in a VM.
Image layers
A docker image is composed of multiple layers. When building an image, a new layer is created for each individual command in the Dockerfile
Running the container and accessing the app
Once the image is build, we can run the container
docker run -p 8000:8000 -d pyserv
To verify that the container is running docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
434339134cc8 pyserv "python server.py" 30 seconds ago Up 31 seconds 0.0.0.0:8000->8000/tcp focused_benz
Shell inside the container
To get inside the container we can run docker exec -it focused_benz sh
The process sh
process will have the same Linux namespace as the main container.
Now that we are inside the container we can explore the process running ps aux
/ # ps aux
PID USER TIME COMMAND
1 root 0:00 python server.py
16 root 0:00 sh
27 root 0:00 ps aux
If you feel curious and open another terminal in your host OS, you will see the process running in the container.
libert >> ps -aux | grep server.py
root 21799 0.0 0.1 13908 12344 ? Ss 19:47 0:00 python server.py
This proves that the process running in the container is also running in the host OS, but the process has a different PID . This is because the container is running in his own Linux Namespace and has his own PID tree. The container filesystem is also isolated from the host OS.
*** References - Kubernetes in Action