# Docker Network ## Docker Network 狀態 * 預設會有3個 ```bash= $ sudo docker network ls NETWORK ID NAME DRIVER SCOPE 16c450163344 bridge bridge local 77bcc73aa5d2 host host local 73e1b85fe920 none null local ``` ## Docker Network 簡介 * 預設會走 bridge * 先跑幾個容器 ![image](https://hackmd.io/_uploads/Hki-IqxHT.png)(https://godleon.github.io/blog/images/docker/bridge_network.jpg) ![image](https://hackmd.io/_uploads/SJZc89xSa.png) ### 查看橋接網卡 ```bash= [user@docker1 ~]$ brctl show bridge name bridge id STP enabled interfaces docker0 8000.0242aefd8a1f no veth0b996df veth2e755f7 veth5ab4339 virbr0 8000.525400dc98bd yes virbr0-nic ``` :::info `brctl` 可以做很多事情, 包括增加/刪除網卡 ::: ### 查看容器網卡資訊 * 網卡資訊 ```bash= [user@docker1 ~]$ sudo docker network inspect bridge [ { "Name": "bridge", # docker network name "Id": "16c450163344edc8283d7f3db5058534b7a16e505aa4176af8f9f5a14d300de8", "Created": "2023-11-26T17:29:47.031410413+08: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": { # busybox 1 "019c290829e6f19d925c9058b2bc01ad30931e33f405ca52dfd89eb17b2edb7c": { "Name": "cranky_ganguly", "EndpointID": "126cee41d9a06df1c571e465299e7d6108b098ade3693462b4b5fcbb8b0358b7", "MacAddress": "02:42:ac:11:00:03", "IPv4Address": "172.17.0.3/16", "IPv6Address": "" }, # busybox 2 "8c4545f8196b6690b01051ffe8fb94549ced8334076ac5c9da93611ea95f350a": { "Name": "quirky_hugle", "EndpointID": "962231e5a4005a3183b36620311c9e178a75f33142f2d0e1eb8d0c1c30bf78e6", "MacAddress": "02:42:ac:11:00:02", "IPv4Address": "172.17.0.2/16", "IPv6Address": "" }, # busybox 3 "f9ebcc09f497a80e2ad8c31f64cf6d9e11533ccf6fbb641c9462ac99c334c191": { "Name": "stoic_mccarthy", "EndpointID": "cbb78e9e7bbc0d24628c83fd024d4c253e18f9f655c729911e38318a63ddc604", "MacAddress": "02:42:ac:11:00:04", "IPv4Address": "172.17.0.4/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": {} } ] ``` * 容器互ping ```bash= / # ping -c 3 172.17.0.3 PING 172.17.0.3 (172.17.0.3): 56 data bytes 64 bytes from 172.17.0.3: seq=0 ttl=64 time=0.079 ms 64 bytes from 172.17.0.3: seq=1 ttl=64 time=0.111 ms 64 bytes from 172.17.0.3: seq=2 ttl=64 time=0.097 ms --- 172.17.0.3 ping statistics --- 3 packets transmitted, 3 packets received, 0% packet loss round-trip min/avg/max = 0.079/0.095/0.111 ms / # ping -c 3 172.17.0.4 PING 172.17.0.4 (172.17.0.4): 56 data bytes 64 bytes from 172.17.0.4: seq=0 ttl=64 time=0.125 ms 64 bytes from 172.17.0.4: seq=1 ttl=64 time=0.085 ms 64 bytes from 172.17.0.4: seq=2 ttl=64 time=0.100 ms --- 172.17.0.4 ping statistics --- 3 packets transmitted, 3 packets received, 0% packet loss round-trip min/avg/max = 0.085/0.103/0.125 ms # 用 "name" ping 不通 / # ping -c 3 b2 ping: bad address 'b2' / # ping -c 3 b3 ping: bad address 'b3' ``` ### 自訂 bridge network * 建立 bridge 網路 ```bash= $ sudo docker network create --driver bridge test-br 71a26db5d96d0f38226d68ac4e9271a56121a602b177e3118865e7fdb64dff5d $ sudo docker network ls NETWORK ID NAME DRIVER SCOPE 16c450163344 bridge bridge local 77bcc73aa5d2 host host local 73e1b85fe920 none null local 71a26db5d96d test-br bridge local ``` * 查看新增的資訊 ```bash= $ sudo ip a s 47: br-71a26db5d96d: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default link/ether 02:42:dd:f9:0b:a4 brd ff:ff:ff:ff:ff:ff inet 172.18.0.1/16 brd 172.18.255.255 scope global br-71a26db5d96d valid_lft forever preferred_lft forever $ sudo docker network inspect test-br [ { "Name": "test-br", "Id": "71a26db5d96d0f38226d68ac4e9271a56121a602b177e3118865e7fdb64dff5d", "Created": "2023-11-26T18:50:32.894562997+08:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "172.18.0.0/16", "Gateway": "172.18.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": {}, "Options": {}, "Labels": {} } ] ``` * 再開兩個終端 ```bash= sudo docker run -d --name br1 --network test-br busybox sh sudo docker run -d --name br2 --network test-br busybox sh ``` **可用IP, Name 互ping** ![image](https://hackmd.io/_uploads/ByzrHjeH6.png) :::info 預設的 bridge 無法用 name 互通, 如果在一個有 web server 跟 DB 的環境, 用自訂的 bridge 就不必知道對方IP ::: * 新增網卡到 busybox 裡 1. 最初 ```bash= / # ip a s 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue 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 41: eth0@if42: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever ``` * 新增網卡 ```bash= $ sudo docker network connect test-br b1 ``` * 添加完成 ```bash= / # ip a s 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue 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 41: eth0@if42: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever 54: eth1@if55: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue link/ether 02:42:ac:12:00:04 brd ff:ff:ff:ff:ff:ff inet 172.18.0.4/16 brd 172.18.255.255 scope global eth1 valid_lft forever preferred_lft forever ``` ## 實作測試 參考: 【Docker系列】Python Flask + Redis 练习程序 ———————————————— 版权声明:本文为CSDN博主「小叶柏杉」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/weixin_48447848/article/details/122612582 * Python Flash + Redis * flash 為 python 前端框架 * Redis 為 快取型資料庫 ### 測試目錄準備 ```bash= $ tree docker_network/ docker_network/ ├── app.py └── Dockerfile ``` * app.py # 6379為 redis 預設port ```python= from flask import Flask from redis import Redis import os import socket app = Flask(__name__) redis = Redis(host=os.environ.get('REDIS_HOST', '127.0.0.1'), port=6379) @app.route('/') def hello(): redis.incr('hits') return f"Hello Container World! I have been seen {redis.get('hits').decode('utf-8')} times and my hostname is {socket.gethostname()}.\n" ``` * Dockerfile ```dockerfile= FROM python:3.9.18-slim RUN pip install flask redis && \ groupadd -r flask && useradd -r -g flask flask && \ mkdir /src && \ chown -R flask:flask /src USER flask COPY app.py /src/app.py WORKDIR /src ENV FLASK_APP=app.py REDIS_HOST=redis EXPOSE 5000 CMD ["flask", "run", "-h", "0.0.0.0"] ``` ### image prepare ```bash= $ sudo docker pull redis $ sudo docker build -t flask-test:0.3 . $ sudo docker images REPOSITORY TAG IMAGE ID CREATED SIZE flask-test 0.3 473c2177dd0f 11 seconds ago 140MB redis latest 961dda256baa 2 weeks ago 138MB ``` ### network ```bash= $ sudo docker network create --driver bridge test-network ``` ### container * 執行完後瀏覽器打開看看 (虛擬機可用127.0.0.1:5000) ```bash= $ sudo docker run -d --name redis-server --network test-network redis # --env REDIS_HOST=redis-server (container_name) $ sudo docker run -d --name flask-python --network test-network -p 5000:5000 --env REDIS_HOST=redis-server flask-test:0.5 ``` ### docker_compose * docker-compose.yml ```bash= version: '2.3' services: flask-demo: image: flask-test:0.5 container_name: flask-python environment: REDIS_HOST: redis-server depends_on: # 表示要等 redis-server 啟動 - redis-server ports: - "5000:5000" networks: - test-network redis-server: image: redis:latest container_name: redis-server networks: - test-network networks: test-network: ``` * run (開瀏覽器看) ```bash= sudo docker-compose up -d [+] Running 2/2 ✔ Container redis-server Started 0.0s ✔ Container flask-python Started 0.0s ``` ## Reference page [[Docker] Bridge Network 簡介](https://godleon.github.io/blog/Docker/docker-network-bridge/)