Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
b1448adb
Unverified
Commit
b1448adb
authored
Nov 15, 2017
by
Frederic Branczyk
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
kubectl: Use metrics-server for kubectl top commands
parent
ddea2dd5
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
305 additions
and
38 deletions
+305
-38
BUILD
pkg/kubectl/cmd/BUILD
+9
-0
BUILD
pkg/kubectl/cmd/testing/BUILD
+1
-0
fake.go
pkg/kubectl/cmd/testing/fake.go
+10
-0
top.go
pkg/kubectl/cmd/top.go
+21
-0
top_node.go
pkg/kubectl/cmd/top_node.go
+65
-6
top_node_test.go
pkg/kubectl/cmd/top_node_test.go
+0
-0
top_pod.go
pkg/kubectl/cmd/top_pod.go
+65
-3
top_pod_test.go
pkg/kubectl/cmd/top_pod_test.go
+0
-0
top_test.go
pkg/kubectl/cmd/top_test.go
+62
-4
BUILD
pkg/kubectl/cmd/util/BUILD
+1
-0
clientcache.go
pkg/kubectl/cmd/util/clientcache.go
+29
-0
factory.go
pkg/kubectl/cmd/util/factory.go
+4
-0
factory_client_access.go
pkg/kubectl/cmd/util/factory_client_access.go
+5
-0
BUILD
pkg/kubectl/metricsutil/BUILD
+1
-0
metrics_client.go
pkg/kubectl/metricsutil/metrics_client.go
+31
-24
metrics_printer.go
pkg/kubectl/metricsutil/metrics_printer.go
+1
-1
No files found.
pkg/kubectl/cmd/BUILD
View file @
b1448adb
...
@@ -140,6 +140,7 @@ go_library(
...
@@ -140,6 +140,7 @@ go_library(
"//vendor/k8s.io/apimachinery/pkg/version:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/version:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/watch:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/watch:go_default_library",
"//vendor/k8s.io/apiserver/pkg/util/flag:go_default_library",
"//vendor/k8s.io/apiserver/pkg/util/flag:go_default_library",
"//vendor/k8s.io/client-go/discovery:go_default_library",
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
"//vendor/k8s.io/client-go/kubernetes/typed/core/v1:go_default_library",
"//vendor/k8s.io/client-go/kubernetes/typed/core/v1:go_default_library",
"//vendor/k8s.io/client-go/kubernetes/typed/rbac/v1:go_default_library",
"//vendor/k8s.io/client-go/kubernetes/typed/rbac/v1:go_default_library",
...
@@ -149,6 +150,9 @@ go_library(
...
@@ -149,6 +150,9 @@ go_library(
"//vendor/k8s.io/client-go/tools/remotecommand:go_default_library",
"//vendor/k8s.io/client-go/tools/remotecommand:go_default_library",
"//vendor/k8s.io/client-go/transport/spdy:go_default_library",
"//vendor/k8s.io/client-go/transport/spdy:go_default_library",
"//vendor/k8s.io/kube-openapi/pkg/util/proto:go_default_library",
"//vendor/k8s.io/kube-openapi/pkg/util/proto:go_default_library",
"//vendor/k8s.io/metrics/pkg/apis/metrics:go_default_library",
"//vendor/k8s.io/metrics/pkg/apis/metrics/v1beta1:go_default_library",
"//vendor/k8s.io/metrics/pkg/client/clientset_generated/clientset:go_default_library",
"//vendor/k8s.io/utils/exec:go_default_library",
"//vendor/k8s.io/utils/exec:go_default_library",
],
],
)
)
...
@@ -224,6 +228,7 @@ go_test(
...
@@ -224,6 +228,7 @@ go_test(
"//pkg/printers:go_default_library",
"//pkg/printers:go_default_library",
"//pkg/printers/internalversion:go_default_library",
"//pkg/printers/internalversion:go_default_library",
"//pkg/util/strings:go_default_library",
"//pkg/util/strings:go_default_library",
"//vendor/github.com/googleapis/gnostic/OpenAPIv2:go_default_library",
"//vendor/github.com/spf13/cobra:go_default_library",
"//vendor/github.com/spf13/cobra:go_default_library",
"//vendor/github.com/stretchr/testify/assert:go_default_library",
"//vendor/github.com/stretchr/testify/assert:go_default_library",
"//vendor/gopkg.in/yaml.v2:go_default_library",
"//vendor/gopkg.in/yaml.v2:go_default_library",
...
@@ -245,11 +250,15 @@ go_test(
...
@@ -245,11 +250,15 @@ go_test(
"//vendor/k8s.io/apimachinery/pkg/util/strategicpatch:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/strategicpatch:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/strategicpatch/testing:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/strategicpatch/testing:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/version:go_default_library",
"//vendor/k8s.io/client-go/dynamic:go_default_library",
"//vendor/k8s.io/client-go/dynamic:go_default_library",
"//vendor/k8s.io/client-go/rest:go_default_library",
"//vendor/k8s.io/client-go/rest:go_default_library",
"//vendor/k8s.io/client-go/rest/fake:go_default_library",
"//vendor/k8s.io/client-go/rest/fake:go_default_library",
"//vendor/k8s.io/client-go/testing:go_default_library",
"//vendor/k8s.io/client-go/tools/remotecommand:go_default_library",
"//vendor/k8s.io/client-go/tools/remotecommand:go_default_library",
"//vendor/k8s.io/metrics/pkg/apis/metrics/v1alpha1:go_default_library",
"//vendor/k8s.io/metrics/pkg/apis/metrics/v1alpha1:go_default_library",
"//vendor/k8s.io/metrics/pkg/apis/metrics/v1beta1:go_default_library",
"//vendor/k8s.io/metrics/pkg/client/clientset_generated/clientset/fake:go_default_library",
"//vendor/k8s.io/utils/exec:go_default_library",
"//vendor/k8s.io/utils/exec:go_default_library",
],
],
)
)
...
...
pkg/kubectl/cmd/testing/BUILD
View file @
b1448adb
...
@@ -40,6 +40,7 @@ go_library(
...
@@ -40,6 +40,7 @@ go_library(
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
"//vendor/k8s.io/client-go/rest:go_default_library",
"//vendor/k8s.io/client-go/rest:go_default_library",
"//vendor/k8s.io/client-go/rest/fake:go_default_library",
"//vendor/k8s.io/client-go/rest/fake:go_default_library",
"//vendor/k8s.io/metrics/pkg/client/clientset_generated/clientset:go_default_library",
],
],
)
)
...
...
pkg/kubectl/cmd/testing/fake.go
View file @
b1448adb
...
@@ -50,6 +50,7 @@ import (
...
@@ -50,6 +50,7 @@ import (
"k8s.io/kubernetes/pkg/kubectl/resource"
"k8s.io/kubernetes/pkg/kubectl/resource"
"k8s.io/kubernetes/pkg/kubectl/validation"
"k8s.io/kubernetes/pkg/kubectl/validation"
"k8s.io/kubernetes/pkg/printers"
"k8s.io/kubernetes/pkg/printers"
metricsclientset
"k8s.io/metrics/pkg/client/clientset_generated/clientset"
)
)
// +k8s:deepcopy-gen=true
// +k8s:deepcopy-gen=true
...
@@ -245,6 +246,7 @@ type TestFactory struct {
...
@@ -245,6 +246,7 @@ type TestFactory struct {
TmpDir
string
TmpDir
string
CategoryExpander
categories
.
CategoryExpander
CategoryExpander
categories
.
CategoryExpander
SkipDiscovery
bool
SkipDiscovery
bool
MetricsClientSet
metricsclientset
.
Interface
ClientForMappingFunc
func
(
mapping
*
meta
.
RESTMapping
)
(
resource
.
RESTClient
,
error
)
ClientForMappingFunc
func
(
mapping
*
meta
.
RESTMapping
)
(
resource
.
RESTClient
,
error
)
UnstructuredClientForMappingFunc
func
(
mapping
*
meta
.
RESTMapping
)
(
resource
.
RESTClient
,
error
)
UnstructuredClientForMappingFunc
func
(
mapping
*
meta
.
RESTMapping
)
(
resource
.
RESTClient
,
error
)
...
@@ -315,6 +317,10 @@ func (f *FakeFactory) KubernetesClientSet() (*kubernetes.Clientset, error) {
...
@@ -315,6 +317,10 @@ func (f *FakeFactory) KubernetesClientSet() (*kubernetes.Clientset, error) {
return
nil
,
nil
return
nil
,
nil
}
}
func
(
f
*
FakeFactory
)
MetricsClientSet
()
(
metricsclientset
.
Interface
,
error
)
{
return
f
.
tf
.
MetricsClientSet
,
f
.
tf
.
Err
}
func
(
f
*
FakeFactory
)
ClientSet
()
(
internalclientset
.
Interface
,
error
)
{
func
(
f
*
FakeFactory
)
ClientSet
()
(
internalclientset
.
Interface
,
error
)
{
return
nil
,
nil
return
nil
,
nil
}
}
...
@@ -675,6 +681,10 @@ func (f *fakeAPIFactory) KubernetesClientSet() (*kubernetes.Clientset, error) {
...
@@ -675,6 +681,10 @@ func (f *fakeAPIFactory) KubernetesClientSet() (*kubernetes.Clientset, error) {
return
clientset
,
f
.
tf
.
Err
return
clientset
,
f
.
tf
.
Err
}
}
func
(
f
*
fakeAPIFactory
)
MetricsClientSet
()
(
metricsclientset
.
Interface
,
error
)
{
return
f
.
tf
.
MetricsClientSet
,
f
.
tf
.
Err
}
func
(
f
*
fakeAPIFactory
)
ClientSet
()
(
internalclientset
.
Interface
,
error
)
{
func
(
f
*
fakeAPIFactory
)
ClientSet
()
(
internalclientset
.
Interface
,
error
)
{
// Swap the HTTP client out of the REST client with the fake
// Swap the HTTP client out of the REST client with the fake
// version.
// version.
...
...
pkg/kubectl/cmd/top.go
View file @
b1448adb
...
@@ -19,8 +19,10 @@ package cmd
...
@@ -19,8 +19,10 @@ package cmd
import
(
import
(
"io"
"io"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
cmdutil
"k8s.io/kubernetes/pkg/kubectl/cmd/util"
cmdutil
"k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
metricsapi
"k8s.io/metrics/pkg/apis/metrics"
"github.com/spf13/cobra"
"github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
...
@@ -30,6 +32,9 @@ import (
...
@@ -30,6 +32,9 @@ import (
type
TopOptions
struct
{}
type
TopOptions
struct
{}
var
(
var
(
supportedMetricsAPIVersions
=
[]
string
{
"v1beta1"
,
}
topLong
=
templates
.
LongDesc
(
i18n
.
T
(
`
topLong
=
templates
.
LongDesc
(
i18n
.
T
(
`
Display Resource (CPU/Memory/Storage) usage.
Display Resource (CPU/Memory/Storage) usage.
...
@@ -51,3 +56,19 @@ func NewCmdTop(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
...
@@ -51,3 +56,19 @@ func NewCmdTop(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
cmd
.
AddCommand
(
NewCmdTopPod
(
f
,
nil
,
out
))
cmd
.
AddCommand
(
NewCmdTopPod
(
f
,
nil
,
out
))
return
cmd
return
cmd
}
}
func
SupportedMetricsAPIVersionAvailable
(
discoveredAPIGroups
*
metav1
.
APIGroupList
)
bool
{
for
_
,
discoveredAPIGroup
:=
range
discoveredAPIGroups
.
Groups
{
if
discoveredAPIGroup
.
Name
!=
metricsapi
.
GroupName
{
continue
}
for
_
,
version
:=
range
discoveredAPIGroup
.
Versions
{
for
_
,
supportedVersion
:=
range
supportedMetricsAPIVersions
{
if
version
.
Version
==
supportedVersion
{
return
true
}
}
}
}
return
false
}
pkg/kubectl/cmd/top_node.go
View file @
b1448adb
...
@@ -25,11 +25,15 @@ import (
...
@@ -25,11 +25,15 @@ import (
"k8s.io/api/core/v1"
"k8s.io/api/core/v1"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/discovery"
corev1
"k8s.io/client-go/kubernetes/typed/core/v1"
corev1
"k8s.io/client-go/kubernetes/typed/core/v1"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
cmdutil
"k8s.io/kubernetes/pkg/kubectl/cmd/util"
cmdutil
"k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/metricsutil"
"k8s.io/kubernetes/pkg/kubectl/metricsutil"
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
metricsapi
"k8s.io/metrics/pkg/apis/metrics"
metricsV1beta1api
"k8s.io/metrics/pkg/apis/metrics/v1beta1"
metricsclientset
"k8s.io/metrics/pkg/client/clientset_generated/clientset"
)
)
// TopNodeOptions contains all the options for running the top-node cli command.
// TopNodeOptions contains all the options for running the top-node cli command.
...
@@ -40,6 +44,8 @@ type TopNodeOptions struct {
...
@@ -40,6 +44,8 @@ type TopNodeOptions struct {
HeapsterOptions
HeapsterTopOptions
HeapsterOptions
HeapsterTopOptions
Client
*
metricsutil
.
HeapsterMetricsClient
Client
*
metricsutil
.
HeapsterMetricsClient
Printer
*
metricsutil
.
TopCmdPrinter
Printer
*
metricsutil
.
TopCmdPrinter
DiscoveryClient
discovery
.
DiscoveryInterface
MetricsClient
metricsclientset
.
Interface
}
}
type
HeapsterTopOptions
struct
{
type
HeapsterTopOptions
struct
{
...
@@ -123,8 +129,16 @@ func (o *TopNodeOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []
...
@@ -123,8 +129,16 @@ func (o *TopNodeOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
o
.
DiscoveryClient
=
clientset
.
DiscoveryClient
o
.
MetricsClient
,
err
=
f
.
MetricsClientSet
()
if
err
!=
nil
{
return
err
}
o
.
NodeClient
=
clientset
.
CoreV1
()
o
.
NodeClient
=
clientset
.
CoreV1
()
o
.
Client
=
metricsutil
.
NewHeapsterMetricsClient
(
clientset
.
CoreV1
(),
o
.
HeapsterOptions
.
Namespace
,
o
.
HeapsterOptions
.
Scheme
,
o
.
HeapsterOptions
.
Service
,
o
.
HeapsterOptions
.
Port
)
o
.
Client
=
metricsutil
.
NewHeapsterMetricsClient
(
clientset
.
CoreV1
(),
o
.
HeapsterOptions
.
Namespace
,
o
.
HeapsterOptions
.
Scheme
,
o
.
HeapsterOptions
.
Service
,
o
.
HeapsterOptions
.
Port
)
o
.
Printer
=
metricsutil
.
NewTopCmdPrinter
(
out
)
o
.
Printer
=
metricsutil
.
NewTopCmdPrinter
(
out
)
return
nil
return
nil
}
}
...
@@ -138,15 +152,35 @@ func (o *TopNodeOptions) Validate() error {
...
@@ -138,15 +152,35 @@ func (o *TopNodeOptions) Validate() error {
func
(
o
TopNodeOptions
)
RunTopNode
()
error
{
func
(
o
TopNodeOptions
)
RunTopNode
()
error
{
var
err
error
var
err
error
selector
:=
labels
.
Everything
()
.
String
()
selector
:=
labels
.
Everything
()
if
len
(
o
.
Selector
)
>
0
{
if
len
(
o
.
Selector
)
>
0
{
selector
=
o
.
Selector
selector
,
err
=
labels
.
Parse
(
o
.
Selector
)
if
err
!=
nil
{
return
err
}
}
}
metrics
,
err
:=
o
.
Client
.
GetNodeMetrics
(
o
.
ResourceName
,
selector
)
apiGroups
,
err
:=
o
.
DiscoveryClient
.
ServerGroups
()
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
if
len
(
metrics
)
==
0
{
metricsAPIAvailable
:=
SupportedMetricsAPIVersionAvailable
(
apiGroups
)
metrics
:=
&
metricsapi
.
NodeMetricsList
{}
if
metricsAPIAvailable
{
metrics
,
err
=
getNodeMetricsFromMetricsAPI
(
o
.
MetricsClient
,
o
.
ResourceName
,
selector
)
if
err
!=
nil
{
return
err
}
}
else
{
metrics
,
err
=
o
.
Client
.
GetNodeMetrics
(
o
.
ResourceName
,
selector
.
String
())
if
err
!=
nil
{
return
err
}
}
if
len
(
metrics
.
Items
)
==
0
{
return
errors
.
New
(
"metrics not available yet"
)
return
errors
.
New
(
"metrics not available yet"
)
}
}
...
@@ -159,7 +193,7 @@ func (o TopNodeOptions) RunTopNode() error {
...
@@ -159,7 +193,7 @@ func (o TopNodeOptions) RunTopNode() error {
nodes
=
append
(
nodes
,
*
node
)
nodes
=
append
(
nodes
,
*
node
)
}
else
{
}
else
{
nodeList
,
err
:=
o
.
NodeClient
.
Nodes
()
.
List
(
metav1
.
ListOptions
{
nodeList
,
err
:=
o
.
NodeClient
.
Nodes
()
.
List
(
metav1
.
ListOptions
{
LabelSelector
:
selector
,
LabelSelector
:
selector
.
String
()
,
})
})
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
...
@@ -173,5 +207,30 @@ func (o TopNodeOptions) RunTopNode() error {
...
@@ -173,5 +207,30 @@ func (o TopNodeOptions) RunTopNode() error {
allocatable
[
n
.
Name
]
=
n
.
Status
.
Allocatable
allocatable
[
n
.
Name
]
=
n
.
Status
.
Allocatable
}
}
return
o
.
Printer
.
PrintNodeMetrics
(
metrics
,
allocatable
)
return
o
.
Printer
.
PrintNodeMetrics
(
metrics
.
Items
,
allocatable
)
}
func
getNodeMetricsFromMetricsAPI
(
metricsClient
metricsclientset
.
Interface
,
resourceName
string
,
selector
labels
.
Selector
)
(
*
metricsapi
.
NodeMetricsList
,
error
)
{
var
err
error
versionedMetrics
:=
&
metricsV1beta1api
.
NodeMetricsList
{}
mc
:=
metricsClient
.
Metrics
()
nm
:=
mc
.
NodeMetricses
()
if
resourceName
!=
""
{
m
,
err
:=
nm
.
Get
(
resourceName
,
metav1
.
GetOptions
{})
if
err
!=
nil
{
return
nil
,
err
}
versionedMetrics
.
Items
=
[]
metricsV1beta1api
.
NodeMetrics
{
*
m
}
}
else
{
versionedMetrics
,
err
=
nm
.
List
(
metav1
.
ListOptions
{
LabelSelector
:
selector
.
String
()})
if
err
!=
nil
{
return
nil
,
err
}
}
metrics
:=
&
metricsapi
.
NodeMetricsList
{}
err
=
metricsV1beta1api
.
Convert_v1beta1_NodeMetricsList_To_metrics_NodeMetricsList
(
versionedMetrics
,
metrics
,
nil
)
if
err
!=
nil
{
return
nil
,
err
}
return
metrics
,
nil
}
}
pkg/kubectl/cmd/top_node_test.go
View file @
b1448adb
This diff is collapsed.
Click to expand it.
pkg/kubectl/cmd/top_pod.go
View file @
b1448adb
...
@@ -25,11 +25,15 @@ import (
...
@@ -25,11 +25,15 @@ import (
"k8s.io/api/core/v1"
"k8s.io/api/core/v1"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/discovery"
corev1
"k8s.io/client-go/kubernetes/typed/core/v1"
corev1
"k8s.io/client-go/kubernetes/typed/core/v1"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
cmdutil
"k8s.io/kubernetes/pkg/kubectl/cmd/util"
cmdutil
"k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/metricsutil"
"k8s.io/kubernetes/pkg/kubectl/metricsutil"
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
metricsapi
"k8s.io/metrics/pkg/apis/metrics"
metricsv1beta1api
"k8s.io/metrics/pkg/apis/metrics/v1beta1"
metricsclientset
"k8s.io/metrics/pkg/client/clientset_generated/clientset"
"github.com/golang/glog"
"github.com/golang/glog"
"github.com/spf13/cobra"
"github.com/spf13/cobra"
...
@@ -45,6 +49,8 @@ type TopPodOptions struct {
...
@@ -45,6 +49,8 @@ type TopPodOptions struct {
HeapsterOptions
HeapsterTopOptions
HeapsterOptions
HeapsterTopOptions
Client
*
metricsutil
.
HeapsterMetricsClient
Client
*
metricsutil
.
HeapsterMetricsClient
Printer
*
metricsutil
.
TopCmdPrinter
Printer
*
metricsutil
.
TopCmdPrinter
DiscoveryClient
discovery
.
DiscoveryInterface
MetricsClient
metricsclientset
.
Interface
}
}
const
metricsCreationDelay
=
2
*
time
.
Minute
const
metricsCreationDelay
=
2
*
time
.
Minute
...
@@ -119,8 +125,16 @@ func (o *TopPodOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []s
...
@@ -119,8 +125,16 @@ func (o *TopPodOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []s
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
o
.
DiscoveryClient
=
clientset
.
DiscoveryClient
o
.
MetricsClient
,
err
=
f
.
MetricsClientSet
()
if
err
!=
nil
{
return
err
}
o
.
PodClient
=
clientset
.
CoreV1
()
o
.
PodClient
=
clientset
.
CoreV1
()
o
.
Client
=
metricsutil
.
NewHeapsterMetricsClient
(
clientset
.
CoreV1
(),
o
.
HeapsterOptions
.
Namespace
,
o
.
HeapsterOptions
.
Scheme
,
o
.
HeapsterOptions
.
Service
,
o
.
HeapsterOptions
.
Port
)
o
.
Client
=
metricsutil
.
NewHeapsterMetricsClient
(
clientset
.
CoreV1
(),
o
.
HeapsterOptions
.
Namespace
,
o
.
HeapsterOptions
.
Scheme
,
o
.
HeapsterOptions
.
Service
,
o
.
HeapsterOptions
.
Port
)
o
.
Printer
=
metricsutil
.
NewTopCmdPrinter
(
out
)
o
.
Printer
=
metricsutil
.
NewTopCmdPrinter
(
out
)
return
nil
return
nil
}
}
...
@@ -141,10 +155,30 @@ func (o TopPodOptions) RunTopPod() error {
...
@@ -141,10 +155,30 @@ func (o TopPodOptions) RunTopPod() error {
return
err
return
err
}
}
}
}
metrics
,
err
:=
o
.
Client
.
GetPodMetrics
(
o
.
Namespace
,
o
.
ResourceName
,
o
.
AllNamespaces
,
selector
)
apiGroups
,
err
:=
o
.
DiscoveryClient
.
ServerGroups
()
if
err
!=
nil
{
return
err
}
metricsAPIAvailable
:=
SupportedMetricsAPIVersionAvailable
(
apiGroups
)
metrics
:=
&
metricsapi
.
PodMetricsList
{}
if
metricsAPIAvailable
{
metrics
,
err
=
getMetricsFromMetricsAPI
(
o
.
MetricsClient
,
o
.
Namespace
,
o
.
ResourceName
,
o
.
AllNamespaces
,
selector
)
if
err
!=
nil
{
return
err
}
}
else
{
metrics
,
err
=
o
.
Client
.
GetPodMetrics
(
o
.
Namespace
,
o
.
ResourceName
,
o
.
AllNamespaces
,
selector
)
if
err
!=
nil
{
return
err
}
}
// TODO: Refactor this once Heapster becomes the API server.
// TODO: Refactor this once Heapster becomes the API server.
// First we check why no metrics have been received.
// First we check why no metrics have been received.
if
len
(
metrics
)
==
0
{
if
len
(
metrics
.
Items
)
==
0
{
// If the API server query is successful but all the pods are newly created,
// If the API server query is successful but all the pods are newly created,
// the metrics are probably not ready yet, so we return the error here in the first place.
// the metrics are probably not ready yet, so we return the error here in the first place.
e
:=
verifyEmptyMetrics
(
o
,
selector
)
e
:=
verifyEmptyMetrics
(
o
,
selector
)
...
@@ -155,7 +189,35 @@ func (o TopPodOptions) RunTopPod() error {
...
@@ -155,7 +189,35 @@ func (o TopPodOptions) RunTopPod() error {
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
return
o
.
Printer
.
PrintPodMetrics
(
metrics
,
o
.
PrintContainers
,
o
.
AllNamespaces
)
return
o
.
Printer
.
PrintPodMetrics
(
metrics
.
Items
,
o
.
PrintContainers
,
o
.
AllNamespaces
)
}
func
getMetricsFromMetricsAPI
(
metricsClient
metricsclientset
.
Interface
,
namespace
,
resourceName
string
,
allNamespaces
bool
,
selector
labels
.
Selector
)
(
*
metricsapi
.
PodMetricsList
,
error
)
{
var
err
error
ns
:=
metav1
.
NamespaceAll
if
!
allNamespaces
{
ns
=
namespace
}
versionedMetrics
:=
&
metricsv1beta1api
.
PodMetricsList
{}
if
resourceName
!=
""
{
m
,
err
:=
metricsClient
.
Metrics
()
.
PodMetricses
(
ns
)
.
Get
(
resourceName
,
metav1
.
GetOptions
{})
if
err
!=
nil
{
return
nil
,
err
}
versionedMetrics
.
Items
=
[]
metricsv1beta1api
.
PodMetrics
{
*
m
}
}
else
{
versionedMetrics
,
err
=
metricsClient
.
Metrics
()
.
PodMetricses
(
ns
)
.
List
(
metav1
.
ListOptions
{
LabelSelector
:
selector
.
String
()})
if
err
!=
nil
{
return
nil
,
err
}
}
metrics
:=
&
metricsapi
.
PodMetricsList
{}
err
=
metricsv1beta1api
.
Convert_v1beta1_PodMetricsList_To_metrics_PodMetricsList
(
versionedMetrics
,
metrics
,
nil
)
if
err
!=
nil
{
return
nil
,
err
}
return
metrics
,
nil
}
}
func
verifyEmptyMetrics
(
o
TopPodOptions
,
selector
labels
.
Selector
)
error
{
func
verifyEmptyMetrics
(
o
TopPodOptions
,
selector
labels
.
Selector
)
error
{
...
...
pkg/kubectl/cmd/top_pod_test.go
View file @
b1448adb
This diff is collapsed.
Click to expand it.
pkg/kubectl/cmd/top_test.go
View file @
b1448adb
...
@@ -29,12 +29,14 @@ import (
...
@@ -29,12 +29,14 @@ import (
"k8s.io/apimachinery/pkg/api/resource"
"k8s.io/apimachinery/pkg/api/resource"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
cmdtesting
"k8s.io/kubernetes/pkg/kubectl/cmd/testing"
cmdtesting
"k8s.io/kubernetes/pkg/kubectl/cmd/testing"
metricsapi
"k8s.io/metrics/pkg/apis/metrics/v1alpha1"
metricsv1alpha1api
"k8s.io/metrics/pkg/apis/metrics/v1alpha1"
metricsv1beta1api
"k8s.io/metrics/pkg/apis/metrics/v1beta1"
)
)
const
(
const
(
baseHeapsterServiceAddress
=
"/api/v1/namespaces/kube-system/services/http:heapster:/proxy"
baseHeapsterServiceAddress
=
"/api/v1/namespaces/kube-system/services/http:heapster:/proxy"
baseMetricsAddress
=
baseHeapsterServiceAddress
+
"/apis/metrics"
baseMetricsAddress
=
baseHeapsterServiceAddress
+
"/apis/metrics"
baseMetricsServerAddress
=
"/apis/metrics.k8s.io/v1beta1"
metricsApiVersion
=
"v1alpha1"
metricsApiVersion
=
"v1alpha1"
)
)
...
@@ -58,12 +60,12 @@ func marshallBody(metrics interface{}) (io.ReadCloser, error) {
...
@@ -58,12 +60,12 @@ func marshallBody(metrics interface{}) (io.ReadCloser, error) {
return
ioutil
.
NopCloser
(
bytes
.
NewReader
(
result
)),
nil
return
ioutil
.
NopCloser
(
bytes
.
NewReader
(
result
)),
nil
}
}
func
testNode
MetricsData
()
(
*
metrics
api
.
NodeMetricsList
,
*
v1
.
NodeList
)
{
func
testNode
V1alpha1MetricsData
()
(
*
metricsv1alpha1
api
.
NodeMetricsList
,
*
v1
.
NodeList
)
{
metrics
:=
&
metricsapi
.
NodeMetricsList
{
metrics
:=
&
metrics
v1alpha1
api
.
NodeMetricsList
{
ListMeta
:
metav1
.
ListMeta
{
ListMeta
:
metav1
.
ListMeta
{
ResourceVersion
:
"1"
,
ResourceVersion
:
"1"
,
},
},
Items
:
[]
metricsapi
.
NodeMetrics
{
Items
:
[]
metrics
v1alpha1
api
.
NodeMetrics
{
{
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
"node1"
,
ResourceVersion
:
"10"
},
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
"node1"
,
ResourceVersion
:
"10"
},
Window
:
metav1
.
Duration
{
Duration
:
time
.
Minute
},
Window
:
metav1
.
Duration
{
Duration
:
time
.
Minute
},
...
@@ -113,3 +115,59 @@ func testNodeMetricsData() (*metricsapi.NodeMetricsList, *v1.NodeList) {
...
@@ -113,3 +115,59 @@ func testNodeMetricsData() (*metricsapi.NodeMetricsList, *v1.NodeList) {
}
}
return
metrics
,
nodes
return
metrics
,
nodes
}
}
func
testNodeV1beta1MetricsData
()
(
*
metricsv1beta1api
.
NodeMetricsList
,
*
v1
.
NodeList
)
{
metrics
:=
&
metricsv1beta1api
.
NodeMetricsList
{
ListMeta
:
metav1
.
ListMeta
{
ResourceVersion
:
"1"
,
},
Items
:
[]
metricsv1beta1api
.
NodeMetrics
{
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
"node1"
,
ResourceVersion
:
"10"
,
Labels
:
map
[
string
]
string
{
"key"
:
"value"
}},
Window
:
metav1
.
Duration
{
Duration
:
time
.
Minute
},
Usage
:
v1
.
ResourceList
{
v1
.
ResourceCPU
:
*
resource
.
NewMilliQuantity
(
1
,
resource
.
DecimalSI
),
v1
.
ResourceMemory
:
*
resource
.
NewQuantity
(
2
*
(
1024
*
1024
),
resource
.
DecimalSI
),
v1
.
ResourceStorage
:
*
resource
.
NewQuantity
(
3
*
(
1024
*
1024
),
resource
.
DecimalSI
),
},
},
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
"node2"
,
ResourceVersion
:
"11"
},
Window
:
metav1
.
Duration
{
Duration
:
time
.
Minute
},
Usage
:
v1
.
ResourceList
{
v1
.
ResourceCPU
:
*
resource
.
NewMilliQuantity
(
5
,
resource
.
DecimalSI
),
v1
.
ResourceMemory
:
*
resource
.
NewQuantity
(
6
*
(
1024
*
1024
),
resource
.
DecimalSI
),
v1
.
ResourceStorage
:
*
resource
.
NewQuantity
(
7
*
(
1024
*
1024
),
resource
.
DecimalSI
),
},
},
},
}
nodes
:=
&
v1
.
NodeList
{
ListMeta
:
metav1
.
ListMeta
{
ResourceVersion
:
"15"
,
},
Items
:
[]
v1
.
Node
{
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
"node1"
,
ResourceVersion
:
"10"
},
Status
:
v1
.
NodeStatus
{
Allocatable
:
v1
.
ResourceList
{
v1
.
ResourceCPU
:
*
resource
.
NewMilliQuantity
(
10
,
resource
.
DecimalSI
),
v1
.
ResourceMemory
:
*
resource
.
NewQuantity
(
20
*
(
1024
*
1024
),
resource
.
DecimalSI
),
v1
.
ResourceStorage
:
*
resource
.
NewQuantity
(
30
*
(
1024
*
1024
),
resource
.
DecimalSI
),
},
},
},
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
"node2"
,
ResourceVersion
:
"11"
},
Status
:
v1
.
NodeStatus
{
Allocatable
:
v1
.
ResourceList
{
v1
.
ResourceCPU
:
*
resource
.
NewMilliQuantity
(
50
,
resource
.
DecimalSI
),
v1
.
ResourceMemory
:
*
resource
.
NewQuantity
(
60
*
(
1024
*
1024
),
resource
.
DecimalSI
),
v1
.
ResourceStorage
:
*
resource
.
NewQuantity
(
70
*
(
1024
*
1024
),
resource
.
DecimalSI
),
},
},
},
},
}
return
metrics
,
nodes
}
pkg/kubectl/cmd/util/BUILD
View file @
b1448adb
...
@@ -81,6 +81,7 @@ go_library(
...
@@ -81,6 +81,7 @@ go_library(
"//vendor/k8s.io/client-go/scale:go_default_library",
"//vendor/k8s.io/client-go/scale:go_default_library",
"//vendor/k8s.io/client-go/tools/clientcmd:go_default_library",
"//vendor/k8s.io/client-go/tools/clientcmd:go_default_library",
"//vendor/k8s.io/client-go/util/homedir:go_default_library",
"//vendor/k8s.io/client-go/util/homedir:go_default_library",
"//vendor/k8s.io/metrics/pkg/client/clientset_generated/clientset:go_default_library",
"//vendor/k8s.io/utils/exec:go_default_library",
"//vendor/k8s.io/utils/exec:go_default_library",
],
],
)
)
...
...
pkg/kubectl/cmd/util/clientcache.go
View file @
b1448adb
...
@@ -27,6 +27,7 @@ import (
...
@@ -27,6 +27,7 @@ import (
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
oldclient
"k8s.io/kubernetes/pkg/client/unversioned"
oldclient
"k8s.io/kubernetes/pkg/client/unversioned"
"k8s.io/kubernetes/pkg/version"
"k8s.io/kubernetes/pkg/version"
metricsclientset
"k8s.io/metrics/pkg/client/clientset_generated/clientset"
)
)
func
NewClientCache
(
loader
clientcmd
.
ClientConfig
,
discoveryClientFactory
DiscoveryClientFactory
)
*
ClientCache
{
func
NewClientCache
(
loader
clientcmd
.
ClientConfig
,
discoveryClientFactory
DiscoveryClientFactory
)
*
ClientCache
{
...
@@ -58,6 +59,7 @@ type ClientCache struct {
...
@@ -58,6 +59,7 @@ type ClientCache struct {
discoveryClient
discovery
.
DiscoveryInterface
discoveryClient
discovery
.
DiscoveryInterface
kubernetesClientCache
kubernetesClientCache
kubernetesClientCache
kubernetesClientCache
metricsClientCache
metricsClientCache
}
}
// kubernetesClientCache creates a new kubernetes.Clientset one time
// kubernetesClientCache creates a new kubernetes.Clientset one time
...
@@ -71,6 +73,17 @@ type kubernetesClientCache struct {
...
@@ -71,6 +73,17 @@ type kubernetesClientCache struct {
err
error
err
error
}
}
// metricsClientCache creates a new metricsclientset.Clientset one time
// and then returns the result for all future requests
type
metricsClientCache
struct
{
// once makes sure the client is only initialized once
once
sync
.
Once
// client is the cached client value
client
*
metricsclientset
.
Clientset
// err is the cached error value
err
error
}
// KubernetesClientSetForVersion returns a new kubernetes.Clientset. It will cache the value
// KubernetesClientSetForVersion returns a new kubernetes.Clientset. It will cache the value
// the first time it is called and return the cached value on subsequent calls.
// the first time it is called and return the cached value on subsequent calls.
// If an error is encountered the first time KubernetesClientSetForVersion is called,
// If an error is encountered the first time KubernetesClientSetForVersion is called,
...
@@ -87,6 +100,22 @@ func (c *ClientCache) KubernetesClientSetForVersion(requiredVersion *schema.Grou
...
@@ -87,6 +100,22 @@ func (c *ClientCache) KubernetesClientSetForVersion(requiredVersion *schema.Grou
return
c
.
kubernetesClientCache
.
client
,
c
.
kubernetesClientCache
.
err
return
c
.
kubernetesClientCache
.
client
,
c
.
kubernetesClientCache
.
err
}
}
// MetricsClientSetForVersion returns a new kubernetes.Clientset. It will cache the value
// the first time it is called and return the cached value on subsequent calls.
// If an error is encountered the first time MetircsClientSetForVersion is called,
// the error will be cached.
func
(
c
*
ClientCache
)
MetricsClientSetForVersion
(
requiredVersion
*
schema
.
GroupVersion
)
(
*
metricsclientset
.
Clientset
,
error
)
{
c
.
metricsClientCache
.
once
.
Do
(
func
()
{
config
,
err
:=
c
.
ClientConfigForVersion
(
requiredVersion
)
if
err
!=
nil
{
c
.
kubernetesClientCache
.
err
=
err
return
}
c
.
metricsClientCache
.
client
,
c
.
metricsClientCache
.
err
=
metricsclientset
.
NewForConfig
(
config
)
})
return
c
.
metricsClientCache
.
client
,
c
.
metricsClientCache
.
err
}
// also looks up the discovery client. We can't do this during init because the flags won't have been set
// also looks up the discovery client. We can't do this during init because the flags won't have been set
// because this is constructed pre-command execution before the command tree is
// because this is constructed pre-command execution before the command tree is
// even set up. Requires the lock to already be acquired
// even set up. Requires the lock to already be acquired
...
...
pkg/kubectl/cmd/util/factory.go
View file @
b1448adb
...
@@ -48,6 +48,7 @@ import (
...
@@ -48,6 +48,7 @@ import (
"k8s.io/kubernetes/pkg/kubectl/resource"
"k8s.io/kubernetes/pkg/kubectl/resource"
"k8s.io/kubernetes/pkg/kubectl/validation"
"k8s.io/kubernetes/pkg/kubectl/validation"
"k8s.io/kubernetes/pkg/printers"
"k8s.io/kubernetes/pkg/printers"
metricsclientset
"k8s.io/metrics/pkg/client/clientset_generated/clientset"
)
)
const
(
const
(
...
@@ -95,6 +96,9 @@ type ClientAccessFactory interface {
...
@@ -95,6 +96,9 @@ type ClientAccessFactory interface {
// KubernetesClientSet gives you back an external clientset
// KubernetesClientSet gives you back an external clientset
KubernetesClientSet
()
(
*
kubernetes
.
Clientset
,
error
)
KubernetesClientSet
()
(
*
kubernetes
.
Clientset
,
error
)
// MetricsClientSet gives you back an external clientset for the metrics API
MetricsClientSet
()
(
metricsclientset
.
Interface
,
error
)
// Returns a RESTClient for accessing Kubernetes resources or an error.
// Returns a RESTClient for accessing Kubernetes resources or an error.
RESTClient
()
(
*
restclient
.
RESTClient
,
error
)
RESTClient
()
(
*
restclient
.
RESTClient
,
error
)
// Returns a client.Config for accessing the Kubernetes server.
// Returns a client.Config for accessing the Kubernetes server.
...
...
pkg/kubectl/cmd/util/factory_client_access.go
View file @
b1448adb
...
@@ -31,6 +31,7 @@ import (
...
@@ -31,6 +31,7 @@ import (
"time"
"time"
"k8s.io/api/core/v1"
"k8s.io/api/core/v1"
metricsclientset
"k8s.io/metrics/pkg/client/clientset_generated/clientset"
"github.com/spf13/cobra"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/spf13/pflag"
...
@@ -201,6 +202,10 @@ func (f *ring0Factory) KubernetesClientSet() (*kubernetes.Clientset, error) {
...
@@ -201,6 +202,10 @@ func (f *ring0Factory) KubernetesClientSet() (*kubernetes.Clientset, error) {
return
f
.
clientCache
.
KubernetesClientSetForVersion
(
nil
)
return
f
.
clientCache
.
KubernetesClientSetForVersion
(
nil
)
}
}
func
(
f
*
ring0Factory
)
MetricsClientSet
()
(
metricsclientset
.
Interface
,
error
)
{
return
f
.
clientCache
.
MetricsClientSetForVersion
(
nil
)
}
func
(
f
*
ring0Factory
)
ClientSet
()
(
internalclientset
.
Interface
,
error
)
{
func
(
f
*
ring0Factory
)
ClientSet
()
(
internalclientset
.
Interface
,
error
)
{
return
f
.
clientCache
.
ClientSetForVersion
(
nil
)
return
f
.
clientCache
.
ClientSetForVersion
(
nil
)
}
}
...
...
pkg/kubectl/metricsutil/BUILD
View file @
b1448adb
...
@@ -23,6 +23,7 @@ go_library(
...
@@ -23,6 +23,7 @@ go_library(
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/client-go/kubernetes/typed/core/v1:go_default_library",
"//vendor/k8s.io/client-go/kubernetes/typed/core/v1:go_default_library",
"//vendor/k8s.io/metrics/pkg/apis/metrics:go_default_library",
"//vendor/k8s.io/metrics/pkg/apis/metrics/v1alpha1:go_default_library",
"//vendor/k8s.io/metrics/pkg/apis/metrics/v1alpha1:go_default_library",
],
],
)
)
...
...
pkg/kubectl/metricsutil/metrics_client.go
View file @
b1448adb
...
@@ -26,7 +26,8 @@ import (
...
@@ -26,7 +26,8 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/schema"
corev1
"k8s.io/client-go/kubernetes/typed/core/v1"
corev1
"k8s.io/client-go/kubernetes/typed/core/v1"
"k8s.io/kubernetes/pkg/apis/core/validation"
"k8s.io/kubernetes/pkg/apis/core/validation"
metricsapi
"k8s.io/metrics/pkg/apis/metrics/v1alpha1"
metricsapi
"k8s.io/metrics/pkg/apis/metrics"
metricsv1alpha1api
"k8s.io/metrics/pkg/apis/metrics/v1alpha1"
)
)
const
(
const
(
...
@@ -97,67 +98,73 @@ func nodeMetricsUrl(name string) (string, error) {
...
@@ -97,67 +98,73 @@ func nodeMetricsUrl(name string) (string, error) {
return
fmt
.
Sprintf
(
"%s/nodes/%s"
,
metricsRoot
,
name
),
nil
return
fmt
.
Sprintf
(
"%s/nodes/%s"
,
metricsRoot
,
name
),
nil
}
}
func
(
cli
*
HeapsterMetricsClient
)
GetNodeMetrics
(
nodeName
string
,
selector
string
)
(
[]
metricsapi
.
NodeMetrics
,
error
)
{
func
(
cli
*
HeapsterMetricsClient
)
GetNodeMetrics
(
nodeName
string
,
selector
string
)
(
*
metricsapi
.
NodeMetricsList
,
error
)
{
params
:=
map
[
string
]
string
{
"labelSelector"
:
selector
}
params
:=
map
[
string
]
string
{
"labelSelector"
:
selector
}
path
,
err
:=
nodeMetricsUrl
(
nodeName
)
path
,
err
:=
nodeMetricsUrl
(
nodeName
)
if
err
!=
nil
{
if
err
!=
nil
{
return
[]
metricsapi
.
NodeMetrics
{}
,
err
return
nil
,
err
}
}
resultRaw
,
err
:=
GetHeapsterMetrics
(
cli
,
path
,
params
)
resultRaw
,
err
:=
GetHeapsterMetrics
(
cli
,
path
,
params
)
if
err
!=
nil
{
if
err
!=
nil
{
return
[]
metricsapi
.
NodeMetrics
{}
,
err
return
nil
,
err
}
}
metrics
:=
make
([]
metricsapi
.
NodeMetrics
,
0
)
versionedMetrics
:=
metricsv1alpha1api
.
NodeMetricsList
{}
if
len
(
nodeName
)
==
0
{
if
len
(
nodeName
)
==
0
{
metricsList
:=
metricsapi
.
NodeMetricsList
{}
err
=
json
.
Unmarshal
(
resultRaw
,
&
versionedMetrics
)
err
=
json
.
Unmarshal
(
resultRaw
,
&
metricsList
)
if
err
!=
nil
{
if
err
!=
nil
{
return
[]
metricsapi
.
NodeMetrics
{}
,
fmt
.
Errorf
(
"failed to unmarshall heapster response: %v"
,
err
)
return
nil
,
fmt
.
Errorf
(
"failed to unmarshall heapster response: %v"
,
err
)
}
}
metrics
=
append
(
metrics
,
metricsList
.
Items
...
)
}
else
{
}
else
{
var
singleMetric
metricsapi
.
NodeMetrics
var
singleMetric
metrics
v1alpha1
api
.
NodeMetrics
err
=
json
.
Unmarshal
(
resultRaw
,
&
singleMetric
)
err
=
json
.
Unmarshal
(
resultRaw
,
&
singleMetric
)
if
err
!=
nil
{
if
err
!=
nil
{
return
[]
metricsapi
.
NodeMetrics
{}
,
fmt
.
Errorf
(
"failed to unmarshall heapster response: %v"
,
err
)
return
nil
,
fmt
.
Errorf
(
"failed to unmarshall heapster response: %v"
,
err
)
}
}
metrics
=
append
(
metrics
,
singleMetric
)
versionedMetrics
.
Items
=
[]
metricsv1alpha1api
.
NodeMetrics
{
singleMetric
}
}
metrics
:=
&
metricsapi
.
NodeMetricsList
{}
err
=
metricsv1alpha1api
.
Convert_v1alpha1_NodeMetricsList_To_metrics_NodeMetricsList
(
&
versionedMetrics
,
metrics
,
nil
)
if
err
!=
nil
{
return
nil
,
err
}
}
return
metrics
,
nil
return
metrics
,
nil
}
}
func
(
cli
*
HeapsterMetricsClient
)
GetPodMetrics
(
namespace
string
,
podName
string
,
allNamespaces
bool
,
selector
labels
.
Selector
)
(
[]
metricsapi
.
PodMetrics
,
error
)
{
func
(
cli
*
HeapsterMetricsClient
)
GetPodMetrics
(
namespace
string
,
podName
string
,
allNamespaces
bool
,
selector
labels
.
Selector
)
(
*
metricsapi
.
PodMetricsList
,
error
)
{
if
allNamespaces
{
if
allNamespaces
{
namespace
=
metav1
.
NamespaceAll
namespace
=
metav1
.
NamespaceAll
}
}
path
,
err
:=
podMetricsUrl
(
namespace
,
podName
)
path
,
err
:=
podMetricsUrl
(
namespace
,
podName
)
if
err
!=
nil
{
if
err
!=
nil
{
return
[]
metricsapi
.
PodMetrics
{}
,
err
return
nil
,
err
}
}
params
:=
map
[
string
]
string
{
"labelSelector"
:
selector
.
String
()}
params
:=
map
[
string
]
string
{
"labelSelector"
:
selector
.
String
()}
allMetrics
:=
make
([]
metricsapi
.
PodMetrics
,
0
)
versionedMetrics
:=
metricsv1alpha1api
.
PodMetricsList
{}
resultRaw
,
err
:=
GetHeapsterMetrics
(
cli
,
path
,
params
)
resultRaw
,
err
:=
GetHeapsterMetrics
(
cli
,
path
,
params
)
if
err
!=
nil
{
if
err
!=
nil
{
return
[]
metricsapi
.
PodMetrics
{}
,
err
return
nil
,
err
}
}
if
len
(
podName
)
==
0
{
if
len
(
podName
)
==
0
{
metrics
:=
metricsapi
.
PodMetricsList
{}
err
=
json
.
Unmarshal
(
resultRaw
,
&
versionedMetrics
)
err
=
json
.
Unmarshal
(
resultRaw
,
&
metrics
)
if
err
!=
nil
{
if
err
!=
nil
{
return
[]
metricsapi
.
PodMetrics
{}
,
fmt
.
Errorf
(
"failed to unmarshall heapster response: %v"
,
err
)
return
nil
,
fmt
.
Errorf
(
"failed to unmarshall heapster response: %v"
,
err
)
}
}
allMetrics
=
append
(
allMetrics
,
metrics
.
Items
...
)
}
else
{
}
else
{
var
singleMetric
metricsapi
.
PodMetrics
var
singleMetric
metrics
v1alpha1
api
.
PodMetrics
err
=
json
.
Unmarshal
(
resultRaw
,
&
singleMetric
)
err
=
json
.
Unmarshal
(
resultRaw
,
&
singleMetric
)
if
err
!=
nil
{
if
err
!=
nil
{
return
[]
metricsapi
.
PodMetrics
{}
,
fmt
.
Errorf
(
"failed to unmarshall heapster response: %v"
,
err
)
return
nil
,
fmt
.
Errorf
(
"failed to unmarshall heapster response: %v"
,
err
)
}
}
allMetrics
=
append
(
allMetrics
,
singleMetric
)
versionedMetrics
.
Items
=
[]
metricsv1alpha1api
.
PodMetrics
{
singleMetric
}
}
}
return
allMetrics
,
nil
metrics
:=
&
metricsapi
.
PodMetricsList
{}
err
=
metricsv1alpha1api
.
Convert_v1alpha1_PodMetricsList_To_metrics_PodMetricsList
(
&
versionedMetrics
,
metrics
,
nil
)
if
err
!=
nil
{
return
nil
,
err
}
return
metrics
,
nil
}
}
func
GetHeapsterMetrics
(
cli
*
HeapsterMetricsClient
,
path
string
,
params
map
[
string
]
string
)
([]
byte
,
error
)
{
func
GetHeapsterMetrics
(
cli
*
HeapsterMetricsClient
,
path
string
,
params
map
[
string
]
string
)
([]
byte
,
error
)
{
...
...
pkg/kubectl/metricsutil/metrics_printer.go
View file @
b1448adb
...
@@ -25,7 +25,7 @@ import (
...
@@ -25,7 +25,7 @@ import (
"k8s.io/apimachinery/pkg/api/resource"
"k8s.io/apimachinery/pkg/api/resource"
"k8s.io/kubernetes/pkg/api/legacyscheme"
"k8s.io/kubernetes/pkg/api/legacyscheme"
"k8s.io/kubernetes/pkg/printers"
"k8s.io/kubernetes/pkg/printers"
metricsapi
"k8s.io/metrics/pkg/apis/metrics
/v1alpha1
"
metricsapi
"k8s.io/metrics/pkg/apis/metrics"
)
)
var
(
var
(
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment