Docker学习笔记-Task04Docker网络

Docker网络

1 Docker基础网络介绍

1.1 外部访问容器

  容器中可以运行一些网络应用,要让外部也可以访问这些应用,可以通过-P或-p参数来指定端口映射。
  当使用-P标记时,Docker会随机映射一个端口到内部容器开放的网络端口。 使用docker container ls可以看到,本地主机的32768被映射到了容器的80端口,此时访问本机的32768端口即可访问容器内NGINX默认页面。
  -p则可以指定要映射的端口,并且,在一个指定端口上只可以绑定一个容器。支持的格式有ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort
在这里插入图片描述
  同样的,可以通过docker logs命令来查看访问记录。
在这里插入图片描述

1.1.1 映射所有接口地址

  使用hostPort:containerPort格式本地的80端口映射到容器的80端口,可以执行$ docker run -d -p 80:80 nginx:alpine,此时默认会绑定本地所有接口上的所有地址。

1.1.2 映射到指定地址的指定端口

  使用ip:hostPort:containerPort格式指定映射使用一个特定地址,如localhost地址127.0.0.1:$ docker run -d -p 127.0.0.1:80:80 nginx:alpine

1.1.3 映射到指定地址的任意端口

  使用ip::containerPort绑定localhost的任意端口到容器的80端口,本地主机会自动分配一个端口:$ docker run -d -p 127.0.0.1::80 nginx:alpine
  还可以使用udp标记来指定udp端口:$ docker run -d -p 127.0.0.1:80:80/udp nginx:alpine

1.1.4 查看映射端口配置

  使用docker port来查看当前映射的端口配置,也可以查看到绑定的地址。
在这里插入图片描述
  注意:容器有自己的内部网络和ip地址(使用docker inspect查看,Docker还可以有一个可变的网络配置)。-p标记可以多次使用来绑定多个端口。
在这里插入图片描述

1.2 容器互联

  如果之前有Docke使用经验,可能已经习惯了使用–link参数来使容器互联。 随着Docker网络的完善,建议将容器加入自定义的Docker网络来连接多个容器,而不是使用 --link参数。

1.2.1 新建网络

  先创建一个新的Docker网络:
  $ docker network create -d bridge my-net
  -d参数指定Docker网络类型,有bridge overlay,其中overlay网络类型用于Swarm mode。

1.2.2 连接容器

  运行一个容器并连接到新建的my-net网络:
  $ docker run -it --rm --name busybox1 --network my-net busybox sh
  打开新的终端,再运行一个容器并加入到my-net网络:
  $ docker run -it --rm --name busybox2 --network my-net busybox sh
  再打开一个新的终端查看容器信息:
在这里插入图片描述
  下面通过ping来证明busybox1容器和busybox2容器建立了互联关系。 在busybox1容器输入以下命令:
在这里插入图片描述
  用ping来测试连接busybox2容器,它会解析成 172.19.0.3。同理在busybox2容器执行ping busybox1,也会成功连接到。这样,busybox1 容器和 busybox2 容器建立了互联关系。
  如果有多个容器之间需要互相连接,推荐使用Docker Compose。

1.3 配置DNS

  如何自定义配置容器的主机名和DNS呢?Docker利用虚拟文件来挂载容器的3个相关配置文件。
  在容器中使用mount命令可以看到挂载信息,这种机制可以让宿主主机DNS信息发生更新后,所有Docker容器的DNS配置通过/etc/resolv.conf文件立刻得到更新。
在这里插入图片描述
  配置全部容器的DNS,也可以在 /etc/docker/daemon.json文件中增加以下内容来设置。
在这里插入图片描述
  这样每次启动的容器DNS自动配置为114.114.114.114和8.8.8.8。使用以下命令来证明其已经生效。
