code: func GetControlPlaneImages(cfg *kubeadmapi.ClusterConfiguration) []string {
  	imgs := []string{}
  
  	// start with core kubernetes images
  	if cfg.UseHyperKubeImage {
  		imgs = append(imgs, GetKubernetesImage(constants.HyperKube, cfg))
  	} else {
  		imgs = append(imgs, GetKubernetesImage(constants.KubeAPIServer, cfg))
  		imgs = append(imgs, GetKubernetesImage(constants.KubeControllerManager, cfg))
  		imgs = append(imgs, GetKubernetesImage(constants.KubeScheduler, cfg))
  		imgs = append(imgs, GetKubernetesImage(constants.KubeProxy, cfg))
  	}
  
  	// pause is not available on the ci image repository so use the default image repository.
  	imgs = append(imgs, GetPauseImage(cfg))
  
  	// if etcd is not external then add the image as it will be required
  	if cfg.Etcd.Local != nil {
  		imgs = append(imgs, GetEtcdImage(cfg))
  	}
  
  	// Append the appropriate DNS images
  	if cfg.DNS.Type == kubeadmapi.CoreDNS {
  		imgs = append(imgs, GetDNSImage(cfg, constants.CoreDNSImageName))
  	} else {
  		imgs = append(imgs, GetDNSImage(cfg, constants.KubeDNSKubeDNSImageName))
  		imgs = append(imgs, GetDNSImage(cfg, constants.KubeDNSSidecarImageName))
  		imgs = append(imgs, GetDNSImage(cfg, constants.KubeDNSDnsMasqNannyImageName))
  	}
  
  	return imgs
  }
docs: // GetControlPlaneImages returns a list of container images kubeadm expects to use on a control plane node