Nomad 系列-快速上手
系列文章
Nomad 重要术语

Nomad 安装设置相关术语
agent- 代理。Agent 是在 Server(服务器) 或 Client(客户端) 模式下运行的 Nomad 进程。client- 客户端。Nomad 客户端负责运行分配给它的任务。它还向服务器注册自己,并监视要分配的任何工作。当运行代理时,客户端可以被称为节点 (Node)。server- 服务器端。Nomad 服务器管理所有作业和客户端,监视任务,并控制哪些任务被放置在哪些客户端节点上。服务器之间相互复制数据以确保高可用性。dev_agent- 开发(模式)代理是一种代理配置,它为运行 Nomad 的单节点集群提供了有用的默认值。它在服务器和客户端模式下运行,并且不会将其群集状态持久化到磁盘,这允许代理从可重复的干净状态启动,而不必在运行之间删除基于磁盘的状态。
Nomad 集群通常由三到五个服务器代理和许多客户端代理组成。
Nomad 使用的相关术语
在 Nomad 调度和运行工作负载的过程中,您将遇到以下术语。
task- 任务是 Nomad 中最小的工作单元(类似 K8s 中的 Pod)。任务由task drivers执行,drivers 包括 docker 和 exec 等,这使得 Nomad 可以灵活地支持任务类型。任务指定其所需的任务驱动程序、驱动程序的配置、约束 (constraints) 和所需的资源。group- 组是在同一 Nomad 客户端上运行的一系列任务。(我个人认为类似于 K8s 中的 Deployment/Statefulset/Daemonset/Job)job- 作业是 Nomad 的核心控制单元,它定义了应用程序及其配置。它可以包含一个或多个任务。(我个人认为 job 类似于 K8s 中的多个资源 yaml manifest 集合。包括:SVC/Ingress/ConfigMap/Deploy/PVC...)job specification- 作业规范,也称为 jobspec,定义了 Nomad 作业的模式。它描述了作业的类型、作业运行所需的任务和资源、作业信息(如作业可以在哪些客户端上运行)等。allocation- 分配是作业中的任务组与客户端节点之间的映射。当运行作业时,Nomad 将选择能够运行它的客户端,并在机器上为作业中定义的任务组中的任务分配资源。(我认为类似于 K8s 中已经在运行的 pod.)
应用程序在 jobspec 中定义为具有 jobspec 的任务组 (groups of tasks),并且一旦提交给 Nomad,就会创建一个作业 (job) 沿着该 jobspec 中定义的每个组的分配 (allocation)。
Nomad 上的应用工作流
典型的应用程序工作流程涉及几个步骤,并从 Nomad 外部开始。
在 Nomad 上运行的任何应用程序的先决条件是具有工作负载工件。Nomad 支持各种工件,包括 Docker 镜像、原始二进制文件 raw binaries、Java 应用程序 和使用 QEMU 的虚拟机映像。
Nomad 不会创建这些应用程序工件,但可以使用 CircleCI,GitHub Actions 或本地构建等 CI 工具来创建工件,然后将其推送到存储库,Nomad 可以在调度作业时从中检索它们。
创建应用程序后,工作流将继续使用 Nomad。

