一、Docker 容器的网络模式
当项目大规模使用 Docker 时,容器通信的问题也就产生了。要解决容器通信问题,必须先了解很多关于网络的知识。Docker 的网络模式非常丰富,可以满足不同容器的通信要求,下表列出了这些网络模式的主要信息
网络模式 | 创建此种网络模式的关键选项 | 简单说明 |
---|---|---|
host 模式 | --network host | 容器直接使用宿主机的网络栈,没有独立的网络命名空间,网络性能高,但容器与宿主机共享网络资源,易出现端口冲突 |
container 模式 | --network container:<已有容器名或 ID> | 新容器共享指定已有容器的网络命名空间,两个容器网络配置相同,适用于需要紧密耦合通信的容器组合 |
none 模式 | --network none | 容器仅有一个 lo 回环接口,无任何外部网络连接,适用于对网络安全性要求极高或需手动配置网络的场景 |
bridge 模式 | 默认模式,可通过 -d bridge 手动指定(一般省略) | Docker 默认网络模式,创建 docker0 虚拟网桥,容器通过 veth 设备连到该网桥,容器有独立 IP,借助主机 NAT 访问外部网络 |
Overlay 模式 | -d overlay | 用于 Docker Swarm 集群,基于 VXLAN 技术创建跨主机的虚拟覆盖网络,实现不同宿主机上容器间的通信 |
macvlan 模式 | -d macvlan,还需指定 --subnet、--gateway 和 -o parent=<宿主机物理网卡> | 为容器分配唯一 MAC 地址,使其像独立物理设备,直接连接宿主机物理网络接口,绕过 docker0 网桥,提高网络性能 |
自定义网络模式 | docker network create 结合如 --subnet、--gateway、--ip-range 等参数 | 用户可根据需求灵活配置网络参数,如子网、网关、IP 范围等,创建符合特定要求的网络 |
1、查看网络
docker network ls
2、bridge模式
桥接模式(Bridge)
特点:容器通过宿主机的网桥(docker0)与外界通信,默认分配独立 IP。
优点:隔离性好,适合多数场景。
缺点:需要 NAT 转发,性能略低;端口需手动管理避免冲突。
特性 | 描述 |
---|---|
网络隔离 | 每个容器拥有独立的网络命名空间(IP、端口、路由表)。 |
核心组件 | - 虚拟网卡对(veth pair):连接容器与宿主机。 - 网桥(docker0):宿主机上的虚拟交换机。 |
通信机制 | - 容器内流量通过 veth pair 到达 docker0。 - 通过 NAT 转发访问外部网络。 |
IP 分配 | Docker 自动分配私有 IP(默认网段 172.17.0.0/16)。 |
端口映射 | 通过 -p 或 -P 参数将容器端口映射到宿主机。 |
数据流向 | 容器 → veth pair → docker0 → 宿主机网卡 → 外部网络。 |
创建
#创建
docker network create -d bridge aaa
删除
#删除
docker network rm my-net
运行容器连接到该网络
docker run -itd --rm --name zhangsan --network aaa busybox sh -c "top"docker run -itd --rm --name lisi --net=aaa busybox sh -c "top"
运行一个容器加入到该网络
docker run -it --rm --name wangwu --net=aaa busybox sh
3、host模式
主机模式(Host)
特点:容器直接使用宿主机网络,无独立 IP 和端口空间。
优点:性能最佳,适合对网络延迟敏感的应用。
缺点:容器间、容器与宿主机共享端口,需手动避免冲突。
特性 | 描述 |
---|---|
网络隔离 | 容器直接使用宿主机的网络命名空间,无隔离。 |
核心组件 | 共享宿主机的网卡、IP、端口、路由表等。 |
通信机制 | 容器内应用直接通过宿主机网络接口通信,无需 NAT 转发。 |
端口管理 | 容器暴露的端口直接占用宿主机端口,需手动避免冲突。 |
性能优势 | 消除网络虚拟化开销,性能接近原生应用。 |
数据流向 | 容器 → 宿主机网卡 → 外部网络。 |
运行容器连接到该网络
docker run -itd --net=host --name host1 busybox sh
docker exec -it host1 shifconfig
4、container模式
容器模式(Container)
特点:容器共享另一个容器的网络栈,IP 和端口完全相同。
适用场景:紧密耦合的应用(如 sidecar 模式)
特性 | 描述 |
---|---|
网络隔离 | 多个容器共享同一个网络命名空间(IP、端口、路由表)。 |
核心组件 | - 基础容器(Base Container):提供网络栈。 - 共享容器:加入基础容器的网络命名空间。 |
通信机制 | 容器间通过 localhost 直接通信,无需网络开销。 |
典型场景 | - Sidecar 模式(如主应用与日志收集器)。 - 容器间高性能通信。 |
数据流向 | 容器 A → 共享网络栈 → 容器 B。 |
创建并启动一个容器
docker run -itd --name AAA busybox
创建容器时指定模式为container并加入AAA这个命名空间中
docker run -itd --net=container:AAA --name aaaaaa busybox
两个容器的IP一致
5、none模式
无网络模式(None)
特点:容器仅有 loopback 接口,无外部网络连接。
适用场景:纯离线计算或数据处理任务。
特性 | 描述 |
---|---|
网络隔离 | 容器仅有 loopback 接口(127.0.0.1),无外部网络连接。 |
核心组件 | 空网络命名空间,无虚拟网卡或网桥。 |
适用场景 | - 纯离线计算任务。 - 敏感数据处理(需完全隔离)。 |
通信限制 | 无法与外部网络或其他容器通信,仅支持容器内部进程间通信。 |
docker network lsdocker run -itd --net=none --name libai busybox shdocker exec -it libai sh
6、macvlan模式
docker network create -d macvlan --subnet=192.168.1.0/24 --gateway=192.168.1.1 -o parent=ens160 -o macvlan_mode=bridge macvlan111docker network lsdocker run -itd --net=macvlan111 --name lihei busybox shdocker exec -it lihei shifconfig# 创建一个名为macvlan111的macvlan网络
# -d macvlan:指定网络驱动为macvlan
# --subnet=192.168.1.0/24:设置子网为192.168.1.0,子网掩码为255.255.255.0
# --gateway=192.168.1.1:设置网关为192.168.1.1
# -o parent=ens160:指定物理网卡为ens160
# -o macvlan_mode=bridge:设置macvlan模式为桥接模式
docker network create -d macvlan --subnet=192.168.1.0/24 --gateway=192.168.1.1 -o parent=ens160 -o macvlan_mode=bridge macvlan111# 列出所有Docker网络,验证macvlan111网络是否创建成功
docker network ls# 运行一个名为lihei的busybox容器
# -itd:交互式运行并在后台保持容器运行
# --net=macvlan111:将容器连接到macvlan111网络
# --name lihei:指定容器名称为lihei
# busybox sh:使用busybox镜像并执行sh shell
docker run -itd --net=macvlan111 --name lihei busybox sh# 进入lihei容器的交互式shell
docker exec -it lihei sh# 在容器内部执行ifconfig命令,查看网络接口配置
ifconfig
7、自定义模式
特点:基于 Bridge 或 Overlay 创建自定义网络,支持 DNS 自动解析。
优点:灵活配置网络策略,推荐生产环境使用
特性 | 描述 |
---|---|
网络隔离 | 基于用户定义的网桥或 overlay 网络,支持多子网隔离。 |
核心组件 | - 自定义网桥(如 docker network create my-net )。- DNS 服务:自动解析容器名到 IP。 |
通信机制 | - 同一网络内容器通过容器名直接通信。 - 跨网络通信需路由或端口映射。 |
IP 管理 | 通过 IPAM(IP Address Management)自动分配唯一 IP。 |
高级特性 | - 支持网络策略(如防火墙规则)。 - 跨主机 overlay 网络(VXLAN/GRE)。 |
数据流向 | 容器 → 自定义网桥 → 宿主机网卡 → 外部网络。 |
docker network create --subnet=172.100.0.0/16 --gateway=172.100.0.1 dufu
docker network ls
docker run -itd --name songjiang --net=dufu busybox
docker run -itd --name linchong --net=dufu busybox
docker ps -a
docker exec -it songjiang sh
ping linchong
二、端口映射
Docker 是一个开源的容器化平台,用于构建、运行和管理应用程序。它使用容器来打包应用程序及其依赖项,使得应用程序可以在不同的环境中快速、可靠地运行。在 Docker 中,端口映射是一个重要的特性,它允许容器内部的应用程序与宿主机进行通信。
Docker 的端口映射使用 -p 或 --publish 选项来实现。通过该选项,可以将容器内部的端口映射到宿主机上的某个端口。这样,容器内部的应用程序可以通过宿主机的端口来访问外部的网络或服务。宿主机上的端口号,表示容器内部的端口号。通过指定这两个端口号,Docker 会将容器内部的端口映射到宿主机的端口上。
1:端口映射
(1)-P(大写):指的是容器应用 PORT 随机映射到宿主机上的 PORT
- 自动绑定所有对外提供服务的容器端口,映射的端口将会从没有使用的端口池中自动随机选择。但是如果连续启动多个容器的话,则下一个容器的端口默认是当前容器占用端口号 +1。
- 生产场景一般不使用随机映射,好处是由 docker 分配,宿主机端口不会冲突。
(2)-p(小写):(宿主机 PORT: 容器 PORT)
- 宿主机 IP 不写表示 “0.0.0.0”,宿主机 PORT 不写表示随机端口,容器 PORT 必须指定,可以同时对多个端口进行映射绑定。
- 指定端口映射,在标准化场景下使用频率高。
- 端口的取值范围 32768--61000 之间
2、随机映射
docker run --rm -d -P nginxdocker ps -acurl 192.168.10.101:32768
宿主机随机映射
docker run --rm -d -p 80 nginx
docker ps -a
3、指定映射
docker run --rm -d -p 8080:80 nginx
docker ps -a
三、持久化
1:什么是数据卷
数据卷是一个可供一个或多个容器使用的特殊目录,它绕过了容器的文件系统,直接将宿主机上的目录或文件挂载到容器内部。这意味着即使容器被删除,数据卷中的数据也不会丢失,从而实现了数据的持久化存储。
2:数据卷的作用
数据持久化
容器的生命周期可能是短暂的,当容器被删除时,其内部文件系统中的数据也会随之消失。而数据卷可以将数据存储在宿主机上,确保数据不会因为容器的删除而丢失。
数据共享
多个容器可以同时挂载同一个数据卷,从而实现容器之间的数据共享。这对于需要共享配置文件、日志文件或其他数据的应用场景非常有用。
数据备份和恢复
由于数据卷中的数据存储在宿主机上,因此可以方便地进行备份和恢复操作。
分离数据和应用
将数据存储在数据卷中,可以使容器的镜像更加轻量级,只包含应用程序本身,而将数据分离出来,提高了容器的可移植性和可维护性。
3、匿名
docker run -itd -v /data1 -v /data2 --name web01 centos:7docker ps -adocker exec -it web01 /bin/bashcd /data1touch aaacd /data2touch bbbexit
cd /var/lib/docker/volumes/
cd 0cb20dc1253c4a323eaad507d1c1d26ab1c365eb053e5002456be259657d5fec/_data
ls
4、具名
docker volume create my_volumedocker run -itd -v my_volume:/data --name web02 centos:7docker exec -it web02 /bin/bashcd datatouch AAAAAAAexit
cd /var/lib/docker/volumes/_data/
ls
5、共享容器数据卷
创建挂载点
mkdir -p /www/html
mkdir -p /www/conf
mkdir -p /www/log
准备数据
配置文件
vim /www/conf/nginx.conf###编辑内容###
#user nobody;
worker_processes 1;#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;#pid logs/nginx.pid;events {worker_connections 1024;
}http {include mime.types;default_type application/octet-stream;#log_format main '$remote_addr - $remote_user [$time_local] "$request" '# '$status $body_bytes_sent "$http_referer" '# '"$http_user_agent" "$http_x_forwarded_for"';#access_log logs/access.log main;sendfile on;#tcp_nopush on;#keepalive_timeout 0;keepalive_timeout 65;#gzip on;server {listen 80;server_name localhost;#charset koi8-r;#access_log logs/host.access.log main;location / {root /www/html;index index.html index.htm index.php;}#error_page 404 /404.html;# redirect server error pages to the static page /50x.html#error_page 500 502 503 504 /50x.html;location = /50x.html {root html;}# proxy the PHP scripts to Apache listening on 127.0.0.1:80##location ~ \.php$ {# proxy_pass http://127.0.0.1;#}# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000##location ~ \.php$ {# root /www/html;# fastcgi_pass php01:9000;# fastcgi_index index.php;# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;# include fastcgi.conf;#}# deny access to .htaccess files, if Apache's document root# concurs with nginx's one##location ~ /\.ht {# deny all;#}}# another virtual host using mix of IP-, name-, and port-based configuration##server {# listen 8000;# listen somename:8080;# server_name somename alias another.alias;# location / {# root html;# index index.html index.htm;# }#}# HTTPS server##server {# listen 443 ssl;# server_name localhost;# ssl_certificate cert.pem;# ssl_certificate_key cert.key;# ssl_session_cache shared:SSL:1m;# ssl_session_timeout 5m;# ssl_ciphers HIGH:!aNULL:!MD5;# ssl_prefer_server_ciphers on;# location / {# root html;# index index.html index.htm;# }#}}
daemon off;
网页文件
echo "KGC" > /www/html/index.html
创建容器
docker run -d -p 9999:80 -v /www/conf/nginx.conf:/etc/nginx/nginx.conf -v /www/html:/www/html -v /www/log:/var/log/nginx --name web999 nginx /bin/bash -c "nginx"docker ps -a
访问测试
curl 192.168.10.101:9999
cat /www/log/access.log