Docker容器网络
前言
Docker
有四种网络连接方式.
- 单机模式:
bridge
、host
和none
. - 多机模式:
overlay
Docker
会自动创建3
个网络.1
2
3
4
5docker network ls
# NETWORK ID NAME DRIVER SCOPE
# 7b083adc391a bridge bridge local
# 5855c878dc68 host host local
# 9895a4ab897d none null local
Docker Container 之间的网络连接
如果我有一个应用的容器, 需要连接到MySQL
的容器, 那么就需要建立两个容器之间的网络连接.Docker
提供了一个--link <container>
的参数, 用来连接到其他的container
.
1 | # 1. 创建一个 bridge1 容器, 并查看ip地址 |
发现bridge2
可以直接ping bridge1
, 不用输入IP
地址.
因为--link bridge1
相当于给bridge2
添加了一条DNS
解析.
而且, 默认的 bridge
是单向的, 这句话先记着, 后面讲
那这两个容器, 是用哪个network
连接的呢?
答案是默认创建的名为bridge
的bridge
类型的network
. 执行下面语句
1 | # docker network inspect <network name> |
可以看到bridge1
和bridge2
这两个容器都绑在名为bridge
的bridge
类型的network
上了.
那如果我想做网络隔离, 绑定到自定义的bridge
上呢?
单机 Docker 网络
bridge 网络隔离
我们可以自己创建一个bridge
, 做网络隔离.
1 | # 1. 创建自己的 bridge |
可以看到, 即使我们手动指定了--link bridge1
, bridge3
容器仍然访问不了bridge1
容器.
因为bridge3
容器和bridge1
容器使用的不是同一个docker
网络.
把bridge1
容器连接到my-bridge
上, 注意, 此时bridge1
仍然存在于默认的网络bridge
上.
1 | # 1. 把 bridge1 连接到 my-bridge |
注意, 我们没有给bridge1
添加--link bridge3
, 只是连接到 my-bridge
, 却可以ping bridge3
.
因为和默认的bridge
不同, 自己创建的bridge
默认是双向的.
host 共享 network namespace
如果我们用Docker
启动了一个nginx
服务器.
此时, 只有宿主机可以访问Docker
容器里的nginx
服务器.
1 | # 1. 运行本地服务器 nginx |
在宿主机里可以访问这个nginx
, 但是在局域网的其他机器上, 却不能访问http://172.17.0.2
.
我们需要把宿主机里的nginx
暴露到外部来, 使用端口映射达到这个目的.
将container
的80
端口, 映射到宿主机的8080
端口, 这样, 我们直接访问宿主机的8080
端口, 就可以间接的访问到nginx
.
1 | docker run -d -p 8080:80 --name web-port-map nginx |
以上文字和host
毫无关联, 只是为下文做铺垫.host
可以共享宿主机的network namespace
, 关于Linux network namespace
可以看我的另一篇文章.
把它想象成一个网络沙箱即可.
还是用nginx
做个简单例子, 我们从上面可以知道部署nginx
需要做端口映射.
但是使用host
共享宿主机的network namespace
就可以不用做端口映射.
1 | docker run -d --name web-host --network host nginx |
我们在外部使用宿主机的IP
地址, 可以访问到80
端口的nginx
.
但是, 这个用法有个缺陷, 如果我想在一台机器上同时启动两个nginx
服务, 就会发生端口冲突, 它们会去争夺80
端口.
none 断网操作
一般用于安全性, 保密性较高的程序.
直接隔离网络, 断网.
1 | docker run -d --name net-none --network none alpine /bin/ping 127.0.0.1 |
可以看到没有分配ip
地址, 只有一个本地的回环地址127.0.0.1
.
多机 Docker 网络
在Docker 1.9
之前, 要实现多机Docker
容器之间的网络通信, 都是通过端口映射或者host
网络, 将Docker
容器的端口暴露到宿主机.
通过宿主机之间的网络通信, 间接完成了多机Docker
容器之间的网络通信.
TODO 待续