使用 Ansible 管理多个服务器上的容器

使用 Ansible 管理多个服务器上的 Lobe-Chat Docker 容器

目标

通过这个剧本,将实现在多个服务器上自动更新 Lobe-Chat 服务,需要的步骤:

  • 停止运行中的 Lobe-Chat 容器。
  • 删除旧版本容器。
  • 拉取最新的 Lobe-Chat 镜像。
  • 根据不同服务器设置对应的端口,启动 Lobe-Chat 容器。

剧本概述

这是我们使用的 Ansible 剧本,其中包含了几个关键任务步骤:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
- name: Manage lobe-chat Docker container on multiple servers
hosts: chatservers
become: yes

vars:
docker_image: lobehub/lobe-chat
container_name: lobe-chat
host_ports:
- { host: "your_ip", port: 80 }

tasks:
- name: Set host-specific port
set_fact:
host_port: "{{ item.port }}"
with_items: "{{ host_ports }}"
when: item.host == ansible_host

- name: Debug host-specific port setting
debug:
msg: "Setting host_port to {{ item.port }} for {{ ansible_host }}"
with_items: "{{ host_ports }}"
when: item.host == ansible_host

- name: Check if lobe-chat container is running
shell: "docker ps -q -f name={{ container_name }}"
register: container_id
changed_when: false

- name: Stop lobe-chat container if it is running
docker_container:
name: "{{ container_name }}"
state: stopped
when: container_id.stdout != ""
ignore_errors: yes

- name: Remove lobe-chat container if it exists
docker_container:
name: "{{ container_name }}"
state: absent
ignore_errors: yes

- name: Pull the latest lobe-chat image
docker_image:
name: "{{ docker_image }}"
source: pull
force_source: yes

- name: Run lobe-chat container
docker_container:
name: "{{ container_name }}"
image: "{{ docker_image }}"
state: started
restart_policy: always
ports:
- "{{ host_port }}:3210"
env:
OPENAI_API_KEY: "sk-iO"
ACCESS_CODE: "12356"
when: host_port is defined

1. 主机与变量定义

首先,定义了目标主机组 chatservers,并使用 become: yes 来确保任务以管理员权限执行。接着,通过 vars 定义了一些变量,如 docker_imagecontainer_name,它们代表了 Lobe-Chat Docker 镜像及容器名称。此外,还定义了一个 host_ports 列表,其中包括了每个主机的具体端口映射信息。

2. 设定主机端口

为了确保每个服务器能够在指定的端口上启动 Lobe-Chat 容器,我们首先通过 set_fact 动态设定每个服务器的端口:

1
2
3
4
5
- name: Set host-specific port
set_fact:
host_port: "{{ item.port }}"
with_items: "{{ host_ports }}"
when: item.host == ansible_host

set_fact 模块用于动态设定 host_port 变量,when 条件判断当前任务只在匹配的服务器上执行。

通过 debug 模块,可以输出一些调试信息,以确保变量设定正确:

1
2
3
- name: Debug host-specific port setting
debug:
msg: "Setting host_port to {{ item.port }} for {{ ansible_host }}"

3. 检查并停止现有的 Lobe-Chat 容器

接下来,通过 docker ps 命令检查当前是否有名为 lobe-chat 的 Docker 容器在运行:

1
2
3
4
- name: Check if lobe-chat container is running
shell: "docker ps -q -f name={{ container_name }}"
register: container_id
changed_when: false

如果容器在运行,则通过以下任务将其停止并移除:

1
2
3
4
5
6
7
8
9
10
11
12
- name: Stop lobe-chat container if it is running
docker_container:
name: "{{ container_name }}"
state: stopped
when: container_id.stdout != ""
ignore_errors: yes

- name: Remove lobe-chat container if it exists
docker_container:
name: "{{ container_name }}"
state: absent
ignore_errors: yes

ignore_errors: yes 确保即使停止或删除容器失败,剧本也会继续执行。

4. 拉取最新 Lobe-Chat 镜像并启动容器

拉取最新的 Lobe-Chat 镜像,并启动容器是最后的关键步骤。通过 docker_image 模块拉取镜像:

1
2
3
4
5
- name: Pull the latest lobe-chat image
docker_image:
name: "{{ docker_image }}"
source: pull
force_source: yes

然后使用 docker_container 模块启动容器,配置环境变量及端口映射:

1
2
3
4
5
6
7
8
9
10
11
- name: Run lobe-chat container
docker_container:
name: "{{ container_name }}"
image: "{{ docker_image }}"
state: started
restart_policy: always
ports:
- "{{ host_port }}:3210"
env:
OPENAI_API_KEY: "sk-iO"
ACCESS_CODE: "12356"

确保 ports 中定义的 host_port 变量已被正确设置,使每个服务器上的容器都在指定端口运行。

总结

通过这个 Ansible 剧本,可以轻松管理多个服务器上的 Docker 容器,自动执行拉取镜像、停止旧容器、删除旧容器和启动新容器的流程。由于 Ansible 是无代理的(agentless),剧本执行非常灵活,特别适用于云环境中的大规模管理。


使用 Ansible 管理多个服务器上的容器
http://example.com/2024/09/21/使用-Ansible-管理多个服务器上的容器/
作者
Sanli Ma
发布于
2024年9月21日
许可协议