mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 03:41:45 +00:00
Merge pull request #5030 from simon3z/nodeinfo
Add support for fetching node collected information
This commit is contained in:
commit
9aa744925e
@ -97,6 +97,10 @@ func (fakeKubeletClient) GetPodStatus(host, podNamespace, podID string) (api.Pod
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func (fakeKubeletClient) GetNodeInfo(host string) (api.NodeInfo, error) {
|
||||
return api.NodeInfo{}, nil
|
||||
}
|
||||
|
||||
func (fakeKubeletClient) HealthCheck(host string) (probe.Result, error) {
|
||||
return probe.Success, nil
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ func init() {
|
||||
&Service{},
|
||||
&NodeList{},
|
||||
&Node{},
|
||||
&NodeInfo{},
|
||||
&Status{},
|
||||
&Endpoints{},
|
||||
&EndpointsList{},
|
||||
@ -70,6 +71,7 @@ func (*ServiceList) IsAnAPIObject() {}
|
||||
func (*Endpoints) IsAnAPIObject() {}
|
||||
func (*EndpointsList) IsAnAPIObject() {}
|
||||
func (*Node) IsAnAPIObject() {}
|
||||
func (*NodeInfo) IsAnAPIObject() {}
|
||||
func (*NodeList) IsAnAPIObject() {}
|
||||
func (*Binding) IsAnAPIObject() {}
|
||||
func (*Status) IsAnAPIObject() {}
|
||||
|
@ -788,6 +788,14 @@ type NodeSpec struct {
|
||||
ExternalID string `json:"externalID,omitempty"`
|
||||
}
|
||||
|
||||
// NodeSystemInfo is a set of ids/uuids to uniquely identify the node.
|
||||
type NodeSystemInfo struct {
|
||||
// MachineID is the machine-id reported by the node
|
||||
MachineID string `json:"machineID"`
|
||||
// SystemUUID is the system-uuid reported by the node
|
||||
SystemUUID string `json:"systemUUID"`
|
||||
}
|
||||
|
||||
// NodeStatus is information about the current status of a node.
|
||||
type NodeStatus struct {
|
||||
// NodePhase is the current lifecycle phase of the node.
|
||||
@ -796,6 +804,17 @@ type NodeStatus struct {
|
||||
Conditions []NodeCondition `json:"conditions,omitempty"`
|
||||
// Queried from cloud provider, if available.
|
||||
Addresses []NodeAddress `json:"addresses,omitempty"`
|
||||
// NodeSystemInfo is a set of ids/uuids to uniquely identify the node
|
||||
NodeInfo NodeSystemInfo `json:"nodeInfo,omitempty"`
|
||||
}
|
||||
|
||||
// NodeInfo is the information collected on the node.
|
||||
type NodeInfo struct {
|
||||
TypeMeta `json:",inline"`
|
||||
// Capacity represents the available resources of a node
|
||||
Capacity ResourceList `json:"capacity,omitempty"`
|
||||
// NodeSystemInfo is a set of ids/uuids to uniquely identify the node
|
||||
NodeSystemInfo `json:",inline,omitempty"`
|
||||
}
|
||||
|
||||
type NodePhase string
|
||||
|
@ -699,6 +699,9 @@ func init() {
|
||||
if err := s.Convert(&in.Status.Addresses, &out.Status.Addresses, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.Convert(&in.Status.NodeInfo, &out.Status.NodeInfo, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, address := range in.Status.Addresses {
|
||||
if address.Type == newer.NodeLegacyHostIP {
|
||||
@ -728,6 +731,9 @@ func init() {
|
||||
if err := s.Convert(&in.Status.Addresses, &out.Status.Addresses, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.Convert(&in.Status.NodeInfo, &out.Status.NodeInfo, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if in.HostIP != "" {
|
||||
newer.AddToNodeAddresses(&out.Status.Addresses,
|
||||
|
@ -43,6 +43,7 @@ func init() {
|
||||
&EndpointsList{},
|
||||
&Minion{},
|
||||
&MinionList{},
|
||||
&NodeInfo{},
|
||||
&Binding{},
|
||||
&Status{},
|
||||
&Event{},
|
||||
@ -77,6 +78,7 @@ func (*ServiceList) IsAnAPIObject() {}
|
||||
func (*Endpoints) IsAnAPIObject() {}
|
||||
func (*EndpointsList) IsAnAPIObject() {}
|
||||
func (*Minion) IsAnAPIObject() {}
|
||||
func (*NodeInfo) IsAnAPIObject() {}
|
||||
func (*MinionList) IsAnAPIObject() {}
|
||||
func (*Binding) IsAnAPIObject() {}
|
||||
func (*Status) IsAnAPIObject() {}
|
||||
|
@ -618,6 +618,14 @@ type EndpointsList struct {
|
||||
Items []Endpoints `json:"items" description:"list of service endpoint lists"`
|
||||
}
|
||||
|
||||
// NodeSystemInfo is a set of ids/uuids to uniquely identify the node.
|
||||
type NodeSystemInfo struct {
|
||||
// MachineID is the machine-id reported by the node
|
||||
MachineID string `json:"machineID" description:"machine id is the machine-id reported by the node"`
|
||||
// SystemUUID is the system-uuid reported by the node
|
||||
SystemUUID string `json:"systemUUID" description:"system uuid is the system-uuid reported by the node"`
|
||||
}
|
||||
|
||||
// NodeStatus is information about the current status of a node.
|
||||
type NodeStatus struct {
|
||||
// NodePhase is the current lifecycle phase of the node.
|
||||
@ -626,6 +634,17 @@ type NodeStatus struct {
|
||||
Conditions []NodeCondition `json:"conditions,omitempty" description:"conditions is an array of current node conditions"`
|
||||
// Queried from cloud provider, if available.
|
||||
Addresses []NodeAddress `json:"addresses,omitempty" description:"list of addresses reachable to the node"`
|
||||
// NodeSystemInfo is a set of ids/uuids to uniquely identify the node
|
||||
NodeInfo NodeSystemInfo `json:"nodeInfo,omitempty" description:"node identity is a set of ids/uuids to uniquely identify the node"`
|
||||
}
|
||||
|
||||
// NodeInfo is the information collected on the node.
|
||||
type NodeInfo struct {
|
||||
TypeMeta `json:",inline"`
|
||||
// Capacity represents the available resources.
|
||||
Capacity ResourceList `json:"capacity,omitempty" description:"resource capacity of a node represented as a map of resource name to quantity of resource"`
|
||||
// NodeSystemInfo is a set of ids/uuids to uniquely identify the node
|
||||
NodeSystemInfo `json:",inline,omitempty" description:"node identity is a set of ids/uuids to uniquely identify the node"`
|
||||
}
|
||||
|
||||
type NodePhase string
|
||||
|
@ -619,6 +619,9 @@ func init() {
|
||||
if err := s.Convert(&in.Status.Addresses, &out.Status.Addresses, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.Convert(&in.Status.NodeInfo, &out.Status.NodeInfo, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, address := range in.Status.Addresses {
|
||||
if address.Type == newer.NodeLegacyHostIP {
|
||||
@ -648,6 +651,9 @@ func init() {
|
||||
if err := s.Convert(&in.Status.Addresses, &out.Status.Addresses, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.Convert(&in.Status.NodeInfo, &out.Status.NodeInfo, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if in.HostIP != "" {
|
||||
newer.AddToNodeAddresses(&out.Status.Addresses,
|
||||
|
@ -42,6 +42,7 @@ func init() {
|
||||
&Endpoints{},
|
||||
&EndpointsList{},
|
||||
&Minion{},
|
||||
&NodeInfo{},
|
||||
&MinionList{},
|
||||
&Binding{},
|
||||
&Status{},
|
||||
@ -77,6 +78,7 @@ func (*ServiceList) IsAnAPIObject() {}
|
||||
func (*Endpoints) IsAnAPIObject() {}
|
||||
func (*EndpointsList) IsAnAPIObject() {}
|
||||
func (*Minion) IsAnAPIObject() {}
|
||||
func (*NodeInfo) IsAnAPIObject() {}
|
||||
func (*MinionList) IsAnAPIObject() {}
|
||||
func (*Binding) IsAnAPIObject() {}
|
||||
func (*Status) IsAnAPIObject() {}
|
||||
|
@ -623,6 +623,14 @@ type EndpointsList struct {
|
||||
Items []Endpoints `json:"items" description:"list of service endpoint lists"`
|
||||
}
|
||||
|
||||
// NodeSystemInfo is a set of ids/uuids to uniquely identify the node.
|
||||
type NodeSystemInfo struct {
|
||||
// MachineID is the machine-id reported by the node
|
||||
MachineID string `json:"machineID" description:"machine id is the machine-id reported by the node"`
|
||||
// SystemUUID is the system-uuid reported by the node
|
||||
SystemUUID string `json:"systemUUID" description:"system uuid is the system-uuid reported by the node"`
|
||||
}
|
||||
|
||||
// NodeStatus is information about the current status of a node.
|
||||
//
|
||||
// https://github.com/GoogleCloudPlatform/kubernetes/blob/master/docs/node.md#node-status
|
||||
@ -633,6 +641,17 @@ type NodeStatus struct {
|
||||
Conditions []NodeCondition `json:"conditions,omitempty" description:"conditions is an array of current node conditions"`
|
||||
// Queried from cloud provider, if available.
|
||||
Addresses []NodeAddress `json:"addresses,omitempty" description:"list of addresses reachable to the node"`
|
||||
// NodeSystemInfo is a set of ids/uuids to uniquely identify the node
|
||||
NodeInfo NodeSystemInfo `json:"nodeInfo,omitempty" description:"node identity is a set of ids/uuids to uniquely identify the node"`
|
||||
}
|
||||
|
||||
// NodeInfo is the information collected on the node.
|
||||
type NodeInfo struct {
|
||||
TypeMeta `json:",inline"`
|
||||
// Capacity represents the available resources.
|
||||
Capacity ResourceList `json:"capacity,omitempty" description:"resource capacity of a node represented as a map of resource name to quantity of resource"`
|
||||
// NodeSystemInfo is a set of ids/uuids to uniquely identify the node
|
||||
NodeSystemInfo `json:",inline,omitempty" description:"node identity is a set of ids/uuids to uniquely identify the node"`
|
||||
}
|
||||
|
||||
// Described the current lifecycle phase of a node.
|
||||
|
@ -40,6 +40,7 @@ func init() {
|
||||
&Endpoints{},
|
||||
&EndpointsList{},
|
||||
&Node{},
|
||||
&NodeInfo{},
|
||||
&NodeList{},
|
||||
&Binding{},
|
||||
&Status{},
|
||||
@ -75,6 +76,7 @@ func (*ServiceList) IsAnAPIObject() {}
|
||||
func (*Endpoints) IsAnAPIObject() {}
|
||||
func (*EndpointsList) IsAnAPIObject() {}
|
||||
func (*Node) IsAnAPIObject() {}
|
||||
func (*NodeInfo) IsAnAPIObject() {}
|
||||
func (*NodeList) IsAnAPIObject() {}
|
||||
func (*Binding) IsAnAPIObject() {}
|
||||
func (*Status) IsAnAPIObject() {}
|
||||
|
@ -819,6 +819,14 @@ type NodeSpec struct {
|
||||
ExternalID string `json:"externalID,omitempty" description:"external ID assigned to the node by some machine database (e.g. a cloud provider)"`
|
||||
}
|
||||
|
||||
// NodeSystemInfo is a set of ids/uuids to uniquely identify the node.
|
||||
type NodeSystemInfo struct {
|
||||
// MachineID is the machine-id reported by the node
|
||||
MachineID string `json:"machineID"`
|
||||
// SystemUUID is the system-uuid reported by the node
|
||||
SystemUUID string `json:"systemUUID"`
|
||||
}
|
||||
|
||||
// NodeStatus is information about the current status of a node.
|
||||
type NodeStatus struct {
|
||||
// NodePhase is the current lifecycle phase of the node.
|
||||
@ -827,6 +835,17 @@ type NodeStatus struct {
|
||||
Conditions []NodeCondition `json:"conditions,omitempty" description:"list of node conditions observed"`
|
||||
// Queried from cloud provider, if available.
|
||||
Addresses []NodeAddress `json:"addresses,omitempty" description:"list of addresses reachable to the node"`
|
||||
// NodeSystemInfo is a set of ids/uuids to uniquely identify the node
|
||||
NodeInfo NodeSystemInfo `json:"nodeInfo,omitempty"`
|
||||
}
|
||||
|
||||
// NodeInfo is the information collected on the node.
|
||||
type NodeInfo struct {
|
||||
TypeMeta `json:",inline"`
|
||||
// Capacity represents the available resources of a node
|
||||
Capacity ResourceList `json:"capacity,omitempty"`
|
||||
// NodeSystemInfo is a set of ids/uuids to uniquely identify the node
|
||||
NodeSystemInfo `json:",inline,omitempty"`
|
||||
}
|
||||
|
||||
type NodePhase string
|
||||
|
@ -22,12 +22,14 @@ import (
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/probe"
|
||||
httprobe "github.com/GoogleCloudPlatform/kubernetes/pkg/probe/http"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
)
|
||||
|
||||
// ErrPodInfoNotAvailable may be returned when the requested pod info is not available.
|
||||
@ -37,6 +39,7 @@ var ErrPodInfoNotAvailable = errors.New("no pod info available")
|
||||
type KubeletClient interface {
|
||||
KubeletHealthChecker
|
||||
PodInfoGetter
|
||||
NodeInfoGetter
|
||||
}
|
||||
|
||||
// KubeletHealthchecker is an interface for healthchecking kubelets
|
||||
@ -52,6 +55,10 @@ type PodInfoGetter interface {
|
||||
GetPodStatus(host, podNamespace, podID string) (api.PodStatusResult, error)
|
||||
}
|
||||
|
||||
type NodeInfoGetter interface {
|
||||
GetNodeInfo(host string) (api.NodeInfo, error)
|
||||
}
|
||||
|
||||
// HTTPKubeletClient is the default implementation of PodInfoGetter and KubeletHealthchecker, accesses the kubelet over HTTP.
|
||||
type HTTPKubeletClient struct {
|
||||
Client *http.Client
|
||||
@ -85,57 +92,61 @@ func NewKubeletClient(config *KubeletConfig) (KubeletClient, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *HTTPKubeletClient) url(host string) string {
|
||||
scheme := "http://"
|
||||
func (c *HTTPKubeletClient) url(host, path, query string) string {
|
||||
scheme := "http"
|
||||
if c.EnableHttps {
|
||||
scheme = "https://"
|
||||
scheme = "https"
|
||||
}
|
||||
|
||||
return fmt.Sprintf(
|
||||
"%s%s",
|
||||
scheme,
|
||||
net.JoinHostPort(host, strconv.FormatUint(uint64(c.Port), 10)))
|
||||
return (&url.URL{
|
||||
Scheme: scheme,
|
||||
Host: net.JoinHostPort(host, strconv.FormatUint(uint64(c.Port), 10)),
|
||||
Path: path,
|
||||
RawQuery: query,
|
||||
}).String()
|
||||
}
|
||||
|
||||
// GetPodInfo gets information about the specified pod.
|
||||
func (c *HTTPKubeletClient) GetPodStatus(host, podNamespace, podID string) (api.PodStatusResult, error) {
|
||||
request, err := http.NewRequest(
|
||||
"GET",
|
||||
fmt.Sprintf(
|
||||
"%s/api/v1beta1/podInfo?podID=%s&podNamespace=%s",
|
||||
c.url(host),
|
||||
podID,
|
||||
podNamespace),
|
||||
nil)
|
||||
status := api.PodStatusResult{}
|
||||
if err != nil {
|
||||
return status, err
|
||||
}
|
||||
response, err := c.Client.Do(request)
|
||||
if err != nil {
|
||||
return status, err
|
||||
}
|
||||
defer response.Body.Close()
|
||||
query := url.Values{"podID": {podID}, "podNamespace": {podNamespace}}
|
||||
response, err := c.getEntity(host, "/api/v1beta1/podInfo", query.Encode(), &status)
|
||||
if response.StatusCode == http.StatusNotFound {
|
||||
return status, ErrPodInfoNotAvailable
|
||||
}
|
||||
return status, err
|
||||
}
|
||||
|
||||
// GetNodeInfo gets information about the specified node.
|
||||
func (c *HTTPKubeletClient) GetNodeInfo(host string) (api.NodeInfo, error) {
|
||||
info := api.NodeInfo{}
|
||||
_, err := c.getEntity(host, "/api/v1beta1/nodeInfo", "", &info)
|
||||
return info, err
|
||||
}
|
||||
|
||||
func (c *HTTPKubeletClient) getEntity(host, path, query string, entity runtime.Object) (*http.Response, error) {
|
||||
request, err := http.NewRequest("GET", c.url(host, path, query), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
response, err := c.Client.Do(request)
|
||||
if err != nil {
|
||||
return response, err
|
||||
}
|
||||
defer response.Body.Close()
|
||||
if response.StatusCode >= 300 || response.StatusCode < 200 {
|
||||
return status, fmt.Errorf("kubelet %q server responded with HTTP error code %d for pod %s/%s", host, response.StatusCode, podNamespace, podID)
|
||||
return response, fmt.Errorf("kubelet %q server responded with HTTP error code %d", host, response.StatusCode)
|
||||
}
|
||||
body, err := ioutil.ReadAll(response.Body)
|
||||
if err != nil {
|
||||
return status, err
|
||||
return response, err
|
||||
}
|
||||
// Check that this data can be unmarshalled
|
||||
err = latest.Codec.DecodeInto(body, &status)
|
||||
if err != nil {
|
||||
return status, err
|
||||
}
|
||||
return status, nil
|
||||
err = latest.Codec.DecodeInto(body, entity)
|
||||
return response, err
|
||||
}
|
||||
|
||||
func (c *HTTPKubeletClient) HealthCheck(host string) (probe.Result, error) {
|
||||
return httprobe.DoHTTPProbe(fmt.Sprintf("%s/healthz", c.url(host)), c.Client)
|
||||
return httprobe.DoHTTPProbe(c.url(host, "/healthz", ""), c.Client)
|
||||
}
|
||||
|
||||
// FakeKubeletClient is a fake implementation of KubeletClient which returns an error
|
||||
@ -148,6 +159,11 @@ func (c FakeKubeletClient) GetPodStatus(host, podNamespace string, podID string)
|
||||
return api.PodStatusResult{}, errors.New("Not Implemented")
|
||||
}
|
||||
|
||||
// GetNodeInfo is a fake implementation of PodInfoGetter.GetNodeInfo
|
||||
func (c FakeKubeletClient) GetNodeInfo(host string) (api.NodeInfo, error) {
|
||||
return api.NodeInfo{}, errors.New("Not Implemented")
|
||||
}
|
||||
|
||||
func (c FakeKubeletClient) HealthCheck(host string) (probe.Result, error) {
|
||||
return probe.Unknown, errors.New("Not Implemented")
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ type NodeController struct {
|
||||
staticResources *api.NodeResources
|
||||
nodes []string
|
||||
kubeClient client.Interface
|
||||
kubeletClient client.KubeletHealthChecker
|
||||
kubeletClient client.KubeletClient
|
||||
registerRetryCount int
|
||||
podEvictionTimeout time.Duration
|
||||
lookupIP func(host string) ([]net.IP, error)
|
||||
@ -61,7 +61,7 @@ func NewNodeController(
|
||||
nodes []string,
|
||||
staticResources *api.NodeResources,
|
||||
kubeClient client.Interface,
|
||||
kubeletClient client.KubeletHealthChecker,
|
||||
kubeletClient client.KubeletClient,
|
||||
registerRetryCount int,
|
||||
podEvictionTimeout time.Duration) *NodeController {
|
||||
return &NodeController{
|
||||
@ -216,7 +216,7 @@ func (s *NodeController) SyncNodeStatus() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
nodes = s.DoChecks(nodes)
|
||||
nodes = s.UpdateNodesStatus(nodes)
|
||||
nodes, err = s.PopulateAddresses(nodes)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -301,13 +301,16 @@ func (s *NodeController) PopulateAddresses(nodes *api.NodeList) (*api.NodeList,
|
||||
return nodes, nil
|
||||
}
|
||||
|
||||
// DoChecks performs health checking for given list of nodes.
|
||||
func (s *NodeController) DoChecks(nodes *api.NodeList) *api.NodeList {
|
||||
// UpdateNodesStatus performs health checking for given list of nodes.
|
||||
func (s *NodeController) UpdateNodesStatus(nodes *api.NodeList) *api.NodeList {
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(len(nodes.Items))
|
||||
for i := range nodes.Items {
|
||||
go func(node *api.Node) {
|
||||
node.Status.Conditions = s.DoCheck(node)
|
||||
if err := s.updateNodeInfo(node); err != nil {
|
||||
glog.Errorf("Can't collect information for node %s: %v", node.Name, err)
|
||||
}
|
||||
wg.Done()
|
||||
}(&nodes.Items[i])
|
||||
}
|
||||
@ -315,6 +318,18 @@ func (s *NodeController) DoChecks(nodes *api.NodeList) *api.NodeList {
|
||||
return nodes
|
||||
}
|
||||
|
||||
func (s *NodeController) updateNodeInfo(node *api.Node) error {
|
||||
nodeInfo, err := s.kubeletClient.GetNodeInfo(node.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for key, value := range nodeInfo.Capacity {
|
||||
node.Spec.Capacity[key] = value
|
||||
}
|
||||
node.Status.NodeInfo = nodeInfo.NodeSystemInfo
|
||||
return nil
|
||||
}
|
||||
|
||||
// DoCheck performs health checking for given node.
|
||||
func (s *NodeController) DoCheck(node *api.Node) []api.NodeCondition {
|
||||
var conditions []api.NodeCondition
|
||||
|
@ -124,6 +124,10 @@ func (c *FakeKubeletClient) GetPodStatus(host, podNamespace, podID string) (api.
|
||||
return api.PodStatusResult{}, errors.New("Not Implemented")
|
||||
}
|
||||
|
||||
func (c *FakeKubeletClient) GetNodeInfo(host string) (api.NodeInfo, error) {
|
||||
return api.NodeInfo{}, errors.New("Not Implemented")
|
||||
}
|
||||
|
||||
func (c *FakeKubeletClient) HealthCheck(host string) (probe.Result, error) {
|
||||
return c.Status, c.Err
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ import (
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/healthz"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/httplog"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
@ -46,8 +47,9 @@ import (
|
||||
|
||||
// Server is a http.Handler which exposes kubelet functionality over HTTP.
|
||||
type Server struct {
|
||||
host HostInterface
|
||||
mux *http.ServeMux
|
||||
host HostInterface
|
||||
mux *http.ServeMux
|
||||
machineInfo *cadvisorApi.MachineInfo
|
||||
}
|
||||
|
||||
type TLSOptions struct {
|
||||
@ -114,6 +116,7 @@ func (s *Server) InstallDefaultHandlers() {
|
||||
healthz.InstallHandler(s.mux)
|
||||
s.mux.HandleFunc("/podInfo", s.handlePodInfoOld)
|
||||
s.mux.HandleFunc("/api/v1beta1/podInfo", s.handlePodInfoVersioned)
|
||||
s.mux.HandleFunc("/api/v1beta1/nodeInfo", s.handleNodeInfoVersioned)
|
||||
s.mux.HandleFunc("/boundPods", s.handleBoundPods)
|
||||
s.mux.HandleFunc("/stats/", s.handleStats)
|
||||
s.mux.HandleFunc("/spec/", s.handleSpec)
|
||||
@ -329,9 +332,51 @@ func (s *Server) handleLogs(w http.ResponseWriter, req *http.Request) {
|
||||
s.host.ServeLogs(w, req)
|
||||
}
|
||||
|
||||
// getCachedMachineInfo assumes that the machine info can't change without a reboot
|
||||
func (s *Server) getCachedMachineInfo() (*cadvisorApi.MachineInfo, error) {
|
||||
if s.machineInfo == nil {
|
||||
info, err := s.host.GetMachineInfo()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.machineInfo = info
|
||||
}
|
||||
return s.machineInfo, nil
|
||||
}
|
||||
|
||||
// handleNodeInfoVersioned handles node info requests against the Kubelet.
|
||||
func (s *Server) handleNodeInfoVersioned(w http.ResponseWriter, req *http.Request) {
|
||||
info, err := s.getCachedMachineInfo()
|
||||
if err != nil {
|
||||
s.error(w, err)
|
||||
return
|
||||
}
|
||||
capacity := api.ResourceList{
|
||||
api.ResourceCPU: *resource.NewMilliQuantity(
|
||||
int64(info.NumCores*1000),
|
||||
resource.DecimalSI),
|
||||
api.ResourceMemory: *resource.NewQuantity(
|
||||
info.MemoryCapacity,
|
||||
resource.BinarySI),
|
||||
}
|
||||
data, err := json.Marshal(api.NodeInfo{
|
||||
Capacity: capacity,
|
||||
NodeSystemInfo: api.NodeSystemInfo{
|
||||
MachineID: info.MachineID,
|
||||
SystemUUID: info.SystemUUID,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
s.error(w, err)
|
||||
return
|
||||
}
|
||||
w.Header().Add("Content-type", "application/json")
|
||||
w.Write(data)
|
||||
}
|
||||
|
||||
// handleSpec handles spec requests against the Kubelet.
|
||||
func (s *Server) handleSpec(w http.ResponseWriter, req *http.Request) {
|
||||
info, err := s.host.GetMachineInfo()
|
||||
info, err := s.getCachedMachineInfo()
|
||||
if err != nil {
|
||||
s.error(w, err)
|
||||
return
|
||||
|
Loading…
Reference in New Issue
Block a user