kdeploy 1.3.3 → 1.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.md CHANGED
@@ -9,10 +9,9 @@
9
9
  |_| |___/
10
10
 
11
11
  ⚡ 轻量级无代理部署工具
12
- 🚀 自动部署,轻松扩展
13
12
  ```
14
13
 
15
- 一个用 Ruby 编写的轻量级、无代理的部署自动化工具。Kdeploy 使您能够使用 SSH 在多个服务器上部署应用程序、管理配置和执行任务,而无需在目标机器上安装任何代理或守护进程。
14
+ Ruby DSL 定义主机与任务,通过 SSH/SCP 在多台服务器上并发执行部署与配置,目标机无需安装 agent。
16
15
 
17
16
  [![Gem Version](https://img.shields.io/gem/v/kdeploy)](https://rubygems.org/gems/kdeploy)
18
17
  [![Ruby](https://github.com/kevin197011/kdeploy/actions/workflows/gem-push.yml/badge.svg)](https://github.com/kevin197011/kdeploy/actions/workflows/gem-push.yml)
@@ -20,1177 +19,103 @@
20
19
 
21
20
  **语言**: [English](README_EN.md) | [中文](README.md)
22
21
 
23
- ## 目录
22
+ **详细需求、DSL、API、架构**:见 [docs/REQUIREMENTS.md](docs/REQUIREMENTS.md)
24
23
 
25
- - [功能特性](#-功能特性)
26
- - [安装](#-安装)
27
- - [快速开始](#-快速开始)
28
- - [使用指南](#-使用指南)
29
- - [配置](#-配置)
30
- - [高级用法](#-高级用法)
31
- - [错误处理](#-错误处理)
32
- - [最佳实践](#-最佳实践)
33
- - [故障排除](#-故障排除)
34
- - [架构](#-架构)
35
- - [开发](#-开发)
36
- - [贡献](#-贡献)
37
- - [许可证](#-许可证)
24
+ ## 功能概览
38
25
 
39
- ## 🌟 功能特性
26
+ - 无代理 SSH 远程执行,多主机并发
27
+ - Ruby DSL:主机、角色、任务;Chef 风格资源(`package`、`service`、`template`、`sync` 等)
28
+ - 文件上传、ERB 模板、目录同步(可选 rsync 快速路径)
29
+ - 试运行、JSON 输出、重试/超时策略
40
30
 
41
- ### 核心功能
31
+ **技术栈**:Ruby、Thor、net-ssh、concurrent-ruby
42
32
 
43
- - 🔑 **无代理远程部署**: 使用 SSH 进行安全的远程执行,无需安装代理
44
- - 📝 **优雅的 Ruby DSL**: 简单而富有表现力的任务定义语法
45
- - 🚀 **并发执行**: 跨多个主机的高效并行任务处理
46
- - 📤 **文件上传支持**: 通过 SCP 轻松部署文件和模板
47
- - 📁 **目录同步功能**: 递归同步目录,支持文件过滤和删除多余文件
48
- - 📊 **任务状态跟踪**: 实时执行监控,提供详细输出
49
- - 🔄 **ERB 模板支持**: 支持变量替换的动态配置生成
50
- - 🎯 **基于角色的部署**: 针对特定服务器角色进行有组织的部署
51
- - 🔍 **试运行模式**: 在执行前预览任务,不进行实际更改
52
- - 🎨 **彩色输出**: 直观的颜色方案(绿色:成功,红色:错误,黄色:警告)
53
- - ⚙️ **灵活的主机定位**: 在特定主机、角色或所有主机上执行任务
54
- - 🔐 **多种身份验证方法**: 支持 SSH 密钥和密码身份验证
55
- - 📈 **执行时间跟踪**: 监控任务执行持续时间以进行性能分析
33
+ ## 安装
56
34
 
57
- ### 技术特性
58
-
59
- - **线程安全执行**: 基于 `concurrent-ruby` 实现可靠的并行处理
60
- - **自定义错误处理**: 详细的错误类型,便于调试
61
- - **配置管理**: 集中式配置,提供合理的默认值
62
- - **可扩展架构**: 模块化设计,易于扩展
63
- - **Shell 自动补全**: 支持 Bash 和 Zsh 的自动补全
64
-
65
- ## 📦 安装
66
-
67
- ### 要求
68
-
69
- - Ruby >= 2.7.0
70
- - 对目标服务器的 SSH 访问权限
71
- - 已配置 SSH 密钥或密码身份验证
72
-
73
- ### 通过 RubyGems 安装
35
+ 要求:Ruby >= 2.7,目标机 SSH 可达。
74
36
 
75
37
  ```bash
76
38
  gem install kdeploy
77
- ```
78
-
79
- ### 通过 Bundler 安装
80
-
81
- 将以下行添加到应用程序的 `Gemfile` 中:
82
-
83
- ```ruby
84
- gem 'kdeploy'
85
- ```
86
-
87
- 然后执行:
88
-
89
- ```bash
90
- bundle install
91
- ```
92
-
93
- ### 验证安装
94
-
95
- ```bash
96
39
  kdeploy version
97
40
  ```
98
41
 
99
- 您应该看到版本信息和横幅。
42
+ Bundler:`gem 'kdeploy'` → `bundle install`
100
43
 
101
- **若找不到 `kdeploy` 命令**:gem 的可执行目录可能不在 PATH 中。将以下内容加入 `~/.zshrc` `~/.bashrc` 后执行 `source ~/.zshrc`:
44
+ 找不到命令时,将 `$(ruby -e 'puts Gem.bindir')` 加入 `PATH`。
102
45
 
103
- ```bash
104
- export PATH="$(ruby -e 'puts Gem.bindir'):$PATH"
105
- ```
46
+ ## 快速开始
106
47
 
107
- ### Shell 自动补全
108
-
109
- Kdeploy 在安装期间自动配置 shell 自动补全。如果需要,可以手动添加到 shell 配置中:
110
-
111
- **对于 Bash** (`~/.bashrc`):
112
- ```bash
113
- source "$(gem contents kdeploy | grep kdeploy.bash)"
114
- ```
115
-
116
- **对于 Zsh** (`~/.zshrc`):
117
48
  ```bash
