In my previous post we saw the fundamentals of what docker is and some basic
commands at docker container fundamentals.
Docker has evolved multifold since then. Different features like stack,
services, swarm mode has been added. Today we are going to talk about the
container basics and the new features as well.
So what is Container?
Container is an isolated area of Operating system running an instance of code
or software. This isolated area has resource limit applied.
Docker Container Orchestration |
In docker container world there are two fundamental concepts:
- Namespaces: represents isolation.
- Control group: grouping of resources and applying limits.
Namespaces:
When you run a container, docker engine creates a set of namespaces in
background to provide isolation from other containers.
Network (net): It provides the container its network stack, its own private routing table, set of IP addresses, socket listing other things related to networks.
FileSystem (mnt) : It provides independent list of mount points within the container which you can use to mount/unmount volumes without affecting the docker host filesystem.
Interprocess communication (POSIX/SysV IPC) : It provides separation of IPC between host and the container. This is important from security point and shouldn't be mixed
Unix Time sharing (uts) : It provides a way to have different hostname
to container on single host.
User(provider users inside container) : This namespace provides a way to map users inside containers to user in host system similar to container port mapping. The processes who needs root access in container can be run using root user in container mapped to less privileged user in host os. That way you protect your host from malicious attacker to take control of host machine.
Control groups:
As the name implies Control Group provides the control over docker containers that the one container is not consuming all the cpu/memory of host and leaving other container in undesired state. It provides can provide realtime metrics of these resources.Now since we have got gist of what all the container is using, let's try some
hands on commands of using containers.
Container Commands:
-
Run a docker container on specific port with a user friendly name:
docker container run -d --name web -p 8000:8080 dockerepo/gsd:1.0
-d means detached mode. if you dont specify this the container will stop as soon as you exit the shell. -p this specifies the port mapping of os: container port. So here 8000 is the host machine port whereas 8080 is the container port. -
Stop and remove docker container:
docker container stop web docker container rm web
-
Run docker container in interactive mode:
docker container run -it --name test alpine sh
This will run alpine linux distribution on your machine in interactive mode and your shell will be attached to the container and any command you type will be actually running in docker container. The last argument that you pass is the type of shell on the container you want to use. For some of the images it may not work as the sh may not be available for that image. To check what shells are available, use below command:docker inspect alpine
check the Cmd section of the output.
-
Run docker container with environment variables:
docker run -e MYVAR1 --env MYVAR2=foo --env-file ./env.list ubuntu bash
You can pass the env variables at runtime as below:docker run --env VAR1=value1 --env VAR2=value2 ubuntu env | grep VAR VAR1=value1 VAR2=value2
Use docker run commandline reference for other options on docker run
Docker Swarm:
Docker swarm is a built in clustering tool provided by docker which provides orchestration capabilities to spread your container replicas ( actually we call it service replicas) across multiple docker hosts. There are lot of other features like secrets, logging and maintaining availability of docker containers.Swarm always check the desired number of replicas and add if any container is down and automatically forwards the requests to healthy replicas.
The docker swarm mode is by default disabled and you need to enable it.
Enable docker swarm:
[node1] (local) root@192.168.0.18 ~ $ docker swarm init --advertise-addr 192.168.0.18 Swarm initialized: current node (z3vvab77qf7rh16dfpvdawmww) is now a manager. To add a worker to this swarm, run the following command: docker swarm join --token SWMTKN-1-xxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxx 192.168.0.18:2377 To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.So when you initiate the docker swarm the current docker node by default becomes docker manager leader. The last option --advertise-addr is optional and only used when your host has multiple IP addresses (ethernet interfaces).
Add new manager node to current swarm:
[node1] (local) root@192.168.0.18 ~
$ docker swarm join-token manager
docker swarm join --token SWMTKN-1-xxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxx 192.168.0.18:2377
Go to your another docker node which you want to add it as manager in current swarm. Use the above docker swarm join command with token printed on the screen.Add new worker node to current swarm:
[node1] (local) root@192.168.0.18 ~
$ docker swarm join-token worker
docker swarm join --token SWMTKN-1-xxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxx 192.168.0.18:2377
Go to your another docker node (for e.g check below node2) which you want to add it as worker in current swarm. Use the above docker swarm join command with token printed on the screen.
[node2] (local) root@192.168.0.19 ~
$ docker swarm join --token SWMTKN-1-xxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxx 192.168.0.18:2377
List all the nodes present in current swarm:
$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
bcbgwgkkx1thjsg5v75566wyx * node1 Ready Active Leader 20.10.17
rl86knbsf666s7cffrcie7klq node2 Ready Active Reachable 20.10.17
p3i15uj0vp790vijvs84r8125 node3 Ready Active 20.10.17
Note: You can only run this command from manager nodeCreate a service with replicas:
[node1] (local) root@192.168.0.18 ~ $ docker service create --name webserver -p 9000:8080 --replicas 3 nginx overall progress: 3 out of 3 tasks 1/3: running 2/3: running 3/3: running verify: Service convergedThe above command evenly create 3 nginx container spread across 3 node. ( 3 node = 3 replicas) you can verify this by running below command:
[node1]
$ docker service ps webserver
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
b6og1go4kwcy webserver.1 nginx:latest node3 Running Running 2 minutes ago
l36uvcl0kaww webserver.2 nginx:latest node1 Running Running 2 minutes ago
q1z7zmz60n4u webserver.3 nginx:latest node2 Running Running 2 minutes ago
Now try to stop a container from one of the node using docker stop command. The swarm automatically detects this and create another replica as below:
$ docker service ps webserver ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS 3204v3w8hnf4 webserver.1 nginx:latest node3 Running Starting less than a second ago b6og1go4kwcy \_ webserver.1 nginx:latest node3 Shutdown Complete 5 seconds ago l36uvcl0kaww webserver.2 nginx:latest node1 Running Running 6 minutes ago q1z7zmz60n4u webserver.3 nginx:latest node2 Running Running 6 minutes agoThe second row highlighted is the container which we stopped and swarm recreated another one to maintain replica count of 3.