kdeploy 1.3.1 → 1.3.4

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