主要实现不同容器间进行通信

默认情况下,Compose 会为我们的应用创建一个网络,服务的每个容器都会加入该网络中。这样,容器就可被该网络中的其他容器访问,不仅如此,该容器还能以服务名称作为 Hostname 被其他容器访问。
默认情况下,应用程序的网络名称基于 Compose 的工程名称,而项目名称基于 docker-compose.yml 所在目录的名称。如需修改工程名称,可使用 —project-name 标识或 COMPOSE_PORJECT_NAME 环境变量。
假如一个应用程序在名为 myapp 的目录中,并且 docker-compose.yml 如下所示:
version: '2'services:web:build: .ports:- "8000:8000"db:image: postgres
当我们运行 docker-compose up 时,将会执行以下几步:
- 创建一个名为 myapp_default 的网络
- 使用 web 服务的配置创建容器,它以 web 这个名称加入网络 myapp_default
- 使用 db 服务的配置创建容器,它以 db 这个名称加入网络 myapp_default
容器间可使用服务名称(web 或 db)作为 Hostname 相互访问。例如,web 这个服务可使用 postgres://db:5432 访问 db 容器。
当服务的配置发生更改时,可使用 docker-compose up 命令更新配置。此时,Compose 会删除旧容器并创建新容器。新容器会以不同的 IP 地址加入网络,名称保持不变。任何指向旧容器的连接都会被关闭,容器会重新找到新容器并连接上去。
使用 links
默认情况下,服务之间可使用服务名称相互访问。links 允许我们定义一个别名,从而使用该别名访问其他服务。
version: '2'
services:
web:
build: .
links:
- "db:database"
db:
image: postgres
自定义网络
一些场景下,默认的网络配置满足不了我们的需求,此时我们可使用 networks 命令自定义网络。networks 命令允许我们创建更加复杂的网络拓扑并指定自定义网络驱动和选项。不仅如此,我们还可使用 networks 将服务连接到不是由 Compose 管理的、外部创建的网络。
version: '2'
services:
proxy:
build: ./proxy
networks:
- front
app:
build: ./app
networks:
- front
- back
db:
image: postgres
networks:
- back
networks:
front:
# Use a custom driver
driver: custom-driver-1
back:
# Use a custom driver which takes special options
driver: custom-driver-2
driver_opts:
foo: "1"
bar: "2"
其中,proxy 服务与 db 服务隔离,两者分别使用自己的网络;app 服务可与两者通信。使用 networks 命令,即可方便实现服务间的网络隔离与连接。
配置默认网络
version: '2'
services:
web:
build: .
ports:
- "8000:8000"
db:
image: postgres
networks:
default:
# Use a custom driver
driver: custom-driver-1
已存在的网络
我们可以预先创建一个名为 myapp 的网络,让 Compose 加入这个新创建的网络,使所有 Compose 可以通信,此时使用 external 选项。
# 创建网络
docker network create <Network Name>
# 查看已存在的网络
docker network list
networks:
default:
external:
name: myapp
示例
创建网络:# docker network create myshop_network
查看网络:# docker network ls
通过 compose 配置,将两个不同局域网的容器放在同一个局域网中,通过 hostname 访问,做到容器只有一个入口的概念。
修改我的 mysql 的 docker-compose.yml 文件
version: '3.1'
services:
db:
image: mysql
container_name: mysql8
command:
# MySQL8的密码验证方式默认是 caching_sha2_password,但是很多的连接工具还不支持该方式
# 就需要手动设置下mysql的密码认证方式为以前的 mysql_native_password 方式
--default-authentication-plugin=mysql_native_password
--character-set-server=utf8mb4
--collation-server=utf8mb4_general_ci
--explicit_defaults_for_timestamp=true
--lower_case_table_names=1
# docker的重启策略:在容器退出时总是重启容器,但是不考虑在Docker守护进程启动时就已经停止了的容器
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: 123456 # root用户的密码
MYSQL_USER: user # 创建新用户
MYSQL_PASSWORD: 123456 # 新用户的密码
# ports:
# - 3306:3306
volumes:
- /usr/local/docker/mysql8/data:/var/lib/mysql
- /usr/local/docker/mysql8/conf:/etc/mysql/conf.d
- /usr/local/docker/mysql8/logs:/logs
# MySQL 的 Web 客户端
adminer:
image: adminer
restart: always
ports:
- 8081:8080
networks:
default:
external:
name: myshop_network
主要添加了 networks:内容和删除了 ports: 因为后续要通过数据库服务名(db)进行访问
在修改我的 myshop , myshop 是我的web服务,它需要链接 mysql 数据库
version: '3.1'
services:
myshop-admin:
image: myshop-admin
container_name: myshop-admin
ports:
- 8085:8080
networks:
default:
external:
name: myshop_network
先重新启动 mysql 容器 ,因为改了配置文件 docker-compose.yml
- 先卸载容器:
docker-compose down - 启动容器:
docker-compose up -d
修改 web 服务的数据库链接地址,通过服务名进行链接
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.connectionURL=jdbc:mysql://db:3306/myshop?useUnicode=true&characterEncoding=utf-8&useSSL=false
jdbc.username=root
jdbc.password=123456
然后将项目重新打包上传到服务器的我 myshop 服务容器下
重新构建镜像docker build -t 192.168.3.202/myshop/admin .
构建成功
编辑 docker-compose.yml 文件
version: '3.1'
services:
myshop-admin:
image: 192.168.3.202/myshop/admin
container_name: myshop-admin
ports:
- 8080:8080
networks:
default:
external:
name: myshop_network
启动容器:docker-compose up -d
测试访问:
查看容器里的服务数据库地址
db 是我的 mysql 镜像的服务名
