blob: 2d37fda4a034db77bf1c1766f946e3be76b98873 [file] [log] [blame]
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package phases
import (
"github.com/pkg/errors"
"k8s.io/klog"
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/options"
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow"
kubeletphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubelet"
"k8s.io/kubernetes/pkg/util/normalizer"
)
var (
kubeletStartPhaseExample = normalizer.Examples(`
# Writes a dynamic environment file with kubelet flags from a InitConfiguration file.
kubeadm init phase kubelet-start --config masterconfig.yaml
`)
)
// kubeletStartData defines the behavior that a runtime data struct passed to the kubelet start phase
// should have. Please note that we are using an interface in order to make this phase reusable in different workflows
// (and thus with different runtime data struct, all of them requested to be compliant to this interface)
type kubeletStartData interface {
Cfg() *kubeadmapi.InitConfiguration
DryRun() bool
KubeletDir() string
}
// NewKubeletStartPhase creates a kubeadm workflow phase that start kubelet on a node.
func NewKubeletStartPhase() workflow.Phase {
return workflow.Phase{
Name: "kubelet-start",
Short: "Writes kubelet settings and (re)starts the kubelet",
Long: "Writes a file with KubeletConfiguration and an environment file with node specific kubelet settings, and then (re)starts kubelet.",
Example: kubeletStartPhaseExample,
Run: runKubeletStart,
InheritFlags: []string{
options.CfgPath,
options.NodeCRISocket,
options.NodeName,
},
}
}
// runKubeletStart executes kubelet start logic.
func runKubeletStart(c workflow.RunData) error {
data, ok := c.(kubeletStartData)
if !ok {
return errors.New("kubelet-start phase invoked with an invalid data struct")
}
// First off, configure the kubelet. In this short timeframe, kubeadm is trying to stop/restart the kubelet
// Try to stop the kubelet service so no race conditions occur when configuring it
if !data.DryRun() {
klog.V(1).Infof("Stopping the kubelet")
kubeletphase.TryStopKubelet()
}
// 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
// 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 {
return errors.Wrap(err, "error writing a dynamic environment file for the kubelet")
}
// Write the kubelet configuration file to disk.
if err := kubeletphase.WriteConfigToDisk(data.Cfg().ComponentConfigs.Kubelet, data.KubeletDir()); err != nil {
return errors.Wrap(err, "error writing kubelet configuration to disk")
}
// Try to start the kubelet service in case it's inactive
if !data.DryRun() {
klog.V(1).Infof("Starting the kubelet")
kubeletphase.TryStartKubelet()
}
return nil
}