从0开始学 docker (每日更新 24-11-8)
配置容器的网络连接
使用默认桥接网络
启动docker时,会自动创建默认的桥接网络,桥接网络通过软件网桥让连接到同一桥接网络的容器之间可以相互通信,同时隔离那些没有连接到该桥接网络的容器
当Docker 守护进程启动时,会自动在 Docker主机上创建一个名为docker0的Linux虚拟网桥,此主机上创建的Docker容器如果没有明确定义,则会自动连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,主机上的所有容器通过它连接在同一个二层网络中。
Docker 守护进程为每个启动的容器创建一个veth对设备,这是直接相连的一对虚拟网络接口,其中一个接口设置为新创建容器的接口(命名为eth0@xxx),位于容器的网络名称空间中;另一个接口连接到虚拟网桥docker0,位于 Docker的网络名称空间中,以vethxxx形式命名。发送到veth对一端的数据包由另一端接收,这样容器就能连接到虚拟网桥上。同时,Docker 守护进程还会从网桥的私有地址空间中分配一个IP地址和子网给该容器。连接到同一网桥的容器之间可以相互通信。
应用场景
网桥模式docker容器拥有独立、隔离的网络栈,容器不具有一个公有IP,因为主机IP地址和veth对的IP地址不在同一个网段中
docker采用网络地址转移(Network Address Transiation,NAT)方式将容器内部服务监听的端口与主机的某一个端口进行绑定,使得主机以外的节点可以将包发送至容器内部
配置实例
在实验开始之前,最好删除正在运行的容器:
docker rm -f $(docker ps -f status=running -q) #强制删除
1.打开一个终端窗口,执行以下命令列出当前已有的网络
2.启动两个centos容器,以分离模式启动容器(后台运行)、交互式(可以交互操作)
由于以分离模式启动,不能立即连接到容器,只会在命令行输出容器ID,因为没有提供任何--network选项,容器会连接到默认桥接网络
执行以下命令,检查容器是否已经启动:
3.执行如下命令,查看bridge网络详细信息:
4.由于容器在后台运行,可以使用docker attach命令连接到centos1,使用ip addr show显示容器的网络接口
5.在centos1容器中ping一个网络来证明是否能连接到外网
-c 2限制ping命令仅尝试两次
#ping -c 2 baidu.com失败,但是ping -c 2 www.baidu.com成功
并ping第二个容器,说明可连通
6.脱离centos1容器连接而不停止它,ctrl+P+Q
6.停止运行那两个容器,注意没有删除
7.删除这两个容器
通过默认网桥使用IPv6
如果docker本身被配置为支持IPv6,则默认网桥会自动配置为支持IPv6
自定义默认网桥
可以根据需要对默认网桥进行自定义,具体方法是在/etc/docker/daemon.json配置文件中指定选项
使用主机网络
主机网络用于启动直接连接到docker主机网络栈的容器,使用的是host网络模式,实质上是关闭docker网络,让容器直接使用主机的网络
与bridge模式不同,host模式没有为容器创建一个隔离的网络环境,这种模式下的容器没有离们网络名称空间,不会获得一个独立的网络名称空间,而是和Docker主机共用一个网络名称空间
Docker容器可以和主机一样使用主机的物理网卡eth0,实现与外界的通信。容器不会虚制自己的网卡和配置自己的IP地址等,而是直接使用主机的IP地址和端口,其IP地址即为主机物理网卡的IP地址,其主机名与主机系统上的主机名一样。由于容器都使用相同的主机接口,所以在同一主机上的容器在绑定端口时必须要相互协调,避免与已经使用的端口号相冲突。主机上的各容器是通过容器发布的端口号来区分的,如果容器或服务没有发布端口,则主机网络不起作用。
容器的其他方面如文件系统、进程列表等与主机是隔离的。
应用场合
与默认的 bridge 模式对比,host 模式有更好的网络性能,因为它使用了主机的本地网络栈,而bridge必须通过Docker守护进程进行虚拟化。当网络性能要求非常高时,推荐使用这种模式运行容器,例如,生产环境的负载均衡或高性能Web服务器。其缺点就是要牺牲一些灵活性,如要考虑端口冲突问题,即不能再使用Docker主机上已经使用的端口。
host 模式能够与其他模式共存,容器可以直接配置主机网络,如某些跨主机的网络解决方案,也采用以容器方式运行。这些方案需要对网络进行配置,如管理 iptables。
容器对本地系统服务具有全部的访问权限,如D-bus, 因此host模式被认为是不安全的;还有,容器共享了主机的网络名称空间,并直接暴露在公共网络中,这是有安全隐患的。另外,需要通过端口映射(port mapping)进行协调。
还应注意,主机网络只能在Linux主机上工作,并不支持Mac OS主机和Windows主机
配置实例
这里以启动一个直接绑定到docker主机80端口的nginx容器进行示范
从网络角度看,这与nginx进程直接在docker主机上而不是容器中直接运行具有相同的隔离级别,然而,在其他方面,比如存储、进程名称空间和用户名称空间,nginx还是和主机隔离的,在操作之前,要先确认端口80在docker主机上未被占用
1.以分离模式创建nginx容器,使之作为后台进程运行,-rm表示该容器退出或者停止时会自动删除
2.测试nginx服务的访问
返回的结果表明可以通过主机的80端口直接访问该容器
3.检查网络栈
首先执行ip addr show命令检查所有网络接口
执行以下命令查看绑定到80端口的是哪个进程
4.执行下面命令停止容器,同时会被删除
相关的网络配置
采用host 模式,容器将共享主机的网络栈,主机的所有接口将对容器可用。容器的主机名将与主机系统上的主机名匹配。注意选项--mac-address在 host 模式时无效。
甚至在 host 模式下,容器默认有它自己的 UTS(UNIX Time-sharing System)名称空间。这种名称空间提供了主机名和域名的隔离,这一特性在Docker容器技术中被用到,使得Docker容器在网络上被视作一个独立的节点,而不仅仅是主机上的一个进程。Docker 利用UTS,让每个镜像可以以本身所提供的服务名称来命名镜像的主机名,且不会对 Docker 主机产生任何影响,由此达到主机名和域名的隔离效果,因此在主机网络中可以使用--hostname 选项在容器中更改主机。与--hostmame类似的--add-host、--dns、--dns-search 和--dns-opt 选项也可用于 host 模式中。这些选项将更新容器中的/etc/hosts 或/etc/resolv.conf文件,但是不会更改主机中的/etc/hosts和/etc/resolv.conf文件。