Docker - komunikacja między kontenerami za pomocą ip

Autor podstrony: Krzysztof Zajączkowski

Stronę tą wyświetlono już: 746 razy

Rozmowa między kontenerowa może być zrealizowana na dwa sposoby. Pierwszy z nich to użycie adresów ip, jakie Docker nadaje każdemu kontenerowi. Do zademonstrowania działania posłużę się obrazem bazy danych mongo:

docker run -d --name mongodb mongo
docker: error during connect: This error may indicate that the docker daemon is not running.: Post "http://%2F%2F.%2Fpipe%2Fdocker_engine/v1.24/containers/create?name=mongodb": open //./pipe/docker_engine: Nie można odnaleźć określonego pliku.
See 'docker run --help'.
Unable to find image 'mongo:latest' locally
latest: Pulling from library/mongo
d7bfe07ed847: Pull complete
97ef66a8492a: Pull complete
20cec14c8f9e: Pull complete
38c3018eb09a: Pull complete
ccc9e1c2556b: Pull complete
593c62d03532: Pull complete
1a103a446c3f: Pull complete
be887b845d3f: Pull complete
e5543880b183: Pull complete
Digest: sha256:37e84d3dd30cdfb5472ec42b8a6b4dc6ca7cacd91ebcfa0410a54528bbc5fa6d
Status: Downloaded newer image for mongo:latest
169b2d38e2d821a6fd82cd126b6653274249d1972d33aae58986daffa588cd9b

Potrzebny też będzie serwer, który z tą bazą się będzie komunikował (cały serwer można pobrać z załącznika na dole strony). Ja do tego celu posłużyłem się napisanym b node prostym serwerem. Główna jego część, zawierająca połączenie do bazy danych wygląda następująco:

