近期文章:
Docker 提供了多种网络模式和功能,以便在容器间建立网络通信和连接外部网络
1. 默认网络模式(bridge):Docker 默认使用 bridge 网络模式,创建一个名为 docker0
的虚拟网桥,并为每个容器分配一个 IP 地址。容器间可以通过 IP 地址相互通信
2. 主机模式(host): 使用主机模式时,容器直接使用宿主机的网络,与宿主机共享网络接口。容器的网络配置与宿主机相同,可以通过宿主机的 IP 地址直接访问容器。
3. 容器间通信: Docker 提供了容器间通信的功能,可以通过容器名称或 IP 地址进行通信。例如,可以使用容器名称作为主机名,在容器间建立连接。
4. 端口映射(Port Mapping): Docker 允许将容器内的端口映射到宿主机的端口上,以便容器服务可以通过宿主机 IP 和端口访问。可以使用 -p
或 --publish
参数来指定映射规则。
5. 自定义网络(Custom Networks): Docker 允许创建自定义网络,以便在一个自定义的网络中连接多个容器。自定义网络可以提供更好的隔离和网络管理。可以使用 docker network create
命令创建自定义网络。
6. DNS 解析: Docker 提供了内置的 DNS 服务,容器可以使用容器名称作为主机名进行 DNS 解析。容器可以通过主机名访问其他容器或外部服务
docker 容器的网络基础
docker run创建Docker容器时,可以用–net选项指定容器的网络模式,Docker有以下4种网络模式:
- bridge模式:使–net =bridge指定,默认设置;
- host模式:使–net =host指定;
- none模式:使–net =none指定;
- container模式:使用–net =container:NAME orID指定。
docker0:
安装docker的时候,会生成一个docker0的虚拟网桥
Linux虚拟网桥的特点:
可以设置ip地址 相当于拥有一个隐藏的虚拟网卡
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255 inet6 fe80::42:caff:fe61:36cd prefixlen 64 scopeid 0x20<link> ether 02:42:ca:61:36:cd txqueuelen 0 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 8 bytes 656 (656.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
每运行一个docker容器都会生成一个veth设备对,这个veth一个接口在容器里,一个接口在物理机上。
安装网桥管理工具
[root@master ~]# yum install bridge-utils -y
brctl show
可以查看到有一个docker0的网桥设备,下面有很多接口,每个接口都表示一个启动的docker容器,因为我在docker上启动了很多容器,所以interfaces较多
[root@master ~]# brctl show bridge name bridge id STP enabled interfaces cni0 8000.da48c56634e7 no veth3dde7ccb docker0 8000.0242ca6136cd no vetheb9993d
docker link设置网络别名
可以给容器起一个代号,这样可以直接以代号访问,避免了容器重启ip变化带来的问题 –link docker run –link=[CONTAINER_NAME]:[ALIAS]
1.启动一个nginx1容器 [root@master data]# docker run --name nginx1 -itd nginx:v1 /bin/bash 255fdeaba30fc46f99b9ca424fb53aceeaced2e494dfd253f221eb9f3a77de05 2.启动一个nginx2容器,--link做链接,那么当我们重新启动nginx2容器时,就算ip变了,也没关系,我们可以在nginx2上ping别名webtest [root@master data]# docker run --name nginx2 -itd --link=nginx1:webtest nginx:v1 /bin/bash 28c45e8729c3bac92d46670e6d6e0647d728713acb2b34d037367a520927526f 3.进入容器 [root@master data]# docker exec -it nginx2 /bin/bash ping nginx1容器的ip别名webtest可以ping通,即使nginx1容器的ip变了也可以通
docker容器的网络模式
docker run创建docker容器时,可以用–net选项指定容器的网络模式,Docker有以下4种网络模式:
- bridge模式:使–net =bridge指定,默认设置;
- host模式:使–net =host指定
- none模式:使–net =none指定;
- container模式:使用–net =container:NAME orID指定
docker bridge模式
默认选择bridge的情况下,容器启动后会通过DHCP获取一个地址
创建桥接网络
[root@master ~]# docker run --name bridge -it --privileged=true centos bash [root@5f384284ef6e /]# ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 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 52: eth0@if53: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:11:00:05 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.17.0.5/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever
案例 1: Web 应用容器
首先,创建一个 Dockerfile,用于构建包含你的 Web 应用的镜像。
FROM nginx:latest COPY ./webapp /usr/share/nginx/html EXPOSE 80
上述 Dockerfile 使用 nginx 镜像作为基础镜像,将 Web 应用文件复制到容器中,并暴露容器的 80 端口
构建镜像并命名为 mywebapp
。
docker build -t mywebapp .
运行容器,并将容器的 80 端口映射到宿主机的 8080 端口
docker run -d --name mywebapp -p 8080:80 mywebapp
现在可以通过访问 http://宿主机IP:8080
来访问Web 应用
案例 2: 多个容器通信
一个应用,由多个容器组成,需要进行容器间的通信
创建一个自定义网络,用于容器间的通信
docker network create mynetwork
启动 Web 服务器容器,并连接到自定义网络
docker run -d --name webserver --network=mynetwork mywebserver #mywebserver 是包含 Web 服务器的镜像
启动数据库容器,并连接到同一自定义网络
docker run -d --name database --network=mynetwork mydatabase #mydatabase 是包含数据库服务的镜像
现在,Web 服务器容器和数据库容器都连接到同一个自定义网络 mynetwork
,它们可以使用容器名称进行通信。例如,在 Web 服务器容器中,可以使用数据库容器的名称 database
来连接数据库
docker host网络模式
Host 网络模式是 Docker 中的一种网络模式,它与默认的 bridge 模式不同。在 Host 网络模式下,容器与宿主机共享网络命名空间,直接使用宿主机的网络接口进行通信,而不是创建一个单独的网络栈
- 网络共享: 容器直接使用宿主机的网络接口,与宿主机共享相同的 IP 地址和网络配置。这使得容器可以直接访问宿主机所连接的网络,并且无需进行端口映射。
- 网络性能: 由于容器与宿主机共享网络栈,容器中的网络性能通常更高。容器与宿主机之间的通信不需要经过网络桥接层,减少了网络转发的开销
- 要使用 Host 网络模式启动容器,可以在
docker run
命令中使用--net=host
参数
[root@master data]# docker run --name host -it --net=host --privileged=true centos bash [root@master /]# ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 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 inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:0c:29:65:10:9b brd ff:ff:ff:ff:ff:ff inet 172.16.40.129/24 brd 172.16.40.255 scope global noprefixroute ens33 valid_lft forever preferred_lft forever inet6 fe80::df71:a790:6b25:5518/64 scope link noprefixroute valid_lft forever preferred_lft forever 3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ca:61:36:cd brd ff:ff:ff:ff:ff:ff inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0 valid_lft forever preferred_lft forever inet6 fe80::42:caff:fe61:36cd/64 scope link valid_lft forever preferred_lft forever 4: flannel.1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN group default link/ether 32:c1:bc:d7:fe:b5 brd ff:ff:ff:ff:ff:ff inet 10.244.0.0/32 scope global flannel.1 ......
需要注意以下几点:
- 在 Host 网络模式下,容器将无法使用宿主机上已占用的端口。因此,在启动容器之前,请确保宿主机上的相应端口未被其他服务占用。
- Host 网络模式会使容器与宿主机紧密耦合,容器将直接使用宿主机的网络资源。因此,需要谨慎使用 Host 网络模式,以确保安全性和隔离性。
- 使用 Host 网络模式时,容器的网络配置(例如 IP 地址、子网掩码、网关等)将与宿主机完全相同,无需进行额外的网络配置。
Host 网络模式适用于一些特定的场景,如需要容器直接与宿主机网络进行交互、需要最大限度提高网络性能的情况等。
案例1:容器化的网络监控工具
我现在需要在容器中运行一个网络监控工具,用于监视宿主机的网络连接和流量。使用 Host 网络模式可以让容器直接访问宿主机的网络接口,以实时监控网络流量和连接状态
创建一个 Dockerfile,用于构建包含网络监控工具的镜像。例如,使用 tcpdump
工具进行网络抓包。
FROM ubuntu:latest RUN apt-get update && apt-get install -y tcpdump
构建镜像并命名为 network-monitor
。
docker build -t network-monitor .
运行容器,并使用 Host 网络模式。
docker run -d --net=host --name network-monitor network-monitor tcpdump -i eth0
现在,网络监控容器将以 Host 网络模式运行,直接访问宿主机的网络接口 eth0。可以在容器中使用 tcpdump
工具来捕获和分析宿主机上的网络流量
docker container模式
Docker网络container模式是指,创建新容器的时候,通过–net container参数,指定其和已经存在的某个容器共享一个 Network Namespace。使它们可以直接使用 localhost 来进行通信,就像在同一台主机上运行的进程一样。容器模式可以在容器之间提供高性能的通信,并且不需要进行端口映射或使用网络地址转换(NAT),如下图所示,右方黄色新创建的container,其网卡共享左边容器。因此就不会拥有自己独立的 IP,而是共享左边容器的 IP 172.17.0.2,端口范围等网络资源,两个容器的进程通过 lo 网卡设备通信
[root@master data]# docker run --name container2 --net=container -it --privileged=true centos [root@f483c8e3f46c /]# ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 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
docker none模式
Docker网络none模式是指创建的容器没有网络地址,只有lo网卡,在无网络模式下,容器没有网络接口,无法与外部网络通信。该模式主要用于一些特殊场景,如只需要运行一个进程的容器或与网络无关的容器。
[root@master data]# docker run -itd --name none --net=none --privileged=true centos f483c8e3f46c65be442989ab0828ccc6f424f53a71809e49a2fdf2f692b11ff7 [root@master data]# docker exec -it none /bin/bash [root@f483c8e3f46c /]# ip addr #只有本地lo地址 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 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