Cluster Infrastructure Provider Specification
Overview
A cluster infrastructure provider supplies whatever prerequisites are necessary for running machines. Examples might include networking, load balancers, firewall rules, and so on.
Data Types
InfraCluster Resources
A cluster infrastructure provider must define an API type for “infrastructure cluster” resources. The type:
- Must belong to an API group served by the Kubernetes apiserver
- May be implemented as a CustomResourceDefinition, or as part of an aggregated apiserver
- Must be namespace-scoped
- Must have the standard Kubernetes “type metadata” and “object metadata”
- Must have a
spec
field with the following:- Required fields:
controlPlaneEndpoint
(apiEndpoint
): the endpoint for the cluster’s control plane.apiEndpoint
is defined as:host
(string): DNS name or IP addressport
(int32): TCP port
- Required fields:
- Must have a
status
field with the following:- Required fields:
ready
(boolean): indicates the provider-specific infrastructure has been provisioned and is ready
- Optional fields:
failureReason
(string): indicates there is a fatal problem reconciling the provider’s infrastructure; meant to be suitable for programmatic interpretationfailureMessage
(string): indicates there is a fatal problem reconciling the provider’s infrastructure; meant to be a more descriptive value thanfailureReason
failureDomains
(failureDomains
): the failure domains that machines should be placed in.failureDomains
is a map, defined asmap[string]FailureDomainSpec
. A unique key must be used for eachFailureDomainSpec
.FailureDomainSpec
is defined as:controlPlane
(bool): indicates if failure domain is appropriate for running control plane instances.attributes
(map[string]string
): arbitrary attributes for users to apply to a failure domain.
- Required fields:
InfraClusterTemplate Resources
For a given InfraCluster resource, you should also add a corresponding InfraClusterTemplate resources:
// InfraClusterTemplateSpec defines the desired state of InfraClusterTemplate.
type InfraClusterTemplateSpec struct {
Template InfraClusterTemplateResource `json:"template"`
}
// +kubebuilder:object:root=true
// +kubebuilder:resource:path=infraclustertemplates,scope=Namespaced,categories=cluster-api,shortName=ict
// +kubebuilder:storageversion
// InfraClusterTemplate is the Schema for the infraclustertemplates API.
type InfraClusterTemplate struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec InfraClusterTemplateSpec `json:"spec,omitempty"`
}
type InfraClusterTemplateResource struct {
// Standard object's metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
// +optional
ObjectMeta clusterv1.ObjectMeta `json:"metadata,omitempty"`
Spec InfraClusterSpec `json:"spec"`
}
List Resources
For any resource, also add list resources, e.g.
//+kubebuilder:object:root=true
// InfraClusterList contains a list of InfraClusters.
type InfraClusterList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []InfraCluster `json:"items"`
}
//+kubebuilder:object:root=true
// InfraClusterTemplateList contains a list of InfraClusterTemplates.
type InfraClusterTemplateList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []InfraClusterTemplate `json:"items"`
}
Behavior
A cluster infrastructure provider must respond to changes to its “infrastructure cluster” 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 cluster infrastructure provider:
Normal resource
- If the resource is externally managed, exit the reconciliation
- The
ResourceIsNotExternallyManaged
predicate can be used to prevent reconciling externally managed resources
- The
- If the resource does not have a
Cluster
owner, exit the reconciliation- The Cluster API
Cluster
reconciler populates this based on the value in theCluster
‘sspec.infrastructureRef
field.
- The Cluster API
- Add the provider-specific finalizer, if needed
- Reconcile provider-specific cluster infrastructure
- If any errors are encountered, exit the reconciliation
- If the provider created a load balancer for the control plane, record its hostname or IP in
spec.controlPlaneEndpoint
- Set
status.ready
totrue
- Set
status.failureDomains
based on available provider failure domains (optional) - Patch the resource to persist changes
Deleted resource
- If the resource has a
Cluster
owner- Perform deletion of provider-specific cluster infrastructure
- If any errors are encountered, exit the reconciliation
- Remove the provider-specific finalizer from the resource
- Patch the resource to persist changes
RBAC
Provider controller
A cluster infrastructure provider must have RBAC permissions for the types it defines. If you are using kubebuilder
to
generate new API types, these permissions should be configured for you automatically. For example, the AWS provider has
the following configuration for its AWSCluster
type:
// +kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=awsclusters,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=awsclusters/status,verbs=get;update;patch
A cluster infrastructure 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 AWS provider has the following
configuration 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 Cluster
resources is configured with full read/write RBAC
permissions for all resources in the infrastructure.cluster.x-k8s.io
API group. This group
represents all cluster infrastructure providers for SIG Cluster Lifecycle-sponsored provider
subprojects. If you are writing a provider not sponsored by the SIG, you must grant full read/write
RBAC permissions for the “infrastructure cluster” resource in your API group to the Cluster API
manager’s ServiceAccount
. ClusterRoles
can be granted using the aggregation label
cluster.x-k8s.io/aggregate-to-manager: "true"
. The following is an example ClusterRole
for a
FooCluster
resource:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: capi-foo-clusters
labels:
cluster.x-k8s.io/aggregate-to-manager: "true"
rules:
- apiGroups:
- infrastructure.foo.com
resources:
- fooclusters
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
Note, the write permissions allow the Cluster
controller to set owner references and labels on the
“infrastructure cluster” resources; they are not used for general mutations of these resources.