docker - 在 Docker Swarm 中运行的容器中获取完整容器名称的可靠方法
问题描述
背景:我有一个设置,其中许多不同的可扩展服务通过连接池(每个实例)连接到他们的数据库。这些服务在 Docker Swarm 中运行。
在我当前的数据库设置中,这最终看起来如下(在此示例中使用 PostgreSQL):
PID | Database | User | Application | Client | ...
... | db1 | app | --standard JDBC driver string-- | x | ...
... | db1 | app | --standard JDBC driver string-- | y | ...
... | db1 | app | --standard JDBC driver string-- | y | ...
... | ... | app | ... | x | ...
... | ... | app | ... | x | ...
... | db2 | app | --standard JDBC driver string-- | y | ...
... | db2 | app | --standard JDBC driver string-- | y | ...
... | ... | app | ... | x | ...
... | ... | app | ... | x | ...
我想要做的是有效地向 DBMS 提供当前的 Docker Swarm 容器名称,包括 scaling identifier,以便能够更好地监控数据库连接,即:
PID | Database | User | Application | Client | ...
... | db1 | app | books-service.1 | x | ...
... | db1 | app | books-service.2 | y | ...
... | db1 | app | books-service.3 | y | ...
... | ... | app | ... | x | ...
... | ... | app | ... | x | ...
... | db2 | app | checkout-service.2 | y | ...
... | db2 | app | checkout-service.2 | y | ...
... | ... | app | ... | x | ...
... | ... | app | ... | x | ...
(显然,设置连接字符串是微不足道的——它正在获取要设置的信息,这就是问题所在)
由于我的应用程序由 Docker Swarm 管理(将来的某个时候,可能是 Kubernetes),我不能通过环境手动设置这个值(因为我不执行 a docker run
)。
在给定的 Swarm 节点上运行docker ps
时,我看到以下输出:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
59cdbf724091 my-docker-registry.net/books-service:latest "/bin/sh -c '/usr/bi…" 7 minutes ago Up 7 minutes books-service.1.zabvo1jal0h2xya9qfftnrnej
0eeeee15e92a my-docker-registry.net/checkout-service:latest "/bin/sh -c 'exec /u…" 8 minutes ago Up 8 minutes checkout-service.2.189s7d09m0q86y7fdf3wpy0vc
值得注意的是该列,其中包含给定容器(或图像,但您更愿意查看它)的实际实例NAMES
的标识符。请注意,此名称不是容器的主机名,默认情况下是容器 ID。
我知道有一些方法可以确定应用程序是否在 Docker 中运行(例如使用 /proc/1/cgroup),但这对我也没有帮助,因为这些方法也只列出了容器 ID。
有没有办法从集群中运行的 Docker 容器中获取这个值?
解决方案
您需要 ( books-service.1
) 是 swarm 服务名称和任务槽的组合。这两者都可以作为环境变量以及完整的任务名称 ( books-service.1.zabvo1jal0h2xya9qfftnrnej
) 传递给容器:
version: "3.0"
services:
test:
image: debian:buster
command: cat /dev/stdout
environment:
SERVICE_NAME: '{{ .Service.Name }}'
TASK_SLOT: '{{ .Task.Slot }}'
TASK_NAME: "{{ .Task.Name }}"
通过这些后,您可以剥离TASK_NAME
以获得所需的内容,也可以将 与 结合SERVICE_NAME
起来TASK_SLOT
。想一想,您可以在模板中将它们组合起来:
version: "3.0"
services:
test:
image: debian:buster
command: cat /dev/stdout
environment:
MY_NAME: '{{ .Service.Name }}.{{.Task.Slot}}'
其他可能的占位符可以在这里找到。
推荐阅读
- jupyterhub - 违反内容安全政策:iframe 中的 JupytherHub
- python - AttributeError:“NoneType”对象没有属性“strip”jupyter notebook
- python - 如何在熊猫上将元组拆分为多列?
- javascript - 如何通过 Chrome 扩展替换 navigator.credentials.create 请求或响应参数?
- r - 在 ggplot 中重新排序数据会导致数据和条形之间不匹配
- python - matplotlib 中的 3D 线框可视化问题
- php - 从 codeigniter 查询的数组结果中删除行
- html - CSS 包装两列(主要内容和菜单栏)
- delphi - 从 go 调用 Delphi dll
- kotlin - Micronaut 数据 - 保存 ZonedDateTime 字段时出错 [无法将类型 [class java.time.ZonedDateTime] 转换为目标类型:class java.util.Date]