Version : 2023.01

Last update :

DOE604 - Volume, Network and Container Management

Content

DOE604 - Volume, Network and Resource Management

Content

LAB #1 - Volume Management

1.1 - Automatic management using Docker

1.2 - Manual Volume Management

1.3 - Manual management of a Bindmount

LAB #2 - Network Management

2.1 - The Docker Network Approach

Bridge

Host

None

Links

2.2 - Running Wordpress in a container

2.3 - Managing a Microservices Architecture

LAB #3 - Monitoring Containers

3.1 - Logs

3.2 - Processes

3.3 - Continuous Activity

LAB #1 - Volume Management

Launch the mongo2 container:

root@debian11:~# docker start mongo2
mongo2

1.1 - Automatic Volume Management by Docker

Check that the process is started in the container:

root@debian11:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
880733c6bdc3 i2tch/mongodb2 "docker-entrypoint.s…" 4 days ago Up 43 seconds 27017/tcp mongo2

Then identify the mount point of the /data/db directory of the container:

root@debian11:~# docker inspect mongo2
...
"Mounts": [
{
"Type": "volume",
"Name": "537cc5d0f0f0aa0af9dd959b45fc9fcbe8467a868b9d61919991366a2813f703",
"Source": "/var/lib/docker/volumes/537cc5d0f0f0aa0af9dd959b45fc9fcbe8467a868b9d61919991366a2813f703/_data",
"Destination": "/data/db",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
},
{
"Type": "volume",
"Name": "58795fb69d54b87b11fcb6ab752a1fa10736e5aa37c8a14b1c36db1306853a59",
"Source": "/var/lib/docker/volumes/58795fb69d54b87b11fcb6ab752a1fa10736e5aa37c8a14b1c36db1306853a59/_data",
"Destination": "/data/configdb",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": "".
}
],
...
"Volumes": {
"/data/configdb": {},
"/data/db": {}
},
...

Looking at the contents of the /data/db directory, we see a classic mongodb data storage tree :

root@debian11:~# ls /var/lib/docker/volumes/537cc5d0f0f0aa0af9dd959b45fc9fcbe8467a868b9d61919991366a2813f703/_data
collection-0-2505194079268383602.wt index-5-2505194079268383602.wt storage.bson
collection-2-2505194079268383602.wt index-6-2505194079268383602.wt WiredTiger
collection-4-2505194079268383602.wt journal WiredTigerLAS.wt
diagnostic.data _mdb_catalog.wt WiredTiger.lock
index-1-2505194079268383602.wt mongod.lock WiredTiger.turtle
index-3-2505194079268383602.wt sizeStorer.wt WiredTiger.wt

Stop and delete the mongo2 container:

root@debian11:~# docker stop mongo2
mongo2
root@debian11:~# docker rm mongo2
mongo2

Now re-create a container from the i2tch/mongodb2 image:

root@debian11:~# docker run -d --name mongo2 i2tch/mongodb2
1980be05ac73d70979f5e932f1a58b6526ae1001a335fd8ca010bbfaac48ca5e
root@debian11:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1980be05ac73 i2tch/mongodb2 "docker-entrypoint.s…" 5 seconds ago Up 4 seconds 27017/tcp mongo2

Use the docker inspect command again to identify the mount point of the /data/db directory:

root@debian11:~# docker inspect mongo2
...
"Mounts": [
{
"Type": "volume",
"Name": "2ec1edeca3acd91aede62091e0d96252eb31e403a00fef324ca2244b2952bb48",
"Source": "/var/lib/docker/volumes/2ec1edeca3acd91aede62091e0d96252eb31e403a00fef324ca2244b2952bb48/_data",
"Destination": "/data/configdb",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
},
{
"Type": "volume",
"Name": "4abe232050675d853d0a4d8beefe31f884e1252c985828c3be47a983aac58605",
"Source": "/var/lib/docker/volumes/4abe232050675d853d0a4d8beefe31f884e1252c985828c3be47a983aac58605/_data",
"Destination": "/data/db",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": "".
}
],
...

Important: Note that the data directory of the previous container, /var/lib/docker/volumes/537cc5d0f0aa0af9dd959b45fc9fcbe8467a868b9d61919991366a2813f703/_data is not the same as the current container /var/lib/docker/volumes/4abe232050675d853d0a4d8beefe31f884e1252c985828c3be47a983aac58605/_data.

As the containers have not been stopped with the -v option, we can see that the directories persist in /var/lib/docker :

root@debian11:~# ls -l /var/lib/docker/volumes/
total 60
drwx-----x 3 root root 4096 Dec 15 14:39 2ec1edeca3acd91aede62091e0d96252eb31e403a00fef324ca2244b2952bb48
drwx-----x 3 root root 4096 Dec 10 17:12 396ad783162131dcc92a649366ab79e24720bf866ce6803868e2ba2df8e90074
drwx-----x 3 root root 4096 Dec 15 14:39 4abe232050675d853d0a4d8beefe31f884e1252c985828c3be47a983aac58605
drwx-----x 3 root root 4096 Dec 10 17:16 537cc5d0f0f0aa0af9dd959b45fc9fcbe8467a868b9d61919991366a2813f703
drwx-----x 3 root root 4096 Dec 10 17:16 58795fb69d54b87b11fcb6ab752a1fa10736e5aa37c8a14b1c36db1306853a59
drwx-----x 3 root root 4096 Dec 10 18:32 7d7b25232f6ec411dc9dfb888048eebbee919eb2cedc301969bc325a8a8d055e
brw------- 1 root root 8, 33 Dec 15 09:56 backingFsBlockDev
drwx-----x 3 root root 4096 Dec 10 17:12 f766fb3cd11eee28312b8804c1439c0f7b0a7d58a0ce4d61ba50af17b7630c8f
-rw------- 1 root root 65536 Dec 15 14:39 metadata.db

Important : Note that not only does this represent a source of wasted disk space but also proves that data is not persistent between two instances of an i2tch/mongodb2 container. This obviously creates a major problem in production.

1.2 - Manual management of a Volume

Stop and delete the mongo2 container then re-create a container with a specific volume to hold the data placed in /data/db of the container by mongodb :

