Docker 探索-容器的网络配置

1 容器的网络
容器网络实质上也是由 Docker 为应用程序所创造的虚拟环境的一部分,它能让应用从宿主机操作系统的网络环境中独立出来,形成容器自有的网络设备、IP 协议栈、端口套接字、IP 路由表、防火墙等等与网络相关的模块
  • 沙盒提供了容器的虚拟网络栈,也就是之前所提到的端口套接字、IP 路由表、防火墙等的内容。其实现隔离了容器网络与宿主机网络,形成了完全独立的容器网络环境。
  • 网络可以理解为 Docker 内部的虚拟子网,网络内的参与者相互可见并能够进行通讯。Docker 的这种虚拟网络也是于宿主机网络存在隔离关系的,其目的主要是形成容器间的安全通讯环境。
  • 端点是位于容器或网络隔离墙之上的洞,其主要目的是形成一个可以控制的突破封闭的网络环境的出入口。当容器的端点与网络的端点形成配对后,就如同在这两者之间搭建了桥梁,便能够进行数据传输了。
这三者形成了 Docker 网络的核心模型,也就是容器网络模型 ( Container Network Model )。
目前 Docker 官方为我们提供了五种 Docker 网络驱动,分别是:Bridge DriverHost DriverOverlay DriverMacLan DriverNone Driver
其中,Bridge 网络是 Docker 容器的默认网络驱动,简而言之其就是通过网桥来实现网络通讯 ( 网桥网络的实现可以基于硬件,也可以基于软件 )。而 Overlay 网络是借助 Docker 集群模块 Docker Swarm 来搭建的跨 Docker Daemon 网络,我们可以通过它搭建跨物理主机的虚拟网络,进而让不同物理机中运行的容器感知不到多个物理机的存在。
容器互联
要让一个容器连接到另外一个容器,我们可以在容器通过 docker create 或 docker run 创建时通过 --link 选项进行配置
sudo docker run -d --name mysql mysql -e MYSQL_RANDOM_ROOT_PASSWORD=yes sudo docker run -d --name webapp webapp:latest --link mysql
就可以在容器webapp里面连接mysql了
暴露端口
需要注意的是,虽然容器间的网络打通了,但并不意味着我们可以任意访问被连接容器中的任何服务。Docker 为容器网络增加了一套安全机制,只有容器自身允许的端口,才能被其他容器所访问
这个容器自我标记端口可被访问的过程,我们通常称为暴露端口。我们在 docker ps 的结果中可以看到容器暴露给其他容器访问的端口。PORTS字段就是暴露出来的端口号。
可以用参数--expose 指定暴露的端口
sudo docker run -d --name mysql -e MYSQL_RANDOM_ROOT_PASSWORD=yes --expose 13306 --expose 23306 mysql:5.7
容器暴露了端口只是类似我们打开了容器的防火墙,具体能不能通过这个端口访问容器中的服务,还需要容器中的应用监听并处理来自这个端口的请求。
通过别名连接
纯粹的通过容器名来打开容器间的网络通道缺乏一定的灵活性,在 Docker 里还支持连接时使用别名来使我们摆脱容器名的限制。
$ sudo docker run -d --name webapp --link mysql:database webapp:latest
在这里,我们使用 --link <name>:<alias> 的形式,连接到 MySQL 容器,并设置它的别名为 database
管理网络
容器能够互相连接的前提是两者同处于一个网络中 ( 这里的网络是指容器网络模型中的网络 )。这个限制很好理解,刚才我们说了,网络这个概念我们可以理解为 Docker 所虚拟的子网,而容器网络沙盒可以看做是虚拟的主机,只有当多个主机在同一子网里时,才能互相看到并进行网络数据交换。
当我们启动 Docker 服务时,它会为我们创建一个默认的 bridge 网络,而我们创建的容器在不专门指定网络的情况下都会连接到这个网络上。所以我们刚才之所以能够把 webapp 容器连接到 mysql 容器上,其原因是两者都处于 bridge 这个网络上。可以通过 docker inspect 来观察一下此事容器的网络
sudo docker inspect mysql [ { ## ...... "NetworkSettings": { ## ...... "Networks": { "bridge": { # 注意这里是brigde "IPAMConfig": null, "Links": null, "Aliases": null, "NetworkID": "bc14eb1da66b67c7d155d6c78cb5389d4ffa6c719c8be3280628b7b54617441b", "EndpointID": 断端点id "1e201db6858341d326be4510971b2f81f0f85ebd09b9b168e1df61bab18a6f22", "Gateway": "172.17.0.1", #网关 "IPAddress": "172.17.0.2",#ip地址 "IPPrefixLen": 16, "IPv6Gateway": "", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "MacAddress": "02:42:ac:11:00:02", # MAC 地址 "DriverOpts": null } }
创建网络
我们也能够创建网络,形成自己定义虚拟子网的目的。
docker CLI 里与网络相关的命令都以 docker network 开头,其中创建网络的命令是 docker network create
$ sudo docker network create -d bridge individual
通过-d 选项我们可以为新的网络指定驱动类型,其值可以是刚才我们所提及的bridge、host、overlay、maclan,none,也可以是其他玩过驱动插件所定义的类型。这里我们使用的是bridge driver
docker network ls 或是 docker network list
NETWORK ID NAME DRIVER SCOPE
a1c4434a23c8 bridge bridge local
0667a1d3e65a host host local
24e8abd13d48 individual bridge local
4906352f394c none null local
之后我们在创建容器的时候,可以通过--network 来指定容器所加入的网络,一旦这个参数被指定,容器便不会默认加入到bridge这个网络中了(可以通过--network bridge 让其加入)
sudo docker run -d --name mysql -e MYSQL_RANDOM_ROOT_PASSWORD=yes --network individual mysql:5.7
观察一下
sudo docker inspect mysql [ { ## ...... "NetworkSettings": { ## ...... "Networks": { "individual": { # 跟指定的network 一样 "IPAMConfig": null, "Links": null, "Aliases": [ "2ad678e6d110" ],
通过--link 让处于另外一个网络的容器连接到这个容器上。
sudo docker run -d --name webapp --link mysql --network bridge webapp:latest
会提示:Error response from daemon: Cannot link to /mysql, as it does not belong to the default network.
可以看到容器并不能正常的启动,而 Docker 提醒我们两个容器处于不同的网络,之间是不能相互连接引用的。
端口映射
当我们需要在容器外通过网络访问容器中的应用的时候就需要进行端口映射功能了。

通过 Docker 端口映射功能,我们可以把容器的端口映射到宿主操作系统的端口上,当我们从外部访问宿主操作系统的端口时,数据请求就会自动发送给与之关联的容器端口。
要映射端口,我们可以在创建容器时使用 -p 或者是 --publish 选项。
sudo docker run -d --name nginx -p 80:80 -p 443:443 nginx:1.12
其中 ip 是宿主操作系统的监听 ip,可以用来控制监听的网卡,默认为 0.0.0.0,也就是监听所有网卡。host-port 和 container-port 分别表示映射到宿主操作系统的端口和容器的端口,这两者是可以不一样的,我们可以将容器的 80 端口映射到宿主操作系统的 8080 端口,传入 -p 8080:80 即可。
sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES bc79fc5d42a6 nginx:1.12 "nginx -g 'daemon of…" 4 seconds ago Up 2 seconds 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp nginx
箭头所指-> 就是映射的端口
0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注