docker 及docker-compose network概念及操作详解
1. docker network概述
Docker通过使用网络驱动程序【network drivers】支持网络容器。默认情况下,Docker提供了多个网络驱动程序,如bridge
和overlay
驱动程序。用户也可以自己写一个网络驱动插件,这样就可以创建自己的驱动程序。
Docker引擎在宿主机会自动创建三个默认网络,创建容器时如果没有配置网络参数则默认使用bridge
网络
docker network ls
NETWORK ID NAME DRIVER SCOPE
07d530169e71 bridge bridge local
5be8dfb27f8c host host local
75467f6f34fb none null local
不同的网络模式适用场景总结如下:
network mode | 最适用的场景 |
---|---|
User-defined bridge networks | 在同一个Docker主机上运行的多个容器之间需要进行通信 |
Host networks | 容器的网络堆栈不应该与Docker主机隔离,但容器的其他方面需要隔离的 |
Overlay networks | 需要运行在不同Docker主机上的容器进行通信时,或者当多个应用程序使用swarm service一起工作时 |
Macvlan networks | 从虚拟机设置迁移或需要您的容器看起来像网络上的物理主机,每个主机都有唯一的MAC地址 |
Third-party network plugins | 需要将Docker与专门的网络堆栈集成 |
2. network相关的操作
# 列出所有当前主机上或Swarm集群上的网络
docker network ls
#查看网络详情
docker network inspect network名称
# 清除未使用的docker网络
docker network prune -f
# 创建网络
ocker network create -d bridge br0
docker network create –subnet=192.168.50.0/24 br0
docker network create –subnet=192.168.50.0/24 –ip-range=192.168.50.0/24 br0
docker network create –subnet=192.168.10.0/24 –internal br1
#将容器添加进一个已有网络
docker network connect bridge 容器名或ID
docker network connect --ip 172.17.0.18 network名称【必须是自己创建的才可以】 容器名或ID
#查看某一个容器中的网络,可以将一个容器连接到多个网络中。
docker inspect 容器名或ID
docker inspect --format='{{json .NetworkSettings.Networks}}' 容器名或ID
# 获取容器IP
docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' 容器名或ID
#将容器从网络中移除
docker network disconnect bridge 容器名或ID
# 删除一个网络
docker network rm network名称
3. Network mode
Docker的网络子系统是可插拔的,基于驱动程序实现。默认提供bridge、host、overlay、ipvlan、macvlan、none,并提供核心网络功能:
3.1. bridge网络
- 在组网方面,网桥网络是在网段之间转发流量的链路层设备。网桥可以是运行在主机内核中的硬件设备或软件设备。
- 在Docker中,网桥网络使用软件桥接,允许连接到同一网桥网络的容器进行通信,同时提供与未连接到该网桥网络的容器的隔离。- -
- Docker网桥驱动程序自动在主机上安装网络隔离规则,使不同网桥网络上的容器之间不能直接通信。
- 网桥网络适用于运行在同一个Docker守护进程主机上的容器之间的网络通信,overlay网络用于运行在不同Docker守护进程主机上的容器之间的通信
- 启动Docker时,会自动创建一个默认网桥网络bridge,新启动的容器默认连接到它
- 可以创建自定义网桥网络。自定义网桥网络优于默认网桥网络,它提供更好的网络隔离。
网桥工作在二层(OSI堆栈),是通用网络设备的一种,可以设置IP地址
3.1.1. 组网方式
在组网方面,网桥网络是在网段之间转发流量的链路层设备。网桥可以是运行在主机内核中的硬件设备或软件设备。
当创建或删除一个自定义网桥,或者连接或断开容器与用户定义网桥的连接,Docker使用特定于操作系统的工具来管理底层网络基础设施
(如添加或删除网桥设备或配置Linux上的iptables规则)。
网络配置过程
如下:
- 在宿主机上创建一对虚拟网卡veth pair设备。veth设备总是成对出现的,它们组成了一个数据的通道,数据从一个设备进入,就会从另一个设备出来。因此,veth设备常用来连接两个网络设备。
- 在容器启动时,Docker引擎将veth pair设备的一端放在新创建的容器中,并命名为eth0。另一端放在宿主机中,以veth***这样类似的名字命名,并将这个网络设备加入到docker0网桥中,可以通过brctl show命令查看。
- 从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。
3.1.2. 自定义网桥与默认网桥的区别
- 用户自定义桥可以在容器之间提供自动DNS解析【DNS resolution 】能力。
- 默认网桥网络上的容器只能通过IP地址相互访问,除非您使用
--link
选项,但不推荐。在自定义网桥网络中,容器之间可以通过名称或别名进行解析
- 默认网桥网络上的容器只能通过IP地址相互访问,除非您使用
- 用户自定义桥提供了更好的隔离
- 所有没有指定
--network
的容器都附加到默认网桥网络。这可能是一个风险,因为不相关的堆栈/服务/容器可以进行通信。 - 使用用户定义的网桥提供了一个有作用域的网络,其中只有连接到该网络的容器才能进行通信
- 所有没有指定
- 容器可以动态地连接或断开与用户定义的网桥的连接
- 在容器的生命周期内,可以动态地连接或断开它与用户定义的网桥的连接。
- 从默认网桥网络中删除容器,需要停止容器并使用不同的网络选项重新创建它。
- 每个用户定义的网桥都会创建一个可配置的网桥,
默认网桥的配置是全局的
- 如果容器使用默认网桥网络,则可以配置它,但所有容器都使用相同的设置,例如MTU和iptables规则。此外,配置默认网桥网络发生在Docker本身之外,并且需要重新启动Docker。
- 用户自定义网桥网络使用
docker network create
创建和配置。如果不同的应用程序组有不同的网络需求,可以在创建桥接时分别配置每个用户定义的桥接。
连接到默认网桥上的所有容器共享环境变量
- 最初在两个容器之间共享环境变量的唯一方法是使用
--link
标志将它们链接起来。这种类型的变量共享在用户定义的网络中是不可能的。但是,有更好的方法来共享环境变量,如下:- 多个容器可以挂载包含共享信息的文件或目录
- 多个容器可以使用docker-compose一起启动,并且compose文件可以定义共享变量
- 最初在两个容器之间共享环境变量的唯一方法是使用
3.2. host
对于独立容器,移除容器和Docker主机之间的网络隔离,直接使用主机的网络。
- 如果容器使用主机网络模式,该容器的网络堆栈
不会与Docker宿主机隔离
(容器共享主机的网络命名空间),并且容器不会分配自己的ip地址
。例如,如果您运行一个绑定到端口80的容器,并且使用主机网络,则容器的应用程序在主机IP地址的端口80上可用。 port-mapping
不生效,-p
、--publish
、-P
、--publish-all
选项被忽略,并产生一个告警WARNING: Published ports are discarded when using host network mode
- 主机模式网络对于
优化性能
非常有用, 在容器需要处理大量端口
的情况下,因为它不需要网络地址转换(NAT),并且没有为每个端口创建“用户空间-代理”。 - 该主机网络驱动程序
仅适用于Linux主机
,不支持Mac、Windows和Windows Server的Docker Desktop
使用命令如下:
docker run --rm -d --network host --name my_nginx nginx
3.3. overlay
在多个Docker守护进程主机之间创建分布式网络。
该网络位于特定主机网络之上(overlays),允许连接到它的容器在启用加密时安全通信。Docker透明地
处理每个数据包往返于正确的Docker守护进程主机和正确的目标容器间的路由
。
overlay
网络可以实现如下容器间的通信,这种策略消除了在这些容器之间进行操作系统级路由的需要。
- 将多个Docker守护进程连接在一起,使
swarm services
能够相互通信 - 在
swarm services
和独立容器之间通信 - 在不同Docker守护进程上的两个独立容器之间通信
3.3.1 组网方式
当初始化一个swarm或将一个Docker主机加入到一个现有的swarm时,在该Docker主机上创建了两个新的网络:
ingress
: 处理与swarm service 相关的控制和数据流量。创建swarm service 时,如果没有连接到自定义的overlay网络,默认连接到这个网络docker_gwbridge
:- 将单个Docker守护进程连接到参与swarm的其他守护进程.
- docker_gwbridge是一个虚拟网桥,连接overlay网络(包括ingress网络)到单个Docker守护进程的物理网络。
- 它不是Docker设备。它存在于Docker主机的内核中。
- 如果需要对docker_gwbridge进行自定义设置,则必须在将Docker主机加入swarm之前或暂时从swarm中移除后进行。
3.3.2. 创建overlay的必要条件
- 需要为参与overlay网络的每个Docker主机开放以下端口:
- TCP端口2377 用于集群管理通信
- TCP和UDP端口 7946 用于节点间通信
- UDP端口4789 用于覆盖网络流量
- 在创建overlay网络之前,需要使用
docker swarm init
将Docker守护进程初始化为swarm manager ,或者使用docker swarm join
将其加入现有的swarm 。其中任何一个都会创建默认的ingress
overlay网络,默认情况下由swarm service使用。即使您从未计划使用swarm services,也需要这样做。之后,可以创建额外的用户定义overlay网络。
3.3.3. 常用操作命令
- 自定义ingress网络
# 1.停止所有连接ingress的容器服务,
# 2.删除ingress网桥
docker network rm ingress
# 3. 创建自定义的ingress网桥
ocker network create \
--driver overlay \
--ingress \
--subnet=10.11.0.0/16 \
--gateway=10.11.0.2 \
--opt com.docker.network.driver.mtu=1200 \
my-ingress
# 4. 重启在第一步关闭的服务
- 自定义docker_gwbridge网络
# 1. Stop Docker.
# 2. 删除已有的docker_gwbridge接口
sudo ip link set docker_gwbridge down
sudo ip link del dev docker_gwbridge
# 3. Start Docker. Do not join or initialize the swarm.
# 4.Create or re-create the docker_gwbridge bridge
docker network create \
--subnet 10.11.0.0/16 \
--opt com.docker.network.bridge.name=docker_gwbridge \
--opt com.docker.network.bridge.enable_icc=false \
--opt com.docker.network.bridge.enable_ip_masquerade=true \
docker_gwbridge
# 5. 初始化或加入swarm。由于桥已经存在,Docker不会通过自动设置创建它。
3.4. ipvlan
IPvlan
网络让用户完全控制IPv4
和IPv6
寻址【addressing
】,VLAN
驱动程序建立在此基础上,为用户提供对二层VLAN标记【layer 2 VLAN tagging
】的完全控制,甚至对底层网络集成感兴趣的用户提供 IPvlan L3 routing
IPvlan是经过验证的、真实的网络虚拟化技术的一个新转变。Linux实现非常轻量级,因为它们不是使用传统的Linux网桥进行隔离,而是与Linux以太网接口或子接口相关联,以加强网络之间的分离和到物理网络的连接。
IPvlan提供了许多独特的功能,并为各种模式的进一步创新提供了大量的空间,2个突出优点如下:
- 移除通常存在于Docker主机NIC【network interface controller】和容器接口之间的桥接,
- 留下一个由容器接口【container interfaces】组成的简单设置,直接连接到Docker主机接口。
使用示例参见:ipvlan network
docker network create -d ipvlan \
--subnet=192.168.210.0/24 \
--subnet=192.168.212.0/24 \
--gateway=192.168.210.254 \
--gateway=192.168.212.254 \
-o ipvlan_mode=l2 -o parent=eth0 ipvlan210
3.5. macvlan
Macvlan网络允许为容器分配MAC地址,使其显示为网络上的物理设备。 Docker守护进程通过容器的MAC地址将流量路由到容器。
在处理希望直接
连接到物理网络
的遗留应用程序(而不是通过Docker主机的网络堆栈路由)时,使用macvlan驱动程序
有时是最佳选择
一些应用程序,特别是遗留应用程序或监视网络流量的应用程序,希望直接连接到物理网络, 可以使用macvlan
网络驱动程序为每个容器的虚拟网络接口分配MAC地址
,使其看起来像一个直接连接到物理网络的物理网络接口
。
使用macvlan
需要注意如下几点:
- 由于IP地址耗尽或“VLAN扩散”,很容易无意中损坏您的网络,在这种情况下,您的网络中有不适当的大量唯一MAC地址
- 网络设备需要能够处理“混杂模式”,即一个物理接口可以分配多个MAC地址
- 应用程序可以使用桥接(在单个Docker主机上)或overlay(在多个Docker主机上通信)工作,从长远来看,这些解决方案可能会更好。
使用示例:
docker network create -d macvlan \
--subnet=192.168.32.0/24 \
--ip-range=192.168.32.128/25 \
--gateway=192.168.32.254 \
--aux-address="my-router=192.168.32.129" \
-o parent=eth0 macnet32
3.6. none
对于此容器,禁用所有连网配置【disable all networking】,通常与自定义网络驱动程序一起使用。在swarm services
中none
不可用。
如何禁用一个容器的网络:Disable networking for a container --network none
docker run --rm -dit --network none --name no-net-alpine alpine:latest ash
docker exec no-net-alpine ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN qlen 1000
link/ipip 0.0.0.0 brd 0.0.0.0
3: sit0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN qlen 1000
link/sit 0.0.0.0 brd 0.0.0.0
#返回为空,表示没有路由表
docker exec no-net-alpine ip route
docker stop no-net-alpine
3.7. Network plugins
可以通过Docker安装和使用第三方网络插件。
这些插件可从Docker Hub或第三方供应商获得,关于安装和使用给定的网络插件,请参阅供应商的文档。
4. docker-compose network
docker-compose network详细配置参见:docker-compose-networking
4.1. 使用示例
假设有一个项目,目录名arkime,docker-compose.yml 配置如下
当执行 docker-compose up 的时候,network配置如下:
- 首先创建一个名字是 arkime_default的bridge网络
- elasticsearch容器加入到 arkime_default网络中,并且在网络中的名称为:es01
- arkime这个容器会加入到 arkime_default网络中,并且在网络中的名称为:arkime-viewer
- 当容器之间通讯时 , 是通过 CONTAINER_PORT 来连接的。
version: '3.1'
services:
elasticsearch:
container_name: es01
image: elastic/elasticsearch:7.16.1
restart: always #unless-stopped
healthcheck:
test: ["CMD-SHELL", "curl --silent --fail localhost:9200/_cluster/health || exit 1"]
interval: 10s
timeout: 5s
retries: 3
start_period: 30s
environment:
- discovery.type=single-node
- xpack.security.enabled=false
- xpack.ml.enabled=false
- ingest.geoip.downloader.enabled=false
volumes:
- ./esdata:/usr/share/elasticsearch/data
mem_limit: 512M #28G 生产环境中配置根据实际存储的数据配置
ulimits:
nofile:
soft: 65535
hard: 65535
memlock:
soft: -1
hard: -1
ports:
- 9200:9200
arkime:
container_name: arkime-viewer
image: mammo0/docker-arkime:latest
restart: always #unless-stopped
depends_on:
- elasticsearch
environment:
- OS_HOST=es01
- OS_PORT=9200
- VIEWER=on
- ARKIME_INTERFACE=eth0
- CAPTURE=off
ports:
- 8005:8005
volumes:
- ./config:/opt/arkime/etc
- ./logs:/data/logs
- ./data:/data/pcap
通过docker network inspect arkime_default
命令,查看结果如下:
[
{
"Name": "arkime_default",
"Id": "e5474a234c87560c85a9cfdc0f2ecff5b40c58b00d1fb466a324f45407b4aef8",
"Created": "2022-12-11T08:40:15.65117582Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.19.0.0/16",
"Gateway": "172.19.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"ab936540b7233550534d32a0c1cbbe34245e9cfc4fca06c5e53c3af5b3306266": {
"Name": "arkime-viewer",
"EndpointID": "b9a19cb5069fd7cf4af7083f5b3a364069b5b21f91b4daa67a1481cf524e1df2",
"MacAddress": "02:42:ac:13:00:03",
"IPv4Address": "172.19.0.3/16",
"IPv6Address": ""
},
"e61aeedafc13837a2b83561234c69823019d24911e99ee9cb86587775488ec73": {
"Name": "es01",
"EndpointID": "9771ecdf8f079f1bcab6fd651162f23979ab101d2bf8773033a22f74bcd7055c",
"MacAddress": "02:42:ac:13:00:02",
"IPv4Address": "172.19.0.2/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {
"com.docker.compose.network": "default",
"com.docker.compose.project": "arkime",
"com.docker.compose.version": "2.7.0"
}
}
]
4.2. 配置示例
详细配置参见:docker-compose-networking
4.2.1. 自定义网络
version: "3"
services:
proxy:
container_name: proxy
image: nginx:lastest
networks:
- frontend
app:
container_name: springboot-service
networks:
- frontend
- backend
db:
image: postgres
networks:
- backend
networks:
frontend:
driver: bridge
backend:
# Use a custom driver which takes special options
ipam:
driver: default
config:
- subnet: 172.28.0.0/16
4.2.2. 配置默认网络
不指定网络时,默认的网络也是可以配置的。不配置的话,默认是使用:brige,也可以修改为其他 的。
version: "3"
services:
web:
container_name: web
ports:
- 8088:8080
db:
container_name: db
image: postgres
networks:
default:
# Use a custom driver
driver: bridge
4.2.3. 指定一个已经存在的网络
指定一个存在的网络,docker-compose创建的容器默认都连接到此网络
networks:
default:
external:
name: my-pre-existing-network
参考
Network containers
Networking overview
bridge network
overlay network
ipvlan network
macvlan network
相关文章
- Docker打包错误:Failed to execute goal com.spotify:docker-maven-plugin:1.2.0:build (default-cli) on project security
- 【Docker】解决docker通过volumes挂载文件不生效,修改后容器内数据不同步,需要重启容器才能同步的问题
- Docker - docker in docker(dind)
- [Docker] Download and Remove Docker Images
- Docker入门教程:诞生背景;用途及安装;image镜像文件;container容器文件;编写Dockerfile脚本文件;RUN与CMD命令的区别;CMD命令的覆盖问题;上传镜像
- 【docker】解决 Failed with result ‘exit-code‘和Start request repeated too quickly和Failed to start Docker
- Linux 离线装 docker & docker-compose
- docker下使用DB2
- 【云原生 | Kubernetes 系列】Docker 面试题2则--取数据库连接数和docker-compose
- 82.第十七章 企业级容器技术docker -- Docker网络管理(十)
- 78.第十七章 企业级容器技术docker -- Docker 镜像制作和管理(六)
- 中秋征文 | 【云原生之Docker】使用docker部署内网穿透工具FRP
- 【云原生之Docker实战】部署docker管理平台shipyard
- 一文4000字教你如何使用可视化的Docker进行UI自动化测试
- Net Core 微服务 - 如何在docker容器里运行一个简单的.net core web api 服务
- Docker----如何更改docker镜像的存储路径
- Docker----执行docker pull 下载镜像时报dial tcp: lookup registry-1.docker.io on 192.168.1.1:53: no such host错
- Docker学习笔记18:docker实例之redis 集群搭建
- Docker学习笔记15:docker使用之Swarm 集群管理
- 华为云之HECS云服务器配置docker环境
- RHEL8安装docker-ce