root@debian11:~# docker stop mongo2
mongo2
root@debian11:~# docker rm mongo2
mongo2
root@debian11:~# docker run -d --name mongo2 -v persistent_data:/data/db i2tch/mongodb2
8b2207df56a727a8472b2949d7a83a1925e751ad0216fe98b6a3db83230c0988
root@debian11:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8b2207df56a7 i2tch/mongodb2 "docker-entrypoint.s…" 6 seconds ago Up 6 seconds 27017/tcp mongo2
root@debian11:~# docker logs mongo2
2023-12-15T13:45:40.845+0000 I CONTROL [main] Automatically disabling TLS 1.0, to force-enable TLS 1.0 specify --sslDisabledProtocols 'none'
2023-12-15T13:45:40.847+0000 I CONTROL [initandlisten] MongoDB starting : pid=1 port=27017 dbpath=/data/db 64-bit host=8b2207df56a7
2023-12-15T13:45:40.847+0000 I CONTROL [initandlisten] db version v4.1.9
2023-12-15T13:45:40.847+0000 I CONTROL [initandlisten] git version: a5fa363117062a20d6056c76e01edb3a08f71b7c
2023-12-15T13:45:40.847+0000 I CONTROL [initandlisten] OpenSSL version: OpenSSL 1.1.1 11 Sep 2018
2023-12-15T13:45:40.847+0000 I CONTROL [initandlisten] allocator: tcmalloc
2023-12-15T13:45:40.847+0000 I CONTROL [initandlisten] modules: none
2023-12-15T13:45:40.847+0000 I CONTROL [initandlisten] build environment:
2023-12-15T13:45:40.847+0000 I CONTROL [initandlisten] distmod: ubuntu1804
2023-12-15T13:45:40.847+0000 I CONTROL [initandlisten] distarch: x86_64
2023-12-15T13:45:40.847+0000 I CONTROL [initandlisten] target_arch: x86_64
2023-12-15T13:45:40.847+0000 I CONTROL [initandlisten] options: { net: { bindIp: "*" } }
2023-12-15T13:45:40.847+0000 I STORAGE [initandlisten]
2023-12-15T13:45:40.847+0000 I STORAGE [initandlisten] ** WARNING: Using the XFS filesystem is strongly recommended with the WiredTiger storage engine
2023-12-15T13:45:40.847+0000 I STORAGE [initandlisten] ** See http://dochub.mongodb.org/core/prodnotes-filesystem
2023-12-15T13:45:40. 847+0000 I STORAGE [initandlisten] wiredtiger_open config: create,cache_size=7485M,session_max=20000,eviction=(threads_min=4,threads_max=4),config_base=false,statistics=(fast),log=(enabled=true,archive=true,path=journal,compressor=snappy),file_manager=(close_idle_time=100000),statistics_log=(wait=0),verbose=(recovery_progress),
2023-12-15T13:45:41.621+0000 I STORAGE [initandlisten] WiredTiger message [1702647941:621009][1:0x7f381cfeaa40], txn-recover: Set global recovery timestamp: (0,0)
2023-12-15T13:45:41.665+0000 I RECOVERY [initandlisten] WiredTiger recoveryTimestamp. Ts: Timestamp(0, 0)
2023-12-15T13:45:41.708+0000 I STORAGE [initandlisten] Timestamp monitor starting
2023-12-15T13:45:41.727+0000 I CONTROL [initandlisten]
2023-12-15T13:45:41.727+0000 I CONTROL [initandlisten] ** NOTE: This is a development version (4.1.9) of MongoDB.
2023-12-15T13:45:41.727+0000 I CONTROL [initandlisten] ** Not recommended for production.
2023-12-15T13:45:41.727+0000 I CONTROL [initandlisten]
2023-12-15T13:45:41.727+0000 I CONTROL [initandlisten] ** WARNING: Access control is not enabled for the database.
2023-12-15T13:45:41.727+0000 I CONTROL [initandlisten] ** Read and write access to data and configuration is unrestricted.
2023-12-15T13:45:41.727+0000 I CONTROL [initandlisten]
2023-12-15T13:45:41.727+0000 I CONTROL [initandlisten]
2023-12-15T13:45:41.727+0000 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
2023-12-15T13:45:41.727+0000 I CONTROL [initandlisten] ** We suggest setting it to 'never'
2023-12-15T13:45:41.727+0000 I CONTROL [initandlisten]
2023-12-15T13:45:41.728+0000 I STORAGE [initandlisten] createCollection: admin.system.version with provided UUID: 1e149d35-bbda-46a7-bc8e-3a300abb052f
2023-12-15T13:45:41.815+0000 I INDEX [initandlisten] index build: done building index _id_ on ns admin.system.version
2023-12-15T13:45:41.815+0000 I SHARDING [initandlisten] Marking collection admin.system.version as collection version: <unsharded>
2023-12-15T13:45:41.815+0000 I COMMAND [initandlisten] setting featureCompatibilityVersion to 4.2
2023-12-15T13:45:41.819+0000 I SHARDING [initandlisten] Marking collection local.system.replset as collection version: <unsharded>
2023-12-15T13:45:41.819+0000 I SHARDING [initandlisten] Marking collection admin.system.roles as collection version: <unsharded>
2023-12-15T13:45:41.819+0000 I STORAGE [initandlisten] createCollection: local.startup_log with generated UUID: 759d58f7-7f35-441f-bd93-f090f4a14427
2023-12-15T13:45:41.856+0000 I INDEX [initandlisten] index build: done building index _id_ on ns local.startup_log
2023-12-15T13:45:41.856+0000 I SHARDING [initandlisten] Marking collection local.startup_log as collection version: <unsharded>
2023-12-15T13:45:41.856+0000 I FTDC [initandlisten] Initializing full-time diagnostic data capture with directory '/data/db/diagnostic.data'
2023-12-15T13:45:41.857+0000 I NETWORK [initandlisten] Listening on /tmp/mongodb-27017.sock
2023-12-15T13:45:41.857+0000 I NETWORK [initandlisten] Listening on 0.0.0.0
2023-12-15T13:45:41.857+0000 I SHARDING [LogicalSessionCacheRefresh] Marking collection config.system.sessions as collection version: <unsharded>
2023-12-15T13:45:41.857+0000 I NETWORK [initandlisten] waiting for connections on port 27017
2023-12-15T13:45:41.857+0000 I STORAGE [LogicalSessionCacheRefresh] createCollection: config.system.sessions with generated UUID: 6936ac77-1578-4a80-b907-f00774284e52
2023-12-15T13:45:41.894+0000 I INDEX [LogicalSessionCacheRefresh] index build: done building index _id_ on ns config.system.sessions
2023-12-15T13:45:41.932+0000 I INDEX [LogicalSessionCacheRefresh] index build: starting on config.system.sessions properties: { v: 2, key: { lastUse: 1 }, name: "lsidTTLIndex", ns: "config.system.sessions", expireAfterSeconds: 1800 } using method: Hybrid
2023-12-15T13:45:41.932+0000 I INDEX [LogicalSessionCacheRefresh] build may temporarily use up to 500 megabytes of RAM
2023-12-15T13:45:41.932+0000 I INDEX [LogicalSessionCacheRefresh] index build: collection scan done. scanned 0 total records in 0 seconds
2023-12-15T13:45:41.932+0000 I INDEX [LogicalSessionCacheRefresh] index build: inserted 0 keys from external sorter into index in 0 seconds
2023-12-15T13:45:41.933+0000 I INDEX [LogicalSessionCacheRefresh] index build: done building index lsidTTLIndex on ns config.system.sessions

