# 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
* 先跑幾個容器
(https://godleon.github.io/blog/images/docker/bridge_network.jpg)

### 查看橋接網卡
```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**

:::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/)