参考案例:
docker run -d --name Etcd-server \
--network app-tier \
--publish 2379:2379 \
--publish 2380:2380 \
--env ALLOW_NONE_AUTHENTICATION=yes \
--env ETCD_ADVERTISE_CLIENT_URLS=http://etcd-server:2379 \
bitnami/etcd:latest
以及 docker-compose 第 56 行。
不理解的点有: 1 、域名什么时候映射 ip 的 2 、如果是集群部署,每台机器都使用 http://etcd:2379 作为 url ,那么集群该如何发现服务 ip 地址
1
muxueqz 2023-03-28 11:17:14 +08:00
docker 根据 name 使用内置的 dns server 自动映射的
|
2
mingge2333 OP @muxueqz 这个不区分大小写的吗
|
3
Twnysta 2023-03-28 12:06:16 +08:00
http://etcd-server:2379 这个不是域名是服务名啊
|
4
DiffView 2023-03-28 13:41:28 +08:00
Docker 可以使用 service name 作为类似于域名解析的原理是 Docker 内置了一个 DNS 服务器,它可以为 Docker 网络中的每个容器提供服务发现和名称解析的功能。在 Docker 网络中,每个容器都可以通过其名称来访问其他容器,就像它们在同一个网络中的计算机一样。
当 Docker 容器启动时,它会自动注册其服务名和 IP 地址到 Docker 的内置 DNS 服务器中。这意味着其他容器可以通过服务名来解析并访问该容器的服务。Docker 的内置 DNS 服务器会自动将服务名解析为相应容器的 IP 地址,从而实现容器之间的服务发现和通信。 此外,Docker 还支持自定义网络,并允许用户指定自己的 DNS 服务器。这使得用户可以在 Docker 网络中使用自己的域名解析方案。 总之,Docker 的服务发现和名称解析功能是通过内置的 DNS 服务器和容器名称来实现的。通过这种方式,Docker 使得容器之间的通信更加方便和简单。 |
6
yinmin 2023-03-28 16:11:27 +08:00
docker 部署一个系统,包含多个容器。我推荐:创建一个虚拟内网,然后每个容器都配置固定 IP 地址,不需要 docker 解析 DNS ,系统更稳定。
例如,nginx 容器使用域名(容器名)proxy 后端程序容器。如果 nginx 先启动,后端程序容器后启动,nginx 会发现域名无法解析而报错,如果都使用 ip 地址,就没这个问题了。 |
7
fairless 2023-03-28 16:26:20 +08:00
使用自定义网络,荣期间就可以直接使用服务名相互访问了
|
8
muxueqz 2023-03-28 16:45:22 +08:00
|
9
mingge2333 OP @muxueqz 谢谢大佬
|
10
mingge2333 OP @yinmin 很有用,那请问 etcd 使用的是容器名,示例在这,56 行 https://github.com/apache/apisix-docker/blob/master/example/docker-compose.yml ,这个目的是为了集群容器间方便查找吧,想确认下 http://etcd:2379 是容器名么,因为容器名是好像是随机生成的。参考这个: https://agarwalrounak.medium.com/default-container-names-in-docker-15bdbf56b539#:~:text=When%20a%20container%20is%20created,assigns%20the%20container%20a%20name.
|
11
lovelylain 2023-03-28 18:21:20 +08:00 via Android 1
@mingge2333 我记得是默认 bridge 不支持这样干,使用自定义的网络就可以用容器名当域名
|
12
archean 2023-03-28 18:24:53 +08:00
@yinmin 个人觉得解决这个问题写个 depends on 就行了,固定 IP 地址徒增运维成本,请教固定 IP 地址还有额外好处吗?
|
13
julyclyde 2023-03-28 21:35:14 +08:00
没听说过 docker 内置 dns 服务器啊
应该是 hosts 的吧? |
14
yinmin 2023-03-29 00:35:29 +08:00
@archean 的确可以通过 depends on(link)方式指定容器的启动次序,但是如果存在嵌套引用 (a->b, b->c, c->a),就没办法写 link 关系了。使用 ip 地址更接近于物理机的部署方式,以前我们使用域名(容器名)部署,但运行一段时间后,我们重新规划了虚拟网络,并把域名都改成固定 ip 地址访问了,这样更稳定些吧。
|
15
yinmin 2023-03-29 00:53:04 +08:00
@mingge2333 容器名是在 yaml 里通过 container_name: <name>指定的,只有未指定名称时,docker 才随机生成。我看了 docker-compose.yml ,在这个示例里没有设置 container_name ,etcd 应该是 service name 。
设定 container_name 的好处是:查看容器列表时,知道每个容器都是啥内容。 不设定 container_name 的好处是:如果你要启用多套容器组,不会有名称冲突。 我测试了,通过 service name 和 container name 都能做 DNS 解析。 |
16
yinmin 2023-03-29 01:00:55 +08:00 1
@mingge2333 我发现 https://github.com/apache/apisix-docker/blob/master/example/docker-compose.yml 的 port 参数可能写的有问题。内网之间容器是可以直接访问的,不需要 port 抛出端口。
这个 yml 示例里,只需要将给外部访问的 web 容器端口通过 port 抛出即可,内部使用的容器不需要 port ,否则会有安全隐患的。 |
17
yinmin 2023-03-29 09:55:10 +08:00 via iPhone 1
在业务系统部署中,例如有 5 个容器:nginx 容器、web 业务系统容器、管理平台容器、mysql 容器、redis 容器。
web 业务系统容器和管理平台容器会经常更新,在更新管理平台容器时,肯定不希望影响 web 业务系统容器。redis 容器通常也不重启。 因此,5 个容器通常分多个 yaml 文件分别管理的,如果容器之间使用域名方式访问,可能会出现问题(先启动的容器没法解析后启动容器的 ip 地址),容器使用固定 ip 地址稳定性更佳。 |