Day 19 - Docker Volume  & Docker Networks

Day 19 - Docker Volume & Docker Networks

Docker-Volume

Docker allows you to create something called volumes. Volumes are like separate storage areas that can be accessed by containers. They allow you to store data, like a database, outside the container, so it doesn't get deleted when the container is deleted. You can also mount from the same volume and create more containers having same data. reference

Volumes | Docker Documentation

Docker volume commands

# To display docker volume commands
$ docker volume –help
# Create docker volume
$ docker volume create <volume-name>
$ docker volume create --name django_todo_volume --opt type=none --opt device=/home/ubuntu/volumes/django-todo --opt o=bind
# Display all docker volumes
$ docker volume ls
# Inspect the docker volume
$ docker volume inspect <volume-name>
# Remove docker volume
$ docker volume rm <volume-name>
# Remove unused volumes
$ docker volume prune

Docker Network

Docker allows you to create virtual spaces called networks, where you can connect multiple containers (small packages that hold all the necessary files for a specific application to run) together. This way, the containers can communicate with each other and with the host machine (the computer on which the Docker is installed). When we run a container, it has its own storage space that is only accessible by that specific container. If we want to share that storage space with other containers, we can't do that. reference

Types Of Network

The most common network types are bridge, overlay, and macvlan.

Bridge Network:

Bridge networking is the most common network type. It is limited to containers within a single host running the Docker engine. Bridge networks are easy to create, manage and troubleshoot.

For the containers on the bridge network to communicate or be reachable from the outside world, port mapping needs to be configured. As an example, consider you can have a Docker container running a web service on port 80. Because this container is attached to the bridge network on a private subnet, a port on the host system like 8000 needs to be mapped to port 80 on the container for outside traffic to reach the web service.

Syntax:

$ docker network create --driver bridge [network name]

Overlay Network:

An overlay network uses software virtualization to create additional layers of network abstraction running on top of a physical network. In Docker, an overlay network driver is used for multi-host network communication. This driver utilizes Virtual Extensible LAN (VXLAN) technology which provides portability between cloud, on-premise and virtual environments. VXLAN solves common portability limitations by extending layer 2 subnets across layer 3 network boundaries, hence containers can run on foreign IP subnets.

Syntax:

$ docker network create -- driver overlay --subnet=192.168.10.0/24 my-overlay-net

--subnet parameter to specify the network block that Docker will use to assign IP addresses to the containers.

Macvlan Network

The macvlan driver is used to connect Docker containers directly to the host network interfaces through layer 2 segmentation. No use of port mapping or network address translation (NAT) is needed and containers can be assigned a public IP address that is accessible from the outside world. Latency in Macvlan networks is low since packets are routed directly from the Docker host network interface controller (NIC) to the containers.

Macvlan has to be configured per host and has support for physical NIC, sub-interface, network bonded interfaces and even teamed interfaces.

Docker network commands

# Creating our own bridge network
$ docker network create - -driver bridge my-network

# Run the docker container using custom network which we have created
$ docker run - -name nginx20 -d - -network my-network -p 7070:80 nginx
# List all the docker networks
$ docker network ls
# Check the containers attached to your network
$ docker network inspect my-network

Task 1

Create a multi-container docker-compose file which will bring UP and bring DOWN containers in a single shot ( Example - Create application and database container )

Sample yaml

Step 1 : Use the docker-compose up command with the -d flag to start a multi-container application in detached mode.

sudo apt -get update

sudo apt install docker.io -y

sudo apt install docker-compose -y

sudo usermod -aG docker $USER

sudo reboot

docker images

  • Step 2 : Use the docker-compose scale command to increase or decrease the number of replicas for a specific service. You can also add replicas in deployment file for auto-scaling.

docker-compose scale web=3

Step 3 : Use the docker-compose ps command to view the status of all containers, and docker-compose logs to view the logs of a specific service.

Step 4 : Use the docker-compose down command to stop and remove all containers, networks, and volumes associated with the application


Task 2

  • Learn how to use Docker Volumes and Named Volumes to share files and directories between multiple containers.

  • docker volume create myvol

  • Volume default directory : /var/lib/docker/volumes/

  • $ Docker pull nginx

  • Create two or more containers that read and write data to the same volume using the docker run --mount command.

  • docker run --name=nginx01 -d -p 80:80 --mount source=myvol,target=/user/share/ngnix/html nginx:latest

  • docker run --name=nginx02 -d -p 81:80 --mount source=myvol,target=/user/share/ngnix/html nginx:latest

  • Verify that the data is the same in all containers by using the docker exec command to run commands inside each container.

    How to get inside the container

  • docker exec -it <container name> bash

    Use the docker volume ls command to list all volumes and docker volume rm command to remove the volume when you're done.

Docker volumes will be only accessable as root user: sudo su

cd /var/lib/docker/volumes/

Since the docker volume named myvol is mounted to containers nginx01 and nginx02, data created in nginx01 and nginx02 should be stored or synced with the myvol

From myvol, I created a file called volume.txt. So same file should reflect in both the nginx container. This is happen vice versa for all the files as volume is atached to containers.

We cannot directly remove docker volume because it is mounted to Container. So kindly stop and remove the containers and remove the volumes

docker ps

docker stop <Container ID>

docker rm <Container ID>

docker volume ls

docker volume rm <volume name>


More about Docker volumes

  1. When we create a container then a volume will be created

  2. Volume is simply a directory inside our container

  3. First, we need to declare the directory volume and then share the volume

  4. Volume will be created in one container

  5. Even if the container os stopped, we can access the volume

  6. You can only declare a directory while creating a directory

  7. You can map volumes in two ways

container --- container

host --- container

Uses of container

  1. share volume between containers

  2. On container deletion, volume will not be deleted

  3. Decoupling container from storage

Simple volume creation with docker file (Automated way)

$ vi dockerfile

FROM ubuntu

VOLUME ["/myvol"]

RUN touch file.txt

$ docker build . -t image

$ docker run -it --name=cont1 image /bin/bash/

$ ll

Volume named myvol will be visible

$ cd myvol

$ cat>file.txt Hi welcome to volumes

$ exit

Sharing the volume with another container

$ docker run -it --name=cont2 --privileged=true --volume-from cont1 image /bin/bash/

$ll

Volume named myvol will be visible

$ cd myvol

$ ls && cat file.txt

Same file will be shared in cont2 as well

$ cat>file1.txt Hi welcome to volumes2

exit

now switch to cont

$ docker start cont1

$ docker attach cont1

$ll

$ cd myvol

$ ll

file.txt and file1..txt will be seen here ...

exit


Manual way of creating a volume

$ docker run -it --name=cont -mount source=myvol,target=/usr/share/nginx/html/ image

$ docker run -it --name=cont3 -v /myvol image /bin/bash

$ ll

$ cd myvol

$ cat>hello.txt hello volumes

$ exit

$ docker run -it --name=cont6 --privileged=true --volume-from cont3 image /bin/bash/

$ ll

$ cd myvol

$ ls

$ hello.txt

$ exit.


Local to container

$ cd /home/ubuntu

$ vim file1 file2 file3

$ docker run -it --name=container -v /home/ubuntu/:myvol image /bin/bash/

$ ll

$ cd myvol

$ ls && file1 file2 file3

$ exit