Note that this time, docker has created a persistent_data directory in the /var/lib/docker/volumes/ directory :

root@debian11:~# ls -l /var/lib/docker/volumes/
total 68
drwx-----x 3 root root 4096 Dec 15 14:39 2ec1edeca3acd91aede62091e0d96252eb31e403a00fef324ca2244b2952bb48
drwx-----x 3 root root 4096 Dec 10 17:12 396ad783162131dcc92a649366ab79e24720bf866ce6803868e2ba2df8e90074
drwx-----x 3 root root 4096 Dec 15 14:39 4abe232050675d853d0a4d8beefe31f884e1252c985828c3be47a983aac58605
drwx-----x 3 root root 4096 Dec 10 17:16 537cc5d0f0f0aa0af9dd959b45fc9fcbe8467a868b9d61919991366a2813f703
drwx-----x 3 root root 4096 Dec 10 17:16 58795fb69d54b87b11fcb6ab752a1fa10736e5aa37c8a14b1c36db1306853a59
drwx-----x 3 root root 4096 Dec 10 18:32 7d7b25232f6ec411dc9dfb888048eebbee919eb2cedc301969bc325a8a8d055e
brw------- 1 root root 8, 33 Dec 15 09:56 backingFsBlockDev
drwx-----x 3 root root 4096 Dec 10 17:12 f766fb3cd11eee28312b8804c1439c0f7b0a7d58a0ce4d61ba50af17b7630c8f
drwx-----x 3 root root 4096 Dec 15 14:45 fa3330b3415f534a7d0053ba95d74fe02765cde317c11cac9691c3132cec3d47
-rw------- 1 root root 65536 Dec 15 14:45 metadata.db
drwx-----x 3 root root 4096 Dec 15 14:45 persistent_data

Stop and delete the mongo2 container then re-create a container using the same specific volume to hold the data placed in /data/db of the container by mongodb :

root@debian11:~# docker stop mongo2
mongo2
root@debian11:~# docker rm mongo2
mongo2
root@debian11:~# docker run -d --name mongo2 -v persistent_data:/data/db i2tch/mongodb2
cc7cc8f3b43346fe47cc5107225b0b98851a73a9b2938530077ca7a3207581a0
root@debian11:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cc7cc8f3b433 i2tch/mongodb2 "docker-entrypoint.s…" 18 seconds ago Up 18 seconds 27017/tcp mongo2

Once again, look for the /data/db mount point using the docker inspect command:

root@debian11:~# docker inspect mongo2
...
"Mounts": [
{
"Type": "volume",
"Name": "persistent_data",
"Source": "/var/lib/docker/volumes/persistent_data/_data",
"Destination": "/data/db",
"Driver": "local",
"Mode": "z",
"RW": true,
"Propagation": ""
},
{
"Type": "volume",
"Name": "cef4abb286a1b519e6cdfb4a2327659cd124dc1513ed55288c014e61a8bf27b7",
"Source": "/var/lib/docker/volumes/cef4abb286a1b519e6cdfb4a2327659cd124dc1513ed55288c014e61a8bf27b7/_data",
"Destination": "/data/configdb",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": "".
}
],
...

Important: Note here that using the same directory between the two containers makes the data persistent and avoids the creation of orphan volumes. For more information on volumes, see : https://docs.docker.com/storage/volumes/.

To create a volume for use with a container use the docker volume create command:

root@debian11:~# docker volume create myvolume
myvolume

To list volumes, use the docker volume ls command:

root@debian11:~# docker volume ls
DRIVER VOLUME NAME
local 2ec1edeca3acd91aede62091e0d96252eb31e403a00fef324ca2244b2952bb48
local 4abe232050675d853d0a4d8beefe31f884e1252c985828c3be47a983aac58605
local 7d7b25232f6ec411dc9dfb888048eebbee919eb2cedc301969bc325a8a8d055e
local 396ad783162131dcc92a649366ab79e24720bf866ce6803868e2ba2df8e90074
local 537cc5d0f0f0aa0af9dd959b45fc9fcbe8467a868b9d61919991366a2813f703
local 58795fb69d54b87b11fcb6ab752a1fa10736e5aa37c8a14b1c36db1306853a59
local cef4abb286a1b519e6cdfb4a2327659cd124dc1513ed55288c014e61a8bf27b7
local f766fb3cd11eee28312b8804c1439c0f7b0a7d58a0ce4d61ba50af17b7630c8f
local fa3330b3415f534a7d0053ba95d74fe02765cde317c11cac9691c3132cec3d47
local myvolume
local persistent_data

Now note the physical location of the created volume:

root@debian11:~# docker volume inspect myvolume
[
{
"CreatedAt": "2023-12-15T14:50:18+01:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/myvolume/_data",
"Name": "myvolume",
"Options": null,
"Scope": "local"
}
]

Create a file in the /var/lib/docker/volumes/myvolume/_data/ directory :

root@debian11:~# touch /var/lib/docker/volumes/myvolume/_data/test-file

Now start a container that uses this volume:

root@debian11:~# docker run -it --name ubuntu-volume --mount source=myvolume,target=/myvolume ubuntu bash

Important: Note the use of the –mount option instead of the –volume or -v option. Introduced in Docker version 17.06, Docker recommends using the –mount option rather than the -v option.

Note that test-file is present in the container:

root@ff76d3820051:/# cd myvolume/
root@ff76d3820051:/myvolume# ls
test-file

Create a second file in the /myvolume directory of the container and exit it:

root@ff76d3820051:/myvolume# touch container_volume
root@ff76d3820051:/myvolume# exit
exit
root@debian11:~#

Now check the contents of the /var/lib/docker/volumes/myvolume/_data/ directory:

root@debian11:~# ls -l /var/lib/docker/volumes/myvolume/_data/
total 0
-rw-r--r-- 1 root root 0 Dec 15 14:55 container_volume
-rw-r--r-- 1 root root 0 Dec 15 14:51 test-file

Important: Note that both files are visible.

root@debian11:~# docker rm ubuntu-volume
ubuntu-volume
root@debian11:~# ls -l /var/lib/docker/volumes/myvolume/_data/
total 0
-rw-r--r-- 1 root root 0 Dec 15 14:55 container_volume
-rw-r--r-- 1 root root 0 Dec 15 14:51 test-file

Important: Note that the two test files are still visible.

Now create a second container by specifying a volume that doesn't exist:

