mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-04 18:00:08 +00:00
Decouple startup of executor and kubelet
This commit is contained in:
parent
a60df400fd
commit
dd5bafdba5
@ -87,7 +87,7 @@ func (s *stateType) transitionTo(to stateType, unless ...stateType) bool {
|
|||||||
|
|
||||||
type kuberTask struct {
|
type kuberTask struct {
|
||||||
mesosTaskInfo *mesos.TaskInfo
|
mesosTaskInfo *mesos.TaskInfo
|
||||||
podName string
|
podName string // empty until pod is sent to kubelet and registed in KubernetesExecutor.pods
|
||||||
}
|
}
|
||||||
|
|
||||||
type podStatusFunc func() (*api.PodStatus, error)
|
type podStatusFunc func() (*api.PodStatus, error)
|
||||||
@ -102,14 +102,12 @@ type KubernetesExecutor struct {
|
|||||||
lock sync.Mutex
|
lock sync.Mutex
|
||||||
client *client.Client
|
client *client.Client
|
||||||
terminate chan struct{} // signals that the executor should shutdown
|
terminate chan struct{} // signals that the executor should shutdown
|
||||||
registered chan struct{} // closed when registerd
|
|
||||||
outgoing chan func() (mesos.Status, error) // outgoing queue to the mesos driver
|
outgoing chan func() (mesos.Status, error) // outgoing queue to the mesos driver
|
||||||
dockerClient dockertools.DockerInterface
|
dockerClient dockertools.DockerInterface
|
||||||
suicideWatch suicideWatcher
|
suicideWatch suicideWatcher
|
||||||
suicideTimeout time.Duration
|
suicideTimeout time.Duration
|
||||||
shutdownAlert func() // invoked just prior to executor shutdown
|
shutdownAlert func() // invoked just prior to executor shutdown
|
||||||
kubeletFinished <-chan struct{} // signals that kubelet Run() died
|
kubeletFinished <-chan struct{} // signals that kubelet Run() died
|
||||||
initialRegistration sync.Once
|
|
||||||
exitFunc func(int)
|
exitFunc func(int)
|
||||||
podStatusFunc func(*api.Pod) (*api.PodStatus, error)
|
podStatusFunc func(*api.Pod) (*api.PodStatus, error)
|
||||||
staticPodsConfigPath string
|
staticPodsConfigPath string
|
||||||
@ -152,7 +150,6 @@ func New(config Config) *KubernetesExecutor {
|
|||||||
shutdownAlert: config.ShutdownAlert,
|
shutdownAlert: config.ShutdownAlert,
|
||||||
exitFunc: config.ExitFunc,
|
exitFunc: config.ExitFunc,
|
||||||
podStatusFunc: config.PodStatusFunc,
|
podStatusFunc: config.PodStatusFunc,
|
||||||
registered: make(chan struct{}),
|
|
||||||
staticPodsConfigPath: config.StaticPodsConfigPath,
|
staticPodsConfigPath: config.StaticPodsConfigPath,
|
||||||
launchGracePeriod: config.LaunchGracePeriod,
|
launchGracePeriod: config.LaunchGracePeriod,
|
||||||
}
|
}
|
||||||
@ -182,12 +179,6 @@ func New(config Config) *KubernetesExecutor {
|
|||||||
return k
|
return k
|
||||||
}
|
}
|
||||||
|
|
||||||
// InitiallyRegistered returns a channel which is closed when the executor is
|
|
||||||
// registered with the Mesos master.
|
|
||||||
func (k *KubernetesExecutor) InitiallyRegistered() <-chan struct{} {
|
|
||||||
return k.registered
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *KubernetesExecutor) Init(driver bindings.ExecutorDriver) {
|
func (k *KubernetesExecutor) Init(driver bindings.ExecutorDriver) {
|
||||||
k.killKubeletContainers()
|
k.killKubeletContainers()
|
||||||
k.resetSuicideWatch(driver)
|
k.resetSuicideWatch(driver)
|
||||||
@ -206,6 +197,15 @@ func (k *KubernetesExecutor) isDone() bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sendPodUpdate assumes that caller is holding state lock; returns true when update is sent otherwise false
|
||||||
|
func (k *KubernetesExecutor) sendPodUpdate(u *kubetypes.PodUpdate) bool {
|
||||||
|
if k.isDone() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
k.updateChan <- *u
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// Registered is called when the executor is successfully registered with the slave.
|
// Registered is called when the executor is successfully registered with the slave.
|
||||||
func (k *KubernetesExecutor) Registered(driver bindings.ExecutorDriver,
|
func (k *KubernetesExecutor) Registered(driver bindings.ExecutorDriver,
|
||||||
executorInfo *mesos.ExecutorInfo, frameworkInfo *mesos.FrameworkInfo, slaveInfo *mesos.SlaveInfo) {
|
executorInfo *mesos.ExecutorInfo, frameworkInfo *mesos.FrameworkInfo, slaveInfo *mesos.SlaveInfo) {
|
||||||
@ -229,12 +229,13 @@ func (k *KubernetesExecutor) Registered(driver bindings.ExecutorDriver,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
k.updateChan <- kubetypes.PodUpdate{
|
// emit an empty update to allow the mesos "source" to be marked as seen
|
||||||
|
k.lock.Lock()
|
||||||
|
defer k.lock.Unlock()
|
||||||
|
k.sendPodUpdate(&kubetypes.PodUpdate{
|
||||||
Pods: []*api.Pod{},
|
Pods: []*api.Pod{},
|
||||||
Op: kubetypes.SET,
|
Op: kubetypes.SET,
|
||||||
}
|
})
|
||||||
|
|
||||||
close(k.registered)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reregistered is called when the executor is successfully re-registered with the slave.
|
// Reregistered is called when the executor is successfully re-registered with the slave.
|
||||||
@ -254,17 +255,6 @@ func (k *KubernetesExecutor) Reregistered(driver bindings.ExecutorDriver, slaveI
|
|||||||
log.Errorf("cannot update node labels: %v", err)
|
log.Errorf("cannot update node labels: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// emit an empty update to allow the mesos "source" to be marked as seen
|
|
||||||
k.lock.Lock()
|
|
||||||
defer k.lock.Unlock()
|
|
||||||
if k.isDone() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
k.updateChan <- kubetypes.PodUpdate{
|
|
||||||
Pods: []*api.Pod{},
|
|
||||||
Op: kubetypes.SET,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// initializeStaticPodsSource unzips the data slice into the static-pods directory
|
// initializeStaticPodsSource unzips the data slice into the static-pods directory
|
||||||
@ -378,14 +368,10 @@ func (k *KubernetesExecutor) handleChangedApiserverPod(pod *api.Pod) {
|
|||||||
oldPod.DeletionTimestamp = pod.DeletionTimestamp
|
oldPod.DeletionTimestamp = pod.DeletionTimestamp
|
||||||
oldPod.DeletionGracePeriodSeconds = pod.DeletionGracePeriodSeconds
|
oldPod.DeletionGracePeriodSeconds = pod.DeletionGracePeriodSeconds
|
||||||
|
|
||||||
if k.isDone() {
|
k.sendPodUpdate(&kubetypes.PodUpdate{
|
||||||
return
|
|
||||||
}
|
|
||||||
update := kubetypes.PodUpdate{
|
|
||||||
Op: kubetypes.UPDATE,
|
Op: kubetypes.UPDATE,
|
||||||
Pods: []*api.Pod{oldPod},
|
Pods: []*api.Pod{oldPod},
|
||||||
}
|
})
|
||||||
k.updateChan <- update
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -538,7 +524,7 @@ func (k *KubernetesExecutor) launchTask(driver bindings.ExecutorDriver, taskId s
|
|||||||
k.lock.Lock()
|
k.lock.Lock()
|
||||||
defer k.lock.Unlock()
|
defer k.lock.Unlock()
|
||||||
|
|
||||||
// Add the task.
|
// find task
|
||||||
task, found := k.tasks[taskId]
|
task, found := k.tasks[taskId]
|
||||||
if !found {
|
if !found {
|
||||||
log.V(1).Infof("task %v not found, probably killed: aborting launch, reporting lost", taskId)
|
log.V(1).Infof("task %v not found, probably killed: aborting launch, reporting lost", taskId)
|
||||||
@ -548,21 +534,23 @@ func (k *KubernetesExecutor) launchTask(driver bindings.ExecutorDriver, taskId s
|
|||||||
|
|
||||||
//TODO(jdef) check for duplicate pod name, if found send TASK_ERROR
|
//TODO(jdef) check for duplicate pod name, if found send TASK_ERROR
|
||||||
|
|
||||||
// from here on, we need to delete containers associated with the task
|
// send the new pod to the kubelet which will spin it up
|
||||||
// upon it going into a terminal state
|
ok := k.sendPodUpdate(&kubetypes.PodUpdate{
|
||||||
|
Op: kubetypes.ADD,
|
||||||
|
Pods: []*api.Pod{pod},
|
||||||
|
})
|
||||||
|
if !ok {
|
||||||
|
return // executor is terminating, cancel launch
|
||||||
|
}
|
||||||
|
|
||||||
|
// mark task as sent by setting the podName and register the sent pod
|
||||||
task.podName = podFullName
|
task.podName = podFullName
|
||||||
k.pods[podFullName] = pod
|
k.pods[podFullName] = pod
|
||||||
|
|
||||||
// send the new pod to the kubelet which will spin it up
|
// From here on, we need to delete containers associated with the task upon
|
||||||
if k.isDone() {
|
// it going into a terminal state.
|
||||||
return
|
|
||||||
}
|
|
||||||
update := kubetypes.PodUpdate{
|
|
||||||
Op: kubetypes.ADD,
|
|
||||||
Pods: []*api.Pod{pod},
|
|
||||||
}
|
|
||||||
k.updateChan <- update
|
|
||||||
|
|
||||||
|
// report task is starting to scheduler
|
||||||
statusUpdate := &mesos.TaskStatus{
|
statusUpdate := &mesos.TaskStatus{
|
||||||
TaskId: mutil.NewTaskID(taskId),
|
TaskId: mutil.NewTaskID(taskId),
|
||||||
State: mesos.TaskState_TASK_STARTING.Enum(),
|
State: mesos.TaskState_TASK_STARTING.Enum(),
|
||||||
@ -575,7 +563,6 @@ func (k *KubernetesExecutor) launchTask(driver bindings.ExecutorDriver, taskId s
|
|||||||
psf := podStatusFunc(func() (*api.PodStatus, error) {
|
psf := podStatusFunc(func() (*api.PodStatus, error) {
|
||||||
return k.podStatusFunc(pod)
|
return k.podStatusFunc(pod)
|
||||||
})
|
})
|
||||||
|
|
||||||
go k._launchTask(driver, taskId, podFullName, psf)
|
go k._launchTask(driver, taskId, podFullName, psf)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -751,14 +738,10 @@ func (k *KubernetesExecutor) removePodTask(driver bindings.ExecutorDriver, tid,
|
|||||||
delete(k.pods, pid)
|
delete(k.pods, pid)
|
||||||
|
|
||||||
// tell the kubelet to remove the pod
|
// tell the kubelet to remove the pod
|
||||||
if k.isDone() {
|
k.sendPodUpdate(&kubetypes.PodUpdate{
|
||||||
return
|
|
||||||
}
|
|
||||||
update := kubetypes.PodUpdate{
|
|
||||||
Op: kubetypes.REMOVE,
|
Op: kubetypes.REMOVE,
|
||||||
Pods: []*api.Pod{pod},
|
Pods: []*api.Pod{pod},
|
||||||
}
|
})
|
||||||
k.updateChan <- update
|
|
||||||
}
|
}
|
||||||
// TODO(jdef): ensure that the update propagates, perhaps return a signal chan?
|
// TODO(jdef): ensure that the update propagates, perhaps return a signal chan?
|
||||||
k.sendStatus(driver, newStatus(mutil.NewTaskID(tid), state, reason))
|
k.sendStatus(driver, newStatus(mutil.NewTaskID(tid), state, reason))
|
||||||
|
@ -23,8 +23,8 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/mock"
|
"github.com/stretchr/testify/mock"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
kubetypes "k8s.io/kubernetes/pkg/kubelet/types"
|
|
||||||
"k8s.io/kubernetes/pkg/kubelet/dockertools"
|
"k8s.io/kubernetes/pkg/kubelet/dockertools"
|
||||||
|
kubetypes "k8s.io/kubernetes/pkg/kubelet/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MockExecutorDriver struct {
|
type MockExecutorDriver struct {
|
||||||
|
@ -35,8 +35,10 @@ import (
|
|||||||
"k8s.io/kubernetes/contrib/mesos/pkg/executor/config"
|
"k8s.io/kubernetes/contrib/mesos/pkg/executor/config"
|
||||||
"k8s.io/kubernetes/contrib/mesos/pkg/hyperkube"
|
"k8s.io/kubernetes/contrib/mesos/pkg/hyperkube"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
|
"k8s.io/kubernetes/pkg/client/cache"
|
||||||
client "k8s.io/kubernetes/pkg/client/unversioned"
|
client "k8s.io/kubernetes/pkg/client/unversioned"
|
||||||
"k8s.io/kubernetes/pkg/credentialprovider"
|
"k8s.io/kubernetes/pkg/credentialprovider"
|
||||||
|
"k8s.io/kubernetes/pkg/fields"
|
||||||
"k8s.io/kubernetes/pkg/healthz"
|
"k8s.io/kubernetes/pkg/healthz"
|
||||||
"k8s.io/kubernetes/pkg/kubelet"
|
"k8s.io/kubernetes/pkg/kubelet"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/cadvisor"
|
"k8s.io/kubernetes/pkg/kubelet/cadvisor"
|
||||||
@ -61,7 +63,8 @@ type KubeletExecutorServer struct {
|
|||||||
*app.KubeletServer
|
*app.KubeletServer
|
||||||
SuicideTimeout time.Duration
|
SuicideTimeout time.Duration
|
||||||
LaunchGracePeriod time.Duration
|
LaunchGracePeriod time.Duration
|
||||||
kletLock sync.Mutex
|
|
||||||
|
kletLock sync.Mutex // TODO(sttts): remove necessity to access the kubelet from the executor
|
||||||
klet *kubelet.Kubelet
|
klet *kubelet.Kubelet
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,27 +90,7 @@ func (s *KubeletExecutorServer) AddFlags(fs *pflag.FlagSet) {
|
|||||||
fs.DurationVar(&s.LaunchGracePeriod, "mesos-launch-grace-period", s.LaunchGracePeriod, "Launch grace period after which launching tasks will be cancelled. Zero disables launch cancellation.")
|
fs.DurationVar(&s.LaunchGracePeriod, "mesos-launch-grace-period", s.LaunchGracePeriod, "Launch grace period after which launching tasks will be cancelled. Zero disables launch cancellation.")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run runs the specified KubeletExecutorServer.
|
func (s *KubeletExecutorServer) runExecutor(execUpdates chan<- kubetypes.PodUpdate, kubeletFinished <-chan struct{}, staticPodsConfigPath string) error {
|
||||||
func (s *KubeletExecutorServer) Run(hks hyperkube.Interface, _ []string) error {
|
|
||||||
rand.Seed(time.Now().UTC().UnixNano())
|
|
||||||
|
|
||||||
oomAdjuster := oom.NewOOMAdjuster()
|
|
||||||
if err := oomAdjuster.ApplyOOMScoreAdj(0, s.OOMScoreAdj); err != nil {
|
|
||||||
log.Info(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// empty string for the docker and system containers (= cgroup paths). This
|
|
||||||
// stops the kubelet taking any control over other system processes.
|
|
||||||
s.SystemContainer = ""
|
|
||||||
s.DockerDaemonContainer = ""
|
|
||||||
|
|
||||||
// create static pods directory
|
|
||||||
staticPodsConfigPath := filepath.Join(s.RootDirectory, "static-pods")
|
|
||||||
err := os.Mkdir(staticPodsConfigPath, 0755)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// create apiserver client
|
// create apiserver client
|
||||||
var apiclient *client.Client
|
var apiclient *client.Client
|
||||||
clientConfig, err := s.CreateAPIServerClientConfig()
|
clientConfig, err := s.CreateAPIServerClientConfig()
|
||||||
@ -119,6 +102,89 @@ func (s *KubeletExecutorServer) Run(hks hyperkube.Interface, _ []string) error {
|
|||||||
// back to the apiserver
|
// back to the apiserver
|
||||||
log.Fatalf("No API client: %v", err)
|
log.Fatalf("No API client: %v", err)
|
||||||
}
|
}
|
||||||
|
exec := executor.New(executor.Config{
|
||||||
|
Updates: execUpdates,
|
||||||
|
APIClient: apiclient,
|
||||||
|
Docker: dockertools.ConnectToDockerOrDie(s.DockerEndpoint),
|
||||||
|
SuicideTimeout: s.SuicideTimeout,
|
||||||
|
KubeletFinished: kubeletFinished,
|
||||||
|
ExitFunc: os.Exit,
|
||||||
|
PodStatusFunc: func(pod *api.Pod) (*api.PodStatus, error) {
|
||||||
|
s.kletLock.Lock()
|
||||||
|
defer s.kletLock.Unlock()
|
||||||
|
|
||||||
|
if s.klet == nil {
|
||||||
|
return nil, fmt.Errorf("PodStatucFunc called before kubelet is initialized")
|
||||||
|
}
|
||||||
|
|
||||||
|
status, err := s.klet.GetRuntime().GetPodStatus(pod)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
status.Phase = kubelet.GetPhase(&pod.Spec, status.ContainerStatuses)
|
||||||
|
hostIP, err := s.klet.GetHostIP()
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("Cannot get host IP: %v", err)
|
||||||
|
} else {
|
||||||
|
status.HostIP = hostIP.String()
|
||||||
|
}
|
||||||
|
return status, nil
|
||||||
|
},
|
||||||
|
StaticPodsConfigPath: staticPodsConfigPath,
|
||||||
|
PodLW: cache.NewListWatchFromClient(apiclient, "pods", api.NamespaceAll,
|
||||||
|
fields.OneTermEqualSelector(client.PodHost, s.HostnameOverride),
|
||||||
|
),
|
||||||
|
})
|
||||||
|
|
||||||
|
// initialize driver and initialize the executor with it
|
||||||
|
dconfig := bindings.DriverConfig{
|
||||||
|
Executor: exec,
|
||||||
|
HostnameOverride: s.HostnameOverride,
|
||||||
|
BindingAddress: s.Address,
|
||||||
|
}
|
||||||
|
driver, err := bindings.NewMesosExecutorDriver(dconfig)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to create executor driver: %v", err)
|
||||||
|
}
|
||||||
|
log.V(2).Infof("Initialize executor driver...")
|
||||||
|
exec.Init(driver)
|
||||||
|
|
||||||
|
// start the driver
|
||||||
|
go func() {
|
||||||
|
if _, err := driver.Run(); err != nil {
|
||||||
|
log.Fatalf("executor driver failed: %v", err)
|
||||||
|
}
|
||||||
|
log.Info("executor Run completed")
|
||||||
|
}()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run runs the specified KubeletExecutorServer.
|
||||||
|
func (s *KubeletExecutorServer) runKubelet(execUpdates <-chan kubetypes.PodUpdate, kubeletFinished chan<- struct{}, staticPodsConfigPath string) error {
|
||||||
|
// empty string for the docker and system containers (= cgroup paths). This
|
||||||
|
// stops the kubelet taking any control over other system processes.
|
||||||
|
s.SystemContainer = ""
|
||||||
|
s.DockerDaemonContainer = ""
|
||||||
|
|
||||||
|
oomAdjuster := oom.NewOOMAdjuster()
|
||||||
|
if err := oomAdjuster.ApplyOOMScoreAdj(0, s.OOMScoreAdj); err != nil {
|
||||||
|
log.Info(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
dockerClient := dockertools.ConnectToDockerOrDie(s.DockerEndpoint)
|
||||||
|
|
||||||
|
// create apiserver client
|
||||||
|
var apiclient *client.Client
|
||||||
|
clientConfig, err := s.CreateAPIServerClientConfig()
|
||||||
|
if err == nil {
|
||||||
|
apiclient, err = client.New(clientConfig)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
// required for k8sm since we need to send api.Binding information back to the apiserver
|
||||||
|
log.Fatalf("No API client: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
log.Infof("Using root directory: %v", s.RootDirectory)
|
log.Infof("Using root directory: %v", s.RootDirectory)
|
||||||
credentialprovider.SetPreferredDockercfgPath(s.RootDirectory)
|
credentialprovider.SetPreferredDockercfgPath(s.RootDirectory)
|
||||||
@ -138,6 +204,15 @@ func (s *KubeletExecutorServer) Run(hks hyperkube.Interface, _ []string) error {
|
|||||||
RootFreeDiskMB: s.LowDiskSpaceThresholdMB,
|
RootFreeDiskMB: s.LowDiskSpaceThresholdMB,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
manifestURLHeader := make(http.Header)
|
||||||
|
if s.ManifestURLHeader != "" {
|
||||||
|
pieces := strings.Split(s.ManifestURLHeader, ":")
|
||||||
|
if len(pieces) != 2 {
|
||||||
|
return fmt.Errorf("manifest-url-header must have a single ':' key-value separator, got %q", s.ManifestURLHeader)
|
||||||
|
}
|
||||||
|
manifestURLHeader.Set(pieces[0], pieces[1])
|
||||||
|
}
|
||||||
|
|
||||||
//TODO(jdef) intentionally NOT initializing a cloud provider here since:
|
//TODO(jdef) intentionally NOT initializing a cloud provider here since:
|
||||||
//(a) the kubelet doesn't actually use it
|
//(a) the kubelet doesn't actually use it
|
||||||
//(b) we don't need to create N-kubelet connections to zookeeper for no good reason
|
//(b) we don't need to create N-kubelet connections to zookeeper for no good reason
|
||||||
@ -181,75 +256,6 @@ func (s *KubeletExecutorServer) Run(hks hyperkube.Interface, _ []string) error {
|
|||||||
log.Warningf("Unknown Docker exec handler %q; defaulting to native", s.DockerExecHandlerName)
|
log.Warningf("Unknown Docker exec handler %q; defaulting to native", s.DockerExecHandlerName)
|
||||||
dockerExecHandler = &dockertools.NativeExecHandler{}
|
dockerExecHandler = &dockertools.NativeExecHandler{}
|
||||||
}
|
}
|
||||||
dockerClient := dockertools.ConnectToDockerOrDie(s.DockerEndpoint)
|
|
||||||
|
|
||||||
//TODO(jdef) either configure Watch here with something useful, or else
|
|
||||||
// get rid of it from executor.Config
|
|
||||||
kubeletFinished := make(chan struct{})
|
|
||||||
execUpdates := make(chan kubetypes.PodUpdate, 1)
|
|
||||||
exec := executor.New(executor.Config{
|
|
||||||
Updates: execUpdates,
|
|
||||||
APIClient: apiclient,
|
|
||||||
Docker: dockerClient,
|
|
||||||
SuicideTimeout: s.SuicideTimeout,
|
|
||||||
KubeletFinished: kubeletFinished,
|
|
||||||
ExitFunc: os.Exit,
|
|
||||||
PodStatusFunc: func(pod *api.Pod) (*api.PodStatus, error) {
|
|
||||||
s.kletLock.Lock()
|
|
||||||
defer s.kletLock.Unlock()
|
|
||||||
|
|
||||||
if s.klet == nil {
|
|
||||||
return nil, fmt.Errorf("PodStatucFunc called before kubelet is initialized")
|
|
||||||
}
|
|
||||||
|
|
||||||
status, err := s.klet.GetRuntime().GetPodStatus(pod)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
status.Phase = kubelet.GetPhase(&pod.Spec, status.ContainerStatuses)
|
|
||||||
hostIP, err := s.klet.GetHostIP()
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("Cannot get host IP: %v", err)
|
|
||||||
} else {
|
|
||||||
status.HostIP = hostIP.String()
|
|
||||||
}
|
|
||||||
return status, nil
|
|
||||||
},
|
|
||||||
StaticPodsConfigPath: staticPodsConfigPath,
|
|
||||||
})
|
|
||||||
|
|
||||||
manifestURLHeader := make(http.Header)
|
|
||||||
if s.ManifestURLHeader != "" {
|
|
||||||
pieces := strings.Split(s.ManifestURLHeader, ":")
|
|
||||||
if len(pieces) != 2 {
|
|
||||||
return fmt.Errorf("manifest-url-header must have a single ':' key-value separator, got %q", s.ManifestURLHeader)
|
|
||||||
}
|
|
||||||
manifestURLHeader.Set(pieces[0], pieces[1])
|
|
||||||
}
|
|
||||||
|
|
||||||
// initialize driver and initialize the executor with it
|
|
||||||
dconfig := bindings.DriverConfig{
|
|
||||||
Executor: exec,
|
|
||||||
HostnameOverride: s.HostnameOverride,
|
|
||||||
BindingAddress: s.Address,
|
|
||||||
}
|
|
||||||
driver, err := bindings.NewMesosExecutorDriver(dconfig)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("failed to create executor driver: %v", err)
|
|
||||||
}
|
|
||||||
log.V(2).Infof("Initialize executor driver...")
|
|
||||||
exec.Init(driver)
|
|
||||||
|
|
||||||
// start the driver
|
|
||||||
go func() {
|
|
||||||
if _, err := driver.Run(); err != nil {
|
|
||||||
log.Fatalf("executor driver failed: %v", err)
|
|
||||||
}
|
|
||||||
log.Info("executor Run completed")
|
|
||||||
}()
|
|
||||||
|
|
||||||
<-exec.InitiallyRegistered()
|
|
||||||
|
|
||||||
// prepare kubelet
|
// prepare kubelet
|
||||||
kcfg := app.KubeletConfig{
|
kcfg := app.KubeletConfig{
|
||||||
@ -335,6 +341,37 @@ func (s *KubeletExecutorServer) Run(hks hyperkube.Interface, _ []string) error {
|
|||||||
}, 5*time.Second, util.NeverStop)
|
}, 5*time.Second, util.NeverStop)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run runs the specified KubeletExecutorServer.
|
||||||
|
func (s *KubeletExecutorServer) Run(hks hyperkube.Interface, _ []string) error {
|
||||||
|
rand.Seed(time.Now().UTC().UnixNano())
|
||||||
|
|
||||||
|
// create shared channels
|
||||||
|
kubeletFinished := make(chan struct{})
|
||||||
|
execUpdates := make(chan kubetypes.PodUpdate, 1)
|
||||||
|
|
||||||
|
// create static pods directory
|
||||||
|
staticPodsConfigPath := filepath.Join(s.RootDirectory, "static-pods")
|
||||||
|
err := os.Mkdir(staticPodsConfigPath, 0755)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// start executor
|
||||||
|
err = s.runExecutor(execUpdates, kubeletFinished, staticPodsConfigPath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// start kubelet
|
||||||
|
err = s.runKubelet(execUpdates, kubeletFinished, staticPodsConfigPath)
|
||||||
|
if err != nil {
|
||||||
|
close(kubeletFinished) // tell executor
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// block until executor is shut down or commits shutdown
|
// block until executor is shut down or commits shutdown
|
||||||
select {}
|
select {}
|
||||||
}
|
}
|
||||||
@ -531,3 +568,4 @@ func (kl *kubeletExecutor) Run(mergedUpdates <-chan kubetypes.PodUpdate) {
|
|||||||
// Force kubelet to delete all pods.
|
// Force kubelet to delete all pods.
|
||||||
kl.HandlePodDeletions(kl.GetPods())
|
kl.HandlePodDeletions(kl.GetPods())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user