mirror of https://github.com/k3s-io/k3s
Merge pull request #72111 from rosti/reduce-initcfg
kubeadm: Reduce the usage of InitConfigurationpull/564/head
commit
b8b689aae0
|
@ -125,7 +125,7 @@ func getSelfhostingSubCommand(in io.Reader) *cobra.Command {
|
||||||
|
|
||||||
// KubernetesVersion is not used, but we set it explicitly to avoid the lookup
|
// KubernetesVersion is not used, but we set it explicitly to avoid the lookup
|
||||||
// of the version from the internet when executing ConfigFileAndDefaultsToInternalConfig
|
// of the version from the internet when executing ConfigFileAndDefaultsToInternalConfig
|
||||||
phases.SetKubernetesVersion(cfg)
|
phases.SetKubernetesVersion(&cfg.ClusterConfiguration)
|
||||||
|
|
||||||
// This call returns the ready-to-use configuration based on the configuration file that might or might not exist and the default cfg populated by flags
|
// This call returns the ready-to-use configuration based on the configuration file that might or might not exist and the default cfg populated by flags
|
||||||
internalcfg, err := configutil.ConfigFileAndDefaultsToInternalConfig(cfgPath, cfg)
|
internalcfg, err := configutil.ConfigFileAndDefaultsToInternalConfig(cfgPath, cfg)
|
||||||
|
|
|
@ -388,7 +388,7 @@ func RunConfigView(out io.Writer, client clientset.Interface) error {
|
||||||
func uploadConfiguration(client clientset.Interface, cfgPath string, defaultcfg *kubeadmapiv1beta1.InitConfiguration) error {
|
func uploadConfiguration(client clientset.Interface, cfgPath string, defaultcfg *kubeadmapiv1beta1.InitConfiguration) error {
|
||||||
// KubernetesVersion is not used, but we set it explicitly to avoid the lookup
|
// KubernetesVersion is not used, but we set it explicitly to avoid the lookup
|
||||||
// of the version from the internet when executing ConfigFileAndDefaultsToInternalConfig
|
// of the version from the internet when executing ConfigFileAndDefaultsToInternalConfig
|
||||||
phaseutil.SetKubernetesVersion(defaultcfg)
|
phaseutil.SetKubernetesVersion(&defaultcfg.ClusterConfiguration)
|
||||||
|
|
||||||
// Default both statically and dynamically, convert to internal API type, and validate everything
|
// Default both statically and dynamically, convert to internal API type, and validate everything
|
||||||
// First argument is unset here as we shouldn't load a config file from disk
|
// First argument is unset here as we shouldn't load a config file from disk
|
||||||
|
|
|
@ -333,7 +333,7 @@ func newInitData(cmd *cobra.Command, args []string, options *initOptions, out io
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks if an external CA is provided by the user.
|
// Checks if an external CA is provided by the user.
|
||||||
externalCA, _ := certsphase.UsingExternalCA(cfg)
|
externalCA, _ := certsphase.UsingExternalCA(&cfg.ClusterConfiguration)
|
||||||
if externalCA {
|
if externalCA {
|
||||||
kubeconfigDir := kubeadmconstants.KubernetesDir
|
kubeconfigDir := kubeadmconstants.KubernetesDir
|
||||||
if options.dryRun {
|
if options.dryRun {
|
||||||
|
|
|
@ -466,14 +466,14 @@ func (j *joinData) Run() error {
|
||||||
|
|
||||||
// Continue with more specific checks based on the init configuration
|
// Continue with more specific checks based on the init configuration
|
||||||
klog.V(1).Infoln("[preflight] Running configuration dependant checks")
|
klog.V(1).Infoln("[preflight] Running configuration dependant checks")
|
||||||
if err := preflight.RunOptionalJoinNodeChecks(utilsexec.New(), initCfg, j.ignorePreflightErrors); err != nil {
|
if err := preflight.RunOptionalJoinNodeChecks(utilsexec.New(), &initCfg.ClusterConfiguration, j.ignorePreflightErrors); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if j.cfg.ControlPlane != nil {
|
if j.cfg.ControlPlane != nil {
|
||||||
// Checks if the cluster configuration supports
|
// Checks if the cluster configuration supports
|
||||||
// joining a new control plane instance and if all the necessary certificates are provided
|
// joining a new control plane instance and if all the necessary certificates are provided
|
||||||
if err := j.CheckIfReadyForAdditionalControlPlane(initCfg); err != nil {
|
if err := j.CheckIfReadyForAdditionalControlPlane(&initCfg.ClusterConfiguration); err != nil {
|
||||||
// outputs the not ready for hosting a new control plane instance message
|
// outputs the not ready for hosting a new control plane instance message
|
||||||
ctx := map[string]string{
|
ctx := map[string]string{
|
||||||
"Error": err.Error(),
|
"Error": err.Error(),
|
||||||
|
@ -539,14 +539,14 @@ func (j *joinData) Run() error {
|
||||||
|
|
||||||
// CheckIfReadyForAdditionalControlPlane ensures that the cluster is in a state that supports
|
// CheckIfReadyForAdditionalControlPlane ensures that the cluster is in a state that supports
|
||||||
// joining an additional control plane instance and if the node is ready to join
|
// joining an additional control plane instance and if the node is ready to join
|
||||||
func (j *joinData) CheckIfReadyForAdditionalControlPlane(initConfiguration *kubeadmapi.InitConfiguration) error {
|
func (j *joinData) CheckIfReadyForAdditionalControlPlane(cfg *kubeadmapi.ClusterConfiguration) error {
|
||||||
// blocks if the cluster was created without a stable control plane endpoint
|
// blocks if the cluster was created without a stable control plane endpoint
|
||||||
if initConfiguration.ControlPlaneEndpoint == "" {
|
if cfg.ControlPlaneEndpoint == "" {
|
||||||
return errors.New("unable to add a new control plane instance a cluster that doesn't have a stable controlPlaneEndpoint address")
|
return errors.New("unable to add a new control plane instance a cluster that doesn't have a stable controlPlaneEndpoint address")
|
||||||
}
|
}
|
||||||
|
|
||||||
// checks if the certificates that must be equal across contolplane instances are provided
|
// checks if the certificates that must be equal across contolplane instances are provided
|
||||||
if ret, err := certsphase.SharedCertificateExists(initConfiguration); !ret {
|
if ret, err := certsphase.SharedCertificateExists(cfg); !ret {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -586,7 +586,7 @@ func (j *joinData) PrepareForHostingControlPlane(initConfiguration *kubeadmapi.I
|
||||||
return errors.Wrap(err, "couldn't create Kubernetes client")
|
return errors.Wrap(err, "couldn't create Kubernetes client")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := etcdphase.CheckLocalEtcdClusterStatus(client, initConfiguration); err != nil {
|
if err := etcdphase.CheckLocalEtcdClusterStatus(client, &initConfiguration.ClusterConfiguration); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -638,7 +638,7 @@ func (j *joinData) BootstrapKubelet(tlsBootstrapCfg *clientcmdapi.Config, initCo
|
||||||
// register the joining node with the specified taints if the node
|
// register the joining node with the specified taints if the node
|
||||||
// is not a master. The markmaster phase will register the taints otherwise.
|
// is not a master. The markmaster phase will register the taints otherwise.
|
||||||
registerTaintsUsingFlags := j.cfg.ControlPlane == nil
|
registerTaintsUsingFlags := j.cfg.ControlPlane == nil
|
||||||
if err := kubeletphase.WriteKubeletDynamicEnvFile(initConfiguration, registerTaintsUsingFlags, kubeadmconstants.KubeletRunDirectory); err != nil {
|
if err := kubeletphase.WriteKubeletDynamicEnvFile(&initConfiguration.ClusterConfiguration, &initConfiguration.NodeRegistration, registerTaintsUsingFlags, kubeadmconstants.KubeletRunDirectory); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -690,7 +690,7 @@ func (j *joinData) PostInstallControlPlane(initConfiguration *kubeadmapi.InitCon
|
||||||
// because it needs two members as majority to agree on the consensus. You will only see this behavior between the time
|
// because it needs two members as majority to agree on the consensus. You will only see this behavior between the time
|
||||||
// etcdctl member add informs the cluster about the new member and the new member successfully establishing a connection to the existing one."
|
// etcdctl member add informs the cluster about the new member and the new member successfully establishing a connection to the existing one."
|
||||||
klog.V(1).Info("[join] adding etcd")
|
klog.V(1).Info("[join] adding etcd")
|
||||||
if err := etcdphase.CreateStackedEtcdStaticPodManifestFile(client, kubeadmconstants.GetStaticPodDirectory(), initConfiguration); err != nil {
|
if err := etcdphase.CreateStackedEtcdStaticPodManifestFile(client, kubeadmconstants.GetStaticPodDirectory(), initConfiguration.NodeRegistration.Name, &initConfiguration.ClusterConfiguration, &initConfiguration.LocalAPIEndpoint); err != nil {
|
||||||
return errors.Wrap(err, "error creating local etcd static pod manifest file")
|
return errors.Wrap(err, "error creating local etcd static pod manifest file")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,7 +95,7 @@ func runCoreDNSAddon(c workflow.RunData) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return dnsaddon.EnsureDNSAddon(cfg, client)
|
return dnsaddon.EnsureDNSAddon(&cfg.ClusterConfiguration, client)
|
||||||
}
|
}
|
||||||
|
|
||||||
// runKubeProxyAddon installs KubeProxy addon to a Kubernetes cluster
|
// runKubeProxyAddon installs KubeProxy addon to a Kubernetes cluster
|
||||||
|
@ -104,7 +104,7 @@ func runKubeProxyAddon(c workflow.RunData) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return proxyaddon.EnsureProxyAddon(cfg, client)
|
return proxyaddon.EnsureProxyAddon(&cfg.ClusterConfiguration, &cfg.LocalAPIEndpoint, client)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getAddonPhaseFlags(name string) []string {
|
func getAddonPhaseFlags(name string) []string {
|
||||||
|
|
|
@ -204,13 +204,8 @@ func runCertsSa(c workflow.RunData) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// if dryrunning, write certificates to a temporary folder (and defer restore to the path originally specified by the user)
|
|
||||||
cfg := data.Cfg()
|
|
||||||
cfg.CertificatesDir = data.CertificateWriteDir()
|
|
||||||
defer func() { cfg.CertificatesDir = data.CertificateDir() }()
|
|
||||||
|
|
||||||
// create the new service account key (or use existing)
|
// create the new service account key (or use existing)
|
||||||
return certsphase.CreateServiceAccountKeyAndPublicKeyFiles(cfg)
|
return certsphase.CreateServiceAccountKeyAndPublicKeyFiles(data.CertificateWriteDir())
|
||||||
}
|
}
|
||||||
|
|
||||||
func runCerts(c workflow.RunData) error {
|
func runCerts(c workflow.RunData) error {
|
||||||
|
|
|
@ -150,6 +150,6 @@ func runControlPlaneSubPhase(component string) func(c workflow.RunData) error {
|
||||||
cfg := data.Cfg()
|
cfg := data.Cfg()
|
||||||
|
|
||||||
fmt.Printf("[control-plane] Creating static Pod manifest for %q\n", component)
|
fmt.Printf("[control-plane] Creating static Pod manifest for %q\n", component)
|
||||||
return controlplane.CreateStaticPodFiles(data.ManifestDir(), cfg, component)
|
return controlplane.CreateStaticPodFiles(data.ManifestDir(), &cfg.ClusterConfiguration, &cfg.LocalAPIEndpoint, component)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,7 +90,7 @@ func runEtcdPhaseLocal() func(c workflow.RunData) error {
|
||||||
// Add etcd static pod spec only if external etcd is not configured
|
// Add etcd static pod spec only if external etcd is not configured
|
||||||
if cfg.Etcd.External == nil {
|
if cfg.Etcd.External == nil {
|
||||||
fmt.Printf("[etcd] Creating static Pod manifest for local etcd in %q\n", data.ManifestDir())
|
fmt.Printf("[etcd] Creating static Pod manifest for local etcd in %q\n", data.ManifestDir())
|
||||||
if err := etcdphase.CreateLocalEtcdStaticPodManifestFile(data.ManifestDir(), cfg); err != nil {
|
if err := etcdphase.CreateLocalEtcdStaticPodManifestFile(data.ManifestDir(), cfg.NodeRegistration.Name, &cfg.ClusterConfiguration, &cfg.LocalAPIEndpoint); err != nil {
|
||||||
return errors.Wrap(err, "error creating local etcd static pod manifest file")
|
return errors.Wrap(err, "error creating local etcd static pod manifest file")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -75,7 +75,7 @@ func runKubeletStart(c workflow.RunData) error {
|
||||||
// Write env file with flags for the kubelet to use. We do not need to write the --register-with-taints for the master,
|
// Write env file with flags for the kubelet to use. We do not need to write the --register-with-taints for the master,
|
||||||
// as we handle that ourselves in the markmaster phase
|
// as we handle that ourselves in the markmaster phase
|
||||||
// TODO: Maybe we want to do that some time in the future, in order to remove some logic from the markmaster phase?
|
// TODO: Maybe we want to do that some time in the future, in order to remove some logic from the markmaster phase?
|
||||||
if err := kubeletphase.WriteKubeletDynamicEnvFile(data.Cfg(), false, data.KubeletDir()); err != nil {
|
if err := kubeletphase.WriteKubeletDynamicEnvFile(&data.Cfg().ClusterConfiguration, &data.Cfg().NodeRegistration, false, data.KubeletDir()); err != nil {
|
||||||
return errors.Wrap(err, "error writing a dynamic environment file for the kubelet")
|
return errors.Wrap(err, "error writing a dynamic environment file for the kubelet")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -126,7 +126,7 @@ func runUploadKubeletConfig(c workflow.RunData) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
klog.V(1).Infof("[upload-config] Uploading the kubelet component config to a ConfigMap")
|
klog.V(1).Infof("[upload-config] Uploading the kubelet component config to a ConfigMap")
|
||||||
if err = kubeletphase.CreateConfigMap(cfg, client); err != nil {
|
if err = kubeletphase.CreateConfigMap(cfg.ClusterConfiguration.ComponentConfigs.Kubelet, cfg.KubernetesVersion, client); err != nil {
|
||||||
return errors.Wrap(err, "error creating kubelet configuration ConfigMap")
|
return errors.Wrap(err, "error creating kubelet configuration ConfigMap")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ import (
|
||||||
|
|
||||||
// SetKubernetesVersion gets the current Kubeadm version and sets it as KubeadmVersion in the config,
|
// SetKubernetesVersion gets the current Kubeadm version and sets it as KubeadmVersion in the config,
|
||||||
// unless it's already set to a value different from the default.
|
// unless it's already set to a value different from the default.
|
||||||
func SetKubernetesVersion(cfg *kubeadmapiv1beta1.InitConfiguration) {
|
func SetKubernetesVersion(cfg *kubeadmapiv1beta1.ClusterConfiguration) {
|
||||||
|
|
||||||
if cfg.KubernetesVersion != kubeadmapiv1beta1.DefaultKubernetesVersion && cfg.KubernetesVersion != "" {
|
if cfg.KubernetesVersion != kubeadmapiv1beta1.DefaultKubernetesVersion && cfg.KubernetesVersion != "" {
|
||||||
return
|
return
|
||||||
|
|
|
@ -51,7 +51,7 @@ func TestSetKubernetesVersion(t *testing.T) {
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
cfg := &kubeadmapiv1beta1.InitConfiguration{ClusterConfiguration: kubeadmapiv1beta1.ClusterConfiguration{KubernetesVersion: test.input}}
|
cfg := &kubeadmapiv1beta1.ClusterConfiguration{KubernetesVersion: test.input}
|
||||||
SetKubernetesVersion(cfg)
|
SetKubernetesVersion(cfg)
|
||||||
if cfg.KubernetesVersion != test.output {
|
if cfg.KubernetesVersion != test.output {
|
||||||
t.Fatalf("expected %q, got %q", test.output, cfg.KubernetesVersion)
|
t.Fatalf("expected %q, got %q", test.output, cfg.KubernetesVersion)
|
||||||
|
|
|
@ -212,7 +212,7 @@ func NewCmdTokenGenerate(out io.Writer) *cobra.Command {
|
||||||
func RunCreateToken(out io.Writer, client clientset.Interface, cfgPath string, cfg *kubeadmapiv1beta1.InitConfiguration, printJoinCommand bool, kubeConfigFile string) error {
|
func RunCreateToken(out io.Writer, client clientset.Interface, cfgPath string, cfg *kubeadmapiv1beta1.InitConfiguration, printJoinCommand bool, kubeConfigFile string) error {
|
||||||
// KubernetesVersion is not used, but we set it explicitly to avoid the lookup
|
// KubernetesVersion is not used, but we set it explicitly to avoid the lookup
|
||||||
// of the version from the internet when executing ConfigFileAndDefaultsToInternalConfig
|
// of the version from the internet when executing ConfigFileAndDefaultsToInternalConfig
|
||||||
phaseutil.SetKubernetesVersion(cfg)
|
phaseutil.SetKubernetesVersion(&cfg.ClusterConfiguration)
|
||||||
|
|
||||||
// This call returns the ready-to-use configuration based on the configuration file that might or might not exist and the default cfg populated by flags
|
// This call returns the ready-to-use configuration based on the configuration file that might or might not exist and the default cfg populated by flags
|
||||||
klog.V(1).Infoln("[token] loading configurations")
|
klog.V(1).Infoln("[token] loading configurations")
|
||||||
|
|
|
@ -105,7 +105,7 @@ func runDiff(flags *diffFlags, args []string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
specs := controlplane.GetStaticPodSpecs(cfg, k8sVer)
|
specs := controlplane.GetStaticPodSpecs(&cfg.ClusterConfiguration, &cfg.LocalAPIEndpoint, k8sVer)
|
||||||
for spec, pod := range specs {
|
for spec, pod := range specs {
|
||||||
var path string
|
var path string
|
||||||
switch spec {
|
switch spec {
|
||||||
|
|
|
@ -74,14 +74,14 @@ func DeployedDNSAddon(client clientset.Interface) (kubeadmapi.DNSAddOnType, stri
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnsureDNSAddon creates the kube-dns or CoreDNS addon
|
// EnsureDNSAddon creates the kube-dns or CoreDNS addon
|
||||||
func EnsureDNSAddon(cfg *kubeadmapi.InitConfiguration, client clientset.Interface) error {
|
func EnsureDNSAddon(cfg *kubeadmapi.ClusterConfiguration, client clientset.Interface) error {
|
||||||
if cfg.DNS.Type == kubeadmapi.CoreDNS {
|
if cfg.DNS.Type == kubeadmapi.CoreDNS {
|
||||||
return coreDNSAddon(cfg, client)
|
return coreDNSAddon(cfg, client)
|
||||||
}
|
}
|
||||||
return kubeDNSAddon(cfg, client)
|
return kubeDNSAddon(cfg, client)
|
||||||
}
|
}
|
||||||
|
|
||||||
func kubeDNSAddon(cfg *kubeadmapi.InitConfiguration, client clientset.Interface) error {
|
func kubeDNSAddon(cfg *kubeadmapi.ClusterConfiguration, client clientset.Interface) error {
|
||||||
if err := CreateServiceAccount(client); err != nil {
|
if err := CreateServiceAccount(client); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -103,9 +103,9 @@ func kubeDNSAddon(cfg *kubeadmapi.InitConfiguration, client clientset.Interface)
|
||||||
dnsDeploymentBytes, err := kubeadmutil.ParseTemplate(KubeDNSDeployment,
|
dnsDeploymentBytes, err := kubeadmutil.ParseTemplate(KubeDNSDeployment,
|
||||||
struct{ DeploymentName, KubeDNSImage, DNSMasqImage, SidecarImage, DNSBindAddr, DNSProbeAddr, DNSDomain, MasterTaintKey string }{
|
struct{ DeploymentName, KubeDNSImage, DNSMasqImage, SidecarImage, DNSBindAddr, DNSProbeAddr, DNSDomain, MasterTaintKey string }{
|
||||||
DeploymentName: kubeadmconstants.KubeDNSDeploymentName,
|
DeploymentName: kubeadmconstants.KubeDNSDeploymentName,
|
||||||
KubeDNSImage: images.GetDNSImage(&cfg.ClusterConfiguration, kubeadmconstants.KubeDNSKubeDNSImageName),
|
KubeDNSImage: images.GetDNSImage(cfg, kubeadmconstants.KubeDNSKubeDNSImageName),
|
||||||
DNSMasqImage: images.GetDNSImage(&cfg.ClusterConfiguration, kubeadmconstants.KubeDNSDnsMasqNannyImageName),
|
DNSMasqImage: images.GetDNSImage(cfg, kubeadmconstants.KubeDNSDnsMasqNannyImageName),
|
||||||
SidecarImage: images.GetDNSImage(&cfg.ClusterConfiguration, kubeadmconstants.KubeDNSSidecarImageName),
|
SidecarImage: images.GetDNSImage(cfg, kubeadmconstants.KubeDNSSidecarImageName),
|
||||||
DNSBindAddr: dnsBindAddr,
|
DNSBindAddr: dnsBindAddr,
|
||||||
DNSProbeAddr: dnsProbeAddr,
|
DNSProbeAddr: dnsProbeAddr,
|
||||||
DNSDomain: cfg.Networking.DNSDomain,
|
DNSDomain: cfg.Networking.DNSDomain,
|
||||||
|
@ -155,11 +155,11 @@ func createKubeDNSAddon(deploymentBytes, serviceBytes []byte, client clientset.I
|
||||||
return createDNSService(kubednsService, serviceBytes, client)
|
return createDNSService(kubednsService, serviceBytes, client)
|
||||||
}
|
}
|
||||||
|
|
||||||
func coreDNSAddon(cfg *kubeadmapi.InitConfiguration, client clientset.Interface) error {
|
func coreDNSAddon(cfg *kubeadmapi.ClusterConfiguration, client clientset.Interface) error {
|
||||||
// Get the YAML manifest
|
// Get the YAML manifest
|
||||||
coreDNSDeploymentBytes, err := kubeadmutil.ParseTemplate(CoreDNSDeployment, struct{ DeploymentName, Image, MasterTaintKey string }{
|
coreDNSDeploymentBytes, err := kubeadmutil.ParseTemplate(CoreDNSDeployment, struct{ DeploymentName, Image, MasterTaintKey string }{
|
||||||
DeploymentName: kubeadmconstants.CoreDNSDeploymentName,
|
DeploymentName: kubeadmconstants.CoreDNSDeploymentName,
|
||||||
Image: images.GetDNSImage(&cfg.ClusterConfiguration, kubeadmconstants.CoreDNSImageName),
|
Image: images.GetDNSImage(cfg, kubeadmconstants.CoreDNSImageName),
|
||||||
MasterTaintKey: kubeadmconstants.LabelNodeRoleMaster,
|
MasterTaintKey: kubeadmconstants.LabelNodeRoleMaster,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -47,13 +47,13 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
// EnsureProxyAddon creates the kube-proxy addons
|
// EnsureProxyAddon creates the kube-proxy addons
|
||||||
func EnsureProxyAddon(cfg *kubeadmapi.InitConfiguration, client clientset.Interface) error {
|
func EnsureProxyAddon(cfg *kubeadmapi.ClusterConfiguration, localEndpoint *kubeadmapi.APIEndpoint, client clientset.Interface) error {
|
||||||
if err := CreateServiceAccount(client); err != nil {
|
if err := CreateServiceAccount(client); err != nil {
|
||||||
return errors.Wrap(err, "error when creating kube-proxy service account")
|
return errors.Wrap(err, "error when creating kube-proxy service account")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate Master Enpoint kubeconfig file
|
// Generate Master Enpoint kubeconfig file
|
||||||
masterEndpoint, err := kubeadmutil.GetMasterEndpoint(cfg)
|
masterEndpoint, err := kubeadmutil.GetMasterEndpoint(cfg.ControlPlaneEndpoint, localEndpoint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -81,7 +81,7 @@ func EnsureProxyAddon(cfg *kubeadmapi.InitConfiguration, client clientset.Interf
|
||||||
return errors.Wrap(err, "error when parsing kube-proxy configmap template")
|
return errors.Wrap(err, "error when parsing kube-proxy configmap template")
|
||||||
}
|
}
|
||||||
proxyDaemonSetBytes, err = kubeadmutil.ParseTemplate(KubeProxyDaemonSet19, struct{ Image, ProxyConfigMap, ProxyConfigMapKey string }{
|
proxyDaemonSetBytes, err = kubeadmutil.ParseTemplate(KubeProxyDaemonSet19, struct{ Image, ProxyConfigMap, ProxyConfigMapKey string }{
|
||||||
Image: images.GetKubernetesImage(constants.KubeProxy, &cfg.ClusterConfiguration),
|
Image: images.GetKubernetesImage(constants.KubeProxy, cfg),
|
||||||
ProxyConfigMap: constants.KubeProxyConfigMap,
|
ProxyConfigMap: constants.KubeProxyConfigMap,
|
||||||
ProxyConfigMapKey: constants.KubeProxyConfigMapKey,
|
ProxyConfigMapKey: constants.KubeProxyConfigMapKey,
|
||||||
})
|
})
|
||||||
|
|
|
@ -223,7 +223,7 @@ func TestEnsureProxyAddon(t *testing.T) {
|
||||||
t.Errorf("test failed to set dynamic defaults: %v", err)
|
t.Errorf("test failed to set dynamic defaults: %v", err)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
err = EnsureProxyAddon(intMaster, client)
|
err = EnsureProxyAddon(&intMaster.ClusterConfiguration, &intMaster.LocalAPIEndpoint, client)
|
||||||
|
|
||||||
// Compare actual to expected errors
|
// Compare actual to expected errors
|
||||||
actErr := "No error"
|
actErr := "No error"
|
||||||
|
|
|
@ -60,12 +60,12 @@ func CreatePKIAssets(cfg *kubeadmapi.InitConfiguration) error {
|
||||||
fmt.Printf("[certs] valid certificates and keys now exist in %q\n", cfg.CertificatesDir)
|
fmt.Printf("[certs] valid certificates and keys now exist in %q\n", cfg.CertificatesDir)
|
||||||
|
|
||||||
// Service accounts are not x509 certs, so handled separately
|
// Service accounts are not x509 certs, so handled separately
|
||||||
return CreateServiceAccountKeyAndPublicKeyFiles(cfg)
|
return CreateServiceAccountKeyAndPublicKeyFiles(cfg.CertificatesDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateServiceAccountKeyAndPublicKeyFiles create a new public/private key files for signing service account users.
|
// CreateServiceAccountKeyAndPublicKeyFiles create a new public/private key files for signing service account users.
|
||||||
// If the sa public/private key files already exists in the target folder, they are used only if evaluated equals; otherwise an error is returned.
|
// If the sa public/private key files already exists in the target folder, they are used only if evaluated equals; otherwise an error is returned.
|
||||||
func CreateServiceAccountKeyAndPublicKeyFiles(cfg *kubeadmapi.InitConfiguration) error {
|
func CreateServiceAccountKeyAndPublicKeyFiles(certsDir string) error {
|
||||||
klog.V(1).Infoln("creating a new public/private key files for signing service account users")
|
klog.V(1).Infoln("creating a new public/private key files for signing service account users")
|
||||||
saSigningKey, err := NewServiceAccountSigningKey()
|
saSigningKey, err := NewServiceAccountSigningKey()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -73,7 +73,7 @@ func CreateServiceAccountKeyAndPublicKeyFiles(cfg *kubeadmapi.InitConfiguration)
|
||||||
}
|
}
|
||||||
|
|
||||||
return writeKeyFilesIfNotExist(
|
return writeKeyFilesIfNotExist(
|
||||||
cfg.CertificatesDir,
|
certsDir,
|
||||||
kubeadmconstants.ServiceAccountKeyBaseName,
|
kubeadmconstants.ServiceAccountKeyBaseName,
|
||||||
saSigningKey,
|
saSigningKey,
|
||||||
)
|
)
|
||||||
|
@ -329,7 +329,7 @@ type certKeyLocation struct {
|
||||||
|
|
||||||
// SharedCertificateExists verifies if the shared certificates - the certificates that must be
|
// SharedCertificateExists verifies if the shared certificates - the certificates that must be
|
||||||
// equal across masters: ca.key, ca.crt, sa.key, sa.pub + etcd/ca.key, etcd/ca.crt if local/stacked etcd
|
// equal across masters: ca.key, ca.crt, sa.key, sa.pub + etcd/ca.key, etcd/ca.crt if local/stacked etcd
|
||||||
func SharedCertificateExists(cfg *kubeadmapi.InitConfiguration) (bool, error) {
|
func SharedCertificateExists(cfg *kubeadmapi.ClusterConfiguration) (bool, error) {
|
||||||
|
|
||||||
if err := validateCACertAndKey(certKeyLocation{cfg.CertificatesDir, kubeadmconstants.CACertAndKeyBaseName, "", "CA"}); err != nil {
|
if err := validateCACertAndKey(certKeyLocation{cfg.CertificatesDir, kubeadmconstants.CACertAndKeyBaseName, "", "CA"}); err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
|
@ -356,7 +356,7 @@ func SharedCertificateExists(cfg *kubeadmapi.InitConfiguration) (bool, error) {
|
||||||
// UsingExternalCA determines whether the user is relying on an external CA. We currently implicitly determine this is the case
|
// UsingExternalCA determines whether the user is relying on an external CA. We currently implicitly determine this is the case
|
||||||
// when both the CA Cert and the front proxy CA Cert are present but the CA Key and front proxy CA Key are not.
|
// when both the CA Cert and the front proxy CA Cert are present but the CA Key and front proxy CA Key are not.
|
||||||
// This allows us to, e.g., skip generating certs or not start the csr signing controller.
|
// This allows us to, e.g., skip generating certs or not start the csr signing controller.
|
||||||
func UsingExternalCA(cfg *kubeadmapi.InitConfiguration) (bool, error) {
|
func UsingExternalCA(cfg *kubeadmapi.ClusterConfiguration) (bool, error) {
|
||||||
|
|
||||||
if err := validateCACert(certKeyLocation{cfg.CertificatesDir, kubeadmconstants.CACertAndKeyBaseName, "", "CA"}); err != nil {
|
if err := validateCACert(certKeyLocation{cfg.CertificatesDir, kubeadmconstants.CACertAndKeyBaseName, "", "CA"}); err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
|
|
|
@ -463,10 +463,8 @@ func TestSharedCertificateExists(t *testing.T) {
|
||||||
os.MkdirAll(tmpdir+"/etcd", os.ModePerm)
|
os.MkdirAll(tmpdir+"/etcd", os.ModePerm)
|
||||||
defer os.RemoveAll(tmpdir)
|
defer os.RemoveAll(tmpdir)
|
||||||
|
|
||||||
cfg := &kubeadmapi.InitConfiguration{
|
cfg := &kubeadmapi.ClusterConfiguration{
|
||||||
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
|
CertificatesDir: tmpdir,
|
||||||
CertificatesDir: tmpdir,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// created expected keys
|
// created expected keys
|
||||||
|
@ -554,7 +552,7 @@ func TestUsingExternalCA(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if val, _ := UsingExternalCA(cfg); val != test.expected {
|
if val, _ := UsingExternalCA(&cfg.ClusterConfiguration); val != test.expected {
|
||||||
t.Errorf("UsingExternalCA did not match expected: %v", test.expected)
|
t.Errorf("UsingExternalCA did not match expected: %v", test.expected)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,7 @@ go_library(
|
||||||
"//cmd/kubeadm/app/util/staticpod:go_default_library",
|
"//cmd/kubeadm/app/util/staticpod:go_default_library",
|
||||||
"//pkg/kubeapiserver/authorizer/modes:go_default_library",
|
"//pkg/kubeapiserver/authorizer/modes:go_default_library",
|
||||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/version:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/version:go_default_library",
|
||||||
"//vendor/github.com/pkg/errors:go_default_library",
|
"//vendor/github.com/pkg/errors:go_default_library",
|
||||||
|
|
|
@ -26,6 +26,7 @@ import (
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"k8s.io/api/core/v1"
|
"k8s.io/api/core/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/util/intstr"
|
||||||
"k8s.io/apimachinery/pkg/util/version"
|
"k8s.io/apimachinery/pkg/util/version"
|
||||||
"k8s.io/klog"
|
"k8s.io/klog"
|
||||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||||
|
@ -40,12 +41,12 @@ import (
|
||||||
// CreateInitStaticPodManifestFiles will write all static pod manifest files needed to bring up the control plane.
|
// CreateInitStaticPodManifestFiles will write all static pod manifest files needed to bring up the control plane.
|
||||||
func CreateInitStaticPodManifestFiles(manifestDir string, cfg *kubeadmapi.InitConfiguration) error {
|
func CreateInitStaticPodManifestFiles(manifestDir string, cfg *kubeadmapi.InitConfiguration) error {
|
||||||
klog.V(1).Infoln("[control-plane] creating static Pod files")
|
klog.V(1).Infoln("[control-plane] creating static Pod files")
|
||||||
return CreateStaticPodFiles(manifestDir, cfg, kubeadmconstants.KubeAPIServer, kubeadmconstants.KubeControllerManager, kubeadmconstants.KubeScheduler)
|
return CreateStaticPodFiles(manifestDir, &cfg.ClusterConfiguration, &cfg.LocalAPIEndpoint, kubeadmconstants.KubeAPIServer, kubeadmconstants.KubeControllerManager, kubeadmconstants.KubeScheduler)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetStaticPodSpecs returns all staticPodSpecs actualized to the context of the current InitConfiguration
|
// GetStaticPodSpecs returns all staticPodSpecs actualized to the context of the current configuration
|
||||||
// NB. this methods holds the information about how kubeadm creates static pod manifests.
|
// NB. this methods holds the information about how kubeadm creates static pod manifests.
|
||||||
func GetStaticPodSpecs(cfg *kubeadmapi.InitConfiguration, k8sVersion *version.Version) map[string]v1.Pod {
|
func GetStaticPodSpecs(cfg *kubeadmapi.ClusterConfiguration, endpoint *kubeadmapi.APIEndpoint, k8sVersion *version.Version) map[string]v1.Pod {
|
||||||
// Get the required hostpath mounts
|
// Get the required hostpath mounts
|
||||||
mounts := getHostPathVolumesForTheControlPlane(cfg)
|
mounts := getHostPathVolumesForTheControlPlane(cfg)
|
||||||
|
|
||||||
|
@ -53,31 +54,31 @@ func GetStaticPodSpecs(cfg *kubeadmapi.InitConfiguration, k8sVersion *version.Ve
|
||||||
staticPodSpecs := map[string]v1.Pod{
|
staticPodSpecs := map[string]v1.Pod{
|
||||||
kubeadmconstants.KubeAPIServer: staticpodutil.ComponentPod(v1.Container{
|
kubeadmconstants.KubeAPIServer: staticpodutil.ComponentPod(v1.Container{
|
||||||
Name: kubeadmconstants.KubeAPIServer,
|
Name: kubeadmconstants.KubeAPIServer,
|
||||||
Image: images.GetKubernetesImage(kubeadmconstants.KubeAPIServer, &cfg.ClusterConfiguration),
|
Image: images.GetKubernetesImage(kubeadmconstants.KubeAPIServer, cfg),
|
||||||
ImagePullPolicy: v1.PullIfNotPresent,
|
ImagePullPolicy: v1.PullIfNotPresent,
|
||||||
Command: getAPIServerCommand(cfg),
|
Command: getAPIServerCommand(cfg, endpoint),
|
||||||
VolumeMounts: staticpodutil.VolumeMountMapToSlice(mounts.GetVolumeMounts(kubeadmconstants.KubeAPIServer)),
|
VolumeMounts: staticpodutil.VolumeMountMapToSlice(mounts.GetVolumeMounts(kubeadmconstants.KubeAPIServer)),
|
||||||
LivenessProbe: staticpodutil.ComponentProbe(cfg, kubeadmconstants.KubeAPIServer, int(cfg.LocalAPIEndpoint.BindPort), "/healthz", v1.URISchemeHTTPS),
|
LivenessProbe: livenessProbe(staticpodutil.GetAPIServerProbeAddress(endpoint), int(endpoint.BindPort), v1.URISchemeHTTPS),
|
||||||
Resources: staticpodutil.ComponentResources("250m"),
|
Resources: staticpodutil.ComponentResources("250m"),
|
||||||
Env: getProxyEnvVars(),
|
Env: getProxyEnvVars(),
|
||||||
}, mounts.GetVolumes(kubeadmconstants.KubeAPIServer)),
|
}, mounts.GetVolumes(kubeadmconstants.KubeAPIServer)),
|
||||||
kubeadmconstants.KubeControllerManager: staticpodutil.ComponentPod(v1.Container{
|
kubeadmconstants.KubeControllerManager: staticpodutil.ComponentPod(v1.Container{
|
||||||
Name: kubeadmconstants.KubeControllerManager,
|
Name: kubeadmconstants.KubeControllerManager,
|
||||||
Image: images.GetKubernetesImage(kubeadmconstants.KubeControllerManager, &cfg.ClusterConfiguration),
|
Image: images.GetKubernetesImage(kubeadmconstants.KubeControllerManager, cfg),
|
||||||
ImagePullPolicy: v1.PullIfNotPresent,
|
ImagePullPolicy: v1.PullIfNotPresent,
|
||||||
Command: getControllerManagerCommand(cfg, k8sVersion),
|
Command: getControllerManagerCommand(cfg, k8sVersion),
|
||||||
VolumeMounts: staticpodutil.VolumeMountMapToSlice(mounts.GetVolumeMounts(kubeadmconstants.KubeControllerManager)),
|
VolumeMounts: staticpodutil.VolumeMountMapToSlice(mounts.GetVolumeMounts(kubeadmconstants.KubeControllerManager)),
|
||||||
LivenessProbe: staticpodutil.ComponentProbe(cfg, kubeadmconstants.KubeControllerManager, 10252, "/healthz", v1.URISchemeHTTP),
|
LivenessProbe: livenessProbe(staticpodutil.GetControllerManagerProbeAddress(cfg), 10252, v1.URISchemeHTTP),
|
||||||
Resources: staticpodutil.ComponentResources("200m"),
|
Resources: staticpodutil.ComponentResources("200m"),
|
||||||
Env: getProxyEnvVars(),
|
Env: getProxyEnvVars(),
|
||||||
}, mounts.GetVolumes(kubeadmconstants.KubeControllerManager)),
|
}, mounts.GetVolumes(kubeadmconstants.KubeControllerManager)),
|
||||||
kubeadmconstants.KubeScheduler: staticpodutil.ComponentPod(v1.Container{
|
kubeadmconstants.KubeScheduler: staticpodutil.ComponentPod(v1.Container{
|
||||||
Name: kubeadmconstants.KubeScheduler,
|
Name: kubeadmconstants.KubeScheduler,
|
||||||
Image: images.GetKubernetesImage(kubeadmconstants.KubeScheduler, &cfg.ClusterConfiguration),
|
Image: images.GetKubernetesImage(kubeadmconstants.KubeScheduler, cfg),
|
||||||
ImagePullPolicy: v1.PullIfNotPresent,
|
ImagePullPolicy: v1.PullIfNotPresent,
|
||||||
Command: getSchedulerCommand(cfg),
|
Command: getSchedulerCommand(cfg),
|
||||||
VolumeMounts: staticpodutil.VolumeMountMapToSlice(mounts.GetVolumeMounts(kubeadmconstants.KubeScheduler)),
|
VolumeMounts: staticpodutil.VolumeMountMapToSlice(mounts.GetVolumeMounts(kubeadmconstants.KubeScheduler)),
|
||||||
LivenessProbe: staticpodutil.ComponentProbe(cfg, kubeadmconstants.KubeScheduler, 10251, "/healthz", v1.URISchemeHTTP),
|
LivenessProbe: livenessProbe(staticpodutil.GetSchedulerProbeAddress(cfg), 10251, v1.URISchemeHTTP),
|
||||||
Resources: staticpodutil.ComponentResources("100m"),
|
Resources: staticpodutil.ComponentResources("100m"),
|
||||||
Env: getProxyEnvVars(),
|
Env: getProxyEnvVars(),
|
||||||
}, mounts.GetVolumes(kubeadmconstants.KubeScheduler)),
|
}, mounts.GetVolumes(kubeadmconstants.KubeScheduler)),
|
||||||
|
@ -85,17 +86,33 @@ func GetStaticPodSpecs(cfg *kubeadmapi.InitConfiguration, k8sVersion *version.Ve
|
||||||
return staticPodSpecs
|
return staticPodSpecs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func livenessProbe(host string, port int, scheme v1.URIScheme) *v1.Probe {
|
||||||
|
return &v1.Probe{
|
||||||
|
Handler: v1.Handler{
|
||||||
|
HTTPGet: &v1.HTTPGetAction{
|
||||||
|
Host: host,
|
||||||
|
Path: "/healthz",
|
||||||
|
Port: intstr.FromInt(port),
|
||||||
|
Scheme: scheme,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
InitialDelaySeconds: 15,
|
||||||
|
TimeoutSeconds: 15,
|
||||||
|
FailureThreshold: 8,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// CreateStaticPodFiles creates all the requested static pod files.
|
// CreateStaticPodFiles creates all the requested static pod files.
|
||||||
func CreateStaticPodFiles(manifestDir string, cfg *kubeadmapi.InitConfiguration, componentNames ...string) error {
|
func CreateStaticPodFiles(manifestDir string, cfg *kubeadmapi.ClusterConfiguration, endpoint *kubeadmapi.APIEndpoint, componentNames ...string) error {
|
||||||
// TODO: Move the "pkg/util/version".Version object into the internal API instead of always parsing the string
|
// TODO: Move the "pkg/util/version".Version object into the internal API instead of always parsing the string
|
||||||
k8sVersion, err := version.ParseSemantic(cfg.KubernetesVersion)
|
k8sVersion, err := version.ParseSemantic(cfg.KubernetesVersion)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// gets the StaticPodSpecs, actualized for the current InitConfiguration
|
// gets the StaticPodSpecs, actualized for the current ClusterConfiguration
|
||||||
klog.V(1).Infoln("[control-plane] getting StaticPodSpecs")
|
klog.V(1).Infoln("[control-plane] getting StaticPodSpecs")
|
||||||
specs := GetStaticPodSpecs(cfg, k8sVersion)
|
specs := GetStaticPodSpecs(cfg, endpoint, k8sVersion)
|
||||||
|
|
||||||
// creates required static pod specs
|
// creates required static pod specs
|
||||||
for _, componentName := range componentNames {
|
for _, componentName := range componentNames {
|
||||||
|
@ -117,9 +134,9 @@ func CreateStaticPodFiles(manifestDir string, cfg *kubeadmapi.InitConfiguration,
|
||||||
}
|
}
|
||||||
|
|
||||||
// getAPIServerCommand builds the right API server command from the given config object and version
|
// getAPIServerCommand builds the right API server command from the given config object and version
|
||||||
func getAPIServerCommand(cfg *kubeadmapi.InitConfiguration) []string {
|
func getAPIServerCommand(cfg *kubeadmapi.ClusterConfiguration, localAPIEndpoint *kubeadmapi.APIEndpoint) []string {
|
||||||
defaultArguments := map[string]string{
|
defaultArguments := map[string]string{
|
||||||
"advertise-address": cfg.LocalAPIEndpoint.AdvertiseAddress,
|
"advertise-address": localAPIEndpoint.AdvertiseAddress,
|
||||||
"enable-admission-plugins": "NodeRestriction",
|
"enable-admission-plugins": "NodeRestriction",
|
||||||
"service-cluster-ip-range": cfg.Networking.ServiceSubnet,
|
"service-cluster-ip-range": cfg.Networking.ServiceSubnet,
|
||||||
"service-account-key-file": filepath.Join(cfg.CertificatesDir, kubeadmconstants.ServiceAccountPublicKeyName),
|
"service-account-key-file": filepath.Join(cfg.CertificatesDir, kubeadmconstants.ServiceAccountPublicKeyName),
|
||||||
|
@ -129,7 +146,7 @@ func getAPIServerCommand(cfg *kubeadmapi.InitConfiguration) []string {
|
||||||
"kubelet-client-certificate": filepath.Join(cfg.CertificatesDir, kubeadmconstants.APIServerKubeletClientCertName),
|
"kubelet-client-certificate": filepath.Join(cfg.CertificatesDir, kubeadmconstants.APIServerKubeletClientCertName),
|
||||||
"kubelet-client-key": filepath.Join(cfg.CertificatesDir, kubeadmconstants.APIServerKubeletClientKeyName),
|
"kubelet-client-key": filepath.Join(cfg.CertificatesDir, kubeadmconstants.APIServerKubeletClientKeyName),
|
||||||
"enable-bootstrap-token-auth": "true",
|
"enable-bootstrap-token-auth": "true",
|
||||||
"secure-port": fmt.Sprintf("%d", cfg.LocalAPIEndpoint.BindPort),
|
"secure-port": fmt.Sprintf("%d", localAPIEndpoint.BindPort),
|
||||||
"allow-privileged": "true",
|
"allow-privileged": "true",
|
||||||
"kubelet-preferred-address-types": "InternalIP,ExternalIP,Hostname",
|
"kubelet-preferred-address-types": "InternalIP,ExternalIP,Hostname",
|
||||||
// add options to configure the front proxy. Without the generated client cert, this will never be useable
|
// add options to configure the front proxy. Without the generated client cert, this will never be useable
|
||||||
|
@ -243,7 +260,7 @@ func calcNodeCidrSize(podSubnet string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// getControllerManagerCommand builds the right controller manager command from the given config object and version
|
// getControllerManagerCommand builds the right controller manager command from the given config object and version
|
||||||
func getControllerManagerCommand(cfg *kubeadmapi.InitConfiguration, k8sVersion *version.Version) []string {
|
func getControllerManagerCommand(cfg *kubeadmapi.ClusterConfiguration, k8sVersion *version.Version) []string {
|
||||||
|
|
||||||
kubeconfigFile := filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.ControllerManagerKubeConfigFileName)
|
kubeconfigFile := filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.ControllerManagerKubeConfigFileName)
|
||||||
caFile := filepath.Join(cfg.CertificatesDir, kubeadmconstants.CACertName)
|
caFile := filepath.Join(cfg.CertificatesDir, kubeadmconstants.CACertName)
|
||||||
|
@ -287,7 +304,7 @@ func getControllerManagerCommand(cfg *kubeadmapi.InitConfiguration, k8sVersion *
|
||||||
}
|
}
|
||||||
|
|
||||||
// getSchedulerCommand builds the right scheduler command from the given config object and version
|
// getSchedulerCommand builds the right scheduler command from the given config object and version
|
||||||
func getSchedulerCommand(cfg *kubeadmapi.InitConfiguration) []string {
|
func getSchedulerCommand(cfg *kubeadmapi.ClusterConfiguration) []string {
|
||||||
defaultArguments := map[string]string{
|
defaultArguments := map[string]string{
|
||||||
"bind-address": "127.0.0.1",
|
"bind-address": "127.0.0.1",
|
||||||
"leader-elect": "true",
|
"leader-elect": "true",
|
||||||
|
|
|
@ -44,11 +44,9 @@ var cpVersion = kubeadmconstants.MinimumControlPlaneVersion.WithPreRelease("beta
|
||||||
|
|
||||||
func TestGetStaticPodSpecs(t *testing.T) {
|
func TestGetStaticPodSpecs(t *testing.T) {
|
||||||
|
|
||||||
// Creates a Master Configuration
|
// Creates a Cluster Configuration
|
||||||
cfg := &kubeadmapi.InitConfiguration{
|
cfg := &kubeadmapi.ClusterConfiguration{
|
||||||
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
|
KubernetesVersion: "v1.9.0",
|
||||||
KubernetesVersion: "v1.9.0",
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Executes GetStaticPodSpecs
|
// Executes GetStaticPodSpecs
|
||||||
|
@ -56,7 +54,7 @@ func TestGetStaticPodSpecs(t *testing.T) {
|
||||||
// TODO: Move the "pkg/util/version".Version object into the internal API instead of always parsing the string
|
// TODO: Move the "pkg/util/version".Version object into the internal API instead of always parsing the string
|
||||||
k8sVersion, _ := version.ParseSemantic(cfg.KubernetesVersion)
|
k8sVersion, _ := version.ParseSemantic(cfg.KubernetesVersion)
|
||||||
|
|
||||||
specs := GetStaticPodSpecs(cfg, k8sVersion)
|
specs := GetStaticPodSpecs(cfg, &kubeadmapi.APIEndpoint{}, k8sVersion)
|
||||||
|
|
||||||
var assertions = []struct {
|
var assertions = []struct {
|
||||||
staticPodName string
|
staticPodName string
|
||||||
|
@ -113,16 +111,14 @@ func TestCreateStaticPodFilesAndWrappers(t *testing.T) {
|
||||||
tmpdir := testutil.SetupTempDir(t)
|
tmpdir := testutil.SetupTempDir(t)
|
||||||
defer os.RemoveAll(tmpdir)
|
defer os.RemoveAll(tmpdir)
|
||||||
|
|
||||||
// Creates a Master Configuration
|
// Creates a Cluster Configuration
|
||||||
cfg := &kubeadmapi.InitConfiguration{
|
cfg := &kubeadmapi.ClusterConfiguration{
|
||||||
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
|
KubernetesVersion: "v1.9.0",
|
||||||
KubernetesVersion: "v1.9.0",
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute createStaticPodFunction
|
// Execute createStaticPodFunction
|
||||||
manifestPath := filepath.Join(tmpdir, kubeadmconstants.ManifestsSubDirName)
|
manifestPath := filepath.Join(tmpdir, kubeadmconstants.ManifestsSubDirName)
|
||||||
err := CreateStaticPodFiles(manifestPath, cfg, test.components...)
|
err := CreateStaticPodFiles(manifestPath, cfg, &kubeadmapi.APIEndpoint{}, test.components...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Error executing createStaticPodFunction: %v", err)
|
t.Errorf("Error executing createStaticPodFunction: %v", err)
|
||||||
continue
|
continue
|
||||||
|
@ -140,18 +136,17 @@ func TestCreateStaticPodFilesAndWrappers(t *testing.T) {
|
||||||
func TestGetAPIServerCommand(t *testing.T) {
|
func TestGetAPIServerCommand(t *testing.T) {
|
||||||
var tests = []struct {
|
var tests = []struct {
|
||||||
name string
|
name string
|
||||||
cfg *kubeadmapi.InitConfiguration
|
cfg *kubeadmapi.ClusterConfiguration
|
||||||
|
endpoint *kubeadmapi.APIEndpoint
|
||||||
expected []string
|
expected []string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "testing defaults",
|
name: "testing defaults",
|
||||||
cfg: &kubeadmapi.InitConfiguration{
|
cfg: &kubeadmapi.ClusterConfiguration{
|
||||||
LocalAPIEndpoint: kubeadmapi.APIEndpoint{BindPort: 123, AdvertiseAddress: "1.2.3.4"},
|
Networking: kubeadmapi.Networking{ServiceSubnet: "bar"},
|
||||||
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
|
CertificatesDir: testCertsDir,
|
||||||
Networking: kubeadmapi.Networking{ServiceSubnet: "bar"},
|
|
||||||
CertificatesDir: testCertsDir,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
endpoint: &kubeadmapi.APIEndpoint{BindPort: 123, AdvertiseAddress: "1.2.3.4"},
|
||||||
expected: []string{
|
expected: []string{
|
||||||
"kube-apiserver",
|
"kube-apiserver",
|
||||||
"--enable-admission-plugins=NodeRestriction",
|
"--enable-admission-plugins=NodeRestriction",
|
||||||
|
@ -183,13 +178,11 @@ func TestGetAPIServerCommand(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "ipv6 advertise address",
|
name: "ipv6 advertise address",
|
||||||
cfg: &kubeadmapi.InitConfiguration{
|
cfg: &kubeadmapi.ClusterConfiguration{
|
||||||
LocalAPIEndpoint: kubeadmapi.APIEndpoint{BindPort: 123, AdvertiseAddress: "2001:db8::1"},
|
Networking: kubeadmapi.Networking{ServiceSubnet: "bar"},
|
||||||
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
|
CertificatesDir: testCertsDir,
|
||||||
Networking: kubeadmapi.Networking{ServiceSubnet: "bar"},
|
|
||||||
CertificatesDir: testCertsDir,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
endpoint: &kubeadmapi.APIEndpoint{BindPort: 123, AdvertiseAddress: "2001:db8::1"},
|
||||||
expected: []string{
|
expected: []string{
|
||||||
"kube-apiserver",
|
"kube-apiserver",
|
||||||
"--enable-admission-plugins=NodeRestriction",
|
"--enable-admission-plugins=NodeRestriction",
|
||||||
|
@ -221,21 +214,19 @@ func TestGetAPIServerCommand(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "an external etcd with custom ca, certs and keys",
|
name: "an external etcd with custom ca, certs and keys",
|
||||||
cfg: &kubeadmapi.InitConfiguration{
|
cfg: &kubeadmapi.ClusterConfiguration{
|
||||||
LocalAPIEndpoint: kubeadmapi.APIEndpoint{BindPort: 123, AdvertiseAddress: "2001:db8::1"},
|
Networking: kubeadmapi.Networking{ServiceSubnet: "bar"},
|
||||||
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
|
Etcd: kubeadmapi.Etcd{
|
||||||
Networking: kubeadmapi.Networking{ServiceSubnet: "bar"},
|
External: &kubeadmapi.ExternalEtcd{
|
||||||
Etcd: kubeadmapi.Etcd{
|
Endpoints: []string{"https://8.6.4.1:2379", "https://8.6.4.2:2379"},
|
||||||
External: &kubeadmapi.ExternalEtcd{
|
CAFile: "fuz",
|
||||||
Endpoints: []string{"https://8.6.4.1:2379", "https://8.6.4.2:2379"},
|
CertFile: "fiz",
|
||||||
CAFile: "fuz",
|
KeyFile: "faz",
|
||||||
CertFile: "fiz",
|
|
||||||
KeyFile: "faz",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
CertificatesDir: testCertsDir,
|
|
||||||
},
|
},
|
||||||
|
CertificatesDir: testCertsDir,
|
||||||
},
|
},
|
||||||
|
endpoint: &kubeadmapi.APIEndpoint{BindPort: 123, AdvertiseAddress: "2001:db8::1"},
|
||||||
expected: []string{
|
expected: []string{
|
||||||
"kube-apiserver",
|
"kube-apiserver",
|
||||||
"--enable-admission-plugins=NodeRestriction",
|
"--enable-admission-plugins=NodeRestriction",
|
||||||
|
@ -267,18 +258,16 @@ func TestGetAPIServerCommand(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "an insecure etcd",
|
name: "an insecure etcd",
|
||||||
cfg: &kubeadmapi.InitConfiguration{
|
cfg: &kubeadmapi.ClusterConfiguration{
|
||||||
LocalAPIEndpoint: kubeadmapi.APIEndpoint{BindPort: 123, AdvertiseAddress: "2001:db8::1"},
|
Networking: kubeadmapi.Networking{ServiceSubnet: "bar"},
|
||||||
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
|
Etcd: kubeadmapi.Etcd{
|
||||||
Networking: kubeadmapi.Networking{ServiceSubnet: "bar"},
|
External: &kubeadmapi.ExternalEtcd{
|
||||||
Etcd: kubeadmapi.Etcd{
|
Endpoints: []string{"http://127.0.0.1:2379", "http://127.0.0.1:2380"},
|
||||||
External: &kubeadmapi.ExternalEtcd{
|
|
||||||
Endpoints: []string{"http://127.0.0.1:2379", "http://127.0.0.1:2380"},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
CertificatesDir: testCertsDir,
|
|
||||||
},
|
},
|
||||||
|
CertificatesDir: testCertsDir,
|
||||||
},
|
},
|
||||||
|
endpoint: &kubeadmapi.APIEndpoint{BindPort: 123, AdvertiseAddress: "2001:db8::1"},
|
||||||
expected: []string{
|
expected: []string{
|
||||||
"kube-apiserver",
|
"kube-apiserver",
|
||||||
"--enable-admission-plugins=NodeRestriction",
|
"--enable-admission-plugins=NodeRestriction",
|
||||||
|
@ -307,23 +296,21 @@ func TestGetAPIServerCommand(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "test APIServer.ExtraArgs works as expected",
|
name: "test APIServer.ExtraArgs works as expected",
|
||||||
cfg: &kubeadmapi.InitConfiguration{
|
cfg: &kubeadmapi.ClusterConfiguration{
|
||||||
LocalAPIEndpoint: kubeadmapi.APIEndpoint{BindPort: 123, AdvertiseAddress: "1.2.3.4"},
|
Networking: kubeadmapi.Networking{ServiceSubnet: "bar"},
|
||||||
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
|
CertificatesDir: testCertsDir,
|
||||||
Networking: kubeadmapi.Networking{ServiceSubnet: "bar"},
|
APIServer: kubeadmapi.APIServer{
|
||||||
CertificatesDir: testCertsDir,
|
ControlPlaneComponent: kubeadmapi.ControlPlaneComponent{
|
||||||
APIServer: kubeadmapi.APIServer{
|
ExtraArgs: map[string]string{
|
||||||
ControlPlaneComponent: kubeadmapi.ControlPlaneComponent{
|
"service-cluster-ip-range": "baz",
|
||||||
ExtraArgs: map[string]string{
|
"advertise-address": "9.9.9.9",
|
||||||
"service-cluster-ip-range": "baz",
|
"audit-policy-file": "/etc/config/audit.yaml",
|
||||||
"advertise-address": "9.9.9.9",
|
"audit-log-path": "/var/log/kubernetes",
|
||||||
"audit-policy-file": "/etc/config/audit.yaml",
|
|
||||||
"audit-log-path": "/var/log/kubernetes",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
endpoint: &kubeadmapi.APIEndpoint{BindPort: 123, AdvertiseAddress: "1.2.3.4"},
|
||||||
expected: []string{
|
expected: []string{
|
||||||
"kube-apiserver",
|
"kube-apiserver",
|
||||||
"--enable-admission-plugins=NodeRestriction",
|
"--enable-admission-plugins=NodeRestriction",
|
||||||
|
@ -357,20 +344,18 @@ func TestGetAPIServerCommand(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "authorization-mode extra-args ABAC",
|
name: "authorization-mode extra-args ABAC",
|
||||||
cfg: &kubeadmapi.InitConfiguration{
|
cfg: &kubeadmapi.ClusterConfiguration{
|
||||||
LocalAPIEndpoint: kubeadmapi.APIEndpoint{BindPort: 123, AdvertiseAddress: "1.2.3.4"},
|
Networking: kubeadmapi.Networking{ServiceSubnet: "bar"},
|
||||||
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
|
CertificatesDir: testCertsDir,
|
||||||
Networking: kubeadmapi.Networking{ServiceSubnet: "bar"},
|
APIServer: kubeadmapi.APIServer{
|
||||||
CertificatesDir: testCertsDir,
|
ControlPlaneComponent: kubeadmapi.ControlPlaneComponent{
|
||||||
APIServer: kubeadmapi.APIServer{
|
ExtraArgs: map[string]string{
|
||||||
ControlPlaneComponent: kubeadmapi.ControlPlaneComponent{
|
"authorization-mode": authzmodes.ModeABAC,
|
||||||
ExtraArgs: map[string]string{
|
|
||||||
"authorization-mode": authzmodes.ModeABAC,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
endpoint: &kubeadmapi.APIEndpoint{BindPort: 123, AdvertiseAddress: "1.2.3.4"},
|
||||||
expected: []string{
|
expected: []string{
|
||||||
"kube-apiserver",
|
"kube-apiserver",
|
||||||
"--enable-admission-plugins=NodeRestriction",
|
"--enable-admission-plugins=NodeRestriction",
|
||||||
|
@ -402,20 +387,18 @@ func TestGetAPIServerCommand(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "secure-port extra-args",
|
name: "secure-port extra-args",
|
||||||
cfg: &kubeadmapi.InitConfiguration{
|
cfg: &kubeadmapi.ClusterConfiguration{
|
||||||
LocalAPIEndpoint: kubeadmapi.APIEndpoint{BindPort: 123, AdvertiseAddress: "1.2.3.4"},
|
Networking: kubeadmapi.Networking{ServiceSubnet: "bar"},
|
||||||
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
|
CertificatesDir: testCertsDir,
|
||||||
Networking: kubeadmapi.Networking{ServiceSubnet: "bar"},
|
APIServer: kubeadmapi.APIServer{
|
||||||
CertificatesDir: testCertsDir,
|
ControlPlaneComponent: kubeadmapi.ControlPlaneComponent{
|
||||||
APIServer: kubeadmapi.APIServer{
|
ExtraArgs: map[string]string{
|
||||||
ControlPlaneComponent: kubeadmapi.ControlPlaneComponent{
|
"secure-port": "123",
|
||||||
ExtraArgs: map[string]string{
|
|
||||||
"secure-port": "123",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
endpoint: &kubeadmapi.APIEndpoint{BindPort: 123, AdvertiseAddress: "1.2.3.4"},
|
||||||
expected: []string{
|
expected: []string{
|
||||||
"kube-apiserver",
|
"kube-apiserver",
|
||||||
"--enable-admission-plugins=NodeRestriction",
|
"--enable-admission-plugins=NodeRestriction",
|
||||||
|
@ -447,20 +430,18 @@ func TestGetAPIServerCommand(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "authorization-mode extra-args Webhook",
|
name: "authorization-mode extra-args Webhook",
|
||||||
cfg: &kubeadmapi.InitConfiguration{
|
cfg: &kubeadmapi.ClusterConfiguration{
|
||||||
LocalAPIEndpoint: kubeadmapi.APIEndpoint{BindPort: 123, AdvertiseAddress: "1.2.3.4"},
|
Networking: kubeadmapi.Networking{ServiceSubnet: "bar"},
|
||||||
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
|
CertificatesDir: testCertsDir,
|
||||||
Networking: kubeadmapi.Networking{ServiceSubnet: "bar"},
|
APIServer: kubeadmapi.APIServer{
|
||||||
CertificatesDir: testCertsDir,
|
ControlPlaneComponent: kubeadmapi.ControlPlaneComponent{
|
||||||
APIServer: kubeadmapi.APIServer{
|
ExtraArgs: map[string]string{
|
||||||
ControlPlaneComponent: kubeadmapi.ControlPlaneComponent{
|
"authorization-mode": authzmodes.ModeWebhook,
|
||||||
ExtraArgs: map[string]string{
|
|
||||||
"authorization-mode": authzmodes.ModeWebhook,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
endpoint: &kubeadmapi.APIEndpoint{BindPort: 123, AdvertiseAddress: "1.2.3.4"},
|
||||||
expected: []string{
|
expected: []string{
|
||||||
"kube-apiserver",
|
"kube-apiserver",
|
||||||
"--enable-admission-plugins=NodeRestriction",
|
"--enable-admission-plugins=NodeRestriction",
|
||||||
|
@ -494,7 +475,7 @@ func TestGetAPIServerCommand(t *testing.T) {
|
||||||
|
|
||||||
for _, rt := range tests {
|
for _, rt := range tests {
|
||||||
t.Run(rt.name, func(t *testing.T) {
|
t.Run(rt.name, func(t *testing.T) {
|
||||||
actual := getAPIServerCommand(rt.cfg)
|
actual := getAPIServerCommand(rt.cfg, rt.endpoint)
|
||||||
sort.Strings(actual)
|
sort.Strings(actual)
|
||||||
sort.Strings(rt.expected)
|
sort.Strings(rt.expected)
|
||||||
if !reflect.DeepEqual(actual, rt.expected) {
|
if !reflect.DeepEqual(actual, rt.expected) {
|
||||||
|
@ -638,11 +619,7 @@ func TestGetControllerManagerCommand(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, rt := range tests {
|
for _, rt := range tests {
|
||||||
// TODO: Make getControllerManagerCommand accept a ClusterConfiguration object instead of InitConfiguration
|
actual := getControllerManagerCommand(rt.cfg, version.MustParseSemantic(rt.cfg.KubernetesVersion))
|
||||||
initcfg := &kubeadmapi.InitConfiguration{
|
|
||||||
ClusterConfiguration: *rt.cfg,
|
|
||||||
}
|
|
||||||
actual := getControllerManagerCommand(initcfg, version.MustParseSemantic(rt.cfg.KubernetesVersion))
|
|
||||||
sort.Strings(actual)
|
sort.Strings(actual)
|
||||||
sort.Strings(rt.expected)
|
sort.Strings(rt.expected)
|
||||||
if !reflect.DeepEqual(actual, rt.expected) {
|
if !reflect.DeepEqual(actual, rt.expected) {
|
||||||
|
@ -815,7 +792,7 @@ func TestGetControllerManagerCommandExternalCA(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
actual := getControllerManagerCommand(test.cfg, version.MustParseSemantic(test.cfg.KubernetesVersion))
|
actual := getControllerManagerCommand(&test.cfg.ClusterConfiguration, version.MustParseSemantic(test.cfg.KubernetesVersion))
|
||||||
expected := test.expectedArgFunc(tmpdir)
|
expected := test.expectedArgFunc(tmpdir)
|
||||||
sort.Strings(actual)
|
sort.Strings(actual)
|
||||||
sort.Strings(expected)
|
sort.Strings(expected)
|
||||||
|
@ -844,11 +821,7 @@ func TestGetSchedulerCommand(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, rt := range tests {
|
for _, rt := range tests {
|
||||||
// TODO: Make getSchedulerCommand accept a ClusterConfiguration object instead of InitConfiguration
|
actual := getSchedulerCommand(rt.cfg)
|
||||||
initcfg := &kubeadmapi.InitConfiguration{
|
|
||||||
ClusterConfiguration: *rt.cfg,
|
|
||||||
}
|
|
||||||
actual := getSchedulerCommand(initcfg)
|
|
||||||
sort.Strings(actual)
|
sort.Strings(actual)
|
||||||
sort.Strings(rt.expected)
|
sort.Strings(rt.expected)
|
||||||
if !reflect.DeepEqual(actual, rt.expected) {
|
if !reflect.DeepEqual(actual, rt.expected) {
|
||||||
|
|
|
@ -42,7 +42,7 @@ const (
|
||||||
var caCertsExtraVolumePaths = []string{"/etc/pki", "/usr/share/ca-certificates", "/usr/local/share/ca-certificates", "/etc/ca-certificates"}
|
var caCertsExtraVolumePaths = []string{"/etc/pki", "/usr/share/ca-certificates", "/usr/local/share/ca-certificates", "/etc/ca-certificates"}
|
||||||
|
|
||||||
// getHostPathVolumesForTheControlPlane gets the required hostPath volumes and mounts for the control plane
|
// getHostPathVolumesForTheControlPlane gets the required hostPath volumes and mounts for the control plane
|
||||||
func getHostPathVolumesForTheControlPlane(cfg *kubeadmapi.InitConfiguration) controlPlaneHostPathMounts {
|
func getHostPathVolumesForTheControlPlane(cfg *kubeadmapi.ClusterConfiguration) controlPlaneHostPathMounts {
|
||||||
hostPathDirectoryOrCreate := v1.HostPathDirectoryOrCreate
|
hostPathDirectoryOrCreate := v1.HostPathDirectoryOrCreate
|
||||||
hostPathFileOrCreate := v1.HostPathFileOrCreate
|
hostPathFileOrCreate := v1.HostPathFileOrCreate
|
||||||
mounts := newControlPlaneHostPathMounts()
|
mounts := newControlPlaneHostPathMounts()
|
||||||
|
|
|
@ -514,11 +514,7 @@ func TestGetHostPathVolumesForTheControlPlane(t *testing.T) {
|
||||||
defer func() { caCertsExtraVolumePaths = []string{"/etc/pki", "/usr/share/ca-certificates"} }()
|
defer func() { caCertsExtraVolumePaths = []string{"/etc/pki", "/usr/share/ca-certificates"} }()
|
||||||
|
|
||||||
for _, rt := range tests {
|
for _, rt := range tests {
|
||||||
// TODO: Make getHostPathVolumesForTheControlPlane accept a ClusterConfiguration object instead of InitConfiguration
|
mounts := getHostPathVolumesForTheControlPlane(rt.cfg)
|
||||||
initcfg := &kubeadmapi.InitConfiguration{
|
|
||||||
ClusterConfiguration: *rt.cfg,
|
|
||||||
}
|
|
||||||
mounts := getHostPathVolumesForTheControlPlane(initcfg)
|
|
||||||
|
|
||||||
// Avoid unit test errors when the flexvolume is mounted
|
// Avoid unit test errors when the flexvolume is mounted
|
||||||
if _, ok := mounts.volumes[kubeadmconstants.KubeControllerManager][flexvolumeDirVolumeName]; ok {
|
if _, ok := mounts.volumes[kubeadmconstants.KubeControllerManager][flexvolumeDirVolumeName]; ok {
|
||||||
|
|
|
@ -46,8 +46,8 @@ const (
|
||||||
// CreateLocalEtcdStaticPodManifestFile will write local etcd static pod manifest file.
|
// CreateLocalEtcdStaticPodManifestFile will write local etcd static pod manifest file.
|
||||||
// This function is used by init - when the etcd cluster is empty - or by kubeadm
|
// This function is used by init - when the etcd cluster is empty - or by kubeadm
|
||||||
// upgrade - when the etcd cluster is already up and running (and the --initial-cluster flag have no impact)
|
// upgrade - when the etcd cluster is already up and running (and the --initial-cluster flag have no impact)
|
||||||
func CreateLocalEtcdStaticPodManifestFile(manifestDir string, cfg *kubeadmapi.InitConfiguration) error {
|
func CreateLocalEtcdStaticPodManifestFile(manifestDir string, nodeName string, cfg *kubeadmapi.ClusterConfiguration, endpoint *kubeadmapi.APIEndpoint) error {
|
||||||
if cfg.ClusterConfiguration.Etcd.External != nil {
|
if cfg.Etcd.External != nil {
|
||||||
return errors.New("etcd static pod manifest cannot be generated for cluster using external etcd")
|
return errors.New("etcd static pod manifest cannot be generated for cluster using external etcd")
|
||||||
}
|
}
|
||||||
// gets etcd StaticPodSpec
|
// gets etcd StaticPodSpec
|
||||||
|
@ -58,7 +58,7 @@ func CreateLocalEtcdStaticPodManifestFile(manifestDir string, cfg *kubeadmapi.In
|
||||||
return errors.Wrapf(err, "failed to create etcd directory %q", cfg.Etcd.Local.DataDir)
|
return errors.Wrapf(err, "failed to create etcd directory %q", cfg.Etcd.Local.DataDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
spec := GetEtcdPodSpec(cfg, emptyInitialCluster)
|
spec := GetEtcdPodSpec(cfg, endpoint, nodeName, emptyInitialCluster)
|
||||||
// writes etcd StaticPod to disk
|
// writes etcd StaticPod to disk
|
||||||
if err := staticpodutil.WriteStaticPodToDisk(kubeadmconstants.Etcd, manifestDir, spec); err != nil {
|
if err := staticpodutil.WriteStaticPodToDisk(kubeadmconstants.Etcd, manifestDir, spec); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -69,7 +69,7 @@ func CreateLocalEtcdStaticPodManifestFile(manifestDir string, cfg *kubeadmapi.In
|
||||||
}
|
}
|
||||||
|
|
||||||
// CheckLocalEtcdClusterStatus verifies health state of local/stacked etcd cluster before installing a new etcd member
|
// CheckLocalEtcdClusterStatus verifies health state of local/stacked etcd cluster before installing a new etcd member
|
||||||
func CheckLocalEtcdClusterStatus(client clientset.Interface, cfg *kubeadmapi.InitConfiguration) error {
|
func CheckLocalEtcdClusterStatus(client clientset.Interface, cfg *kubeadmapi.ClusterConfiguration) error {
|
||||||
fmt.Println("[etcd] Checking etcd cluster health")
|
fmt.Println("[etcd] Checking etcd cluster health")
|
||||||
|
|
||||||
// creates an etcd client that connects to all the local/stacked etcd members
|
// creates an etcd client that connects to all the local/stacked etcd members
|
||||||
|
@ -91,7 +91,7 @@ func CheckLocalEtcdClusterStatus(client clientset.Interface, cfg *kubeadmapi.Ini
|
||||||
// CreateStackedEtcdStaticPodManifestFile will write local etcd static pod manifest file
|
// CreateStackedEtcdStaticPodManifestFile will write local etcd static pod manifest file
|
||||||
// for an additional etcd member that is joining an existing local/stacked etcd cluster.
|
// for an additional etcd member that is joining an existing local/stacked etcd cluster.
|
||||||
// Other members of the etcd cluster will be notified of the joining node in beforehand as well.
|
// Other members of the etcd cluster will be notified of the joining node in beforehand as well.
|
||||||
func CreateStackedEtcdStaticPodManifestFile(client clientset.Interface, manifestDir string, cfg *kubeadmapi.InitConfiguration) error {
|
func CreateStackedEtcdStaticPodManifestFile(client clientset.Interface, manifestDir string, nodeName string, cfg *kubeadmapi.ClusterConfiguration, endpoint *kubeadmapi.APIEndpoint) error {
|
||||||
// creates an etcd client that connects to all the local/stacked etcd members
|
// creates an etcd client that connects to all the local/stacked etcd members
|
||||||
klog.V(1).Info("creating etcd client that connects to etcd pods")
|
klog.V(1).Info("creating etcd client that connects to etcd pods")
|
||||||
etcdClient, err := etcdutil.NewFromCluster(client, cfg.CertificatesDir)
|
etcdClient, err := etcdutil.NewFromCluster(client, cfg.CertificatesDir)
|
||||||
|
@ -100,10 +100,10 @@ func CreateStackedEtcdStaticPodManifestFile(client clientset.Interface, manifest
|
||||||
}
|
}
|
||||||
|
|
||||||
// notifies the other members of the etcd cluster about the joining member
|
// notifies the other members of the etcd cluster about the joining member
|
||||||
etcdPeerAddress := etcdutil.GetPeerURL(cfg)
|
etcdPeerAddress := etcdutil.GetPeerURL(endpoint)
|
||||||
|
|
||||||
klog.V(1).Infof("Adding etcd member: %s", etcdPeerAddress)
|
klog.V(1).Infof("Adding etcd member: %s", etcdPeerAddress)
|
||||||
initialCluster, err := etcdClient.AddMember(cfg.NodeRegistration.Name, etcdPeerAddress)
|
initialCluster, err := etcdClient.AddMember(nodeName, etcdPeerAddress)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -117,7 +117,7 @@ func CreateStackedEtcdStaticPodManifestFile(client clientset.Interface, manifest
|
||||||
|
|
||||||
klog.V(1).Info("Creating local etcd static pod manifest file")
|
klog.V(1).Info("Creating local etcd static pod manifest file")
|
||||||
// gets etcd StaticPodSpec, actualized for the current InitConfiguration and the new list of etcd members
|
// gets etcd StaticPodSpec, actualized for the current InitConfiguration and the new list of etcd members
|
||||||
spec := GetEtcdPodSpec(cfg, initialCluster)
|
spec := GetEtcdPodSpec(cfg, endpoint, nodeName, initialCluster)
|
||||||
// writes etcd StaticPod to disk
|
// writes etcd StaticPod to disk
|
||||||
if err := staticpodutil.WriteStaticPodToDisk(kubeadmconstants.Etcd, manifestDir, spec); err != nil {
|
if err := staticpodutil.WriteStaticPodToDisk(kubeadmconstants.Etcd, manifestDir, spec); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -133,9 +133,9 @@ func CreateStackedEtcdStaticPodManifestFile(client clientset.Interface, manifest
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetEtcdPodSpec returns the etcd static Pod actualized to the context of the current InitConfiguration
|
// GetEtcdPodSpec returns the etcd static Pod actualized to the context of the current configuration
|
||||||
// NB. GetEtcdPodSpec methods holds the information about how kubeadm creates etcd static pod manifests.
|
// NB. GetEtcdPodSpec methods holds the information about how kubeadm creates etcd static pod manifests.
|
||||||
func GetEtcdPodSpec(cfg *kubeadmapi.InitConfiguration, initialCluster []etcdutil.Member) v1.Pod {
|
func GetEtcdPodSpec(cfg *kubeadmapi.ClusterConfiguration, endpoint *kubeadmapi.APIEndpoint, nodeName string, initialCluster []etcdutil.Member) v1.Pod {
|
||||||
pathType := v1.HostPathDirectoryOrCreate
|
pathType := v1.HostPathDirectoryOrCreate
|
||||||
etcdMounts := map[string]v1.Volume{
|
etcdMounts := map[string]v1.Volume{
|
||||||
etcdVolumeName: staticpodutil.NewVolume(etcdVolumeName, cfg.Etcd.Local.DataDir, &pathType),
|
etcdVolumeName: staticpodutil.NewVolume(etcdVolumeName, cfg.Etcd.Local.DataDir, &pathType),
|
||||||
|
@ -143,8 +143,8 @@ func GetEtcdPodSpec(cfg *kubeadmapi.InitConfiguration, initialCluster []etcdutil
|
||||||
}
|
}
|
||||||
return staticpodutil.ComponentPod(v1.Container{
|
return staticpodutil.ComponentPod(v1.Container{
|
||||||
Name: kubeadmconstants.Etcd,
|
Name: kubeadmconstants.Etcd,
|
||||||
Command: getEtcdCommand(cfg, initialCluster),
|
Command: getEtcdCommand(cfg, endpoint, nodeName, initialCluster),
|
||||||
Image: images.GetEtcdImage(&cfg.ClusterConfiguration),
|
Image: images.GetEtcdImage(cfg),
|
||||||
ImagePullPolicy: v1.PullIfNotPresent,
|
ImagePullPolicy: v1.PullIfNotPresent,
|
||||||
// Mount the etcd datadir path read-write so etcd can store data in a more persistent manner
|
// Mount the etcd datadir path read-write so etcd can store data in a more persistent manner
|
||||||
VolumeMounts: []v1.VolumeMount{
|
VolumeMounts: []v1.VolumeMount{
|
||||||
|
@ -152,20 +152,20 @@ func GetEtcdPodSpec(cfg *kubeadmapi.InitConfiguration, initialCluster []etcdutil
|
||||||
staticpodutil.NewVolumeMount(certsVolumeName, cfg.CertificatesDir+"/etcd", false),
|
staticpodutil.NewVolumeMount(certsVolumeName, cfg.CertificatesDir+"/etcd", false),
|
||||||
},
|
},
|
||||||
LivenessProbe: staticpodutil.EtcdProbe(
|
LivenessProbe: staticpodutil.EtcdProbe(
|
||||||
cfg, kubeadmconstants.Etcd, kubeadmconstants.EtcdListenClientPort, cfg.CertificatesDir,
|
&cfg.Etcd, kubeadmconstants.EtcdListenClientPort, cfg.CertificatesDir,
|
||||||
kubeadmconstants.EtcdCACertName, kubeadmconstants.EtcdHealthcheckClientCertName, kubeadmconstants.EtcdHealthcheckClientKeyName,
|
kubeadmconstants.EtcdCACertName, kubeadmconstants.EtcdHealthcheckClientCertName, kubeadmconstants.EtcdHealthcheckClientKeyName,
|
||||||
),
|
),
|
||||||
}, etcdMounts)
|
}, etcdMounts)
|
||||||
}
|
}
|
||||||
|
|
||||||
// getEtcdCommand builds the right etcd command from the given config object
|
// getEtcdCommand builds the right etcd command from the given config object
|
||||||
func getEtcdCommand(cfg *kubeadmapi.InitConfiguration, initialCluster []etcdutil.Member) []string {
|
func getEtcdCommand(cfg *kubeadmapi.ClusterConfiguration, endpoint *kubeadmapi.APIEndpoint, nodeName string, initialCluster []etcdutil.Member) []string {
|
||||||
defaultArguments := map[string]string{
|
defaultArguments := map[string]string{
|
||||||
"name": cfg.GetNodeName(),
|
"name": nodeName,
|
||||||
"listen-client-urls": fmt.Sprintf("%s,%s", etcdutil.GetClientURLByIP("127.0.0.1"), etcdutil.GetClientURL(cfg)),
|
"listen-client-urls": fmt.Sprintf("%s,%s", etcdutil.GetClientURLByIP("127.0.0.1"), etcdutil.GetClientURL(endpoint)),
|
||||||
"advertise-client-urls": etcdutil.GetClientURL(cfg),
|
"advertise-client-urls": etcdutil.GetClientURL(endpoint),
|
||||||
"listen-peer-urls": etcdutil.GetPeerURL(cfg),
|
"listen-peer-urls": etcdutil.GetPeerURL(endpoint),
|
||||||
"initial-advertise-peer-urls": etcdutil.GetPeerURL(cfg),
|
"initial-advertise-peer-urls": etcdutil.GetPeerURL(endpoint),
|
||||||
"data-dir": cfg.Etcd.Local.DataDir,
|
"data-dir": cfg.Etcd.Local.DataDir,
|
||||||
"cert-file": filepath.Join(cfg.CertificatesDir, kubeadmconstants.EtcdServerCertName),
|
"cert-file": filepath.Join(cfg.CertificatesDir, kubeadmconstants.EtcdServerCertName),
|
||||||
"key-file": filepath.Join(cfg.CertificatesDir, kubeadmconstants.EtcdServerKeyName),
|
"key-file": filepath.Join(cfg.CertificatesDir, kubeadmconstants.EtcdServerKeyName),
|
||||||
|
@ -179,7 +179,7 @@ func getEtcdCommand(cfg *kubeadmapi.InitConfiguration, initialCluster []etcdutil
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(initialCluster) == 0 {
|
if len(initialCluster) == 0 {
|
||||||
defaultArguments["initial-cluster"] = fmt.Sprintf("%s=%s", cfg.GetNodeName(), etcdutil.GetPeerURL(cfg))
|
defaultArguments["initial-cluster"] = fmt.Sprintf("%s=%s", nodeName, etcdutil.GetPeerURL(endpoint))
|
||||||
} else {
|
} else {
|
||||||
// NB. the joining etcd member should be part of the initialCluster list
|
// NB. the joining etcd member should be part of the initialCluster list
|
||||||
endpoints := []string{}
|
endpoints := []string{}
|
||||||
|
|
|
@ -32,19 +32,18 @@ import (
|
||||||
|
|
||||||
func TestGetEtcdPodSpec(t *testing.T) {
|
func TestGetEtcdPodSpec(t *testing.T) {
|
||||||
// Creates a Master Configuration
|
// Creates a Master Configuration
|
||||||
cfg := &kubeadmapi.InitConfiguration{
|
cfg := &kubeadmapi.ClusterConfiguration{
|
||||||
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
|
KubernetesVersion: "v1.7.0",
|
||||||
KubernetesVersion: "v1.7.0",
|
Etcd: kubeadmapi.Etcd{
|
||||||
Etcd: kubeadmapi.Etcd{
|
Local: &kubeadmapi.LocalEtcd{
|
||||||
Local: &kubeadmapi.LocalEtcd{
|
DataDir: "/var/lib/etcd",
|
||||||
DataDir: "/var/lib/etcd",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
endpoint := &kubeadmapi.APIEndpoint{}
|
||||||
|
|
||||||
// Executes GetEtcdPodSpec
|
// Executes GetEtcdPodSpec
|
||||||
spec := GetEtcdPodSpec(cfg, []etcdutil.Member{})
|
spec := GetEtcdPodSpec(cfg, endpoint, "", []etcdutil.Member{})
|
||||||
|
|
||||||
// Assert each specs refers to the right pod
|
// Assert each specs refers to the right pod
|
||||||
if spec.Spec.Containers[0].Name != kubeadmconstants.Etcd {
|
if spec.Spec.Containers[0].Name != kubeadmconstants.Etcd {
|
||||||
|
@ -58,35 +57,31 @@ func TestCreateLocalEtcdStaticPodManifestFile(t *testing.T) {
|
||||||
defer os.RemoveAll(tmpdir)
|
defer os.RemoveAll(tmpdir)
|
||||||
|
|
||||||
var tests = []struct {
|
var tests = []struct {
|
||||||
cfg *kubeadmapi.InitConfiguration
|
cfg *kubeadmapi.ClusterConfiguration
|
||||||
expectedError bool
|
expectedError bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
cfg: &kubeadmapi.InitConfiguration{
|
cfg: &kubeadmapi.ClusterConfiguration{
|
||||||
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
|
KubernetesVersion: "v1.7.0",
|
||||||
KubernetesVersion: "v1.7.0",
|
Etcd: kubeadmapi.Etcd{
|
||||||
Etcd: kubeadmapi.Etcd{
|
Local: &kubeadmapi.LocalEtcd{
|
||||||
Local: &kubeadmapi.LocalEtcd{
|
DataDir: tmpdir + "/etcd",
|
||||||
DataDir: tmpdir + "/etcd",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedError: false,
|
expectedError: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
cfg: &kubeadmapi.InitConfiguration{
|
cfg: &kubeadmapi.ClusterConfiguration{
|
||||||
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
|
KubernetesVersion: "v1.7.0",
|
||||||
KubernetesVersion: "v1.7.0",
|
Etcd: kubeadmapi.Etcd{
|
||||||
Etcd: kubeadmapi.Etcd{
|
External: &kubeadmapi.ExternalEtcd{
|
||||||
External: &kubeadmapi.ExternalEtcd{
|
Endpoints: []string{
|
||||||
Endpoints: []string{
|
"https://etcd-instance:2379",
|
||||||
"https://etcd-instance:2379",
|
|
||||||
},
|
|
||||||
CAFile: "/etc/kubernetes/pki/etcd/ca.crt",
|
|
||||||
CertFile: "/etc/kubernetes/pki/etcd/apiserver-etcd-client.crt",
|
|
||||||
KeyFile: "/etc/kubernetes/pki/etcd/apiserver-etcd-client.key",
|
|
||||||
},
|
},
|
||||||
|
CAFile: "/etc/kubernetes/pki/etcd/ca.crt",
|
||||||
|
CertFile: "/etc/kubernetes/pki/etcd/apiserver-etcd-client.crt",
|
||||||
|
KeyFile: "/etc/kubernetes/pki/etcd/apiserver-etcd-client.key",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -97,7 +92,7 @@ func TestCreateLocalEtcdStaticPodManifestFile(t *testing.T) {
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
// Execute createStaticPodFunction
|
// Execute createStaticPodFunction
|
||||||
manifestPath := filepath.Join(tmpdir, kubeadmconstants.ManifestsSubDirName)
|
manifestPath := filepath.Join(tmpdir, kubeadmconstants.ManifestsSubDirName)
|
||||||
err := CreateLocalEtcdStaticPodManifestFile(manifestPath, test.cfg)
|
err := CreateLocalEtcdStaticPodManifestFile(manifestPath, "", test.cfg, &kubeadmapi.APIEndpoint{})
|
||||||
|
|
||||||
if !test.expectedError {
|
if !test.expectedError {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -230,23 +225,18 @@ func TestGetEtcdCommand(t *testing.T) {
|
||||||
|
|
||||||
for _, rt := range tests {
|
for _, rt := range tests {
|
||||||
t.Run(rt.name, func(t *testing.T) {
|
t.Run(rt.name, func(t *testing.T) {
|
||||||
cfg := &kubeadmapi.InitConfiguration{
|
endpoint := &kubeadmapi.APIEndpoint{
|
||||||
LocalAPIEndpoint: kubeadmapi.APIEndpoint{
|
AdvertiseAddress: rt.advertiseAddress,
|
||||||
AdvertiseAddress: rt.advertiseAddress,
|
}
|
||||||
},
|
cfg := &kubeadmapi.ClusterConfiguration{
|
||||||
NodeRegistration: kubeadmapi.NodeRegistrationOptions{
|
Etcd: kubeadmapi.Etcd{
|
||||||
Name: rt.nodeName,
|
Local: &kubeadmapi.LocalEtcd{
|
||||||
},
|
DataDir: "/var/lib/etcd",
|
||||||
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
|
ExtraArgs: rt.extraArgs,
|
||||||
Etcd: kubeadmapi.Etcd{
|
|
||||||
Local: &kubeadmapi.LocalEtcd{
|
|
||||||
DataDir: "/var/lib/etcd",
|
|
||||||
ExtraArgs: rt.extraArgs,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
actual := getEtcdCommand(cfg, rt.initialCluster)
|
actual := getEtcdCommand(cfg, endpoint, rt.nodeName, rt.initialCluster)
|
||||||
sort.Strings(actual)
|
sort.Strings(actual)
|
||||||
sort.Strings(rt.expected)
|
sort.Strings(rt.expected)
|
||||||
if !reflect.DeepEqual(actual, rt.expected) {
|
if !reflect.DeepEqual(actual, rt.expected) {
|
||||||
|
|
|
@ -135,7 +135,7 @@ func getKubeConfigSpecs(cfg *kubeadmapi.InitConfiguration) (map[string]*kubeConf
|
||||||
return nil, errors.Wrap(err, "couldn't create a kubeconfig; the CA files couldn't be loaded")
|
return nil, errors.Wrap(err, "couldn't create a kubeconfig; the CA files couldn't be loaded")
|
||||||
}
|
}
|
||||||
|
|
||||||
masterEndpoint, err := kubeadmutil.GetMasterEndpoint(cfg)
|
masterEndpoint, err := kubeadmutil.GetMasterEndpoint(cfg.ControlPlaneEndpoint, &cfg.LocalAPIEndpoint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -285,7 +285,7 @@ func WriteKubeConfigWithClientCert(out io.Writer, cfg *kubeadmapi.InitConfigurat
|
||||||
return errors.Wrap(err, "couldn't create a kubeconfig; the CA files couldn't be loaded")
|
return errors.Wrap(err, "couldn't create a kubeconfig; the CA files couldn't be loaded")
|
||||||
}
|
}
|
||||||
|
|
||||||
masterEndpoint, err := kubeadmutil.GetMasterEndpoint(cfg)
|
masterEndpoint, err := kubeadmutil.GetMasterEndpoint(cfg.ControlPlaneEndpoint, &cfg.LocalAPIEndpoint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -312,7 +312,7 @@ func WriteKubeConfigWithToken(out io.Writer, cfg *kubeadmapi.InitConfiguration,
|
||||||
return errors.Wrap(err, "couldn't create a kubeconfig; the CA files couldn't be loaded")
|
return errors.Wrap(err, "couldn't create a kubeconfig; the CA files couldn't be loaded")
|
||||||
}
|
}
|
||||||
|
|
||||||
masterEndpoint, err := kubeadmutil.GetMasterEndpoint(cfg)
|
masterEndpoint, err := kubeadmutil.GetMasterEndpoint(cfg.ControlPlaneEndpoint, &cfg.LocalAPIEndpoint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -162,7 +162,7 @@ func TestGetKubeConfigSpecs(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Asserts InitConfiguration values injected into spec
|
// Asserts InitConfiguration values injected into spec
|
||||||
masterEndpoint, err := kubeadmutil.GetMasterEndpoint(cfg)
|
masterEndpoint, err := kubeadmutil.GetMasterEndpoint(cfg.ControlPlaneEndpoint, &cfg.LocalAPIEndpoint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,6 @@ import (
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/util/version"
|
"k8s.io/apimachinery/pkg/util/version"
|
||||||
clientset "k8s.io/client-go/kubernetes"
|
clientset "k8s.io/client-go/kubernetes"
|
||||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/componentconfigs"
|
"k8s.io/kubernetes/cmd/kubeadm/app/componentconfigs"
|
||||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/util/apiclient"
|
"k8s.io/kubernetes/cmd/kubeadm/app/util/apiclient"
|
||||||
|
@ -51,9 +50,9 @@ func WriteConfigToDisk(kubeletConfig *kubeletconfig.KubeletConfiguration, kubele
|
||||||
|
|
||||||
// CreateConfigMap creates a ConfigMap with the generic kubelet configuration.
|
// CreateConfigMap creates a ConfigMap with the generic kubelet configuration.
|
||||||
// Used at "kubeadm init" and "kubeadm upgrade" time
|
// Used at "kubeadm init" and "kubeadm upgrade" time
|
||||||
func CreateConfigMap(cfg *kubeadmapi.InitConfiguration, client clientset.Interface) error {
|
func CreateConfigMap(cfg *kubeletconfig.KubeletConfiguration, k8sVersionStr string, client clientset.Interface) error {
|
||||||
|
|
||||||
k8sVersion, err := version.ParseSemantic(cfg.KubernetesVersion)
|
k8sVersion, err := version.ParseSemantic(k8sVersionStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -61,7 +60,7 @@ func CreateConfigMap(cfg *kubeadmapi.InitConfiguration, client clientset.Interfa
|
||||||
configMapName := kubeadmconstants.GetKubeletConfigMapName(k8sVersion)
|
configMapName := kubeadmconstants.GetKubeletConfigMapName(k8sVersion)
|
||||||
fmt.Printf("[kubelet] Creating a ConfigMap %q in namespace %s with the configuration for the kubelets in the cluster\n", configMapName, metav1.NamespaceSystem)
|
fmt.Printf("[kubelet] Creating a ConfigMap %q in namespace %s with the configuration for the kubelets in the cluster\n", configMapName, metav1.NamespaceSystem)
|
||||||
|
|
||||||
kubeletBytes, err := getConfigBytes(cfg.ComponentConfigs.Kubelet)
|
kubeletBytes, err := getConfigBytes(cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,6 @@ import (
|
||||||
"k8s.io/apimachinery/pkg/util/version"
|
"k8s.io/apimachinery/pkg/util/version"
|
||||||
"k8s.io/client-go/kubernetes/fake"
|
"k8s.io/client-go/kubernetes/fake"
|
||||||
core "k8s.io/client-go/testing"
|
core "k8s.io/client-go/testing"
|
||||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||||
kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config"
|
kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config"
|
||||||
)
|
)
|
||||||
|
@ -33,15 +32,8 @@ import (
|
||||||
func TestCreateConfigMap(t *testing.T) {
|
func TestCreateConfigMap(t *testing.T) {
|
||||||
nodeName := "fake-node"
|
nodeName := "fake-node"
|
||||||
client := fake.NewSimpleClientset()
|
client := fake.NewSimpleClientset()
|
||||||
cfg := &kubeadmapi.InitConfiguration{
|
k8sVersionStr := constants.CurrentKubernetesVersion.String()
|
||||||
NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: nodeName},
|
cfg := &kubeletconfig.KubeletConfiguration{}
|
||||||
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
|
|
||||||
KubernetesVersion: constants.CurrentKubernetesVersion.String(),
|
|
||||||
ComponentConfigs: kubeadmapi.ComponentConfigs{
|
|
||||||
Kubelet: &kubeletconfig.KubeletConfiguration{},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
client.PrependReactor("get", "nodes", func(action core.Action) (bool, runtime.Object, error) {
|
client.PrependReactor("get", "nodes", func(action core.Action) (bool, runtime.Object, error) {
|
||||||
return true, &v1.Node{
|
return true, &v1.Node{
|
||||||
|
@ -61,7 +53,7 @@ func TestCreateConfigMap(t *testing.T) {
|
||||||
return true, nil, nil
|
return true, nil, nil
|
||||||
})
|
})
|
||||||
|
|
||||||
if err := CreateConfigMap(cfg, client); err != nil {
|
if err := CreateConfigMap(cfg, k8sVersionStr, client); err != nil {
|
||||||
t.Errorf("CreateConfigMap: unexpected error %v", err)
|
t.Errorf("CreateConfigMap: unexpected error %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,29 +46,29 @@ type kubeletFlagsOpts struct {
|
||||||
|
|
||||||
// WriteKubeletDynamicEnvFile writes an environment file with dynamic flags to the kubelet.
|
// WriteKubeletDynamicEnvFile writes an environment file with dynamic flags to the kubelet.
|
||||||
// Used at "kubeadm init" and "kubeadm join" time.
|
// Used at "kubeadm init" and "kubeadm join" time.
|
||||||
func WriteKubeletDynamicEnvFile(cfg *kubeadmapi.InitConfiguration, registerTaintsUsingFlags bool, kubeletDir string) error {
|
func WriteKubeletDynamicEnvFile(cfg *kubeadmapi.ClusterConfiguration, nodeReg *kubeadmapi.NodeRegistrationOptions, registerTaintsUsingFlags bool, kubeletDir string) error {
|
||||||
hostName, err := nodeutil.GetHostname("")
|
hostName, err := nodeutil.GetHostname("")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
flagOpts := kubeletFlagsOpts{
|
flagOpts := kubeletFlagsOpts{
|
||||||
nodeRegOpts: &cfg.NodeRegistration,
|
nodeRegOpts: nodeReg,
|
||||||
featureGates: cfg.FeatureGates,
|
featureGates: cfg.FeatureGates,
|
||||||
pauseImage: images.GetPauseImage(&cfg.ClusterConfiguration),
|
pauseImage: images.GetPauseImage(cfg),
|
||||||
registerTaintsUsingFlags: registerTaintsUsingFlags,
|
registerTaintsUsingFlags: registerTaintsUsingFlags,
|
||||||
execer: utilsexec.New(),
|
execer: utilsexec.New(),
|
||||||
pidOfFunc: procfs.PidOf,
|
pidOfFunc: procfs.PidOf,
|
||||||
defaultHostname: hostName,
|
defaultHostname: hostName,
|
||||||
}
|
}
|
||||||
stringMap := buildKubeletArgMap(flagOpts)
|
stringMap := buildKubeletArgMap(flagOpts)
|
||||||
argList := kubeadmutil.BuildArgumentListFromMap(stringMap, cfg.NodeRegistration.KubeletExtraArgs)
|
argList := kubeadmutil.BuildArgumentListFromMap(stringMap, nodeReg.KubeletExtraArgs)
|
||||||
envFileContent := fmt.Sprintf("%s=%s\n", constants.KubeletEnvFileVariableName, strings.Join(argList, " "))
|
envFileContent := fmt.Sprintf("%s=%s\n", constants.KubeletEnvFileVariableName, strings.Join(argList, " "))
|
||||||
|
|
||||||
return writeKubeletFlagBytesToDisk([]byte(envFileContent), kubeletDir)
|
return writeKubeletFlagBytesToDisk([]byte(envFileContent), kubeletDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
// buildKubeletArgMap takes a InitConfiguration object and builds based on that a string-string map with flags
|
// buildKubeletArgMap takes a kubeletFlagsOpts object and builds based on that a string-string map with flags
|
||||||
// that should be given to the local kubelet daemon.
|
// that should be given to the local kubelet daemon.
|
||||||
func buildKubeletArgMap(opts kubeletFlagsOpts) map[string]string {
|
func buildKubeletArgMap(opts kubeletFlagsOpts) map[string]string {
|
||||||
kubeletFlags := map[string]string{}
|
kubeletFlags := map[string]string{}
|
||||||
|
|
|
@ -61,7 +61,7 @@ func PerformPostUpgradeTasks(client clientset.Interface, cfg *kubeadmapi.InitCon
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the new, version-branched kubelet ComponentConfig ConfigMap
|
// Create the new, version-branched kubelet ComponentConfig ConfigMap
|
||||||
if err := kubeletphase.CreateConfigMap(cfg, client); err != nil {
|
if err := kubeletphase.CreateConfigMap(cfg.ClusterConfiguration.ComponentConfigs.Kubelet, cfg.KubernetesVersion, client); err != nil {
|
||||||
errs = append(errs, errors.Wrap(err, "error creating kubelet configuration ConfigMap"))
|
errs = append(errs, errors.Wrap(err, "error creating kubelet configuration ConfigMap"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,21 +108,21 @@ func PerformPostUpgradeTasks(client clientset.Interface, cfg *kubeadmapi.InitCon
|
||||||
}
|
}
|
||||||
|
|
||||||
// Upgrade kube-dns/CoreDNS and kube-proxy
|
// Upgrade kube-dns/CoreDNS and kube-proxy
|
||||||
if err := dns.EnsureDNSAddon(cfg, client); err != nil {
|
if err := dns.EnsureDNSAddon(&cfg.ClusterConfiguration, client); err != nil {
|
||||||
errs = append(errs, err)
|
errs = append(errs, err)
|
||||||
}
|
}
|
||||||
// Remove the old DNS deployment if a new DNS service is now used (kube-dns to CoreDNS or vice versa)
|
// Remove the old DNS deployment if a new DNS service is now used (kube-dns to CoreDNS or vice versa)
|
||||||
if err := removeOldDNSDeploymentIfAnotherDNSIsUsed(cfg, client, dryRun); err != nil {
|
if err := removeOldDNSDeploymentIfAnotherDNSIsUsed(&cfg.ClusterConfiguration, client, dryRun); err != nil {
|
||||||
errs = append(errs, err)
|
errs = append(errs, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := proxy.EnsureProxyAddon(cfg, client); err != nil {
|
if err := proxy.EnsureProxyAddon(&cfg.ClusterConfiguration, &cfg.LocalAPIEndpoint, client); err != nil {
|
||||||
errs = append(errs, err)
|
errs = append(errs, err)
|
||||||
}
|
}
|
||||||
return errorsutil.NewAggregate(errs)
|
return errorsutil.NewAggregate(errs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func removeOldDNSDeploymentIfAnotherDNSIsUsed(cfg *kubeadmapi.InitConfiguration, client clientset.Interface, dryRun bool) error {
|
func removeOldDNSDeploymentIfAnotherDNSIsUsed(cfg *kubeadmapi.ClusterConfiguration, client clientset.Interface, dryRun bool) error {
|
||||||
return apiclient.TryRunCommand(func() error {
|
return apiclient.TryRunCommand(func() error {
|
||||||
installedDeploymentName := kubeadmconstants.KubeDNSDeploymentName
|
installedDeploymentName := kubeadmconstants.KubeDNSDeploymentName
|
||||||
deploymentToDelete := kubeadmconstants.CoreDNSDeploymentName
|
deploymentToDelete := kubeadmconstants.CoreDNSDeploymentName
|
||||||
|
@ -210,7 +210,7 @@ func writeKubeletConfigFiles(client clientset.Interface, cfg *kubeadmapi.InitCon
|
||||||
// Write env file with flags for the kubelet to use. We do not need to write the --register-with-taints for the master,
|
// Write env file with flags for the kubelet to use. We do not need to write the --register-with-taints for the master,
|
||||||
// as we handle that ourselves in the markmaster phase
|
// as we handle that ourselves in the markmaster phase
|
||||||
// TODO: Maybe we want to do that some time in the future, in order to remove some logic from the markmaster phase?
|
// TODO: Maybe we want to do that some time in the future, in order to remove some logic from the markmaster phase?
|
||||||
if err := kubeletphase.WriteKubeletDynamicEnvFile(cfg, false, kubeletDir); err != nil {
|
if err := kubeletphase.WriteKubeletDynamicEnvFile(&cfg.ClusterConfiguration, &cfg.NodeRegistration, false, kubeletDir); err != nil {
|
||||||
errs = append(errs, errors.Wrap(err, "error writing a dynamic environment file for the kubelet"))
|
errs = append(errs, errors.Wrap(err, "error writing a dynamic environment file for the kubelet"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -267,7 +267,7 @@ func performEtcdStaticPodUpgrade(client clientset.Interface, waiter apiclient.Wa
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return true, errors.Wrap(err, "failed to retrieve the current etcd version")
|
return true, errors.Wrap(err, "failed to retrieve the current etcd version")
|
||||||
}
|
}
|
||||||
currentEtcdVersionStr, ok := currentEtcdVersions[etcdutil.GetClientURL(cfg)]
|
currentEtcdVersionStr, ok := currentEtcdVersions[etcdutil.GetClientURL(&cfg.LocalAPIEndpoint)]
|
||||||
if !ok {
|
if !ok {
|
||||||
return true, errors.Wrap(err, "failed to retrieve the current etcd version")
|
return true, errors.Wrap(err, "failed to retrieve the current etcd version")
|
||||||
}
|
}
|
||||||
|
@ -293,7 +293,7 @@ func performEtcdStaticPodUpgrade(client clientset.Interface, waiter apiclient.Wa
|
||||||
|
|
||||||
// Write the updated etcd static Pod manifest into the temporary directory, at this point no etcd change
|
// Write the updated etcd static Pod manifest into the temporary directory, at this point no etcd change
|
||||||
// has occurred in any aspects.
|
// has occurred in any aspects.
|
||||||
if err := etcdphase.CreateLocalEtcdStaticPodManifestFile(pathMgr.TempManifestDir(), cfg); err != nil {
|
if err := etcdphase.CreateLocalEtcdStaticPodManifestFile(pathMgr.TempManifestDir(), cfg.NodeRegistration.Name, &cfg.ClusterConfiguration, &cfg.LocalAPIEndpoint); err != nil {
|
||||||
return true, errors.Wrap(err, "error creating local etcd static pod manifest file")
|
return true, errors.Wrap(err, "error creating local etcd static pod manifest file")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -453,7 +453,7 @@ func TestStaticPodControlPlane(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("couldn't run CreateInitStaticPodManifestFiles: %v", err)
|
t.Fatalf("couldn't run CreateInitStaticPodManifestFiles: %v", err)
|
||||||
}
|
}
|
||||||
err = etcdphase.CreateLocalEtcdStaticPodManifestFile(pathMgr.RealManifestDir(), oldcfg)
|
err = etcdphase.CreateLocalEtcdStaticPodManifestFile(pathMgr.RealManifestDir(), oldcfg.NodeRegistration.Name, &oldcfg.ClusterConfiguration, &oldcfg.LocalAPIEndpoint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("couldn't run CreateLocalEtcdStaticPodManifestFile: %v", err)
|
t.Fatalf("couldn't run CreateLocalEtcdStaticPodManifestFile: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -973,11 +973,11 @@ func RunJoinNodeChecks(execer utilsexec.Interface, cfg *kubeadmapi.JoinConfigura
|
||||||
}
|
}
|
||||||
|
|
||||||
// RunOptionalJoinNodeChecks executes all individual, applicable to node configuration dependant checks
|
// RunOptionalJoinNodeChecks executes all individual, applicable to node configuration dependant checks
|
||||||
func RunOptionalJoinNodeChecks(execer utilsexec.Interface, initCfg *kubeadmapi.InitConfiguration, ignorePreflightErrors sets.String) error {
|
func RunOptionalJoinNodeChecks(execer utilsexec.Interface, cfg *kubeadmapi.ClusterConfiguration, ignorePreflightErrors sets.String) error {
|
||||||
checks := []Checker{}
|
checks := []Checker{}
|
||||||
|
|
||||||
// Check ipvs required kernel module if we use ipvs kube-proxy mode
|
// Check ipvs required kernel module if we use ipvs kube-proxy mode
|
||||||
if initCfg.ComponentConfigs.KubeProxy != nil && initCfg.ComponentConfigs.KubeProxy.Mode == ipvsutil.IPVSProxyMode {
|
if cfg.ComponentConfigs.KubeProxy != nil && cfg.ComponentConfigs.KubeProxy.Mode == ipvsutil.IPVSProxyMode {
|
||||||
checks = append(checks,
|
checks = append(checks,
|
||||||
ipvsutil.RequiredIPVSKernelModulesAvailableCheck{Executor: execer},
|
ipvsutil.RequiredIPVSKernelModulesAvailableCheck{Executor: execer},
|
||||||
)
|
)
|
||||||
|
|
|
@ -29,35 +29,35 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetMasterEndpoint returns a properly formatted endpoint for the control plane built according following rules:
|
// GetMasterEndpoint returns a properly formatted endpoint for the control plane built according following rules:
|
||||||
// - If the ControlPlaneEndpoint is defined, use it.
|
// - If the controlPlaneEndpoint is defined, use it.
|
||||||
// - if the ControlPlaneEndpoint is defined but without a port number, use the ControlPlaneEndpoint + api.BindPort is used.
|
// - if the controlPlaneEndpoint is defined but without a port number, use the controlPlaneEndpoint + localEndpoint.BindPort is used.
|
||||||
// - Otherwise, in case the ControlPlaneEndpoint is not defined, use the api.AdvertiseAddress + the api.BindPort.
|
// - Otherwise, in case the controlPlaneEndpoint is not defined, use the localEndpoint.AdvertiseAddress + the localEndpoint.BindPort.
|
||||||
func GetMasterEndpoint(cfg *kubeadmapi.InitConfiguration) (string, error) {
|
func GetMasterEndpoint(controlPlaneEndpoint string, localEndpoint *kubeadmapi.APIEndpoint) (string, error) {
|
||||||
// parse the bind port
|
// parse the bind port
|
||||||
bindPortString := strconv.Itoa(int(cfg.LocalAPIEndpoint.BindPort))
|
bindPortString := strconv.Itoa(int(localEndpoint.BindPort))
|
||||||
if _, err := ParsePort(bindPortString); err != nil {
|
if _, err := ParsePort(bindPortString); err != nil {
|
||||||
return "", errors.Wrapf(err, "invalid value %q given for api.bindPort", cfg.LocalAPIEndpoint.BindPort)
|
return "", errors.Wrapf(err, "invalid value %q given for api.bindPort", localEndpoint.BindPort)
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse the AdvertiseAddress
|
// parse the AdvertiseAddress
|
||||||
var ip = net.ParseIP(cfg.LocalAPIEndpoint.AdvertiseAddress)
|
var ip = net.ParseIP(localEndpoint.AdvertiseAddress)
|
||||||
if ip == nil {
|
if ip == nil {
|
||||||
return "", errors.Errorf("invalid value `%s` given for api.advertiseAddress", cfg.LocalAPIEndpoint.AdvertiseAddress)
|
return "", errors.Errorf("invalid value `%s` given for api.advertiseAddress", localEndpoint.AdvertiseAddress)
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the master url using cfg.API.AdvertiseAddress + the cfg.API.BindPort
|
// set the master url using localEndpoint.AdvertiseAddress + the localEndpoint.BindPort
|
||||||
masterURL := &url.URL{
|
masterURL := &url.URL{
|
||||||
Scheme: "https",
|
Scheme: "https",
|
||||||
Host: net.JoinHostPort(ip.String(), bindPortString),
|
Host: net.JoinHostPort(ip.String(), bindPortString),
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the controlplane endpoint is defined
|
// if the controlplane endpoint is defined
|
||||||
if len(cfg.ControlPlaneEndpoint) > 0 {
|
if len(controlPlaneEndpoint) > 0 {
|
||||||
// parse the controlplane endpoint
|
// parse the controlplane endpoint
|
||||||
var host, port string
|
var host, port string
|
||||||
var err error
|
var err error
|
||||||
if host, port, err = ParseHostPort(cfg.ControlPlaneEndpoint); err != nil {
|
if host, port, err = ParseHostPort(controlPlaneEndpoint); err != nil {
|
||||||
return "", errors.Wrapf(err, "invalid value %q given for controlPlaneEndpoint", cfg.ControlPlaneEndpoint)
|
return "", errors.Wrapf(err, "invalid value %q given for controlPlaneEndpoint", controlPlaneEndpoint)
|
||||||
}
|
}
|
||||||
|
|
||||||
// if a port is provided within the controlPlaneAddress warn the users we are using it, else use the bindport
|
// if a port is provided within the controlPlaneAddress warn the users we are using it, else use the bindport
|
||||||
|
|
|
@ -198,7 +198,7 @@ func TestGetMasterEndpoint(t *testing.T) {
|
||||||
|
|
||||||
for _, rt := range tests {
|
for _, rt := range tests {
|
||||||
t.Run(rt.name, func(t *testing.T) {
|
t.Run(rt.name, func(t *testing.T) {
|
||||||
actualEndpoint, actualError := GetMasterEndpoint(rt.cfg)
|
actualEndpoint, actualError := GetMasterEndpoint(rt.cfg.ControlPlaneEndpoint, &rt.cfg.LocalAPIEndpoint)
|
||||||
|
|
||||||
if (actualError != nil) && !rt.expectedError {
|
if (actualError != nil) && !rt.expectedError {
|
||||||
t.Errorf("%s unexpected failure: %v", rt.name, actualError)
|
t.Errorf("%s unexpected failure: %v", rt.name, actualError)
|
||||||
|
|
|
@ -290,14 +290,14 @@ func CheckConfigurationIsHA(cfg *kubeadmapi.Etcd) bool {
|
||||||
|
|
||||||
// GetClientURL creates an HTTPS URL that uses the configured advertise
|
// GetClientURL creates an HTTPS URL that uses the configured advertise
|
||||||
// address and client port for the API controller
|
// address and client port for the API controller
|
||||||
func GetClientURL(cfg *kubeadmapi.InitConfiguration) string {
|
func GetClientURL(localEndpoint *kubeadmapi.APIEndpoint) string {
|
||||||
return "https://" + net.JoinHostPort(cfg.LocalAPIEndpoint.AdvertiseAddress, strconv.Itoa(constants.EtcdListenClientPort))
|
return "https://" + net.JoinHostPort(localEndpoint.AdvertiseAddress, strconv.Itoa(constants.EtcdListenClientPort))
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPeerURL creates an HTTPS URL that uses the configured advertise
|
// GetPeerURL creates an HTTPS URL that uses the configured advertise
|
||||||
// address and peer port for the API controller
|
// address and peer port for the API controller
|
||||||
func GetPeerURL(cfg *kubeadmapi.InitConfiguration) string {
|
func GetPeerURL(localEndpoint *kubeadmapi.APIEndpoint) string {
|
||||||
return "https://" + net.JoinHostPort(cfg.LocalAPIEndpoint.AdvertiseAddress, strconv.Itoa(constants.EtcdListenPeerPort))
|
return "https://" + net.JoinHostPort(localEndpoint.AdvertiseAddress, strconv.Itoa(constants.EtcdListenPeerPort))
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetClientURLByIP creates an HTTPS URL based on an IP address
|
// GetClientURLByIP creates an HTTPS URL based on an IP address
|
||||||
|
|
|
@ -72,7 +72,7 @@ func TestCheckConfigurationIsHA(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func testGetURL(t *testing.T, getURLFunc func(*kubeadmapi.InitConfiguration) string, port int) {
|
func testGetURL(t *testing.T, getURLFunc func(*kubeadmapi.APIEndpoint) string, port int) {
|
||||||
portStr := strconv.Itoa(port)
|
portStr := strconv.Itoa(port)
|
||||||
var tests = []struct {
|
var tests = []struct {
|
||||||
name string
|
name string
|
||||||
|
@ -102,12 +102,7 @@ func testGetURL(t *testing.T, getURLFunc func(*kubeadmapi.InitConfiguration) str
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
cfg := &kubeadmapi.InitConfiguration{
|
url := getURLFunc(&kubeadmapi.APIEndpoint{AdvertiseAddress: test.advertiseAddress})
|
||||||
LocalAPIEndpoint: kubeadmapi.APIEndpoint{
|
|
||||||
AdvertiseAddress: test.advertiseAddress,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
url := getURLFunc(cfg)
|
|
||||||
if url != test.expectedURL {
|
if url != test.expectedURL {
|
||||||
t.Errorf("expected %s, got %s", test.expectedURL, url)
|
t.Errorf("expected %s, got %s", test.expectedURL, url)
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,11 +12,9 @@ go_test(
|
||||||
embed = [":go_default_library"],
|
embed = [":go_default_library"],
|
||||||
deps = [
|
deps = [
|
||||||
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
||||||
"//cmd/kubeadm/app/constants:go_default_library",
|
|
||||||
"//cmd/kubeadm/test:go_default_library",
|
"//cmd/kubeadm/test:go_default_library",
|
||||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
|
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -32,7 +30,6 @@ go_library(
|
||||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
|
|
||||||
"//vendor/github.com/pkg/errors:go_default_library",
|
"//vendor/github.com/pkg/errors:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
|
@ -31,7 +31,6 @@ import (
|
||||||
"k8s.io/api/core/v1"
|
"k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/api/resource"
|
"k8s.io/apimachinery/pkg/api/resource"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/util/intstr"
|
|
||||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/util"
|
"k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||||
|
@ -82,28 +81,11 @@ func ComponentResources(cpu string) v1.ResourceRequirements {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ComponentProbe is a helper function building a ready v1.Probe object from some simple parameters
|
|
||||||
func ComponentProbe(cfg *kubeadmapi.InitConfiguration, componentName string, port int, path string, scheme v1.URIScheme) *v1.Probe {
|
|
||||||
return &v1.Probe{
|
|
||||||
Handler: v1.Handler{
|
|
||||||
HTTPGet: &v1.HTTPGetAction{
|
|
||||||
Host: GetProbeAddress(cfg, componentName),
|
|
||||||
Path: path,
|
|
||||||
Port: intstr.FromInt(port),
|
|
||||||
Scheme: scheme,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
InitialDelaySeconds: 15,
|
|
||||||
TimeoutSeconds: 15,
|
|
||||||
FailureThreshold: 8,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// EtcdProbe is a helper function for building a shell-based, etcdctl v1.Probe object to healthcheck etcd
|
// EtcdProbe is a helper function for building a shell-based, etcdctl v1.Probe object to healthcheck etcd
|
||||||
func EtcdProbe(cfg *kubeadmapi.InitConfiguration, componentName string, port int, certsDir string, CACertName string, CertName string, KeyName string) *v1.Probe {
|
func EtcdProbe(cfg *kubeadmapi.Etcd, port int, certsDir string, CACertName string, CertName string, KeyName string) *v1.Probe {
|
||||||
tlsFlags := fmt.Sprintf("--cacert=%[1]s/%[2]s --cert=%[1]s/%[3]s --key=%[1]s/%[4]s", certsDir, CACertName, CertName, KeyName)
|
tlsFlags := fmt.Sprintf("--cacert=%[1]s/%[2]s --cert=%[1]s/%[3]s --key=%[1]s/%[4]s", certsDir, CACertName, CertName, KeyName)
|
||||||
// etcd pod is alive if a linearizable get succeeds.
|
// etcd pod is alive if a linearizable get succeeds.
|
||||||
cmd := fmt.Sprintf("ETCDCTL_API=3 etcdctl --endpoints=https://[%s]:%d %s get foo", GetProbeAddress(cfg, componentName), port, tlsFlags)
|
cmd := fmt.Sprintf("ETCDCTL_API=3 etcdctl --endpoints=https://[%s]:%d %s get foo", GetEtcdProbeAddress(cfg), port, tlsFlags)
|
||||||
|
|
||||||
return &v1.Probe{
|
return &v1.Probe{
|
||||||
Handler: v1.Handler{
|
Handler: v1.Handler{
|
||||||
|
@ -225,71 +207,80 @@ func ReadStaticPodFromDisk(manifestPath string) (*v1.Pod, error) {
|
||||||
return pod, nil
|
return pod, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetProbeAddress returns an IP address or 127.0.0.1 to use for liveness probes
|
// GetAPIServerProbeAddress returns the probe address for the API server
|
||||||
// in static pod manifests.
|
func GetAPIServerProbeAddress(endpoint *kubeadmapi.APIEndpoint) string {
|
||||||
func GetProbeAddress(cfg *kubeadmapi.InitConfiguration, componentName string) string {
|
// In the case of a self-hosted deployment, the initial host on which kubeadm --init is run,
|
||||||
switch {
|
// will generate a DaemonSet with a nodeSelector such that all nodes with the label
|
||||||
case componentName == kubeadmconstants.KubeAPIServer:
|
// node-role.kubernetes.io/master='' will have the API server deployed to it. Since the init
|
||||||
// In the case of a self-hosted deployment, the initial host on which kubeadm --init is run,
|
// is run only once on an initial host, the API advertise address will be invalid for any
|
||||||
// will generate a DaemonSet with a nodeSelector such that all nodes with the label
|
// future hosts that do not have the same address. Furthermore, since liveness and readiness
|
||||||
// node-role.kubernetes.io/master='' will have the API server deployed to it. Since the init
|
// probes do not support the Downward API we cannot dynamically set the advertise address to
|
||||||
// is run only once on an initial host, the API advertise address will be invalid for any
|
// the node's IP. The only option then is to use localhost.
|
||||||
// future hosts that do not have the same address. Furthermore, since liveness and readiness
|
if endpoint != nil && endpoint.AdvertiseAddress != "" {
|
||||||
// probes do not support the Downward API we cannot dynamically set the advertise address to
|
return endpoint.AdvertiseAddress
|
||||||
// the node's IP. The only option then is to use localhost.
|
}
|
||||||
if cfg.LocalAPIEndpoint.AdvertiseAddress != "" {
|
|
||||||
return cfg.LocalAPIEndpoint.AdvertiseAddress
|
return "127.0.0.1"
|
||||||
}
|
}
|
||||||
case componentName == kubeadmconstants.KubeControllerManager:
|
|
||||||
if addr, exists := cfg.ControllerManager.ExtraArgs[kubeControllerManagerAddressArg]; exists {
|
// GetControllerManagerProbeAddress returns the kubernetes controller manager probe address
|
||||||
return addr
|
func GetControllerManagerProbeAddress(cfg *kubeadmapi.ClusterConfiguration) string {
|
||||||
}
|
if addr, exists := cfg.ControllerManager.ExtraArgs[kubeControllerManagerAddressArg]; exists {
|
||||||
case componentName == kubeadmconstants.KubeScheduler:
|
return addr
|
||||||
if addr, exists := cfg.Scheduler.ExtraArgs[kubeSchedulerAddressArg]; exists {
|
}
|
||||||
return addr
|
return "127.0.0.1"
|
||||||
}
|
}
|
||||||
case componentName == kubeadmconstants.Etcd:
|
|
||||||
if cfg.Etcd.Local != nil && cfg.Etcd.Local.ExtraArgs != nil {
|
// GetSchedulerProbeAddress returns the kubernetes scheduler probe address
|
||||||
if arg, exists := cfg.Etcd.Local.ExtraArgs[etcdListenClientURLsArg]; exists {
|
func GetSchedulerProbeAddress(cfg *kubeadmapi.ClusterConfiguration) string {
|
||||||
// Use the first url in the listen-client-urls if multiple url's are specified.
|
if addr, exists := cfg.Scheduler.ExtraArgs[kubeSchedulerAddressArg]; exists {
|
||||||
if strings.ContainsAny(arg, ",") {
|
return addr
|
||||||
arg = strings.Split(arg, ",")[0]
|
}
|
||||||
|
return "127.0.0.1"
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetEtcdProbeAddress returns the etcd probe address
|
||||||
|
func GetEtcdProbeAddress(cfg *kubeadmapi.Etcd) string {
|
||||||
|
if cfg.Local != nil && cfg.Local.ExtraArgs != nil {
|
||||||
|
if arg, exists := cfg.Local.ExtraArgs[etcdListenClientURLsArg]; exists {
|
||||||
|
// Use the first url in the listen-client-urls if multiple url's are specified.
|
||||||
|
if strings.ContainsAny(arg, ",") {
|
||||||
|
arg = strings.Split(arg, ",")[0]
|
||||||
|
}
|
||||||
|
parsedURL, err := url.Parse(arg)
|
||||||
|
if err != nil || parsedURL.Hostname() == "" {
|
||||||
|
return "127.0.0.1"
|
||||||
|
}
|
||||||
|
// Return the IP if the URL contains an address instead of a name.
|
||||||
|
if ip := net.ParseIP(parsedURL.Hostname()); ip != nil {
|
||||||
|
// etcdctl doesn't support auto-converting zero addresses into loopback addresses
|
||||||
|
if ip.Equal(net.IPv4zero) {
|
||||||
|
return "127.0.0.1"
|
||||||
}
|
}
|
||||||
parsedURL, err := url.Parse(arg)
|
if ip.Equal(net.IPv6zero) {
|
||||||
if err != nil || parsedURL.Hostname() == "" {
|
return net.IPv6loopback.String()
|
||||||
break
|
|
||||||
}
|
|
||||||
// Return the IP if the URL contains an address instead of a name.
|
|
||||||
if ip := net.ParseIP(parsedURL.Hostname()); ip != nil {
|
|
||||||
// etcdctl doesn't support auto-converting zero addresses into loopback addresses
|
|
||||||
if ip.Equal(net.IPv4zero) {
|
|
||||||
return "127.0.0.1"
|
|
||||||
}
|
|
||||||
if ip.Equal(net.IPv6zero) {
|
|
||||||
return net.IPv6loopback.String()
|
|
||||||
}
|
|
||||||
return ip.String()
|
|
||||||
}
|
|
||||||
// Use the local resolver to try resolving the name within the URL.
|
|
||||||
// If the name can not be resolved, return an IPv4 loopback address.
|
|
||||||
// Otherwise, select the first valid IPv4 address.
|
|
||||||
// If the name does not resolve to an IPv4 address, select the first valid IPv6 address.
|
|
||||||
addrs, err := net.LookupIP(parsedURL.Hostname())
|
|
||||||
if err != nil {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
var ip net.IP
|
|
||||||
for _, addr := range addrs {
|
|
||||||
if addr.To4() != nil {
|
|
||||||
ip = addr
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if addr.To16() != nil && ip == nil {
|
|
||||||
ip = addr
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return ip.String()
|
return ip.String()
|
||||||
}
|
}
|
||||||
|
// Use the local resolver to try resolving the name within the URL.
|
||||||
|
// If the name can not be resolved, return an IPv4 loopback address.
|
||||||
|
// Otherwise, select the first valid IPv4 address.
|
||||||
|
// If the name does not resolve to an IPv4 address, select the first valid IPv6 address.
|
||||||
|
addrs, err := net.LookupIP(parsedURL.Hostname())
|
||||||
|
if err != nil {
|
||||||
|
return "127.0.0.1"
|
||||||
|
}
|
||||||
|
var ip net.IP
|
||||||
|
for _, addr := range addrs {
|
||||||
|
if addr.To4() != nil {
|
||||||
|
ip = addr
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if addr.To16() != nil && ip == nil {
|
||||||
|
ip = addr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ip.String()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return "127.0.0.1"
|
return "127.0.0.1"
|
||||||
|
|
|
@ -27,9 +27,7 @@ import (
|
||||||
|
|
||||||
"k8s.io/api/core/v1"
|
"k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/util/intstr"
|
|
||||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
|
||||||
testutil "k8s.io/kubernetes/cmd/kubeadm/test"
|
testutil "k8s.io/kubernetes/cmd/kubeadm/test"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -42,151 +40,73 @@ func TestComponentResources(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestComponentProbe(t *testing.T) {
|
func TestGetAPIServerProbeAddress(t *testing.T) {
|
||||||
var tests = []struct {
|
tests := []struct {
|
||||||
name string
|
desc string
|
||||||
cfg *kubeadmapi.InitConfiguration
|
endpoint *kubeadmapi.APIEndpoint
|
||||||
component string
|
expected string
|
||||||
port int
|
|
||||||
path string
|
|
||||||
scheme v1.URIScheme
|
|
||||||
expected string
|
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "default apiserver advertise address with http",
|
desc: "nil endpoint returns 127.0.0.1",
|
||||||
cfg: &kubeadmapi.InitConfiguration{
|
expected: "127.0.0.1",
|
||||||
LocalAPIEndpoint: kubeadmapi.APIEndpoint{
|
|
||||||
AdvertiseAddress: "",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
component: kubeadmconstants.KubeAPIServer,
|
|
||||||
port: 1,
|
|
||||||
path: "foo",
|
|
||||||
scheme: v1.URISchemeHTTP,
|
|
||||||
expected: "127.0.0.1",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "default apiserver advertise address with https",
|
desc: "empty AdvertiseAddress endpoint returns 127.0.0.1",
|
||||||
cfg: &kubeadmapi.InitConfiguration{
|
endpoint: &kubeadmapi.APIEndpoint{},
|
||||||
LocalAPIEndpoint: kubeadmapi.APIEndpoint{
|
expected: "127.0.0.1",
|
||||||
AdvertiseAddress: "",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
component: kubeadmconstants.KubeAPIServer,
|
|
||||||
port: 2,
|
|
||||||
path: "bar",
|
|
||||||
scheme: v1.URISchemeHTTPS,
|
|
||||||
expected: "127.0.0.1",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "valid ipv4 apiserver advertise address with http",
|
desc: "filled in AdvertiseAddress endpoint returns it",
|
||||||
cfg: &kubeadmapi.InitConfiguration{
|
endpoint: &kubeadmapi.APIEndpoint{
|
||||||
LocalAPIEndpoint: kubeadmapi.APIEndpoint{
|
AdvertiseAddress: "10.10.10.10",
|
||||||
AdvertiseAddress: "1.2.3.4",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
component: kubeadmconstants.KubeAPIServer,
|
expected: "10.10.10.10",
|
||||||
port: 1,
|
|
||||||
path: "foo",
|
|
||||||
scheme: v1.URISchemeHTTP,
|
|
||||||
expected: "1.2.3.4",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "valid ipv6 apiserver advertise address with http",
|
|
||||||
cfg: &kubeadmapi.InitConfiguration{
|
|
||||||
LocalAPIEndpoint: kubeadmapi.APIEndpoint{
|
|
||||||
AdvertiseAddress: "2001:db8::1",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
component: kubeadmconstants.KubeAPIServer,
|
|
||||||
port: 1,
|
|
||||||
path: "foo",
|
|
||||||
scheme: v1.URISchemeHTTP,
|
|
||||||
expected: "2001:db8::1",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "valid IPv4 controller-manager probe",
|
|
||||||
cfg: &kubeadmapi.InitConfiguration{
|
|
||||||
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
|
|
||||||
ControllerManager: kubeadmapi.ControlPlaneComponent{
|
|
||||||
ExtraArgs: map[string]string{"address": "1.2.3.4"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
component: kubeadmconstants.KubeControllerManager,
|
|
||||||
port: 1,
|
|
||||||
path: "foo",
|
|
||||||
scheme: v1.URISchemeHTTP,
|
|
||||||
expected: "1.2.3.4",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "valid IPv6 controller-manager probe",
|
|
||||||
cfg: &kubeadmapi.InitConfiguration{
|
|
||||||
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
|
|
||||||
ControllerManager: kubeadmapi.ControlPlaneComponent{
|
|
||||||
ExtraArgs: map[string]string{"address": "2001:db8::1"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
component: kubeadmconstants.KubeControllerManager,
|
|
||||||
port: 1,
|
|
||||||
path: "foo",
|
|
||||||
scheme: v1.URISchemeHTTP,
|
|
||||||
expected: "2001:db8::1",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "valid IPv4 scheduler probe",
|
|
||||||
cfg: &kubeadmapi.InitConfiguration{
|
|
||||||
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
|
|
||||||
Scheduler: kubeadmapi.ControlPlaneComponent{
|
|
||||||
ExtraArgs: map[string]string{"address": "1.2.3.4"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
component: kubeadmconstants.KubeScheduler,
|
|
||||||
port: 1,
|
|
||||||
path: "foo",
|
|
||||||
scheme: v1.URISchemeHTTP,
|
|
||||||
expected: "1.2.3.4",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "valid IPv6 scheduler probe",
|
|
||||||
cfg: &kubeadmapi.InitConfiguration{
|
|
||||||
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
|
|
||||||
Scheduler: kubeadmapi.ControlPlaneComponent{
|
|
||||||
ExtraArgs: map[string]string{"address": "2001:db8::1"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
component: kubeadmconstants.KubeScheduler,
|
|
||||||
port: 1,
|
|
||||||
path: "foo",
|
|
||||||
scheme: v1.URISchemeHTTP,
|
|
||||||
expected: "2001:db8::1",
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, rt := range tests {
|
|
||||||
t.Run(rt.name, func(t *testing.T) {
|
for _, test := range tests {
|
||||||
actual := ComponentProbe(rt.cfg, rt.component, rt.port, rt.path, rt.scheme)
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
if actual.Handler.HTTPGet.Host != rt.expected {
|
actual := GetAPIServerProbeAddress(test.endpoint)
|
||||||
t.Errorf("%s test case failed:\n\texpected: %s\n\t actual: %s",
|
if actual != test.expected {
|
||||||
rt.name, rt.expected,
|
t.Errorf("Unexpected result from GetAPIServerProbeAddress:\n\texpected: %s\n\tactual: %s", test.expected, actual)
|
||||||
actual.Handler.HTTPGet.Host)
|
|
||||||
}
|
}
|
||||||
if actual.Handler.HTTPGet.Port != intstr.FromInt(rt.port) {
|
})
|
||||||
t.Errorf("%s test case failed:\n\texpected: %v\n\t actual: %v",
|
}
|
||||||
rt.name, rt.port,
|
}
|
||||||
actual.Handler.HTTPGet.Port)
|
|
||||||
}
|
func TestGetControllerManagerProbeAddress(t *testing.T) {
|
||||||
if actual.Handler.HTTPGet.Path != rt.path {
|
tests := []struct {
|
||||||
t.Errorf("%s test case failed:\n\texpected: %s\n\t actual: %s",
|
desc string
|
||||||
rt.name, rt.path,
|
cfg *kubeadmapi.ClusterConfiguration
|
||||||
actual.Handler.HTTPGet.Path)
|
expected string
|
||||||
}
|
}{
|
||||||
if actual.Handler.HTTPGet.Scheme != rt.scheme {
|
{
|
||||||
t.Errorf("%s test case failed:\n\texpected: %v\n\t actual: %v",
|
desc: "no controller manager extra args leads to 127.0.0.1 being used",
|
||||||
rt.name, rt.scheme,
|
cfg: &kubeadmapi.ClusterConfiguration{
|
||||||
actual.Handler.HTTPGet.Scheme)
|
ControllerManager: kubeadmapi.ControlPlaneComponent{
|
||||||
|
ExtraArgs: map[string]string{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: "127.0.0.1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "setting controller manager extra address arg to something acknowledges it",
|
||||||
|
cfg: &kubeadmapi.ClusterConfiguration{
|
||||||
|
ControllerManager: kubeadmapi.ControlPlaneComponent{
|
||||||
|
ExtraArgs: map[string]string{
|
||||||
|
kubeControllerManagerAddressArg: "10.10.10.10",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: "10.10.10.10",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
|
actual := GetControllerManagerProbeAddress(test.cfg)
|
||||||
|
if actual != test.expected {
|
||||||
|
t.Errorf("Unexpected result from GetControllerManagerProbeAddress:\n\texpected: %s\n\tactual: %s", test.expected, actual)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -194,150 +114,124 @@ func TestComponentProbe(t *testing.T) {
|
||||||
|
|
||||||
func TestEtcdProbe(t *testing.T) {
|
func TestEtcdProbe(t *testing.T) {
|
||||||
var tests = []struct {
|
var tests = []struct {
|
||||||
name string
|
name string
|
||||||
cfg *kubeadmapi.ClusterConfiguration
|
cfg *kubeadmapi.Etcd
|
||||||
component string
|
port int
|
||||||
port int
|
certsDir string
|
||||||
certsDir string
|
cacert string
|
||||||
cacert string
|
cert string
|
||||||
cert string
|
key string
|
||||||
key string
|
expected string
|
||||||
expected string
|
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "valid etcd probe using listen-client-urls IPv4 addresses",
|
name: "valid etcd probe using listen-client-urls IPv4 addresses",
|
||||||
cfg: &kubeadmapi.ClusterConfiguration{
|
cfg: &kubeadmapi.Etcd{
|
||||||
Etcd: kubeadmapi.Etcd{
|
Local: &kubeadmapi.LocalEtcd{
|
||||||
Local: &kubeadmapi.LocalEtcd{
|
ExtraArgs: map[string]string{
|
||||||
ExtraArgs: map[string]string{
|
"listen-client-urls": "http://1.2.3.4:2379,http://4.3.2.1:2379"},
|
||||||
"listen-client-urls": "http://1.2.3.4:2379,http://4.3.2.1:2379"},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
component: kubeadmconstants.Etcd,
|
port: 1,
|
||||||
port: 1,
|
certsDir: "secretsA",
|
||||||
certsDir: "secretsA",
|
cacert: "ca1",
|
||||||
cacert: "ca1",
|
cert: "cert1",
|
||||||
cert: "cert1",
|
key: "key1",
|
||||||
key: "key1",
|
expected: "ETCDCTL_API=3 etcdctl --endpoints=https://[1.2.3.4]:1 --cacert=secretsA/ca1 --cert=secretsA/cert1 --key=secretsA/key1 get foo",
|
||||||
expected: "ETCDCTL_API=3 etcdctl --endpoints=https://[1.2.3.4]:1 --cacert=secretsA/ca1 --cert=secretsA/cert1 --key=secretsA/key1 get foo",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "valid etcd probe using listen-client-urls unspecified IPv6 address",
|
name: "valid etcd probe using listen-client-urls unspecified IPv6 address",
|
||||||
cfg: &kubeadmapi.ClusterConfiguration{
|
cfg: &kubeadmapi.Etcd{
|
||||||
Etcd: kubeadmapi.Etcd{
|
Local: &kubeadmapi.LocalEtcd{
|
||||||
Local: &kubeadmapi.LocalEtcd{
|
ExtraArgs: map[string]string{
|
||||||
ExtraArgs: map[string]string{
|
"listen-client-urls": "http://[0:0:0:0:0:0:0:0]:2379"},
|
||||||
"listen-client-urls": "http://[0:0:0:0:0:0:0:0]:2379"},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
component: kubeadmconstants.Etcd,
|
port: 1,
|
||||||
port: 1,
|
certsDir: "secretsB",
|
||||||
certsDir: "secretsB",
|
cacert: "ca2",
|
||||||
cacert: "ca2",
|
cert: "cert2",
|
||||||
cert: "cert2",
|
key: "key2",
|
||||||
key: "key2",
|
expected: "ETCDCTL_API=3 etcdctl --endpoints=https://[::1]:1 --cacert=secretsB/ca2 --cert=secretsB/cert2 --key=secretsB/key2 get foo",
|
||||||
expected: "ETCDCTL_API=3 etcdctl --endpoints=https://[::1]:1 --cacert=secretsB/ca2 --cert=secretsB/cert2 --key=secretsB/key2 get foo",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "valid etcd probe using listen-client-urls unspecified IPv6 address 2",
|
name: "valid etcd probe using listen-client-urls unspecified IPv6 address 2",
|
||||||
cfg: &kubeadmapi.ClusterConfiguration{
|
cfg: &kubeadmapi.Etcd{
|
||||||
Etcd: kubeadmapi.Etcd{
|
Local: &kubeadmapi.LocalEtcd{
|
||||||
Local: &kubeadmapi.LocalEtcd{
|
ExtraArgs: map[string]string{
|
||||||
ExtraArgs: map[string]string{
|
"listen-client-urls": "http://[::0:0]:2379"},
|
||||||
"listen-client-urls": "http://[::0:0]:2379"},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
component: kubeadmconstants.Etcd,
|
port: 1,
|
||||||
port: 1,
|
certsDir: "secretsB",
|
||||||
certsDir: "secretsB",
|
cacert: "ca2",
|
||||||
cacert: "ca2",
|
cert: "cert2",
|
||||||
cert: "cert2",
|
key: "key2",
|
||||||
key: "key2",
|
expected: "ETCDCTL_API=3 etcdctl --endpoints=https://[::1]:1 --cacert=secretsB/ca2 --cert=secretsB/cert2 --key=secretsB/key2 get foo",
|
||||||
expected: "ETCDCTL_API=3 etcdctl --endpoints=https://[::1]:1 --cacert=secretsB/ca2 --cert=secretsB/cert2 --key=secretsB/key2 get foo",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "valid etcd probe using listen-client-urls unspecified IPv6 address 3",
|
name: "valid etcd probe using listen-client-urls unspecified IPv6 address 3",
|
||||||
cfg: &kubeadmapi.ClusterConfiguration{
|
cfg: &kubeadmapi.Etcd{
|
||||||
Etcd: kubeadmapi.Etcd{
|
Local: &kubeadmapi.LocalEtcd{
|
||||||
Local: &kubeadmapi.LocalEtcd{
|
ExtraArgs: map[string]string{
|
||||||
ExtraArgs: map[string]string{
|
"listen-client-urls": "http://[::]:2379"},
|
||||||
"listen-client-urls": "http://[::]:2379"},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
component: kubeadmconstants.Etcd,
|
port: 1,
|
||||||
port: 1,
|
certsDir: "secretsB",
|
||||||
certsDir: "secretsB",
|
cacert: "ca2",
|
||||||
cacert: "ca2",
|
cert: "cert2",
|
||||||
cert: "cert2",
|
key: "key2",
|
||||||
key: "key2",
|
expected: "ETCDCTL_API=3 etcdctl --endpoints=https://[::1]:1 --cacert=secretsB/ca2 --cert=secretsB/cert2 --key=secretsB/key2 get foo",
|
||||||
expected: "ETCDCTL_API=3 etcdctl --endpoints=https://[::1]:1 --cacert=secretsB/ca2 --cert=secretsB/cert2 --key=secretsB/key2 get foo",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "valid etcd probe using listen-client-urls unspecified IPv4 address",
|
name: "valid etcd probe using listen-client-urls unspecified IPv4 address",
|
||||||
cfg: &kubeadmapi.ClusterConfiguration{
|
cfg: &kubeadmapi.Etcd{
|
||||||
Etcd: kubeadmapi.Etcd{
|
Local: &kubeadmapi.LocalEtcd{
|
||||||
Local: &kubeadmapi.LocalEtcd{
|
ExtraArgs: map[string]string{
|
||||||
ExtraArgs: map[string]string{
|
"listen-client-urls": "http://1.2.3.4:2379,http://4.3.2.1:2379"},
|
||||||
"listen-client-urls": "http://1.2.3.4:2379,http://4.3.2.1:2379"},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
component: kubeadmconstants.Etcd,
|
port: 1,
|
||||||
port: 1,
|
certsDir: "secretsA",
|
||||||
certsDir: "secretsA",
|
cacert: "ca1",
|
||||||
cacert: "ca1",
|
cert: "cert1",
|
||||||
cert: "cert1",
|
key: "key1",
|
||||||
key: "key1",
|
expected: "ETCDCTL_API=3 etcdctl --endpoints=https://[1.2.3.4]:1 --cacert=secretsA/ca1 --cert=secretsA/cert1 --key=secretsA/key1 get foo",
|
||||||
expected: "ETCDCTL_API=3 etcdctl --endpoints=https://[1.2.3.4]:1 --cacert=secretsA/ca1 --cert=secretsA/cert1 --key=secretsA/key1 get foo",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "valid etcd probe using listen-client-urls IPv6 addresses",
|
name: "valid etcd probe using listen-client-urls IPv6 addresses",
|
||||||
cfg: &kubeadmapi.ClusterConfiguration{
|
cfg: &kubeadmapi.Etcd{
|
||||||
Etcd: kubeadmapi.Etcd{
|
Local: &kubeadmapi.LocalEtcd{
|
||||||
Local: &kubeadmapi.LocalEtcd{
|
ExtraArgs: map[string]string{
|
||||||
ExtraArgs: map[string]string{
|
"listen-client-urls": "http://[2001:db8::1]:2379,http://[2001:db8::2]:2379"},
|
||||||
"listen-client-urls": "http://[2001:db8::1]:2379,http://[2001:db8::2]:2379"},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
component: kubeadmconstants.Etcd,
|
port: 1,
|
||||||
port: 1,
|
certsDir: "secretsB",
|
||||||
certsDir: "secretsB",
|
cacert: "ca2",
|
||||||
cacert: "ca2",
|
cert: "cert2",
|
||||||
cert: "cert2",
|
key: "key2",
|
||||||
key: "key2",
|
expected: "ETCDCTL_API=3 etcdctl --endpoints=https://[2001:db8::1]:1 --cacert=secretsB/ca2 --cert=secretsB/cert2 --key=secretsB/key2 get foo",
|
||||||
expected: "ETCDCTL_API=3 etcdctl --endpoints=https://[2001:db8::1]:1 --cacert=secretsB/ca2 --cert=secretsB/cert2 --key=secretsB/key2 get foo",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "valid IPv4 etcd probe using hostname for listen-client-urls",
|
name: "valid IPv4 etcd probe using hostname for listen-client-urls",
|
||||||
cfg: &kubeadmapi.ClusterConfiguration{
|
cfg: &kubeadmapi.Etcd{
|
||||||
Etcd: kubeadmapi.Etcd{
|
Local: &kubeadmapi.LocalEtcd{
|
||||||
Local: &kubeadmapi.LocalEtcd{
|
ExtraArgs: map[string]string{
|
||||||
ExtraArgs: map[string]string{
|
"listen-client-urls": "http://localhost:2379"},
|
||||||
"listen-client-urls": "http://localhost:2379"},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
component: kubeadmconstants.Etcd,
|
port: 1,
|
||||||
port: 1,
|
certsDir: "secretsC",
|
||||||
certsDir: "secretsC",
|
cacert: "ca3",
|
||||||
cacert: "ca3",
|
cert: "cert3",
|
||||||
cert: "cert3",
|
key: "key3",
|
||||||
key: "key3",
|
expected: "ETCDCTL_API=3 etcdctl --endpoints=https://[127.0.0.1]:1 --cacert=secretsC/ca3 --cert=secretsC/cert3 --key=secretsC/key3 get foo",
|
||||||
expected: "ETCDCTL_API=3 etcdctl --endpoints=https://[127.0.0.1]:1 --cacert=secretsC/ca3 --cert=secretsC/cert3 --key=secretsC/key3 get foo",
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, rt := range tests {
|
for _, rt := range tests {
|
||||||
t.Run(rt.name, func(t *testing.T) {
|
t.Run(rt.name, func(t *testing.T) {
|
||||||
// TODO: Make EtcdProbe accept a ClusterConfiguration object instead of InitConfiguration
|
actual := EtcdProbe(rt.cfg, rt.port, rt.certsDir, rt.cacert, rt.cert, rt.key)
|
||||||
initcfg := &kubeadmapi.InitConfiguration{
|
|
||||||
ClusterConfiguration: *rt.cfg,
|
|
||||||
}
|
|
||||||
actual := EtcdProbe(initcfg, rt.component, rt.port, rt.certsDir, rt.cacert, rt.cert, rt.key)
|
|
||||||
if actual.Handler.Exec.Command[2] != rt.expected {
|
if actual.Handler.Exec.Command[2] != rt.expected {
|
||||||
t.Errorf("%s test case failed:\n\texpected: %s\n\t actual: %s",
|
t.Errorf("%s test case failed:\n\texpected: %s\n\t actual: %s",
|
||||||
rt.name, rt.expected,
|
rt.name, rt.expected,
|
||||||
|
|
Loading…
Reference in New Issue