root@debian11:~# docker run -it --rm --name ubuntu-volume --mount source=myvolume1,target=/myvolume1 ubuntu bash
root@5547f3231534:/# ls
bin dev home lib32 libx32 mnt opt root sbin sys usr
boot etc lib lib64 media myvolume1 proc run srv tmp var
root@5547f3231534:/# cd myvolume1
root@5547f3231534:/myvolume1# touch file_myvolume1
root@5547f3231534:/myvolume1# exit
exit
root@debian11:~#

Note that Docker has automatically created the volume:

root@debian11:~# docker volume ls
DRIVER VOLUME NAME
local 2ec1edeca3acd91aede62091e0d96252eb31e403a00fef324ca2244b2952bb48
local 4abe232050675d853d0a4d8beefe31f884e1252c985828c3be47a983aac58605
local 7d7b25232f6ec411dc9dfb888048eebbee919eb2cedc301969bc325a8a8d055e
local 396ad783162131dcc92a649366ab79e24720bf866ce6803868e2ba2df8e90074
local 537cc5d0f0f0aa0af9dd959b45fc9fcbe8467a868b9d61919991366a2813f703
local 58795fb69d54b87b11fcb6ab752a1fa10736e5aa37c8a14b1c36db1306853a59
local cef4abb286a1b519e6cdfb4a2327659cd124dc1513ed55288c014e61a8bf27b7
local f766fb3cd11eee28312b8804c1439c0f7b0a7d58a0ce4d61ba50af17b7630c8f
local fa3330b3415f534a7d0053ba95d74fe02765cde317c11cac9691c3132cec3d47
local myvolume
local myvolume1
local persistent_data
root@debian11:~# ls -l /var/lib/docker/volumes/myvolume1/_data/
total 0
-rw-r--r-- 1 root root root 0 Dec 15 15:01 file_myvolume1

1.3 - Manual management of a Bindmount

Another type of volume that can be used with Docker is the Bindmount. A Bindmount:

depends on the file structure of the Docker host,

cannot be controlled by the Docker CLI.

To create a Bindmount, start by creating the bindmount directory in /root and place the test_bindfile in it:

root@debian11:~# mkdir bindmount
root@debian11:~# touch bindmount/test_bind

Mount the Bindmount inside a container and create the container_bind file:

root@debian11:~# docker run -it --name ubuntu-volume --mount type=bind,source=/root/bindmount,target=/bindmount ubuntu bash
root@1cd3cc50e6c0:/# ls
bin boot etc lib lib64 media opt root sbin sys usr
bindmount dev home lib32 libx32 mnt proc run srv tmp var
root@1cd3cc50e6c0:/# cd bindmount/
root@1cd3cc50e6c0:/bindmount# ls
test_bind
root@1cd3cc50e6c0:/bindmount# touch container_bind
root@1cd3cc50e6c0:/bindmount# ls
container_bind test_bind
root@1cd3cc50e6c0:/bindmount# exit
exit
root@debian11:~#

Check for the presence of the files in the /root/bindmount directory:

root@debian11:~# ls -l bindmount/
total 0
-rw-r--r-- 1 root root 0 Dec 15 15:27 container_bind
-rw-r--r-- 1 root root 0 Dec 15 15:25 test_bind
root@debian11:~# docker rm ubuntu-volume
ubuntu-volume
root@debian11:~# ls -l bindmount/
total 0
-rw-r--r-- 1 root root 0 Dec 15 15:27 container_bind
-rw-r--r-- 1 root root 0 Dec 15 15:25 test_bind

Note that the Docker CLI has no knowledge of this mount point:

root@debian11:~# docker volume ls
DRIVER VOLUME NAME
local 2ec1edeca3acd91aede62091e0d96252eb31e403a00fef324ca2244b2952bb48
local 4abe232050675d853d0a4d8beefe31f884e1252c985828c3be47a983aac58605
local 7d7b25232f6ec411dc9dfb888048eebbee919eb2cedc301969bc325a8a8d055e
local 396ad783162131dcc92a649366ab79e24720bf866ce6803868e2ba2df8e90074
local 537cc5d0f0f0aa0af9dd959b45fc9fcbe8467a868b9d61919991366a2813f703
local 58795fb69d54b87b11fcb6ab752a1fa10736e5aa37c8a14b1c36db1306853a59
local cef4abb286a1b519e6cdfb4a2327659cd124dc1513ed55288c014e61a8bf27b7
local f766fb3cd11eee28312b8804c1439c0f7b0a7d58a0ce4d61ba50af17b7630c8f
local fa3330b3415f534a7d0053ba95d74fe02765cde317c11cac9691c3132cec3d47
local myvolume
local myvolume1
local persistent_data

LAB #2 - Network Management

2.1 - The Docker Network Approach

Docker provides three default networks:

root@debian11:~# docker network ls
NETWORK ID NAME DRIVER SCOPE
2473b0d9324a bridge bridge local
b0a285caf920 host host local
a2da9933cdce none null local

Bridge

This type of network is limited to containers on a single host running Docker. Containers can only communicate with each other and they are not accessible from the outside. In order for containers on the network to communicate or be accessible from the outside world, port mapping must be configured.

By default Docker works in Bridge or (Bridge) mode and creates an intermediate interface for this purpose called docker0 :

root@debian11:~# ip addr show docker0
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:07:c9:88:32 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:7ff:fec9:8832/64 scope link
valid_lft forever preferred_lft forever

Boot a container named resotest from a CentOS image :

root@debian11:~# docker run -itd --name=resotest centos
2126924504d8dedb920728cc7c2a6c73e87f8c5c3d13c17c4fcc2bfe8ff93cc9

Then run the docker network inspect bridge command from the Debian_9 host virtual machine:

root@debian11:~# docker network inspect bridge
[
{
"Name": "bridge",
"Id": "2473b0d9324a421018cdf501060801d34c599991bed76751ae328bc68126a180",
"Created": "2023-12-15T09:56:50.183135221+01:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.17.0.0/16",
"Gateway": "172.17.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"2126924504d8dedb920728cc7c2a6c73e87f8c5c3d13c17c4fcc2bfe8ff93cc9": {
"Name": "resotest",
"EndpointID": "e9ae0ba15d4588571fe77a9a8e1564e92620f9532bed8ee38d060b954116b20c",
"MacAddress": "02:42:ac:11:00:03",
"IPv4Address": "172.17.0.3/16",
"IPv6Address": ""
},
"cc7cc8f3b43346fe47cc5107225b0b98851a73a9b2938530077ca7a3207581a0": {
"Name": "mongo2",
"EndpointID": "d9f30326f473f12a45f6aacf97cee0f12c9c545e45ed7808b0cba809fa48ae9a",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
}
},
"Options": {
"com.docker.network.bridge.default_bridge": "true",
"com.docker.network.bridge.enable_icc": "true",
"com.docker.network.bridge.enable_ip_masquerade": "true",
"com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
"com.docker.network.bridge.name": "docker0",
"com.docker.network.driver.mtu": "1500"
},
"Labels": {}
}
]

