From d56817f7590717c040871d841fb938e01923917b Mon Sep 17 00:00:00 2001 From: Dalton Hubble Date: Mon, 14 Dec 2015 09:46:37 -0800 Subject: [PATCH] docs: Add some README, API and config docs --- README.md | 137 +++++++++++++++++++++++++++++++++++++++++++------ docs/api.md | 96 ++++++++++++++++++++++++++++++++++ docs/config.md | 22 ++++++++ 3 files changed, 240 insertions(+), 15 deletions(-) create mode 100644 docs/api.md create mode 100644 docs/config.md diff --git a/README.md b/README.md index 76360e15..219fced7 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,99 @@ -# Boot Config Service +# CoreOS on Hardware -Boot config service for PXE, iPXE, and Pixiecore. +`bootcfg` serves configs to PXE/iPXE/Pixiecore network boot clients machines based on their hardware attributes, to declaratively setup clusters on virtual or physical hardware. -## Validation +Boot configs (kernel, options) and cloud configs can be defined for machines with a specific UUID, a specific MAC address, or as the default. `bootcfg` serves configs as iPXE scripts and as JSON to implement the Pixiecore [API spec](https://github.com/danderson/pixiecore/blob/master/README.api.md). + +`bootcfg` can run as a container or on a provisioner machine directly and operates alongside your existing DHCP and PXE boot setups. + +## Usage + +Pull the container image + + docker pull quay.io/dghubble/bootcfg:latest + +or build the binary from source. + + ./build + ./docker-build + +Next, prepare a [data config directory](#configs) or use the example in [data](data). Optionally create an [image assets](#assets) directory. + +Run the application on your host or as a Docker container with flag or environment variable [arguments](docs/config.md). + + docker run -p 8080:8080 --name=bootcfg --rm -v $PWD/data:/data -v $PWD/images:/images dghubble/bootcfg:latest -address=0.0.0.0:8080 + +You can quickly check that `/ipxe?uuid=val` and `/pixiecore/v1/boot/:mac` serve the expected boot config and `/cloud?uuid=val` serves the expected cloud config. Proceed to [Networking](#networking) for discussion about connecting clients to your new boot config service. + +### Configs + +A `Store` maintains associations between machine attributes and different types of bootstrapping configurations. Currently, `bootcfg` includes a `FileStore` which can search a filesystem directory for `boot` and `cloud` configs. + +Prepare a config data directory. If you keep a versioned repository of declarative configs, consider keeping this directory there. + + data + ├── boot + │   └── default + └── cloud + ├── default + └── uuid + └── 1cff2cd8-f00a-42c8-9426-f55e6a1847f6 + └── mac + └── 1cff2cd8-f00a-42c8-9426-f55e6a1847f6 + +To find boot configs and cloud configs, the `FileStore` searches the `uuid` directory for a file matching a client machine's UUID, then searches `mac` for file matching the client's MAC address, and finally falls back to using the `default` file if present. + +A typical boot config can be written as + + { + "kernel": "/images/stable/coreos_production_pxe.vmlinuz", + "initrd": ["/images/stable/coreos_production_pxe_image.cpio.gz"], + "cmdline": { + "cloud-config-url": "http://172.17.0.2:8080/cloud?uuid=${uuid}", + "coreos.autologin": "" + } + } + +Point kernel and initrd to either the URIs of images or to local [assets](#assets) served by `bootcfg`. If the OS in the boot config supports it, point `cloud-config-url` to the `/cloud` endpoint at the name or IP where you plan to run `bootcfg`. + +For this example, we use the internal IP Docker will assign to the first container on its bridge, because we'll attach PXE clients to the same bridge. + +A typical cloud config script: + + #cloud-config + coreos: + units: + - name: etcd2.service + command: start + - name: fleet.service + command: start + write_files: + - path: "/home/core/welcome" + owner: "core" + permissions: "0644" + content: | + File added by the default cloud-config. + +See the [data](/data) directory for examples. Alternative `Store` backends and support for additional machine attributes is forthcoming. + +### Image Assets + +Optionally, `bootcfg` can serve free-form static assets (e.g. kernel and initrd images) if an `-images-path` argument to a mounted volume directory is provided. + + images/ + └── coreos + └── 835.9.0 + ├── coreos_production_pxe.vmlinuz + └── coreos_production_pxe_image.cpio.gz + +Run the `get-coreos` script to quickly download kernel and initrd images from a recent CoreOS release into an `/images` directory. + + ./scripts/get-coreos + +To use the hosted images, tweak `kernel` and `initrd` in a boot config file. For example, change `http://stable.release.core-os.net/amd64-usr/current/coreos_production_pxe.vmlinuz` to `/images/coreos/835.9.0/coreos_production_pxe.vmlinuz` so your client machines don't all download a remote image. + +## Networking The boot config service can be validated in PXE, iPXE, and Pixiecore scenarios using a libvirt virtual network with VM or bare metal PXE clients. @@ -18,31 +108,43 @@ Start the container services specific to the scenario you wish to test, followin ### iPXE -Run the boot config service container. +Configure your iPXE server to chainload the `bootcfg` iPXE boot script hosted at `$BOOTCFG_BASE_URL/boot.ipxe`. The base URL should be of the for `protocol://hostname:port` where where hostname is the IP address of the config server or a DNS name for it. - ./build - ./docker-build - ./docker-run + # dnsmasq.conf + # if request from iPXE, serve bootcfg's iPXE boot script (via HTTP) + dhcp-boot=tag:ipxe,http://172.17.0.2:8080/boot.ipxe -Run the included `ipxe` Docker image which runs DHCP and sends options to point iPXE clients to the boot config service and to chainload PXE clients to iPXE. +#### docker0 + +If you're running `bootcfg` on Docker an easy way to try PXE/iPXE booting is by running the included `ipxe` container on the same Docker bridge. + +The `ipxe` Docker image runs DHCP and sends options to point PXE/iPXE clients to the boot config service (hardcoded to http://172.17.0.2:8080). For PXE clients, iPXE firmware is chainloaded. cd dockerfiles/ipxe ./docker-build ./docker-run -Create a PXE boot client VM using virt-manager as described above. +Create a PXE boot client VM or attach a bare metal PXE boot client to the `docker0` virtual bridge. See [clients](#Clients). + +### PXE + +To use `bootcfg` with PXE, you must [chainload iPXE](http://ipxe.org/howto/chainloading). This can be done by configuring your PXE/DHCP/TFTP server to send `undionly.kpxe` over TFTP to PXE clients. + + # dnsmasq.conf + enable-tftp + tftp-root=/var/lib/tftpboot + # if regular PXE firmware, serve iPXE firmware (via TFTP) + dhcp-boot=tag:!ipxe,undionly.kpxe + +`bootcfg` does not respond to DHCP requests or serve files over TFTP. #### Pixecore -Run the boot config service container. - - make run-docker - Run the Pixiecore server container which uses `api` mode to call through to the config service. make run-pixiecore -Finally, run the `vethdhcp` to create a virtual ethernet connection on the `docker0` bridge, assign an IP address, and run dnsmasq to provide DHCP service to VMs we'll add to the bridge. +Finally, run the `vethdhcp` script to create a virtual ethernet connection on the `docker0` bridge, assign an IP address, and run dnsmasq to provide DHCP service to VMs we'll add to the bridge. make run-dhcp @@ -50,7 +152,12 @@ Create a PXE boot client VM using virt-manager as described above. ### Troubleshooting -Check your firewall settings to ensure you've allowed DHCP to run. If you get an "address is already in use" error, try stopping the `default` network created in virt-manager. If you find that the `docker0` bridge receives DHCP Offers from dnsmasq, but the VM does not you may need to change an iptables rule. +* Check your firewall settings to ensure you've allowed DHCP to run. +* On some platforms, SELinux prevents file serving unless contexts are changed appropriately. +* If you get an "address is already in use" error, try stopping the `default` network created in virt-manager. +* If you find that the `docker0` bridge receives DHCP Offers from dnsmasq, but the VM does not you may need to change an iptables rule. + +Change subnet MASQUERADE. $ iptables -L -t nat $ iptables -t nat -R POSTROUTING 1 -s 172.17.0.0/16 ! -d 172.17.0.0/16 -j MASQUERADE diff --git a/docs/api.md b/docs/api.md new file mode 100644 index 00000000..32c018da --- /dev/null +++ b/docs/api.md @@ -0,0 +1,96 @@ + +# bootcfg API + +## iPXE Script + +Serves a static iPXE boot script which gathers client machine attributes and chain loads to the iPXE boot config endpoint. Configure your iPXE server or DHCP options to boot from this script (e.g. set `dhcp-boot:dhcp-boot=tag:ipxe,http://provisioner.example.com/ipxe/boot.ipxe` if using `dnsmasq`). + + GET http://bootcfg.example.com/boot.ipxe + +**Response** + + #!ipxe + chain config?uuid=${uuid} + +## iXPE Boot Config + +Renders an iPXE boot config script based on hardware attribute query parameters and registered boot configs. Hardware attributes are matched in priority order: UUID, MAC address, default (if set). + + GET http://bootcfg.example.com/ipxe + +**Query Parameters** + +| Name | Type | Description | +|------|--------|---------------| +| uuid | string | Hardware UUID | +| mac | string | MAC address | + +**Response** + + #!ipxe + kernel kernel-for-machine.vmlinuz cmd-line-options + initrd initrd-for-machine + boot + +`kernel-for-machine`, `cmd-line-options`, and `initrf-for-machine` are populated from a boot config. + +## Pixiecore Boot Config + +Renders a Pixiecore boot config as JSON to implement the Pixiecore API [spec](https://github.com/danderson/pixiecore/blob/master/README.api.md) for Pixiecore setups. Currently, Pixiecore only provides MAC addresses for mapping to boot configs. + + GET http://bootcfg.example.com/pixiecore/v1/boot/:MAC + +**URL Parameters** + +| Name | Type | Description | +|------|--------|-------------| +| mac | string | MAC address | + +**Response** + + { + "kernel": "\/images\/coreos_production_pxe.vmlinuz", + "initrd": [ + "\/images\/coreos_production_pxe_image.cpio.gz" + ], + "cmdline": { + "coreos.autologin": "" + } + } + +## Cloud Configs + +Serves cloud configs based on hardware attribute query parameters and registered cloud configs. Hardware attributes are matched in priority order: UUID, MAC address, default (if set). + + GET http://bootcfg.example.com/cloud + +**Query Parameters** + +| Name | Type | Description | +|------|--------|---------------| +| uuid | string | Hardware UUID | +| mac | string | MAC address | + +**Response** + + #cloud-config + coreos: + units: + - name: etcd2.service + command: start + - name: fleet.service + command: start + +## Image Assets + +If you need to host kernel and initrd images within your network, bootcfg server's `/images/` route serves free-form static assets. Set the `-images-path` when starting the bootcfg server. Here is an example images directory layout: + + images/ + └── coreos + └── 835.9.0 + ├── coreos_production_pxe.vmlinuz + └── coreos_production_pxe_image.cpio.gz + └── 877.1.0 + ├── coreos_production_pxe.vmlinuz + └── coreos_production_pxe_image.cpio.gz + diff --git a/docs/config.md b/docs/config.md new file mode 100644 index 00000000..e04ef277 --- /dev/null +++ b/docs/config.md @@ -0,0 +1,22 @@ + +# Config: Flags and Variables + +`bootcfg` arguments can be provided as flags or as environment variables. + +| flag | varaible | example | +|------|----------|---------| +| -address | BOOTCFG_ADDRESS | 0.0.0.0:8080 | +| -data-path | BOOTCFG_DATA_PATH | ./data | +| -images-path | BOOTCFG_IMAGES_PATH | ./images, ./static | +| -log-level | BOOTCFG_LOG_LEVEL | critical, error, warning, notice, info, debug | + +## Examples + +Binary + + ./run -address=0.0.0.0:8080 -data-path=./data -images-path=./images -log-level=info + +Container + + docker run -p 8080:8080 --name=bootcfg --rm -v $PWD/data:/data -v $PWD/images:/images coreos/bootcfg:latest -address=0.0.0.0:8080 -data-path=./data -images-path=./images +