118
- source "$(gem contents kdeploy | grep kdeploy.zsh)"
119
- autoload -Uz compinit && compinit
49
+ kdeploy init my-deploy
50
+ cd my-deploy
120
51
  ```
121
52
 
122
- 添加配置后:
123
- 1. 对于 Bash: `source ~/.bashrc`
124
- 2. 对于 Zsh: `source ~/.zshrc`
125
-
126
- 现在您可以使用 Tab 补全:
127
- - 命令: `kdeploy [TAB]`
128
- - 文件路径: `kdeploy execute [TAB]`
129
- - 选项: `kdeploy execute deploy.rb [TAB]`
130
-
131
- ## 🚀 快速开始
132
-
133
- ### 1. 初始化新项目
134
-
135
- ```bash
136
- kdeploy init my-deployment
137
- ```
138
-
139
- 这将创建一个新目录,包含:
140
- - `deploy.rb` - 主部署配置文件
141
- - `config/` - 配置文件和模板目录
142
- - `README.md` - 项目文档
143
-
144
- ### 2. 配置主机和任务
145
-
146
- 编辑 `deploy.rb`(使用 Chef 风格资源 DSL):
53
+ 编辑 `deploy.rb`:
147
54
 
148
55
  ```ruby
149
- # 定义主机
150
56
  host "web01", user: "ubuntu", ip: "10.0.0.1", key: "~/.ssh/id_rsa"
