Merge pull request #78665 from benmoss/automated-cherry-pick-of-#78594-upstream-release-1.14

Automated cherry pick of #78594: Fix memory leak from not closing hcs container handles
k3s-v1.14.4
Kubernetes Prow Robot 2019-06-19 03:34:33 -07:00 committed by GitHub
commit 40238163d1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 24 additions and 9 deletions

View File

@ -19,6 +19,7 @@ limitations under the License.
package stats package stats
import ( import (
"fmt"
"time" "time"
"github.com/Microsoft/hcsshim" "github.com/Microsoft/hcsshim"
@ -40,18 +41,11 @@ func (p *criStatsProvider) listContainerNetworkStats() (map[string]*statsapi.Net
stats := make(map[string]*statsapi.NetworkStats) stats := make(map[string]*statsapi.NetworkStats)
for _, c := range containers { for _, c := range containers {
container, err := hcsshim.OpenContainer(c.ID) cstats, err := fetchContainerStats(c)
if err != nil { if err != nil {
klog.V(4).Infof("Failed to open container %q with error '%v', continue to get stats for other containers", c.ID, err) klog.V(4).Infof("Failed to fetch statistics for container %q with error '%v', continue to get stats for other containers", c.ID, err)
continue continue
} }
cstats, err := container.Statistics()
if err != nil {
klog.V(4).Infof("Failed to get statistics for container %q with error '%v', continue to get stats for other containers", c.ID, err)
continue
}
if len(cstats.Network) > 0 { if len(cstats.Network) > 0 {
stats[c.ID] = hcsStatsToNetworkStats(cstats.Timestamp, cstats.Network) stats[c.ID] = hcsStatsToNetworkStats(cstats.Timestamp, cstats.Network)
} }
@ -60,6 +54,27 @@ func (p *criStatsProvider) listContainerNetworkStats() (map[string]*statsapi.Net
return stats, nil return stats, nil
} }
func fetchContainerStats(c hcsshim.ContainerProperties) (stats hcsshim.Statistics, err error) {
var (
container hcsshim.Container
)
container, err = hcsshim.OpenContainer(c.ID)
if err != nil {
return
}
defer func() {
if closeErr := container.Close(); closeErr != nil {
if err != nil {
err = fmt.Errorf("failed to close container after error %v; close error: %v", err, closeErr)
} else {
err = closeErr
}
}
}()
return container.Statistics()
}
// hcsStatsToNetworkStats converts hcsshim.Statistics.Network to statsapi.NetworkStats // hcsStatsToNetworkStats converts hcsshim.Statistics.Network to statsapi.NetworkStats
func hcsStatsToNetworkStats(timestamp time.Time, hcsStats []hcsshim.NetworkStats) *statsapi.NetworkStats { func hcsStatsToNetworkStats(timestamp time.Time, hcsStats []hcsshim.NetworkStats) *statsapi.NetworkStats {
result := &statsapi.NetworkStats{ result := &statsapi.NetworkStats{