- 创建 job spec - 作业规范包含应用程序所需的任务,包括工件驻留的位置、网络配置(如端口和服务定义)、所需实例数量等等。
- 部署 job - 作业规范将提交给 Nomad,并根据作业配置在一个或多个客户端上为作业安排分配。
- 更新和重新部署 job - 更新应用程序代码或作业规范,然后重新提交给 Nomad 进行调度。
快速入门
接下来我们快速上手 Nomad, 主要展示如何部署示例应用程序。
前提
- Docker 已安装
- Nomad 二进制(包括 CLI) 已安装
- (可选)CNI 插件已安装
- Nomad 集群已创建并运行(至少包括 1 个 Server 和 1 个 Client)
部署示例应用程序 Job
这里我们直接使用 git clone Nomad 官方提供的 Demo:
git clone https://github.com/hashicorp-education/learn-nomad-getting-started.git
cd learn-nomad-getting-started
git checkout -b nomad-getting-started v1.1
示例应用程序在 Docker 容器中运行,由一个数据库和一个从数据库读取数据的 Web 前端组成。您将使用 参数化批处理作业 parameterized batch job 设置数据库,然后使用 定期批处理作业 periodic batch job 启动其他将数据写入数据库的短期作业。
Job 类型
Service(服务) 作业用于长期运行的服务(类似于 K8s 中的 Deployment),这些服务一直运行到显式停止。
Batch 作业是指在成功退出之前一直运行的短期作业(类似于 K8s 中的 Job 和 CronJob)。
- 参数化 (parameterized) 块允许您配置批处理作业以接受必需或可选的输入。您可以使用
nomad job dispatch命令触发作业。 - 周期性 (periodic) 块允许您安排 Nomad 作业在设置的时间运行。这些也被称为 Nomad cron jobs(类似于 K8s 中的
CronJob)。
示例应用程序 Pytechco 概述
示例应用程序 pytechco 模拟在一家技术公司工作的员工。他们联机,完成任务,然后注销。
跳转到本地计算机上示例 repo 的 jobs 目录:
cd jobs
下面每个组成应用程序的 jobspec 文件都将 driver 属性设置为 docker ,并使用 image 属性指定存储在 GHCR 中 config 块中的镜像。而 Redis 作业使用了 Docker Hub 上托管的官方 Redis 镜像。
Redis 服务
jobs/pytechco-redis.nomad.hcl 内容如下:
task "redis-task" {
driver = "docker"
config {
image = "redis:7.0.7-alpine"
}
}
pytechco-redis.nomad.hcl -此服务作业运行并将 Redis 数据库暴露为 Nomad 服务,以供其他应用程序组件连接。jobspec 将类型设置为 service ,配置 Nomad service 块(类似于 K8s 中的 Service) 以使用 Nomad 原生服务发现 (Nomad native service discovery),并创建名为 redis-svc 的服务。具体如下:
job "pytechco-redis" {
type = "service"
group "ptc-redis" {
count = 1
network {
port "redis" {
to = 6379
}
}
service {
name = "redis-svc"
port = "redis"
provider = "nomad"
}
task "redis-task" {
driver = "docker"
config {
image = "redis:7.0.7-alpine"
ports = ["redis"]
}
}
}
}
以上代码说明如下:
type = "service":servicetype 的 job, 类似于 K8s 中的 Deploymentgroup "ptc-redis": group 块ptc-rediscount = 1: 副本数为 1to = 6379: 位于network块中,指示连接到 (to) 容器中的 6379 端口 (host 或 bridge 端口随机分派)service {: service 块,类似于 K8s 中的Serviceprovider = "nomad": Nomad 从 1.3 版本及以后,新增 Nomad native service. 注意:如果不指定,默认使用 consul service.(前提是需要安装 consul)task "redis-task" {: task 块,类似于 K8s 中的 Pod.driver = "docker": Nomad 不同于 K8s. K8s 默认只支持一种运行时,即容器运行时;Nomad 默认就支持多种运行时 (nomad 的术语是driver), 典型如:docker, java, raw binarier, QEMU 等,这里指定使用 docker driver.config {: 这里是特定于 docker 的driver的配置,包括:image和portsimage = "redis:7.0.7-alpine": Docker Hub 的redis:7.0.7-alpine"镜像ports = ["redis"]: 对外暴露的端口列表,这里是redis, 即在network中定义的to = 6379
Web 服务
pytechco-web.nomad.hcl -此服务作业运行 Web 应用程序前端,显示存储在数据库中的值和活动员工。jobspec 将类型设置为 service ,并为应用程序使用静态端口 5000 。它还使用 nomadService 内置函数来获取 Redis 数据库服务的地址和端口信息。
job "pytechco-web" {
type = "service"
group "ptc-web" {
count = 1
network {
port "web" {
static = 5000
}
}
service {
name = "ptc-web-svc"
port = "web"
provider = "nomad"
}
task "ptc-web-task" {
template {
data = <<EOH
{{ range nomadService "redis-svc" }}
REDIS_HOST={{ .Address }}
REDIS_PORT={{ .Port }}
FLASK_HOST=0.0.0.0
REFRESH_INTERVAL=500
{{ end }}
EOH
destination = "local/env.txt"
env = true
}
driver = "docker"
config {
image = "ghcr.io/hashicorp-education/learn-nomad-getting-started/ptc-web:1.0"
ports = ["web"]
}
}
}
}
详细说明如下(大部分和 redis 类似,这里不重复介绍了):
static = 5000: 位于network块中,指定静态端口为 5000. 与to不一样在于,to指定内部端口,外部端口随机分派;static内外部端口都相同,这里是5000端口。template {: template 块。作用类似于 K8s 中的 ConfigMap.data = <<EOH: 具体配置内容,这里是引用nomadService内置函数来获取 Redis 数据库服务的地址和端口信息。配置内容为EOH包裹的内容。REDIS_HOST={{ .Address }}: 即运行后的分派 (alloc) 的外部(通常是 host) 地址REDIS_PORT={{ .Port }}: 即运行后分派的外部端口(不是 6379), 是一个 20000-30000 之间的随机端口。
destination = "local/env.txt: 配置文件在分派后的位置。env = true: 同时也将REDIS_HOSTREDIS_PORT等设置为分配 (alloc) 容器中的环境变量。
Setup Parameterized Batch
pytechco-setup.nomad.hcl -此参数化批处理作业 (parameterized batch job) 使用默认值设置数据库。您可以多次调度它来重置数据库。jobspec 将类型设置为 batch ,并有一个带有 meta_required 属性的 parameterized 块,在分派时需要 budget 的值。
job "pytechco-setup" {
type = "batch"
parameterized {
meta_required = ["budget"]
}
group "ptc-setup" {
count = 1
task "ptc-setup-task" {
template {
data = <<EOH
{{ range nomadService "redis-svc" }}
REDIS_HOST={{ .Address }}
REDIS_PORT={{ .Port }}
{{ end }}
PTC_BUDGET={{ env "NOMAD_META_budget" }}
EOH
destination = "local/env.txt"
env = true
}
driver = "docker"
config {
image = "ghcr.io/hashicorp-education/learn-nomad-getting-started/ptc-setup:1.0"
}
}
}
}
具体说明如下:
type = "batch"Job 类型为batch, 类似于 K8s 中的Job或CronJobparameterized {: 该 Job 有一个带有meta_required属性的parameterized块,在分派时需要budget的值PTC_BUDGET={{ env "NOMAD_META_budget }}获取环境变量NOMAD_META_budget的值并赋给PTC_BUDGET
Employee Periodic Batch
pytechco-employee.nomad.hcl -此定期批处理作业使员工联机。它随机化了员工的工作类型和其他变量,如他们工作的时间和他们完成任务的速度。jobspec 将类型设置为 batch ,并有一个 periodic 块将 cron 属性设置为允许它每 3 秒启动一个新作业的值。
job "pytechco-employee" {
type = "batch"
periodic {
cron = "0/3 * * * * * *"
prohibit_overlap = false
}
group "ptc-employee" {
count = 1
task "ptc-employee-task" {
restart {
attempts = 2
delay = "15s"
interval = "10s"
mode = "fail"
}
template {
data = <<EOH
{{ range nomadService "redis-svc" }}
REDIS_HOST={{ .Address }}
REDIS_PORT={{ .Port }}
PTC_EMPLOYEE_ID={{ env "NOMAD_SHORT_ALLOC_ID"}}
{{ end }}
EOH
destination = "local/env.txt"
env = true
}
driver = "docker"
config {
image = "ghcr.io/hashicorp-education/learn-nomad-getting-started/ptc-employee:1.0"
// args = [
// "--employee-type", "sales_engineer"
// ]
}
}
}
}
具体说明如下:
periodic {:type = "batch"再加上periodic, 就类似于 K8s 中的CronJobrestart {: Batch 执行过程中的异常重启机制配置。PTC_EMPLOYEE_ID={{ env "NOMAD_SHORT_ALLOC_ID"}}: 将环境变量NOMAD_SHORT_ALLOC_ID(该环境变量由 Nomad 生成,类似于 K8s 的 pod name) 赋值给PTC_EMPLOYEE_ID// args = [://HCL 中的注释,此行不起作用。args是dockerdriverconfig中的args配置。
从 Nomad 1.5.0 开始, datacenter 属性默认为集群中所有可用的数据中心( "*" )。因此,本教程的作业规范将省略该属性,因为默认值已足够。如果您运行的是较早版本的 Nomad CLI 和集群二进制文件,则需要包含并设置该属性。
部署应用程序
具体命令如下:
提交数据库 Job:
$ nomad job run pytechco-redis.nomad.hcl
==> 2023-03-10T12:16:09-05:00: Monitoring evaluation "d44af37b"
2023-03-10T12:16:09-05:00: Evaluation triggered by job "pytechco-redis"
2023-03-10T12:16:10-05:00: Evaluation within deployment: "0ea05651"
2023-03-10T12:16:10-05:00: Allocation "be0bda79" created: node "2c9f4b7e", group "ptc-redis"
2023-03-10T12:16:10-05:00: Evaluation status changed: "pending" -> "complete"
==> 2023-03-10T12:16:10-05:00: Evaluation "d44af37b" finished with status "complete"
==> 2023-03-10T12:16:10-05:00: Monitoring deployment "0ea05651"
✓ Deployment "0ea05651" successful
2023-03-10T12:16:24-05:00
ID = 0ea05651
Job ID = pytechco-redis
Job Version = 0
Status = successful
Description = Deployment completed successfully
Deployed
Task Group Desired Placed Healthy Unhealthy Progress Deadline
ptc-redis 1 1 1 0 2023-03-10T17:26:23Z
提交 web Job:
nomad job run pytechco-web.nomad.hcl
获取 webapp 的 IP 地址。以下命令获取 Web 作业的分配 ID,并使用该 ID 获取分配的状态。然后,它在分配状态输出中搜索 IP 地址,并将 IP 地址格式化为与 webapp 端口的链接。在浏览器中打开输出中的 URL 以查看 webapp 前端。
nomad node status -verbose \
$(nomad job allocs pytechco-web | grep -i running | awk '{print $2}') | \
grep -i ip-address | awk -F "=" '{print $2}' | xargs | \
awk '{print "http://"$1":5000"}'
提交 Setup Job:
nomad job run pytechco-setup.nomad.hcl
通过提供 budget 值分派该 setup job:
$ nomad job dispatch -meta budget="200" pytechco-setup
Dispatched Job ID = pytechco-setup/dispatch-1678468734-396cfa83
Evaluation ID = 53a77034
==> 2023-03-10T12:18:54-05:00: Monitoring evaluation "53a77034"
2023-03-10T12:18:54-05:00: Evaluation triggered by job "pytechco-setup/dispatch-1678468734-396cfa83"
2023-03-10T12:18:54-05:00: Allocation "d6c60ffd" created: node "2c9f4b7e", group "ptc-setup"
2023-03-10T12:18:54-05:00: Evaluation status changed: "pending" -> "complete"
==> 2023-03-10T12:18:54-05:00: Evaluation "53a77034" finished with status "complete"
提交 Employee Job:
nomad job run pytechco-employee.nomad.hcl
跳转到 Nomad UI,单击 "Jobs" 页面,然后单击 pytechco-employee job。由于这是一个 cron batch job,您可以看到它每 3 秒创建一个新作业。

跳转回 webapp URL。效果如下:

更新应用程序
首先,停止 employee job:
nomad job stop -purge pytechco-employee
通过使用新 budget 500 再次分派 setup job 来重置数据库:
$ nomad job dispatch -meta budget="500" pytechco-setup
Dispatched Job ID = pytechco-setup/dispatch-1678469008-6ffe1c0c
Evaluation ID = e8e420f0
==> 2023-03-10T12:23:28-05:00: Monitoring evaluation "e8e420f0"
2023-03-10T12:23:28-05:00: Evaluation triggered by job "pytechco-setup/dispatch-1678469008-6ffe1c0c"
2023-03-10T12:23:28-05:00: Allocation "74acf63e" created: node "2c9f4b7e", group "ptc-setup"
2023-03-10T12:23:28-05:00: Evaluation status changed: "pending" -> "complete"
==> 2023-03-10T12:23:28-05:00: Evaluation "e8e420f0" finished with status "complete"
打开 pytechco-employee.nomad.hcl 文件并取消注释任务配置的 args 块,使作业仅创建类型为 sales_engineer 的员工。然后将cron更新为 0/1 * * * * * * ,使作业每秒运行一次。保存文件。
...
cron = "0/1 * * * * * *"
...
args = [
"--employee-type", "sales_engineer"
]
...
再次提交 employee job 并跳转到 Web 应用程序。请注意,所有在线员工现在都只是销售工程师 (sales_enginee)(之前是有多个不同的员工类型),而且他们中的更多人在任何给定时间都在线。
$ nomad job run pytechco-employee.nomad.hcl
Job registration successful
Approximate next launch time: 2023-03-10T17:24:18Z (1s from now)
清理应用程序
停止并清理所有 Jobs:
nomad job stop -purge pytechco-employee
nomad job stop -purge pytechco-web
nomad job stop -purge pytechco-redis
nomad job stop -purge pytechco-setup
总结
本文中,我们一起了解了 Nomad 的术语,并根据官方 Demo, 部署和更新了 Nomad Job。同时穿插了解了 Nomad 和 K8s 的一些类比和对比。
后面就正式进入具体实战环节,包括:Nomad 与 Traefik 和 Tailscale 的集成等独家内容。敬请期待。
️参考文档
三人行, 必有我师; 知识共享, 天下为公. 本文由东风微鸣技术博客 EWhisper.cn 编写.
Nomad 系列-快速上手的更多相关文章
- [Android开发学iOS系列] 快速上手UIKit
快速上手iOS UIKit UIKit是苹果官方的framework, 其中包含了各种UI组件, window和view, 事件处理, 交互, 动画, 资源管理等基础设施支持. 按照前面的介绍, 用U ...
- NeoLoad系列- 快速上手教程
1.新建工程 2.点击录制脚本按钮 3.在弹出的开始录制对话框中,填写虚拟用户信息. Record in下拉框,用来填写用户路径,一般有三个容器组成: Init, Actions, and End.当 ...
- 快速上手系列-C语言之指针篇(一)
快速上手系列-C语言之指针篇(一) 浊酒敬风尘 发布时间:18-06-2108:29 指针的灵活运用使得c语言更加强大,指针是C语言中十分重要的部分,可以说指针是C语言的灵魂.当然指针不是万能的,但没 ...
- ESFramework 4.0 快速上手(06) -- Rapid引擎(续)
<ESFramework 4.0 快速上手>系列介绍的都是如何使用Rapid引擎(快速引擎) -- RapidServerEngine 和 RapidPassiveEngine.其实,大家 ...
- ESFramework 4.0 快速上手(01) -- Rapid引擎
(在阅读该文之前,请先阅读 ESFramework 4.0 概述 ,会对本文的理解更有帮助.) ESFramework/ESPlatform 4.0 的终极目标是为百万级的用户同时在线提供支持,因为强 ...
- EF Core 快速上手——创建应用的DbContext
系列文章 EF Core 快速上手--EF Core 入门 EF Core 快速上手--EF Core的三种主要关系类型 本节导航 定义应用的DbContext 创建DbContext的一个实例 创建 ...
- EF Core 快速上手——EF Core的三种主要关系类型
系列文章 EF Core 快速上手--EF Core 入门 本节导航 三种数据库关系类型建模 Migration方式创建和习修改数据库 定义和创建应用DbContext 将复杂查询拆分为子查询 本 ...
- 从零开始学 Web 之 Ajax(三)Ajax 概述,快速上手
大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:ht ...
- Mac快速上手指南
上周刚入手了2017版MacBookPro,预装macOS High Sierra.第一次接触Mac系统,经过一周的使用,简单总结下与Windows相比最常用的功能,快速上手. 1.Mac键盘实现Ho ...
- [Full-stack] 快速上手开发 - React
故事背景 [1] 博客笔记结合<React快速上手开发>再次系统地.全面地走一遍. [2] React JS Tutorials:包含了JS --> React --> Red ...
随机推荐
- nginx发布vue 项目
在本次使用nginx发布vue项目遇到 配置location 始终404 和 在项目子目录点击浏览器刷新出现404问题 使用nginx发布vue项目,为了方便测试就下载了一个nginx 放置自己目录下 ...
- web自动化08-下拉选择框、弹出框、滚动条
1.下拉选择框操作 下拉框就是HTML中<select>元素: 先列需求: 需求:使用'注册A.html'页面,完成对城市的下拉框的操作 1).选择'广州' 2).暂停2秒,选择'上海 ...
- 前端自动识别CAD图纸提取信息方法总结
前言 CAD图纸自动识别和提取信息具有许多意义,包括以下几个方面: 提高工作效率:传统上,对于大量的CAD图纸,人工识别和提取信息是一项耗时且繁琐的任务.通过自动化这一过程,可以大大提高工作效率,节省 ...
- 让ChatGPT来写今年的高考作文,能得几分?
使用最新的ChatGPT4模型,做2023年全国甲卷的高考作文. 作文考试题目如下 人们因技术发展得以更好地掌控时间,但也有人因此成了时间的仆人.这句话引发了你怎样的联想与思考?请写一篇文章. 要求: ...
- go语言编写算法
1.冒泡排序 // 冒泡排序 a := []uint8{9, 20, 10, 23, 7, 22, 88, 102} for i := 0; i < len(a); i++ { for k := ...
- 花了一周时间,总算把mysql的加锁搞清楚了,再也不怕间隙锁和next-key了
接触mysql都知道在mysql中有很多锁,共享锁(S).排他锁(X).间隙锁(gap).next-key,当然还有意向锁.表锁等.今天不讲别的,专门来看下innodb引擎下的锁是什么样子的. 现在有 ...
- 自然语言处理 Paddle NLP - 信息抽取技术及应用
1.什么是信息抽取 即自动从无结构或半结构的文本中抽取出结构化信息的任务(病历抽取) 2.实体抽取 3.关系抽取 4.事件抽取 信息抽取和知识图谱是一个上下游的关系.抽取的结果,可以组装成知识图谱(一 ...
- 一致性hash算法原理及实践
大家好,我是蓝胖子,想起之前学算法的时候,常常只知表面,不得精髓,这个算法到底有哪些应用场景,如何应用在工作中,后来随着工作的深入,一些不懂的问题才慢慢被抽丝剥茧分解出来. 今天我们就来看看工作和面试 ...
- Linux下Redis集群部署
一.Redis集群介绍 Redis 集群是一个提供在多个Redis节点间共享数据的程序集.Redis集群并不支持处理多个keys的命令,因为这需要在不同的节点间移动数据,从而达不到像Redis那样的性 ...
- 本地python调试 问题笔记
ImportError: cannot import name 'int_classes' from 'torch._six' 把 "from torch._six import stri ...