151
- host "web02", user: "ubuntu", ip: "10.0.0.2", key: "~/.ssh/id_rsa"
152
- role :web, %w[web01 web02]
153
-
154
- # 定义部署任务
155
- task :deploy_web, roles: :web do
156
- package "nginx"
157
- directory "/etc/nginx/conf.d"
158
- template "/etc/nginx/nginx.conf", source: "./config/nginx.conf.erb",
159
- variables: { domain_name: "example.com", port: 3000 }
160
- file "/etc/nginx/conf.d/app.conf", source: "./config/app.conf"
161
- run "nginx -t", sudo: true
162
- service "nginx", action: %i[enable restart]
163
- end
164
- ```
165
-
166
- ### 3. 运行部署
167
-
168
- ```bash
169
- kdeploy execute deploy.rb deploy_web
170
- ```
171
-
172
- ## 📖 使用指南
173
-
174
- ### 命令参考
175
-
176
- #### `kdeploy init [DIR]`
177
-
178
- 初始化新的部署项目。
179
-
180
- ```bash
181
- # 在当前目录初始化
182
- kdeploy init .
183
-
184
- # 在指定目录初始化
185
- kdeploy init my-deployment
186
- ```
187
-
188
- #### `kdeploy execute TASK_FILE [TASK]`
189
-
190
- 从配置文件执行部署任务。
191
-
192
- **基本用法:**
193
- ```bash
194
- # 执行文件中的所有任务
195
- kdeploy execute deploy.rb
196
-
197
- # 执行特定任务
198
- kdeploy execute deploy.rb deploy_web
199
- ```
200
-
201
- **选项:**
202
- - `--limit HOSTS`: 限制执行到特定主机(逗号分隔)
203
- - `--parallel NUM`: 并行执行数量(默认: 10)
204
- - `--dry-run`: 预览模式 - 显示将要执行的操作而不实际执行
205
- - `--debug`: 调试模式 - 显示 `run` 命令的 stdout/stderr 详细输出(便于排查问题)
206
- - `--no-banner`: 不输出 Banner(更适合脚本/CI 场景)
207
- - `--format FORMAT`: 输出格式(`text`|`json`,默认 `text`)
208
- - `--retries N`: 网络相关操作重试次数(默认 `0`)
209
- - `--retry-delay SECONDS`: 每次重试间隔秒数(默认 `1`)
210
- - `--retry-on-nonzero`: 非零退出码重试开关(默认 `false`)
211
- - `--timeout SECONDS`: 单 host 执行超时(秒,默认不启用)
212
- - `--step-timeout SECONDS`: 单 step 执行超时(秒,默认不启用)
213
- - `--retry-policy JSON`: 重试策略 JSON(覆盖 `.kdeploy.yml`)
214
-
215
- **示例:**
216
- ```bash
217
- # 预览部署而不执行
218
- kdeploy execute deploy.rb deploy_web --dry-run
219
-
220
- # 仅在特定主机上执行
221
- kdeploy execute deploy.rb deploy_web --limit web01,web02
222
-
223
- # 使用自定义并行数量
224
- kdeploy execute deploy.rb deploy_web --parallel 5
225
-
226
- # 输出详细调试信息(stdout/stderr)
227
- kdeploy execute deploy.rb deploy_web --debug
228
-
229
- # 机器可读 JSON 输出(便于集成)
230
- kdeploy execute deploy.rb deploy_web --format json --no-banner
231
-
232
- # 重试网络抖动导致的失败
233
- kdeploy execute deploy.rb deploy_web --retries 3 --retry-delay 1
234
-
235
- # 对非零退出码进行重试
236
- kdeploy execute deploy.rb deploy_web --retries 2 --retry-on-nonzero
237
-
238
- # 设置单 host 超时(秒)
239
- kdeploy execute deploy.rb deploy_web --timeout 120
240
-
241
- # 设置单 step 超时(秒)
242
- kdeploy execute deploy.rb deploy_web --step-timeout 30
243
-
244
- # 使用 CLI 覆盖重试策略(JSON)
245
- kdeploy execute deploy.rb deploy_web --retry-policy '{"run":{"retries":2,"retry_on_exit_codes":[2]}}'
246
-
247
- # 使用文件覆盖重试策略(JSON)
248
- kdeploy execute deploy.rb deploy_web --retry-policy-file ./retry_policy.example.json
249
-
250
- # 组合选项
251
- kdeploy execute deploy.rb deploy_web --limit web01 --parallel 3 --dry-run
252
- ```
253
-
254
- #### `kdeploy version`
255
-
256
- 显示版本信息。
257
-
258
- ```bash
259
- kdeploy version
260
- ```
261
-
262
- #### `kdeploy help [COMMAND]`
263
-
264
- 显示帮助信息。
265
-
266
- ```bash
267
- # 显示一般帮助
268
- kdeploy help
269
-
270
- # 显示特定命令的帮助
271
- kdeploy help execute
272
- ```
273
-
274
- ### 主机定义
275
-
276
- #### 基本主机配置
277
-
278
- ```ruby
279
- # 使用 SSH 密钥的单个主机
280
- host "web01",
281
- user: "ubuntu",
282
- ip: "10.0.0.1",
283
- key: "~/.ssh/id_rsa"
284
-
285
- # 使用密码身份验证的主机
286
- host "web02",
287
- user: "admin",
288
- ip: "10.0.0.2",
289
- password: "your-password"
290
-
291
- # 使用自定义 SSH 端口的主机
292
- host "web03",
293
- user: "ubuntu",
294
- ip: "10.0.0.3",
295
- key: "~/.ssh/id_rsa",
296
- port: 2222
297
-
298
- # 使用 sudo 的主机(所有命令自动使用 sudo)
299
- host "web04",
300
- user: "ubuntu",
301
- ip: "10.0.0.4",
302
- key: "~/.ssh/id_rsa",
303
- use_sudo: true
304
- ```
305
-
306
- #### 主机配置选项
307
-
308
- | 选项 | 类型 | 必需 | 描述 |
309
- |------|------|------|------|
310
- | `user` | String | 是 | SSH 用户名 |
311
- | `ip` | String | 是 | 服务器 IP 地址或主机名 |
312
- | `key` | String | 否* | SSH 私钥文件路径 |
313
- | `password` | String | 否* | SSH 密码 |
314
- | `port` | Integer | 否 | SSH 端口(默认: 22) |
315
- | `use_sudo` | Boolean | 否 | 是否对所有命令自动使用 sudo(默认: false) |
316
- | `sudo_password` | String | 否 | sudo 密码(如果需要密码验证) |
317
-
318
- \* 身份验证需要 `key` 或 `password` 之一。
319
-
320
- #### 动态主机定义
321
-
322
- ```ruby
323
- # 以编程方式定义多个主机
324
- %w[web01 web02 web03].each do |name|
325
- host name,
326
- user: "ubuntu",
327
- ip: "10.0.0.#{name[-1]}",
328
- key: "~/.ssh/id_rsa"
329
- end
330
-
331
- # 从外部源定义主机
332
- require 'yaml'
333
- hosts_config = YAML.load_file('hosts.yml')
334
- hosts_config.each do |name, config|
335
- host name, **config
336
- end
337
- ```
338
-
339
- ### 角色管理
340
-
341
- 角色允许您对主机进行分组,并在任务中集体定位它们。
342
-
343
- ```ruby
344
- # 定义角色
345
- role :web, %w[web01 web02 web03]
346
- role :db, %w[db01 db02]
347
- role :cache, %w[cache01]
348
- role :all, %w[web01 web02 web03 db01 db02 cache01]
349
-
350
- # 在任务中使用角色
351
- task :deploy_web, roles: :web do
352
- # 在所有 Web 服务器上执行
353
- end
354
-
355
- task :backup_db, roles: :db do
356
- # 在所有数据库服务器上执行
357
- end
358
-
359
- # 多个角色
360
- task :deploy_all, roles: [:web, :cache] do
361
- # 在 Web 和缓存服务器上执行
362
- end
363
- ```
364
-
365
- ### 任务定义
366
-
367
- #### 基本任务
368
-
369
- ```ruby
370
- task :hello do
371
- run "echo 'Hello, World!'"
372
- end
373
- ```
374
-
375
- #### 基于角色的任务
376
-
377
- ```ruby
378
- task :deploy_web, roles: :web do
379
- service "nginx", action: :restart
380
- end
381
- ```
382
-
383
- #### 特定主机任务
384
-
385
- ```ruby
386
- task :maintenance, on: %w[web01] do
387
- service "nginx", action: :stop
388
- run "apt-get update && apt-get upgrade -y", sudo: true
389
- service "nginx", action: %i[start enable]
390
- end
391
- ```
392
-
393
- #### 多命令任务
57
+ role :web, %w[web01]
394
58
 
395
- ```ruby
396
59
  task :deploy_web, roles: :web do
397
60
  package "nginx"
398
- directory "/etc/nginx/conf.d"
399
61
  template "/etc/nginx/nginx.conf", source: "./config/nginx.conf.erb", variables: { port: 3000 }
400
- file "/etc/nginx/conf.d/app.conf", source: "./config/app.conf"
401
62
  run "nginx -t", sudo: true
402
63
  service "nginx", action: %i[enable restart]
403
64
  end
