From f2cc62068887ecbe34788fcdc811ae5363446d67 Mon Sep 17 00:00:00 2001 From: Andy Goldstein Date: Tue, 10 Dec 2019 16:23:36 -0500 Subject: [PATCH] Add bootstrap provider spec doc Signed-off-by: Andy Goldstein --- docs/book/src/SUMMARY.md | 1 + .../src/images/bootstrap-provider.plantuml | 32 ++++++ docs/book/src/images/bootstrap-provider.png | Bin 0 -> 32457 bytes docs/book/src/providers/bootstrap.md | 93 ++++++++++++++++++ 4 files changed, 126 insertions(+) create mode 100644 docs/book/src/images/bootstrap-provider.plantuml create mode 100644 docs/book/src/images/bootstrap-provider.png create mode 100644 docs/book/src/providers/bootstrap.md diff --git a/docs/book/src/SUMMARY.md b/docs/book/src/SUMMARY.md index a0ab05e949f8..400c97741f32 100644 --- a/docs/book/src/SUMMARY.md +++ b/docs/book/src/SUMMARY.md @@ -19,6 +19,7 @@ - [Provider Implementers](./providers/implementers.md) - [v1alpha1 to v1alpha2](./providers/v1alpha1-to-v1alpha2.md) - [Cluster Infrastructure](./providers/cluster-infrastructure.md) + - [Bootstrap](./providers/bootstrap.md) - [Implementer's Guide](./providers/implementers-guide/overview.md) - [Naming](./providers/implementers-guide/naming.md) - [Create Repo and Generate CRDs](./providers/implementers-guide/generate_crds.md) diff --git a/docs/book/src/images/bootstrap-provider.plantuml b/docs/book/src/images/bootstrap-provider.plantuml new file mode 100644 index 000000000000..3a1c0b46d981 --- /dev/null +++ b/docs/book/src/images/bootstrap-provider.plantuml @@ -0,0 +1,32 @@ +@startuml + +start + +:New/Updated resource; + +if (Deleted?) then (yes) + stop +else (no) + if (Has machine owner?) then (yes) + if (Has status.failureReason/failureMessage?) then (yes) + stop + else (no) + if (Cluster exists?) then (no) + stop + else (yes) + if (Bootstrap data secret exists?) then (no) + :Generate bootstrap data & create secret; + else (yes) + endif + + :Set status.dataSecretName; + :set status.ready to true; + endif + endif + else (no) + endif +endif +:Patch resource to persist changes; +stop + +@enduml diff --git a/docs/book/src/images/bootstrap-provider.png b/docs/book/src/images/bootstrap-provider.png new file mode 100644 index 0000000000000000000000000000000000000000..7e82cb958ab08fe888286d8ab96621377357ebe3 GIT binary patch literal 32457 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 IownEi0{8@@i~s-t literal 0 HcmV?d00001 diff --git a/docs/book/src/providers/bootstrap.md b/docs/book/src/providers/bootstrap.md new file mode 100644 index 000000000000..ca9e466dd99c --- /dev/null +++ b/docs/book/src/providers/bootstrap.md @@ -0,0 +1,93 @@ +# Bootstrap Provider Specification + +## Overview + +A bootstrap provider generates bootstrap data that is used to bootstrap a Kubernetes node. + +## Data Types + +### Bootstrap API resource +A bootstrap provider must define an API type for bootstrap resources. The type: + +1. Must belong to an API group served by the Kubernetes apiserver +2. May be implemented as a CustomResourceDefinition, or as part of an aggregated apiserver +3. Must be namespace-scoped +4. Must have the standard Kubernetes "type metadata" and "object metadata" +5. Should have a `spec` field containing fields relevant to the bootstrap provider +6. Must have a `status` field with the following: + 1. Required fields: + 1. `ready` (boolean): indicates the bootstrap data has been generated and is ready + 1. `dataSecretName` (string): the name of the secret that stores the generated bootstrap data + 2. Optional fields: + 1. `failureReason` (string): indicates there is a fatal problem reconciling the bootstrap data; + meant to be suitable for programmatic interpretation + 2. `failureMessage` (string): indicates there is a fatal problem reconciling the bootstrap data; + meant to be a more descriptive value than `failureReason` + +Note: because the `dataSecretName` is part of `status`, this value must be deterministically recreatable from the data in the +`Cluster`, `Machine`, and/or bootstrap resource. If the name is randomly generated, it is not always possible to move +the resource and its associated secret from one management cluster to another. + +### Bootstrap Secret + +The `Secret` containing bootstrap data must: + +1. Use the API resource's `status.dataSecretName` for its name +1. Have the label `cluster.x-k8s.io/cluster-name` set to the name of the cluster +1. Have a controller owner reference to the API resource +1. Have a single key, `value`, containing the bootstrap data + +## Behavior + +A bootstrap provider must respond to changes to its bootstrap resources. This process is +typically called reconciliation. The provider must watch for new, updated, and deleted resources and respond +accordingly. + +The following diagram shows the typical logic for a bootstrap provider: + +![Bootstrap provider activity diagram](../images/bootstrap-infra-provider.png) + +1. If the resource does not have a `Machine` owner, exit the reconciliation + 1. The Cluster API `Machine` reconciler populates this based on the value in the `Machine`'s `spec.bootstrap.configRef` + field. +1. If the resource has `status.failureReason` or `status.failureMessage` set, exit the reconciliation +1. If the `Cluster` to which this resource belongs cannot be found, exit the reconciliation +1. Deterministically generate the name for the bootstrap data secret +1. Try to retrieve the `Secret` with the name from the previous step + 1. If it does not exist, generate bootstrap data and create the `Secret` +1. Set `status.dataSecretName` to the generated name +1. Set `status.ready` to true +1. Patch the resource to persist changes + +## RBAC + +### Provider controller + +A bootstrap provider must have RBAC permissions for the types it defines, as well as the bootstrap data `Secret` +resources it manages. If you are using `kubebuilder` to generate new API types, these permissions should be configured +for you automatically. For example, the Kubeadm bootstrap provider the following configuration for its `KubeadmConfig` +type: + +``` +// +kubebuilder:rbac:groups=bootstrap.cluster.x-k8s.io,resources=kubeadmconfigs;kubeadmconfigs/status,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups="",resources=secrets,verbs=get;list;watch;create;update;patch;delete +``` + +A bootstrap provider may also need RBAC permissions for other types, such as `Cluster`. If you need +read-only access, you can limit the permissions to `get`, `list`, and `watch`. The following +configuration can be used for retrieving `Cluster` resources: + +``` +// +kubebuilder:rbac:groups=cluster.x-k8s.io,resources=clusters;clusters/status,verbs=get;list;watch +``` + +### Cluster API controllers + +The Cluster API controller for `Machine` resources is configured with full read/write RBAC permissions for all resources +in the `bootstrap.cluster.x-k8s.io` API group. This group represents all bootstrap providers for SIG Cluster +Lifecycle-sponsored provider subprojects. If you are writing a provider not sponsored by the SIG, you must add new RBAC +permissions for the Cluster API `manager-role` role, granting it full read/write access to the bootstrap resource in +your API group. + +Note, the write permissions allow the `Machine` controller to set owner references and labels on the bootstrap +resources; they are not used for general mutations of these resources.