* The reusable wait-for-status-check GitHub Workflow is only used
in public repos which can use actions for free. So we might as
well use GitHub-managed runners
* Motived by re-evaluating runner usage in response to GitHub
pricing changes. Shift costs to Microsoft where possible
* Add wait-for-status-checks reusable GitHub Workflow to wait
for all status checks in a PR. Mark this as a required check
so that GitHub auto-merge can be used
Rel: https://github.com/poseidon/wait-for-status-checks/
* Remove dependency on github.com/coreos/pkg because the module
is no longer maintained and it doesn't follow the usual release
conventions
* The last time flagutils was touched as 9 years ago by me. Bring
the function into the matchbox repo
* A few years ago there was a SVE for gopkg.in/yaml.v2 so we used
a replace to force MVS to pick a patched version of the package.
However, these days, no indirect dependencies use gopkg.in/yaml.v2
at all, they use gopkg.in/yaml.v3 so we can remove this
* We now use GitHub Actions instead of a private Drone which is great
for OSS build transparency, but one drawback to that change is that
we no longer auto-deploy matchbox to internal Poseidon Labs infra
* We don't want public workflows for deploys to our private infra
Some commands were added in the ipxeBootstrap to enable architecture detection based on the architecture the iPXE version used was built for.
This is done through the use of an additional flag in the chain which is the ipxeBootstrap using the buildarch parameter.
* Add a publish workflow that uses the mkdocs-pages re-usable GitHub
Workflow when the `release-docs` branch is updated
* Build the docs site with mkdocs and publish to GitHub Pages
* Migrate from the internal Drone server using a GitHub Workflow
to perform the multi-arch container image build
* Use self-hosted GitHub runners on ARM64 to perform the ARM64
build step faster that QEMU/KVM emulation
* Mandate approval for all workflow runs from outside contributors
since the builds use push credentials and partially run internally
* Regenerate example Ignition using fcct v0.18.0 to produce Ignition
spec v3.4.0 as a followup to https://github.com/poseidon/matchbox/pull/1079
* Fix one profile example where a double escape isn't needed
* Emphasize that Container Linux Configs have been dropped and
that Butane is the way forward to use modern Ignition v2
* Include some links to Flatcar Linux docs
* Update Makefile and docs for v0.10.0 release process
* Update github.com/coreos/go-semver from v0.3.0 to 167f5da to
prevent it from using gopkg.in/yaml.v2 (CVE-2019-11254)
```
go mod why gopkg.in/yaml.v2
(main module does not need package gopkg.in/yaml.v2)
```
* Recommend preparing Ignition configs external to Matchbox (e.g.
with Terraform poseidon/terraform-provider-ct)
* Document that Matchbox Rendering is discouraged
* Add Butane Config support as a replacement for dropping Container
Linux Config support. Perform Matchbox Go template evaluation,
translation to Ignition, and parsing to a forward compatible version
* Both Flatcar Linux and Fedora CoreOS now support Ignition v2
(spec v3.x) for machine consumption
* Drop support for Ignition v0.35.0 (Ignition spec v2.x)
* Drop support for Container Linux Configs (the YAML format that
rendered to Ignition v2.x JSON for Flatcar Linux)
* Deprecate rendering Container Linux Configs
* Use tools like [poseidon/ct](https://github.com/poseidon/terraform-provider-ct) or
[butane](https://coreos.github.io/butane/getting-started/) to validate and convert a
Butane Config (`focs` or `flatcar`) to Ignition (for Matchbox to serve)
* Please migrate to serving CoreOS Ignition directly, the Container
Linux related HTTP and gRPC endpoints will be removed in future
* Discontinue using Matchbox's Container Linux Config features
* Flatcar Linux OS now supports Ignition v2.13+ which means it
can accept Ignition v3.x spec's, like Fedora CoreOS. Matchbox
supports this by serving Ignition documents directly
* Users of the poseidon/matchbox Terraform provider can pass
a `matchbox_profile` `raw_ignition` contents with the desired
Ignition v3.3 spec
* Users of the poseidon/ct Terraform provider can write Butane
Config YAML, perform templating, and render an Ignition document
using either the fcos or the flatcar variant
* Default branch was renamed from master to main
* Internal build and publishing workflows were unaffected,
the GitHub Action is just for public contribution vetting
* Add initrd=main karg directive for UEFI (ignored by BIOS)
* Update Butane config version to v1.4.0 (generates Ignition v3.3.0)
in `fedora-coreos` and `fedora-coreos-install` examples
* Update virt-install flag --os-variant
* Removed virt-install deprecated flag --os-type
* Remove virt-install QEMU/KVM event preserve since it apparently
wasn't implemented anyway and QEMU/KVM now warns about it
* Remove serial consol kernel argument from examples, but still
mention it in docs
Rel:
* https://github.com/coreos/fedora-coreos-docs/pull/282
* https://www.spinics.net/linux/fedora/libvir/msg222078.html
We still support passing the rootfs image as an appended initrd, but we
recommend using coreos.live.rootfs_url instead: it generally boots faster
and requires less RAM.
When coreos-installer is running from the live image, it no longer needs
a separate install image, since by default it installs from content
embedded in the live system.
* Looking at enabling some update automation, the clarity of
using non-vendored Go modules/checksums outweighs the risk
of a module disappearing (mitigated by proxies)
* Update Fedora CoreOS live PXE and disk install examples to
Fedora 33
* Increase libvirt VM memory from 2GB to 3GB to support live
PXE example, which is mostly just for laptop examples/demos.
Reduce the VM count from 3 to 2 to compensate.
* Change `fedora-coreos.ign` to suggest using an ed25519 SSH
key since Fedora CoreOS 33 disables RSA SHA1 (256 is still ok
but most people won't know which they have)
* Update Terraform examples to use Terraform v0.13
* Refresh examples to show Fedora CoreOS and Flatcar Linux
* Remove the etcd3 example, not worth it to maintain
* Refactor examples to boot provision minimal hosts
with Fedora CoreOS or Flatcar Linux
* Remove the etcd3 cluster example or other specific
kinds of hosts
* Update script get-fedora-coreos
* Remove script get-coreos
* Matchbox is published as a binary or container image,
not planning to resume RPM/Copr publishing since its a
pain
* Publishing to Copr repo stopped in v0.6 (3 years ago)
* Use our own infra to perform image builds and push images. Provides
future options for publishing images to multiple image registries and
for multiple architectures, while keeping push permissions in-house
* Remove Travis ability to push to Quay
* Consider splitting repo and also enabling Quay automated builds
* Use our own infra to perform image builds and push images.
Provides future options for publishing images to multiple
image registries and for multiple architectures, while keeping
push permissions in-house
* Remove Travis ability to push to Quay
* Use Travis only for Go tests of Pull Requests
* Use `quay.io/dghubble/protoc` as the standard codegen
environment across projects. Pin a version (v3.10.1)
* Generated code is now automatically ignored by golint
based on the comment header, which will simplify linting
* Upgrade protobuf from 2bba0603135d to v1.3.2
* Upgrade grpc from v1.2.1 to v1.25.1
* Remove `get-protoc` and `codegen` scripts
* Travis creates a Go v1.13.4 environment, checks out the source
repo, and _then_ executes the `install` block to install `golint`
* With module-aware Go, this means installing `golint` caused a
diff, before the Matchbox `make` target was invoked. Builds were
correctly identified as "dirty" as a result
* Release tags v0.8.1 and v0.8.2 have been removed to avoid any
confusion. Container images with binaries considered dirty have
been removed as well
* rkt achieved its mission creating the OCI standard,
pluggable runtimes, and prevented Docker world
domination. We can now proceed with disarmament
* Few, if any, developers still use rkt locally
* Matchbox examples should be simple and educational to
show how to PXE provision machines into clusters. Today,
these goals are achieved well enough by the 3-node etcd
cluster example
* Several years ago, I put together examples PXE booting
Kubernetes clusters with Matchbox. That was before we wrote
Tectonic or Kubernetes was as popular as it is. Today, a
Kubernetes distro is a project in its own right. It no
longer makes sense to maintain (duplicate) a Kubernetes
distro as "an example" inside Matchbox.
* Matchbox is now used for Kubernetes cluster provisioning in
more organizations than ever. It backs the poseidon/Typhoon and
kinvolk/Locomotive distros. These both serve as great external
examples of using Matchbox to provision Kubernetes clusters
Attention: If you relied on Matchbox Kubernetes docs, you can
find a similar guide at https://typhoon.psdn.io/cl/bare-metal/
(same author). https://github.com/poseidon/typhoon/
* Remove files that are unused or refer to CoreOS policies
or points of contact that no longer apply
* Specifically, CoreOS (and by extension Red Hat) no longer
manages this project, events, etc.
* Update base image from alpine:3.6 to alpine:3.9
* Automatically publish dnsmasq image on merge to a branch
named "dnsmasq". Similar to how matchbox is automatically
published from master. Set the version based on git SHA
* Matchbox has moved to a new home in Poseidon
* Update Makefile so container image name uses
poseidon instead of coreos
* Publish container images to quay.io/poseidon/matchbox
* Render Container Linux Configs referenced in Profiles
as Ignition v2.2.0 documents.
* Recall, configs suffixed with .ign/.ignition will be
served as-is, as raw Ignition. Parse warnings will be
shown
* Serve Ignition configs (ending in .ign/.ignition) with v2.1
or v2.2 formats (previously, configs above v2.1 produced warnings
that the config was too new)
* Use Go 1.11 modules with `GO111MODULE=on`
* Change `make vendor` target to call `go mod vendor`
* Enforce builds and tests use the vendor directory by setting
the `-mod=vendor` flag (notice, travis does not fetch)
* Remove glide requirement and glide files
* Squid proxy docs were added as a draft in 2017 to show a
containerized setup for caching images for network boot
environments
* These docs never matured to a point of viability, I don't
make use of squid, and they're unmaintained. Users would be
better served consulting the squid project
* Local QEMU/KVM tutorials use either docker or rkt/acbuild,
but they're dated. rkt and acbuild are no longer in mainstream
use since they successfully drove OCI standardization
* Remove the rkt examples, as they are just more difficult for
newcomers to use and seldom maintained at this point
* Retain Docker examples, although podman will likely supplant
all docker usage in future
* Upstream author changed case of his/her username (breaking)
* Fix to lowercase name so clients using Go modules can avoid
case-sensitive conflicts. Go modules do not handle this real-world
case well
* Define the required versions of terraform-provider-matchbox
and terraform-provider-ct, with install instructions
* Refresh the tutorial for using Matchbox to PXE boot local
QEMU/KVM machines (using Terraform as a client)
* Add ipxe.efi to dnsmasq image's /var/lib/tftpboot directory
* Add initrd kernel argument respected only by UEFI
https://github.com/coreos/bugs/issues/1239
* Improve network-setup docs and scripts to cover UEFI clients
and to support launching UEFI QEMU/KVM clusters locally
* Reduce references to grub.efi flow, its not a happy path
* Upstream fixes to bump all control plane components to v1.7.5
* Stop including etcd-network-checkpointer with on-host etcd
* Remove experimental_self_hosted_etcd support
* Starting in Go 1.7, the standard library http.Request includes
a Context for passing request-scoped values between chained handlers
* Delete the ContextHandler (breaking, should not have been
exported to begin with)
* Mount host /opt/cni/bin in Kubelet to use host's CNI plugins
* Switch /var/run/kubelet-pod.uuid to /var/cache/kubelet-pod.uuid
to persist between reboots and cleanup old Kubelet pods
* Organize Kubelet flags in alphabetical order
In virt-install v1.4.2, the meaning of `--pxe` changed from "allow pxe
boot" to "always pxe boot." This breaks matchbox, since we expect hosts
to pxe-boot only with empty hds. On hosts with v1.4.2, the VMs loop,
re-installing CL over and over.
The flag isn't necessary anyways, since we pass `--boot=hd,network`,
which enables pxe-booting.
* Provide better errors to clients that forget to specify the
port or include a protocol scheme by mistake
* grpc-go uses net.SplitHostPort to validate server listener
addresses are 'host:port', but doesn't validate Dial targets
etcd examples set ETCDCTL_API=3 but are using v2 etcdctl commands. This
works on CL by accident because it ships with 2.3 so etcdctl doesn't
recognize the API env var.
* Users should deploy the Container Linux Update Operator to coordinate
reboots of Container Linux nodes in a Kubernetes cluster
* Write cluster addon docs to describe CLUO
* Terraform modules `bootkube` and `profiles` (Kubernetes) disable
locksmithd
* Use the container linux update operator to coordinate reboots
* Stop using locksmithd for reboot coordination
* etcd TLS assets now only need to be distributed to controller
nodes which are etcd peers
`After=network-online.target` *should* mean this isn't needed in most
cases, but per
https://www.freedesktop.org/wiki/Software/systemd/NetworkTarget/, the
definition of "network-online" is a little shaky.
Regardless, being a little more resilient to network flakes and races is
a good thing. The count of `10` was arbitrarily chosen.
* Ensure that Matchbox (open-source) and Tectonic (enterprise)
are kept separate, Tectonic has its own docs
* Matchbox is agnostic to Kubernetes distribution
* Fixes a regression introduced in 6f02107 which upgraded to
Kubernetes v1.6.6 and added self-hosted etcd with TLS
* Both on-host and self-hosted etcd now require clients to use
TLS client certs so locksmithd
* Upgrade to bootkube v0.4.5
* Enable TLS for experimental self-hosted etcd
* Upstream manifest generation changes modify the flannel
Daemonset, switch several control plane components to run
as non-root, and add an explicit UpdateStrategy to the
control plane components
* Add create, status, and destroy subcommands that use docker as
the container runtime for testing local QEMU/KVM clusters. Before,
only rkt could be used.
* Update local QEMU/KVM tutorial documentation
gRPC API verification step has invalid paths to client.crt and client.key; these are created in ~/matchbox-v0.6.1-linux-amd64/scripts/tls (depending on where the matchbox installer is extracted).
Matchbox added generic template support to enable experimenting with
rendering different kinds of templates, beyond Container Linux configs
and cloud-configs. We'd like to add a gRPC endpoint for generic
templates, as is done for other configs to support gRPC clients.
* Module "profiles" provides container-linux-install and
cached-container-linux-install Profiles
* Module bootkube accepts cached_install variable to determine
whether the cluster should install Container Linux from cache
or from the public download site (default)
* Static Kubernetes / rktnetes examples are no longer going to be
maintained by this repo or upgraded to Kubernetes v1.6. This is not
considered a deprecation bc the reference clusters are examples.
* Remove static Kubernetes cluster examples so users don't choose it
* Self-hosted Kubernetes (bootkube) is now the standard recommended
Kubernetes cluster configuration
* Listing pods or nodes as the final step of cluster creation should
not fail the entire build, its mainly for a pretty output
* There is no official definition of when a Kubernetes cluster is
"done" bootstrapping, they can momentarily fail to response in the
first minute or so as components stabalize
* Calculate the required service IP values from the service CIDR
* These inputs were never truly customizable anyway since bootkube
start assumed the 1st, 10th, and 15th offsets for named services
* Use the dghubble/bootkube-terraform terraform module to generate
the exact same assets that `bootkube render` would
* Use terraform to automate the kubeconfig copy and bootkube start
* Removes the reuqirement to download a bootkube binary, render assets,
and manually copy assets to nodes
Fixing the source URL format to confirm to more normative rpmbuild
standards and to allow for proper use of spectool/rpmspectool. This
change now produces a proper archive with the name and version number
used.
* Add an option to try experimental self-hosted etcd which uses
the etcd-operator to deploy an etcd cluster as pods atop Kubernetes
and disables the on-host etcd cluster
* When enabled, configure locksmithd to coordinate reboots through
self-hosted etcd
* Add matchbox_http_endpoint and matchbox_rpc_endpoint as variables
* Remove dghubble ssh public key from default
* Add a terraform.tfvars.example and gitignore terraform.tfvars
* Add container-linux-install profile to install Container Linux
* Add cached-container-linux-install profile to install Container Linux
from cached matchbox assets
Previously, the terraform readme was incomplete by only including
terraform plan and apply commands. Additionally, the readme was
updated to include instructions for updating the profiles module
source.
Fixes#502
* Terraform example typo's the port number in the etcd_endpoints
* Causes worker etcd-gateway to fail so Container Linux updates may
not been coordinated by locksmith
* Add grub.efi to get-tftp-files script. This matches prior
dnsmasq images, but was not part of a repeatable build
* Switch rkt run examples to pull from quay.io
* Remove script using acbuild to create ACIs
* Stop shipping or mentioning bootcmd CLI tool
* bootcmd has not been built out into a user-facing tool
* terraform-provider-matchbox addresses some of the need
* Keep bootcmd implementation as an example matchbox gRPC client
* Show matchbox deployment, service, and TLS secret creation
* Provide an Ingress resource for exposing HTTP and gRPC APIs
* Add note mentioning matchbox can be run publicly if best practices
are followed
* 1.8 changed the behavior of url.Parse so it is no longer
appropriate for parsing values like 0.0.0.0:8080
* Pass the address directly to http.ListenAndServe which gives
reasonable errors when bad values are given
Unless `GOARM` is specified, the Go compiler will choose the compiling system's architecture as a target (similar to GCC's `-march=native`). This commit prevents that by explicitly selecting ARMv6 (e.g. Raspberry Pi 1) as the target.
According to the documentation, ARM64 does not need this, as ARMv8 is implicit and the value of `GOARM` is not considered for this architecture.
See-Also: https://github.com/golang/go/wiki/GoArm
* Move toward a unified container image which is run
either by rkt or docker
* Sadly, image signing only supported by rkt and is not
part of the new standard
* Add Profile 'args' field as a list of kernel args
* Deprecate 'cmdline' field map of kernel args
* Add missing console=tty0 console=ttyS0 kernel args
to all example clusters
* Show `virsh console nodeN` command for development
with local QEMU/KVM nodes
* Focus on real-world, varied network environments
and flexibility, and bare-metal Tectonic
* iPXE provides better hardware introspection than being
limited to MAC
* ISC DHCP and dnsmasq provides production DHCP service
* Drop Pixiecore from the setups we can support or recommend
Before:
$ sudo ./scripts/devnet
./scripts/devnet: line 20: $1: unbound variable
After:
$ sudo ./scripts/devnet
USAGE: devnet <command>
Commands:
create create bootcfg and PXE services on the bridge
destroy destroy the services on the bridge
* Use the same k8s-controller and k8s-worker profiles
whether booting a live cluster or installing to disk
* Exta root=/dev/sda kernel arg during install is fine
* simple example just network boots CoreOS machines
* simple-install example just network boots and installs CoreOS
* Simple examples don't do much provisioning, except adding pubkeys
* Add `scripts/libvirt create` subcommand for rkt setups
* Add --os-variant=generic to remove nag messages to specify
* Rename places QEMU/KVM VMs were called libvirt VMs
Distributions like Debian 8 ship a `gpg` (1.4.x) and a `gpg2` (2.1.x) binary,
which both use the same config files, and thus cannot be used at the same
time, due to incompatible options. Thus we allow the user to specify which
gpg binary they want to use.
Previously this matched very specific HTTP status codes only, while now it
matches any success or redirection status code. It also works for "HTTP/2"
answers in addition to "HTTP/2.0".
Fixes: #331
* Self-hosted Kuberntes api-server comes up without a hostname
override and detects the hostname it should use from `uname -n`
* kube-apiserver name must correspond to routable kubelet
hostname-override
* Provision /etc/hostname with the FQDN so `uname -n` can be
used by Kubernetes (until NODE_NAME is avail. in k8s 1.4)
* Print helpful message if SAN is unset
* Don't prompt to sign certs, false illusion of choice. Users
running cert-gen need self-signed certs.
* Remove intermediate cert signing requests
* Decrease the scariness of the self-signed warnings
* Add changelog entries since v0.4.0
* Link to Tectonic Installer post
* Don't highlight pixiecore on README. Endpoints support
it, but its not encouraged.
* Get/build protoc and protoc-gen-go binaries under tools
so they do not interfere with any user installations
* Ensure protoc and protoc-gen-go versions are pinned
* Use DNS names to refer to nodes in etcd examples to mirror
production
* Add dnsmasq.conf files for metal0 (rkt) and docker0 examples
which include static MAC->IP and Name->IP mappings
* Remove the etcd-docker example cluster, no longer needed
* Clusters which install to disk auto-update so this bump just
changes the "starting" version. Deployed alpha clusters should
already be using 1109.1.0.
* Serve /metadata including group metadata, selectors, and
query variables in KEY=value "env file" format lines
* Recurse into nested maps (e.g. OUTER_INNER=val)
* Add query parameters to template variables, referenced by
{{.request.query.param}}
* Render Ignition/Fuze, cloud-config, and generic templates and
metadata with collected variables
* Replace template variable {{.query}} with {{.request.raw_query}}
(breaking)
* Simplify common http request handling chains
* Separate github.com/dghubble/ctxh source so we can move
it to a separate CoreOS package or vendor upstream
* Remove unused requireGET
* Units which fail due to unmet dependencies are not restarted.
Upstream issue: github.com/systemd/systemd/issues/1312
* Avoid depending on flanneld. Instead, check and fail if unmet
to force a restart (retry)
* Remove unneeded k8s-assets dependency on kubelet. The k8s-assets
script itself just checks for the Kubernetes API to be up anyway
* Kubelet must be able to resolve DNS names which are
known to the host
* Fixes a bug in which only IP's could be used for
k8s_controller_endpoint metadata
* Upstream systemd issue: github.com/systemd/systemd/issues/1312
* Units which fail due to unmet dependencies are not restarted
as they would be upon failure. Kubelet should keep trying until
flanneld is active.
* Apply the recommended work-around by adding an ExecStart
which checks for a Wanted dependency and purposefully fails
when unmet in order to force a restart to keep trying.
* When raw Ignition (.ign/.ignition) content is provided, Parse
the contents with ignition, but return the contents as JSON
regardless of the result to respect user pass-through expectations
* Warn on parse errors which can occur if a newer Ignition format
is used than the version of Ignition that bootcfg was compiled
with
* By default, templates for Ignition are rendered and
parsed as github.com/coreos/fuze YAML configs, which
formalize the transform from YAML to Ignition JSON
* Ignition files (.ign/.ignition) should be validated and
served directly, without template rendering
* Remove support for Ignition v1
* This change is breaking! Users need to tweak any YAML
Ignition templates to the very similar Fuze YAML format
* Upgrade the self-hosted Kubernetes cluster example to
use bootkube v0.1.1 which supports apiserver checkpointing
in order to tolerate apiserver downtime (e.g. controller
reboot)
* Bumps Kubernetes version to v1.3.0-beta.2
* Re-enable CoreOS auto-updates
* Revert NetBoot id in storage.proto for compatibility
* Add URL.RawQuery to data for generic templates
* Add generic directory to scripts/setup-data-dir
* Add documentation for generic templates.
Profiles now have GenericId which can be used to render a "generic" go template file (neither ignition nor cloud-init) using group metadata and selectors. The storage interface and it's implementations use GetGeneric to retrieve this template.
Partially addresses #224
* scp kubeconfig to hosts rather than insecurely distributing
credentials within Ignition configs. This is also easier than
copy-pasting k8s secrets into machine metadata (slow).
* Self-hosted Kubernetes machine configurations can be versioned
without containing Kubernetes credentials
* Use path-based activiation for the host kubelet
* Update from Kubernetes v1.2.2 to v1.3.0-alpha.5_coreos.0.
* Update host kubelet flags accordingly
* gRPC API server requires a CA certificate to verify
and authenticate clients (passed via -ca-file)
* gRPC clients must authenticate with a client certificate
and key (passed via -cert-file and -key-file)
* A CA certificate (e.g. ca.crt) should be used to sign a server
certificate (server.crt for a private key server.key)
* gRPC API server requires a server certificate and key to be enabled
(passed via -cert-file and -key-file)
* gRPC client bootcmd tool must verify the server identity using a
known CA (passed to bootcmd via -ca-file)
* This provides transport security, it does not provide client
authentication
* Examples which install CoreOS to disk should reference
a CoreOS install image from bootcfg assets to speed up
installs and improve the offline use-case
* Update scripts/get-coreos to download and verify the
CoreOS install image
* Update CoreOS version to get rkt 1.2.1->1.6.0 improvements
for running the kubelet wrapper in Kubernetes clusters
* Update CoreOS version for other clusters so users only need
to download one cached version of assets to run examples
* Rendering an Ignition config or cloud-config template
with machine group metadata will error and log if a metadata
value is missing.
* Previously, the default missing value was "no value"
* Match machines by MAC address in examples
* Re-use the MAC address to assign static networkd configs
where needed.
* UUID is useful to uniquely identify a machine (unlike MAC)
but many users had difficulty finding the network device name
to use in static networkd configs. Selecting by MAC reduces
the potential for user error here.
* bootkube clusters work with bootkube 5c1efe3ac61e270
* Copy bootkube generated assets and executable to any master
* Change hosts to use kubelet client certificate instead of token
* Update bootkube deployment documentation
The docs had the user skip image verification for an image pulled from
Quay, claiming that since Quay hosts docker images the image is
unsigned. This is true when fetching the docker file with "docker://",
but when an ACI is pulled from Quay (which it converts on the fly), the
ACI will be properly signed.
* Stop showing version hash at / path. If bootcfg were deployed
at a public endpoint, the version could be used by attackers to
find out-of-date deployments.
* Users try to use the latest reference example clusters with
a bootcfg v0.3.0 deployment, which did not yet support Ignition
2.0.0. Wait until closer to v0.4.0 to bump Ignition configs.
* Allow Ignition 2.0.0 JSON documents to be served
* Stop requiring Ignition templates to use file extensions to
specify their rendered format for parsing
* Profiles should use only the user-provided DNS endpoint.
Adding 8.8.8.8 can cause inconsistent resolution and in some
setups, 8.8.8.8 is not routable.
* Setting k8s_version via metadata gives the impression
it can be bumped and the cluster will operate with the
desired version. In reality, the k8s profiles change in
minor but important ways which we validate between k8s
releases. It should be part of the k8s profile Ignition.
* bootcfg/version package provides the linker's GIT SHA based
version to bootcfg components
* Display the bootcfg version via the HTTP server / path for
convenience and for validating a deployed version easily
* Log requests to the / rooted subtree paths to surface machines
which are making requests containing typos and mistakes that do
not match HTTP API endpoints
* In the k8s-install example, the k8s-certs@.service checks for
the wrong file and always attempts to curl TLS assets from bootcfg.
After restarts or auto-updates, if bootcfg is not running, the certs
are present on disk so the kubelet and k8s cluster operate normally,
while k8s-certs services fail (mostly harmless).
* Fixes k8s-certs@service failures after restarts when bootcfg is
unavailable. Provisioned nodes should not have a hard dependency on
bootcfg service.
<!-- READ: Issues are used to receive focused bug reports from users and to track planned future enhancements by the authors. Topics like support, debugging help, advice, and operation are out of scope and should not use issues-->
**Description**
A clear and concise description of what the bug is.
**Steps to Reproduce**
Provide clear steps to reproduce the bug.
- [ ] Relevant error messages if appropriate (concise, not a dump of everything).
**Expected behavior**
A clear and concise description of what you expected to happen.
* Release: Matchbox version or Git SHA (reporting latest is **not** helpful)
**Possible Solution**
<!-- Most bug reports should have some inkling about solutions. Otherwise, your report may be less of a bug and more of a support request (see top).-->
* Update butane from v0.17.0 to v0.18.0 ([#1079](https://github.com/poseidon/matchbox/pull/1079))
* Add support for `fcos` [v1.5.0](https://coreos.github.io/butane/config-fcos-v1_5/) Butane Configs
* Add support for `flatcar` [v1.1.0](https://coreos.github.io/butane/config-flatcar-v1_1/) Butane Configs
* Render Ignition as Ignition spec [v3.4.0](https://coreos.github.io/ignition/configuration-v3_4/)
## v0.10.0
* Remove support for Ignition v0.35.0 (Ignition spec v2.x)
* Remove support for Container Linux Configs (**action required**)
* Container Linux Configs were a YAML format that rendered to Ignition (spec v2.x)
* Flatcar Linux now supports Ignition v2 (spec v3.x)
* Butane is a suitable YAML format that renders Ignition v2 (spec v3.x)
* Upgrade Ignition from v0.35.0 (spec v2.x) to v2.14.0 (spec v3.x)
* Update Go version (v1.20.2) and alpine base image (v3.17.3)
* Add limited support for Matchbox rendering Butane configs ([#997](https://github.com/poseidon/matchbox/pull/997)) ([docs](https://matchbox.psdn.io/ignition/#matchbox-rendering))
* Recommend writing Butane via external tools (**action required**)
* For Terraform, use [poseidon/terraform-provider-ct](https://github.com/poseidon/terraform-provider-ct)
* For a CLI, use [`butane`](https://github.com/coreos/butane)
* Parse Ignition and render forward to Ignition v2 (spec v3.3)
* Ignition is [forward](https://github.com/coreos/ignition/blob/main/config/v3_3/config.go#L61) compatible (e.g. a `v3.1` spec can be rendered as `v3.3` safely)
If you still template Container Linux Configs via Matchbox, [migrate](https://www.flatcar.org/docs/latest/provisioning/config-transpiler/) to Butane by prepending:
```yaml
variant:flatcar
version:1.0.0
```
## v0.9.1
* Add dependabot Go module update automation ([#833](https://github.com/poseidon/matchbox/pull/833))
* Update Go version (v1.18.4) and alpine base image (v3.16.1)
* Move `dnsmasq` container image to its own [repo](https://github.com/poseidon/dnsmasq) ([#840](https://github.com/poseidon/matchbox/pull/840))
* Deprecate rendering Container Linux Configs
* Please migrate to serving CoreOS Ignition directly
* Use tools like [poseidon/ct](https://github.com/poseidon/terraform-provider-ct) or [butane](https://coreos.github.io/butane/getting-started/) to validate and convert a Butane Config (`focs` or `flatcar`) to Ignition (for Matchbox to serve)
### Docs/Examples
* Migrate docs website to GitHub Pages ([#976](https://github.com/poseidon/matchbox/pull/976))
* Update Fedora CoreOS images and configuration ([#972](https://github.com/poseidon/matchbox/pull/972))
* Update Fedora CoreOS initrd karg for UEFI ([#978](https://github.com/poseidon/matchbox/pull/978))
* Update Flatcar Linux examples to use Ignition v3.3.0 ([#980](https://github.com/poseidon/matchbox/pull/980))
## v0.9.0
* Refresh docs and examples for Fedora CoreOS and Flatcar Linux ([#815](https://github.com/poseidon/matchbox/pull/815), [#816](https://github.com/poseidon/matchbox/pull/816))
* Publish Matchbox images from internal infra to Quay (`quay.io/poseidon/matchbox`)
* Update Go version from v1.13.4 to v1.14.9
* Update base image from `alpine:3.10` to `alpine:3.12` ([#784](https://github.com/poseidon/matchbox/pull/784))
* Include `contrib/k8s` in release tarballs ([#788](https://github.com/poseidon/matchbox/pull/788))
* Remove outdated systemd units ([#817](https://github.com/poseidon/matchbox/pull/817))
* Remove RPM spec file (Copr publishing stopped in v0.6)
## v0.8.3
* Publish docs to [https://matchbox.psdn.io](https://matchbox.psdn.io/) ([#769](https://github.com/poseidon/matchbox/pull/769))
* Update Go version from v1.11.7 to v1.13.4 ([#766](https://github.com/poseidon/matchbox/pull/766), [#770](https://github.com/poseidon/matchbox/pull/770))
* Update container image base from `alpine:3.9` to `alpine:3.10` ([#761](https://github.com/poseidon/matchbox/pull/761))
* Include `get-fedora-coreos` convenience script ([#763](https://github.com/poseidon/matchbox/pull/763))
* Remove rkt tutorials and docs ([#765](https://github.com/poseidon/matchbox/pull/765))
## v0.8.1 - v0.8.2
Releases `v0.8.1` and `v0.8.2` were not built cleanly
* Release tags and container images have been removed
* Caused by go get golint (module-aware) mutating `go.mod` on Travis (see [#775](https://github.com/poseidon/matchbox/pull/775), [#777](https://github.com/poseidon/matchbox/pull/777))
## v0.8.0
* Transfer Matchbox repo from coreos to poseidon GitHub Org
* Publish container images at [quay.io/poseidon/matchbox](https://quay.io/repository/poseidon/matchbox)
* Build Matchbox with Go v1.11.7 for images and binaries
* Update container image base from alpine:3.6 to alpine:3.9
* Render Container Linux Configs as Ignition v2.2.0
* Validate raw Ignition configs with the v2.2 spec (warn-only)
* Fix warnings that v2.2 configs are too new
Note: Release signing key [has changed](https://github.com/poseidon/matchbox/blob/v0.8.0/Documentation/deployment.md) with the project move.
### Examples
* Update Kubernetes example clusters to v1.14.1 (Terraform-based)
## v0.7.1 (2018-11-01)
* Add `kernel_args` variable to the terraform bootkube-install cluster definition
* Add `get-flatcar` helper script
* Add optional TLS support to read-only HTTP API
* Build Matchbox with Go 1.11.1 for images and binaries
### Examples
* Upgrade Kubernetes example clusters to v1.10.0 (Terraform-based)
* Upgrade Kubernetes example clusters to v1.8.5
## v0.7.0 (2017-12-12)
* Add gRPC API endpoints for managing generic (experimental) templates
* Update Container Linux config transpiler to v0.5.0
* Update Ignition to v0.19.0, render v2.1.0 Ignition configs
* Drop support for Container Linux versions below 1465.0.0 (breaking)
* Build Matchbox with Go 1.8.5 for images and binaries
* Remove Profile `Cmdline` map (deprecated in v0.5.0), use `Args` slice instead
* Remove pixiecore support (deprecated in v0.5.0)
* Remove `ContextHandler`, `ContextHandlerFunc`, and `NewHandler` from the `matchbox/http` package.
### Examples / Modules
* Upgrade Kubernetes example clusters to v1.8.4
* Kubernetes examples clusters enable etcd TLS
* Deploy the Container Linux Update Operator (CLUO) to coordinate reboots of Container Linux nodes in Kubernetes clusters. See the cluster [addon docs](Documentation/cluster-addons.md).
* Kubernetes examples (terraform and non-terraform) mask locksmithd
* Terraform modules `bootkube` and `profiles` (Kubernetes) mask locksmithd
## v0.6.1 (2017-05-25)
* Improve the installation documentation
* Move examples/etc/matchbox/cert-gen to scripts/tls
* Build Matchbox with Go 1.8.3 for images and binaries
### Examples
* Upgrade self-hosted Kubernetes cluster examples to v1.6.4
* Add NoSchedule taint to self-hosted Kubernetes controllers
* Remove static Kubernetes and rktnetes cluster examples
## v0.6.0 (2017-04-25)
* New [terraform-provider-matchbox](https://github.com/coreos/terraform-provider-matchbox) plugin for Terraform users!
* New hosted [documentation](https://coreos.com/matchbox/docs/latest) on coreos.com
* Add `ProfileDelete`, `GroupDelete`, `IgnitionGet` and `IgnitionDelete` gRPC endpoints
* Build matchbox with Go 1.8 for container images and binaries
* Generate code with gRPC v1.2.1 and matching Go protoc-gen-go plugin
* Update Ignition to v0.14.0 and coreos-cloudinit to v1.13.0
* Update "fuze" docs to the new name [Container Linux Configs](https://coreos.com/os/docs/latest/configuration.html)
* Remove `bootcmd` binary from release tarballs
### Examples
* Upgrade Kubernetes v1.5.5 (static) example clusters
* Upgrade Kubernetes v1.6.1 (self-hosted) example cluster
* Use etcd3 by default in all clusters (remove etcd2 clusters)
* Add Terraform examples for etcd3 and self-hosted Kubernetes 1.6.1
## v0.5.0 (2017-01-23)
* Rename project to CoreOS `matchbox`!
* Add Profile `args` field to list kernel args
* Update [Fuze](https://github.com/coreos/container-linux-config-transpiler) and [Ignition](https://github.com/coreos/ignition) to v0.11.2
* Switch from `golang.org/x/net/context` to `context`
* Deprecate Profile `cmd` field map of kernel args
* Deprecate Pixiecore support
* Drop build support for Go 1.6
#### Rename
* Move repo from github.com/coreos/coreos-baremetal to github.com/coreos/matchbox
* Rename `bootcfg` binary to `matchbox`
* Rename `bootcfg` packages to `matchbox`
* Publish a `quay.io/coreos/matchbox` container image. The `quay.io/coreos/bootcfg` image will no longer be updated.
* Rename environment variable prefix from `BOOTCFG*` to `MATCHBOX*`
* Change config directory to `/etc/matchbox`
* Change default `-data-path` to `/var/lib/matchbox`
* Change default `-assets-path` to `/var/lib/matchbox/assets`
#### Examples
* Upgrade Kubernetes v1.5.1 (static) example clusters
* Upgrade Kubernetes v1.5.1 (self-hosted) example cluster
* Switch Kubernetes (self-hosted) to run flannel as pods
* Combine rktnetes Ignition into Kubernetes static cluster
#### Migration
* binary users should install the `matchbox` binary (see [installation](Documentation/deployment.md))
* rkt/docker users should start using `quay.io/coreos/matchbox` (see [installation](Documentation/deployment.md))
* RPM users should uninstall bootcfg and install matchbox (see [installation](Documentation/deployment.md))
* Move `/etc/bootcfg` configs and certificates to `/etc/matchbox`
* Move `/var/lib/bootcfg` data to `/var/lib/matchbox`
* See the new [contrib/systemd](contrib/systemd) service examples
* Remove the old `bootcfg` user if you created one
## v0.4.2 (2016-12-7)
#### Improvements
* Add RPM packages to Copr
* Fix packaged `contrib/systemd` units
* Update Go version to 1.7.4
#### Examples
* Upgrade Kubernetes v1.4.6 (static manifest) example clusters
* Upgrade Kubernetes v1.4.6 (rktnetes) example clusters
* Upgrade Kubernetes v1.4.6 (self-hosted) example cluster
## v0.4.1 (2016-10-17)
#### Improvements
* Add ARM and ARM64 release architectures (#309)
* Add guide for installing bootcfg on CoreOS (#306)
* Improvements to the bootcfg cert-gen script (#310)
#### Examples
* Add Kubernetes example with rkt container runtime (i.e. rktnetes)
* Upgrade Kubernetes v1.4.1 (static manifest) example clusters
* Upgrade Kubernetes v1.4.1 (rktnetes) example clusters
* Upgrade Kubernetes v1.4.1 (self-hosted) example cluster
* Add etcd3 example cluster (PXE in-RAM or install to disk)
* Use DNS names (instead of IPs) in example clusters (except bootkube)
## v0.4.0 (2016-07-21)
#### Features
* Add/improve rkt, Docker, Kubernetes, and binary/systemd deployment docs
* TLS Client Authentication:
* Add gRPC API TLS and TLS client-to-server authentication (#140)
* Enable gRPC API by providing a TLS server `-cert-file` and `-key-file`, and a `-ca-file` to authenticate client certificates
* Provide the `bootcmd` tool a TLS client `-cert-file` and `-key-file`, and a `-ca-file` to verify the server identity.
* Improvements to Ignition Support:
* Allow Fuze YAML template files for Ignition 2.0.0 (#141)
* Stop requiring Ignition templates to use file extensions (#176)
* Logging Improvements:
* Add structured logging with Logrus (#254, #268)
* Log requests for bootcfg assets (#214)
* Show `bootcfg` message at the home path `/`
* Fix http package log messages (#173)
* Templating:
* Allow query parameters to be used as template variables as `{{.request.query.foo}}` (#182)
* Support nested maps in responses from the "env file" metadata endpoint (#84)
* Error when a template is rendered with variables which are missing a referenced key. Previously, missing lookups defaulted to "no value" (#210)
* gRPC API
* Add DialTimeout to gRPC client config (#273)
* Add IgnitionPut and Close to the client (#160,#193)
#### Changes
* gRPC API requires TLS client authentication
* Replace Ignition YAML templates with Fuze templates
- Fuze formalizes the transform from Fuze configs (YAML) to Ignition 2.0.0 (JSON)
- [Migrate templates from v0.3.0](Documentation/ignition.md#migration-from-v030)
- Require CoreOS 1010.1.0 or newer
- Drop support for Ignition v1 format
* Replace template variable `{{.query}}` with `{{.request.raw_query}}`
#### Examples
* Kubernetes
* Upgrade Kubernetes v1.3.0 (static manifest) example clusters
* Add Kubernetes v1.3.0-beta.2 (self-hosted) example cluster
* Mount /etc/resolv.conf into host kubelet for skydns and pod DNS lookups (#237,#260)
* Fix a bug in the k8s example k8s-certs@.service file check (#156)
* Avoid systemd dependency failures by restarting components (#257,#274)
- IRC: #[coreos](irc://irc.freenode.org:6667/#coreos) IRC channel on freenode.org
Please avoid emailing maintainers found in the MAINTAINERS file directly. They
are very busy and read the mailing lists.
## Getting Started
- Fork the repository on GitHub
- Read the [README](README.md) for build and test instructions
- Play with the project, submit bugs, submit patches!
## Contribution Flow
This is a rough outline of what a contributor's workflow looks like:
- Create a topic branch from where you want to base your work (usually master).
- Make commits of logical units.
- Make sure your commit messages are in the proper format (see below).
- Push your changes to a topic branch in your fork of the repository.
- Make sure the tests pass, and add any new tests as appropriate.
- Submit a pull request to the original repository.
Thanks for your contributions!
### Coding Style
CoreOS projects written in Go follow a set of style guidelines that we've documented
[here](https://github.com/coreos/docs/tree/master/golang). Please follow them when
working on your contributions.
### Format of the Commit Message
We follow a rough convention for commit messages that is designed to answer two
questions: what changed and why. The subject line should feature the what and
the body of the commit should describe the why.
```
scripts: add the test-cluster command
this uses tmux to setup a test cluster that you can easily kill and
start for debugging.
Fixes #38
```
The format can be described more formally as follows:
```
<subsystem>: <what changed>
<BLANK LINE>
<why this change was made>
<BLANK LINE>
<footer>
```
The first line is the subject and should be no longer than 70 characters, the
second line is always blank, and other lines should be wrapped at 80 characters.
This allows the message to be easier to read on GitHub as well as in various
git tools.
By contributing, you agree to the Linux Foundation's Developer Certificate of Origin ([DCO](DCO)). The DCO is a statement that you, the contributor, have the legal right to make your contribution and understand the contribution will be distributed as part of this project.
Serves a static iPXE boot script which gathers client machine attributes and chainloads to the iPXE endpoint. Configure your DHCP server or iPXE server to boot from this script.
Finds the profile matching the machine and renders the network boot config as JSON to implement the [Pixiecore API](https://github.com/danderson/pixiecore/blob/master/README.api.md). Currently, Pixiecore only provides the machine's MAC address for matching.
`bootcfg` is an HTTP and gRPC service that renders signed [Ignition configs](https://coreos.com/ignition/docs/latest/what-is-ignition.html), [cloud-configs](https://coreos.com/os/docs/latest/cloud-config.html), network boot configs, and metadata to machines to create CoreOS clusters. `bootcfg` maintains **Group** definitions which match machines to *profiles* based on labels (e.g. UUID, MAC address, stage, region). A **Profile** is a named set of config templates (e.g. iPXE, GRUB, Ignition config, Cloud-Config). The aim is to use CoreOS Linux's early-boot capabilities to provision CoreOS machines.
Network boot endpoints provide PXE, iPXE, GRUB, and [Pixiecore](https://github.com/danderson/pixiecore/blob/master/README.api.md) support. `bootcfg` can be deployed as a binary, as an [appc](https://github.com/appc/spec) container with rkt, or as a Docker container.
## Getting Started
Get started running `bootcfg` on your Linux machine, with rkt or Docker, to network boot virtual or physical machines into CoreOS clusters.
* [Getting Started with rkt](getting-started-rkt.md)
* [Getting Started with Docker](getting-started-docker.md)
## Flags
See [flags and variables](config.md)
## API
See [API](api.md)
## Data
A `Store` stores machine Profiles, Groups, Ignition configs, and cloud-configs. By default, `bootcfg` uses a `FileStore` to search a `-data-path` for these resources.
Prepare `/var/lib/bootcfg` with `profile`, `groups`, `ignition`, and `cloud` subdirectories. You may wish to keep these files under version control. The [examples](../examples) directory is a valid target with some pre-defined configs and templates.
/var/lib/bootcfg
├── cloud
│ ├── cloud.yaml
│ └── worker.sh
├── ignition
│ └── hello.json
│ └── etcd.yaml
│ └── simple_networking.yaml
├── groups
│ └── default.json
│ └── node1.json
│ └── us-central1-a.json
└── profiles
└── etcd.json
└── worker.json
Ignition templates can be JSON or YAML files (rendered as JSON). Cloud-Config templates can be a script or YAML file. Both may contain [Go template](https://golang.org/pkg/text/template/) elements which will be executed with machine Group [metadata](#groups-and-metadata). For details and examples:
* [Ignition Config](ignition.md)
* [Cloud-Config](cloud-config.md)
### Profiles
Profiles specify a Ignition config, Cloud-Config, and network boot config.
The `"boot"` settings will be used to render configs to network boot programs such as iPXE, GRUB, or Pixiecore. You may reference remote kernel and initrd assets or [local assets](#assets).
To use cloud-config, set the `cloud-config-url` kernel option to reference the `bootcfg` [Cloud-Config endpoint](api.md#cloud-config), which will render the `cloud_id` file.
To use Ignition, set the `coreos.config.url` kernel option to reference the `bootcfg` [Ignition endpoint](api.md#ignition-config), which will render the `ignition_id` file. Be sure to add the `coreos.first_boot` option as well.
## Groups and Metadata
Groups define selectors which match zero or more machines. Machine(s) matching a group will boot and provision according to the group's `Profile` and `metadata`.
Create a group definition with a `Profile` to be applied, selectors for matching machines, and any `metadata` needed to render the Ignition or Cloud config templates. For example `/var/lib/bootcfg/groups/node1.json` matches a single machine with MAC address `52:54:00:89:d8:10`.
For example, a request to `/ignition?mac=52:54:00:89:d8:10` would render the Ignition template in the "etcd" `Profile`, with the machine group's metadata. A request to `/ignition` would match the default group (which has no selectors) and render the Ignition in the "etcd-proxy" Profile. Avoid defining multiple default groups as resolution will not be deterministic.
### Reserved Labels
Some labels are normalized or parsed specially because they have reserved semantic purpose.
*`hostname` - hostname reported by a network boot program
*`serial` - serial reported by a network boot program
Client's booted with the `/ipxe.boot` endpoint will introspect and make a request to `/ipxe` with the `uuid`, `mac`, `hostname`, and `serial` value as query arguments. Pixiecore can only detect MAC addresss and cannot substitute it into later config requests ([issue](https://github.com/coreos/coreos-baremetal/issues/36)).
## Assets
`bootcfg` can serve `-assets-path` static assets at `/assets`. This is helpful for reducing bandwidth usage when serving the kernel and initrd to network booted machines. The default assets-path is `/var/lib/bootcfg/assets` or you can pass `-assets-path=""` to disable asset serving.
bootcfg.foo/assets/
└── coreos
└── VERSION
├── coreos_production_pxe.vmlinuz
└── coreos_production_pxe_image.cpio.gz
For example, a `Profile` might refer to a local asset `/assets/coreos/VERSION/coreos_production_pxe.vmlinuz` instead of `http://stable.release.core-os.net/amd64-usr/VERSION/coreos_production_pxe.vmlinuz`.
See the [get-coreos](../scripts/README.md#get-coreos) script to quickly download, verify, and place CoreOS assets.
## Network
`bootcfg` does not implement or exec a DHCP/TFTP server. Use the [coreos/dnsmasq](../contrib/dnsmasq) image if you need a quick DHCP, proxyDHCP, TFTP, or DNS setup.
**Note:** We recommend you migrate to [Ignition](https://coreos.com/blog/introducing-ignition.html).
CoreOS Cloud-Config is a system for configuring machines with a Cloud-Config file or executable script from user-data. Cloud-Config runs in userspace on each boot and implements a subset of the [cloud-init spec](http://cloudinit.readthedocs.org/en/latest/topics/format.html#cloud-config-data). See the cloud-config [docs](https://coreos.com/os/docs/latest/cloud-config.html) for details.
Cloud-Config template files can be added in `/var/lib/bootcfg/cloud` or in a `cloud` subdirectory of a custom `-data-path`. Template files may contain [Go template](https://golang.org/pkg/text/template/) elements which will be evaluated with Group `metadata` when served.
/var/lib/bootcfg
├── cloud
│ ├── cloud.yaml
│ └── script.sh
├── ignition
└── profiles
Reference a Cloud-Config in a [Profile](bootcfg.md#profiles). When PXE booting, use the kernel option `cloud-config-url` to point to `bootcfg` [cloud-config endpoint](api.md#cloud-config).
## Configs
Here is an example Cloud-Config which starts some units and writes a file.
#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: |
{{.greeting}}
### Examples
See [examples/cloud](../examples/cloud) for example Cloud-Config files.
### Validator
The Cloud-Config [Validator](https://coreos.com/validate/) is useful for checking your Cloud-Config files for errors.
## Comparison with Ignition
Cloud-Config starts after userspace has started, on every boot. Ignition starts before PID 1 and only runs on the first boot. Ignition favors immutable infrastructure.
Ignition is favored as the replacement for CoreOS Cloud-Config. Tasks often only need to be run once and can be performed more easily before systemd has started (e.g. configuring networking). Ignition can write service units for tasks that need to be run on each boot. Instead of depending on Cloud-Config variable substitution, Ignition favors using systemd's EnvironmentFile expansion to start units with a metadata file from a metadata source.
For local development, install the dependencies for libvirt with UEFI.
* [UEFI with QEMU](https://fedoraproject.org/wiki/Using_UEFI_with_QEMU)
## Application Container
Run the `bootcfg` ACI with rkt according to the [development docs](develop.md). Examples contains a [grub.yaml](../../examples/grub.yaml) config with a default machine group for GRUB net booting.
## Client VM
Create a VM with an e1000 or virtio network device.
Publish the signed binary tarball(s) and the signed ACI with the Github release. The Docker image is published to Quay.io when the tag is pushed to master.
In this tutorial, we'll run `bootcfg` on your Linux machine with Docker to network boot and provision a cluster of CoreOS machines locally. You'll be able to create Kubernetes clustes, etcd clusters, and test network setups.
If you're ready to try [rkt](https://coreos.com/rkt/docs/latest/), see [Getting Started with rkt](getting-started-rkt.md).
## Requirements
Install the package dependencies and start the Docker daemon.
# Fedora
sudo dnf install docker virt-install virt-manager
sudo systemctl start docker
# Debian/Ubuntu
# check Docker's docs to install Docker 1.8+ on Debian/Ubuntu
Download the CoreOS PXE image assets to `examples/assets`.
./scripts/get-coreos
./scripts/get-coreos channel version
## Containers
#### Latest
Run the latest Docker image from `quay.io/coreos/bootcfg` with the `etcd-docker` example. The container should receive the IP address 172.17.0.2 on the `docker0` bridge.
Take a look at the [etcd groups](../examples/groups/etcd-docker) to get an idea of how machines are mapped to Profiles. Explore some endpoints port mapped to localhost:8080.
Since the virtual network has no network boot services, use the `dnsmasq` image to create an iPXE network boot environment which runs DHCP, DNS, and TFTP.
In this case, dnsmasq runs a DHCP server allocating IPs to VMs between 172.17.0.43 and 172.17.0.99, resolves `bootcfg.foo` to 172.17.0.2 (the IP where `bootcfg` runs), and points iPXE clients to `http://bootcfg.foo:8080/boot.ipxe`.
## Client VMs
Create VM nodes which have known hardware attributes. The nodes will be attached to the `docker0` bridge where Docker's containers run.
sudo ./scripts/libvirt create-docker
sudo virt-manager
You can use `virt-manager` to watch the console and reboot VM machines with
sudo ./scripts/libvirt poweroff
sudo ./scripts/libvirt start
## Verify
The VMs should network boot and provision themselves into a three node etcd cluster, with other nodes behaving as etcd proxies.
The example profile added autologin so you can verify that etcd works between nodes.
systemctl status etcd2
etcdctl set /message hello
etcdctl get /message
fleetctl list-machines
Clean up the VM machines.
sudo ./scripts/libvirt poweroff
sudo ./scripts/libvirt destroy
## Going Further
Explore the [examples](../examples). Try the [k8s-docker example](../examples/groups/k8s-docker) to produce a TLS-authenticated Kubernetes cluster you can access locally with `kubectl` ([docs](../examples/README.md#kubernetes)).
Learn more about [bootcfg](bootcfg.md) or adapt an example for your own [physical hardware](physical-hardware.md) and network.
In this tutorial, we'll run `bootcfg` on your Linux machine with `rkt` and `CNI` to network boot and provision a cluster of CoreOS machines locally. You'll be able to create Kubernetes clustes, etcd clusters, and test network setups.
## Requirements
Install [rkt](https://github.com/coreos/rkt/releases) and [acbuild](https://github.com/appc/acbuild/releases) from the latest releases ([example script](https://github.com/dghubble/phoenix/blob/master/scripts/fedora/sources.sh)). Optionally setup rkt [privilege separation](https://coreos.com/rkt/docs/latest/trying-out-rkt.html).
**Note**: rkt does not yet integrate with SELinux on Fedora. As a workaround, temporarily set enforcement to permissive if you are comfortable (`sudo setenforce Permissive`). Check the rkt [distribution notes](https://github.com/coreos/rkt/blob/master/Documentation/distributions.md) or see the tracking [issue](https://github.com/coreos/rkt/issues/1727).
Clone the [coreos-baremetal](https://github.com/coreos/coreos-baremetal) source which contains the examples and scripts.
Note: The insecure flag is needed since [Quay.io](https://quay.io/repository/coreos/bootcfg) serves ACIs coverted from Docker images (docker2aci) and Docker images don't support signatures.
#### Release
Alternately, run the most recent tagged and signed [release](https://github.com/coreos/coreos-baremetal/releases). Trust the [CoreOS App Signing Key](https://coreos.com/security/app-signing-key/) for image signature verification.
If you get an error about the IP assignment, garbage collect old pods.
sudo rkt gc --grace-period=0
./scripts/rkt-gc-force # sometimes needed
Take a look at the [etcd groups](../examples/groups/etcd) to get an idea of how machines are mapped to Profiles. Explore some endpoints exposed by the service.
Since the virtual network has no network boot services, use the `dnsmasq` ACI to create an iPXE network boot environment which runs DHCP, DNS, and TFTP.
Trust the [CoreOS App Signing Key](https://coreos.com/security/app-signing-key/).
In this case, dnsmasq runs a DHCP server allocating IPs to VMs between 172.15.0.50 and 172.15.0.99, resolves `bootcfg.foo` to 172.15.0.2 (the IP where `bootcfg` runs), and points iPXE clients to `http://bootcfg.foo:8080/boot.ipxe`.
## Client VMs
Create VM nodes which have known hardware attributes. The nodes will be attached to the `metal0` bridge where your pods run.
sudo ./scripts/libvirt create-rkt
sudo virt-manager
You can use `virt-manager` to watch the console and reboot VM machines with
sudo ./scripts/libvirt poweroff
sudo ./scripts/libvirt start
## Verify
The VMs should network boot and provision themselves into a three node etcd cluster, with other nodes behaving as etcd proxies.
The example profile added autologin so you can verify that etcd works between nodes.
systemctl status etcd2
etcdctl set /message hello
etcdctl get /message
fleetctl list-machines
Press ^] three times to stop a rkt pod. Clean up the VM machines.
sudo ./scripts/libvirt poweroff
sudo ./scripts/libvirt destroy
## Going Further
Explore the [examples](../examples). Try the [k8s example](../examples/groups/k8s) to produce a TLS-authenticated Kubernetes cluster you can access locally with `kubectl` ([docs](../examples/README.md#kubernetes)).
Learn more about [bootcfg](bootcfg.md) or adapt an example for your own [physical hardware](physical-hardware.md) and network.
Ignition is a system for declaratively provisioning disks from the initramfs, before systemd starts. It runs only on the first boot and handles formatting partitioning, writing files (systemd units, networkd units, dropins, regular files), and configuring users. See the Ignition [docs](https://coreos.com/ignition/docs/latest/) for details.
Ignition template files can be added in the `/var/lib/bootcfg/ignition` directory or in an `ignition` subdirectory of a custom `-data-path`. Template files should contain Ignition JSON or YAML (which will be rendered as JSON) and may contain [Go template](https://golang.org/pkg/text/template/) elements which will be evaluated with Group `metadata` when served.
/var/lib/bootcfg
├── cloud
├── ignition
│ └── simple.json
│ └── etcd.yaml
│ └── etcd-proxy.yaml
│ └── networking.yaml
└── profiles
Reference an Ignition config in a [Profile](bootcfg.md#profiles). When PXE booting, use the kernel option `coreos.first_boot=1` and `coreos.config.url` to point to the `bootcfg` [Ignition endpoint](api.md#ignition-config).
## Configs
Here is an example Ignition config for static networking, which will be rendered, with metadata, into YAML and tranformed into machine-friendly JSON.
ignition/network.yaml:
---
ignition_version: 1
networkd:
units:
- name: 00-{{.networkd_name}}.network
contents: |
[Match]
Name={{.networkd_name}}
[Network]
Gateway={{.networkd_gateway}}
DNS={{.networkd_dns}}
DNS=8.8.8.8
Address={{.networkd_address}}
{{ if .ssh_authorized_keys }}
passwd:
users:
- name: core
ssh_authorized_keys:
{{ range $element := .ssh_authorized_keys }}
- {{$element}}
{{end}}
{{end}}
Response from `/ignition?mac=address` for a particular machine.
Note that rendered Ignition does **not** allow variables - the response has been fully rendered with `metadata` for the requesting machine.
Ignition configs can be provided directly as JSON as well. This is useful for simple cases or if you prefer to use your own templating solution to generate Ignition configs.
Physical machines [network boot](network-booting.md) in an network boot environment with DHCP/TFTP/DNS services or with [coreos/dnsmasq](../contrib/dnsmasq).
`bootcfg` serves iPXE, GRUB, or Pixiecore boot configs via HTTP to machines based on Group selectors (e.g. UUID, MAC, region, etc.) and machine Profiles. Kernel and initrd images are fetched and booted with Ignition to install CoreOS. The "first boot" Ignition config if fetched and CoreOS is installed.
CoreOS boots ("first boot" from disk) and runs Ignition to provision its disk with systemd units, files, keys, and more to become a cluster node. Systemd units may fetch metadata from a remote source if needed.
Coordinated auto-updates are enabled. Systems like [fleet](https://coreos.com/docs/#fleet) or [Kubernetes](http://kubernetes.io/docs/) coordinate container services. IPMI, vendor utilities, or first-boot are used to re-provision machines into new roles.
The `bootcfg` OpenPGP signature endpoints serve detached binary and ASCII armored signatures of rendered configs, if enabled. Each config endpoint has corresponding signature endpoints, typically suffixed with `.sig` or `.asc`.
To enable OpenPGP signing, provide the path to a secret keyring containing a single signing key with `-key-ring-path` or by setting `BOOTCFG_KEY_RING_PATH`. If a passphrase is required, set it via the `BOOTCFG_PASSPHRASE` environment variable.
Here are example signature endpoints without their query parameters.
In production, mount your signing keyring and source the passphrase from a [Kubernetes secret](http://kubernetes.io/v1.1/docs/user-guide/secrets.html). Use a signing subkey exported to a keyring by itself, which can be revoked by a primary key, if needed.
To try it locally, you may use the test fixture keyring. **Warning: The test fixture keyring is for examples only.**
## Verify
Verify a signature response and config response from the command line using the public key. Notice that most configs have a trailing newline.
**Warning: The test fixture keyring is for examples only.**
Create a signing key or subkey according to your requirements and security policies. Here are some basic [guides](https://coreos.com/rkt/docs/latest/signing-and-verification-guide.html).
Physical or baremetal hardware can be booted and configured with CoreOS by PXE, iPXE, and Pixiecore network environments. This guide will show how to setup and test network boot environments with physical clients.
DHCP, TFTP, and HTTP services can run on separate network hosts or on the same host in PXE network environments. We'll focus on configuring a single *provisioner* Linux host to run these services as containers.
## Requirements
Client hardware boot firmware must support PXE or iPXE and the client must have at least one PXE-capable network interface. Most boot firmware and network cards support PXE so you're probably ok.
## Inspect
Identify whether the network runs a DHCP service which can be configured or whether you'll need to run a proxyDHCP service. Check a host's routing table to find the gateway where DHCP is likely to be running.
route -n # e.g. Gateway 192.168.1.1
## bootcfg
Set up `bootcfg` according to the [docs](bootcfg.md). Pull the `coreos/bootcfg` image, prepare a data volume with `Machine` definitions, `Spec` definitions and ignition/cloud configs. Optionally, include a volume of downloaded image assets.
Run the `bootcfg` container to serve configs for any of the network environments we'll discuss next.
Note, the kernel options in the `Spec` [examples](../examples) reference 172.17.0.2 (the libvirt case). Your kernel cmdline options should reference the IP or DNS name where `bootcfg` runs.
## Network Setups
Your network may already have a configurable PXE or iPXE server, configurable DHCP, a DHCP server you cannot modify, or no DHCP server at all. We'll show how to setup each network environment to talk to `bootcfg`, depending on your circumstances.
Otherwise create a PXE, iPXE, or Pixiecore network boot environment using the CoreOS [dnsmasq](../contrib/dnsmasq) container image which can run DHCP, proxyDHCP, TFTP, and/or DNS with `dnsmasq`. Use `--net=host` to run the services on the host and use `--dhcp-boot` to point clients to `bootcfg`.
### Configurable iPXE
If your network environment already supports iPXE, edit your iPXE boot script to chainload from `bootcfg`
# boot.ipxe
chain http://192.168.1.100:8080/boot.ipxe
Substitute the name or IP and port where `bootcfg` runs.
### Configurable DHCP
If the DHCP server on your network is PXE-enabled and configurable, send the `bootcfg` iPXE endpoint as the boot filename option (e.g. `http://192.168.1.100:8080/boot.ipxe`). Substitute the name or IP and port where `bootcfg` runs.
Optionally, respond to older PXE client firmware with the location of the `undionly.kpxe` boot program on your TFTP server.
With `dnsmasq`, here is an example `dnsmasq.conf`
# dnsmasq.conf
dhcp-range=192.168.1.1,192.168.1.254,30m
enable-tftp
tftp-root=/var/lib/tftpboot
# set tag "ipxe" if request comes from iPXE ("iPXE" user class)
dhcp-userclass=set:ipxe,iPXE
# if PXE request came from regular firmware, serve iPXE firmware (via TFTP)
dhcp-boot=tag:!ipxe,undionly.kpxe
# if PXE request came from iPXE, serve an iPXE boot script (via HTTP)
If the network already runs a DHCP service, setup a PXE/iPXE network environment alongside it with proxyDHCP and TFTP.
Run DHCP in proxy mode to respond to DHCP requests on the subnet. Optionally, serve the `undionly.pxe` boot file to older, non-iPXE clients (the '#' means not). Detect iPXE clients by the user class sent in their DHCPDISCOVER (or by Option 175) and point them to the `bootcfg` iPXE boot script.
```
sudo docker run --net=host --rm --cap-add=NET_ADMIN quay.io/coreos/dnsmasq -d -q -i enp0s25 --dhcp-range=192.168.1.1,proxy,255.255.255.0 --enable-tftp --tftp-root=/var/lib/tftpboot --dhcp-userclass=set:ipxe,iPXE --pxe-service=tag:#ipxe,x86PC,"PXE chainload to iPXE",undionly.kpxe --pxe-service=tag:ipxe,x86PC,"iPXE",http://192.168.1.100:8080/boot.ipxe
```
Change the `dhcp-range`, `-i interface`, and boot.ipxe endpoint to match your environment.
In this example, an existing router at 192.168.1.1 runs DHCP to allocate IP addresses between 192.168.1.2 and 192.168.1.254. The proxyDHCP is configured to respond to disocver requests on the 192.168.1.0/24 subnet. `bootcfg` runs on host (192.168.1.100) to serve iPXE boot scripts.
### DHCP
If the network does not already run a DHCP service, you can run one yourself and provide PXE options to baremetal clients. This is the case if your baremetal machines are connected to an isolated switch.
Identify a host machine which should run the DHCP service. If this machine has two NICs, it can serve as a router, using one for the uplink connection and the other to connect to the subnet with baremetal clients.
Run DHCP to allocate IP address leases and TFTP to serve the `undionly.pxe` boot file to older, non-iPXE clients (the '#' means not). Point iPXE clients to the `bootcfg` iPXE boot script.
Change the `dhcp-range`, `-i interface`, and boot.ipxe endpoint to match your environment.
In this example, a DHCP server is configured to allocate IP addresses between 192.168.1.101 and 192.168.1.150. `bootcfg` runs on host (192.168.1.100) to serve iPXE boot scripts.
You may have to explicitly assign the interface (-i) a network address and mark the interface as up.
ip addr add 192.168.1.100/24 dev enp0s20u1
ip link set dev enp0s20u1 up
## Troubleshooting
See [troubleshooting](troubleshooting.md).
### Alternatives
If you prefer, [Debian](http://www.debian-administration.org/article/478/Setting_up_a_server_for_PXE_network_booting), [Fedora](https://docs.fedoraproject.org/en-US/Fedora/7/html/Installation_Guide/ap-pxe-server.html), and [Ubuntu](https://help.ubuntu.com/community/DisklessUbuntuHowto) provide guides on PXE server setups. CoreOS-baremetal also includes [Vagrantfiles](vagrant) to quickly setup example Fedora PXE, iPXE, and Pixiecore servers on libvirt.
Running DHCP or proxyDHCP with `coreos/dnsmasq` on a host requires that the Firewall allow DHCP and TFTP (for chainloading) services to run.
## Port Collision
Running DHCP or proxyDHCP can cause port already in use collisions depending on what's running. Fedora runs bootp listening on udp/67 for example. Find the service using the port.
sudo lsof -i :67
Evaluate whether you can configure the existing service or whether you'd like to stop it and test with `coreos/dnsmasq`.
## No boot filename received
PXE client firmware did not receive a DHCP Offer with PXE-Options after several attempts. If you're using the `coreos/dnsmasq` image with `-d`, each request should log to stdout. Using the wrong `-i` interface is the most common reason DHCP requests are not received. Otherwise, wireshark can be useful for investigating.
`matchbox` is a service that matches bare-metal machines to profiles that PXE boot and provision clusters. Machines are matched by labels like MAC or UUID during PXE and profiles specify a kernel/initrd, iPXE config, and Ignition config.
[](https://travis-ci.org/coreos/coreos-baremetal) [](https://godoc.org/github.com/coreos/coreos-baremetal) [](https://quay.io/repository/coreos/bootcfg)
## Features
CoreOS on Baremetal provides guides and a service for network booting and provisioning CoreOS clusters on virtual or physical hardware.
* Chainload via iPXE and match hardware labels
* Provision Fedora CoreOS or Flatcar Linux (powered by [Ignition](https://github.com/coreos/ignition))
* Authenticated gRPC API for clients (e.g. Terraform)
`bootcfg` is an HTTP and gRPC service that renders signed [Ignition configs](https://coreos.com/ignition/docs/latest/what-is-ignition.html), [cloud-configs](https://coreos.com/os/docs/latest/cloud-config.html), network boot configs, and metadata to machines to create CoreOS clusters. Groups match machines based on labels (e.g. UUID, MAC, stage, region) and use named Profiles for provisioning. Network boot endpoints provide PXE, iPXE, GRUB, and Pixiecore support. `bootcfg` can be deployed as a binary, as an [appc](https://github.com/appc/spec) container with [rkt](https://coreos.com/rkt/docs/latest/), or as a Docker container.
Matchbox can be installed from a binary or a container image.
*[Getting Started with rkt](Documentation/getting-started-rkt.md)
*[Getting Started with Docker](Documentation/getting-started-docker.md)
*Install Matchbox as a [binary](docs/deployment.md#matchbox-binary), as a [container image](docs/deployment.md#container-image), or on [Kubernetes](docs/deployment.md#kubernetes)
*Setup a PXE-enabled [network](docs/network-setup.md)
### Examples
## Tutorials
Check the [examples](examples) to find Profiles for booting and provisioning machines into higher-order CoreOS clusters. Network boot [libvirt](scripts/README.md#libvirt) VMs to try the examples on your Linux laptop.
Start provisioning machines with Fedora CoreOS or Flatcar Linux.
*Multi-node Kubernetes cluster with TLS (network booted or installed to disk)
*Multi-node etcd cluster (network booted or installed to disk)
*Multi-stage CoreOS installs
*GRUB Netboot CoreOS
* iPXE Boot CoreOS with a root fs
* iPXE Boot CoreOS
*[Terraform Usage](docs/getting-started.md)
*Fedora CoreOS (PXE install to disk)
*Flatcar Linux (PXE install to disk)
*[Local QEMU/KVM](docs/getting-started-docker.md)
* Fedora CoreOS (live PXE or PXE install to disk)
* Flatcar Linux (live PXE or PXE install to disk)
## Contrib
* [dnsmasq](contrib/dnsmasq/README.md) - Run DHCP, TFTP, and DNS services as a container
* [terraform-provider-matchbox](https://github.com/poseidon/terraform-provider-matchbox) - Terraform provider plugin for Matchbox
[](https://quay.io/repository/coreos/dnsmasq)
Moved to [dnsmasq](https://github.com/poseidon/dnsmasq).
`dnsmasq` provides an App Container Image (ACI) or Docker image for running DHCP, proxy DHCP, DNS, and/or TFTP with [dnsmasq](http://www.thekelleys.org.uk/dnsmasq/doc.html) in a container/pod. Use it to test different network setups with clusters of network bootable machines.
The image bundles `undionly.kpxe` which chainloads PXE clients to iPXE and `grub.efi` (experimental) which chainloads UEFI architectures to GRUB2.
docker run quay.io/coreos/dnsmasq --cap-add=NET_ADMIN
## Configuration Flags
Configuration arguments can be provided at the command line. Check the dnsmasq [man pages](http://www.thekelleys.org.uk/dnsmasq/docs/dnsmasq-man.html) for a complete list, but here are some important flags.
| flag | description | example |
|----------|-------------|---------|
| -dhcp-range | Enable DHCP, lease given range | `172.15,0.50,172.15.0.99`, `192.168.1.1,proxy,255.255.255.0` |
| --dhcp-boot | DHCP next server option | `http://bootcfg.foo:8080/boot.ipxe` |
| --enable-tftp | Enable serving from tftp-root over TFTP | NA |
| --address | IP address for a domain name | /bootcfg.foo/172.15.0.2 |
## ACI
Build a `dnsmasq` ACI with the build script which uses [acbuild](https://github.com/appc/acbuild).
cd contrib/dnsmasq
./get-tftp-files
sudo ./build-aci
Run `dnsmasq.aci` with rkt to run DHCP/proxyDHCP/TFTP/DNS services.
Serves a static iPXE boot script which gathers client machine attributes and chainloads to the iPXE endpoint. Use DHCP/TFTP to point iPXE clients to this endpoint as the next-server.
```
GET http://matchbox.foo/boot.ipxe
GET http://matchbox.foo/boot.ipxe.0 // for dnsmasq
Client's booted with the `/ipxe.boot` endpoint will introspect and make a request to `/ipxe` with the `uuid`, `mac`, `hostname`, and `serial` value as query arguments.
## iPXE
Finds the profile for the machine and renders the network boot config (kernel, options, initrd) as an iPXE script.
Finds the profile for the machine and renders the network boot config as a GRUB config. Use DHCP/TFTP to point GRUB clients to this endpoint as the next-server.
Migrate to [Ignition configs](ignition.md). Cloud-Config support will be removed in the future.
CoreOS Cloud-Config is a system for configuring machines with a Cloud-Config file or executable script from user-data. Cloud-Config runs in userspace on each boot and implements a subset of the [cloud-init spec](http://cloudinit.readthedocs.org/en/latest/topics/format.html#cloud-config-data). See the cloud-config [docs](https://coreos.com/os/docs/latest/cloud-config.html) for details.
Cloud-Config template files can be added in `/var/lib/matchbox/cloud` or in a `cloud` subdirectory of a custom `-data-path`. Template files may contain [Go template](https://golang.org/pkg/text/template/) elements which will be evaluated with group metadata, selectors, and query params.
```
/var/lib/matchbox
├── cloud
│ ├── cloud.yaml
│ └── script.sh
├── ignition
└── profiles
```
## Reference
Reference a Cloud-Config in a [Profile](matchbox.md#profiles) with `cloud_id`. When PXE booting, use the kernel option `cloud-config-url` to point to `matchbox` [cloud-config endpoint](api-http.md#cloud-config).
## Examples
Here is an example Cloud-Config which starts some units and writes a file.
```yaml
#cloud-config
coreos:
units:
- name:etcd2.service
command:start
write_files:
- path:"/home/core/welcome"
owner:"core"
permissions:"0644"
content:|
{{.greeting}}
```
The Cloud-Config [Validator](https://coreos.com/validate/) is also useful for checking your Cloud-Config files for errors.
## Comparison with Ignition
Cloud-Config starts after userspace has started, on every boot. Ignition starts before PID 1 and only runs on the first boot. Ignition favors immutable infrastructure.
Ignition is favored as the replacement for CoreOS Cloud-Config. Tasks often only need to be run once and can be performed more easily before systemd has started (e.g. configuring networking). Ignition can write service units for tasks that need to be run on each boot. Instead of depending on Cloud-Config variable substitution, Ignition favors using systemd's EnvironmentFile expansion to start units with a metadata file from a metadata source.
The gRPC API allows clients with a TLS client certificate and key to make RPC requests to programmatically create or update `matchbox` resources. The API can be enabled with the `-rpc-address` flag and by providing a TLS server certificate and key with `-cert-file` and `-key-file` and a CA certificate for authenticating clients with `-ca-file`.
Run the binary with TLS credentials from `examples/etc/matchbox`.
Clients, such as `bootcmd`, verify the server's certificate with a CA bundle passed via `-ca-file` and present a client certificate and key via `-cert-file` and `-key-file` to cal the gRPC API.
This guide walks through deploying the `matchbox` service on a Linux host (as a binary or container image) or on a Kubernetes cluster.
## Provisoner
Matchbox is a service for network booting and provisioning machines to create Fedora CoreOS or Flatcar Linux clusters. Matchbox may installed on a host server or Kubernetes cluster that can serve configs to client machines in a lab or datacenter.
Choose one of the supported installation options:
* [Matchbox binary](#matchbox-binary)
* [Container image](#container-image)
* [Kubernetes manifests](#kubernetes)
## Download
Download the latest Matchbox [release](https://github.com/poseidon/matchbox/releases).
Verify the release has been signed by Dalton Hubble's GPG [Key](https://keyserver.ubuntu.com/pks/lookup?search=0x8F515AD1602065C8&op=vindex)'s signing subkey.
gpg: Good signature from "Dalton Hubble <dghubble@gmail.com>"
```
Untar the release.
```sh
$ tar xzvf matchbox-v0.10.0-linux-amd64.tar.gz
$ cd matchbox-v0.10.0-linux-amd64
```
## Install
Run Matchbox as a binary, a container image, or on Kubernetes.
### Matchbox Binary
Pre-built binaries are available for generic Linux distributions. Copy the `matchbox` static binary to an appropriate location on the host.
```sh
$ sudo cp matchbox /usr/local/bin
```
#### Set up User/Group
The `matchbox` service should be run by a non-root user with access to the `matchbox` data directory (`/var/lib/matchbox`). Create a `matchbox` user and group.
Customize Matchbox by editing the systemd unit or adding a systemd dropin. Find the complete set of `matchbox` flags and environment variables at [config](config.md).
```sh
$ sudo systemctl edit matchbox
```
By default, the read-only HTTP machine endpoint will be exposed on port **8080**.
Create machine profiles, groups, or Ignition configs by adding files to `/var/lib/matchbox`.
### Kubernetes
Install Matchbox on a Kubernetes cluster with the example manifests.
```sh
$ kubectl apply -R -f contrib/k8s
$ kubectl get services
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
matchbox 10.3.0.145 <none> 8080/TCP,8081/TCP 46m
```
Example manifests in [contrib/k8s](../contrib/k8s) enable the gRPC API to allow client apps to update matchbox objects. Generate TLS server certificates for `matchbox-rpc.example.com` [as shown](#generate-tls-certificates) and create a Kubernetes secret. Alternately, edit the example manifests if you don't need the gRPC API enabled.
Create an Ingress resource to expose the HTTP read-only and gRPC API endpoints. The Ingress example requires the cluster to have a functioning [Nginx Ingress Controller](https://github.com/kubernetes/ingress).
The Matchbox gRPC API allows clients (terraform-provider-matchbox) to create and update Matchbox resources. TLS credentials are needed for client authentication and to establish a secure communication channel. Client machines (those PXE booting) read from the HTTP endpoints and do not require this setup.
The `cert-gen` helper script generates a self-signed CA, server certificate, and client certificate. **Prefer your organization's PKI, if possible**
Navigate to the `scripts/tls` directory.
```sh
$ cd scripts/tls
```
Export `SAN` to set the Subject Alt Names which should be used in certificates. Provide the fully qualified domain name or IP (discouraged) where Matchbox will be installed.
For large production environments, use a cache proxy or mirror suitable for your environment to serve images.
## Network
Review [network setup](https://github.com/poseidon/matchbox/blob/master/docs/network-setup.md) with your network administrator to set up DHCP, TFTP, and DNS services on your network. At a high level, your goals are to:
* Chainload PXE firmwares to iPXE
* Point iPXE client machines to the `matchbox` iPXE HTTP endpoint `http://matchbox.example.com:8080/boot.ipxe`
* Ensure `matchbox.example.com` resolves to your `matchbox` deployment
Poseidon provides [dnsmasq](https://github.com/poseidon/matchbox/tree/master/contrib/dnsmasq) as `quay.io/poseidon/dnsmasq`.
# TLS
Matchbox can serve the read-only HTTP API with TLS.
| Name | Type | Description |
|----------------|--------|-------------|
| -web-ssl | bool | true/false |
| -web-cert-file | string | Path to the server TLS certificate file |
| -web-key-file | string | Path to the server TLS key file |
However, it is more common to use an Ingress Controller (Kubernetes) to terminate TLS.
### Operational notes
* Secrets: Matchbox **can** be run as a public facing service. However, you **must** follow best practices and avoid writing secret material into machine user-data. Instead, load secret materials from an internal secret store.
* Storage: Example manifests use Kubernetes `emptyDir` volumes to store `matchbox` data. Swap those out for a Kubernetes persistent volume if available.
In this tutorial, we'll run `matchbox` on a Linux machine with Docker to network boot and provision local QEMU/KVM machines as Fedora CoreOS or Flatcar Linux machines. You'll be able to test network setups and Ignition provisioning.
!!! note
To provision physical machines, see [network setup](network-setup.md) and [deployment](deployment.md).
## Requirements
Install the package dependencies and start the Docker daemon.
For development convenience, add `/etc/hosts` entries for nodes so they may be referenced by name.
```sh
# /etc/hosts
...
172.17.0.21 node1.example.com
172.17.0.22 node2.example.com
172.17.0.23 node3.example.com
```
## Containers
Run the `matchbox` and `dnsmasq` services on the `docker0` bridge. `dnsmasq` will run DHCP, DNS and TFTP services to create a suitable network boot environment. `matchbox` will serve configs to machines as they PXE boot.
The `devnet` convenience script can start these services and accepts the name of any example in [examples](https://github.com/poseidon/matchbox/tree/master/examples).
```sh
$ sudo ./scripts/devnet create fedora-coreos
```
Inspect the logs.
```
$ sudo ./scripts/devnet status
```
Inspect the examples and Matchbox endpoints to see how machines (e.g. node1 with MAC `52:54:00:a1:9c:ae`) are mapped to Profiles, and therefore iPXE and Ignition configs.
In this tutorial, we'll use `matchbox` with Terraform to provision Fedora CoreOS or Flatcar Linux machines.
We'll install the `matchbox` service, setup a PXE network boot environment, and use Terraform configs to declare infrastructure and apply resources on `matchbox`.
## matchbox
Install `matchbox` on a host server or Kubernetes cluster. Generate TLS credentials and enable the gRPC API as directed. Save the `ca.crt`, `client.crt`, and `client.key` on your local machine (e.g. `~/.matchbox`).
* Installing on a [Linux distro](deployment.md)
* Installing on [Kubernetes](deployment.md#kubernetes)
* Running with [docker](deployment.md#docker)
Verify the matchbox read-only HTTP endpoints are accessible.
```sh
$ curl http://matchbox.example.com:8080
matchbox
```
Verify your TLS client certificate and key can be used to access the gRPC API.
Select from the Terraform [examples](https://github.com/poseidon/matchbox/tree/master/examples/terraform). For example,
*`fedora-coreos-install` - PXE boot, install Fedora CoreOS to disk, reboot, and machines come up with your SSH authorized key set
*`flatcar-install` - PXE boot, install Flatcar Linux to disk, reboot, and machines come up with your SSH authorized key set
These aren't exactly full clusters, but they show declarations and network provisioning.
```sh
$ cd fedora-coreos-install # or flatcar-install
```
!!! note
Fedora CoreOS images are only served via HTTPS, so your iPXE firmware must be compiled to support HTTPS downloads.
Let's review the terraform config and learn a bit about Matchbox.
### Provider
Matchbox is configured as a provider platform for bare-metal resources.
```tf
// Configure the matchbox provider
provider"matchbox"{
endpoint=var.matchbox_rpc_endpoint
client_cert=file("~/.matchbox/client.crt")
client_key=file("~/.matchbox/client.key")
ca=file("~/.matchbox/ca.crt")
}
terraform{
required_providers{
ct={
source="poseidon/ct"
version="0.10.0"
}
matchbox={
source="poseidon/matchbox"
version="0.5.0"
}
}
}
```
### Profiles
Machine profiles specify the kernel, initrd, kernel args, Ignition Config, or other configs (e.g. templated Butane Config, generic) used to network boot and provision a bare-metal machine. The profile below would PXE boot machines using a Fedora CoreOS kernel and initrd (see [assets](api-http.md#assets) to learn about caching for speed), perform a disk install, reboot (first boot from disk), and use a [Fedora CoreOS Config](https://github.com/coreos/fcct/blob/master/docs/configuration-v1_1.md) to generate an Ignition config to provision.
"--name main https://builds.coreos.fedoraproject.org/prod/streams/${var.os_stream}/builds/${var.os_version}/x86_64/fedora-coreos-${var.os_version}-live-initramfs.x86_64.img"
Matcher groups match machines based on labels like MAC, UUID, etc. to different profiles and templates in machine-specific values. The group below does not have a `selector` block, so any machines which network boot from Matchbox will match this group and be provisioned using the `fedora-coreos-install` profile. Machines are matched to the most specific matching group.
Some Terraform [variables](https://www.terraform.io/docs/configuration/variables.html) are used in the examples. A quick way to set their value is by creating a `terraform.tfvars` file.
Matchbox can integrate with many on-premise network setups. It does not seek to be the DHCP server, TFTP server, or DNS server for the network. Instead, matchbox serves iPXE scripts as the entrypoint for provisioning network booted machines. PXE clients are supported by chainloading iPXE firmware.
In the simplest case, an iPXE-enabled network can chain to Matchbox,
```
# /var/www/html/ipxe/default.ipxe
chain http://matchbox.foo:8080/boot.ipxe
```
Read [network-setup.md](network-setup.md) for the complete range of options. Network admins have a great amount of flexibility:
* May keep using existing DHCP, TFTP, and DNS services
* May configure subnets, architectures, or specific machines to delegate to matchbox
* May place matchbox behind a menu entry (timeout and default to matchbox)
If you've never setup a PXE-enabled network before or you're trying to setup a home lab, checkout the [quay.io/poseidon/dnsmasq](https://quay.io/repository/poseidon/dnsmasq) container image [copy-paste examples](https://github.com/poseidon/matchbox/blob/master/docs/network-setup.md#poseidondnsmasq) and see the section about [proxy-DHCP](https://github.com/poseidon/matchbox/blob/master/docs/network-setup.md#proxy-dhcp).
## Boot
Its time to network boot your machines. Use the BMC's remote management capabilities (may be vendor-specific) to set the boot device (on the next boot only) to PXE and power on each machine.
```sh
$ ipmitool -H node1.example.com -U USER -P PASS power off
$ ipmitool -H node1.example.com -U USER -P PASS power on
```
Each machine should chainload iPXE, delegate to Matchbox, receive its iPXE config (or other supported configs) and begin the provisioning process. The examples assume machines are configured to boot from disk first and PXE only when requested, but you can write profiles for different cases.
Once the install completes and the machine reboots, you can SSH.
```ssh
$ ssh core@node1.example.com
```
To re-provision the machine for another purpose, run `terraform apply` and PXE boot machines again.
## Going Further
Matchbox can be used to provision multi-node Fedora CoreOS or Flatcar Linux clusters at one or many on-premise sites if deployed in an HA way. Machines can be matched individually by MAC address, UUID, region, or other labels you choose. Installs can be made much faster by caching images in the built-in HTTP [assets](api-http.md#assets) server.
[Ignition](https://github.com/coreos/ignition) can be used to partition disks, create file systems, write systemd units, write networkd configs or regular files, and create users. Nodes can be network provisioned into a complete cluster system that meets your needs. For example, see [Typhoon](https://typhoon.psdn.io/fedora-coreos/bare-metal/).
For local development, install the dependencies for libvirt with UEFI.
* [UEFI with QEMU](https://fedoraproject.org/wiki/Using_UEFI_with_QEMU)
Ensure that you've gone through the [matchbox with docker](getting-started-docker.md) and [matchbox](matchbox.md) guides and understand the basics.
## Containers
Run `matchbox` according to [matchbox with Docker](getting-started-docker.md), but mount the [grub](../examples/groups/grub) group example. Then start the `poseidon/dnsmasq` Docker image, which bundles a `grub.efi`.
[Ignition](https://coreos.github.io/ignition/) configs define how disks should be provisioned (on network boot and first-boot from disk) to partition disks, write files (regular files, systemd units, networkd units, etc.), and configure users. Ignition is used by:
* Fedora CoreOS
* RHEL CoreOS
* Flatcar Linux
See the Ignition Config v3.x [specs](https://coreos.github.io/ignition/specs/) for details.
## Usage
Ignition configs can be added to the `/var/lib/matchbox/ignition` directory or in an `ignition` subdirectory of a custom `-data-path`. Ignition configs must end in `.ign` or `ignition`.
```
/var/lib/matchbox
├── ignition
│ └── k8s-controller.ign
│ └── k8s-worker.ign
└── profiles
```
Matchbox Profiles can set an Ignition config for provisioning machines. Specify the Ignition config in a [Profile](matchbox.md#profiles) with `ignition_id`.
```json
{
"id":"worker",
"name":"My Profile",
"boot":{
...
},
"ignition_id":"my-ignition.ign"
}
```
When PXE booting, set kernel arguments depending on the OS (e.g. `ignition.firstboot` on FCOS, `flatcar.first_boot=yes` on Flatcar).
Point the `ignition.config.url` or `flatcar.config.url` to point to the `matchbox` [Ignition endpoint](api-http.md#ignition-config).
Matchbox parses Ignition configs (e.g. `.ign` or `.ignition`) at spec v3.3 or below and renders to the current supported version (v3.3). This relies on Ignition's [forward compatibility](https://github.com/coreos/ignition/blob/main/config/v3_3/config.go#L61).
## Writing Configs
Ignition configs can be prepared externally and loaded via the gRPC API, rather than writing Ignition by hand.
### Terraform
Terraform can be used to prepare Ignition configs, while providing integrations with external systems and rich templating. Using tools like [poseidon/terraform-provider-ct](https://github.com/poseidon/terraform-provider-ct), you can write Butane config (an easier YAML format), validate configs, and load Ignition into Matchbox ([examples](https://github.com/poseidon/matchbox/tree/main/examples/terraform)).
Define a Butane config for Fedora CoreOS or Flatcar Linux:
```yaml
variant:fcos
version:1.5.0
passwd:
users:
- name:core
ssh_authorized_keys:
- ssh-key foo
```
```yaml
variant:flatcar
version:1.1.0
passwd:
users:
- name:core
ssh_authorized_keys:
- ssh-key foo
```
Define a `ct_config` data source with strict validation. Optionally use Terraform [templating](https://github.com/poseidon/terraform-provider-ct).
```tf
data"ct_config""worker"{
content=file("worker.yaml")
strict=true
pretty_print=false
snippets=[
file("units.yaml"),
file("storage.yaml"),
]
}
```
Then render the Butane config to Ignition and use it in a Matchbox Profile.
See the Terraform [examples](https://github.com/poseidon/matchbox/tree/main/examples#terraform-examples) for details.
### Butane
The [Butane](https://coreos.github.io/butane/) command line tool can be used to convert Butane configs (an easier YAML format) to Ignition. Then you can use the Matchbox gRPC API to upload the rendered Ignition to Matchbox for serving to machines on boot.
See [examples/ignition](../examples/ignition) for Butane config examples.
### Matchbox Rendering
While Matchbox recommends preparing Ignition configs externally (e.g. using Terraform's rich templating), Matchbox does still support limited templating and translation features with a builtin Butane converter.
Specify a Butane config in a [Profile](matchbox.md#profiles) with `ignition_id` (file must not end in `.ign` or `.ignition`).
```json
{
"id":"worker",
"name":"My Profile",
"boot":{
...
},
"ignition_id":"butane.yaml"
}
```
Here is an example Butane config with Matchbox template elements. Template files may contain [Go template](https://golang.org/pkg/text/template/) elements which will be interpreted using group metadata, selectors, and query params.
```yaml
variant:flatcar
version:1.1.0
storage:
files:
- path:/var/home/core/foo
mode:0644
contents:
inline:|
{{.example_contents}}
{{if index . "ssh_authorized_keys" }}
passwd:
users:
- name:core
ssh_authorized_keys:
{{range $element := .ssh_authorized_keys }}
- {{$element}}
{{end}}
{{end}}
```
Matchbox will use the Butane library to config to the current supported Ignition version. This relies on Ignition's [forward compatibility](https://github.com/coreos/ignition/blob/main/config/v3_3/config.go#L61).
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.