Important: Note here that the mongo2 and resotest containers do not have the same address as the docker0 interface on the host machine. However, the addresses are in the same segment - 172.17.0.0/16 indicated by the “Subnet” output: “172.17.0.0/16”.

You can disconnect a container from the network using the following command:

root@debian11:~# docker network disconnect bridge resotest
root@debian11:~# docker network inspect bridge
[
{
"Name": "bridge",
"Id": "2473b0d9324a421018cdf501060801d34c599991bed76751ae328bc68126a180",
"Created": "2023-12-15T09:56:50.183135221+01:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.17.0.0/16",
"Gateway": "172.17.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"cc7cc8f3b43346fe47cc5107225b0b98851a73a9b2938530077ca7a3207581a0": {
"Name": "mongo2",
"EndpointID": "d9f30326f473f12a45f6aacf97cee0f12c9c545e45ed7808b0cba809fa48ae9a",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
}
},
"Options": {
"com.docker.network.bridge.default_bridge": "true",
"com.docker.network.bridge.enable_icc": "true",
"com.docker.network.bridge.enable_ip_masquerade": "true",
"com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
"com.docker.network.bridge.name": "docker0",
"com.docker.network.driver.mtu": "1500"
},
"Labels": {}
}
]

Now create your own bridged network called my-bridged-network :

root@debian11:~# docker network create -d bridge --subnet 172.25.0.0/16 --gateway 172.25.0.1 my-bridged-network
4d26c1192dd7b25c3c787ef41b7bfb94d0eb989d230f33906db6d54ed9c128cc
root@debian11:~# docker network ls
NETWORK ID NAME DRIVER SCOPE
2473b0d9324a bridge bridge local
b0a285caf920 host host local
4d26c1192dd7 my-bridged-network bridge local
a2da9933cdce none null local

Obviously, this network is currently empty:

