mirror of https://github.com/k3s-io/k3s
commit
9723ff7ffd
|
@ -27,6 +27,7 @@ import (
|
||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
|
"k8s.io/kubernetes/pkg/api/errors"
|
||||||
"k8s.io/kubernetes/pkg/api/resource"
|
"k8s.io/kubernetes/pkg/api/resource"
|
||||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||||
|
@ -1312,17 +1313,19 @@ func (d *NodeDescriber) Describe(namespace, name string) (string, error) {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
var pods []*api.Pod
|
fieldSelector, err := fields.ParseSelector("spec.nodeName=" + name + ",status.phase!=" + string(api.PodSucceeded) + ",status.phase!=" + string(api.PodFailed))
|
||||||
allPods, err := d.Pods(namespace).List(unversioned.ListOptions{})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
for i := range allPods.Items {
|
// in a policy aware setting, users may have access to a node, but not all pods
|
||||||
pod := &allPods.Items[i]
|
// in that case, we note that the user does not have access to the pods
|
||||||
if pod.Spec.NodeName != name {
|
canViewPods := true
|
||||||
continue
|
nodeNonTerminatedPodsList, err := d.Pods(namespace).List(unversioned.ListOptions{FieldSelector: unversioned.FieldSelector{fieldSelector}})
|
||||||
|
if err != nil {
|
||||||
|
if !errors.IsForbidden(err) {
|
||||||
|
return "", err
|
||||||
}
|
}
|
||||||
pods = append(pods, pod)
|
canViewPods = false
|
||||||
}
|
}
|
||||||
|
|
||||||
var events *api.EventList
|
var events *api.EventList
|
||||||
|
@ -1334,10 +1337,10 @@ func (d *NodeDescriber) Describe(namespace, name string) (string, error) {
|
||||||
events, _ = d.Events("").Search(ref)
|
events, _ = d.Events("").Search(ref)
|
||||||
}
|
}
|
||||||
|
|
||||||
return describeNode(node, pods, events)
|
return describeNode(node, nodeNonTerminatedPodsList, events, canViewPods)
|
||||||
}
|
}
|
||||||
|
|
||||||
func describeNode(node *api.Node, pods []*api.Pod, events *api.EventList) (string, error) {
|
func describeNode(node *api.Node, nodeNonTerminatedPodsList *api.PodList, events *api.EventList, canViewPods bool) (string, error) {
|
||||||
return tabbedString(func(out io.Writer) error {
|
return tabbedString(func(out io.Writer) error {
|
||||||
fmt.Fprintf(out, "Name:\t%s\n", node.Name)
|
fmt.Fprintf(out, "Name:\t%s\n", node.Name)
|
||||||
fmt.Fprintf(out, "Labels:\t%s\n", labels.FormatLabels(node.Labels))
|
fmt.Fprintf(out, "Labels:\t%s\n", labels.FormatLabels(node.Labels))
|
||||||
|
@ -1384,10 +1387,13 @@ func describeNode(node *api.Node, pods []*api.Pod, events *api.EventList) (strin
|
||||||
if len(node.Spec.ExternalID) > 0 {
|
if len(node.Spec.ExternalID) > 0 {
|
||||||
fmt.Fprintf(out, "ExternalID:\t%s\n", node.Spec.ExternalID)
|
fmt.Fprintf(out, "ExternalID:\t%s\n", node.Spec.ExternalID)
|
||||||
}
|
}
|
||||||
if err := describeNodeResource(pods, node, out); err != nil {
|
if canViewPods && nodeNonTerminatedPodsList != nil {
|
||||||
return err
|
if err := describeNodeResource(nodeNonTerminatedPodsList, node, out); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Fprintf(out, "Pods:\tnot authorized\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
if events != nil {
|
if events != nil {
|
||||||
DescribeEvents(events, out)
|
DescribeEvents(events, out)
|
||||||
}
|
}
|
||||||
|
@ -1444,13 +1450,12 @@ func (d *HorizontalPodAutoscalerDescriber) Describe(namespace, name string) (str
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func describeNodeResource(pods []*api.Pod, node *api.Node, out io.Writer) error {
|
func describeNodeResource(nodeNonTerminatedPodsList *api.PodList, node *api.Node, out io.Writer) error {
|
||||||
nonTerminatedPods := filterTerminatedPods(pods)
|
fmt.Fprintf(out, "Non-terminated Pods:\t(%d in total)\n", len(nodeNonTerminatedPodsList.Items))
|
||||||
fmt.Fprintf(out, "Non-terminated Pods:\t(%d in total)\n", len(nonTerminatedPods))
|
|
||||||
fmt.Fprint(out, " Namespace\tName\t\tCPU Requests\tCPU Limits\tMemory Requests\tMemory Limits\n")
|
fmt.Fprint(out, " Namespace\tName\t\tCPU Requests\tCPU Limits\tMemory Requests\tMemory Limits\n")
|
||||||
fmt.Fprint(out, " ---------\t----\t\t------------\t----------\t---------------\t-------------\n")
|
fmt.Fprint(out, " ---------\t----\t\t------------\t----------\t---------------\t-------------\n")
|
||||||
for _, pod := range nonTerminatedPods {
|
for _, pod := range nodeNonTerminatedPodsList.Items {
|
||||||
req, limit, err := api.PodRequestsAndLimits(pod)
|
req, limit, err := api.PodRequestsAndLimits(&pod)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -1466,7 +1471,7 @@ func describeNodeResource(pods []*api.Pod, node *api.Node, out io.Writer) error
|
||||||
|
|
||||||
fmt.Fprint(out, "Allocated resources:\n (Total limits may be over 100%, i.e., overcommitted. More info: http://releases.k8s.io/HEAD/docs/user-guide/compute-resources.md)\n CPU Requests\tCPU Limits\tMemory Requests\tMemory Limits\n")
|
fmt.Fprint(out, "Allocated resources:\n (Total limits may be over 100%, i.e., overcommitted. More info: http://releases.k8s.io/HEAD/docs/user-guide/compute-resources.md)\n CPU Requests\tCPU Limits\tMemory Requests\tMemory Limits\n")
|
||||||
fmt.Fprint(out, " ------------\t----------\t---------------\t-------------\n")
|
fmt.Fprint(out, " ------------\t----------\t---------------\t-------------\n")
|
||||||
reqs, limits, err := getPodsTotalRequestsAndLimits(nonTerminatedPods)
|
reqs, limits, err := getPodsTotalRequestsAndLimits(nodeNonTerminatedPodsList)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -1495,10 +1500,10 @@ func filterTerminatedPods(pods []*api.Pod) []*api.Pod {
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func getPodsTotalRequestsAndLimits(pods []*api.Pod) (reqs map[api.ResourceName]resource.Quantity, limits map[api.ResourceName]resource.Quantity, err error) {
|
func getPodsTotalRequestsAndLimits(podList *api.PodList) (reqs map[api.ResourceName]resource.Quantity, limits map[api.ResourceName]resource.Quantity, err error) {
|
||||||
reqs, limits = map[api.ResourceName]resource.Quantity{}, map[api.ResourceName]resource.Quantity{}
|
reqs, limits = map[api.ResourceName]resource.Quantity{}, map[api.ResourceName]resource.Quantity{}
|
||||||
for _, pod := range pods {
|
for _, pod := range podList.Items {
|
||||||
podReqs, podLimits, err := api.PodRequestsAndLimits(pod)
|
podReqs, podLimits, err := api.PodRequestsAndLimits(&pod)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -359,53 +359,55 @@ func TestDefaultDescribers(t *testing.T) {
|
||||||
|
|
||||||
func TestGetPodsTotalRequests(t *testing.T) {
|
func TestGetPodsTotalRequests(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
pods []*api.Pod
|
pods *api.PodList
|
||||||
expectedReqs, expectedLimits map[api.ResourceName]resource.Quantity
|
expectedReqs, expectedLimits map[api.ResourceName]resource.Quantity
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
pods: []*api.Pod{
|
pods: &api.PodList{
|
||||||
{
|
Items: []api.Pod{
|
||||||
Spec: api.PodSpec{
|
{
|
||||||
Containers: []api.Container{
|
Spec: api.PodSpec{
|
||||||
{
|
Containers: []api.Container{
|
||||||
Resources: api.ResourceRequirements{
|
{
|
||||||
Requests: api.ResourceList{
|
Resources: api.ResourceRequirements{
|
||||||
api.ResourceName(api.ResourceCPU): resource.MustParse("1"),
|
Requests: api.ResourceList{
|
||||||
api.ResourceName(api.ResourceMemory): resource.MustParse("300Mi"),
|
api.ResourceName(api.ResourceCPU): resource.MustParse("1"),
|
||||||
api.ResourceName(api.ResourceStorage): resource.MustParse("1G"),
|
api.ResourceName(api.ResourceMemory): resource.MustParse("300Mi"),
|
||||||
|
api.ResourceName(api.ResourceStorage): resource.MustParse("1G"),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
{
|
||||||
{
|
Resources: api.ResourceRequirements{
|
||||||
Resources: api.ResourceRequirements{
|
Requests: api.ResourceList{
|
||||||
Requests: api.ResourceList{
|
api.ResourceName(api.ResourceCPU): resource.MustParse("90m"),
|
||||||
api.ResourceName(api.ResourceCPU): resource.MustParse("90m"),
|
api.ResourceName(api.ResourceMemory): resource.MustParse("120Mi"),
|
||||||
api.ResourceName(api.ResourceMemory): resource.MustParse("120Mi"),
|
api.ResourceName(api.ResourceStorage): resource.MustParse("200M"),
|
||||||
api.ResourceName(api.ResourceStorage): resource.MustParse("200M"),
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
{
|
||||||
{
|
Spec: api.PodSpec{
|
||||||
Spec: api.PodSpec{
|
Containers: []api.Container{
|
||||||
Containers: []api.Container{
|
{
|
||||||
{
|
Resources: api.ResourceRequirements{
|
||||||
Resources: api.ResourceRequirements{
|
Requests: api.ResourceList{
|
||||||
Requests: api.ResourceList{
|
api.ResourceName(api.ResourceCPU): resource.MustParse("60m"),
|
||||||
api.ResourceName(api.ResourceCPU): resource.MustParse("60m"),
|
api.ResourceName(api.ResourceMemory): resource.MustParse("43Mi"),
|
||||||
api.ResourceName(api.ResourceMemory): resource.MustParse("43Mi"),
|
api.ResourceName(api.ResourceStorage): resource.MustParse("500M"),
|
||||||
api.ResourceName(api.ResourceStorage): resource.MustParse("500M"),
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
{
|
||||||
{
|
Resources: api.ResourceRequirements{
|
||||||
Resources: api.ResourceRequirements{
|
Requests: api.ResourceList{
|
||||||
Requests: api.ResourceList{
|
api.ResourceName(api.ResourceCPU): resource.MustParse("34m"),
|
||||||
api.ResourceName(api.ResourceCPU): resource.MustParse("34m"),
|
api.ResourceName(api.ResourceMemory): resource.MustParse("83Mi"),
|
||||||
api.ResourceName(api.ResourceMemory): resource.MustParse("83Mi"),
|
api.ResourceName(api.ResourceStorage): resource.MustParse("700M"),
|
||||||
api.ResourceName(api.ResourceStorage): resource.MustParse("700M"),
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue