容器通信类型:
1. 容器与 world wide web
通信
这种类型的通信 docker 直接支持。代码不需要作任何修改,例如,使用 axios
从 https://swapi.dev/api/films
获取数据:
app.get("/movies", async (req, res) => {
try {
const response = await axios.get("https://swapi.dev/api/films");
res.status(200).json({ movies: response.data });
} catch (error) {
res.status(500).json({ message: "Something went wrong." });
}
});
2. 容器与本机上的服务通信
例如,容器内的 Node app 要访问安装在本机上的 MongoDB,必须将代码中的 localhost
修改为 host.docker.internal
mongoose.connect(
// 'mongodb://localhost:27017/swfavorites', 修改成下面的代码
'mongodb://host.docker.internal:27017/swfavorites',
{ useNewUrlParser: true },
(err) => {
if (err) {
console.log(err);
} else {
app.listen(3000);
}
}
);
docker 能够理解 host.docker.internal
并将其翻译为本机 ip 地址。
3. 容器与容器的通信(即跨容器通信)
假定现在有两个容器,一个容器装的是 Node App,一个容器装的是 MongoDB,Node App 容器想要与这个 MongoDB 容器通信,进行数据存储访问等操作。
方法1: 使用 ip 地址,这个方法繁琐,步骤如下:
1. 创建 MongoDB 容器,
不需要 Dockerfile,运行下述命令创建并运行一个名称为 mongodb
的容器:
docker run -d --name mongodb mongo
2. 查看容器的 ip 地址
使用下述命令查看刚生成的 mongodb
的 ip 地址:
docker container inspect mongodb
可以看到显示的此容器的ip地址为172.18.0.2
:
"IPAddress": "172.18.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:12:00:02",
"DriverOpts": null
3. 修改代码中的 localhost
替换为上述 ip 地址:
mongoose.connect(
// 'mongodb://localhost:27017/swfavorites',
'mongodb://172.18.0.2:27017/swfavorites',
{ useNewUrlParser: true },
(err) => {
if (err) {
console.log(err);
} else {
app.listen(3000);
}
}
);
方法 2,使用容器网络
1. 首先创建 docker 内部网络:
docker network create favorites-net
可以使用命令: docker network ls
查看所有的现有的 docker 网络。
2. 创建使用这一网络的容器
创建使用网络favorites-net
的node app 容器:
docker run -d --name mongodb --network favorites-net mongo
创建使用网络 favorite-net
的MongoDB 容器:
docker run --name favorites --network favorites-net -d --rm -p 3000:3000 favorites-node
--name
: 容器命名
--network
:容器将要使用的内部网络
--d
: 容器以 detached 模式运行
--rm
:容器在停止后将被自动删除
-p
: publish,映射本机端口到容器端口
两个容器间通信,直接用容器名称代替 ip 地址:
mongoose.connect(
// 'mongodb://localhost:27017/swfavorites',
// 要访问另一个容器,只需要将 localhost 改为该容器的名称
// 这里数据库容器的名称是 mongodb (容器创建时由 --name 选项指定)
"mongodb://mongodb:27017/swfavorites",
{ useNewUrlParser: true },
(err) => {
if (err) {
console.log(err);
} else {
app.listen(3000);
}
}
);
任何容器都可以成某个 docker 网络的一部分,只要两个容器属于同一网络,它们之间就可以互相自由通信,端口不需要指定。
只要一个容器向另一个容器发送请求,docker 将自动解析容器名称,并将其替换为实际的 ip 地址,
Docker 网络驱动
Docker 网络支持多种不同类型的驱动,不同的驱动对应不同的网络行为。
默认的驱动是 bridge
,使用这种驱动类型,处于同一网络中的容器可以通过容器名称发现对方。
设置网络驱动的命令如下:
docker network create --driver bridge my-net
如果省略 --driver
选项,创建的网络的驱动的类型就是 bridge
,驱动类型为bridge
的网络实际最常用,所以创建网络时, --driver
一般可以省略。
其他类型的驱动有 host
,overlay
,macvlan
, none
, 等等。