root@debian11:~# docker network inspect my-bridged-network
[
{
"Name": "my-bridged-network",
"Id": "4d26c1192dd7b25c3c787ef41b7bfb94d0eb989d230f33906db6d54ed9c128cc",
"Created": "2023-12-15T15:34:02.824127656+01:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.25.0.0/16",
"Gateway": "172.25.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]

Now run two containers and look at the network information :

root@debian11:~# docker run -itd --name=centos1 centos
cb2875ab1059e66308228d9179b810db748ad287453cf758206a7025f57b0176
root@debian11:~# docker run -itd --name=centos2 centos
fc417b22a20d3f9de674889962452bfe453ced1fc389410b225055f865cb817f
root@debian11:~# docker inspect --format='{{json .NetworkSettings.Networks}}' centos1
{"bridge":{"IPAMConfig":null,"Links":null,"Aliases":null,"NetworkID":"2473b0d9324a421018cdf501060801d34c599991bed76751ae328bc68126a180","EndpointID": "a0e5d67f4652be807583fba65a76bf1a0462200aa198c92ab29845f88c45d559","Gateway":"172. 17.0.1","IPAddress":"172.17.0.3","IPPrefixLen":16,"IPv6Gateway":"","GlobalIPv6Address":"","GlobalIPv6PrefixLen":0,"MacAddress":"02:42:ac:11:00:03","DriverOpts":null}}
root@debian11:~# docker inspect --format='{{json .NetworkSettings.Networks}}' centos2
{"bridge":{"IPAMConfig":null,"Links":null,"Aliases":null,"NetworkID":"2473b0d9324a421018cdf501060801d34c599991bed76751ae328bc68126a180","EndpointID": "15ed4b05703524f64015b12683ea01729dd26a7dfe68ab638383ea075d8d1428","Gateway":"172. 17.0.1","IPAddress":"172.17.0.4","IPPrefixLen":16,"IPv6Gateway":"","GlobalIPv6Address":"","GlobalIPv6PrefixLen":0,"MacAddress":"02:42:ac:11:00:04","DriverOpts":null}}
root@debian11:~# docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' centos1
172.17.0.3
root@debian11:~# docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' centos2
172.17.0.4

Put the centos1 container in the my-bridged-network :

root@debian11:~# docker network connect my-bridged-network centos1
root@debian11:~# docker network inspect my-bridged-network
[
{
"Name": "my-bridged-network",
"Id": "4d26c1192dd7b25c3c787ef41b7bfb94d0eb989d230f33906db6d54ed9c128cc",
"Created": "2023-12-15T15:34:02.824127656+01:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.25.0.0/16",
"Gateway": "172.25.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"cb2875ab1059e66308228d9179b810db748ad287453cf758206a7025f57b0176": {
"Name": "centos1",
"EndpointID": "a7de8c07d195168c20548b33b506073caa03c16770f330a2e576aedcda25662c",
"MacAddress": "02:42:ac:19:00:02",
"IPv4Address": "172.25.0.2/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
root@debian11:~# docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' centos1
172.17.0.3172.25.0.2

Important: Note that the centos1 container is in two networks.

Do the same for the centos2 container:

root@debian11:~# docker network connect my-bridged-network centos2
root@debian11:~# docker network inspect my-bridged-network
[
{
"Name": "my-bridged-network",
"Id": "4d26c1192dd7b25c3c787ef41b7bfb94d0eb989d230f33906db6d54ed9c128cc",
"Created": "2023-12-15T15:34:02.824127656+01:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.25.0.0/16",
"Gateway": "172.25.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"cb2875ab1059e66308228d9179b810db748ad287453cf758206a7025f57b0176": {
"Name": "centos1",
"EndpointID": "a7de8c07d195168c20548b33b506073caa03c16770f330a2e576aedcda25662c",
"MacAddress": "02:42:ac:19:00:02",
"IPv4Address": "172.25.0.2/16",
"IPv6Address": ""
},
"fc417b22a20d3f9de674889962452bfe453ced1fc389410b225055f865cb817f": {
"Name": "centos2",
"EndpointID": "8467b7d4233dbf855d0538dbc9b1fe718874434913baae403391b3da81ccb92b",
"MacAddress": "02:42:ac:19:00:03",
"IPv4Address": "172.25.0.3/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
root@debian11:~# docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' centos2
172.17.0.4172.25.0.3

Connect to the centos1 container by running bash :

root@debian11:~# docker exec -it centos1 bash
[root@cb2875ab1059 /]#

Check that the network is working:

[root@cb2875ab1059 /]# ping 172.25.0.3
PING 172.25.0.3 (172.25.0.3) 56(84) bytes of data.
64 bytes from 172.25.0.3: icmp_seq=1 ttl=64 time=0.140 ms
64 bytes from 172.25.0.3: icmp_seq=2 ttl=64 time=0.099 ms
^C
--- 172.25.0.3 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1021ms
rtt min/avg/max/mdev = 0.099/0.119/0.140/0.023 ms

The possible options for network management are vast. Here are two more examples.

It is possible to add a DNS server address when launching a container:

[root@cb2875ab1059 /]# exit
exit
root@debian11:~# docker stop mongo2
mongo2
root@debian11:~# docker rm mongo2
mongo2
root@debian11:~# docker run -it --name mongo2 --dns 8.8.8.8 i2tch/mongodb2 bash
root@aa2717305397:/# cat /etc/resolv.conf
nameserver 8.8.8.8

Or pass an entry for the /etc/hosts file:

root@aa2717305397:/# exit
exit
root@debian11:~# docker stop mongo2
mongo2
root@debian11:~# docker rm mongo2
mongo2
root@debian11:~# docker run -it --name mongo2 --add-host mickeymouse:127.0.0.1 i2tch/mongodb2 bash
root@519423c7fb32:/# cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
127.0.0.1 mickeymouse
172.17.0.2 519423c7fb32
root@519423c7fb32:/# exit
exit
root@debian11:~#

Host

This type of network is used in cases where the network does not need to be isolated from the host while isolating other aspects of the container. Containers use the same interface as the host by taking the same IP address as the host machine.

In the case of the virtual machine, the IP address of the interface connected to the local network is 10.0.3.46 :

root@debian11:~# ip addr show ens18
2: ens18: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 56:a3:fd:18:02:6d brd ff:ff:ff:ff:ff:ff
altname enp0s18
inet 10.0.3.46/24 brd 10.0.3.255 scope global noprefixroute ens18
valid_lft forever preferred_lft forever
inet6 fe80::54a3:fdff:fe18:26d/64 scope link noprefixroute
valid_lft forever preferred_lft forever

Boot a container from the centos image in a host network :

root@debian11:~# docker run -it --rm --network host --name centos3 centos bash
[root@debian11 /]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens18: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 56:a3:fd:18:02:6d brd ff:ff:ff:ff:ff:ff
altname enp0s18
inet 10.0.3.46/24 brd 10.0.3.255 scope global noprefixroute ens18
valid_lft forever preferred_lft forever
inet6 fe80::54a3:fdff:fe18:26d/64 scope link noprefixroute
valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:07:c9:88:32 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:7ff:fec9:8832/64 scope link
valid_lft forever preferred_lft forever
102: br-4d26c1192dd7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:2d:69:ac:d5 brd ff:ff:ff:ff:ff:ff
inet 172.25.0.1/16 brd 172.25.255.255 scope global br-4d26c1192dd7
valid_lft forever preferred_lft forever
inet6 fe80::42:2dff:fe69:acd5/64 scope link
valid_lft forever preferred_lft forever
104: vethc5ca04a@if103: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether 42:98:9a:1c:41:76 brd ff:ff:ff:ff:ff:ff link-netnsid 2
inet6 fe80::4098:9aff:fe1c:4176/64 scope link
valid_lft forever preferred_lft forever
106: veth6a46250@if105: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether 5e:9d:9a:86:23:b0 brd ff:ff:ff:ff:ff:ff link-netnsid 3
inet6 fe80::5c9d:9aff:fe86:23b0/64 scope link
valid_lft forever preferred_lft forever
108: vethc5ccfca@if107: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-4d26c1192dd7 state UP group default
link/ether f2:37:cb:08:ff:8f brd ff:ff:ff:ff:ff:ff link-netnsid 2
inet6 fe80::f037:cbff:fe08:ff8f/64 scope link
valid_lft forever preferred_lft forever
110: vetha87ff61@if109: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-4d26c1192dd7 state UP group default
link/ether 2e:e0:2d:5c:5d:c7 brd ff:ff:ff:ff:ff:ff link-netnsid 3
inet6 fe80::2ce0:2dff:fe5c:5dc7/64 scope link
valid_lft forever preferred_lft forever
[root@debian11 /]# hostname
debian11
[root@debian11 /]# exit
exit
root@debian11:~#

The purpose of this type of network is to allow access to services in the container directly from the IP address of the Docker host. For example, a nginx in the container could be reached directly on 10.0.3.46:80 without needing to go through port exposure.

For this reason, in the case of the -p option used in the host network, this option is not taken into account and produces the warning WARNING: Published ports are discarded when using host network mode. The major use of the host network is therefore in the case where multiple ports in the container need to be reachable.

Important: Note that the host type network only works on Linux. It is therefore incompatible with Docker Desktop for Mac, Docker Desktop for Windows and Docker EE for Windows Server.

None

This type of network is mainly used when using a network plugin available in the Docker Hub.

It is therefore possible to launch a completely watertight container using the none network:

root@debian11:~# docker stop mongo2
mongo2
root@debian11:~# docker rm mongo2
mongo2
root@debian11:~# docker run -it --name mongo2 --network none i2tch/mongodb2 bash
root@5bfbf0306ad7:/#
===Links===
The mechanism of links between containers is very powerful and makes it easy to reach another container, provided that the two containers are on the same network. Create a container called **centos3** which is linked to the **centos2** container which it also knows under the alias **alias**:
<code>
root@332aa9930f30:/# exit
exit
root@debian9:~# docker run -itd --name centos3 --link centos2:alias centos
6a315259b2946c3bf2bb69f608cbe910d87edaadedb4f805e7a4dbf6af1eb916
root@debian9:~# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6a315259b294 centos "/bin/bash" 33 seconds ago Up 32 seconds centos3
332aa9930f30 i2tch/mongodb2 "docker-entrypoint..." 3 minutes ago Exited (127) 39 seconds ago mongo2
aaed3bc8e404 centos "/bin/bash" 16 minutes ago Up 16 minutes centos2
9f36a628c72b centos "/bin/bash" 16 minutes ago Up 16 minutes centos1
2169360fcbfd centos "/bin/bash" 20 minutes ago Up 20 minutes resotest
ea239635e141 testcache "more /tmp/moment" 7 hours ago Exited (0) 7 hours ago test1
21b0490a93dd i2tch/mydocker "/entrypoint.sh my..." 7 hours ago Exited (137) 6 hours ago myDocker
bdb4bc0f81de i2tch/mongodb1 "docker-entrypoint..." 18 hours ago Created 27017/tcp mongo1
f5b45072b831 i2tch/mongodb "bash" 19 hours ago Exited (137) 6 hours ago mongo
9731a48f126a nginx "nginx -g 'daemon ..." 19 hours ago Exited (0) 6 hours ago cocky_gates
eacd70596e23 nginx "nginx -g 'daemon ..." 19 hours ago Exited (0) 19 hours ago adoring_yonath
cffb4456e9c4 ubuntu "/bin/bash" 20 hours ago Exited (0) 20 hours ago i2tch
root@debian11:~# docker exec -it centos3 bash
[root@57e92a8b25d7 /]# ping centos2
PING alias (172.17.0.4) 56(84) bytes of data.
64 bytes from alias (172.17.0.4): icmp_seq=1 ttl=64 time=0.146 ms
64 bytes from alias (172.17.0.4): icmp_seq=2 ttl=64 time=0.088 ms
64 bytes from alias (172.17.0.4): icmp_seq=3 ttl=64 time=0.081 ms
64 bytes from alias (172.17.0.4): icmp_seq=4 ttl=64 time=0.070 ms
^C
--- alias ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3079ms
rtt min/avg/max/mdev = 0.070/0.096/0.146/0.030 ms
[root@57e92a8b25d7 /]# cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.4 alias fc417b22a20d centos2
172.17.0.2 57e92a8b25d7
[root@57e92a8b25d7 /]# exit
exit
root@debian11:~#
root@debian11:~# docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' centos3
172.17.0.2

Note, however, that the link is unidirectional:

root@debian11:~# docker exec -it centos2 bash
[root@fc417b22a20d /]# ping centos3
ping: centos3: Name or service not known
[root@fc417b22a20d /]# ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.097 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.082 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.125 ms
^C
--- 172.17.0.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2029ms
rtt min/avg/max/mdev = 0.082/0.101/0.125/0.019 ms

In the case above, centos2 can reach centos3 using the IP address 172.17.0.2 because centos2 is in both networks with IP addresses 172.17.0.4 and 172.25.0.3 :

[root@fc417b22a20d /]# exit
exit
root@debian11:~# docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' centos2
172.17.0.4172.25.0.3

2.2 - Launching Wordpress in a container

Create the ~/wordpress directory and place yourself in it:

root@debian11:~# mkdir ~/wordpress && cd ~/wordpress

Create a container called wordpressdb from the mariadb:latest image:

root@debian11:~/wordpress# docker run -e MYSQL_ROOT_PASSWORD=fenestros -e MYSQL_DATABASE=wordpress --name wordpressdb -v "$PWD/database":/var/lib/mysql -d mysql:latest
Unable to find image 'mysql:latest' locally
latest: Pulling from library/mysql
e9f2695d7e5b: Pull complete
80c6055edb33: Pull complete
c646ab461d8b: Pull complete
012006c6a591: Pull complete
929d5fa34b95: Pull complete
17e0243877fa: Pull complete
1850b459cd2f: Pull complete
8dceaed53baf: Pull complete
197b834ea1cd: Pull complete
8df78c25b227: Pull complete
Digest: sha256:ceb98918916bd5261b3e9866ac8271d75d276b8a4db56f1dc190770342a77a9b
Status: Downloaded newer image for mysql:latest
db3732939266ed8a112857db9c970ca39571785e62db74175bda9be5a0f9d726

Check that the container is working:

root@debian11:~/wordpress# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
db3732939266 mysql:latest "docker-entrypoint.s…" About a minute ago Up 52 seconds 3306/tcp, 33060/tcp wordpressdb
57e92a8b25d7 centos "/bin/bash" 12 minutes ago Up 12 minutes centos3
fc417b22a20d centos "/bin/bash" 25 minutes ago Up 25 minutes centos2
cb2875ab1059 centos "/bin/bash" 26 minutes ago Up 25 minutes centos1
2126924504d8 centos "/bin/bash" 29 minutes ago Up 29 minutes resotest

Create a container called wordpress linked to the wordpressdb container:

root@debian11:~/wordpress# docker run -e WORDPRESS_DB_USER=root -e WORDPRESS_DB_PASSWORD=fenestros --name wordpress --link wordpressdb:mysql -p 10.0.3.46:80:80 -v "$PWD/html":/var/www/html -d wordpress
Unable to find image 'wordpress:latest' locally
latest: Pulling from library/wordpress
1f7ce2fa46ab: Already exists
48824c101c6a: Pull complete
249ff3a7bbe6: Pull complete
aa5d47f22b64: Pull complete
851cb5d3b62c: Pull complete
090f07e09d3e: Pull complete
74f97600920f: Pull complete
f48a9f994636: Pull complete
108b4c091efa: Pull complete
94f753607622: Pull complete
5d0ec11ef45d: Pull complete
87757e6fac28: Pull complete
899a04597fc2: Pull complete
44506e60b7c1: Pull complete
305ecc1d68f5: Pull complete
a4e6cb47406c: Pull complete
8d4e2943ab66: Pull complete
cab275157cee: Pull complete
b12b496c1035: Pull complete
5bc81c9fd938: Pull complete
e737031fb816: Pull complete
Digest: sha256:3a2a8b925c86967a43027ec3ba146e1859de1fa0f0f535dd9b40f4d39f8b9caa
Status: Downloaded newer image for wordpress:latest
63fec083f4d6bb6a17563d9c6b4aefce2430abea6a2172997038c8f6edabab78

Check that the container is working:

root@debian11:~/wordpress# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
63fec083f4d6 wordpress "docker-entrypoint.s…" About a minute ago Up About a minute 10.0.3.46:80->80/tcp wordpress
db3732939266 mysql:latest "docker-entrypoint.s…" 6 minutes ago Up 6 minutes 3306/tcp, 33060/tcp wordpressdb
57e92a8b25d7 centos "/bin/bash" 18 minutes ago Up 18 minutes centos3
fc417b22a20d centos "/bin/bash" 31 minutes ago Up 31 minutes centos2
cb2875ab1059 centos "/bin/bash" 31 minutes ago Up 31 minutes centos1
2126924504d8 centos "/bin/bash" 35 minutes ago Up 35 minutes resotest

Check that Wordpress is working:

root@debian11:~/wordpress# lynx --dump http://10.0.3.46
WordPress
Select a default language [English (United States)__________]
Continue
root@debian11:~/wordpress#
root@debian11:~/wordpress# cd -
/root
root@debian11:~#

2.3 - Managing a Microservices Architecture

You are going to set up a simple application in the form of microservices, developed by Docker and called demo-voting-app, :

In this application, the voting-app container allows you to vote for cats or dogs. This application runs under Python and provides an HTML interface:

During the vote, the result of the vote is stored in Redis in an in-memory database. The result is then passed to the Worker container, which runs under .NET and updates the persistent database in the db container, which runs under PostgreSQL.

The result-app application running in NodeJS then reads the table from the PostgreSQL database and displays the result in HTML format:

This application can be set up under docker with the following commands:

root@debian11:~# docker run -d --name=redis redis
Unable to find image 'redis:latest' locally
latest: Pulling from library/redis
1f7ce2fa46ab: Already exists
4827e9d1e197: Pull complete
5845062cfda9: Pull complete
44d659adcf8b: Pull complete
b6962d83313d: Pull complete
5d29cf86ecab: Pull complete
4f4fb700ef54: Pull complete
3a2d9f90268c: Pull complete
Digest: sha256:396b0f027ba2f33bf385771a621b58c1fd834fd2c522c35c98fd24fc17863c2f
Status: Downloaded newer image for redis:latest
227554e3e4c198272cbf21dd468e7cf78d4a75ad5ed000a9df364aa98726bc86
root@debian11:~# docker run -d --name=db -e POSTGRES_PASSWORD=postgres -e POSTGRES_USER=postgres postgres:9.4
Unable to find image 'postgres:9.4' locally
9.4: Pulling from library/postgres
619014d83c02: Pull complete
7ec0fe6664f6: Pull complete
9ca7ba8f7764: Pull complete
9e1155d037e2: Pull complete
febcfb7f8870: Pull complete
8c78c79412b5: Pull complete
5a35744405c5: Pull complete
27717922e067: Pull complete
36f0c5255550: Pull complete
dbf0a396f422: Pull complete
ec4c06ea33e5: Pull complete
e8dd33eba6d1: Pull complete
51c81b3b2c20: Pull complete
2a03dd76f5d7: Pull complete
Digest: sha256:42a7a6a647a602efa9592edd1f56359800d079b93fa52c5d92244c58ac4a2ab9
Status: Downloaded newer image for postgres:9.4
5083545dcbf88ed9d1e605d306fe8dba86df1c130fcc843e7fba30eadd524545
root@debian11:~# docker run -d --name=vote -p 5000:80 --link redis:redis dockersamples/examplevotingapp_vote
Unable to find image 'dockersamples/examplevotingapp_vote:latest' locally
latest: Pulling from dockersamples/examplevotingapp_vote
a378f10b3218: Pull complete
c11bdfacfd25: Pull complete
64fc9a66a5d8: Pull complete
5146634606ba: Pull complete
479ce1f6823a: Pull complete
070425b38bdc: Pull complete
ce42fc94cbff: Pull complete
6bad37ec452b: Pull complete
edf50a17349a: Pull complete
db9bdfb7847f: Pull complete
Digest: sha256:797919beacc239d80f6c568e170ad4be0a6afd0ff0567e89d45f1dc3350b87f7
Status: Downloaded newer image for dockersamples/examplevotingapp_vote:latest
81e6fcb9f6920c048b3062e3da8e7e48b0475e5de3059ff3e5e63cbf73cb5fe6
root@debian11:~# docker run -d --name=result -p 5001:80 --link db:db dockersamples/examplevotingapp_result
Unable to find image 'dockersamples/examplevotingapp_result:latest' locally
latest: Pulling from dockersamples/examplevotingapp_result
a378f10b3218: Already exists
bc194d4002b7: Pull complete
231a505b2fbc: Pull complete
71731700a241: Pull complete
9c2ee871f3d2: Pull complete
a5ec303d8450: Pull complete
0548d3f3cdbd: Pull complete
c33ac9356c9f: Pull complete
495a50ede288: Pull complete
66140bd7f458: Pull complete
4d77129208cd: Pull complete
Digest: sha256:0b8fe15d93c08b9b90ad2eba02af526c1bee8bc9fab162a6b93b3186aa0a5faf
Status: Downloaded newer image for dockersamples/examplevotingapp_result:latest
33a264a36bdc63ba7c0a4e3412e437d20357b1142a02e26b6f6ccfb4aaab6cf2
root@debian11:~# docker run -d --name=worker --link db:db --link redis:redis dockersamples/examplevotingapp_worker
Unable to find image 'dockersamples/examplevotingapp_worker:latest' locally
latest: Pulling from dockersamples/examplevotingapp_worker
e67fdae35593: Pull complete
0ab66724116f: Pull complete
14ccddebb1bc: Pull complete
5e265b51b431: Pull complete
9ac34f7bda15: Pull complete
17081859cc14: Pull complete
Digest: sha256:bfa42cb2a0200cef7d384635225ca670f08c063341fc401bd27bae67ba6afc04
Status: Downloaded newer image for dockersamples/examplevotingapp_worker:latest
cf27f30654d2c527f30c1ed4b80a517ab589dc1579c30af7bd4e53eba746354a
root@debian11:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cf27f30654d2 dockersamples/examplevotingapp_worker "dotnet Worker.dll" 7 seconds ago Up 3 seconds worker
33a264a36bdc dockersamples/examplevotingapp_result "/usr/bin/tini -- no…" 31 seconds ago Up 26 seconds 0.0.0.0:5001->80/tcp, :::5001->80/tcp result
81e6fcb9f692 dockersamples/examplevotingapp_vote "gunicorn app:app -b…" 55 seconds ago Up 50 seconds 0.0.0.0:5000->80/tcp, :::5000->80/tcp vote
5083545dcbf8 postgres:9.4 "docker-entrypoint.s…" About a minute ago Up About a minute 5432/tcp db
227554e3e4c1 redis "docker-entrypoint.s…" About a minute ago Up About a minute 6379/tcp redis
63fec083f4d6 wordpress "docker-entrypoint.s…" 43 minutes ago Up 42 minutes 10.0.3.46:80->80/tcp wordpress
db3732939266 mysql:latest "docker-entrypoint.s…" 48 minutes ago Up 48 minutes 3306/tcp, 33060/tcp wordpressdb
57e92a8b25d7 centos "/bin/bash" 59 minutes ago Up 59 minutes centos3
fc417b22a20d centos "/bin/bash" About an hour ago Up About an hour centos2
cb2875ab1059 centos "/bin/bash" About an hour ago Up About an hour centos1
2126924504d8 centos "/bin/bash" About an hour ago Up About an hour resotest

This solution uses a Bridge type network. This type of network is limited to containers on a single host running Docker. Containers can only communicate with each other and they are not accessible from the outside. In order for containers on the network to communicate or be accessible from the outside world, port mapping must be configured.

LAB #3 - Supervising Containers

3.1 - The logs

View the logs of a container:

root@debian11:~# docker logs mongo2
root@5bfbf0306ad7:/# ip a
bash: ip: command not found
root@5bfbf0306ad7:/# ip addr
bash: ip: command not found
root@5bfbf0306ad7:/# exit
exit

3.2 - Processes

View the processes in a container :

root@debian11:~# docker top centos3
UID PID PPID C STIME TTY TIME CMD
root 818263 818243 0 15:49 pts/0 00:00:00 /bin/bash

3.3 - Continuous Activityu

To see the activity of a container, use the following command:

root@debian11:~# docker stats centos3
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
57e92a8b25d7 centos3 0.00% 880KiB / 15.62GiB 0.01% 4.72kB / 854B 0B / 4.1kB 1
^C
root@debian11:~#

Copyright © 2023 Hugh Norris.