在DockerSwarm中以堆栈形式部署分布式应用
立即解锁
发布时间: 2025-09-13 00:14:41 阅读量: 3 订阅数: 44 AIGC 

# 在 Docker Swarm 中以堆栈形式部署分布式应用
## 1. 应用配置与数据库连接问题
当应用配置为使用 Postgres 作为数据库时,配置对象会将设置加载到副本中。然而,当你访问 `http://localhost:8080`(如果你使用 Windows 系统,也可以从其他机器访问你的机器),会发现应用无法正常工作。查看 Web 服务的日志,会显示大量关于数据库连接的错误。这是因为虽然部署配置了 Web 应用使用 Postgres,但配置对象没有提供数据库的连接详细信息,导致连接失败。
## 2. 使用秘密管理机密设置
### 2.1 秘密的概念与特性
秘密是 Swarm 中由集群管理的资源,其工作方式与配置对象几乎完全相同。你可以从本地文件创建秘密,该秘密会存储在集群数据库中。然后在服务规范中引用该秘密,其内容会在运行时加载到容器文件系统中。与配置对象的关键区别在于,你只能在工作流程的一个点以纯文本形式读取秘密:即当秘密从 Swarm 加载到容器内部时。
秘密在集群中的整个生命周期都是加密的。数据以加密形式存储在管理器共享的数据库中,并且秘密只会交付给计划运行需要该秘密的副本的节点。从管理节点传输到工作节点时,秘密是加密的,只有在容器内部才会解密,显示原始文件内容。
### 2.2 创建和检查秘密
以下是创建和检查秘密的操作步骤:
```bash
# 从本地 JSON 文件创建秘密
docker secret create todo-list-secret ./todo-list/secrets/secrets.json
# 使用 --pretty 标志检查秘密以查看数据
docker secret inspect --pretty todo-list-secret
```
使用秘密的用户体验与配置对象相同,唯一的区别是一旦秘密被存储,就无法读取其内容。检查秘密只会显示资源的元数据,而不是实际数据。
### 2.3 在应用部署中使用秘密
当秘密存储在 Swarm 中后,我们可以使用引用该秘密的服务规范部署应用的新版本。以下是 `v4.yml` 文件中关键部分的示例:
```yaml
services:
todo-web:
image: diamol/ch06-todo-list
ports:
- 8080:80
configs:
- source: todo-list-config
target: /app/config/config.json
secrets:
- source: todo-list-secret
target: /app/config/secrets.json
#...
secrets:
todo-list-secret:
external: true
```
秘密的内容是更多的 JSON 数据,加载到应用查找配置源的另一个路径中。这会为应用设置连接详细信息,使其使用 Postgres 容器作为数据存储。部署应用后,无论哪个 Web 副本为用户提供服务,用户都会获得相同的项目列表。
### 2.4 部署更新后的应用
部署应用的最新版本,提供缺失的数据库连接字符串并修复 Web 应用:
```bash
# 部署应用的新版本
docker stack deploy -c ./todo-list/v4.yml todo
# 检查堆栈的副本
docker stack ps todo
```
虽然 Compose 文件中只有 Web 服务定义发生了变化,但运行此命令时,Docker 会显示正在更新两个服务。实际上,它不会对数据库服务进行任何更新,这是 CLI 稍微误导性的输出。
### 2.5 配置对象和秘密的更新
配置对象和秘密一旦在集群中创建就无法更新。如果需要更新应用的配置,需要执行以下三个步骤:
1. 创建一个具有更新内容且名称与先前对象不同的新配置对象或秘密。
2. 在 Compose 文件中更新应用使用的配置对象或秘密的名称,指定新名称。
3. 从更新后的 Compose 文件部署堆栈。
这个过程意味着每次更改配置时都需要更新服务,即运行中的容器会被新容器替换。与 Kubernetes 不同,Kubernetes 允许更新集群中现有的配置和秘密对象,但这也会带来一些问题,因为有些应用平台会监视配置文件的更改,而有些则不会,所以更改可能会被忽略,最终还是需要替换容器。Swarm 在这方面是一致的,每次推出配置更改时都需要更新服务。
### 2.6 服务更新的必要性
更新服务并不需要担心。每当应用有新功能需要部署,或者所使用的依赖项或镜像所基于的操作系统有安全更新时,都需要推出容器更新。至少,你应该每月发布一次更新,这也是 Docker Hub 上大多数基于操作系统的镜像的更新频率。
## 3. 在 Swarm 中使用卷存储数据
### 3.1 Docker 卷的概念
Docker 卷是与容器具有独立生命周期的存储单元。任何需要容器化的有状态应用都可以使用卷进行存储。卷作为容器文件系统的一部分出现,但实际上存储在容器外部。应用升级时会替换容器,并将卷附加到新容器,使新容器从先前容器拥有的所有数据开始。
### 3.2 集群中卷的存储差异
在编排器中,卷的概念相同,即在 Compose 文件中为服务添加卷挂载规范,副本会将该卷视为本地目录。然而,数据的存储方式有很大差异。在集群中,有多个节点可以运行容器,每个节点都有自己的磁盘来存储本地卷。维持更新之间状态的最简单方法是使用本地卷,但存在一个问题:替换副本可能会被调度到与原始节点不同的节点上,从而无法访问原始节点的数据。
### 3.3 为节点添加标签
你可以为服务指定特定节点,这样更新将始终在拥有数据的节点上运行。以下是为节点添加标签的操作步骤:
```bash
# 查找节点 ID 并添加标签
docker nod
```
0
0
复制全文
相关推荐









