diff --git a/pkg/kubelet/dockertools/manager.go b/pkg/kubelet/dockertools/manager.go index 64f3ae833df..0929da9fc3a 100644 --- a/pkg/kubelet/dockertools/manager.go +++ b/pkg/kubelet/dockertools/manager.go @@ -1858,7 +1858,7 @@ func (dm *DockerManager) SyncPod(pod *api.Pod, _ api.PodStatus, podStatus *kubec return } if !usesHostNetwork(pod) && dm.configureHairpinMode { - if err = hairpin.SetUpContainer(podInfraContainer.State.Pid, "eth0"); err != nil { + if err = hairpin.SetUpContainer(podInfraContainer.State.Pid, network.DefaultInterfaceName); err != nil { glog.Warningf("Hairpin setup failed for pod %q: %v", format.Pod(pod), err) } } diff --git a/pkg/kubelet/network/cni/cni.go b/pkg/kubelet/network/cni/cni.go index 6fa7615348f..584baeed490 100644 --- a/pkg/kubelet/network/cni/cni.go +++ b/pkg/kubelet/network/cni/cni.go @@ -34,7 +34,6 @@ const ( CNIPluginName = "cni" DefaultNetDir = "/etc/cni/net.d" DefaultCNIDir = "/opt/cni/bin" - DefaultInterfaceName = "eth0" VendorCNIDirTemplate = "%s/opt/%s/bin" ) @@ -143,7 +142,7 @@ func (plugin *cniNetworkPlugin) Status(namespace string, name string, id kubecon if !ok { return nil, fmt.Errorf("CNI execution called on non-docker runtime") } - ipStr, err := runtime.GetContainerIP(string(id), DefaultInterfaceName) + ipStr, err := runtime.GetContainerIP(string(id), network.DefaultInterfaceName) if err != nil { return nil, err } @@ -196,7 +195,7 @@ func buildCNIRuntimeConf(podName string, podNs string, podInfraContainerID kubec rt := &libcni.RuntimeConf{ ContainerID: podInfraContainerID.ID, NetNS: podNetnsPath, - IfName: DefaultInterfaceName, + IfName: network.DefaultInterfaceName, Args: [][2]string{ {"K8S_POD_NAMESPACE", podNs}, {"K8S_POD_NAME", podName}, diff --git a/pkg/kubelet/network/kubenet/kubenet_linux.go b/pkg/kubelet/network/kubenet/kubenet_linux.go index 4eebe27e397..0cae97a29ad 100644 --- a/pkg/kubelet/network/kubenet/kubenet_linux.go +++ b/pkg/kubelet/network/kubenet/kubenet_linux.go @@ -35,10 +35,9 @@ import ( ) const ( - KubenetPluginName = "kubenet" - BridgeName = "cbr0" - DefaultCNIDir = "/opt/cni/bin" - DefaultInterfaceName = "eth0" + KubenetPluginName = "kubenet" + BridgeName = "cbr0" + DefaultCNIDir = "/opt/cni/bin" ) type kubenetNetworkPlugin struct { @@ -139,7 +138,7 @@ func (plugin *kubenetNetworkPlugin) Event(name string, details map[string]interf // Set bridge address to first address in IPNet cidr.IP.To4()[3] += 1 - json := fmt.Sprintf(NET_CONFIG_TEMPLATE, BridgeName, plugin.MTU, DefaultInterfaceName, podCIDR, cidr.IP.String()) + json := fmt.Sprintf(NET_CONFIG_TEMPLATE, BridgeName, plugin.MTU, network.DefaultInterfaceName, podCIDR, cidr.IP.String()) plugin.netConfig, err = libcni.ConfFromBytes([]byte(json)) if err == nil { glog.V(5).Infof("CNI network config:\n%s", json) @@ -282,6 +281,6 @@ func buildCNIRuntimeConf(podName string, podNs string, podInfraContainerID kubec return &libcni.RuntimeConf{ ContainerID: podInfraContainerID.ID, NetNS: podNetnsPath, - IfName: DefaultInterfaceName, + IfName: network.DefaultInterfaceName, } } diff --git a/pkg/kubelet/network/network.go b/pkg/kubelet/network/network.go new file mode 100644 index 00000000000..1396d415585 --- /dev/null +++ b/pkg/kubelet/network/network.go @@ -0,0 +1,20 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package network + +// TODO: Consider making this value configurable. +const DefaultInterfaceName = "eth0" diff --git a/pkg/kubelet/server/stats/summary.go b/pkg/kubelet/server/stats/summary.go index 809cb4cdb4c..6098c81bc7e 100644 --- a/pkg/kubelet/server/stats/summary.go +++ b/pkg/kubelet/server/stats/summary.go @@ -27,6 +27,7 @@ import ( "k8s.io/kubernetes/pkg/kubelet/cm" "k8s.io/kubernetes/pkg/kubelet/dockertools" "k8s.io/kubernetes/pkg/kubelet/leaky" + "k8s.io/kubernetes/pkg/kubelet/network" "k8s.io/kubernetes/pkg/types" "github.com/golang/glog" @@ -107,7 +108,7 @@ func (sb *summaryBuilder) build() (*stats.Summary, error) { NodeName: sb.node.Name, CPU: rootStats.CPU, Memory: rootStats.Memory, - Network: sb.containerInfoV2ToNetworkStats(&rootInfo), + Network: sb.containerInfoV2ToNetworkStats("node:"+sb.node.Name, &rootInfo), Fs: &stats.FsStats{ AvailableBytes: &sb.rootFsInfo.Available, CapacityBytes: &sb.rootFsInfo.Capacity, @@ -201,7 +202,7 @@ func (sb *summaryBuilder) buildSummaryPods() []stats.PodStats { containerName := dockertools.GetContainerName(cinfo.Spec.Labels) if containerName == leaky.PodInfraContainerName { // Special case for infrastructure container which is hidden from the user and has network stats - podStats.Network = sb.containerInfoV2ToNetworkStats(&cinfo) + podStats.Network = sb.containerInfoV2ToNetworkStats("pod:"+ref.Namespace+"_"+ref.Name, &cinfo) podStats.StartTime = unversioned.NewTime(cinfo.Spec.CreationTime) } else { podStats.Containers = append(podStats.Containers, sb.containerInfoV2ToStats(containerName, &cinfo)) @@ -281,7 +282,7 @@ func (sb *summaryBuilder) containerInfoV2ToStats( return cStats } -func (sb *summaryBuilder) containerInfoV2ToNetworkStats(info *cadvisorapiv2.ContainerInfo) *stats.NetworkStats { +func (sb *summaryBuilder) containerInfoV2ToNetworkStats(name string, info *cadvisorapiv2.ContainerInfo) *stats.NetworkStats { if !info.Spec.HasNetwork { return nil } @@ -289,26 +290,19 @@ func (sb *summaryBuilder) containerInfoV2ToNetworkStats(info *cadvisorapiv2.Cont if !found { return nil } - var ( - rxBytes uint64 - rxErrors uint64 - txBytes uint64 - txErrors uint64 - ) - // TODO(stclair): check for overflow for _, inter := range cstat.Network.Interfaces { - rxBytes += inter.RxBytes - rxErrors += inter.RxErrors - txBytes += inter.TxBytes - txErrors += inter.TxErrors - } - return &stats.NetworkStats{ - Time: unversioned.NewTime(cstat.Timestamp), - RxBytes: &rxBytes, - RxErrors: &rxErrors, - TxBytes: &txBytes, - TxErrors: &txErrors, + if inter.Name == network.DefaultInterfaceName { + return &stats.NetworkStats{ + Time: unversioned.NewTime(cstat.Timestamp), + RxBytes: &inter.RxBytes, + RxErrors: &inter.RxErrors, + TxBytes: &inter.TxBytes, + TxErrors: &inter.TxErrors, + } + } } + glog.Warningf("Missing default interface %q for s", network.DefaultInterfaceName, name) + return nil } func (sb *summaryBuilder) containerInfoV2ToUserDefinedMetrics(info *cadvisorapiv2.ContainerInfo) []stats.UserDefinedMetric { diff --git a/pkg/kubelet/server/stats/summary_test.go b/pkg/kubelet/server/stats/summary_test.go index 7ded64c0e14..e67bda8251b 100644 --- a/pkg/kubelet/server/stats/summary_test.go +++ b/pkg/kubelet/server/stats/summary_test.go @@ -265,10 +265,17 @@ func summaryTestContainerInfo(seed int, podName string, podNamespace string, con }, Network: &v2.NetworkStats{ Interfaces: []v1.InterfaceStats{{ + Name: "eth0", RxBytes: uint64(seed + offsetNetRxBytes), RxErrors: uint64(seed + offsetNetRxErrors), TxBytes: uint64(seed + offsetNetTxBytes), TxErrors: uint64(seed + offsetNetTxErrors), + }, { + Name: "cbr0", + RxBytes: 100, + RxErrors: 100, + TxBytes: 100, + TxErrors: 100, }}, }, CustomMetrics: generateCustomMetrics(spec.CustomMetrics),