kubelet 源码分析(一)
概述
k8s版本: 1.13.10
代码路径: https://github.com/kubernetes/kubernetes/tree/v1.12.0/cmd/kubelet
代码走读的路线是:从kubernetes/cmd/kubelet开始,这里包括了kubelet的参数解析、初始化、依赖组件等,然后到达kubernetes/pkg/kubelet模块,开始kubelet的核心逻辑
本文主要看入口方法和pod的新建逻辑。
cmd入口
cmd 文件夹是kubelet启动的入口,包括了启动参数的解析等,代码目录结构如下:
kubernetes/cmd/kubelet:
.
├── BUILD
├── OWNERS
├── app
│ ├── BUILD
│ ├── OWNERS
│ ├── auth.go
│ ├── init_others.go
│ ├── init_windows.go
│ ├── options # 包括kubelet使用到的option
│ │ ├── BUILD
│ │ ├── container_runtime.go
│ │ ├── globalflags.go
│ │ ├── globalflags_linux.go
│ │ ├── globalflags_other.go
│ │ ├── options.go # 包括KubeletFlags、AddFlags、AddKubeletConfigFlags等
│ │ ├── options_test.go
│ │ ├── osflags_others.go
│ │ └── osflags_windows.go
│ ├── plugins.go
│ ├── server.go # 包括NewKubeletCommand、Run、RunKubelet、CreateAndInitKubelet、startKubelet等
│ ├── server_linux.go
│ ├── server_test.go
│ └── server_unsupported.go
└── kubelet.go # kubelet的main入口函数
在 kubelet.go 文件的注释中就解释了 kubelet 的作用:
kubelet二进制文件负责维护特定主机VM上的一组容器,它同步来自配置文件和etcd的数据,然后它查询Docker以查看当前运行的是什么,通过启动或停止Docker容器来运行一组pod,并同步配置数据给 docker。
kubelet.go: main入口函数,使用cobra作为命令行库
func main() {rand.Seed(time.Now().UnixNano())command := app.NewKubeletCommand(server.SetupSignalHandler())logs.InitLogs()defer logs.FlushLogs()if err := command.Execute(); err != nil {fmt.Fprintf(os.Stderr, "%v\n", err)os.Exit(1)}
}
server.go: 做参数初始化和校验,通过对各种特定参数的解析,最终生成kubeletFlags和kubeletConfig两个重要的参数对象,用来构造kubeletServer和其他需求。
// 使用kubeletFlags和kubeletConfig构造KubeletServer对象
kubeletServer := &options.KubeletServer{KubeletFlags: *kubeletFlags,KubeletConfiguration: *kubeletConfig,
}
kubeletFlags和kubeletConfig的含义可以参考[kubelet 先导篇],是 1.10 版本之后 kubelet 对配置的一次重新定义,Flags是机器独占参数,config 是可以共享的参数,可以用于动态更新 kubelet
如果开启了docker shim参数,则执行RunDockershim。
// 如果开启了,就运行docker shim
if kubeletServer.KubeletFlags.ExperimentalDockershim {if err := RunDockershim(&kubeletServer.KubeletFlags, kubeletConfig, stopCh); err != nil {glog.Fatal(err)}return
}
运行kubelet并且不退出。由Run函数进入后续的操作。
glog.V(5).Infof("KubeletConfiguration: %#v", kubeletServer.KubeletConfiguration)
if err := Run(kubeletServer, kubeletDeps, stopCh); err != nil {glog.Fatal(err)
}
Run方法:
func Run(s *options.KubeletServer, kubeDeps *kubelet.Dependencies, stopCh <-chan struct{}) error {glog.Infof("Version: %+v", version.Get())if err := initForOS(s.KubeletFlags.WindowsService); err != nil {return fmt.Errorf("failed OS init: %v", err)}if err := run(s, kubeDeps, stopCh); err != nil {return fmt.Errorf("failed to run Kubelet: %v", err)}return nil
}
构造kubeDeps,包括KubeClient,CSIClient,CAdvisor等,初始化后,被 kubelet 的 server 使用
return &kubelet.Dependencies{Auth: nil, // default does not enforce auth[nz]CAdvisorInterface: nil, // cadvisor.New launches background processes (bg http.ListenAndServe, and some bg cleaners), not set hereCloud: nil, // cloud provider might start background processesContainerManager: nil,DockerClientConfig: dockerClientConfig,KubeClient: nil,HeartbeatClient: nil,CSIClient: nil,EventClient: nil,Mounter: mounter,OOMAdjuster: oom.NewOOMAdjuster(),OSInterface: kubecontainer.RealOS{},VolumePlugins: ProbeVolumePlugins(),DynamicPluginProber: GetDynamicPluginProber(s.VolumePluginDir, pluginRunner),TLSOptions: tlsOptions}, nil
}
RunKubelet函数核心代码为执行了CreateAndInitKubelet和startKubelet两个函数的操作,以下对这两个函数进行分析。
CreateAndInitKubelet方法:
k, err := CreateAndInitKubelet(&kubeServer.KubeletConfiguration,kubeDeps,&kubeServer.ContainerRuntimeOptions,kubeServer.ContainerRuntime,kubeServer.RuntimeCgroups,kubeServer.HostnameOverride,kubeServer.NodeIP,kubeServer.ProviderID,kubeServer.CloudProvider,kubeServer.CertDirectory,kubeServer.RootDirectory,kubeServer.RegisterNode,kubeServer.RegisterWithTaints,kubeServer.AllowedUnsafeSysctls,kubeServer.RemoteRuntimeEndpoint,kubeServer.RemoteImageEndpoint,kubeServer.ExperimentalMounterPath,kubeServer.ExperimentalKernelMemcgNotification,kubeServer.ExperimentalCheckNodeCapabilitiesBeforeMount,kubeServer.ExperimentalNodeAllocatableIgnoreEvictionThreshold,kubeServer.MinimumGCAge,kubeServer.MaxPerPodContainerCount,kubeServer.MaxContainerCount,kubeServer.MasterServiceNamespace,kubeServer.RegisterSchedulable,kubeServer.NonMasqueradeCIDR,kubeServer.KeepTerminatedPodVolumes,kubeServer.NodeLabels,kubeServer.SeccompProfileRoot,kubeServer.BootstrapCheckpointPath,kubeServer.NodeStatusMaxImages)if err != nil {return fmt.Errorf("failed to create kubelet: %v", err)}
NewMainKubelet–>PodConfig–>NewPodConfig–>kubetypes.PodUpdate。会生成一个podUpdate的channel来监听pod的变化,该channel会在k.Run(podCfg.Updates())中作为关键入参。
if kubeDeps.PodConfig == nil {return fmt.Errorf("failed to create kubelet, pod source config was nil")}podCfg := kubeDeps.PodConfigrlimit.RlimitNumFiles(uint64(kubeServer.MaxOpenFiles))// 如果设置了只运行一次的参数,则执行k.RunOnce,否则执行核心函数startKubelet。具体实现如下:if runOnce {if _, err := k.RunOnce(podCfg.Updates()); err != nil {return fmt.Errorf("runonce failed: %v", err)}klog.Infof("Started kubelet as runonce")else {startKubelet(k, podCfg, &kubeServer.KubeletConfiguration, kubeDeps, kubeServer.EnableServer)klog.Infof("Started kubelet")}
startKubelet方法:
func startKubelet(k kubelet.Bootstrap, podCfg *config.PodConfig, kubeCfg *kubeletconfiginternal.KubeletConfiguration, kubeDeps *kubelet.Dependencies, enableServer bool) {// start the kubeletgo wait.Until(func() {k.Run(podCfg.Updates())}, 0, wait.NeverStop)// start the kubelet serverif enableServer {go k.ListenAndServe(net.ParseIP(kubeCfg.Address), uint(kubeCfg.Port), kubeDeps.TLSOptions, kubeDeps.Auth, kubeCfg.EnableDebuggingHandlers, kubeCfg.EnableContentionProfiling)}if kubeCfg.ReadOnlyPort > 0 {go k.ListenAndServeReadOnly(net.ParseIP(kubeCfg.Address), uint(kubeCfg.ReadOnlyPort))}
}
通过长驻进程的方式运行k.Run,不退出,kubelet.Bootstrap是引入了kubernetes/pkg/kubelet/kubelet.go,将实际运行逻辑转移到了 pkg 目录下。
kubelet 主方法
位于 pkg/kubelet/kubelet.go 文件
Bootstrap定义了kubelet 拥有的方法,被 cmd 层的 server.go调用,ListenAndServe就是其中一个
type Bootstrap interface {GetConfiguration() kubeletconfiginternal.KubeletConfigurationBirthCry()StartGarbageCollection()ListenAndServe(address net.IP, port uint, tlsOptions *server.TLSOptions, auth server.AuthInterface, enableDebuggingHandlers, enableContentionProfiling bool)ListenAndServeReadOnly(address net.IP, port uint)ListenAndServePodResources()Run(<-chan kubetypes.PodUpdate)RunOnce(<-chan kubetypes.PodUpdate) ([]RunPodResult, error)
}
kubelet 初始化了很多manager,用于处理 pod 生命周期中的各种操作,如 oom 判断,secret、configmap 处理、liveness判断等。。
- containerRefManager
- oomWatcher
- klet.secretManager
- klet.configMapManager
- klet.livenessManager
- klet.podManager
- klet.resourceAnalyzer
- imageManager
- klet.statusManager
- klet.volumeManager
- eviction.NewManager
目前pod所使用的runtime只有docker和remote两种,rkt已经废弃。
if containerRuntime == "rkt" {klog.Fatalln("rktnetes has been deprecated in favor of rktlet. Please see https://github.com/kubernetes-incubator/rktlet for more information.")}
当runtime是docker的时候,会执行docker相关操作。
switch containerRuntime {case kubetypes.DockerContainerRuntime:streamingConfig := getStreamingConfig(kubeCfg, kubeDeps, crOptions)ds, err := dockershim.NewDockerService(kubeDeps.DockerClientConfig, crOptions.PodSandboxImage, streamingConfig,&pluginSettings, runtimeCgroups, kubeCfg.CgroupDriver, crOptions.DockershimRootDirectory, !crOptions.RedirectContainerStreaming)if err != nil {return nil, err}if err := server.Start(); err != nil {return nil, err}
...
kubelet 的工作核心就是在围绕着不同的生产者生产出来的不同的有关 pod 的消息来调用相应的消费者(不同的子模块)完成不同的行为(创建和删除 pod 等),即图中的控制循环(SyncLoop),通过不同的事件驱动这个控制循环运行。
pod处理逻辑
调用路径
当一个 pod 完成调度,与一个 node 绑定起来之后,这个 pod 就会触发 kubelet 在循环控制里注册的 handler,上图中的 HandlePods 部分。
此时,通过检查 pod 在 kubelet 内存中的状态,kubelet 就能判断出这是一个新调度过来的 pod,从而触发 Handler 里的 ADD 事件对应的逻辑处理。然后 kubelet 会为这个 pod 生成对应的 podStatus,接着检查 pod 所声明的 volume 是不是准备好了,然后调用下层的容器运行时。如果是 update 事件的话,kubelet 就会根据 pod 对象具体的变更情况,调用下层的容器运行时进行容器的重建。
podWorker主要用来对pod相应事件进行处理和同步,包含以下三个方法:UpdatePod、ForgetNonExistingPodWorkers、ForgetWorker。
type PodWorkers interface {UpdatePod(options *UpdatePodOptions)ForgetNonExistingPodWorkers(desiredPods map[types.UID]empty)ForgetWorker(uid types.UID)
}
完整调用路径:
main —> NewKubeletCommand —> Run(kubeletServer…) —> run(s, kubeDeps, stopCh) —> RunKubelet(s, kubeDeps, s.RunOnce) —> startKubelet —> k.Run(podCfg.Updates()) / k.ListenAndServe —> (kl *Kubelet) Run —> kl.pleg.Start() / kl.syncLoop(updates, kl) —> syncLoopIteration
kubelet的控制循环syncLoop
syncLoop对pod的生命周期进行管理,其中syncLoop调用了syncLoopIteration函数,该函数根据podUpdate的信息,针对不同的操作,由SyncHandler来执行pod的增删改查等生命周期的管理,其中的syncHandler包括HandlePodSyncs和HandlePodCleanups等。
即使没有需要更新的 pod 配置,kubelet 也会定时去做同步和清理 pod 的工作。然后在 for 循环中一直调用 syncLoopIteration,如果在每次循环过程中出现比较严重的错误,kubelet 会记录到 runtimeState 中,遇到错误就等待 5 秒中继续循环。
syncLoopIteration实际执行了pod的操作,此部分设置了几种不同的channel:
- configCh:该信息源由 kubeDeps 对象中的 PodConfig 子模块提供,该模块将同时 watch 3 个不同来源的 pod 信息的变化(file,http,apiserver),一旦某个来源的 pod 信息发生了更新(创建/更新/删除),这个 channel 中就会出现被更新的 pod 信息和更新的具体操作。
- syncCh:定时器管道,每隔一秒去同步最新保存的 pod 状态
- houseKeepingCh:housekeeping 事件的管道,做 pod 清理工作
- plegCh:该信息源由 kubelet 对象中的 pleg 子模块提供,该模块主要用于周期性地向 container runtime 查询当前所有容器的状态,如果状态发生变化,则这个 channel 产生事件。
- livenessManager.Updates():健康检查发现某个 pod 不可用,kubelet 将根据 Pod 的restartPolicy 自动执行正确的操作
syncLoopIteration方法内容如下:
func (kl *Kubelet) syncLoopIteration(configCh <-chan kubetypes.PodUpdate, handler SyncHandler,
syncCh <-chan time.Time, housekeepingCh <-chan time.Time, plegCh <-chan *pleg.PodLifecycleEvent) bool {
select {
case u, open := <-configCh:if !open {glog.Errorf("Update channel is closed. Exiting the sync loop.")return false}switch u.Op {case kubetypes.ADD:...case kubetypes.UPDATE:...case kubetypes.REMOVE:...case kubetypes.RECONCILE:...case kubetypes.DELETE:...case kubetypes.RESTORE:...case kubetypes.SET:...}...
case e := <-plegCh:...
case <-syncCh:...
case update := <-kl.livenessManager.Updates():...
case <-housekeepingCh:...
}
return true
}
pod新增:HandlePodAdditions
- 先根据pod创建时间对pod进行排序,然后遍历pod列表,来执行pod的相关操作。
func (kl *Kubelet) HandlePodAdditions(pods []*v1.Pod) {start := kl.clock.Now()sort.Sort(sliceutils.PodsByCreationTime(pods))for _, pod := range pods {...}
}
- 将pod添加到pod manager中
for _, pod := range pods {// Responsible for checking limits in resolv.confif kl.dnsConfigurer != nil && kl.dnsConfigurer.ResolverConfig != "" {kl.dnsConfigurer.CheckLimitsForResolvConf()}existingPods := kl.podManager.GetPods()// Always add the pod to the pod manager. Kubelet relies on the pod// manager as the source of truth for the desired state. If a pod does// not exist in the pod manager, it means that it has been deleted in// the apiserver and no action (other than cleanup) is required.kl.podManager.AddPod(pod)...
}
- 如果是mirror pod,则对mirror pod进行处理。
if kubepod.IsMirrorPod(pod) {kl.handleMirrorPod(pod, start)continue
}
- 如果当前pod的状态不是Terminated状态,则判断是否接受该pod,如果不接受则将pod状态改为Failed。
if !kl.podIsTerminated(pod) {// Only go through the admission process if the pod is not// terminated.// We failed pods that we rejected, so activePods include all admitted// pods that are alive.activePods := kl.filterOutTerminatedPods(existingPods)// Check if we can admit the pod; if not, reject it.if ok, reason, message := kl.canAdmitPod(activePods, pod); !ok {kl.rejectPod(pod, reason, message)continue}
}
- 执行dispatchWork函数,该函数是syncHandler中调用到的核心函数,该函数在pod worker中启动一个异步循环,来分派pod的相关操作
mirrorPod, _ := kl.podManager.GetMirrorPodByPod(pod)
kl.dispatchWork(pod, kubetypes.SyncPodCreate, mirrorPod, start)
- 最后,在 probeManager 中添加 pod,如果 pod 中定义了 readiness 和 liveness 健康检查,启动 goroutine 定期进行检测
kl.probeManager.AddPod(pod)
pod的清理任务HandlePodCleanups
其中包括terminating的pod,orphaned的pod等。
func (kl *Kubelet) HandlePodCleanups() error {var (cgroupPods map[types.UID]cm.CgroupNameerr error)if kl.cgroupsPerQOS {pcm := kl.containerManager.NewPodContainerManager()cgroupPods, err = pcm.GetAllPodsFromCgroups()if err != nil {return fmt.Errorf("failed to get list of pods that still exist on cgroup mounts: %v", err)}}...
}
- 列出所有pod包括mirror pod。
activePods := kl.filterOutTerminatedPods(allPods)desiredPods := make(map[types.UID]empty)
for _, pod := range activePods {desiredPods[pod.UID] = empty{}
}
- pod worker停止不再存在的pod的任务,并从probe manager中清除pod。
kl.podWorkers.ForgetNonExistingPodWorkers(desiredPods)
kl.probeManager.CleanupPods(activePods)
- 将需要杀死的pod加入到podKillingCh的channel中,podKiller的任务会监听该channel并获取需要杀死的pod列表来执行杀死pod的操作。
runningPods, err := kl.runtimeCache.GetPods()
if err != nil {glog.Errorf("Error listing containers: %#v", err)return err
}
for _, pod := range runningPods {if _, found := desiredPods[pod.ID]; !found {kl.podKillingCh <- &kubecontainer.PodPair{APIPod: nil, RunningPod: pod}}
}
- 当pod不再被绑定到该节点,移除podStatus,其中removeOrphanedPodStatuses最后调用的函数是statusManager的RemoveOrphanedStatuses方法。
kl.removeOrphanedPodStatuses(allPods, mirrorPods)
- 移除所有的orphaned volume。
err = kl.cleanupOrphanedPodDirs(allPods, runningPods)
if err != nil {// We want all cleanup tasks to be run even if one of them failed. So// we just log an error here and continue other cleanup tasks.// This also applies to the other clean up tasks.glog.Errorf("Failed cleaning up orphaned pod directories: %v", err)
}
- 移除mirror pod。
kl.podManager.DeleteOrphanedMirrorPods()
- 删除不再运行的pod的cgroup。
if kl.cgroupsPerQOS {kl.cleanupOrphanedPodCgroups(cgroupPods, activePods)
}
- 执行垃圾回收(GC)操作。
kl.backOff.GC()
syncHandler
- HandlePodAdditions、HandlePodUpdates、HandlePodReconcile、HandlePodSyncs都调用到了dispatchWork来执行pod的相关操作。
- HandlePodCleanups的pod清理任务,通过channel的方式加需要清理的pod给podKiller来清理。
- syncHandler中使用到pod manager、probe manager、pod worker、podKiller来执行相关操作。
- syncHandler中的各种handler是根据podUpdate中不同的操作类型(增删改查等)来执行具体的handler。
syncHandler主要执行以下的工作流:
- 如果是正在创建的pod,则记录pod worker的启动latency。
- 调用generateAPIPodStatus为pod提供v1.PodStatus信息。
- 如果pod是第一次运行,记录pod的启动latency。
- 更新status manager中的pod状态。
- 如果pod不应该被运行则杀死pod。
- 如果pod是一个static pod,并且没有对应的mirror pod,则创建一个mirror pod。
- 如果没有pod的数据目录则给pod创建对应的数据目录。
- 等待volume被attach或mount。
- 获取pod的secret数据。
- 调用container runtime的SyncPod函数,执行相关pod操作。
- 更新pod的ingress和egress的traffic limit。
- 当以上任务流中有任何的error,则return error。在下一次执行syncPod的任务流会被再次执行。对于错误信息会被记录到event中,方便debug。
pod worker中有一个managePodLoop方法,调用了syncPodFn,而syncPodFn实际就是kubelet.SyncPod,也就是 经典的pod 的控制循环
SyncPod
基础概念:
Pod只是一个逻辑概念,他实际操作的还是容器运行时如 docker,然后操作 cgroup、linux namespace。
如上图所示,Pod 里有两个用户容器 A 和 B,还有一个infra container, 它也叫做pause容器,也被称为sandbox,意思是沙箱,这个沙箱为其他容器提供共享的网络和文件挂载资源。当这个容器被创建出来并hold住Network Namespace之后,其他由用户自己定义的容器就可以通过container模式加入到这个容器的Network Namespace中。这也就意味着,对于在一个POD中的容器A和容器B来说,他们拥有相同的IP地址,可以通过localhost进行互相通信。
创建 pod
SyncPod主要执行sync操作使得运行的pod达到期望状态的pod。主要执行以下操作:
- 计算 Pod 中沙盒和容器的变更;
- 强制停止 Pod 对应的沙盒;
- 强制停止所有不应该运行的容器;
- 为 Pod 创建新的沙盒;
- 创建 Pod 规格中指定的初始化容器;
- 依次创建 Pod 规格中指定的常规容器;
概况就是:首先计算 Pod 规格和沙箱的变更,然后停止可能影响这一次创建或者更新的容器,最后依次创建沙盒、初始化容器和常规容器。
如创建 pod 逻辑:
func (m *kubeGenericRuntimeManager) SyncPod(pod *v1.Pod, _ v1.PodStatus, podStatus *kubecontainer.PodStatus, pullSecrets []v1.Secret, backOff *flowcontrol.Backoff) (result kubecontainer.PodSyncResult) {podContainerChanges := m.computePodActions(pod, podStatus)if podContainerChanges.CreateSandbox {ref, _ := ref.GetReference(legacyscheme.Scheme, pod)}if podContainerChanges.KillPod {if podContainerChanges.CreateSandbox {m.purgeInitContainers(pod, podStatus)}} else {for containerID, containerInfo := range podContainerChanges.ContainersToKill {m.killContainer(pod, containerID, containerInfo.name, containerInfo.message, nil) }}}podSandboxID := podContainerChanges.SandboxIDif podContainerChanges.CreateSandbox {podSandboxID, _, _ = m.createPodSandbox(pod, podContainerChanges.Attempt)}podSandboxConfig, _ := m.generatePodSandboxConfig(pod, podContainerChanges.Attempt)if container := podContainerChanges.NextInitContainerToStart; container != nil {msg, _ := m.startContainer(podSandboxID, podSandboxConfig, container, pod, podStatus, pullSecrets, podIP, kubecontainer.ContainerTypeInit)}for _, idx := range podContainerChanges.ContainersToStart {container := &pod.Spec.Containers[idx]msg, _ := m.startContainer(podSandboxID, podSandboxConfig, container, pod, podStatus, pullSecrets, podIP, kubecontainer.ContainerTypeRegular)}return
}
初始化容器和常规容器调用 startContainer 来启动:
func (m *kubeGenericRuntimeManager) startContainer(podSandboxID string, podSandboxConfig *runtimeapi.PodSandboxConfig, container *v1.Container, pod *v1.Pod, podStatus *kubecontainer.PodStatus, pullSecrets []v1.Secret, podIP string, containerType kubecontainer.ContainerType) (string, error) {imageRef, _, _ := m.imagePuller.EnsureImageExists(pod, container, pullSecrets)// ...containerID, _ := m.runtimeService.CreateContainer(podSandboxID, containerConfig, podSandboxConfig)m.internalLifecycle.PreStartContainer(pod, container, containerID)m.runtimeService.StartContainer(containerID)if container.Lifecycle != nil && container.Lifecycle.PostStart != nil {kubeContainerID := kubecontainer.ContainerID{Type: m.runtimeName,ID: containerID,}msg, _ := m.runner.Run(kubeContainerID, pod, container, container.Lifecycle.PostStart)}return "", nil
}
在启动每一个容器的过程中也都按照相同的步骤进行操作:
- 通过镜像拉取器获得当前容器中使用镜像的引用;
- 调用远程的 runtimeService 创建容器;
- 调用内部的生命周期方法 PreStartContainer 为当前的容器设置分配的 CPU 等资源;
- 调用远程的 runtimeService 开始运行镜像;
- 如果当前的容器包含 PostStart 钩子就会执行该回调;
- 每次 SyncPod 被调用时不一定是创建新的 Pod 对象,它还会承担更新、删除和同步 Pod 规格的职能,根据输入的新规格执行相应的操作。
健康检查
pod 创建好之后,如果我们配置了livenessProbe或者readinessProbe,健康检查的 handler 就出场了。
在 Pod 被创建或者被移除时,会被加入到当前节点上的 ProbeManager 中,ProbeManager 会负责这些 Pod 的健康检查,也就是刚刚提到的HandlePodAdditions和HandlePodRemoves方法
func (kl *Kubelet) HandlePodAdditions(pods []*v1.Pod) {start := kl.clock.Now()for _, pod := range pods {kl.podManager.AddPod(pod)kl.dispatchWork(pod, kubetypes.SyncPodCreate, mirrorPod, start)kl.probeManager.AddPod(pod)}
}func (kl *Kubelet) HandlePodRemoves(pods []*v1.Pod) {start := kl.clock.Now()for _, pod := range pods {kl.podManager.DeletePod(pod)kl.deletePod(pod)kl.probeManager.RemovePod(pod)}
}
每一个新的 Pod 都会被调用 ProbeManager 的AddPod 函数,这个方法会初始化一个新的 Goroutine 并在其中运行对当前 Pod 进行健康检查:
func (m *manager) AddPod(pod *v1.Pod) {key := probeKey{podUID: pod.UID}for _, c := range pod.Spec.Containers {key.containerName = c.Nameif c.ReadinessProbe != nil {key.probeType = readinessw := newWorker(m, readiness, pod, c)m.workers[key] = wgo w.run()}if c.LivenessProbe != nil {key.probeType = livenessw := newWorker(m, liveness, pod, c)m.workers[key] = wgo w.run()}}
}
删除 pod
Kubelet 在 HandlePodRemoves 方法处理删除逻辑,最终会通知PodKiller,并调用deletePod方法
func (kl *Kubelet) deletePod(pod *v1.Pod) error {kl.podWorkers.ForgetWorker(pod.UID)runningPods, _ := kl.runtimeCache.GetPods()runningPod := kubecontainer.Pods(runningPods).FindPod("", pod.UID)podPair := kubecontainer.PodPair{APIPod: pod, RunningPod: &runningPod}kl.podKillingCh <- &podPairreturn nil
}
Kubelet 除了将事件通知给 PodKiller 之外,还需要将当前 Pod 对应的 Worker 从持有的 podWorkers 中删除
经过一系列的方法调用之后,最终调用容器运行时的 killContainersWithSyncResult 方法,这个方法会同步地杀掉当前 Pod 中全部的容器:
func (m *kubeGenericRuntimeManager) killContainersWithSyncResult(pod *v1.Pod, runningPod kubecontainer.Pod, gracePeriodOverride *int64) (syncResults []*kubecontainer.SyncResult) {containerResults := make(chan *kubecontainer.SyncResult, len(runningPod.Containers))for _, container := range runningPod.Containers {go func(container *kubecontainer.Container) {killContainerResult := kubecontainer.NewSyncResult(kubecontainer.KillContainer, container.Name)m.killContainer(pod, container.ID, container.Name, "Need to kill Pod", gracePeriodOverride)containerResults <- killContainerResult}(container)}close(containerResults)for containerResult := range containerResults {syncResults = append(syncResults, containerResult)}return
}
对于每一个容器来说,它们在被停止之前都会先调用PreStop
的钩子方法,让容器中的应用程序能够有时间完成一些未处理的操作,随后调用远程的服务停止运行的容器:
func (m *kubeGenericRuntimeManager) killContainer(pod *v1.Pod, containerID kubecontainer.ContainerID, containerName string, reason string, gracePeriodOverride *int64) error {containerSpec := kubecontainer.GetContainerSpec(pod, containerName);gracePeriod := int64(minimumGracePeriodInSeconds)switch {case pod.DeletionGracePeriodSeconds != nil:gracePeriod = *pod.DeletionGracePeriodSecondscase pod.Spec.TerminationGracePeriodSeconds != nil:gracePeriod = *pod.Spec.TerminationGracePeriodSeconds}m.executePreStopHook(pod, containerID, containerSpec, gracePeriodm.internalLifecycle.PreStopContainer(containerID.ID)m.runtimeService.StopContainer(containerID.ID, gracePeriod)m.containerRefManager.ClearRef(containerID)return err
}
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
相关文章
- lambda表达式三级选框组装map
在使用lambda表达式的时候,总是会遇到一些问题,比如,在整理三级联动选框的时候,如何组装map//获取所有的专业技术序列 List<ProfessionalTechnologySeriesExt> baseList = professionalTechnologySeriesService.getAll(); // Map<Integer, String> collect = b…...
2024/5/6 23:06:50 - 表格
关于表格 表格的组成结构: table:整体表格框架 tr:单元行 td(th):单元格 table包含tr,tr包含td合并单元格 合并的本质: 不是侵占,而是给自身添加位置rowspan: 垂直合并,又称跨行合并;自身在本列中多占一个位置 clospan: 水平合并,又称跨列合并;自身在本行中多占一个位…...
2024/5/7 0:45:41 - jsp中使用usebean显示找不到class
当执行到到如下的语句时候,会报错,显示找不到Student 类经过试验后,发现src文件夹的路径并没有关系,你把它放在那里都没有影响,关键你要使用的类必须要打包,如下所示:之后语句改为即可:...
2024/5/7 0:45:37 - Python第三节(运算符与基础数据类型)
运算符 算术元运算符 以下假设变量: a=10,b=20:运算符 描述 实例+ 加-两个对象相加 a+b输出结果30- 减-得到负数或是一个数减去另一个数 a-b输出结果-10* 乘-两个数相乘或是返回一个被重复若干次的字符串 a*b输出结果200/ 除-x除以y b/a输出结果2% 取模-返回除法的余数 b%a…...
2024/5/7 0:45:33 - 用python解“BCD解密”问题
7-4 BCD解密 BCD数是用一个字节来表达两位十进制的数,每四个比特表示一位。所以如果一个BCD数的十六进制是0x12,它表达的就是十进制的12。但是小明没学过BCD,把所有的BCD数都当作二进制数转换成十进制输出了。于是BCD的0x12被输出成了十进制的18了! 现在,你的程序要读入这…...
2024/5/6 6:36:47 - 苹果cms v8程序漏洞被注入恶意代码修复说明
大家好! 苹果cms v8被大规模注入恶意代码,导致很多人都不敢在用,无论官方怎么修复,更新,都无济于事。到底是什么原因呢! 网上有很多人提到了,黑客是如何入侵网站找到漏洞在植入代码,但是几乎都没说到应该怎么禁止,或者预防, 我是怎么发现网站被挂码的,我从搭建电影站…...
2024/5/7 0:45:25 - 动态规划之最长回文串
Helloworld分治...
2024/5/7 0:45:22 - 1003:对齐输出-1003:对齐输出
1003:对齐输出 时间限制: 1000 ms 内存限制: 66536 KB 提交数: 106286 通过数: 33166 【题目描述】 读入三个整数,按每个整数占8个字符的宽度,右对齐输出它们,按照格式要求依次输出三个整数,之间以一个空格分开。 【输入】 只有一行,包含三个整数,整数之间以…...
2024/5/7 0:45:18 - 用PuTTY学习Shell命令基本操作(2)
点击“系统”–>选择“防火墙”关闭防火墙:点击“关闭”–>输入登录密码–>点击“选项”–>选择“禁用防火墙”–>禁用成功后,关闭–>点击“是”即可 操作如图:返回点至桌面,双击打开“终端”(第3步已拖拽上去)–>在界面中输入“ifconfig”–>查找…...
2024/5/7 0:45:14 - Scipy文件输入/输出
Scipy文件输入/输出 import scipy.io as io 随机生成数组,使用scipy中的io.savemat()保存 文件格式是.mat,标准的二进制文件 io.savemat(data, mdict={"data":data }) image = io.loadmat(data.mat)读写图片使用scipy中misc.imread()/imsave() misc.imread(ss.jfif…...
2024/5/7 0:45:13 - 1097 Deduplication on a Linked List
使用注释的方式进行输出,会出现一个段错误 #include <iostream> #include <vector> using namespace std; const int maxn = 100000; struct node{int add, data, next; }rec[maxn];int del[10010] = {0}, head, n, n1, n2, d; int main(){scanf("%d %d"…...
2024/5/7 0:45:05 - Webmin 远程命令执行漏洞(CVE-2019-15107)——vulhub漏洞复现
前言:Webmin是一个用于管理类Unix系统的管理配置工具,具有Web页面。在其找回密码页面中,存在一处无需权限的命令注入漏洞,通过这个漏洞攻击者即可以执行任意系统命令。影响版本:Webmin <= 1.920漏洞代码:def peer "#{ss1 ? https:// : http:// }#{rhost}:#{rp…...
2024/5/7 0:45:01 - 笑话
我:“妈,今天的菜太咸了” 我妈:“哦,那你等会儿再吃” 我:“为什么?” 我妈:“因为时间会冲淡一切”小全头发掉了,变成了小王八 小王剪了个中分,变成了小全。 气象员小王活活气死了一头大象。=>气象员 动物 北极熊问企鹅:你为什么不来找我玩呢? 企鹅说:我 太…...
2024/5/6 21:28:16 - PAT乙级真题1095 || 解码PAT准考证(详解,C/C++示例,测试点分析)
【欢迎关注微信公众号:计算机黑科学大全,在对话框回复:PAT乙级真题】获取全部真题详解及代码示例,邀请大家加入PAT算法刷题交流qq群:821388108 个人博客:https://mzwang.top解码PAT准考证 题目描述: PAT 准考证号由 4 部分组成:第 1 位是级别,即 T 代表顶级;A 代表甲…...
2024/5/7 0:44:54 - 递归获得指定文件夹下的所有文件夹、文件
原文地址 因为有了一个想从一个大文件夹下find出所有的.doc文件的需求,这个需求的关键活动就是递归获得文件夹下的所有文件。通过一番找资料,整理出两种递归获取指定文件夹下所有文件夹、文件的方法。方式一,使用os.walk(path)函数获取使用该函数需要导入os模块。 import os…...
2024/5/7 0:44:49 - Operating Systems-tep Chapter4和Chapter5 读书笔记
Chapter4 插曲:线程APIpthread_create 线程创建pthread_join 等待线程执行完成,可以接收等待线程执行完后的返回值一个创建多个线程去并行执行特定任务并行程序会用join来确保所有的工作都完成,才退出或进入下一阶段工作。phread_mutex_lock 是对一个锁变量上锁,pthread_mut…...
2024/5/6 8:21:05 - Linux常用命令——用户管理命令
Linux常用命令——用户管理命令 (一)文件搜索命令:useradd命令名称:useradd 命令所在路径:/usr/sbin/useradd 执行权限:所有用户 语法:luseradd 用户名 功能描述: 添加新用户 范例: $useradd Auraros(建立一个名为Auraros的新用户)(二)用户管理命令:passwd命令名…...
2024/5/7 0:44:46 - 7、关联查询
关联查询 一对一、一对多、多对一、多对多 MyBatis:多对一、多对多的本质就是一对多的变化 一对一 a、业务扩展类 新建一个c类,继承类属性多的a类,然后在c类里面加入b类的属性,则c类拥有a、b类的属性,即业务扩展类 <select id="queryPersonByIdWithOneToOne"…...
2024/5/7 0:44:41 - Caffe入门:caffe solver.prototxt详解
solver算是caffe的核心的核心,它协调着整个模型的运作。caffe程序运行必带的一个参数就是solver配置文件在Deep Learning中,往往loss function是非凸的,没有解析解,我们需要通过优化方法求解。solver的主要作用就是交替调用前向(forword)算法和后向(backward)算法来更新…...
2024/5/7 0:44:37 - 数值积分,求解圆周率
数值积分,求解圆周率 f = lambda x:(1-x**2)**0.5 a = -1 b = 1from scipy.integrate import quad area, err = quad(f, a, b) area*2...
2024/5/7 0:44:33
最新文章
- 达摩院 2025届暑期实习 大模型算法
文章目录 写在前面一面/技术面 2024/4/7 晚上19:00-20:00二面/技术面 2024/4/23 早上11:15-12:15 写在前面 学校情况:211本中9硕,本硕都是计算机科班,但研究方向并不是NLP,而是图表示学习论文情况:1A(NeurIPS)1B(ICDM…...
2024/5/7 2:27:34 - 梯度消失和梯度爆炸的一些处理方法
在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言,在此感激不尽。 权重和梯度的更新公式如下: w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...
2024/5/6 9:38:23 - 论文阅读AI工具链
文献检索 可以利用智谱清言来生成合适的文献检索式,并根据需要不断调整。 谷歌学术 在Google Scholar中进行检索时,您可以使用类似的逻辑来构建您的搜索式,但是语法会有所不同。Google Scholar的搜索框接受普通的文本搜索,但是…...
2024/5/5 8:47:40 - 动态规划刷题(算法竞赛、蓝桥杯)--饥饿的奶牛(线性DP)
1、题目链接:饥饿的奶牛 - 洛谷 #include <bits/stdc.h> using namespace std; const int N3000010; vector<int> a[N];//可变数组vector存区间 int n,mx,f[N]; int main(){scanf("%d",&n);for(int i1;i<n;i){int x,y;scanf("%…...
2024/5/1 13:50:31 - 【外汇早评】美通胀数据走低,美元调整
原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...
2024/5/4 23:54:56 - 【原油贵金属周评】原油多头拥挤,价格调整
原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...
2024/5/4 23:54:56 - 【外汇周评】靓丽非农不及疲软通胀影响
原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...
2024/5/4 23:54:56 - 【原油贵金属早评】库存继续增加,油价收跌
原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...
2024/5/6 9:21:00 - 【外汇早评】日本央行会议纪要不改日元强势
原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...
2024/5/4 23:54:56 - 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响
原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...
2024/5/4 23:55:05 - 【外汇早评】美欲与伊朗重谈协议
原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...
2024/5/4 23:54:56 - 【原油贵金属早评】波动率飙升,市场情绪动荡
原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...
2024/5/4 23:55:16 - 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试
原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...
2024/5/4 23:54:56 - 【原油贵金属早评】市场情绪继续恶化,黄金上破
原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...
2024/5/6 1:40:42 - 【外汇早评】美伊僵持,风险情绪继续升温
原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...
2024/5/4 23:54:56 - 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势
原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...
2024/5/4 23:55:17 - 氧生福地 玩美北湖(上)——为时光守候两千年
原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...
2024/5/4 23:55:06 - 氧生福地 玩美北湖(中)——永春梯田里的美与鲜
原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...
2024/5/4 23:54:56 - 氧生福地 玩美北湖(下)——奔跑吧骚年!
原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...
2024/5/4 23:55:06 - 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!
原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...
2024/5/5 8:13:33 - 「发现」铁皮石斛仙草之神奇功效用于医用面膜
原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...
2024/5/4 23:55:16 - 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者
原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...
2024/5/4 23:54:58 - 广州械字号面膜生产厂家OEM/ODM4项须知!
原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...
2024/5/6 21:42:42 - 械字号医用眼膜缓解用眼过度到底有无作用?
原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...
2024/5/4 23:54:56 - 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...
解析如下:1、长按电脑电源键直至关机,然后再按一次电源健重启电脑,按F8健进入安全模式2、安全模式下进入Windows系统桌面后,按住“winR”打开运行窗口,输入“services.msc”打开服务设置3、在服务界面,选中…...
2022/11/19 21:17:18 - 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。
%读入6幅图像(每一幅图像的大小是564*564) f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...
2022/11/19 21:17:16 - 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...
win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面,在等待界面中我们需要等待操作结束才能关机,虽然这比较麻烦,但是对系统进行配置和升级…...
2022/11/19 21:17:15 - 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...
有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows,请勿关闭计算机”的提示,要过很久才能进入系统,有的用户甚至几个小时也无法进入,下面就教大家这个问题的解决方法。第一种方法:我们首先在左下角的“开始…...
2022/11/19 21:17:14 - win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...
置信有很多用户都跟小编一样遇到过这样的问题,电脑时发现开机屏幕显现“正在配置Windows Update,请勿关机”(如下图所示),而且还需求等大约5分钟才干进入系统。这是怎样回事呢?一切都是正常操作的,为什么开时机呈现“正…...
2022/11/19 21:17:13 - 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...
Win7系统开机启动时总是出现“配置Windows请勿关机”的提示,没过几秒后电脑自动重启,每次开机都这样无法进入系统,此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一:开机按下F8,在出现的Windows高级启动选…...
2022/11/19 21:17:12 - 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...
有不少windows10系统用户反映说碰到这样一个情况,就是电脑提示正在准备windows请勿关闭计算机,碰到这样的问题该怎么解决呢,现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法:1、2、依次…...
2022/11/19 21:17:11 - 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...
今天和大家分享一下win7系统重装了Win7旗舰版系统后,每次关机的时候桌面上都会显示一个“配置Windows Update的界面,提示请勿关闭计算机”,每次停留好几分钟才能正常关机,导致什么情况引起的呢?出现配置Windows Update…...
2022/11/19 21:17:10 - 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...
只能是等着,别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚,只能是考虑备份数据后重装系统了。解决来方案一:管理员运行cmd:net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...
2022/11/19 21:17:09 - 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?
原标题:电脑提示“配置Windows Update请勿关闭计算机”怎么办?win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢?一般的方…...
2022/11/19 21:17:08 - 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...
关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!关机提示 windows7 正在配…...
2022/11/19 21:17:05 - 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...
钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...
2022/11/19 21:17:05 - 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...
前几天班里有位学生电脑(windows 7系统)出问题了,具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面,长时间没反应,无法进入系统。这个问题原来帮其他同学也解决过,网上搜了不少资料&#x…...
2022/11/19 21:17:04 - 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...
本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法,并在最后教给你1种保护系统安全的好方法,一起来看看!电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中,添加了1个新功能在“磁…...
2022/11/19 21:17:03 - 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...
许多用户在长期不使用电脑的时候,开启电脑发现电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机。。.这要怎么办呢?下面小编就带着大家一起看看吧!如果能够正常进入系统,建议您暂时移…...
2022/11/19 21:17:02 - 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...
配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!配置windows update失败 还原更改 请勿关闭计算机&#x…...
2022/11/19 21:17:01 - 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...
不知道大家有没有遇到过这样的一个问题,就是我们的win7系统在关机的时候,总是喜欢显示“准备配置windows,请勿关机”这样的一个页面,没有什么大碍,但是如果一直等着的话就要两个小时甚至更久都关不了机,非常…...
2022/11/19 21:17:00 - 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...
当电脑出现正在准备配置windows请勿关闭计算机时,一般是您正对windows进行升级,但是这个要是长时间没有反应,我们不能再傻等下去了。可能是电脑出了别的问题了,来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...
2022/11/19 21:16:59 - 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...
我们使用电脑的过程中有时会遇到这种情况,当我们打开电脑之后,发现一直停留在一个界面:“配置Windows Update失败,还原更改请勿关闭计算机”,等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢࿰…...
2022/11/19 21:16:58 - 如何在iPhone上关闭“请勿打扰”
Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...
2022/11/19 21:16:57