404
65
  ```
405
66
 
406
- #### 任务选项
407
-
408
- | 选项 | 类型 | 描述 |
409
- |------|------|------|
410
- | `roles` | Symbol/Array | 在具有指定角色的主机上执行 |
411
- | `on` | Array | 在特定主机上执行 |
412
-
413
- **注意**: 如果未指定 `roles` 或 `on`,任务将在所有已定义的主机上执行。
414
-
415
- ### 命令类型
416
-
417
- #### `run` - 执行 Shell 命令
418
-
419
- 在远程服务器上执行命令。
420
-
421
- ```ruby
422
- # 单行命令
423
- run "sudo systemctl restart nginx"
424
-
425
- # 多行命令(推荐用于复杂命令)
426
- run <<~SHELL
427
- cd /var/www/app
428
- git pull origin main
429
- bundle install
430
- sudo systemctl restart puma
431
- SHELL
432
- ```
433
-
434
- **参数:**
435
- - `command`: 要执行的命令字符串
436
- - `sudo`: 布尔值,是否使用 sudo 执行此命令(可选,默认: nil,继承主机配置)
437
-
438
- **sudo 使用方式:**
439
-
440
- 1. **在主机级别配置**(所有命令自动使用 sudo):
441
- ```ruby
442
- host "web01",
443
- user: "ubuntu",
444
- ip: "10.0.0.1",
445
- key: "~/.ssh/id_rsa",
446
- use_sudo: true # 所有命令自动使用 sudo
447
- ```
448
-
449
- 2. **在命令级别配置**(仅特定命令使用 sudo):
450
- ```ruby
451
- task :deploy do
452
- run "systemctl restart nginx", sudo: true # 仅此命令使用 sudo
453
- run "echo 'Deployed'" # 此命令不使用 sudo
454
- end
455
- ```
456
-
457
- 3. **使用 sudo 密码**(如果需要密码验证):
458
- ```ruby
459
- host "web01",
460
- user: "ubuntu",
461
- ip: "10.0.0.1",
462
- key: "~/.ssh/id_rsa",
463
- use_sudo: true,
464
- sudo_password: "your-sudo-password" # 仅在需要密码时配置
465
- ```
466
-
467
- **注意:**
468
- - 如果命令已经以 `sudo` 开头,工具不会重复添加
469
- - 推荐使用 NOPASSWD 配置 sudo,避免在配置文件中存储密码
470
- - 命令级别的 `sudo` 选项会覆盖主机级别的 `use_sudo` 配置
471
-
472
- **最佳实践**: 对多行命令使用 heredoc (`<<~SHELL`) 以提高可读性。
473
-
474
- #### `upload` - 上传文件
475
-
476
- 将文件上传到远程服务器。
477
-
478
- ```ruby
479
- upload "./config/nginx.conf", "/etc/nginx/nginx.conf"
480
- upload "./scripts/deploy.sh", "/tmp/deploy.sh"
481
- ```
482
-
483
- **参数:**
484
- - `source`: 本地文件路径
485
- - `destination`: 远程文件路径
486
-
487
- #### `upload_template` - 上传 ERB 模板
488
-
489
- 上传并渲染 ERB 模板,支持变量替换。
490
-
491
- ```ruby
492
- upload_template "./config/nginx.conf.erb", "/etc/nginx/nginx.conf",
493
- domain_name: "example.com",
494
- port: 3000,
495
- worker_processes: 4
496
- ```
497
-
498
- **参数:**
499
- - `source`: 本地 ERB 模板文件路径
500
- - `destination`: 远程文件路径
501
- - `variables`: 用于模板渲染的变量哈希
502
-
503
- #### `sync` - 同步目录
504
-
505
- 递归同步本地目录到远程服务器,支持文件过滤和删除多余文件。
506
-
507
- ```ruby
508
- # 基本同步
509
- sync "./app", "/var/www/app"
510
-
511
- # 同步并忽略特定文件/目录
512
- sync "./app", "/var/www/app",
513
- ignore: [".git", "*.log", "node_modules", "*.tmp"]
514
-
515
- # 同步并删除远程多余文件
516
- sync "./app", "/var/www/app",
517
- ignore: [".git", "*.log"],
518
- delete: true
519
-
520
- # 排除特定文件(与 ignore 相同,但语义更清晰)
521
- sync "./config", "/etc/app",
522
- exclude: ["*.example", "*.bak", ".env.local"]
523
-
524
- # 启用快速同步(本地/远端均有 rsync 时优先使用)
525
- sync "./app", "/var/www/app",
526
- fast: true
527
-
528
- # 设置同步并行度
529
- sync "./app", "/var/www/app",
530
- parallel: 4
531
- ```
532
-
533
- **参数:**
534
- - `source`: 本地源目录路径
535
- - `destination`: 远程目标目录路径
536
- - `ignore`: 要忽略的文件/目录模式数组(支持 .gitignore 风格的通配符)
537
- - `exclude`: 与 `ignore` 相同,用于语义清晰
538
- - `delete`: 布尔值,是否删除远程目录中不存在于源目录的文件(默认: false)
539
- - `fast`: 布尔值,启用快速同步路径(优先 rsync,默认: false)
540
- - `parallel`: 上传并行度(默认: 1)
541
-
542
- **忽略模式支持:**
543
- - `*.log` - 匹配所有 .log 文件
544
- - `node_modules` - 匹配 node_modules 目录或文件
545
- - `**/*.tmp` - 递归匹配所有 .tmp 文件
546
- - `.git` - 匹配 .git 目录
547
- - `config/*.local` - 匹配 config 目录下的所有 .local 文件
548
-
549
- **使用场景:**
550
- - 部署应用程序代码
551
- - 同步配置文件目录
552
- - 同步静态资源文件
553
- - 保持本地和远程目录结构一致
554
-
555
- ### Chef 风格资源 DSL
556
-
557
- Kdeploy 提供类似 Chef 的声明式资源 DSL,可替代或与底层原语(`run`、`upload`、`upload_template`)混用。
558
-
559
- #### `package` - 安装系统包
560
-
561
- ```ruby
562
- package "nginx"
563
- package "nginx", version: "1.18"
564
- package "nginx", platform: :yum # CentOS/RHEL
565
- ```
566
-
567
- 默认使用 apt(Ubuntu/Debian);`platform: :yum` 生成 yum 命令。
568
-
569
- #### `service` - 管理系统服务(systemd)
570
-
571
- ```ruby
572
- service "nginx", action: [:enable, :start]
573
- service "nginx", action: :restart
574
- service "nginx", action: [:stop, :disable]
575
- ```
576
-
577
- 支持 `:start`、`:stop`、`:restart`、`:reload`、`:enable`、`:disable`。
578
-
579
- #### `template` - 部署 ERB 模板
580
-
581
- ```ruby
582
- template "/etc/nginx/nginx.conf", source: "./config/nginx.conf.erb", variables: { port: 3000 }
583
- # 或 block 语法
584
- template "/etc/app.conf" do
585
- source "./config/app.erb"
586
- variables(domain: "example.com")
587
- end
588
- ```
589
-
590
- #### `file` - 上传本地文件
591
-
592
- ```ruby
593
- file "/etc/nginx/conf.d/app.conf", source: "./config/app.conf"
594
- ```
595
-
596
- #### `directory` - 确保远程目录存在
597
-
598
- ```ruby
599
- directory "/etc/nginx/conf.d"
600
- directory "/var/log/app", mode: "0755"
601
- ```
602
-
603
- **示例:使用资源 DSL 部署 Nginx**
604
-
605
- ```ruby
606
- task :deploy_nginx, roles: :web do
607
- package "nginx"
608
- directory "/etc/nginx/conf.d"
609
- template "/etc/nginx/nginx.conf", source: "./config/nginx.conf.erb", variables: { port: 3000 }
610
- file "/etc/nginx/conf.d/app.conf", source: "./config/app.conf"
611
- run "nginx -t"
612
- service "nginx", action: [:enable, :restart]
613
- end
614
- ```
615
-
616
- ### 模板支持
617
-
618
- Kdeploy 支持 ERB(嵌入式 Ruby)模板,用于动态配置生成。
619
-
620
- #### 创建模板
621
-
622
- 创建 ERB 模板文件(例如,`config/nginx.conf.erb`):
623
-
624
- ```erb
625
- user nginx;
626
- worker_processes <%= worker_processes %>;
627
- error_log /var/log/nginx/error.log;
628
- pid /run/nginx.pid;
629
-
630
- events {
631
- worker_connections <%= worker_connections %>;
632
- }
633
-
634
- http {
635
- include /etc/nginx/mime.types;
636
- default_type application/octet-stream;
637
-
638
- upstream app_servers {
639
- server 127.0.0.1:<%= port %>;
640
- }
641
-
642
- server {
643
- listen 80;
644
- server_name <%= domain_name %>;
645
-
646
- location / {
647
- proxy_pass http://app_servers;
648
- proxy_http_version 1.1;
649
- proxy_set_header Upgrade $http_upgrade;
650
- proxy_set_header Connection 'upgrade';
651
- proxy_set_header Host $host;
652
- proxy_cache_bypass $http_upgrade;
653
- }
654
- }
655
- }
656
- ```
657
-
658
- #### 使用模板
659
-
660
- ```ruby
661
- task :deploy_config do
662
- template "/etc/nginx/nginx.conf", source: "./config/nginx.conf.erb",
663
- variables: { domain_name: "example.com", port: 3000, worker_processes: 4, worker_connections: 2048 }
664
- end
665
- ```
666
-
667
- #### 模板特性
668
-
669
- - 完整的 ERB 语法支持
670
- - 变量替换
671
- - 条件逻辑
672
- - 循环和迭代
673
- - Ruby 代码执行
674
-
675
- ### 清单块
676
-
677
- 使用 `inventory` 块来组织主机定义:
678
-
679
- ```ruby
680
- inventory do
681
- host 'web01', user: 'ubuntu', ip: '10.0.0.1', key: '~/.ssh/id_rsa'
682
- host 'web02', user: 'ubuntu', ip: '10.0.0.2', key: '~/.ssh/id_rsa'
683
- host 'db01', user: 'root', ip: '10.0.0.3', key: '~/.ssh/id_rsa'
684
- end
685
- ```
686
-
687
- ## ⚙️ 配置
688
-
689
- ### 默认配置
690
-
691
- Kdeploy 使用可自定义的合理默认值:
692
-
693
- - **默认并行数量**: 10 个并发执行
694
- - **SSH 超时**: 30 秒
695
- - **主机密钥验证**: 禁用(为方便起见,在生产环境中启用)
696
-
697
- ### 环境变量
698
-
699
- 您可以使用环境变量覆盖默认值:
67
+ 执行:
700
68
 
701
69
  ```bash
702
- export KDEPLOY_PARALLEL=5
703
- export KDEPLOY_SSH_TIMEOUT=60
704
- ```
705
-
706
- ### 配置文件
707
-
708
- 对于项目特定的配置,创建 `.kdeploy.yml`:
709
-
710
- ```yaml
711
- parallel: 5
712
- ssh_timeout: 60
713
- verify_host_key: true
714
- retries: 2
715
- retry_delay: 1
716
- retry_on_nonzero: false
717
- step_timeout: 30
718
- sync_fast: false
719
- sync_parallel: 4
720
- retry_policy:
721
- run:
722
- retries: 2
723
- retry_on_exit_codes: [2, 255]
724
- upload:
725
- retries: 0
70
+ kdeploy execute deploy.rb deploy_web --dry-run # 预览
71
+ kdeploy execute deploy.rb deploy_web # 执行
726
72
  ```
727
73
 
728
- 配置文件会自动从当前目录向上查找,直到找到 `.kdeploy.yml` 文件。
729
-
730
- **重试策略示例文件**: `retry_policy.example.json`
74
+ 常用选项:`--limit web01`、`--parallel 5`、`--format json`、`--retries 3`。完整选项见 [docs/REQUIREMENTS.md](docs/REQUIREMENTS.md#fr-cli-04-execute-选项)。
731
75
 
732
- ## 🔧 高级用法
76
+ **Docker 多机实测**:`cd docker/lab && docker compose --profile test up --build runner`(见 [docker/lab/README.md](docker/lab/README.md))
733
77
 
734
- ### 条件执行
735
-
736
- 在部署文件中使用 Ruby 条件:
737
-
738
- ```ruby
739
- task :deploy do
740
- service "nginx", action: :stop if ENV['ENVIRONMENT'] == 'production'
78
+ ## 配置
741
79
 
742
- file "/etc/nginx/nginx.conf", source: "./config/nginx.conf"
80
+ 项目根目录可放 `.kdeploy.yml`(从当前目录向上查找):
743
81
 
744
- service "nginx", action: :start if ENV['ENVIRONMENT'] == 'production'
745
- end
746
- ```
747
-
748
- ### 重试策略示例
749
-
750
- 你可以通过文件覆盖重试策略:
751
-
752
- ```bash
753
- kdeploy execute deploy.rb deploy_web --retry-policy-file ./retry_policy.example.json
754
- ```
755
-
756
- 示例文件见:`retry_policy.example.json` / `retry_policy.example.yml`
757
-
758
- ### 循环主机
759
-
760
- ```ruby
761
- # 根据主机执行不同的命令
762
- task :custom_setup do
763
- @hosts.each do |name, config|
764
- if name.start_with?('web')
765
- run "echo 'Web 服务器: #{name}'"
766
- elsif name.start_with?('db')
767
- run "echo '数据库服务器: #{name}'"
768
- end
769
- end
770
- end
771
- ```
772
-
773
- ### 任务中的错误处理
774
-
775
- ```ruby
776
- task :deploy do
777
- service "nginx", action: :stop
778
- file "/etc/nginx/nginx.conf", source: "./config/nginx.conf"
779
- run "nginx -t" || raise "Nginx 配置无效"
780
- service "nginx", action: :start
781
- end
782
- ```
783
-
784
- ### 使用外部库
785
-
786
- ```ruby
787
- require 'yaml'
788
- require 'json'
789
-
790
- # 从外部文件加载配置
791
- config = YAML.load_file('config.yml')
792
-
793
- task :deploy do
794
- config['commands'].each do |cmd|
795
- run cmd
796
- end
797
- end
798
- ```
799
-
800
- ## 🚨 错误处理
801
-
802
- ### 错误类型
803
-
804
- Kdeploy 提供特定的错误类型以便更好地调试:
805
-
806
- - `Kdeploy::TaskNotFoundError` - 任务未找到
807
- - `Kdeploy::HostNotFoundError` - 主机未找到
808
- - `Kdeploy::SSHError` - SSH 操作失败
809
- - `Kdeploy::SCPError` - SCP 上传失败
810
- - `Kdeploy::TemplateError` - 模板渲染失败
811
- - `Kdeploy::ConfigurationError` - 配置错误
812
- - `Kdeploy::FileNotFoundError` - 文件未找到
813
-
814
- ### 错误输出
815
-
816
- 错误显示包括:
817
- - 红色颜色编码
818
- - 详细的错误消息
819
- - 主机信息
820
- - 原始错误上下文
821
-
822
- ## 💡 最佳实践
823
-
824
- ### 1. 对多行命令使用 Heredoc
825
-
826
- ```ruby
827
- # ✅ 好的做法
828
- run <<~SHELL
829
- cd /var/www/app
830
- git pull origin main
831
- bundle install
832
- SHELL
833
-
834
- # ❌ 避免
835
- run "cd /var/www/app && git pull origin main && bundle install"
836
- ```
837
-
838
- ### 2. 使用角色进行组织
839
-
840
- ```ruby
841
- # ✅ 好的做法 - 使用角色进行组织
842
- role :web, %w[web01 web02]
843
- role :db, %w[db01 db02]
844
-
845
- task :deploy_web, roles: :web do
846
- # ...
847
- end
848
-
849
- # ❌ 避免 - 硬编码主机名
850
- task :deploy do
851
- # 难以维护
852
- end
853
- ```
854
-
855
- ### 3. 使用模板进行动态配置
856
-
857
- ```ruby
858
- # ✅ 好的做法 - 使用 template 资源
859
- template "/etc/nginx/nginx.conf", source: "./config/nginx.conf.erb",
860
- variables: { domain_name: "example.com", port: 3000 }
861
-
862
- # ❌ 避免 - 硬编码值
863
- run "echo 'server_name example.com;' > /etc/nginx/nginx.conf"
864
- ```
865
-
866
- ### 4. 部署前验证
867
-
868
- ```ruby
869
- task :deploy do
870
- template "/etc/nginx/nginx.conf", source: "./config/nginx.conf.erb", variables: { port: 3000 }
871
- file "/etc/nginx/conf.d/app.conf", source: "./config/app.conf"
872
- run "nginx -t", sudo: true # 配置无效时 run 会抛异常
873
- service "nginx", action: :reload
874
- end
82
+ ```yaml
83
+ parallel: 10
84
+ ssh_timeout: 30
85
+ verify_host_key: never
86
+ retries: 0
875
87
  ```
876
88
 
877
- ### 5. 使用试运行进行测试
89
+ 重试策略示例:`retry_policy.example.json`
878
90
 
879
- 在实际部署之前,始终使用 `--dry-run` 进行测试:
91
+ ## 示例
880
92
 
881
93
  ```bash
94
+ cd samples
882
95
  kdeploy execute deploy.rb deploy_web --dry-run
883
96
  ```
884
97
 
885
- ### 6. 正确组织文件
98
+ Nginx、Node Exporter、目录同步等任务;可用 Vagrant 本地验证。
886
99
 
887
- ```
888
- project/
889
- ├── deploy.rb # 主部署文件
890
- ├── config/ # 配置文件
891
- │ ├── nginx.conf.erb # 模板
892
- │ └── app.conf # 静态配置
893
- └── scripts/ # 辅助脚本
894
- └── deploy.sh
895
- ```
896
-
897
- ### 7. 版本控制
898
-
899
- - 提交 `deploy.rb` 和模板
900
- - 使用 `.gitignore` 处理敏感文件
901
- - 将密钥存储在环境变量中
902
-
903
- ### 8. 并行执行
904
-
905
- 根据您的基础设施调整并行数量:
906
-
907
- ```bash
908
- # 对于许多主机,增加并行数量
909
- kdeploy execute deploy.rb deploy --parallel 20
910
-
911
- # 对于有限资源,减少
912
- kdeploy execute deploy.rb deploy --parallel 3
913
- ```
914
-
915
- ## 🔍 故障排除
916
-
917
- ### 常见问题
918
-
919
- #### SSH 身份验证失败
920
-
921
- **问题**: `SSH authentication failed`
922
-
923
- **解决方案**:
924
- 1. 验证 SSH 密钥路径是否正确
925
- 2. 检查密钥权限: `chmod 600 ~/.ssh/id_rsa`
926
- 3. 手动测试 SSH 连接: `ssh user@host`
927
- 4. 验证用户名和 IP 地址
928
-
929
- #### 主机未找到
930
-
931
- **问题**: `No hosts found for task`
932
-
933
- **解决方案**:
934
- 1. 验证任务中的主机名是否与已定义的主机匹配
935
- 2. 检查角色定义
936
- 3. 如果使用了 `--limit` 选项,请验证
937
-
938
- #### 命令执行失败
939
-
940
- **问题**: 远程服务器上的命令失败
941
-
942
- **解决方案**:
943
- 1. 在目标服务器上手动测试命令
944
- 2. 检查用户权限(可能需要 sudo)
945
- 3. 验证命令语法
946
- 4. 检查服务器日志
947
-
948
- #### 模板渲染错误
949
-
950
- **问题**: 模板上传失败
951
-
952
- **解决方案**:
953
- 1. 验证模板中的 ERB 语法
954
- 2. 检查是否提供了所有必需的变量
955
- 3. 验证模板文件是否存在
956
- 4. 在本地测试模板渲染
957
-
958
- #### 连接超时
959
-
960
- **问题**: SSH 连接超时
961
-
962
- **解决方案**:
963
- 1. 检查网络连接
964
- 2. 验证防火墙规则
965
- 3. 在配置中增加超时时间
966
- 4. 检查目标服务器上的 SSH 服务
967
-
968
- ## 🏗️ 架构
969
-
970
- ### 核心组件
971
-
972
- - **CLI** (`cli.rb`): 使用 Thor 的命令行界面
973
- - **DSL** (`dsl.rb`): 用于任务定义的领域特定语言
974
- - **Executor** (`executor.rb`): SSH/SCP 执行引擎
975
- - **Runner** (`runner.rb`): 并发任务执行协调器
976
- - **CommandExecutor** (`command_executor.rb`): 单个命令执行
977
- - **Template** (`template.rb`): ERB 模板渲染
978
- - **Output** (`output.rb`): 输出格式化和显示
979
- - **Configuration** (`configuration.rb`): 配置管理
980
- - **Errors** (`errors.rb`): 自定义错误类型
981
-
982
- ### 执行流程
983
-
984
- 1. **解析配置**: 加载并解析 `deploy.rb`
985
- 2. **解析主机**: 根据任务定义确定目标主机
986
- 3. **并发执行**: 跨主机并行运行任务,按序执行每台主机上的命令
987
- 4. **收集结果**: 收集执行结果和状态
988
- 5. **显示输出**: 格式化并向用户显示结果
989
-
990
- ### 并发模型
991
-
992
- Kdeploy 使用带有固定线程池的 `concurrent-ruby`:
993
- - 默认: 10 个并发执行
994
- - 可通过 `--parallel` 选项配置
995
- - 线程安全的结果收集
996
- - 自动资源清理
997
-
998
- ## 🔧 开发
999
-
1000
- ### 设置开发环境
100
+ ## 开发
1001
101
 
1002
102
  ```bash
1003
- # 克隆仓库
1004
- git clone https://github.com/kevin197011/kdeploy.git
1005
- cd kdeploy
1006
-
1007
- # 安装依赖
103
+ git clone git@github.com:kevin197011/kdeploy.git && cd kdeploy
1008
104
  bundle install
1009
-
1010
- # 运行测试
1011
- bundle exec rspec
1012
-
1013
- # 运行控制台
1014
- bin/console
1015
- ```
1016
-
1017
- ### 项目结构
1018
-
1019
- ```
1020
- kdeploy/
1021
- ├── lib/
1022
- │ └── kdeploy/
1023
- │ ├── cli.rb # CLI 接口
1024
- │ ├── dsl.rb # DSL 定义
1025
- │ ├── executor.rb # SSH/SCP 执行器
1026
- │ ├── runner.rb # 任务运行器
1027
- │ ├── command_executor.rb # 命令执行器
1028
- │ ├── template.rb # 模板处理器
1029
- │ ├── output.rb # 输出接口
1030
- │ ├── configuration.rb # 配置
1031
- │ ├── errors.rb # 错误类型
1032
- │ └── ...
1033
- ├── spec/ # 测试
1034
- ├── exe/ # 可执行文件
1035
- ├── sample/ # 示例项目
1036
- └── README.md # 本文档
1037
- ```
1038
-
1039
- ### 运行测试
1040
-
1041
- ```bash
1042
- # 运行所有测试
1043
105
  bundle exec rspec
1044
-
1045
- # 运行特定测试文件
1046
- bundle exec rspec spec/kdeploy_spec.rb
1047
-
1048
- # 运行覆盖率
1049
- COVERAGE=true bundle exec rspec
1050
- ```
1051
-
1052
- ### 构建 Gem
1053
-
1054
- ```bash
1055
- # 构建 gem
1056
- gem build kdeploy.gemspec
1057
-
1058
- # 本地安装
1059
- gem install ./kdeploy-*.gem
1060
- ```
1061
-
1062
- ### 代码风格
1063
-
1064
- 项目使用 RuboCop 进行代码风格检查:
1065
-
1066
- ```bash
1067
- # 检查风格
1068
106
  bundle exec rubocop
1069
-
1070
- # 自动修复问题
1071
- bundle exec rubocop -a
1072
- ```
1073
-
1074
- ## 🤝 贡献
1075
-
1076
- 欢迎贡献!请遵循以下步骤:
1077
-
1078
- 1. **Fork 仓库**
1079
- 2. **创建功能分支**: `git checkout -b feature/my-new-feature`
1080
- 3. **进行更改**: 遵循代码风格并添加测试
1081
- 4. **提交更改**: 使用约定式提交消息
1082
- 5. **推送到分支**: `git push origin feature/my-new-feature`
1083
- 6. **创建 Pull Request**: 提供清晰的更改描述
1084
-
1085
- ### 贡献指南
1086
-
1087
- - 遵循现有代码风格
1088
- - 为新功能添加测试
1089
- - 更新文档
1090
- - 确保所有测试通过
1091
- - 遵循约定式提交格式
1092
-
1093
- ### 提交消息格式
1094
-
1095
- 遵循 [约定式提交](https://www.conventionalcommits.org/):
1096
-
1097
- ```
1098
- <type>(<scope>): <subject>
1099
-
1100
- <body>
1101
-
1102
- <footer>
1103
- ```
1104
-
1105
- 类型: `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore`
1106
-
1107
- ## 📚 示例
1108
-
1109
- ### 示例项目
1110
-
1111
- 本仓库的 [sample/](sample/) 目录提供完整示例,包含 Nginx、Node Exporter、目录同步等任务,支持 Vagrant 本地测试:
1112
-
1113
- ```bash
1114
- cd sample
1115
- vagrant up
1116
- kdeploy execute deploy.rb deploy_web --dry-run # 预览
1117
- kdeploy execute deploy.rb deploy_web # 执行
1118
- ```
1119
-
1120
- ### 常见部署场景
1121
-
1122
- #### Web 应用程序部署
1123
-
1124
- ```ruby
1125
- host "web01", user: "deploy", ip: "10.0.0.1", key: "~/.ssh/id_rsa"
1126
- role :web, %w[web01]
1127
-
1128
- task :deploy_app, roles: :web do
1129
- run <<~SHELL
1130
- cd /var/www/app
1131
- git pull origin main
1132
- bundle install
1133
- rake db:migrate
1134
- sudo systemctl restart puma
1135
- SHELL
1136
- end
1137
- ```
1138
-
1139
- #### 数据库备份
1140
-
1141
- ```ruby
1142
- host "db01", user: "postgres", ip: "10.0.0.10", key: "~/.ssh/id_rsa"
1143
- role :db, %w[db01]
1144
-
1145
- task :backup, roles: :db do
1146
- run <<~SHELL
1147
- pg_dump mydb > /tmp/backup_$(date +%Y%m%d).sql
1148
- gzip /tmp/backup_*.sql
1149
- aws s3 cp /tmp/backup_*.sql.gz s3://backups/
1150
- rm /tmp/backup_*.sql.gz
1151
- SHELL
1152
- end
1153
- ```
1154
-
1155
- #### 配置管理
1156
-
1157
- ```ruby
1158
- task :update_config, roles: :web do
1159
- template "/etc/app/config.yml", source: "./config/app.yml.erb",
1160
- variables: { environment: "production", database_url: ENV['DATABASE_URL'], redis_url: ENV['REDIS_URL'] }
1161
- service "app", action: :reload
1162
- end
1163
107
  ```
1164
108
 
1165
- #### 目录同步部署
1166
-
1167
- ```ruby
1168
- task :deploy_app, roles: :web do
1169
- sync "./app", "/var/www/app",
1170
- ignore: [".git", "*.log", "node_modules", ".env.local", "*.tmp"],
1171
- delete: true
1172
- sync "./config", "/etc/app", exclude: ["*.example", "*.bak"]
1173
- service "app", action: :restart
1174
- end
1175
- ```
1176
-
1177
- ## 📝 许可证
1178
-
1179
- 该 gem 在 [MIT 许可证](https://opensource.org/licenses/MIT) 条款下作为开源提供。
109
+ 需求与验收标准:[docs/REQUIREMENTS.md](docs/REQUIREMENTS.md)
1180
110
 
1181
- ## 🔗 链接
111
+ ## 贡献
1182
112
 
1183
- - **GitHub**: https://github.com/kevin197011/kdeploy
1184
- - **RubyGems**: https://rubygems.org/gems/kdeploy
1185
- - **Issues**: https://github.com/kevin197011/kdeploy/issues
1186
- - **示例**: [sample/](sample/) 目录(含 Vagrant 配置)
113
+ Fork 功能分支 → 测试通过 → PR。提交信息遵循 [Conventional Commits](https://www.conventionalcommits.org/)。
1187
114
 
1188
- ## 🙏 致谢
115
+ ## 许可证
1189
116
 
1190
- - 使用 [Thor](https://github.com/rails/thor) 构建 CLI
1191
- - 使用 [net-ssh](https://github.com/net-ssh/net-ssh) 进行 SSH 操作
1192
- - 由 [concurrent-ruby](https://github.com/ruby-concurrency/concurrent-ruby) 提供并发支持
117
+ [MIT](https://opensource.org/licenses/MIT)
1193
118
 
1194
- ---
119
+ ## 链接
1195
120
 
1196
- **为 DevOps 社区用 ❤️ 制作**
121
+ - [GitHub](https://github.com/kevin197011/kdeploy) · [RubyGems](https://rubygems.org/gems/kdeploy) · [Issues](https://github.com/kevin197011/kdeploy/issues)