diff --git a/docs/user-guide/src/SUMMARY.md b/docs/user-guide/src/SUMMARY.md index 2a531e8f..e87bb5bd 100644 --- a/docs/user-guide/src/SUMMARY.md +++ b/docs/user-guide/src/SUMMARY.md @@ -34,6 +34,8 @@ - [Install Ironic](ironic/ironic_installation.md) - [Ironic python agent](ironic/ironic-python-agent.md) - [Ironic container images](ironic/ironic-container-images.md) + - [Ironic Standalone Operator](irso/introduction.md) + - [Install Ironic with IrSO](irso/install-basics.md) - [Cluster-api-provider-metal3](capm3/introduction.md) - [Install MetalĀ³ provider](capm3/installation_guide.md) - [Features](capm3/features.md) diff --git a/docs/user-guide/src/irso/install-basics.md b/docs/user-guide/src/irso/install-basics.md new file mode 100644 index 00000000..bdc520b3 --- /dev/null +++ b/docs/user-guide/src/irso/install-basics.md @@ -0,0 +1,162 @@ +# Installing Ironic + +This document covers installing Ironic in different scenarios. You need to +answer a few questions before you can pick the one that suits you: + +- Which physical network interface will be used for provisioning? Without any + configuration, Ironic will use the host cluster networking. + +- If you use a dedicated network interface, are you going to use the built-in + Keepalived service to configure the IP address on the control plane node + where the Ironic pod is located? If not, you need to make sure the interface + has a usable address on this node. + +- Do you want to use network boot (iPXE) during provisioning? DHCP adds more + requirements and requires explicit configuration. Without it, only virtual + media provisioning is possible (see [supported + hardware](../bmo/supported_hardware.md)). + +- Are you going to use TLS for the Ironic API? It is not recommended to run + without TLS. To enable it, you need to manage the TLS secret. [Cert + Manager](https://cert-manager.io/) is the recommended service for it. + +## Using Ironic + +Regardless of the scenario you choose, you will need to create at least an +`Ironic` object and wait for it to become ready: + +```bash +NAMESPACE="test-ironic" # change to match your deployment +kubectl create -f ironic.yaml +kubectl wait --for=condition=Ready --timeout="10m" -n "$NAMESPACE" ironic/ironic +``` + +If the resource does not become `Ready`, check its status and the status of the +corresponding `Deployment`. + +Once it is ready, get the credentials from the associated secret, e.g. with + +```bash +SECRET=$(kubectl get ironic/ironic -n "$NAMESPACE" --template={{.spec.apiCredentialsName}}) +USERNAME=$(kubectl get secrets/$SECRET -n "$NAMESPACE" --template={{.data.username}} | base64 -d) +PASSWORD=$(kubectl get secrets/$SECRET -n "$NAMESPACE" --template={{.data.password}} | base64 -d) +``` + +Now you can point BMO at the Ironic's service at `ironic.test-ironic.svc`. + +## Scenario 1: no network boot, no dedicated networking + +In this scenario, Ironic will use whatever networking is used by the cluster. +No DHCP will be available, bare-metal machines will be provisioned using +virtual media. Since there is no dedicated network interface, Keepalived is +also not needed. + +It is enough to create the following resource: + +```yaml +apiVersion: ironic.metal3.io/v1alpha1 +kind: Ironic +metadata: + name: ironic + namespace: test-ironic +spec: + version: "27.0" +``` + +**HINT:** there is need to configure API credentials: IrSO will generate a +random password for you. + +However, there is one option that you might want to set in all scenarios: the +public SSH key for the ramdisk. Configuring it allows an easier debugging if +anything goes wrong during provisioning. + +```yaml +apiVersion: ironic.metal3.io/v1alpha1 +kind: Ironic +metadata: + name: ironic + namespace: test-ironic +spec: + deployRamdisk: + sshKey: "ssh-ed25519 AAAAC3..." + version: "27.0" +``` + +**WARNING:** the provided SSH key will **not** be installed on the machines +deployed by Ironic. See [instance +customization](../bmo/instance_customization.md) instead. + +## Scenario 2: dedicated networking and TLS + +In this scenario, a separate network interface is used (`em2` in the example). +The IP address on the interface will be managed by Keepalived, and the Ironic +API will be secured by TLS. + +To make TLS work without resorting to insecure configuration, the certificate +must contain the DNS name derived from the service (e.g. +`ironic.test-ironic.svc`), as well as the provided IP address (`192.0.2.1` in +this example). + +For simplicity, lets use the openssl CLI to generate a self-signed certificate +(use something like Cert Manager in production): + +```console +openssl req -x509 -new -subj "/CN=ironic.test-ironic.svc" \ + -addext "subjectAltName = DNS:ironic.test-ironic.svc,IP:192.0.2.1" \ + -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 -nodes \ + -keyout ironic-tls.key -out ironic-tls.crt +kubectl create secret tls ironic-tls -n test-ironic --key=ironic-tls.key --cert=ironic-tls.crt +``` + +**NOTE:** without a dedicated interface we would have to add all cluster IP +addresses to the certificate, which is often not desired. + +Now you can create your Ironic deployment: + +```yaml +apiVersion: ironic.metal3.io/v1alpha1 +kind: Ironic +metadata: + name: ironic + namespace: test-ironic +spec: + deployRamdisk: + sshKey: "ssh-ed25519 AAAAC3..." + networking: + interface: "em2" + ipAddress: "192.0.2.1" + ipAddressManager: keepalived + tls: + certificateName: ironic-tls + version: "27.0" +``` + +Now you can access Ironic either via the service or at `192.0.2.1:6385`. + +## Scenario 3: dedicated networking with DHCP and Keepalived + +In this scenario, network booting will be available on the dedicated network +interface. Assuming the network CIDR is `192.0.2.0/24`: + +```yaml +apiVersion: ironic.metal3.io/v1alpha1 +kind: Ironic +metadata: + name: ironic + namespace: test-ironic +spec: + deployRamdisk: + sshKey: "ssh-ed25519 AAAAC3..." + networking: + dhcp: + networkCIDR: "192.0.2.0/24" + interface: "em2" + ipAddress: "192.0.2.1" + ipAddressManager: keepalived + tls: + certificateName: ironic-tls + version: "27.0" +``` + +**NOTE:** when the DHCP range is not provided, IrSO will pick one for you. In +this example, it will be `192.0.2.10 - 192.0.2.253`. diff --git a/docs/user-guide/src/irso/introduction.md b/docs/user-guide/src/irso/introduction.md new file mode 100644 index 00000000..7dbf292a --- /dev/null +++ b/docs/user-guide/src/irso/introduction.md @@ -0,0 +1,85 @@ +# Ironic Standalone Operator + +Ironic Standalone Operator (IrSO) is a Kubernetes controller that installs and +manages Ironic in a configuration suitable for Metal3. IrSO has the following +features: + +- Flexible networking configuration, support for Keepalived. +- Using SQLite or MariaDB as the database backend. +- Optional support for a DHCP service (dnsmasq). +- Optional support for automatically downloading an + [IPA](../ironic/ironic-python-agent.md) image. + +IrSO uses [ironic-image](../ironic/ironic-container-images.md) under the hood. + +## Installing Ironic Standalone Operator + +On every source code change, a new IrSO image is built and published at +`quay.io/metal3-io/ironic-standalone-operator`. To install it in your cluster, +you can use the Kustomize templates provided in the source repository: + +```console +git clone https://github.com/metal3-io/ironic-standalone-operator +cd ironic-standalone-operator +git checkout -b + +make install deploy +kubectl wait --for=condition=Available --timeout=60s \ + -n ironic-standalone-operator-system deployment/ironic-standalone-operator-controller-manager +``` + +## API resources + +IrSO uses two Custom Resources to manage an Ironic installation: + +[Ironic](https://github.com/metal3-io/ironic-standalone-operator/blob/main/config/crd/bases/ironic.metal3.io_ironics.yaml) +manages Ironic itself and all of its auxiliary services. + +[IronicDatabase](https://github.com/metal3-io/ironic-standalone-operator/blob/main/config/crd/bases/ironic.metal3.io_ironicdatabases.yaml) +manages a MariaDB instance for Ironic (if required). + +See [installing Ironic with IrSO](./install-basics.md) for information on how +to use these resources. + +## How is Ironic installed? + +By default, IrSO installs Ironic as a single pod on a **control plane** node. +This is because Ironic currently requires *host networking*, and thus it's not +advisable to let it co-exist with tenant workload. + +### Installed components + +An Ironic installation always contains these three components: + +- `ironic` is the main API service, as well as the conductor process that + handles actions on bare-metal machines. +- `httpd` is the web server that serves images and configuration for iPXE and + virtual media boot, as well as works as the HTTPS frontend for Ironic. +- `ramdisk-logs` is a script that unpacks any ramdisk logs and outputs them + for consumption via `kubectl logs` or similar tools. + +There is also a standard init container: + +- `ramdisk-downloader` downloads images of the deployment/inspection ramdisk + and stores them locally for easy access. + +When network boot (iPXE) is enabled, another component is deployed: + +- `dnsmasq` serves DHCP and functions as a PXE server for bootstrapping iPXE. + +With Keepalived support enabled: + +- `keepalived` manages the IP address on the provisioning interface. + +### Supported versions + +A major and minor version can be supplied to the `Ironic` resource to request +a specific branch of ironic-image (and thus Ironic). Here are supported version +values for each branch and release of the operator: + +| Operator version | Ironic version(s) | Default version | +| ---------------- | ----------------- | --------------- | +| latest (main) | 27.0 | latest | + +**NOTE:** the special version value `latest` always installs the latest +available version of ironic-image and Ironic.