in kinder/pkg/cluster/manager/create.go [158:247]
func createNodes(clusterName string, flags *CreateOptions) error {
// compute the desired nodes, and inform the user that we are setting them up
desiredNodes := nodesToCreate(clusterName, flags)
numberOfNodes := len(desiredNodes)
if flags.externalEtcd {
numberOfNodes++
}
fmt.Printf("Preparing nodes %s\n", strings.Repeat("📦", numberOfNodes))
// detect CRI runtime installed into images before actually creating nodes
runtime, err := status.InspectCRIinImage(flags.image)
if err != nil {
log.Errorf("Error detecting CRI for images %s! %v", flags.image, err)
return err
}
log.Infof("Detected %s container runtime for image %s", runtime, flags.image)
createHelper, err := nodes.NewCreateHelper(runtime)
if err != nil {
log.Errorf("Error creating NewCreateHelper for CRI %s! %v", flags.image, err)
return err
}
// create all of the node containers, concurrently
fns := []func() error{}
for _, desiredNode := range desiredNodes {
desiredNode := desiredNode // capture loop variable
fns = append(fns, func() error {
switch desiredNode.Role {
case constants.ExternalLoadBalancerNodeRoleValue:
return createHelper.CreateExternalLoadBalancer(clusterName, desiredNode.Name)
case constants.ControlPlaneNodeRoleValue, constants.WorkerNodeRoleValue:
return createHelper.CreateNode(clusterName, desiredNode.Name, flags.image, desiredNode.Role, flags.volumes)
default:
return nil
}
})
}
log.Info("Creating nodes...")
if err := untilError(fns); err != nil {
return err
}
// add an external etcd if explicitly requested
if flags.externalEtcd {
log.Info("Getting required etcd image...")
c, err := status.FromDocker(clusterName)
if err != nil {
return err
}
etcdImage, err := c.BootstrapControlPlane().EtcdImage()
if err != nil {
return err
}
// attempt to explicitly pull the etcdImage if it doesn't exist locally
// we don't care if this errors, we'll still try to run which also pulls
_, _ = host.PullImage(etcdImage, 4)
log.Info("Creating external etcd...")
if err := createHelper.CreateExternalEtcd(clusterName, fmt.Sprintf("%s-etcd", clusterName), etcdImage); err != nil {
return err
}
}
// get the cluster
c, err := status.FromDocker(clusterName)
if err != nil {
return err
}
// writes to the nodes the cluster settings that will be re-used by kinder during the cluster lifecycle.
c.Settings = &status.ClusterSettings{
IPFamily: status.IPv4Family, // support for ipv6 is still WIP
}
if err := c.WriteSettings(); err != nil {
return err
}
// writes to the nodes the node settings
for _, n := range c.K8sNodes() {
if err := n.WriteNodeSettings(&status.NodeSettings{}); err != nil {
return err
}
}
return nil
}