1. 驱逐
Eviction,即驱逐的意思,意思是当节点出现异常时,为了保证工作负载的可用性,kubernetes将有相应的机制驱逐该节点上的Pod。
2. 驱逐类型
目前有4个主要的驱逐场景, 分布是手工驱逐,节点的压力驱逐,污点导致驱逐,pod抢占导致驱逐. 一般而言主要关注的是节点压力导致的驱逐.
2.1 手工驱逐
可以使用 drain
手工排空当前的计算节点. 不过在一般实践中都是先禁止调度,而后才是排空当前节点的 pod.
root# kubectl drain nodeXX
node/nodeXX already cordoned
evicting pod "xx"
pod/xx evicted
node/nodeXX evicted
手动驱逐是kubectl测直接删除所有pod,然后设置不可调度。
这里可以通过查看源代码和实验验证。核心代码:
drain.NewCmdDrain(f, ioStreams)
// RunDrain runs the 'drain' command
func (o *DrainCmdOptions) RunDrain() error {
if err := o.RunCordonOrUncordon(true); err != nil {
return err
}
printObj, err := o.ToPrinter("drained")
if err != nil {
return err
}
drainedNodes := sets.NewString()
var fatal error
for _, info := range o.nodeInfos {
var err error
if !o.drainer.DryRun {
err = o.deleteOrEvictPodsSimple(info)
}
if err == nil || o.drainer.DryRun {
drainedNodes.Insert(info.Name)
printObj(info.Object, o.Out)
} else {
fmt.Fprintf(o.ErrOut, "error: unable to drain node %q, aborting command...\n\n", info.Name)
remainingNodes := []string{}
fatal = err
for _, remainingInfo := range o.nodeInfos {
if drainedNodes.Has(remainingInfo.Name) {
continue
}
remainingNodes = append(remainingNodes, remainingInfo.Name)
}
if len(remainingNodes) > 0 {
fmt.Fprintf(o.ErrOut, "There are pending nodes to be drained:\n")
for _, nodeName := range remainingNodes {
fmt.Fprintf(o.ErrOut, " %s\n", nodeName)
}
}
break
}
}
return fatal
}
额外补充单纯使用 cordon
的时候,并不会对已经存在在这个节点上的 pod 发生驱逐. NoSchedule 是影响的调度去行为, NoExectue 才会导致驱逐.
root# kubectl cordon xx
node/xx cordoned
spec:
taints:
- effect: NoSchedule
key: node.kubernetes.io/unschedulable
timeAdded: "xxx"
unschedulable: true
2.2 压力驱逐-kublet驱逐
参考上一篇文章。
2.3 污点驱逐
参考上上篇文章。
2.4 pod抢占驱逐
scheduler开启抢占的时候用到。后面在分析
网友评论