在这里插入图片描述
  如果用户想要手动指定容器的配置,可以在使用docker run命令启动容器时加入如下参数:-h HOSTNAME或者–hostname=HOSTNAME设定容器的主机名,它会被写到容器内的/etc/hostname和 /etc/hosts。但它在容器外部看不到,既不会在docker container ls中显示,也不会在其他的容器的 /etc/hosts看到。
  --dns=IP_ADDRESS添加DNS服务器到容器的 /etc/resolv.conf中,让容器用这个服务器来解析所有不在 /etc/hosts中的主机名。
  --dns-search=DOMAIN设定容器的搜索域,当设定搜索域为.example.com时,在搜索一个名为host的主机时,DNS不仅搜索host,还会搜索host.example.com。
  如果在容器启动时没有指定最后两个参数,Docker会默认用主机上的 /etc/resolv.conf来配置容器。

2 Docker的网络模式

  可以通过docker network ls查看网络,默认创建三种网络。
在这里插入图片描述
  常见网络的含义:
在这里插入图片描述

2.1 Bridge 模式

  bridge模式是docker的默认网络模式,关于bridge网络模式的使用,只需要在创建容器时通过参数–net bridge或者–network bridge指定即可,当然这也是创建容器默认使用的网络模式,也就是说这个参数是可以省略的。
  当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上,附加在其上的任何网卡之间都能自动转发数据包。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。在主机上创建一对虚拟网卡veth pair设备,Docker将veth pair设备的一端放在新创建的容器中,并命名为eth0(容器的网卡),另一端放在主机中,以vethxxx这样类似的名字命名,并将这个网络设备加入到docker0网桥中。可以通过brctl show命令查看。
  比如运行一个基于busybox(busybox被称为嵌入式Linux的瑞士军刀,整合了很多小的unix下的通用功能到一个小的可执行文件中)。镜像构建的容器 bbox01,查看ip addr:
在这里插入图片描述
  然后宿主机通过 ip addr 查看信息如下。同时,守护进程还会从网桥docker0的私有地址空间中分配一个IP地址和子网给该容器,并设置docker0的IP地址为容器的默认网关。也可以安装yum install -y bridge-utils以后,通过brctl show命令查看网桥信息。
在这里插入图片描述
  通过以上的比较可以发现,证实了之前所说的:守护进程会创建一对对等虚拟设备接口 veth pair,将其中一个接口设置为容器的eth0接口(容器的网卡),另一个接口放置在宿主机的命名空间中,以类似vethxxx这样的名字命名。
  对于每个容器的IP地址和Gateway信息,可以通过docker inspect容器名称|ID进行查看,在NetworkSettings节点中可以看到详细信息。
在这里插入图片描述
  可以通过docker network inspect bridge查看所有bridge网络模式下的容器,在Containers节点中可以看到容器名称。
在这里插入图片描述

2.2 Host 模式

  host网络模式需要在创建容器时通过参数–net host或者–network host指定。
  采用 host 网络模式的Docker Container,可以直接使用宿主机的IP地址与外界进行通信,若宿主机的eth0是一个公有IP,那么容器也拥有这个公有IP,同时容器内服务的端口也可以使用宿主机的端口,无需额外进行NAT转换。
  host 网络模式可以让容器共享宿主机网络栈,这样的好处是外部主机与容器直接通信,但是容器的网络缺少隔离性。
  比如基于host网络模式创建了一个基于busybox镜像构建的容器bbox02,查看ip addr:
在这里插入图片描述
  然后宿主机通过 ip addr 查看信息如下:
在这里插入图片描述
  可以通过docker network inspect host查看所有host网络模式下的容器,在Containers节点中可以看到容器名称。
在这里插入图片描述
  如果启动容器的时候使host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。

2.3 None 模式

  none网络模式是指禁用网络功能,只有lo接口local的简写,代表127.0.0.1,即 localhost 本地环回接口。在创建容器时通过参数–net none或者–network none指定。
  none网络模式不为Docker Container创建任何的网络环境,容器内部就只能使用loopback网络设备,不会再有其他的网络资源。可以说none模式为Docke Container做了极少的网络设定,在没有网络配置的情况下,作为Docker发者,才能在这基础做其他无限多可能的网络定制开发。
  比如基于none网络模式创建了一个基于busybox镜像构建的容器bbox03,查看ip addr:
在这里插入图片描述
  可以通过docker network inspect none查看所有none网络模式下的容器,在Containers节点中可以看到容器名称。
在这里插入图片描述

  使用none模式,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息,需要自己为Docker 容器添加网卡、配置 IP 等。

2.4 Container 模式

  container网络模式是Docker中一种较为特别的网络的模式。在创建容器时通过参数–net container:已运行的容器名称|ID或者–network container:已运行的容器名称|ID指定。
处于这个模式下的Docker容器会共享一个网络栈,这样两个容器之间可以使用localhost高效快速通信。
  container网络模式下新创建的容器不会创建自己的网卡、配置自己的IP,而是和一个指定的容器共享IP、端口范围等。同样两个容器除了网络方面相同之外,其他的如文件系统、进程列表等还是隔离的。
  比如基于容器bbox01创建了container网络模式的容器bbox04,查看ip addr:
在这里插入图片描述
  容器bbox01的ip addr信息如下:
在这里插入图片描述
  宿主机的ip addr信息如下:
在这里插入图片描述
  通过以上测试可以发现,Docker守护进程只创建了一对对等虚拟设备接口用于连接bbox01容器和宿主机,而bbox04容器则直接使用了bbox01容器的网卡信息。这个时候如果将bbox01容器停止,会发现bbox04容器就只剩下lo接口了。
在这里插入图片描述
  然后bbox01容器重启以后,bbox04容器也重启一下,就又可以获取到网卡信息了。
在这里插入图片描述
  这个模式指定新创建的容器和已经存在的一个容器共享一个Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过lo网卡设备通信。

3 Docker的高级网络配置

