in kinder/pkg/cluster/manager/actions/kubeadm-config.go [199:337]
func getKubeadmConfig(c *status.Cluster, n *status.Node, data kubeadm.ConfigData, options kubeadmConfigOptions) (string, error) {
kubeadmVersion, err := n.KubeadmVersion()
if err != nil {
return "", err
}
log.Debugf("kubeadm version %s", kubeadmVersion)
kubeadmConfigVersion := options.configVersion
if len(kubeadmConfigVersion) == 0 {
kubeadmConfigVersion = kubeadm.GetKubeadmConfigVersion(kubeadmVersion)
}
log.Debugf("using kubeadm config version %s", kubeadmConfigVersion)
// generate the "raw config", using the kubeadm config template provided by kind
rawconfig, err := kubeadm.Config(kubeadmConfigVersion, data)
if err != nil {
return "", err
}
// apply all the kinder specific settings using patches
var patches = []string{}
var jsonPatches = []kubeadm.PatchJSON6902{}
// add patches for instructing kubeadm to use the CRI runtime engine installed on a node
// NB. this is a no-op in case of containerd, because it is already the default in the raw config
// TODO: currently we are always specifying the CRI kubeadm should use; it will be nice in the future to
// have the possibility to test the kubeadm CRI autodetection
nodeCRI, err := n.CRI()
if err != nil {
return "", err
}
criConfigHelper, err := nodes.NewConfigHelper(nodeCRI)
if err != nil {
return "", err
}
criPatches, err := criConfigHelper.GetKubeadmConfigPatches(kubeadmConfigVersion, data.ControlPlane)
if err != nil {
return "", err
}
patches = append(patches, criPatches...)
// if requested automatic copy certs and the node is a controlplane node,
// add patches for adding the certificateKey value
// NB. this is a no-op in case of kubeadm config API older than v1beta2, because
// this feature was not supported before (the --certificate-key flag should be used instead)
if options.copyCertsMode == CopyCertsModeAuto && n.IsControlPlane() {
automaticCopyCertsPatches, err := kubeadm.GetAutomaticCopyCertsPatches(kubeadmConfigVersion)
if err != nil {
return "", err
}
patches = append(patches, automaticCopyCertsPatches...)
}
// add patches directory to the config
patchesDirectoryPatches, err := kubeadm.GetPatchesDirectoryPatches(kubeadmConfigVersion)
// skip if kubeadm config version is not v1beta3
if err == nil {
patches = append(patches, patchesDirectoryPatches...)
}
// if requested to use file discovery and not the first control-plane, add patches for using file discovery
if options.discoveryMode != TokenDiscovery && !(n == c.BootstrapControlPlane()) {
// remove token from config
removeTokenPatch, err := kubeadm.GetRemoveTokenPatch(kubeadmConfigVersion)
if err != nil {
return "", err
}
jsonPatches = append(jsonPatches, removeTokenPatch)
// create the discovery file on the node
// NB. this requires that kubeadm init is already completed on the BootstrapControlPlane in order
// to have CAs and admin.conf already in place
if err := createDiscoveryFile(c, n, options.discoveryMode); err != nil {
return "", errors.Wrapf(err, "failed to generate a discovery file. Please ensure that kubeadm-init is already completed")
}
// add discovery file path to the config
fileDiscoveryPatch, err := kubeadm.GetFileDiscoveryPatch(kubeadmConfigVersion)
if err != nil {
return "", err
}
patches = append(patches, fileDiscoveryPatch)
// if the file discovery does not contains the authorization credentials, add tls discovery token
if options.discoveryMode == FileDiscoveryWithoutCredentials {
tlsBootstrapPatch, err := kubeadm.GetTLSBootstrapPatch(kubeadmConfigVersion)
if err != nil {
return "", err
}
patches = append(patches, tlsBootstrapPatch)
}
}
// if the cluster is using an external etcd node, add patches for configuring access
// to external etcd cluster
if c.ExternalEtcd() != nil {
externalEtcdIP, externalEtcdIPV6, err := c.ExternalEtcd().IP()
if err != nil {
return "", errors.Wrapf(err, "failed to get IP for node: %s", c.ExternalEtcd().Name())
}
// configure the right protocol addresses
if c.Settings.IPFamily == status.IPv6Family {
externalEtcdIP = externalEtcdIPV6
}
externalEtcdPatch, err := kubeadm.GetExternalEtcdPatch(kubeadmConfigVersion, externalEtcdIP)
if err != nil {
return "", err
}
patches = append(patches, externalEtcdPatch)
}
// apply patches
patched, err := kubeadm.Build(rawconfig, patches, jsonPatches)
if err != nil {
return "", err
}
// Select the objects that are relevant for a specific node;
// if the node is the bootstrap control plane, then all the objects used as init time
if n == c.BootstrapControlPlane() {
return selectYamlFramentByKind(patched,
"ClusterConfiguration",
"InitConfiguration",
"KubeletConfiguration",
"KubeProxyConfiguration"), nil
}
// otherwise select only the JoinConfiguration
return selectYamlFramentByKind(patched,
"JoinConfiguration",
), nil
}