kerbernets 中CPU亲和性是1.8中的alpha 特性.这个特性主要功能是可以控制启动容器在cpu核数控制和具体运行在哪个核上。
这个特性主要修改的代码在pkg/kubelet/cm 中。
首先在cmd/kubelet/app/server.go中启动容器管理器ContainerManager。
kubeDeps.ContainerManager, err = cm.NewContainerManager(
而在启动容器管理器时候。初始CPU管理器cpumanager。
pkg/kubelet/cm/container_manager_linux.go:197:
func NewContainerManager(mountUtil mount.Interface, cadvisorInter
// Initialize CPU manager
if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.CPUManager) {
cm.cpuManager, err = cpumanager.NewManager(
nodeConfig.ExperimentalCPUManagerPolicy,
nodeConfig.ExperimentalCPUManagerReconcilePeriod,
machineInfo,
cm.GetNodeAllocatableReservation(),
nodeConfig.KubeletRootDir,
)
if err != nil {
glog.Errorf("failed to initialize cpu manager: %v", err)
return nil, err
}
}
当kubelet启动或者销毁容器前,容器生命周期实现都会调用CPU管理器来管理CPU相关特性。
pkg/kubelet/cm/internal_container_lifecycle.go
func (i *internalContainerLifecycleImpl) PreStartContainer(pod *v1.Pod, container *v1.Container, containerID string) error {
if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.CPUManager) {
return i.cpuManager.AddContainer(pod, container, containerID)
}
return nil
}
func (i *internalContainerLifecycleImpl) PreStopContainer(containerID string) error {
if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.CPUManager) {
return i.cpuManager.RemoveContainer(containerID)
}
return nil
}
func (i *internalContainerLifecycleImpl) PostStopContainer(containerID string) error {
if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.CPUManager) {
return i.cpuManager.RemoveContainer(containerID)
}
return nil
}
其中添加容器到CPU管理器
err = m.updateContainerCPUSet(containerID, cpus)
m.containerRuntime.UpdateContainerResources(
containerID,
&runtimeapi.LinuxContainerResources{
CpusetCpus: cpus.String(),
})
}
调用docker 客户端修改容器资源
pkg/kubelet/dockershim/docker_container.go
func (ds *dockerService) UpdateContainerResources(containerID string, resources *runtimeapi.LinuxContainerResources) error {
updateConfig := dockercontainer.UpdateConfig{
Resources: dockercontainer.Resources{
CPUPeriod: resources.CpuPeriod,
CPUQuota: resources.CpuQuota,
CPUShares: resources.CpuShares,
Memory: resources.MemoryLimitInBytes,
CpusetCpus: resources.CpusetCpus,
CpusetMems: resources.CpusetMems,
},
}
err := ds.client.UpdateContainerResources(containerID, updateConfig)//最终调用docker API post更新数据
if err != nil {
return fmt.Errorf("failed to update container %q: %v", containerID, err)
}
return nil
}