前言
在生产环境中,为 Docker 容器设置固定 IP 通常是为了确保服务的稳定性和可预测性。但值得注意的是,Docker 容器本身不直接支持静态 IP 分配。这是因为 Docker 网络是基于桥接或覆盖网络的,它们通常不提供静态 IP 分配。
在很多场景下,我们需要为某个容器配置多个IP。比如docker环境下nacos 连接mysql。mysql是公共服务,可能为某几个服务提供持久化存储,因此提供了某个子网下的静态IP,而nacos集群在另外一组静态IP下,通常有两种方案
- 通过宿主机映射
- 通过docker 网络的桥接模式配置多IP
比如宿主机内网IP:172.16.20.1
,docker nacos集群 nacos1 IP 172.18.0.1
、 nacos2 IP 172.18.0.2
、 nacos3 IP 172.18.0.3
,docker mysql 主从 mysql-master 172.20.0.1
、mysql-slave 172.20.0.2
,此时nacos和mysql网络是不通的,因此本文围绕第二种方式展开讨论提供解决方案。
使用 Docker 网络和自定义的 IP 分配
# 创建一个自定义的 Docker 网络,并通过网络配置来手动分配 IP 地址给容器。
docker network create --driver bridge --subnet=172.18.0.0/24 nacos_network
docker network create --driver bridge --subnet=172.20.0.0/24 mysql_network
#运行 MySQL 容器并指定网络和 IP:
# 其他mysql参数不展开讨论,参考本人docker-compose mysql相关博文
docker run -d --name mysql_m1 --net mysql_network --ip 172.20.0.1 mysql:latest
docker run -d --name mysql_s1 --net mysql_network --ip 172.20.0.2 mysql:latest
使用 Docker Compose 和自定义网络
你也可以在 docker-compose.yml 文件中定义自定义网络,并为服务指定静态 IP。
示例 docker-compose.yaml
:
version: '3'
services:
mysql:
image: mysql:latest
networks:
mynet:
ipv4_address: 172.20.0.1
networks:
mynet:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/24
使用外部网络插件(如 Weave 或 Calico)
对于更复杂的需求,或者当你需要跨多个 Docker 主机管理网络时,可以考虑使用外部网络插件。这些插件提供了更高级的网络管理功能,包括静态 IP 分配。例如,使用 Weave 或 Calico 作为网络解决方案:
安装 Weave:
curl -L git.io/weave -o /usr/local/bin/weave
chmod a+x /usr/local/bin/weave
weave launch
weave expose
使用 Calico:
Calico 需要与 Kubernetes 或 Docker Swarm 结合使用,并提供更强大的网络策略和 IP 分配。
注意事项:
持久化配置:确保你的网络配置(如自定义 IP 和子网)在容器重启或 Docker 服务重启后依然有效。这通常需要持久化你的网络配置。
安全性:在生产环境中使用静态 IP 需要考虑安全性,确保只有授权的容器可以访问这些 IP。
监控和管理:监控网络和容器的 IP 分配可以帮助预防冲突和资源管理问题。
通过上述方法,你可以在 Docker 和 Docker Compose 中为 MySQL 设置静态 IP,从而提高生产环境的稳定性和可管理性。
方案一和方案二整合,搭建docker nacos mysql
- 手动创建公共服务网络子网
# 创建一个自定义的 Docker 网络,并通过网络配置来手动分配 IP 地址给容器。
docker network create --driver bridge --subnet=172.20.0.0/24 docker_network
- 创建mysql的
docker-compose.yaml
,将其加入子网
version: '3.0'
services:
mysql:
image: mysql:8.0.28 # 使用 MySQL 8.0.28 镜像
container_name: docker_mysql8 # 容器名称为 docker_mysql
# 设置网络
ports:
- 3307:3307
restart: always # 容器退出时自动重启
oom_score_adj: -1000 # 防止被OOM kill, -1000为最低优先级
environment:
MYSQL_ROOT_PASSWORD: root # 设置 MySQL root 用户的密码为 root
volumes: # 挂载数据目录
- ./data:/var/lib/mysql
- ./mysql-files:/var/lib/mysql-files
- ./my.cnf:/etc/mysql/my.cnf:ro # 挂载配置文件,并设置为只读模式
command:
- --defaults-file=/etc/mysql/my.cnf # 使用指定的配置文件启动
networks:
mysql_docker_network: # 指向下面networks网络
ipv4_address: 172.20.0.1
networks:
mysql_docker_network:
external: true
name: docker_network # 使用之前的自建网络
- 创建nacos
docker-compose.yaml
文件
version: "3.0"
services:
nacos1:
hostname: nacos1
container_name: nacos1
image: nacos/nacos-server:v2.5.0
environment:
- MODE=cluster
- PREFER_HOST_MODE=hostname
- NACOS_SERVERS=172.18.0.1:8848 172.18.0.2:8848 172.18.0.3:8848
- NACOS_SERVER_IP=172.18.0.1
- SPRING_DATASOURCE_PLATFORM=mysql
- MYSQL_SERVICE_HOST=172.20.0.1
- MYSQL_其他参数: 略
volumes: 略
ports: 略
networks:
nacos_cluster_network:
ipv4_address: 172.18.0.1
nacos_docker_network:
ipv4_address: 172.20.0.21
nacos2:
hostname: nacos2
image: nacos/nacos-server:v2.5.0
container_name: nacos2
environment:
- MODE=cluster
- PREFER_HOST_MODE=hostname
- NACOS_SERVERS=172.18.0.1:8848 172.18.0.2:8848 172.18.0.3:8848
- NACOS_SERVER_IP=172.18.0.2
- SPRING_DATASOURCE_PLATFORM=mysql
- MYSQL_SERVICE_HOST=172.20.0.1
- MYSQL_其他参数: 略
volumes: 略
ports: 略
networks:
nacos_cluster_network:
ipv4_address: 172.18.0.2
nacos_docker_network:
ipv4_address: 172.20.0.22
nacos3:
hostname: nacos3
image: nacos/nacos-server:v2.5.0
container_name: nacos3
environment:
- MODE=cluster
- PREFER_HOST_MODE=hostname
- NACOS_SERVERS=172.18.0.1:8848 172.18.0.2:8848 172.18.0.3:8848
- NACOS_SERVER_IP=172.18.0.3
- SPRING_DATASOURCE_PLATFORM=mysql
- MYSQL_SERVICE_HOST=172.20.0.1
- MYSQL_其他参数: 略
volumes: 略
ports: 略
networks:
nacos_cluster_network:
ipv4_address: 172.20.0.4
nacos_docker_network:
ipv4_address: 172.20.0.23
networks:
nacos_cluster_network:
ipam:
config:
- subnet: 172.20.0.0/16
nacos_docker_network:
external: true
name: docker_network