Cluster Resources
A Cluster
represents the global configuration of a Kubernetes cluster.
Cluster
Cluster has 4 fields:
Spec
contains the desired cluster state specified by the object. While much
of the Spec
is defined by users, unspecified parts may be filled in with
defaults or by Controllers such as autoscalers.
Status
contains only observed cluster state and is only written by
controllers. Status
is not the source of truth for any information, but
instead aggregates and publishes observed state.
TypeMeta
contains metadata about the API itself - such as Group, Version,
Kind.
ObjectMeta
contains metadata about the specific object instance, for example,
it's name, namespace, labels, and annotations, etc. ObjectMeta
contains data
common to most objects.
// Cluster is the Schema for the clusters API
// +k8s:openapi-gen=true
// +kubebuilder:resource:shortName=cl
// +kubebuilder:subresource:status
type Cluster struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec ClusterSpec `json:"spec,omitempty"`
Status ClusterStatus `json:"status,omitempty"`
}
ClusterSpec
The ClusterNetwork
field includes the information necessary to configure
kubelet networking for Pod
s and Service
s.
The ProviderSpec
is recommended to be a serialized API object in a format
owned by that provider. This will allow the configuration to be strongly typed,
versioned, and have as much nested depth as appropriate. These provider-specific
API definitions are meant to live outside of the Cluster API, which will allow
them to evolve independently of it.
// ClusterSpec defines the desired state of Cluster
type ClusterSpec struct {
// Cluster network configuration
// +optional
ClusterNetwork ClusterNetworkingConfig `json:"clusterNetwork"`
// Provider-specific serialized configuration to use during
// cluster creation. It is recommended that providers maintain
// their own versioned API types that should be
// serialized/deserialized from this field.
// +optional
ProviderSpec ProviderSpec `json:"providerSpec,omitempty"`
}
ClusterStatus
Like ProviderSpec
, ProviderStatus
is recommended to be a serialized API
object in a format owned by that provider.
Some providers use the APIEndpoint
field to determine when one or more
control plane machines have been provisioned. This may be necessary before worker nodes
can be provisioned. For example, cluster-api-provider-gcp
does this:
if len(cluster.Status.APIEndpoints) == 0 {
return nil, fmt.Errorf("control plane endpoint not found in apiEndpoints for cluster %v", cluster)
}
TODO: Provide examples of how ErrorReason
and ErrorMessage
are
used in practice.
// ClusterStatus defines the observed state of Cluster
type ClusterStatus struct {
// APIEndpoint represents the endpoint to communicate with the IP.
// +optional
APIEndpoints []APIEndpoint `json:"apiEndpoints,omitempty"`
// NB: Eventually we will redefine ErrorReason as ClusterStatusError once the
// following issue is fixed.
// https://github.com/kubernetes-incubator/apiserver-builder/issues/176
// If set, indicates that there is a problem reconciling the
// state, and will be set to a token value suitable for
// programmatic interpretation.
// +optional
ErrorReason common.ClusterStatusError `json:"errorReason,omitempty"`
// If set, indicates that there is a problem reconciling the
// state, and will be set to a descriptive error message.
// +optional
ErrorMessage string `json:"errorMessage,omitempty"`
// Provider-specific status.
// It is recommended that providers maintain their
// own versioned API types that should be
// serialized/deserialized from this field.
// +optional
ProviderStatus *runtime.RawExtension `json:"providerStatus,omitempty"`
}
Cluster Actuator Interface
All methods should be idempotent.
Reconcile()
will be called whenever there is a change to the Cluster
Spec
, or after every resync period.
If a Cluster
resource is deleted, the controller will call the actuator's
Delete()
method until it succeeds, or the finalizer is removed (see below).
TODO: Determine what the current resync period is.
// Actuator controls clusters on a specific infrastructure. All
// methods should be idempotent unless otherwise specified.
type Actuator interface {
// Reconcile creates or applies updates to the cluster.
Reconcile(*clusterv1.Cluster) error
// Delete the cluster.
Delete(*clusterv1.Cluster) error
}
Cluster Controller Semantics
- If the
Cluster
hasn't been deleted and doesn't have a finalizer, add one. - If the
Cluster
is being deleted, and there is no finalizer, we're done. - Call the provider specific
Delete()
method.- If the
Delete()
method returns true, remove the finalizer, we're done.
- If the
- If the
Cluster
has not been deleted, call theReconcile()
method.