#Docker Compose 方式下容器网络
##背景
我们项目使用docker compose 部署服务,之前后端服务访问数据库都是通过数据库服务映射到主机的特定端口来访问。近期出于安全方面的考虑的,我们需要让后端服务和数据库通信走容器内部网络。
为了解决这个的问题,就需要了解一下容器间网络通信的基础。
networks
container name
在使用Compose启动容器时,Compose 默认给你的 app 设置一个网络。 service 中的每个容器默认都加入这个网络,容器之间彼此是互通的。并且,可以利用容器名字识别到。
Note: 你 app 的网络默认情况下是和你的
project name
有关的。这个project name
其实就是你 docker-compose.yml 文件存放的那个目录的名字。比如,目录名叫db
,那么默认情况下会创建一个叫db_default
的网络。你可以使用--project-name
或COMPSE_PROJECT_NAME
环境变量。
举个栗子,docker-compose.yml
:
version: "2.1"
services:
web:
image: nginx
ports:
- "8080:80"
busybox:
image: busybox
entrypoint:
- top
这个文件放在project
目录下当我们执行了 docker-compose up -d
之后:
- 一个叫
project_default
的网络将会被创建。
- web 和 busybox 容器将会被创建,并加入
project_default
网络中
project $ docker network ls
NETWORK ID NAME DRIVER SCOPE
f17520060e9d bridge bridge local
a3028588ea24 host host local
d5f0e66b912f none null local
5ecd6959d2a3 project_default bridge local
现在project_default 网络中的web 和 busybox 就可以通过container_name相互访问。例如,busybox
可以使用 web:80
访问web应用。
links
通过链接,您可以给某个 service 定义别名,通过该别名可以从其他服务访问服务。默认情况下,任何服务都可以通过该服务的名称访问任何其他服务。下面的例子中,busybox
是一个服务名,在 busybox
服务中,给 web
定义了一个别名 nginx
。那么,在 busybox
服务中,既可以通过 web
又可以通过 nginx
查找到主机名了。
version: "3"
services:
busybox:
build: busybox
links:
- "web:nginx"
web:
image: nginx
Links are a legacy option. We recommend using networks instead.
###Specify custom networks
Instead of just using the default app network, you can specify your own networks with the top-level
networks
key. This lets you create more complex topologies and specify custom network drivers and options. You can also use it to connect services to externally-created networks which aren’t managed by Compose.
Each service can specify what networks to connect to with the service-level
networks
key, which is a list of names referencing entries under the top-levelnetworks
key.
官方文档中提到我们可以使用 compsose 文件的 top-level 关键字 networks
自定义网络。这让你可以创建更复杂的拓扑并指定自定义网络驱动程序和选项。 你还可以使用它将服务连接到不由 Compose 管理的外部创建的网络。
来个栗子:我们使用project_1和project_2目录中的compose文件,分别创建了两个服务。并使用top-level关键字networks
定义了自定义网络custom_network
。
project_1 $ cat docker-compose.yml
version: "2.1"
services:
web:
image: nginx
networks:
- custom_network //添加到特定网络
networks:
custom_network:
name: custom_network
project_2 $ cat docker-compose.yml
version: "2.1"
services:
busybox:
image: busybox
entrypoint:
- top
networks:
- custom_network
networks:
custom_network:
name: custom_network
注意点:在 top-level关键字networks中, name 这个标签,需要在 Compose 2.1 版本及以上才能使用
我们来分别创建服务和网络,在创建project_2目录中的服务时,我们可以看到如果添加的网络已经存在,就不会再创建。
project_1 $ docker-compose up -d
Creating network "custom_network" with the default driver
Creating web ... done
project_1 $ cd ../project_2/
project_2 $ docker-compose up -d
Creating busybox ... done
我们来看结果:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8abdef4cc1ba busybox "top" 17 minutes ago Up 17 minutes busybox
40bb2e637286 nginx "nginx -g 'daemon of…" 18 minutes ago Up 18 minutes 80/tcp web
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
f17520060e9d bridge bridge local
//刚创建的网络,如果查看网络的详细信息就会发现两个服务已经被添加进custom_network
f26744e467d4 custom_network bridge local
a3028588ea24 host host local
d5f0e66b912f none null local
external
external: true
加上这行表示我这个服务用的网络是用外部的网络,不用自动创建。docker-compose up不会创建该网络,如果不存在,则会引发错误。
举个栗子:
app1 $ cat docker-compose.yaml
version: "3.7"
services:
web:
image: nginx
networks:
- outside
- default
db:
image: postgres
networks:
- default
networks:
outside:
external: true
注意点:对于 compose 3.3 及更低版本,外部不能与其他网络配置键(driver,driver_opts,ipam,internal)一起使用。版本 3.4 及更高版本不再存在此限制。
因为我们没有创建outside网络,所以在启动的时候就出现了报错。
app1 $ docker-compose up -d
ERROR: Network outside declared as external, but could not be found. Please create the network manually using `docker network create outside` and try again.
下面我们来创建outside网络,并重新启动它
app1 $ docker network create outside
3ce8ad24edfcccb6f39c2feb7f849f3cb560f145af60f839c02e21db82bc6b47
app1 $ docker-compose up -d
Creating network "app1_default" with the default driver
Creating app1_web_1 ... done
Creating app1_db_1 ... done
这时候不会去创建一个 [projectname]_outside
的网络, Compose 会去查找一个已存在的叫做 outside
的网络,并且将它和 web
服务相连。
##小结
我们可以看到容器间网络通信我们可以通过4种方法来实现:
-
container name
-
links
-
Specify custom networks
-
external
来源:CSDN
作者:weixin_39145281
链接:https://blog.csdn.net/weixin_39145281/article/details/103733885