在 Docker Compose 中,可以通过network_mode选项和外部网络的方式连接外部网络。
可以在服务定义中使用 network_mode 选项将容器连接到外部网络。例如,要将一个容器连接到主机的网络,可以这样设置:
(1)创建一个简单的 nginx 配置信息:
hx@hxstrive:~$ cat /var/data/nginx_config/simple.conf server { listen 80; server_name localhost; location / { root /usr/share/nginx/html; index index.html index.htm; } }
(2)编写一个 docker-compose.yml 文件,如下:
version: '3' # 定义服务 services: # 定义mysql服务 mysql: image: mysql:latest environment: MYSQL_ROOT_PASSWORD: 12345678 MYSQL_DATABASE: demo_db volumes: - /var/data/mysql:/var/lib/mysql networks: - mynetwork # 定义nginx服务 nginx: image: nginx:latest # 看这里 network_mode: host depends_on: - mysql volumes: - /var/data/nginx_config:/etc/nginx/conf.d # 自定义网络 networks: mynetwork: driver: bridge
上面例子中,定义了 mysql 和 nginx 服务,nginx 服务将直接使用主机的网络(network_mode 设置为 host),与主机上的其他进程和网络资源进行通信。
启动应用验证:
// 启动服务 root@hxstrive:~# docker-compose up -d Creating network "root_mynetwork" with driver "bridge" Creating root_mysql_1 ... done Creating root_nginx_1 ... done // 查看已启动的容器 root@hxstrive:~# docker-compose ps Name Command State Ports --------------------------------------------------------------------------- root_mysql_1 docker-entrypoint.sh mysqld Up 3306/tcp, 33060/tcp root_nginx_1 /docker-entrypoint.sh ngin ... Up // 访问 localhost 地址,验证服务是否可以访问 root@hxstrive:~# curl localhost <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> html { color-scheme: light dark; } body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html>
注意:如果将服务的网络模式设置为 host,则不能使用 posts 配置端口映射,否则将抛出“docker.errors.InvalidArgument: "host" network_mode is incompatible with port_bindings”错误。
如果要连接到一个已经存在的外部网络(手动创建或者由其他容器创建的网络),可以在服务定义中指定网络名称,然后通过 external 属性进行配置(true-标识外部网络;false-相反)。具体步骤如下:
首先,确保外部网络已经存在,可以使用 docker network ls 命令查看现有网络。
然后,在 docker-compose.yml 文件中这样设置:
version: '3' # 服务定义 services: # 定义MySQL服务 mysql: image: mysql:latest environment: MYSQL_ROOT_PASSWORD: 12345678 MYSQL_DATABASE: demo_db volumes: - /var/data/mysql:/var/lib/mysql networks: - mynetwork # 定义nginx服务 nginx: image: nginx:latest ports: - "8080:80" depends_on: - mysql volumes: - /var/data/nginx_config:/etc/nginx/conf.d networks: - mynetwork networks: mynetwork: # 标识网络是外部已经存在的网络,看这里 external: true
上面例子中,mysql 和 nginx 服务连接到名为 mynetwork 的外部网络。通过将 external 属性设置为 true,Docker Compose 知道这个网络是外部的,不会尝试创建它。
// 启动容器 root@hxstrive:~# docker-compose up -d Creating root_mysql_1 ... done Creating root_nginx_1 ... done // 查看启动的容器进程 root@hxstrive:~# docker-compose ps Name Command State Ports -------------------------------------------------------------------------------------------- root_mysql_1 docker-entrypoint.sh mysqld Up 3306/tcp, 33060/tcp root_nginx_1 /docker-entrypoint.sh ngin ... Up 0.0.0.0:8080->80/tcp,:::8080->80/tcp
如果指定的网络不存在,尝试启动容器将抛出“ERROR: Network mynetwork declared as external, but could not be found. Please create the network manually using `docker network create mynetwork` and try again.”错误:
root@hxstrive:~# docker-compose up -d ERROR: Network mynetwork declared as external, but could not be found. Please create the network manually using `docker network create mynetwork` and try again. // 可以手动创建一个网络,解决该问题 root@hxstrive:~# docker network create mynetwork 750730ce466717ea43d0525ebd148e2dbd908eb8fb88ed7e8cf422a160461248
(1)连接到外部网络时要小心,确保容器的安全性和隔离性。外部网络可能包含不受信任的资源或潜在的安全风险。
(2)使用 network_mode: host 选项时,容器将直接共享主机的网络栈,这可能会导致端口冲突和其他问题。在使用这种方式时,要确保容器和主机上的其他进程不会使用相同的端口。
(3)在连接到外部网络之前,最好了解网络的配置和安全策略,以确保容器的正常运行和数据安全。