diff --git a/pkg/cluster/config/v1alpha2/types.go b/pkg/cluster/config/v1alpha2/types.go index c25cdafb46..3bba38f7ce 100644 --- a/pkg/cluster/config/v1alpha2/types.go +++ b/pkg/cluster/config/v1alpha2/types.go @@ -28,7 +28,7 @@ type Config struct { // TypeMeta representing the type of the object and its API schema version. metav1.TypeMeta `json:",inline"` - // nodes constains the list of nodes defined in the `kind` Config + // Nodes constains the list of nodes defined in the `kind` Config Nodes []Node `json:"nodes"` } @@ -39,7 +39,7 @@ type Node struct { // Replicas is the number of desired node replicas. // Defaults to 1 Replicas *int32 `json:"replicas,omitempty"` - // Role defines the role of the nodw in the in the Kubernetes cluster managed by `kind` + // Role defines the role of the node in the in the Kubernetes cluster managed by `kind` // Defaults to "control-plane" Role NodeRole `json:"role,omitempty"` // Image is the node image to use when running the cluster @@ -70,7 +70,7 @@ const ( ExternalEtcdRole NodeRole = "external-etcd" // ExternalLoadBalancerRole identifies a node that hosts an external load balancer for API server // in HA configurations. - // WARNING: this node type is not yet implemented! - // Please note that `kind` nodes hosting external load balancer are not kubernetes nodes + // If multiple control-plane nodes exists, a node with this role will be added automatically if missing. + // Please note that `kind` nodes hosting external load balancer are not Kubernetes nodes. ExternalLoadBalancerRole NodeRole = "external-load-balancer" ) diff --git a/pkg/cluster/config/validate.go b/pkg/cluster/config/validate.go index e881c44045..2c29b203a7 100644 --- a/pkg/cluster/config/validate.go +++ b/pkg/cluster/config/validate.go @@ -30,7 +30,7 @@ func (c *Config) Validate() error { // All nodes in the config should be valid for i, n := range c.Nodes { if err := n.Validate(); err != nil { - errs = append(errs, errors.Errorf("invalid configuration for node %d", i)) + errs = append(errs, errors.Errorf("invalid configuration for node %d: %v", i, err)) } } diff --git a/pkg/cluster/internal/create/derivedconfig.go b/pkg/cluster/internal/create/derivedconfig.go index 495a7cd6c0..6f8f8f1943 100644 --- a/pkg/cluster/internal/create/derivedconfig.go +++ b/pkg/cluster/internal/create/derivedconfig.go @@ -24,6 +24,7 @@ import ( "sigs.k8s.io/kind/pkg/util" "github.com/pkg/errors" + log "github.com/sirupsen/logrus" ) // DerivedConfig contains config-like data computed from pkg/cluster/config.Config @@ -141,6 +142,16 @@ func Derive(c *config.Config) (*DerivedConfig, error) { } } + // Add a load balancer automatically if one does not exists already and if the number + // of control plane nodes is more than one + if d.ExternalLoadBalancer() == nil && len(d.ControlPlanes()) > 1 { + n := config.Node{ + Role: config.ExternalLoadBalancerRole, + Image: d.BootStrapControlPlane().Image, // should always return non-nil in this branch + } + log.Info("Automatically creating a load balancer node") + d.Add(&n) + } return d, nil }