Network communication is essential part of Docker container technology. This technology usages to communicate between various level of components.
A container can have communication with some other container and even can have communication with host or internet as well.
As per below image we can see basic ways of container communication.
As per above image we can categorize networking for container as below. And this categorization is just simple category even more complex component communication could be there.
1=> Container to Internet Communication: This type of communication is between Container to Internet, whereas information is pushed/pulled from specific website or API.
2=> Container to Local Host Communication: This type of communication is between Container to Local Host, whereas information is pushed/pull to Local Host.
3=> Container to Container Communication: This type of communication is between Container to Container, where one container gets/push information to another Container.
Let we do practice on each type of communication as mentioned above one by one.
1=> Container to Internet Communication:
As mentioned above this type of communication will push/pull information from internet. Let we have a test application as below.
=> In this test we will pull information from "http://www.example.com/" whereas this website only contains few lines in in html pages as below
=> Below is sample Python project using a Dockerfile that uses www as an HTTP GET request
=> Container will pull information from above website and then it will display on screen of Visual Code Studio.
=> Application has been created in Python language.
=> Download attached file for this practice and unzip the same in directory on local host and open that directory in Visual Code Studio.
Download Source code from Container_to_WWW
PS D:\Docker> docker images PS D:\Docker> PS D:\Docker> docker build -t container_to_www . [+] Building 3.2s (9/9) FINISHED => [internal] load .dockerignore 0.1s => => transferring context: 2B 0.0s => [internal] load build definition from Dockerfile 0.1s => => transferring dockerfile: 439B 0.0s => [internal] load metadata for docker.io/library/python:3.9 3.0s => [1/4] FROM docker.io/library/python:3.9@sha256:ba10a2af9d6c3bd0d20c46ecbf866dabcbad4e6a3dd7b82e2dfb1a9b6d479d87 0.0s => [internal] load build context 0.0s => => transferring context: 221B 0.0s => CACHED [2/4] WORKDIR /app 0.0s => CACHED [3/4] COPY . /app 0.0s => CACHED [4/4] RUN pip install --trusted-host pypi.python.org -r requirements.txt 0.0s => exporting to image 0.0s => => exporting layers 0.0s => => writing image sha256:ab7aebe1590a18b0ea36223e9b9df5fb5ac2d6a4ad4e198b12058ab8d4774886 0.0s => => naming to docker.io/library/container_to_www 0.0s PS D:\Docker> PS D:\Docker> PS D:\Docker> docker run --rm container_to_www 200 <!doctype html> <html> <head> <title>Example Domain</title> <meta charset="utf-8" /> <meta http-equiv="Content-type" content="text/html; charset=utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <style type="text/css"> body { background-color: #f0f0f2; margin: 0; padding: 0; font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; } div { width: 600px; margin: 5em auto; padding: 2em; background-color: #fdfdff; border-radius: 0.5em; box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02); } a:link, a:visited { color: #38488f; } @media (max-width: 700px) { div { margin: 0 auto; width: auto; } } </style> </head> <body> <div> <h1>Example Domain</h1> <p>This domain is for use in illustrative examples in documents. You may use this domain in literature without prior coordination or asking for permission.</p> <p><a href="https://www.iana.org/domains/example">More information...</a></p> </div> </body> </html> PS D:\Docker> PS D:\Docker>
As we can see App Container is able to fetch information from mentioned website. We can further store/edit this information in database or file.
2=> Container to Local Host Communication:
As mentioned above this type of communication will push/pull information from Local Host. Let we have a test application as below.
=> In this test Container will pull information from Local Host's excel sheet, whereas this sheet contains 3 rows and 2 columns as below.
=> Below is sample Python project using a Dockerfile that uses panda and python for the same.
=> Container will pull information from Local Host's data.xls sheet and then it will display on screen of Visual Code Studio.
=> Application has been created in Python language.
=> Download attached file for this practice and unzip the same in directory on local host and open that directory in Visual Code Studio.
=> In this practice You can mount your local directory that contains the excel file to the container directory using the -v flag. For example, if your excel file is in /home/user/data.xls.
Download Source code from Container_to_LocalHost
PS D:\Docker> docker build -t container_to_local . 2023/07/21 12:50:58 http2: server: error reading preface from client //./pipe/docker_engine: file has already been closed [+] Building 42.6s (9/9) FINISHED => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => [internal] load build definition from Dockerfile 0.1s => => transferring dockerfile: 444B 0.0s => [internal] load metadata for docker.io/library/python:3.9-slim 3.3s => [1/4] FROM docker.io/library/python:3.9-slim@sha256:1981920906ec577fb1a83bffca080ad659692688e80aee4cfe58d4642ac108e 13.4s => => resolve docker.io/library/python:3.9-slim@sha256:1981920906ec577fb1a83bffca080ad659692688e80aee4cfe58d4642ac108e8 0.0s => => sha256:8907808d3b44847339337650291bd7335df77de15bcfe60067c5ea722827507b 1.37kB / 1.37kB 0.0s => => sha256:ba55b0c3bfaac86103a5fc4c41ddf0197a4adf4dc9be2a4f5f517ba458280826 6.91kB / 6.91kB 0.0s => => sha256:faef57eae888cbe4a5613eca6741b5e48d768b83f6088858aee9a5a2834f8151 29.12MB / 29.12MB 5.8s => => sha256:36578dff3c0fff67d9b9ae5e14142d1ac9db66c0d7257ac839d956ce63402d64 3.50MB / 3.50MB 1.5s => => sha256:dc5bc15716acbc025c03967a49b525d09c6c9ec16f8481cfb9d817a6838df959 16.94MB / 16.94MB 2.9s => => sha256:1981920906ec577fb1a83bffca080ad659692688e80aee4cfe58d4642ac108e8 1.86kB / 1.86kB 0.0s => => sha256:f127de16bbdd6992261b9ea20fe2bea9f26a06f294733544e63a8ad1e2208c4f 244B / 244B 1.8s => => sha256:02fcdd01704cd15b92a2ea7a238a48b6178aedb087841c25fb116cac953723dc 3.13MB / 3.13MB 3.1s => => extracting sha256:faef57eae888cbe4a5613eca6741b5e48d768b83f6088858aee9a5a2834f8151 3.1s => => extracting sha256:36578dff3c0fff67d9b9ae5e14142d1ac9db66c0d7257ac839d956ce63402d64 0.3s => => extracting sha256:dc5bc15716acbc025c03967a49b525d09c6c9ec16f8481cfb9d817a6838df959 2.6s => [internal] load build context 0.1s PS D:\Docker> docker run -v "D:/Docker:/app" container_to_local The excel file has 3 rows and 2 columns. Fruit Name Description 0 Apple An apple is a round, edible fruit produced by ... 1 Orange An orange is a fruit of various citrus species... 2 Mango A mango is an edible stone fruit produced by t...
3=> Container to Container Communication:
As mentioned above this type of communication will push/pull information from another Container and vice versa. Let we have a test application as below.
=> In this test case we will be using Postman API software , which will use to PULL/PUSH information to and from database and API services.
=> We will use API which is as https://swapi.dev/ this will fetch movie information and store into database from Web.
=> we will use Mongo DB as out storage database and from there information will be Pulled.
Please download below attached zip file for this practice.
Download Source code from cross_container_communication
1=> Let first we prepare our Mongodb image as below
PS D:\Docker> docker run -d --name mongodb mongo
2=>Let we fetch the IP address for this mongodb container as below. We will replace this IP in our json file for further processing.
PS D:\Docker> docker container inspect mongodb [ { "Id": "207c9b9c0ec3957e2ea7a184a23b7016dc5e4acb977ccc0a67bcb33f9e265e59", "Created": "2023-07-24T07:51:39.53993459Z", "Path": "docker-entrypoint.sh", "Args": [ "mongod" ... ... "NetworkSettings": { "Bridge": "", "SandboxID": "ba1de7caf23ea1e3ab0002eaa3df8d5a6d0b08cc4f8da9327f4321f9f5fa9508", "HairpinMode": false, "LinkLocalIPv6Address": "", "LinkLocalIPv6PrefixLen": 0, "Ports": { "27017/tcp": null }, "SandboxKey": "/var/run/docker/netns/ba1de7caf23e", "SecondaryIPAddresses": null, "SecondaryIPv6Addresses": null, "EndpointID": "3d9fdf655c1dbe0dafc439b978c13c4df7d87747033ba03dfe6fc8743f814129", "Gateway": "172.17.0.1", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "IPAddress": "172.17.0.2", "IPPrefixLen": 16, "IPv6Gateway": "", "MacAddress": "02:42:ac:11:00:02", "Networks": { "bridge": { "IPAMConfig": null, "Links": null, "Aliases": null, "NetworkID": "e42054b6efd38d2d821056e07ff3a2b87958a2f365dcf9dff2755eba4823a14b", "EndpointID": "3d9fdf655c1dbe0dafc439b978c13c4df7d87747033ba03dfe6fc8743f814129", "Gateway": "172.17.0.1", "IPAddress": "172.17.0.2", "IPPrefixLen": 16, "IPv6Gateway": "", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "MacAddress": "02:42:ac:11:00:02", "DriverOpts": null } } } } ]
3=> Replace this IP in app.js file as below.
mongoose.connect('mongodb://172.17.0.2:27017/swfavorites',{ useNewUrlParser: true },(err) => {if (err) {console.log(err);} else {app.listen(3000);}});
=> Save it and create new image file as below.
PS D:\Docker> docker build -t favorites-node .
4=> As of now we do have below images and containers
PS D:\Docker> docker images REPOSITORY TAG IMAGE ID CREATED SIZE favorites-node latest 8bdeacc2b56a 2 hours ago 1.12GB mongo latest fb5fba25b25a 10 days ago 654MB PS D:\Docker> PS D:\Docker> PS D:\Docker> docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c5decfa80457 favorites-node "docker-entrypoint.s…" 2 hours ago Up 2 hours 0.0.0.0:3000->3000/tcp favorites 207c9b9c0ec3 mongo "docker-entrypoint.s…" 2 hours ago Up 2 hours 27017/tcp mongodb PS D:\Docker>
at this stage our application is ready now we will use POSTMAN api tool to pull and push data inside mongo db as below,
=> Open postman api tool and fetch data from mongo db as below.
Here was can see blank records available in favorite array , which say that it's able to fetch data from database but having no records.
=> Let we Push records in mongo DB database as below from postman api using application.
And we can see we are able to insert data and save the same.
=> Let we fetch saved information from mongodb database as below.
As we can see we are able to fetch the information from another container using favorites app container.
Cross container communication using --network option in docker container
As we saw in last example cross container communication happed using absolute IP address of particular container. But this is not good practice to do the same.
So to resolve this issue there is --network option in docker container .
--network in docker is a flag that allows you to specify the network that a container should attach to when it is created or run. Docker provides different types of networks for different use cases, such as bridge, host, overlay, macvlan, and none. By default, a container attaches to the bridge network, which is a private network created by Docker on the host. You can also create your own user-defined networks using the docker network create command.
Using the --network flag, you can connect a container to one or more networks and enable communication between containers on the same or different networks. For example, you can use docker run --network app-net web to run a web server container on a user-defined network called app-net. You can also use docker network connect to connect an existing container to another network.
The --network flag also supports some options, such as --ip or --ip6, which allow you to specify the IP address of the container on the network. For example, you can use docker run --network app-net --ip 172.18.0.3 web to run a web server container on app-net with a specific IP address.
The --network flag is useful for creating and managing networks that suit your application needs. For example, you can create a two-tier network using docker-compose that consists of a web server and a database server on separate networks
To enable cross container communication using --network in docker container, you need to follow these steps:
• Create a user-defined network using the command docker network create <network-name>. For example, docker network create app-net.
• Run the containers using the --network flag and specify the network name. For example, docker run -d --name web --network app-net web and docker run -d --name db --network app-net db.
• Use the container name as the hostname to connect to the other container. For example, in the web server container, you can use db as the host name to connect to the database container.
PS D:\Docker> docker network create My_Network ef03d7e277b0ecd7e82bdca1a0dd0def855d5dc1e91687315da5cde2687610de PS D:\Docker> docker network ls NETWORK ID NAME DRIVER SCOPE ef03d7e277b0 My_Network bridge local e42054b6efd3 bridge bridge local c5e1b0d9cd12 host host local 15f453b1a3be none null local PS D:\Docker\app> docker network create todo-app 15a5ae1fd972d5aec5f4e95465d89a8cad30d2357bc00747b27d1f1a807821b1 PS D:\Docker\app> docker network ls NETWORK ID NAME DRIVER SCOPE ef03d7e277b0 My_Network bridge local e42054b6efd3 bridge bridge local c5e1b0d9cd12 host host local 15f453b1a3be none null local 15a5ae1fd972 todo-app bridge local PS D:\Docker\app>
Let we use the same option and perform the new test as below.
Download Source code from Using Bridge Network
Step 1=> Let we create a bridge as nework as below.
PS D:\Docker\app> docker network create todo-app 15a5ae1fd972d5aec5f4e95465d89a8cad30d2357bc00747b27d1f1a807821b1 PS D:\Docker\app> docker network ls NETWORK ID NAME DRIVER SCOPE ef03d7e277b0 My_Network bridge local e42054b6efd3 bridge bridge local c5e1b0d9cd12 host host local 15f453b1a3be none null local 15a5ae1fd972 todo-app bridge local PS D:\Docker\app>
Step 2=> Create a Mysql DB image as below
$ docker run -d `
--network todo-app --network-alias mysql `
-v todo-mysql-data:/var/lib/mysql `
-e MYSQL_ROOT_PASSWORD=secret `
-e MYSQL_DATABASE=todos `
mysql:8.0Step 3=> Let we create application image as below.
$ docker run -dp 127.0.0.1:3000:3000 `
-w /app -v "$(pwd):/app" `
--network todo-app `
-e MYSQL_HOST=mysql `
-e MYSQL_USER=root `
-e MYSQL_PASSWORD=secret `
-e MYSQL_DB=todos `
node:18-alpine `
sh -c "yarn install && yarn run dev"Step 4=> Check below containers and open the logs for application container and wait for below output.
PS D:\Docker\app> docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 0387448dbf0f node:18-alpine "docker-entrypoint.s…" 8 minutes ago Up 8 minutes 127.0.0.1:3000->3000/tcp flamboyant_poitras cdeb22b2edc3 mysql:8.0 "docker-entrypoint.s…" 9 minutes ago Up 9 minutes 3306/tcp, 33060/tcp busy_spence PS D:\Docker\app> PS D:\Docker\app> docker logs -f 0387448dbf0f yarn install v1.22.19 [1/4] Resolving packages... [2/4] Fetching packages... [3/4] Linking dependencies... $ nodemon src/index.js [nodemon] 2.0.20 [nodemon] to restart at any time, enter `rs` [nodemon] watching path(s): *.* [nodemon] watching extensions: js,mjs,json [nodemon] starting `node src/index.js` Waiting for mysql:3306. Connected! Connected to mysql db at host mysql Listening on port 3000 PS D:\Docker\app>
Step 5=> Open a Browser and type below URL . And New Items as below.
http://localhost:3000/
Step 6=> Let we verify the details from Database as below. Use password as "secret"
PS D:\Docker\app> docker exec -it cdeb22b2edc3 mysql -p todos Enter password: Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 12 Server version: 8.0.33 MySQL Community Server - GPL Copyright (c) 2000, 2023, Oracle and/or its affiliates. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> mysql> mysql> select * from todo_items; +--------------------------------------+---------------+-----------+ | id | name | completed | +--------------------------------------+---------------+-----------+ | 8b227f2d-365c-4652-963b-29ca8ee929f5 | St. Xavier | 0 | | 3b2bb678-ab35-4a03-a6ff-feb3b1530332 | Anderson | 0 | | 2f5eaf7b-5fe1-4f7a-ac95-dd6916aeb9ba | James Matthew | 0 | +--------------------------------------+---------------+-----------+ 3 rows in set (0.00 sec) mysql>
So we can see data is being stored in database and we have used --network option as well.

No comments:
Post a Comment