github.com/smintz/nomad@v0.8.3/website/source/intro/getting-started/jobs.html.md (about) 1 --- 2 layout: "intro" 3 page_title: "Jobs" 4 sidebar_current: "getting-started-jobs" 5 description: |- 6 Learn how to submit, modify and stop jobs in Nomad. 7 --- 8 9 # Jobs 10 11 Jobs are the primary configuration that users interact with when using 12 Nomad. A job is a declarative specification of tasks that Nomad should run. 13 Jobs have a globally unique name, one or many task groups, which are themselves 14 collections of one or many tasks. 15 16 The format of the jobs is documented in the [job specification][jobspec]. They 17 can either be specified in [HashiCorp Configuration Language][hcl] or JSON, 18 however we recommend only using JSON when the configuration is generated by a machine. 19 20 ## Running a Job 21 22 To get started, we will use the [`job init` command](/docs/commands/job/init.html) which 23 generates a skeleton job file: 24 25 ```text 26 $ nomad job init 27 Example job file written to example.nomad 28 ``` 29 30 You can view the contents of this file by running `cat example.nomad`. In this 31 example job file, we have declared a single task 'redis' which is using 32 the Docker driver to run the task. The primary way you interact with Nomad 33 is with the [`job run` command](/docs/commands/job/run.html). The `run` command takes 34 a job file and registers it with Nomad. This is used both to register new 35 jobs and to update existing jobs. 36 37 We can register our example job now: 38 39 ```text 40 $ nomad job run example.nomad 41 ==> Monitoring evaluation "13ebb66d" 42 Evaluation triggered by job "example" 43 Allocation "883269bf" created: node "e42d6f19", group "cache" 44 Evaluation within deployment: "b0a84e74" 45 Evaluation status changed: "pending" -> "complete" 46 ==> Evaluation "13ebb66d" finished with status "complete" 47 ``` 48 49 Anytime a job is updated, Nomad creates an evaluation to determine what 50 actions need to take place. In this case, because this is a new job, Nomad has 51 determined that an allocation should be created and has scheduled it on our 52 local agent. 53 54 To inspect the status of our job we use the [`status` command](/docs/commands/status.html): 55 56 ```text 57 $ nomad status example 58 ID = example 59 Name = example 60 Submit Date = 10/31/17 22:58:40 UTC 61 Type = service 62 Priority = 50 63 Datacenters = dc1 64 Status = running 65 Periodic = false 66 Parameterized = false 67 68 Summary 69 Task Group Queued Starting Running Failed Complete Lost 70 cache 0 0 1 0 0 0 71 72 Latest Deployment 73 ID = b0a84e74 74 Status = successful 75 Description = Deployment completed successfully 76 77 Deployed 78 Task Group Desired Placed Healthy Unhealthy 79 cache 1 1 1 0 80 81 Allocations 82 ID Node ID Task Group Version Desired Status Created Modified 83 8ba85cef 171a583b cache 0 run running 5m ago 5m ago 84 ``` 85 86 Here we can see that the result of our evaluation was the creation of an 87 allocation that is now running on the local node. 88 89 An allocation represents an instance of Task Group placed on a node. To inspect 90 an allocation we use the [`alloc status` command](/docs/commands/alloc/status.html): 91 92 ```text 93 $ nomad alloc status 883269bf 94 ID = 883269bf 95 Eval ID = 13ebb66d 96 Name = example.cache[0] 97 Node ID = e42d6f19 98 Job ID = example 99 Job Version = 0 100 Client Status = running 101 Client Description = <none> 102 Desired Status = run 103 Desired Description = <none> 104 Created = 5m ago 105 Modified = 5m ago 106 Deployment ID = fa882a5b 107 Deployment Health = healthy 108 109 Task "redis" is "running" 110 Task Resources 111 CPU Memory Disk IOPS Addresses 112 8/500 MHz 6.3 MiB/256 MiB 300 MiB 0 db: 127.0.0.1:22672 113 114 Task Events: 115 Started At = 10/31/17 22:58:49 UTC 116 Finished At = N/A 117 Total Restarts = 0 118 Last Restart = N/A 119 120 Recent Events: 121 Time Type Description 122 10/31/17 22:58:49 UTC Started Task started by client 123 10/31/17 22:58:40 UTC Driver Downloading image redis:3.2 124 10/31/17 22:58:40 UTC Task Setup Building Task Directory 125 10/31/17 22:58:40 UTC Received Task received by client 126 ``` 127 128 We can see that Nomad reports the state of the allocation as well as its 129 current resource usage. By supplying the `-stats` flag, more detailed resource 130 usage statistics will be reported. 131 132 To see the logs of a task, we can use the [logs command](/docs/commands/alloc/logs.html): 133 134 ```text 135 $ nomad alloc logs 883269bf redis 136 _._ 137 _.-``__ ''-._ 138 _.-`` `. `_. ''-._ Redis 3.2.1 (00000000/0) 64 bit 139 .-`` .-```. ```\/ _.,_ ''-._ 140 ( ' , .-` | `, ) Running in standalone mode 141 |`-._`-...-` __...-.``-._|'` _.-'| Port: 6379 142 | `-._ `._ / _.-' | PID: 1 143 `-._ `-._ `-./ _.-' _.-' 144 |`-._`-._ `-.__.-' _.-'_.-'| 145 | `-._`-._ _.-'_.-' | http://redis.io 146 `-._ `-._`-.__.-'_.-' _.-' 147 |`-._`-._ `-.__.-' _.-'_.-'| 148 | `-._`-._ _.-'_.-' | 149 `-._ `-._`-.__.-'_.-' _.-' 150 `-._ `-.__.-' _.-' 151 `-._ _.-' 152 `-.__.-' 153 ... 154 ``` 155 156 ## Modifying a Job 157 158 The definition of a job is not static, and is meant to be updated over time. 159 You may update a job to change the docker container, to update the application version, 160 or to change the count of a task group to scale with load. 161 162 For now, edit the `example.nomad` file to update the count and set it to 3: 163 164 ``` 165 # The "count" parameter specifies the number of the task groups that should 166 # be running under this group. This value must be non-negative and defaults 167 # to 1. 168 count = 3 169 ``` 170 171 Once you have finished modifying the job specification, use the [`job plan` 172 command](/docs/commands/job/plan.html) to invoke a dry-run of the scheduler to see 173 what would happen if you ran the updated job: 174 175 ```text 176 $ nomad job plan example.nomad 177 +/- Job: "example" 178 +/- Task Group: "cache" (2 create, 1 in-place update) 179 +/- Count: "1" => "3" (forces create) 180 Task: "redis" 181 182 Scheduler dry-run: 183 - All tasks successfully allocated. 184 185 Job Modify Index: 7 186 To submit the job with version verification run: 187 188 nomad job run -check-index 7 example.nomad 189 190 When running the job with the check-index flag, the job will only be run if the 191 server side version matches the job modify index returned. If the index has 192 changed, another user has modified the job and the plan's results are 193 potentially invalid. 194 ``` 195 196 We can see that the scheduler detected the change in count and informs us that 197 it will cause 2 new instances to be created. The in-place update that will 198 occur is to push the updated job specification to the existing allocation and 199 will not cause any service interruption. We can then run the job with the run 200 command the `plan` emitted. 201 202 By running with the `-check-index` flag, Nomad checks that the job has not 203 been modified since the plan was run. This is useful if multiple people are 204 interacting with the job at the same time to ensure the job hasn't changed 205 before you apply your modifications. 206 207 ``` 208 $ nomad job run -check-index 7 example.nomad 209 ==> Monitoring evaluation "93d16471" 210 Evaluation triggered by job "example" 211 Evaluation within deployment: "0d06e1b6" 212 Allocation "3249e320" created: node "e42d6f19", group "cache" 213 Allocation "453b210f" created: node "e42d6f19", group "cache" 214 Allocation "883269bf" modified: node "e42d6f19", group "cache" 215 Evaluation status changed: "pending" -> "complete" 216 ==> Evaluation "93d16471" finished with status "complete" 217 ``` 218 219 Because we set the count of the task group to three, Nomad created two 220 additional allocations to get to the desired state. It is idempotent to 221 run the same job specification again and no new allocations will be created. 222 223 Now, let's try to do an application update. In this case, we will simply change 224 the version of redis we want to run. Edit the `example.nomad` file and change 225 the Docker image from "redis:3.2" to "redis:4.0": 226 227 ``` 228 # Configure Docker driver with the image 229 config { 230 image = "redis:4.0" 231 } 232 ``` 233 234 We can run `plan` again to see what will happen if we submit this change: 235 236 ```text 237 +/- Job: "example" 238 +/- Task Group: "cache" (1 create/destroy update, 2 ignore) 239 +/- Task: "redis" (forces create/destroy update) 240 +/- Config { 241 +/- image: "redis:3.2" => "redis:4.0" 242 port_map[0][db]: "6379" 243 } 244 245 Scheduler dry-run: 246 - All tasks successfully allocated. 247 248 Job Modify Index: 1127 249 To submit the job with version verification run: 250 251 nomad job run -check-index 1127 example.nomad 252 253 When running the job with the check-index flag, the job will only be run if the 254 server side version matches the job modify index returned. If the index has 255 changed, another user has modified the job and the plan's results are 256 potentially invalid. 257 ``` 258 259 The plan output shows us that one allocation will be updated and that the other 260 two will be ignored. This is due to the `max_parallel` setting in the `update` 261 stanza, which is set to 1 to instruct Nomad to perform only a single change at 262 a time. 263 264 Once ready, use `run` to push the updated specification: 265 266 ```text 267 $ nomad job run example.nomad 268 ==> Monitoring evaluation "293b313a" 269 Evaluation triggered by job "example" 270 Evaluation within deployment: "f4047b3a" 271 Allocation "27bd4a41" created: node "e42d6f19", group "cache" 272 Evaluation status changed: "pending" -> "complete" 273 ==> Evaluation "293b313a" finished with status "complete" 274 ``` 275 276 After running, the rolling upgrade can be followed by running `nomad status` and 277 watching the deployed count. 278 279 We can see that Nomad handled the update in three phases, only updating a single 280 allocation in each phase and waiting for it to be healthy for `min_healthy_time` 281 of 10 seconds before moving on to the next. The update strategy can be 282 configured, but rolling updates makes it easy to upgrade an application at large 283 scale. 284 285 ## Stopping a Job 286 287 So far we've created, run and modified a job. The final step in a job lifecycle 288 is stopping the job. This is done with the [`job stop` command](/docs/commands/job/stop.html): 289 290 ```text 291 $ nomad job stop example 292 ==> Monitoring evaluation "6d4cd6ca" 293 Evaluation triggered by job "example" 294 Evaluation within deployment: "f4047b3a" 295 Evaluation status changed: "pending" -> "complete" 296 ==> Evaluation "6d4cd6ca" finished with status "complete" 297 ``` 298 299 When we stop a job, it creates an evaluation which is used to stop all 300 the existing allocations. If we now query the job status, we can see it is 301 now marked as `dead (stopped)`, indicating that the job has been stopped and 302 Nomad is no longer running it: 303 304 ```text 305 $ nomad status example 306 ID = example 307 Name = example 308 Submit Date = 11/01/17 17:30:40 UTC 309 Type = service 310 Priority = 50 311 Datacenters = dc1 312 Status = dead (stopped) 313 Periodic = false 314 Parameterized = false 315 316 Summary 317 Task Group Queued Starting Running Failed Complete Lost 318 cache 0 0 0 0 6 0 319 320 Latest Deployment 321 ID = f4047b3a 322 Status = successful 323 Description = Deployment completed successfully 324 325 Deployed 326 Task Group Desired Placed Healthy Unhealthy 327 cache 3 3 3 0 328 329 Allocations 330 ID Node ID Task Group Version Desired Status Created Modified 331 8ace140d 2cfe061e cache 2 stop complete 5m ago 5m ago 332 8af5330a 2cfe061e cache 2 stop complete 6m ago 6m ago 333 df50c3ae 2cfe061e cache 2 stop complete 6m ago 6m ago 334 ``` 335 336 If we wanted to start the job again, we could simply `run` it again. 337 338 ## Next Steps 339 340 Users of Nomad primarily interact with jobs, and we've now seen 341 how to create and scale our job, perform an application update, 342 and do a job tear down. Next we will add another Nomad 343 client to [create our first cluster](cluster.html) 344 345 [jobspec]: /docs/job-specification/index.html "Nomad Job Specification" 346 [hcl]: https://github.com/hashicorp/hcl "HashiCorp Configuration Language"