容器内端口冲突问题

我在容器内同时启动两个达梦数据库容器,他们在容器内部都占用5236端口会冲突吗?

不会冲突。

只要你是通过 Docker(或 Kubernetes 等容器引擎)启动的两个独立容器,即使它们在容器内部都监听相同的端口(如达梦数据库默认的 5236 端口),也不会发生冲突。

原理解析

  1. 网络命名空间隔离 (Network Namespace Isolation):
    每个 Docker 容器都有自己独立的网络栈(包括网卡、IP 地址、路由表和端口空间)。

    • 容器 A 认为自己是唯一的,占用 0.0.0.0:5236。
    • 容器 B 也认为自己是唯一的,占用 0.0.0.0:5236。
    • 因为它们处于不同的网络命名空间中,互不可见,所以内部端口完全不会冲突。
  2. 冲突发生的场景(宿主机端口):
    冲突只会发生在**映射到宿主机(Host)**的端口上。

    • 如果你启动第一个容器时使用了 -p 5236:5236(将容器的 5236 映射到宿主机的 5236)。
    • 启动第二个容器时也使用了 -p 5236:5236。
    • 这时会报错,因为宿主机的 5236 端口只能被一个进程占用。

正确的启动方式示例

为了同时运行两个达梦容器,你需要为它们映射不同的宿主机端口,或者让它们使用不同的自定义网络进行内部通信。

场景一:都需要从宿主机访问

你需要将它们的宿主机端口区分开,例如一个用 5236,另一个用 5237:

# 启动第一个达梦容器
docker run -d --name dm_instance_1 \
  -p 5236:5236 \
  -e PAGE_SIZE=16 \
  -e LD_LIBRARY_PATH=/opt/dmdbms/bin \
  dameng/db

# 启动第二个达梦容器 (注意宿主机端口改为 5237)
docker run -d --name dm_instance_2 \
  -p 5237:5236 \
  -e PAGE_SIZE=16 \
  -e LD_LIBRARY_PATH=/opt/dmdbms/bin \
  dameng/db
  • 访问实例 1:连接 localhost:5236
  • 访问实例 2:连接 localhost:5237
  • 容器内部:两者依然都是 5236,互不影响。
场景二:容器间互相访问

如果这两个容器需要互相调用(例如做主备集群),通常建议创建一个 Docker 自定义网络,通过容器名称或服务名加端口 5236 直接访问,无需映射宿主机端口:

# 创建网络
docker network create dm-net

# 启动容器加入网络
docker run -d --name dm_primary --network dm-net dameng/db
docker run -d --name dm_standby --network dm-net dameng/db
  • 在 dm_standby 容器中,可以直接通过 dm_primary:5236 访问主库。

总结

  • 容器内端口 (Container Port):可以相同(都是 5236),不冲突。
  • 宿主机映射端口 (Host Port):必须不同(如 5236 和 5237),否则冲突。

更多推荐