mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-29 22:46:12 +00:00
Merge pull request #5619 from vmarmol/rate
Spread out pod status updates to apiserver.
This commit is contained in:
commit
52e1ee9d5b
@ -51,6 +51,7 @@ type KubeletServer struct {
|
|||||||
FileCheckFrequency time.Duration
|
FileCheckFrequency time.Duration
|
||||||
HTTPCheckFrequency time.Duration
|
HTTPCheckFrequency time.Duration
|
||||||
StatusUpdateFrequency time.Duration
|
StatusUpdateFrequency time.Duration
|
||||||
|
PodStatusUpdateFrequency time.Duration
|
||||||
ManifestURL string
|
ManifestURL string
|
||||||
EnableServer bool
|
EnableServer bool
|
||||||
Address util.IP
|
Address util.IP
|
||||||
@ -83,13 +84,14 @@ type KubeletServer struct {
|
|||||||
// NewKubeletServer will create a new KubeletServer with default values.
|
// NewKubeletServer will create a new KubeletServer with default values.
|
||||||
func NewKubeletServer() *KubeletServer {
|
func NewKubeletServer() *KubeletServer {
|
||||||
return &KubeletServer{
|
return &KubeletServer{
|
||||||
SyncFrequency: 10 * time.Second,
|
SyncFrequency: 10 * time.Second,
|
||||||
FileCheckFrequency: 20 * time.Second,
|
FileCheckFrequency: 20 * time.Second,
|
||||||
HTTPCheckFrequency: 20 * time.Second,
|
HTTPCheckFrequency: 20 * time.Second,
|
||||||
StatusUpdateFrequency: 20 * time.Second,
|
StatusUpdateFrequency: 20 * time.Second,
|
||||||
EnableServer: true,
|
PodStatusUpdateFrequency: 2 * time.Minute,
|
||||||
Address: util.IP(net.ParseIP("127.0.0.1")),
|
EnableServer: true,
|
||||||
Port: ports.KubeletPort,
|
Address: util.IP(net.ParseIP("127.0.0.1")),
|
||||||
|
Port: ports.KubeletPort,
|
||||||
PodInfraContainerImage: kubelet.PodInfraContainerImage,
|
PodInfraContainerImage: kubelet.PodInfraContainerImage,
|
||||||
RootDirectory: defaultRootDir,
|
RootDirectory: defaultRootDir,
|
||||||
RegistryBurst: 10,
|
RegistryBurst: 10,
|
||||||
@ -110,6 +112,7 @@ func (s *KubeletServer) AddFlags(fs *pflag.FlagSet) {
|
|||||||
fs.StringVar(&s.Config, "config", s.Config, "Path to the config file or directory of files")
|
fs.StringVar(&s.Config, "config", s.Config, "Path to the config file or directory of files")
|
||||||
fs.DurationVar(&s.SyncFrequency, "sync_frequency", s.SyncFrequency, "Max period between synchronizing running containers and config")
|
fs.DurationVar(&s.SyncFrequency, "sync_frequency", s.SyncFrequency, "Max period between synchronizing running containers and config")
|
||||||
fs.DurationVar(&s.StatusUpdateFrequency, "status_update_frequency", s.StatusUpdateFrequency, "Duration between posting node status to master")
|
fs.DurationVar(&s.StatusUpdateFrequency, "status_update_frequency", s.StatusUpdateFrequency, "Duration between posting node status to master")
|
||||||
|
fs.DurationVar(&s.PodStatusUpdateFrequency, "pod_status_update_frequency", s.PodStatusUpdateFrequency, "Duration between posting pod status updates to the master")
|
||||||
fs.DurationVar(&s.FileCheckFrequency, "file_check_frequency", s.FileCheckFrequency, "Duration between checking config files for new data")
|
fs.DurationVar(&s.FileCheckFrequency, "file_check_frequency", s.FileCheckFrequency, "Duration between checking config files for new data")
|
||||||
fs.DurationVar(&s.HTTPCheckFrequency, "http_check_frequency", s.HTTPCheckFrequency, "Duration between checking http for new data")
|
fs.DurationVar(&s.HTTPCheckFrequency, "http_check_frequency", s.HTTPCheckFrequency, "Duration between checking http for new data")
|
||||||
fs.StringVar(&s.ManifestURL, "manifest_url", s.ManifestURL, "URL for accessing the container manifest")
|
fs.StringVar(&s.ManifestURL, "manifest_url", s.ManifestURL, "URL for accessing the container manifest")
|
||||||
@ -176,6 +179,7 @@ func (s *KubeletServer) Run(_ []string) error {
|
|||||||
ConfigFile: s.Config,
|
ConfigFile: s.Config,
|
||||||
ManifestURL: s.ManifestURL,
|
ManifestURL: s.ManifestURL,
|
||||||
StatusUpdateFrequency: s.StatusUpdateFrequency,
|
StatusUpdateFrequency: s.StatusUpdateFrequency,
|
||||||
|
PodStatusUpdateFrequency: s.PodStatusUpdateFrequency,
|
||||||
FileCheckFrequency: s.FileCheckFrequency,
|
FileCheckFrequency: s.FileCheckFrequency,
|
||||||
HTTPCheckFrequency: s.HTTPCheckFrequency,
|
HTTPCheckFrequency: s.HTTPCheckFrequency,
|
||||||
PodInfraContainerImage: s.PodInfraContainerImage,
|
PodInfraContainerImage: s.PodInfraContainerImage,
|
||||||
@ -273,21 +277,22 @@ func SimpleRunKubelet(client *client.Client,
|
|||||||
RootDirectory: rootDir,
|
RootDirectory: rootDir,
|
||||||
ManifestURL: manifestURL,
|
ManifestURL: manifestURL,
|
||||||
PodInfraContainerImage: kubelet.PodInfraContainerImage,
|
PodInfraContainerImage: kubelet.PodInfraContainerImage,
|
||||||
Port: port,
|
Port: port,
|
||||||
Address: util.IP(net.ParseIP(address)),
|
Address: util.IP(net.ParseIP(address)),
|
||||||
EnableServer: true,
|
EnableServer: true,
|
||||||
EnableDebuggingHandlers: true,
|
EnableDebuggingHandlers: true,
|
||||||
StatusUpdateFrequency: 3 * time.Second,
|
StatusUpdateFrequency: 3 * time.Second,
|
||||||
SyncFrequency: 3 * time.Second,
|
PodStatusUpdateFrequency: 2 * time.Minute,
|
||||||
MinimumGCAge: 10 * time.Second,
|
SyncFrequency: 3 * time.Second,
|
||||||
MaxPerPodContainerCount: 5,
|
MinimumGCAge: 10 * time.Second,
|
||||||
MaxContainerCount: 100,
|
MaxPerPodContainerCount: 5,
|
||||||
MasterServiceNamespace: masterServiceNamespace,
|
MaxContainerCount: 100,
|
||||||
VolumePlugins: volumePlugins,
|
MasterServiceNamespace: masterServiceNamespace,
|
||||||
TLSOptions: tlsOptions,
|
VolumePlugins: volumePlugins,
|
||||||
CadvisorInterface: cadvisorInterface,
|
TLSOptions: tlsOptions,
|
||||||
ConfigFile: configFilePath,
|
CadvisorInterface: cadvisorInterface,
|
||||||
ImageGCPolicy: imageGCPolicy,
|
ConfigFile: configFilePath,
|
||||||
|
ImageGCPolicy: imageGCPolicy,
|
||||||
}
|
}
|
||||||
RunKubelet(&kcfg)
|
RunKubelet(&kcfg)
|
||||||
}
|
}
|
||||||
@ -373,6 +378,7 @@ type KubeletConfig struct {
|
|||||||
ConfigFile string
|
ConfigFile string
|
||||||
ManifestURL string
|
ManifestURL string
|
||||||
StatusUpdateFrequency time.Duration
|
StatusUpdateFrequency time.Duration
|
||||||
|
PodStatusUpdateFrequency time.Duration
|
||||||
FileCheckFrequency time.Duration
|
FileCheckFrequency time.Duration
|
||||||
HTTPCheckFrequency time.Duration
|
HTTPCheckFrequency time.Duration
|
||||||
Hostname string
|
Hostname string
|
||||||
@ -435,6 +441,7 @@ func createAndInitKubelet(kc *KubeletConfig, pc *config.PodConfig) (*kubelet.Kub
|
|||||||
kc.Recorder,
|
kc.Recorder,
|
||||||
kc.CadvisorInterface,
|
kc.CadvisorInterface,
|
||||||
kc.StatusUpdateFrequency,
|
kc.StatusUpdateFrequency,
|
||||||
|
kc.PodStatusUpdateFrequency,
|
||||||
kc.ImageGCPolicy)
|
kc.ImageGCPolicy)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -122,6 +122,7 @@ func NewMainKubelet(
|
|||||||
recorder record.EventRecorder,
|
recorder record.EventRecorder,
|
||||||
cadvisorInterface cadvisor.Interface,
|
cadvisorInterface cadvisor.Interface,
|
||||||
statusUpdateFrequency time.Duration,
|
statusUpdateFrequency time.Duration,
|
||||||
|
podStatusUpdateFrequency time.Duration,
|
||||||
imageGCPolicy ImageGCPolicy) (*Kubelet, error) {
|
imageGCPolicy ImageGCPolicy) (*Kubelet, error) {
|
||||||
if rootDirectory == "" {
|
if rootDirectory == "" {
|
||||||
return nil, fmt.Errorf("invalid root directory %q", rootDirectory)
|
return nil, fmt.Errorf("invalid root directory %q", rootDirectory)
|
||||||
@ -129,6 +130,9 @@ func NewMainKubelet(
|
|||||||
if resyncInterval <= 0 {
|
if resyncInterval <= 0 {
|
||||||
return nil, fmt.Errorf("invalid sync frequency %d", resyncInterval)
|
return nil, fmt.Errorf("invalid sync frequency %d", resyncInterval)
|
||||||
}
|
}
|
||||||
|
if podStatusUpdateFrequency <= 0 {
|
||||||
|
return nil, fmt.Errorf("invalid status update frequency %d", podStatusUpdateFrequency)
|
||||||
|
}
|
||||||
dockerClient = metrics.NewInstrumentedDockerInterface(dockerClient)
|
dockerClient = metrics.NewInstrumentedDockerInterface(dockerClient)
|
||||||
|
|
||||||
// Wait for the Docker daemon to be up (with a timeout).
|
// Wait for the Docker daemon to be up (with a timeout).
|
||||||
@ -179,6 +183,7 @@ func NewMainKubelet(
|
|||||||
rootDirectory: rootDirectory,
|
rootDirectory: rootDirectory,
|
||||||
statusUpdateFrequency: statusUpdateFrequency,
|
statusUpdateFrequency: statusUpdateFrequency,
|
||||||
resyncInterval: resyncInterval,
|
resyncInterval: resyncInterval,
|
||||||
|
podStatusUpdateFrequency: podStatusUpdateFrequency,
|
||||||
podInfraContainerImage: podInfraContainerImage,
|
podInfraContainerImage: podInfraContainerImage,
|
||||||
containerIDToRef: map[string]*api.ObjectReference{},
|
containerIDToRef: map[string]*api.ObjectReference{},
|
||||||
runner: dockertools.NewDockerContainerCommandRunner(dockerClient),
|
runner: dockertools.NewDockerContainerCommandRunner(dockerClient),
|
||||||
@ -232,16 +237,17 @@ type serviceLister interface {
|
|||||||
|
|
||||||
// Kubelet is the main kubelet implementation.
|
// Kubelet is the main kubelet implementation.
|
||||||
type Kubelet struct {
|
type Kubelet struct {
|
||||||
hostname string
|
hostname string
|
||||||
dockerClient dockertools.DockerInterface
|
dockerClient dockertools.DockerInterface
|
||||||
dockerCache dockertools.DockerCache
|
dockerCache dockertools.DockerCache
|
||||||
kubeClient client.Interface
|
kubeClient client.Interface
|
||||||
rootDirectory string
|
rootDirectory string
|
||||||
podInfraContainerImage string
|
podInfraContainerImage string
|
||||||
podWorkers *podWorkers
|
podWorkers *podWorkers
|
||||||
statusUpdateFrequency time.Duration
|
statusUpdateFrequency time.Duration
|
||||||
resyncInterval time.Duration
|
resyncInterval time.Duration
|
||||||
sourcesReady SourcesReadyFn
|
podStatusUpdateFrequency time.Duration
|
||||||
|
sourcesReady SourcesReadyFn
|
||||||
|
|
||||||
// Protects the pods array
|
// Protects the pods array
|
||||||
// We make complete array copies out of this while locked, which is OK because once added to this array,
|
// We make complete array copies out of this while locked, which is OK because once added to this array,
|
||||||
@ -507,7 +513,11 @@ func (kl *Kubelet) Run(updates <-chan PodUpdate) {
|
|||||||
glog.Warning("No api server defined - no node status update will be sent.")
|
glog.Warning("No api server defined - no node status update will be sent.")
|
||||||
}
|
}
|
||||||
go kl.syncNodeStatus()
|
go kl.syncNodeStatus()
|
||||||
go util.Forever(kl.syncStatus, kl.resyncInterval)
|
|
||||||
|
// syncStatus handles its own frequency and throttling, run it always.
|
||||||
|
go util.Forever(func() {
|
||||||
|
kl.syncStatus(kl.podStatusUpdateFrequency)
|
||||||
|
}, 0)
|
||||||
kl.syncLoop(updates, kl)
|
kl.syncLoop(updates, kl)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1673,12 +1683,25 @@ func (kl *Kubelet) syncLoop(updates <-chan PodUpdate, handler SyncHandler) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// syncStatus syncs pods statuses with the apiserver.
|
// syncStatus syncs pods statuses with the apiserver. Spread the updates over the specified deadline.
|
||||||
func (kl *Kubelet) syncStatus() {
|
func (kl *Kubelet) syncStatus(deadline time.Duration) {
|
||||||
|
start := time.Now()
|
||||||
glog.V(3).Infof("Syncing pods status")
|
glog.V(3).Infof("Syncing pods status")
|
||||||
|
|
||||||
pods, _ := kl.GetPods()
|
pods, _ := kl.GetPods()
|
||||||
|
if len(pods) == 0 {
|
||||||
|
// No pods, sleep the rest of our deadline.
|
||||||
|
time.Sleep(deadline - time.Since(start))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(vmarmol): Enhance util.RateLimiter for our use here.
|
||||||
|
singleDeadline := time.Duration(deadline.Nanoseconds() / int64(len(pods)))
|
||||||
|
t := time.NewTicker(singleDeadline)
|
||||||
for _, pod := range pods {
|
for _, pod := range pods {
|
||||||
|
// Don't hit the api server too hard, wait for the next time slot.
|
||||||
|
<-t.C
|
||||||
|
|
||||||
status, err := kl.GetPodStatus(GetPodFullName(&pod), pod.UID)
|
status, err := kl.GetPodStatus(GetPodFullName(&pod), pod.UID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Warningf("Error getting pod %q status: %v, retry later", pod.Name, err)
|
glog.Warningf("Error getting pod %q status: %v, retry later", pod.Name, err)
|
||||||
@ -1691,6 +1714,7 @@ func (kl *Kubelet) syncStatus() {
|
|||||||
glog.V(3).Infof("Status for pod %q updated successfully: %s", pod.Name, pod)
|
glog.V(3).Infof("Status for pod %q updated successfully: %s", pod.Name, pod)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
t.Stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the Kubelet's internal pods with those provided by the update.
|
// Update the Kubelet's internal pods with those provided by the update.
|
||||||
|
Loading…
Reference in New Issue
Block a user