Skip to content

Commit

Permalink
Add OCP-specific documentation (kubernetes-sigs#419)
Browse files Browse the repository at this point in the history
  • Loading branch information
qbarrand committed Feb 3, 2023
1 parent 0b67e5d commit 5aca98e
Show file tree
Hide file tree
Showing 7 changed files with 124 additions and 47 deletions.
1 change: 1 addition & 0 deletions docs/mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ nav:
- Binary firmwares: documentation/firmwares.md
- Secure boot: documentation/secure_boot.md
- Preflight validation: documentation/preflight_validation.md
- documentation/troubleshooting.md
- documentation/uninstall.md
- Developer:
- developer/index.md
Expand Down
4 changes: 2 additions & 2 deletions docs/mkdocs/documentation/firmwares.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ module, when the pod is terminated.
In addition to building the kernel module itself, include the binary firmware in the builder image.

```dockerfile
FROM ubuntu as builder
FROM registry.redhat.io/ubi8/ubi-minimal as builder

# Build the kmod

RUN ["mkdir", "/firmware"]
RUN ["curl", "-o", "/firmware/firmware.bin", "https://artifacts.example.com/firmware.bin"]

FROM ubuntu
FROM registry.redhat.io/ubi8/ubi-minimal

# Copy the kmod, install modprobe, run depmod

Expand Down
73 changes: 54 additions & 19 deletions docs/mkdocs/documentation/module_loader_image.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,36 +15,35 @@ To generate dependencies and map files for a specific kernel version, run `depmo

## Example `Dockerfile`

The `Dockerfile` below can accommodate any kernel available in the Ubuntu repositories.
Pass the kernel version you are building an image from using the `--build-arg KERNEL_VERSION=1.2.3` Docker CLI switch.
The example below builds a test kernel module from the KMM repository.
Please note that a Red Hat subscription is required to download the `kernel-devel` package.
If you are building your image on OpenShift, consider [using Driver Toolkit](#using-driver-toolkit--dtk-) or [using an
entitled build](https://cloud.redhat.com/blog/how-to-use-entitled-image-builds-to-build-drivercontainers-with-ubi-on-openshift).

```dockerfile
FROM ubuntu as builder
FROM registry.redhat.io/ubi8/ubi as builder

ARG KERNEL_VERSION

RUN apt-get update && apt-get install -y bc \
bison \
flex \
libelf-dev \
gnupg \
wget \
git \
make \
RUN dnf install -y \
gcc \
linux-headers-${KERNEL_VERSION}
git \
kernel-devel-${KERNEL_VERSION} \
make

WORKDIR /usr/src

RUN ["git", "clone", "https://github.com/rh-ecosystem-edge/kernel-module-management.git"]

WORKDIR /usr/src/kernel-module-management/ci/kmm-kmod
RUN ["make"]

FROM ubuntu
RUN KERNEL_SRC_DIR=/lib/modules/${KERNEL_VERSION}/build make all

FROM registry.redhat.io/ubi8/ubi-minimal

ARG KERNEL_VERSION

RUN apt-get update && apt-get install -y kmod
RUN microdnf install kmod

COPY --from=builder /usr/src/kernel-module-management/ci/kmm-kmod/kmm_ci_a.ko /opt/lib/modules/${KERNEL_VERSION}/
COPY --from=builder /usr/src/kernel-module-management/ci/kmm-kmod/kmm_ci_b.ko /opt/lib/modules/${KERNEL_VERSION}/
Expand All @@ -61,10 +60,8 @@ The `ConfigMap` needs to be located in the same namespace as the `Module`.

KMM will first check if the image name specified in the `containerImage` field exists.
If it does, the build will be skipped.
Otherwise, KMM will create a Job to build your image.
The [kaniko](https://github.com/GoogleContainerTools/kaniko) build system is used.
KMM monitors the health of the build job, retrying if necessary.

Otherwise, KMM creates a [`Build`](https://docs.openshift.com/container-platform/4.12/cicd/builds/build-configuration.html)
object to build your image.
Once the image is built, KMM proceeds with the `Module` reconciliation.

```yaml
Expand Down Expand Up @@ -93,4 +90,42 @@ Once the image is built, KMM proceeds with the `Module` reconciliation.
# Optional and not recommended! If true, KMM will skip any TLS server certificate validation when checking if
# the container image already exists.
insecureSkipTLSVerify: false
```

### Using Driver Toolkit (DTK)

[Driver Toolkit](https://docs.openshift.com/container-platform/4.12/hardware_enablement/psap-driver-toolkit.html) is a
convenient base image that contains most tools and libraries required to build ModuleLoader images for the OpenShift
version that is currently running in the cluster.
It is recommended to use DTK as the first stage of a multi-stage `Dockerfile` to build the kernel modules, and to copy
the `.ko` files into a smaller end-user image such as [`ubi-minimal`](https://catalog.redhat.com/software/containers/ubi8/ubi-minimal).

To leverage DTK in your in-cluster build, use the `DTK_AUTO` build argument.
The value is automatically set by KMM when creating the `Build` object.

```dockerfile
ARG DTK_AUTO

FROM ${DTK_AUTO} as builder

ARG KERNEL_VERSION

WORKDIR /usr/src

RUN ["git", "clone", "https://github.com/rh-ecosystem-edge/kernel-module-management.git"]

WORKDIR /usr/src/kernel-module-management/ci/kmm-kmod

RUN KERNEL_SRC_DIR=/lib/modules/${KERNEL_VERSION}/build make all

FROM registry.redhat.io/ubi8/ubi-minimal

ARG KERNEL_VERSION

RUN microdnf install kmod

COPY --from=builder /usr/src/kernel-module-management/ci/kmm-kmod/kmm_ci_a.ko /opt/lib/modules/${KERNEL_VERSION}/
COPY --from=builder /usr/src/kernel-module-management/ci/kmm-kmod/kmm_ci_b.ko /opt/lib/modules/${KERNEL_VERSION}/

RUN depmod -b /opt ${KERNEL_VERSION}
```
37 changes: 21 additions & 16 deletions docs/mkdocs/documentation/preflight_validation.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ Preflight will try to validate every `Module` loaded in the cluster, in parallel

## Validation kick-off

Preflight validation is triggered by creating a `PreflightValidation` resource in the cluster. This Spec contains two
Preflight validation is triggered by creating a `PreflightValidationOCP` resource in the cluster. This Spec contains two
fields:
```go
type PreflightValidationSpec struct {
// KernelVersion describes the kernel image that all Modules need to be checked against.
type PreflightValidationOCPSpec struct {
// releaseImage describes the OCP release image that all Modules need to be checked against.
// +kubebuilder:validation:Required
KernelVersion string `json:"kernelVersion"`
ReleaseImage string `json:"releaseImage"`

// Boolean flag that determines whether images build during preflight must also
// be pushed to a defined repository
Expand All @@ -22,7 +22,9 @@ type PreflightValidationSpec struct {
}
```

1. `KernelVersion` - the version of the kernel that the cluster will be upgraded to. Mandatory field
1. `ReleaseImage` - the name of the release image for the OpenShift Container Platform version the cluster will be
upgraded to.
Mandatory field.
2. `PushBuiltImage` - if true, then the images created during the Build and Sign validation will be pushed to their
repositories (false by default).

Expand All @@ -32,9 +34,9 @@ Preflight validation will try to validate every module loaded in the cluster. Pr
a `Module`, once its validation is successful.
In case module validation has failed, admin can change the module definitions, and Preflight will try to validate the
module again in the next loop.
If admin want to run Preflight validation for additional kernel, then another `PreflightValidation` resource should be
created.
Once all the modules have been validated, it is recommended to delete the `PreflightValidation` resource.
If admin want to run Preflight validation for additional kernel, then another `PreflightValidationOCP` resource should
be created.
Once all the modules have been validated, it is recommended to delete the `PreflightValidationOCP` resource.

## Validation status

Expand Down Expand Up @@ -103,7 +105,7 @@ Image validation consists of 2 stages:
Build validation is executed only in case image validation has failed, and there is a `build` section in the `Module`
that is relevant for the upgraded kernel.
Build validation will try to run build job and validate that it finishes successfully.
If the `PushBuiltImage` flag is defined in the `PreflightValidation` CR, it will also try to push the resulting image
If the `PushBuiltImage` flag is defined in the `PreflightValidationOCP` CR, it will also try to push the resulting image
into its repo.
The resulting image name is taken from the definition of the `containerImage` field of the `Module` CR.

Expand All @@ -117,26 +119,29 @@ Sign validation is executed only in case image validation has failed, there is a
relevant for the upgrade kernel, and build validation finished successfully in case there was a `build` section in the
`Module` relevant for the upgraded kernel.
Sign validation will try to run the sign job and validate that it finishes successfully.
In case the `PushBuiltImage` flag is defined in the `PreflightValidation` CR, it will also try to push the resulting
In case the `PushBuiltImage` flag is defined in the `PreflightValidationOCP` CR, it will also try to push the resulting
image to its registry.
The result image is always the image defined in the `ContainerImage` field of the `Module`.
The input image is either the output of the Build stage, or an image defined in the `UnsignedImage` field.

!!! note
In case a `build` section exists, the `sign` section input image is the `build` section's output image.
Therefore, in order for the input image to be available for the `sign` section, the `PushBuiltImage` flag must be
defined in the `PreflightValidation` CR.
defined in the `PreflightValidationOCP` CR.

## Example CR
Below is an example of the `PreflightValidation` resource in the YAML format.
In the example, we want to verify all the currently present modules against the upcoming `5.8.18-101.fc31.x86_64`
kernel, and push the resulting images of Build/Sign into the defined repositories.
Below is an example of the `PreflightValidationOCP` resource in the YAML format.
In the example, we want to verify all the currently present modules against the upcoming kernel version including in the
OCP release `4.11.18`, which release image `quay.io/openshift-release-dev/ocp-release@sha256:22e149142517dfccb47be828f012659b1ccf71d26620e6f62468c264a7ce7863`
points to.
`.spec.pushBuiltImage` is true, so KMM will push the resulting images of Build/Sign into the defined repositories.

```yaml
apiVersion: kmm.sigs.x-k8s.io/v1beta1
kind: PreflightValidation
kind: PreflightValidationOCP
metadata:
name: preflight
spec:
kernelVersion: 5.8.18-101.fc31.x86_64
releaseImage: quay.io/openshift-release-dev/ocp-release@sha256:22e149142517dfccb47be828f012659b1ccf71d26620e6f62468c264a7ce7863
pushBuiltImage: true
```
16 changes: 8 additions & 8 deletions docs/mkdocs/documentation/secure_boot.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ The two files created (`my_signing_key_pub.der` containing the cert and `my_sign
key) can then be added as [secrets](https://kubernetes.io/docs/concepts/configuration/secret/) either directly by:

```shell
kubectl create secret generic my-signing-key --from-file=key=<my_signing_key.priv>
kubectl create secret generic my-signing-key-pub --from-file=key=<my_signing_key_pub.der>
oc create secret generic my-signing-key --from-file=key=<my_signing_key.priv>
oc create secret generic my-signing-key-pub --from-file=key=<my_signing_key_pub.der>
```
OR

Expand Down Expand Up @@ -73,21 +73,21 @@ data:

and then applying the yaml file using:
```shell
kubectl apply -f <yaml filename>
oc apply -f <yaml filename>
```

## Checking the keys

To check the public key secret is set correctly:
```shell
kubectl get secret -o yaml <certificate secret name> | awk '/cert/{print $2; exit}' | base64 -d | openssl x509 -inform der -text
oc get secret -o yaml <certificate secret name> | awk '/cert/{print $2; exit}' | base64 -d | openssl x509 -inform der -text
```

This should display a certificate with a Serial Number, Issuer, Subject etc.

And to check the private key:
```shell
kubectl get secret -o yaml <private key secret name> | awk '/key/{print $2; exit}' | base64 -d
oc get secret -o yaml <private key secret name> | awk '/key/{print $2; exit}' | base64 -d
```

Which should display a key, including `-----BEGIN PRIVATE KEY-----` and `-----END PRIVATE KEY-----` lines
Expand Down Expand Up @@ -222,7 +222,7 @@ spec:

# Debugging & troubleshooting

If your driver containers end up in `PostStartHookError` or `CrashLoopBackOff` status, and `kubectl describe` shows an
event: `modprobe: ERROR: could not insert '<your kmod name>': Required key not available` then the kmods are either not
signed, or signed with the wrong key.
If your driver containers end up in `PostStartHookError` or `CrashLoopBackOff` status, and `oc describe` shows an event:
`modprobe: ERROR: could not insert '<your kmod name>': Required key not available` then the kmods are either not signed,
or signed with the wrong key.

31 changes: 31 additions & 0 deletions docs/mkdocs/documentation/troubleshooting.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Troubleshooting

## Using `oc adm must-gather`

The `oc adm must-gather` is the preferred way to collect a support bundle and provide debugging information to Red Hat
support.

### For KMM

```shell
export MUST_GATHER_IMAGE=$(oc get deployment -n openshift-kmm kmm-operator-controller-manager -ojsonpath='{.spec.template.spec.containers[?(@.name=="manager")].env[?(@.name=="RELATED_IMAGES_MUST_GATHER")].value}')
oc adm must-gather --image="${MUST_GATHER_IMAGE}" -- /usr/bin/gather
```

### For KMM-Hub

```shell
export MUST_GATHER_IMAGE=$(oc get deployment -n openshift-kmm-hub kmm-operator-hub-controller-manager -ojsonpath='{.spec.template.spec.containers[?(@.name=="manager")].env[?(@.name=="RELATED_IMAGES_MUST_GATHER")].value}')
oc adm must-gather --image="${MUST_GATHER_IMAGE}" -- /usr/bin/gather -u
```

### Different namespace

Use the `-n NAMESPACE` switch to specify a namespace if you installed KMM in a custom namespace.

## Reading operator logs

| Component | Command |
|-----------|---------------------------------------------------------------------------------|
| KMM | `oc logs -fn openshift-kmm deployments/kmm-operator-controller-manager` |
| KMM-Hub | `oc logs -fn openshift-kmm-hub deployments/kmm-operator-hub-controller-manager` |
9 changes: 7 additions & 2 deletions docs/mkdocs/documentation/uninstall.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
# Uninstalling

## Using `kubectl`
## If installed from the Red Hat catalog

To uninstall KMM, either use the OpenShift console under "Operators" --> "Installed Operators" (preferred), or delete
the `Subscription` resource in the KMM namespace.

## If installed using `oc`

```shell
kubectl delete -k https://github.com/rh-ecosystem-edge/kernel-module-management/config/default
oc delete -k https://github.com/rh-ecosystem-edge/kernel-module-management/config/default
```

0 comments on commit 5aca98e

Please sign in to comment.