sigs.k8s.io/cluster-api@v1.7.1/docs/book/src/developer/providers/cluster-infrastructure.md (about) 1 # Cluster Infrastructure Provider Specification 2 3 ## Overview 4 5 A cluster infrastructure provider supplies whatever prerequisites are necessary for running machines. 6 Examples might include networking, load balancers, firewall rules, and so on. 7 8 ## Data Types 9 10 ### InfraCluster Resources 11 12 A cluster infrastructure provider must define an API type for "infrastructure cluster" resources. The type: 13 14 1. Must belong to an API group served by the Kubernetes apiserver 15 2. Must be implemented as a CustomResourceDefinition. 16 1. The CRD name must have the format produced by `sigs.k8s.io/cluster-api/util/contract.CalculateCRDName(Group, Kind)`. 17 3. Must be namespace-scoped 18 4. Must have the standard Kubernetes "type metadata" and "object metadata" 19 5. Must have a `spec` field with the following: 20 1. Required fields: 21 1. `controlPlaneEndpoint` (`apiEndpoint`): the endpoint for the cluster's control plane. `apiEndpoint` is defined 22 as: 23 - `host` (string): DNS name or IP address 24 - `port` (int32): TCP port 25 6. Must have a `status` field with the following: 26 1. Required fields: 27 1. `ready` (boolean): indicates the provider-specific infrastructure has been provisioned and is ready 28 2. Optional fields: 29 1. `failureReason` (string): indicates there is a fatal problem reconciling the provider's infrastructure; 30 meant to be suitable for programmatic interpretation 31 2. `failureMessage` (string): indicates there is a fatal problem reconciling the provider's infrastructure; 32 meant to be a more descriptive value than `failureReason` 33 3. `failureDomains` (`FailureDomains`): the failure domains that machines should be placed in. `FailureDomains` 34 is a map, defined as `map[string]FailureDomainSpec`. A unique key must be used for each `FailureDomainSpec`. 35 `FailureDomainSpec` is defined as: 36 - `controlPlane` (bool): indicates if failure domain is appropriate for running control plane instances. 37 - `attributes` (`map[string]string`): arbitrary attributes for users to apply to a failure domain. 38 39 ### InfraClusterTemplate Resources 40 41 For a given InfraCluster resource, you should also add a corresponding InfraClusterTemplate resources: 42 43 ``` go 44 // InfraClusterTemplateSpec defines the desired state of InfraClusterTemplate. 45 type InfraClusterTemplateSpec struct { 46 Template InfraClusterTemplateResource `json:"template"` 47 } 48 49 // +kubebuilder:object:root=true 50 // +kubebuilder:resource:path=infraclustertemplates,scope=Namespaced,categories=cluster-api,shortName=ict 51 // +kubebuilder:storageversion 52 53 // InfraClusterTemplate is the Schema for the infraclustertemplates API. 54 type InfraClusterTemplate struct { 55 metav1.TypeMeta `json:",inline"` 56 metav1.ObjectMeta `json:"metadata,omitempty"` 57 58 Spec InfraClusterTemplateSpec `json:"spec,omitempty"` 59 } 60 61 type InfraClusterTemplateResource struct { 62 // Standard object's metadata. 63 // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata 64 // +optional 65 ObjectMeta clusterv1.ObjectMeta `json:"metadata,omitempty"` 66 Spec InfraClusterSpec `json:"spec"` 67 } 68 ``` 69 70 The CRD name of the template must also have the format produced by `sigs.k8s.io/cluster-api/util/contract.CalculateCRDName(Group, Kind)`. 71 72 ### List Resources 73 74 For any resource, also add list resources, e.g. 75 76 ```go 77 //+kubebuilder:object:root=true 78 79 // InfraClusterList contains a list of InfraClusters. 80 type InfraClusterList struct { 81 metav1.TypeMeta `json:",inline"` 82 metav1.ListMeta `json:"metadata,omitempty"` 83 Items []InfraCluster `json:"items"` 84 } 85 86 //+kubebuilder:object:root=true 87 88 // InfraClusterTemplateList contains a list of InfraClusterTemplates. 89 type InfraClusterTemplateList struct { 90 metav1.TypeMeta `json:",inline"` 91 metav1.ListMeta `json:"metadata,omitempty"` 92 Items []InfraClusterTemplate `json:"items"` 93 } 94 ``` 95 96 ## Behavior 97 98 A cluster infrastructure provider must respond to changes to its "infrastructure cluster" resources. This process is 99 typically called reconciliation. The provider must watch for new, updated, and deleted resources and respond 100 accordingly. 101 102 The following diagram shows the typical logic for a cluster infrastructure provider: 103 104  105 106 ### Normal resource 107 108 1. If the resource is externally managed, exit the reconciliation 109 1. The `ResourceIsNotExternallyManaged` predicate can be used to prevent reconciling externally managed resources 110 1. If the resource does not have a `Cluster` owner, exit the reconciliation 111 1. The Cluster API `Cluster` reconciler populates this based on the value in the `Cluster`'s `spec.infrastructureRef` 112 field. 113 1. Add the provider-specific finalizer, if needed 114 1. Reconcile provider-specific cluster infrastructure 115 1. If any errors are encountered, exit the reconciliation 116 1. If the provider created a load balancer for the control plane, record its hostname or IP in `spec.controlPlaneEndpoint` 117 1. Set `status.ready` to `true` 118 1. Set `status.failureDomains` based on available provider failure domains (optional) 119 1. Patch the resource to persist changes 120 121 ### Deleted resource 122 123 1. If the resource has a `Cluster` owner 124 1. Perform deletion of provider-specific cluster infrastructure 125 1. If any errors are encountered, exit the reconciliation 126 1. Remove the provider-specific finalizer from the resource 127 1. Patch the resource to persist changes 128 129 ## RBAC 130 131 ### Provider controller 132 133 A cluster infrastructure provider must have RBAC permissions for the types it defines. If you are using `kubebuilder` to 134 generate new API types, these permissions should be configured for you automatically. For example, the AWS provider has 135 the following configuration for its `AWSCluster` type: 136 137 ``` 138 // +kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=awsclusters,verbs=get;list;watch;create;update;patch;delete 139 // +kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=awsclusters/status,verbs=get;update;patch 140 ``` 141 142 A cluster infrastructure provider may also need RBAC permissions for other types, such as `Cluster`. If you need 143 read-only access, you can limit the permissions to `get`, `list`, and `watch`. The AWS provider has the following 144 configuration for retrieving `Cluster` resources: 145 146 ``` 147 // +kubebuilder:rbac:groups=cluster.x-k8s.io,resources=clusters;clusters/status,verbs=get;list;watch 148 ``` 149 150 ### Cluster API controllers 151 152 The Cluster API controller for `Cluster` resources is configured with full read/write RBAC 153 permissions for all resources in the `infrastructure.cluster.x-k8s.io` API group. This group 154 represents all cluster infrastructure providers for SIG Cluster Lifecycle-sponsored provider 155 subprojects. If you are writing a provider not sponsored by the SIG, you must grant full read/write 156 RBAC permissions for the "infrastructure cluster" resource in your API group to the Cluster API 157 manager's `ServiceAccount`. `ClusterRoles` can be granted using the [aggregation label] 158 `cluster.x-k8s.io/aggregate-to-manager: "true"`. The following is an example `ClusterRole` for a 159 `FooCluster` resource: 160 161 ```yaml 162 apiVersion: rbac.authorization.k8s.io/v1 163 kind: ClusterRole 164 metadata: 165 name: capi-foo-clusters 166 labels: 167 cluster.x-k8s.io/aggregate-to-manager: "true" 168 rules: 169 - apiGroups: 170 - infrastructure.foo.com 171 resources: 172 - fooclusters 173 verbs: 174 - create 175 - delete 176 - get 177 - list 178 - patch 179 - update 180 - watch 181 ``` 182 183 Note, the write permissions allow the `Cluster` controller to set owner references and labels on the 184 "infrastructure cluster" resources; they are not used for general mutations of these resources. 185 186 [aggregation label]: https://kubernetes.io/docs/reference/access-authn-authz/rbac/#aggregated-clusterroles