const express = require('express'); const mongoose = require('mongoose'); const wishesRouter = require('./routes/wishes.route'); const homeRouter = require('./routes/home.route'); const app = express(); app.use(express.json()); app.use('/', homeRouter); app.use('/', wishesRouter); app.get('/test', (req, res, next) => { res.end('<h2>Hello test d!</h2>') }) app.get('/wishes') mongoose.connect( // połączenie serwera za pomocą Docker-owego adresu IP 'mongodb://172.17.0.2:27017/wisches', { useNewUrlParser: true }, (err) => { if (err) { console.log(err); } else { app.listen(8888); // uruchomienie serwera na porcie 8888 } } )

Jak jednak zdobyć można informację o tym tajemniczym adresie ip ano bardzo prosto, korzystając z następującego polecenia:

docker container inspect mongodb
[
    {
        "Id": "169b2d38e2d821a6fd82cd126b6653274249d1972d33aae58986daffa588cd9b",
        "Created": "2022-06-21T17:41:31.6836661Z",
        "Path": "docker-entrypoint.sh",
        "Args": [
            "mongod"
        ],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 1505,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2022-06-21T17:41:32.3891246Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
        },
        "Image": "sha256:c8b57c4bf7e3a88daf948d5d17bc7145db05771e928b3b3095ca4590719b5469",
        "ResolvConfPath": "/var/lib/docker/containers/169b2d38e2d821a6fd82cd126b6653274249d1972d33aae58986daffa588cd9b/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/169b2d38e2d821a6fd82cd126b6653274249d1972d33aae58986daffa588cd9b/hostname",
        "HostsPath": "/var/lib/docker/containers/169b2d38e2d821a6fd82cd126b6653274249d1972d33aae58986daffa588cd9b/hosts",
        "LogPath": "/var/lib/docker/containers/169b2d38e2d821a6fd82cd126b6653274249d1972d33aae58986daffa588cd9b/169b2d38e2d821a6fd82cd126b6653274249d1972d33aae58986daffa588cd9b-json.log",
        "Name": "/mongodb",
        "RestartCount": 0,
        "Driver": "overlay2",
        "Platform": "linux",
        "MountLabel": "",
        "ProcessLabel": "",
        "AppArmorProfile": "",
        "ExecIDs": null,
        "HostConfig": {
            "Binds": null,
            "ContainerIDFile": "",
            "LogConfig": {
                "Type": "json-file",
                "Config": {}
            },
            "NetworkMode": "default",
            "PortBindings": {},
            "RestartPolicy": {
                "Name": "no",
                "MaximumRetryCount": 0
            },
            "AutoRemove": false,
            "VolumeDriver": "",
            "VolumesFrom": null,
            "CapAdd": null,
            "CapDrop": null,
            "CgroupnsMode": "host",
            "Dns": [],
            "DnsOptions": [],
            "DnsSearch": [],
            "ExtraHosts": null,
            "GroupAdd": null,
            "IpcMode": "private",
            "Cgroup": "",
            "Links": null,
            "OomScoreAdj": 0,
            "PidMode": "",
            "Privileged": false,
            "PublishAllPorts": false,
            "ReadonlyRootfs": false,
            "SecurityOpt": null,
            "UTSMode": "",
            "UsernsMode": "",
            "ShmSize": 67108864,
            "Runtime": "runc",
            "ConsoleSize": [
                16,
                229
            ],
            "Isolation": "",
            "CpuShares": 0,
            "Memory": 0,
            "NanoCpus": 0,
            "CgroupParent": "",
            "BlkioWeight": 0,
            "BlkioWeightDevice": [],
            "BlkioDeviceReadBps": null,
            "BlkioDeviceWriteBps": null,
            "BlkioDeviceReadIOps": null,
            "BlkioDeviceWriteIOps": null,
            "CpuPeriod": 0,
            "CpuQuota": 0,
            "CpuRealtimePeriod": 0,
            "CpuRealtimeRuntime": 0,
            "CpusetCpus": "",
            "CpusetMems": "",
            "Devices": [],
            "DeviceCgroupRules": null,
            "DeviceRequests": null,
            "KernelMemory": 0,
            "KernelMemoryTCP": 0,
            "MemoryReservation": 0,
            "MemorySwap": 0,
            "MemorySwappiness": null,
            "OomKillDisable": false,
            "PidsLimit": null,
            "Ulimits": null,
            "CpuCount": 0,
            "CpuPercent": 0,
            "IOMaximumIOps": 0,
            "IOMaximumBandwidth": 0,
            "MaskedPaths": [
                "/proc/asound",
                "/proc/acpi",
                "/proc/kcore",
                "/proc/keys",
                "/proc/latency_stats",
                "/proc/timer_list",
                "/proc/timer_stats",
                "/proc/sched_debug",
                "/proc/scsi",
                "/sys/firmware"
            ],
            "ReadonlyPaths": [
                "/proc/bus",
                "/proc/fs",
                "/proc/irq",
                "/proc/sys",
                "/proc/sysrq-trigger"
            ]
        },
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/67b62836de62d3e7c59b380b3d3bc08f86fc53b0390965de5a5971c2e9fba407-init/diff:/var/lib/docker/overlay2/3f6cdf147c5b72a6856b0f5fe8c8a9e1784f41414e0f70995381c556605873b7/diff:/var/lib/docker/overlay2/5568777fcac0002c758efce5b15c7294d5dc30f0820ddff79b20cdebbdaaaea4/diff:/var/lib/docker/overlay2/b7fb681e3766b6d75bededb284e42ea36d00e820a4664719e5fa2aa18a8ebb00/diff:/var/lib/docker/overlay2/38dc503d7a2f9be8c576dd2a0e626b44af9d76b5da02f98f8a655800f0a6ee49/diff:/var/lib/docker/overlay2/aab3aed4464bb0bf1728b98df88aa8b60867e22354609bfa1c35f4807747a097/diff:/var/lib/docker/overlay2/fdd7af1755e7d68564e4d81de7cf308a02a91c6c4907a50fdaeededabba8d913/diff:/var/lib/docker/overlay2/f8668dbfb96f13de188c0acc246aa1aaf2f003395f7ca2707aaceb610f21dca1/diff:/var/lib/docker/overlay2/952947c26d416fdf94c22df413c5821205438f031ceae1cba6d10fa3dbff3fb3/diff:/var/lib/docker/overlay2/dc2cc92060768807eb3db972956304d1ae5215ee75ca0c632133b869cdba6bd4/diff",
                "MergedDir": "/var/lib/docker/overlay2/67b62836de62d3e7c59b380b3d3bc08f86fc53b0390965de5a5971c2e9fba407/merged",
                "UpperDir": "/var/lib/docker/overlay2/67b62836de62d3e7c59b380b3d3bc08f86fc53b0390965de5a5971c2e9fba407/diff",
                "WorkDir": "/var/lib/docker/overlay2/67b62836de62d3e7c59b380b3d3bc08f86fc53b0390965de5a5971c2e9fba407/work"
            },
            "Name": "overlay2"
        },
        "Mounts": [
            {
                "Type": "volume",
                "Name": "d246cd882e4eaec88e68239aae16cee0fc9b2bf670a790e0a19442ece6e53375",
                "Source": "/var/lib/docker/volumes/d246cd882e4eaec88e68239aae16cee0fc9b2bf670a790e0a19442ece6e53375/_data",
                "Destination": "/data/configdb",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            },
            {
                "Type": "volume",
                "Name": "35811e6ca86d47b69c9ac45326df4d4539b68e46bd87c10c954666b9b8a3a85a",
                "Source": "/var/lib/docker/volumes/35811e6ca86d47b69c9ac45326df4d4539b68e46bd87c10c954666b9b8a3a85a/_data",
                "Destination": "/data/db",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],
        "Config": {
            "Hostname": "169b2d38e2d8",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "27017/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "GOSU_VERSION=1.12",
                "JSYAML_VERSION=3.13.1",
                "MONGO_PACKAGE=mongodb-org",
                "MONGO_REPO=repo.mongodb.org",
                "MONGO_MAJOR=5.0",
                "MONGO_VERSION=5.0.9",
                "HOME=/data/db"
            ],
            "Cmd": [
                "mongod"
            ],
            "Image": "mongo",
            "Volumes": {
                "/data/configdb": {},
                "/data/db": {}
            },
            "WorkingDir": "",
            "Entrypoint": [
                "docker-entrypoint.sh"
            ],
            "OnBuild": null,
            "Labels": {}
        },
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "e44cabced1c41817f34914209f9f53ebae9f751fb47f2161fba001d3f4645074",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {
                "27017/tcp": null
            },
            "SandboxKey": "/var/run/docker/netns/e44cabced1c4",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "7dd0a804d6dfeedfc95666b3cadcd8c516a30532efe7782303f235f6bce78f2d",
            "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,
                    "EndpointID": "7dd0a804d6dfeedfc95666b3cadcd8c516a30532efe7782303f235f6bce78f2d",
                    "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
                }
            }
        }
    }
]

Wśród nadmiaru informacji należy odnaleźć wpis: "IPAddress": "172.17.0.2", który jak zapewne odgadłeś zawiera ip kontenera.

Nie pozostało nic innego jak tylko zbudować obraz:

docker build -t node-api:1.0 .

by po chwili, lub co najwyżej dwóch oddać się najdzikszej rozkoszy uruchomienia nowej instancji kontenera:

docker run -p 8889:8888 --name node -v "${pwd}:/app" --rm -it node-api:1.0

> serwer-docker@1.0.0 start /app
> nodemon -L index.js

[nodemon] 2.0.16
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: js,mjs,json
[nodemon] starting `node index.js`

Teraz można wypisać w przeglądarce: http://localhost:8889/wishes aby zobaczyć pustą listę życzeń. Używając zaś Postman-a można dodać jakieś życzenie:

Docker - mongodb wysyłka żądania za pomocą Postmana
Rys. 1
Docker - mongodb wysyłka żądania za pomocą Postmana
Propozycje książek

Załączniki:

Serwer w kontenerze Dockera przygotowany do nawiązania kontaktu z bazą danych MongoDb z drugiego kontenera