metrics_grabber.go 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. /*
  2. Copyright 2015 The Kubernetes Authors.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package metrics
  14. import (
  15. "fmt"
  16. "time"
  17. "k8s.io/kubernetes/pkg/api"
  18. client "k8s.io/kubernetes/pkg/client/unversioned"
  19. "k8s.io/kubernetes/pkg/fields"
  20. "k8s.io/kubernetes/pkg/master/ports"
  21. "k8s.io/kubernetes/pkg/util/system"
  22. "github.com/golang/glog"
  23. )
  24. const (
  25. ProxyTimeout = 2 * time.Minute
  26. )
  27. type MetricsCollection struct {
  28. ApiServerMetrics ApiServerMetrics
  29. ControllerManagerMetrics ControllerManagerMetrics
  30. KubeletMetrics map[string]KubeletMetrics
  31. SchedulerMetrics SchedulerMetrics
  32. }
  33. type MetricsGrabber struct {
  34. client *client.Client
  35. grabFromApiServer bool
  36. grabFromControllerManager bool
  37. grabFromKubelets bool
  38. grabFromScheduler bool
  39. masterName string
  40. registeredMaster bool
  41. }
  42. func NewMetricsGrabber(c *client.Client, kubelets bool, scheduler bool, controllers bool, apiServer bool) (*MetricsGrabber, error) {
  43. registeredMaster := false
  44. masterName := ""
  45. nodeList, err := c.Nodes().List(api.ListOptions{})
  46. if err != nil {
  47. return nil, err
  48. }
  49. if len(nodeList.Items) < 1 {
  50. glog.Warning("Can't find any Nodes in the API server to grab metrics from")
  51. }
  52. for _, node := range nodeList.Items {
  53. if system.IsMasterNode(&node) {
  54. registeredMaster = true
  55. masterName = node.Name
  56. break
  57. }
  58. }
  59. if !registeredMaster {
  60. scheduler = false
  61. controllers = false
  62. glog.Warningf("Master node is not registered. Grabbing metrics from Scheduler and ControllerManager is disabled.")
  63. }
  64. return &MetricsGrabber{
  65. client: c,
  66. grabFromApiServer: apiServer,
  67. grabFromControllerManager: controllers,
  68. grabFromKubelets: kubelets,
  69. grabFromScheduler: scheduler,
  70. masterName: masterName,
  71. registeredMaster: registeredMaster,
  72. }, nil
  73. }
  74. func (g *MetricsGrabber) GrabFromKubelet(nodeName string) (KubeletMetrics, error) {
  75. nodes, err := g.client.Nodes().List(api.ListOptions{FieldSelector: fields.Set{api.ObjectNameField: nodeName}.AsSelector()})
  76. if err != nil {
  77. return KubeletMetrics{}, err
  78. }
  79. if len(nodes.Items) != 1 {
  80. return KubeletMetrics{}, fmt.Errorf("Error listing nodes with name %v, got %v", nodeName, nodes.Items)
  81. }
  82. kubeletPort := nodes.Items[0].Status.DaemonEndpoints.KubeletEndpoint.Port
  83. return g.grabFromKubeletInternal(nodeName, int(kubeletPort))
  84. }
  85. func (g *MetricsGrabber) grabFromKubeletInternal(nodeName string, kubeletPort int) (KubeletMetrics, error) {
  86. if kubeletPort <= 0 || kubeletPort > 65535 {
  87. return KubeletMetrics{}, fmt.Errorf("Invalid Kubelet port %v. Skipping Kubelet's metrics gathering.", kubeletPort)
  88. }
  89. output, err := g.getMetricsFromNode(nodeName, int(kubeletPort))
  90. if err != nil {
  91. return KubeletMetrics{}, err
  92. }
  93. return parseKubeletMetrics(output)
  94. }
  95. func (g *MetricsGrabber) GrabFromScheduler() (SchedulerMetrics, error) {
  96. if !g.registeredMaster {
  97. return SchedulerMetrics{}, fmt.Errorf("Master's Kubelet is not registered. Skipping Scheduler's metrics gathering.")
  98. }
  99. output, err := g.getMetricsFromPod(fmt.Sprintf("%v-%v", "kube-scheduler", g.masterName), api.NamespaceSystem, ports.SchedulerPort)
  100. if err != nil {
  101. return SchedulerMetrics{}, err
  102. }
  103. return parseSchedulerMetrics(output)
  104. }
  105. func (g *MetricsGrabber) GrabFromControllerManager() (ControllerManagerMetrics, error) {
  106. if !g.registeredMaster {
  107. return ControllerManagerMetrics{}, fmt.Errorf("Master's Kubelet is not registered. Skipping ControllerManager's metrics gathering.")
  108. }
  109. output, err := g.getMetricsFromPod(fmt.Sprintf("%v-%v", "kube-controller-manager", g.masterName), api.NamespaceSystem, ports.ControllerManagerPort)
  110. if err != nil {
  111. return ControllerManagerMetrics{}, err
  112. }
  113. return parseControllerManagerMetrics(output)
  114. }
  115. func (g *MetricsGrabber) GrabFromApiServer() (ApiServerMetrics, error) {
  116. output, err := g.getMetricsFromApiServer()
  117. if err != nil {
  118. return ApiServerMetrics{}, nil
  119. }
  120. return parseApiServerMetrics(output)
  121. }
  122. func (g *MetricsGrabber) Grab() (MetricsCollection, error) {
  123. result := MetricsCollection{}
  124. var errs []error
  125. if g.grabFromApiServer {
  126. metrics, err := g.GrabFromApiServer()
  127. if err != nil {
  128. errs = append(errs, err)
  129. } else {
  130. result.ApiServerMetrics = metrics
  131. }
  132. }
  133. if g.grabFromScheduler {
  134. metrics, err := g.GrabFromScheduler()
  135. if err != nil {
  136. errs = append(errs, err)
  137. } else {
  138. result.SchedulerMetrics = metrics
  139. }
  140. }
  141. if g.grabFromControllerManager {
  142. metrics, err := g.GrabFromControllerManager()
  143. if err != nil {
  144. errs = append(errs, err)
  145. } else {
  146. result.ControllerManagerMetrics = metrics
  147. }
  148. }
  149. if g.grabFromKubelets {
  150. result.KubeletMetrics = make(map[string]KubeletMetrics)
  151. nodes, err := g.client.Nodes().List(api.ListOptions{})
  152. if err != nil {
  153. errs = append(errs, err)
  154. } else {
  155. for _, node := range nodes.Items {
  156. kubeletPort := node.Status.DaemonEndpoints.KubeletEndpoint.Port
  157. metrics, err := g.grabFromKubeletInternal(node.Name, int(kubeletPort))
  158. if err != nil {
  159. errs = append(errs, err)
  160. }
  161. result.KubeletMetrics[node.Name] = metrics
  162. }
  163. }
  164. }
  165. if len(errs) > 0 {
  166. return MetricsCollection{}, fmt.Errorf("Errors while grabbing metrics: %v", errs)
  167. }
  168. return result, nil
  169. }