Skip to content

Commit

Permalink
Add documentation for ephemeral-storage apis and bootstrap-commands
Browse files Browse the repository at this point in the history
  • Loading branch information
piyush-jena committed Oct 11, 2024
1 parent af7705e commit 92e2922
Show file tree
Hide file tree
Showing 6 changed files with 1,120 additions and 1 deletion.
2 changes: 1 addition & 1 deletion content/en/os/1.22.x/api/endpoints/index.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ The following output is generated from [Bottlerocket's OpenAPI Spec](https://git

---

{{< swaggerui src="../../../../external/openapi/1.15.x/openapi.yaml" >}}
{{< swaggerui src="../../../../external/openapi/1.22.x/openapi.yaml" >}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
+++
title="bootstrap-commands"
type="docs"
toc_hide=true
description="Settings related to bootstrap commands (`settings.bootstrap-commands.*`)"
+++

{{< settings >}}
129 changes: 129 additions & 0 deletions content/en/os/1.22.x/concepts/bootstrap-commands/_index.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
+++
title = "Bootstrap Commands"
type = "docs"
description = "Configure the host with Bottlerocket API commands during boot."
+++

Bootstrap commands are a way to configure and modify a Bottlerocket instance using the Bottlerocket API at boot time. They run prior to the {{< ver-ref project="os" page="/concepts/bootstrap-containers/" >}}Bootstrap Containers{{</ ver-ref >}}.

## Lifecycle

When you define a bootstrap command using user-data or the Bottlerocket API, the following sequence occurs on next boot:

- [`systemd`](https://systemd.io/) runs all the bootstrap commands in lexicographical order of their names. Each Bottlerocket API command inside a bootstrap-command runs serially in the declared order.
- `systemd` will not move to the next [target](https://www.freedesktop.org/software/systemd/man/systemd.target.html) until all of the bootstrap commands start, run and exit.
- any bootstrap command configured with `mode=once` will change to `mode=off` once complete.
- any bootstrap command set to `essential=true` that exits with a non-zero exit code halts the boot process.

### Examples

{{< twocol
containerclass="td-max-width-on-larger-screens docs-figure"
rowclass="docs-figure" >}}
{{< twocol_inner colsplit="7" >}}
{{< bootstrap_commands_diagram example=1 >}}
{{</ twocol_inner >}}
{{% twocol_inner %}}
This example shows four bootstrap commands whose names begin with `001-cmd`,`002-cmd`,`003-cmd`, and `004-cmd`.
The start order of these commands is in lexicographical order of their names.
The boot does not proceed to the next stage until the last bootstrap command completes.
{{%/ twocol_inner %}}
{{</ twocol >}}

{{< twocol
containerclass="td-max-width-on-larger-screens docs-figure"
rowclass="docs-figure" >}}
{{< twocol_inner colsplit="7" >}}
{{< bootstrap_commands_diagram example=2 >}}
{{</ twocol_inner >}}
{{% twocol_inner %}}
This example is the same as the previous one except the bootstrap command `003-cmd` is configured with {{< ver-ref project="os" page="/api/settings/bootstrap-commands#name_essential">}}`essential=true`{{< /ver-ref >}}.
Bootstrap command `003-cmd` exits with a non-zero exit code and consequently the boot halts. As a result, `004-cmd` isn't run at all.
{{%/ twocol_inner %}}
{{</ twocol >}}

{{< twocol
containerclass="td-max-width-on-larger-screens docs-figure"
rowclass="docs-figure" >}}
{{< twocol_inner colsplit="7" >}}
{{< bootstrap_commands_diagram example=3 >}}
{{</ twocol_inner >}}
{{% twocol_inner %}}
This example is the same as the first except bootstrap command `004-cmd` is configured with {{< ver-ref project="os" page="/api/settings/bootstrap-commands#name_mode">}}`mode=once`{{< /ver-ref >}}.
After `004-cmd` finishes, the bootstrap command `004-cmd` is turned off by settings its `mode` to `off`, and will no longer be executed in future boot sequences.
{{%/ twocol_inner %}}
{{</ twocol >}}

### Considerations

As a consequence of this lifecycle, you should keep a few things in mind when using bootstrap commands:

1. Bootstrap commands **can only** run `apiclient` commands.
2. Bootstrap commands can’t run `apiclient exec` commands because host containers aren’t ready at this stage of the boot.
3. Running `apiclient reboot` in a bootstrap command with `mode=always` will cause the node to reboot endlessly.
4. `apiclient reboot` in a bootstrap command with `mode=once` will hold off the reboot until the completion of all bootstrap commands.
5. Due to serial nature of bootstrap commands, they should be short-running to reduce overhead on boot times.

## Use cases

The following are a few examples use cases for bootstrap commands

### Configure ephemeral disks

**In a Kubernetes host**

```
[settings.bootstrap-commands.k8s-ephemeral-storage]
commands = [
["apiclient", "ephemeral-storage", "init"],
["apiclient", "ephemeral-storage" ,"bind", "--dirs", "/var/lib/containerd", "/var/lib/kubelet", "/var/log/pods"]
]
essential = true
mode = "always"
```

**In an ECS host**

```
[settings.bootstrap-commands.ecs-ephemeral-storage]
commands = [
["apiclient", "ephemeral-storage", "init"],
["apiclient", "ephemeral-storage" ,"bind", "--dirs", "/var/lib/containerd", "/var/lib/docker", "/var/log/ecs"]
]
essential = true
mode = "always"
```

### Running the CIS reports

**Bottlerocket CIS Benchmark**

```
[settings.bootstrap-commands.bottlerocket-cis-benchmark]
commands = [["apiclient", "report", "cis", "-l", "2"]]
essential = true
mode = "always"
```

**Kubernetes CIS Benchmark**

```
[settings.bootstrap-commands.kubernetes-cis-benchmark]
commands = [["apiclient", "report", "cis-k8s", "-l", "2"]]
essential = true
mode = "always"
```

### Checking and Applying Updates

```
[settings.bootstrap-commands.kubernetes-cis-benchmark]
commands = [["apiclient", "update", "apply", "--check", "--reboot"]]
essential = true
mode = "always"
```

## Also see
- {{< ver-ref project="os" page="/api/settings/bootstrap-commands">}} bootstrap-commands in the API Setting Reference{{< /ver-ref >}}

{{< on-github >}}
59 changes: 59 additions & 0 deletions data/settings/1.22.x/bootstrap-commands.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
[[docs.ref.name_commands]]
name_override = "<name>.commands"
description = "Specifies the API commands to be run as part of the bootstrap command. Each API command is expressed as a list of strings and commands field comprises of a list of API commands."
see = [
["[`settings.bootstrap-commands.<name>.mode`](../bootstrap-commands/#name_mode) for a full example with `settings.bootstrap-commands.<name>.commands`."],
["The {{< ver-ref project=\"os\" page=\"/concepts/bootstrap-commands#lifecycle\" >}}bootstrap commands lifecycle{{< /ver-ref >}} conceptual documentationion"]
]

[[docs.ref.name_essential]]
name_override = "<name>.essential"
description = "If `essential` is set to `true` the bootstrap command will halt the boot process when it exits with a non-zero exit code."
default = "`false`"
accepted_values = [
"`true`",
"`false`"
]
see = [
["[`settings.bootstrap-commands.<name>.mode`](../bootstrap-commands/#name_mode) for a full example with `settings.bootstrap-commands.<name>.essential`."],
["The {{< ver-ref project=\"os\" page=\"/concepts/bootstrap-commands#lifecycle\" >}}bootstrap commands lifecycle{{< /ver-ref >}} conceptual documentationion"]
]


[[docs.ref.name_mode]]
name_override = "<name>.mode"
description = """
Specifies how (or if) a bootstrap command starts at boot.
If you set the value to:
* `"always"`, the bootstrap command will start on every boot,
* `"off"`, the bootstrap command will not start at boot,
* `"once"`, the bootstrap command will start on the first boot but after exit, the `mode` changes to `off`.
"""
accepted_values = [
"`\"always\"`",
"`\"off\"`",
"`\"once\"`"
]
see = [
["[`settings.bootstrap-commands.<name>.mode`](../bootstrap-commands/#name_mode) for a full example with `settings.bootstrap-commands.<name>.mode`."],
["The {{< ver-ref project=\"os\" page=\"/concepts/bootstrap-commands#lifecycle\" >}}bootstrap commands lifecycle{{< /ver-ref >}} conceptual documentation"]
]

[[docs.ref.name_mode.example]]
direct_toml = """
# Creates a bootstrap command called `mybootstrap`
# It runs everytime the instance boots and if exits with a non-zero code, will halt the boot process
[settings.bootstrap-commands.mybootstrap]
commands = [["apiclient", "ephemeral-storage", "init"], ["apiclient", "ephemeral-storage" ,"bind", "--dirs", "/var/lib/containerd", "/var/lib/docker", "/var/log/ecs"]]
essential = true
mode = "always"
"""
direct_shell = """
# Creates a bootstrap container called `mybootstrap`
# It runs only one time and if exits with a non-zero code, will halt the boot process
apiclient set \\
bootstrap-commands.mybootstrap.source=[["apiclient", "ephemeral-storage", "init"], ["apiclient", "ephemeral-storage" ,"bind", "--dirs", "/var/lib/containerd", "/var/lib/docker", "/var/log/ecs"]] \\
bootstrap-commands.mybootstrap.essential=true \\
bootstrap-commands.mybootstrap.mode=\"always\"
"""
129 changes: 129 additions & 0 deletions layouts/shortcodes/bootstrap_commands_diagram.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
{{- $example := .Get "example" -}}

{{ if (eq $example 1) }}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="100%" viewBox="-0.5 -0.5 561 361" class="bootstrap-container-diagram">
<defs/>
<g>
<path d="M 280 60 L 280 73.63" class="sequence-arrow-line"/>
<path d="M 280 78.88 L 276.5 71.88 L 280 73.63 L 283.5 71.88 Z" class="sequence-arrow-point" />
<rect x="0" y="0" width="560" height="60" class="systemd-box" />
<g transform="translate(257.5,23.5)">
<text x="23" y="12" class="systemd-box-text" >systemd</text>
</g>
<path d="M 280 280 L 280 293.63" class="sequence-arrow-line"/>
<path d="M 280 298.88 L 276.5 291.88 L 280 293.63 L 283.5 291.88 Z" class="sequence-arrow-point" />
<rect x="0" y="80" width="560" height="200" class="bootstrap-containers-rect"/>
<rect x="10" y="70" width="130" height="20" class="bootstrap-containers-label-back" />
<g transform="translate(20.5,73.5)">
<text x="55" y="12" class="bootstrap-containers-text">bootstrap commands</text>
</g>
<rect x="10" y="90" width="110" height="40" class="container-b1"/>
<g transform="translate(57.5,102.5)">
<text x="8" y="12" class="container-b1">001-cmd</text>
</g>
<rect x="153" y="130" width="110" height="30" class="container-b2"/>
<g transform="translate(200.5,137)">
<text x="8" y="12" class="container-b2">002-cmd</text>
</g>
<rect x="297" y="160" width="110" height="50" class="container-b3"/>
<g transform="translate(344.5,177)">
<text x="8" y="12" class="container-b3">003-cmd</text>
</g>
<rect x="440" y="210" width="110" height="60" class="container-b4"/>
<g transform="translate(487.5,230)">
<text x="8" y="12" class="container-b4">004-cmd</text>
</g>
<rect x="0" y="300" width="560" height="60" class="next-boot-stage"/>
<g transform="translate(238.5,323.5)">
<text x="41" y="12" class="next-boot-stage">next boot stage</text>
</g>
</g>
</svg>
{{ end }}
{{ if (eq $example 2) }}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="100%" viewBox="-0.5 -0.5 561 274" class="bootstrap-container-diagram">
<defs/>
<g>
<path d="M 280 60 L 280 73.63" class="sequence-arrow-line"/>
<path d="M 280 78.88 L 276.5 71.88 L 280 73.63 L 283.5 71.88 Z" class="sequence-arrow-point"/>
<rect x="0" y="0" width="560" height="60" class="systemd-box" />
<g transform="translate(257.5,23.5)">
<text x="23" y="12" class="systemd-box-text" >systemd</text>
</g>
<path d="M 280 180 L 280 250.63" class="sequence-arrow-line"/>
<path d="M 280 250.88 L 276.5 243.88 L 280 245.63 L 283.5 243.88 Z" class="sequence-arrow-point" /> <rect x="0" y="80" width="560" height="140" class="bootstrap-containers-rect"/>
<rect x="10" y="70" width="130" height="20" class="bootstrap-containers-label-back" />
<rect x="10" y="90" width="110" height="40" class="container-b1"/>
<g transform="translate(57.5,102.5)">
<text x="8" y="12" class="container-b1">001-cmd</text>
</g>
<g transform="translate(20.5,73.5)">
<text x="55" y="12" class="bootstrap-containers-text">bootstrap commands</text>
</g>
<rect x="153" y="130" width="110" height="30" class="container-b2"/>
<g transform="translate(200.5,137)">
<text x="8" y="12" class="container-b2">002-cmd</text>
</g>
<rect x="297" y="160" width="110" height="50" class="container-b3"/>
<g transform="translate(344.5,177)">
<text x="8" y="8" class="container-b3">003-cmd</text>
<text x="8" y="21" class="container-b3">essential = true</text>
</g>
<g transform="translate(256.5,253.5)">
<text x="23" y="12" class="boot-halt">boot halt</text>
</g>
<path d="M 407 210 L 437.75 190 L 510 190 Q 530 190 530 210 Q 530 230 510 230 L 437.75 230 Z" class="exit-flag"/>
<g transform="translate(441.5,203.5)">
<text x="29" y="12" class="exit-flag">exit code 1</text>
</g>
</g>
</svg>
{{end}}
{{ if (eq $example 3) }}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="100%" viewBox="-0.5 -0.5 561 411" class="bootstrap-container-diagram">
<defs/>
<g>
<path d="M 280 60 L 280 73.63" class="sequence-arrow-line" />
<path d="M 280 78.88 L 276.5 71.88 L 280 73.63 L 283.5 71.88 Z" class="sequence-arrow-point" />
<rect x="0" y="0" width="560" height="60" class="systemd-box" />
<g transform="translate(257.5,23.5)">
<text x="23" y="12" class="systemd-box-text" >systemd</text>
</g>
<rect x="0" y="80" width="560" height="250" class="bootstrap-containers-rect"/>
<rect x="10" y="70" width="130" height="20" class="bootstrap-containers-label-back" />
<g transform="translate(20.5,73.5)">
<text x="55" y="12" class="bootstrap-containers-text">bootstrap commands</text>
</g>
<rect x="10" y="90" width="110" height="40" class="container-b1"/>
<g transform="translate(57.5,102.5)">
<text x="8" y="12" class="container-b1">001-cmd</text>
</g>
<rect x="153" y="130" width="110" height="30" class="container-b2"/>
<g transform="translate(200.5,137)">
<text x="8" y="12" class="container-b2">002-cmd</text>
</g>
<rect x="297" y="160" width="110" height="50" class="container-b3"/>
<g transform="translate(344.5,177)">
<text x="8" y="8" class="container-b3">003-cmd</text>
<text x="8" y="21" class="container-b3">essential = true</text>
</g>
<path d="M 495 270 L 495 290 L 495 280 L 495 293.63" class="sequence-arrow-line"/>
<path d="M 495 298.88 L 491.5 291.88 L 495 293.63 L 498.5 291.88 Z" class="sequence-arrow-point" />
<rect x="440" y="210" width="110" height="60" class="container-b4"/>
<g transform="translate(487.5,230)">
<text x="8" y="12" class="container-b4">004-cmd</text>
<text x="8" y="22" class="container-b4">mode=once</text>
</g>
<g transform="translate(449.5,281.5)">
<text x="46" y="30" class="mode-to-off">Update mode for</text>
<text x="46" y="45" class="mode-to-off">004-cmd to off</text>
</g>
<path d="M 280 330 L 280 343.63" class="sequence-arrow-line"/>
<path d="M 280 348.88 L 276.5 341.88 L 280 343.63 L 283.5 341.88 Z" class="sequence-arrow-point"/>
<rect x="0" y="350" width="560" height="60" class="next-boot-stage"/>
<g transform="translate(238.5,373.5)">
<text x="41" y="12" class="next-boot-stage">next boot stage</text>
</g>
</g>
</svg>
{{end}}
Loading

0 comments on commit 92e2922

Please sign in to comment.