3.1 快速配置指南

  下面是一个跟Docker网络相关的命令列表,其中有些命令选项只有在Docker服务启动的时候才能配置,而且不能马上生效。
  -b BRIDGE或–bridge=BRIDGE指定容器挂载的网桥
  --bip=CIDR定制docker0的掩码
  -H SOCKET…或–host=SOCKET… Docker服务端接收命令的通道
  --icc=true|false是否支持容器之间进行通信
  --ip-forward=true|false请看下文容器之间的通信
  --iptables=true|false是否允许Docker添加iptables规则
  --mtu=BYTES容器网络中的MTU
  下面2个命令选项既可以在启动服务时指定,也可以在启动容器时指定。在Docker服务启动的时候指定则会成为默认值,后面执行docker run时可以覆盖设置的默认值。
  --dns=IP_ADDRESS…使用指定的DNS服务器
  --dns-search=DOMAIN…指定DNS搜索域
  最后这些选项只有在docker run执行时使用,因为它是针对容器的特性内容。
  -h HOSTNAME或–hostname=HOSTNAME配置容器主机名
  --link=CONTAINER_NAME:ALIAS添加到另一个容器的连接
  --net=bridge|none|container:NAME_or_ID|host配置容器的桥接模式
  -p SPEC或–publish=SPEC`映射容器端口到宿主主机
  -P or --publish-all=true|false映射容器所有端口到宿主主机

3.2 容器访问控制

  容器的访问控制主要通过Linux上的iptables防火墙来进行管理和实现。iptables是Linux上默认的防火墙软件,在大部分发行版中都自带。

3.2.1 容器访问外部网络

  容器要想访问外部网络,需要本地系统的转发支持。在Linux系统中,检查转发是否打开。
  sysctl net.ipv4.ip_forward
  net.ipv4.ip_forward = 1
  如果为0,说明没有开启转发,则需要手动打开。
  sysctl -w net.ipv4.ip_forward=1
  如果在启动Docker服务的时候设定–ip-forward=true, Docker就会自动设定系统的ip_forward参数为1。

3.2.2 容器之间访问

  容器之间相互访问,需要两方面的支持。
  容器的网络拓扑是否已经互联。默认情况下,所有容器都会被连接到docker0网桥上。
  本地系统的防火墙软件-- iptables是否允许通过。

3.2.3 访问所有端口

  当启动Docker服务的时候,默认会添加一条转发策略到本地主机iptables的FORWARD链上。策略为通过(ACCEPT)还是禁止(DROP)取决于配置–icc=true(缺省值)还是–icc=false。当然,如果手动指定–iptables=false则不会添加iptables规则。
  可见,默认情况下,不同容器之间是允许网络互通的。如果为了安全考虑,可以在/etc/docker/daemon.json文件中配置{“icc”: false}来禁止它。

3.2.4 访问指定端口

  在通过-icc=false关闭网络访问后,还可以通过–link=CONTAINER_NAME:ALIAS选项来访问容器的开放端口。
  例如,在启动Docker服务时,可以同时使用cc=false --iptables=true参数来关闭允许相互的网络访问,并让Docker可以修改系统中的iptables规则。此时,系统中的iptables规则可能是类似的。
在这里插入图片描述
  之后,启动容器(docker run)时使用–link=CONTAINER_NAME:ALIAS选项。Docker会在iptable中为两个容器分别添加一条ACCEPT规则,允许相互访问开放的端口(取决于 Dockerfile中的EXPOSE指令)。当添加了–link=CONTAINER_NAME:ALIAS选项后,添加了iptables规则。
在这里插入图片描述
  注意:–link=CONTAINER_NAME:ALIAS中的CONTAINER_NAME目前必须是Docker分配的名字,或使用–name参数指定的名字,主机名则不会被识别。

3.3 端口映射实现

  默认情况下,容器可以主动访问到外部网络的连接,但是外部网络无法访问到容器。

3.3.1 容器访问外部实现

  容器所有到外部网络的连接,源地址都会被NAT成本地系统的IP地址。这是使用iptables的源地址伪装操作实现的。
  查看主机的NAT规则:
在这里插入图片描述
  其中,上述规则将所有源地址在172.17.0.0/16网段,目标地址为其他网段(外部网络)的流量动态伪装为从系统网卡发出。MASQUERADE跟传统SNAT的好处是它能动态从网卡获取地址。

3.3.2 外部访问容器实现

  容器允许外部访问,可以在docker run时候通过-p或-P参数来启用。不管用那种办法,其实也是在本地的iptable的NAT表中添加相应的规则。
  使用-P时:
在这里插入图片描述
  使用-p 80:80时:
在这里插入图片描述
  注意:这里的规则映射了0.0.0.0,意味着将接受主机来自所有接口的流量。用户可以通过-p IP:host_port:container_port或-p IP::port来指定允许访问容器的主机上的IP、接口等,以制定更严格的规则。如果希望永久绑定到某个固定的IP地址,可以在Docker配置文件 /etc/docker/daemon.json中添加如下内容。
  {
   “ip”: “0.0.0.0”
  }

3.4 配置docker0网桥

  Docker服务默认会创建一个docker0网桥(其上有一个docker0内部接口),它在内核层连通了其他的物理或虚拟网卡,这就将所有容器和本地主机都放到同一个物理网络。
  Docker默认指定了docker0接口的IP地址和子网掩码,让主机和容器之间可以通过网桥相互通信,它还给出了MTU(接口允许接收的最大传输单元),通常是1500 Bytes,或宿主主机网络路由上支持的默认值,这些值都可以在服务启动的时候进行配置。
  --bip=CIDR IP地址加掩码格式,例如192.168.1.5/24
  --mtu=BYTES覆盖默认的Docker mtu配置
  也可以在配置文件中配置DOCKER_OPTS,然后重启服务。
  由于目前Docker网桥是Linux网桥,用户可以使用brctl show来查看网桥和端口连接信息。
在这里插入图片描述
  注:brctl命令在Debian、Ubuntu中可以使用sudo apt-get install bridge-utils来安装。
每次创建一个新容器的时候,Docker从可用的地址段中选择一个空闲的IP地址分配给容器的eth0端口。使用本地主机上docker0接口的IP作为所有容器的默认网关。
在这里插入图片描述

3.5 自定义网桥

  除了默认的docker0网桥,用户也可以指定网桥来连接各个容器。在启动Docker服务的时候,使用-b BRIDGE或–bridge=BRIDGE来指定使用的网桥。
  如果服务已经运行,那需要先停止服务,并删除旧的网桥:
  $ sudo systemctl stop docker
  $ sudo ip link set dev docker0 down
  $ sudo brctl delbr docker0
  然后创建一个网桥 bridge0:
  $ sudo brctl addbr bridge0
  $ sudo ip addr add 192.168.5.1/24 dev bridge0
  $ sudo ip link set dev bridge0 up
  查看确认网桥创建并启动:
  $ ip addr show bridge0
  在Docker配置文件 /etc/docker/daemon.json中添加如下内容,即可将 Docker 默认桥接到创建的网桥上。
  {
   “bridge”: “bridge0”,
  }
  可以继续用brctl show命令查看桥接的信息。另外,在容器中可以使用ip addr和ip route命令来查看IP地址配置和路由信息。

3.6 外部工具

  pipework
  Jérôme Petazzoni 编写了一个叫pipework的shell脚本,可以帮助用户在比较复杂的场景中完成容器的连接。
  playground
  Brandon Rhodes创建了一个提供完整的Docker容器网络拓扑管理的Python库,包括路由、NAT防火墙,以及一些提供HTTP SMTP POP IMAP Telnet SSH FTP的服务器。

3.7 编辑网络配置文件

  Docker1.2.0开始支持在运行中的容器里编辑 /etc/hosts, /etc/hostname和/etc/resolv.conf文件。但是这些修改是临时的,只在运行的容器中保留,容器终止或重启后并不会被保存下来,也不会被docker commit提交。

3.8 实例:创建一个点到点连接

  默认情况下,Docker会将所有容器连接到由docker0提供的虚拟子网中。用户有时候需要两个容器之间可以直连通信,而不用通过主机网桥进行桥接。解决办法很简单:创建一对peer接口,分别放到两个容器中,配置成点到点链路类型即可。
  首先启动2个容器:
在这里插入图片描述
  找到进程号,然后创建网络命名空间的跟踪文件:
在这里插入图片描述
  创建一对peer接口,然后配置路由:
在这里插入图片描述
  现在这2个容器就可以相互ping通,并成功建立连接。点到点链路不需要子网和子网掩码。此外,也可以不指定–net=none来创建点到点链路,这样容器还可以通过原先的网络来通信。
  利用类似的办法,可以创建一个只跟主机通信的容器。但是一般情况下,更推荐使用–icc=false来关闭容器之间的通信。

要启动Redis Manager,可以按照以下步骤进行操作: 1. 首先,确保已经安装了Docker,并且已经下载了Redis Manager的Docker镜像。 2. 创建一个目录,用于存放Redis Manager的配置文件和数据。可以使用以下命令创建目录: ``` mkdir /path/to/redis-manager ``` 3. 在创建的目录中,创建一个配置文件redis-manager.conf,并根据需要进行配置。可以参考Redis Manager的官方文档或者使用现有的配置文件作为模板。 4. 使用以下命令启动Redis Manager容器: ``` docker run -p 8081:8081 --name redis-manager -v /path/to/redis-manager/redis-manager.conf:/etc/redis-manager/redis-manager.conf -v /path/to/redis-manager/data:/data -d redis-manager ``` 这个命令会将容器的8081端口映射到主机的8081端口,并将配置文件和数据目录挂载到容器内部。 5. 等待一段时间,Redis Manager容器会启动并运行。可以通过访问http://localhost:8081来访问Redis Manager的Web界面。 请注意,以上步骤中的路径和端口号可以根据实际情况进行修改。同时,确保在启动容器时使用了正确的Docker镜像名称和版本号。 #### 引用[.reference_title] - *1* *2* [Docker 安装 Redis-5.0.12,详细步骤](https://blog.csdn.net/weixin_49343190/article/details/118499260)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [docker学习笔记(四) ——docker启动redis文件并挂载文件](https://blog.csdn.net/qq_42221135/article/details/119650051)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值