// setNodeInodePressureCondition for the node. // TODO: this needs to move somewhere centralized... func (kl *Kubelet) setNodeInodePressureCondition(node *api.Node) { currentTime := unversioned.NewTime(kl.clock.Now()) var condition *api.NodeCondition // Check if NodeInodePressure condition already exists and if it does, just pick it up for update. for i := range node.Status.Conditions { if node.Status.Conditions[i].Type == api.NodeInodePressure { condition = &node.Status.Conditions[i] } } newCondition := false // If the NodeInodePressure condition doesn't exist, create one if condition == nil { condition = &api.NodeCondition{ Type: api.NodeInodePressure, Status: api.ConditionUnknown, } // cannot be appended to node.Status.Conditions here because it gets // copied to the slice. So if we append to the slice here none of the // updates we make below are reflected in the slice. newCondition = true } // Update the heartbeat time condition.LastHeartbeatTime = currentTime // Note: The conditions below take care of the case when a new NodeInodePressure condition is // created and as well as the case when the condition already exists. When a new condition // is created its status is set to api.ConditionUnknown which matches either // condition.Status != api.ConditionTrue or // condition.Status != api.ConditionFalse in the conditions below depending on whether // the kubelet is under inode pressure or not. if kl.evictionManager.IsUnderInodePressure() { if condition.Status != api.ConditionTrue { condition.Status = api.ConditionTrue condition.Reason = "KubeletHasInodePressure" condition.Message = "kubelet has inode pressure" condition.LastTransitionTime = currentTime kl.recordNodeStatusEvent(api.EventTypeNormal, "NodeHasInodePressure") } } else { if condition.Status != api.ConditionFalse { condition.Status = api.ConditionFalse condition.Reason = "KubeletHasNoInodePressure" condition.Message = "kubelet has no inode pressure" condition.LastTransitionTime = currentTime kl.recordNodeStatusEvent(api.EventTypeNormal, "NodeHasNoInodePressure") } } if newCondition { node.Status.Conditions = append(node.Status.Conditions, *condition) } }
// Set Ready condition for the node. func (kl *Kubelet) setNodeReadyCondition(node *api.Node) { // NOTE(aaronlevy): NodeReady condition needs to be the last in the list of node conditions. // This is due to an issue with version skewed kubelet and master components. // ref: https://github.com/kubernetes/kubernetes/issues/16961 currentTime := unversioned.NewTime(kl.clock.Now()) var newNodeReadyCondition api.NodeCondition if rs := kl.runtimeState.errors(); len(rs) == 0 { newNodeReadyCondition = api.NodeCondition{ Type: api.NodeReady, Status: api.ConditionTrue, Reason: "KubeletReady", Message: "kubelet is posting ready status", LastHeartbeatTime: currentTime, } } else { newNodeReadyCondition = api.NodeCondition{ Type: api.NodeReady, Status: api.ConditionFalse, Reason: "KubeletNotReady", Message: strings.Join(rs, ","), LastHeartbeatTime: currentTime, } } // Record any soft requirements that were not met in the container manager. status := kl.containerManager.Status() if status.SoftRequirements != nil { newNodeReadyCondition.Message = fmt.Sprintf("%s. WARNING: %s", newNodeReadyCondition.Message, status.SoftRequirements.Error()) } readyConditionUpdated := false needToRecordEvent := false for i := range node.Status.Conditions { if node.Status.Conditions[i].Type == api.NodeReady { if node.Status.Conditions[i].Status == newNodeReadyCondition.Status { newNodeReadyCondition.LastTransitionTime = node.Status.Conditions[i].LastTransitionTime } else { newNodeReadyCondition.LastTransitionTime = currentTime needToRecordEvent = true } node.Status.Conditions[i] = newNodeReadyCondition readyConditionUpdated = true break } } if !readyConditionUpdated { newNodeReadyCondition.LastTransitionTime = currentTime node.Status.Conditions = append(node.Status.Conditions, newNodeReadyCondition) } if needToRecordEvent { if newNodeReadyCondition.Status == api.ConditionTrue { kl.recordNodeStatusEvent(api.EventTypeNormal, events.NodeReady) } else { kl.recordNodeStatusEvent(api.EventTypeNormal, events.NodeNotReady) } } }
// Set OODcondition for the node. func (kl *Kubelet) setNodeOODCondition(node *api.Node) { currentTime := unversioned.NewTime(kl.clock.Now()) var nodeOODCondition *api.NodeCondition // Check if NodeOutOfDisk condition already exists and if it does, just pick it up for update. for i := range node.Status.Conditions { if node.Status.Conditions[i].Type == api.NodeOutOfDisk { nodeOODCondition = &node.Status.Conditions[i] } } newOODCondition := false // If the NodeOutOfDisk condition doesn't exist, create one. if nodeOODCondition == nil { nodeOODCondition = &api.NodeCondition{ Type: api.NodeOutOfDisk, Status: api.ConditionUnknown, } // nodeOODCondition cannot be appended to node.Status.Conditions here because it gets // copied to the slice. So if we append nodeOODCondition to the slice here none of the // updates we make to nodeOODCondition below are reflected in the slice. newOODCondition = true } // Update the heartbeat time irrespective of all the conditions. nodeOODCondition.LastHeartbeatTime = currentTime // Note: The conditions below take care of the case when a new NodeOutOfDisk condition is // created and as well as the case when the condition already exists. When a new condition // is created its status is set to api.ConditionUnknown which matches either // nodeOODCondition.Status != api.ConditionTrue or // nodeOODCondition.Status != api.ConditionFalse in the conditions below depending on whether // the kubelet is out of disk or not. if kl.isOutOfDisk() { if nodeOODCondition.Status != api.ConditionTrue { nodeOODCondition.Status = api.ConditionTrue nodeOODCondition.Reason = "KubeletOutOfDisk" nodeOODCondition.Message = "out of disk space" nodeOODCondition.LastTransitionTime = currentTime kl.recordNodeStatusEvent(api.EventTypeNormal, "NodeOutOfDisk") } } else { if nodeOODCondition.Status != api.ConditionFalse { // Update the out of disk condition when the condition status is unknown even if we // are within the outOfDiskTransitionFrequency duration. We do this to set the // condition status correctly at kubelet startup. if nodeOODCondition.Status == api.ConditionUnknown || kl.clock.Since(nodeOODCondition.LastTransitionTime.Time) >= kl.outOfDiskTransitionFrequency { nodeOODCondition.Status = api.ConditionFalse nodeOODCondition.Reason = "KubeletHasSufficientDisk" nodeOODCondition.Message = "kubelet has sufficient disk space available" nodeOODCondition.LastTransitionTime = currentTime kl.recordNodeStatusEvent(api.EventTypeNormal, "NodeHasSufficientDisk") } else { glog.Infof("Node condition status for OutOfDisk is false, but last transition time is less than %s", kl.outOfDiskTransitionFrequency) } } } if newOODCondition { node.Status.Conditions = append(node.Status.Conditions, *nodeOODCondition) } }