Merge pull request #674 from abhi/master

Removing DAD config and updating plugins to v0.7.0
This commit is contained in:
Lantao Liu 2018-03-16 16:32:01 -07:00 committed by GitHub
commit 948d3132c9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 160 additions and 343 deletions

View File

@ -78,9 +78,6 @@ type PluginConfig struct {
StatsCollectPeriod int `toml:"stats_collect_period" json:"statsCollectPeriod,omitempty"` StatsCollectPeriod int `toml:"stats_collect_period" json:"statsCollectPeriod,omitempty"`
// SystemdCgroup enables systemd cgroup support. // SystemdCgroup enables systemd cgroup support.
SystemdCgroup bool `toml:"systemd_cgroup" json:"systemdCgroup,omitempty"` SystemdCgroup bool `toml:"systemd_cgroup" json:"systemdCgroup,omitempty"`
// EnableIPv6DAD enables IPv6 DAD.
// TODO(random-liu): Use optimistic_dad when it's GA.
EnableIPv6DAD bool `toml:"enable_ipv6_dad" json:"enableIPv6DAD,omitempty"`
} }
// Config contains all configurations for cri server. // Config contains all configurations for cri server.
@ -115,7 +112,6 @@ func DefaultConfig() PluginConfig {
SandboxImage: "gcr.io/google_containers/pause:3.0", SandboxImage: "gcr.io/google_containers/pause:3.0",
StatsCollectPeriod: 10, StatsCollectPeriod: 10,
SystemdCgroup: false, SystemdCgroup: false,
EnableIPv6DAD: false,
Registry: Registry{ Registry: Registry{
Mirrors: map[string]Mirror{ Mirrors: map[string]Mirror{
"docker.io": { "docker.io": {

View File

@ -19,7 +19,6 @@ package server
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"os/exec"
"path" "path"
"path/filepath" "path/filepath"
"strconv" "strconv"
@ -37,7 +36,6 @@ import (
"github.com/opencontainers/selinux/go-selinux/label" "github.com/opencontainers/selinux/go-selinux/label"
"golang.org/x/net/context" "golang.org/x/net/context"
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2" runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
"k8s.io/kubernetes/pkg/util/sysctl"
"github.com/containerd/cri/pkg/store" "github.com/containerd/cri/pkg/store"
imagestore "github.com/containerd/cri/pkg/store/image" imagestore "github.com/containerd/cri/pkg/store/image"
@ -400,38 +398,6 @@ func newSpecGenerator(spec *runtimespec.Spec) generate.Generator {
return g return g
} }
// disableNetNSDAD disables duplicate address detection in the network namespace.
// DAD has a negative affect on sandbox start latency, since we have to wait
// a second or more for the addresses to leave the "tentative" state.
func disableNetNSDAD(ns string) error {
dad := "net/ipv6/conf/default/accept_dad"
sysctlBin, err := exec.LookPath("sysctl")
if err != nil {
return fmt.Errorf("could not find sysctl binary: %v", err)
}
nsenterBin, err := exec.LookPath("nsenter")
if err != nil {
return fmt.Errorf("could not find nsenter binary: %v", err)
}
// If the sysctl doesn't exist, it means ipv6 is disabled.
if _, err := sysctl.New().GetSysctl(dad); err != nil {
return nil
}
output, err := exec.Command(nsenterBin,
fmt.Sprintf("--net=%s", ns), "-F", "--",
sysctlBin, "-w", fmt.Sprintf("%s=%s", dad, "0"),
).CombinedOutput()
if err != nil {
return fmt.Errorf("failed to write sysctl %q - output: %s, error: %s",
dad, output, err)
}
return nil
}
func getPodCNILabels(id string, config *runtime.PodSandboxConfig) map[string]string { func getPodCNILabels(id string, config *runtime.PodSandboxConfig) map[string]string {
return map[string]string{ return map[string]string{
"K8S_POD_NAMESPACE": config.GetMetadata().GetNamespace(), "K8S_POD_NAMESPACE": config.GetMetadata().GetNamespace(),

View File

@ -107,21 +107,11 @@ func (c *criContainerdService) RunPodSandbox(ctx context.Context, r *runtime.Run
sandbox.NetNSPath = "" sandbox.NetNSPath = ""
} }
}() }()
if !c.config.EnableIPv6DAD {
// It's a known issue that IPv6 DAD increases sandbox start latency by several seconds.
// Disable it when it's not enabled to avoid the latency.
// See:
// * https://github.com/kubernetes/kubernetes/issues/54651
// * https://www.agwa.name/blog/post/beware_the_ipv6_dad_race_condition
if err := disableNetNSDAD(sandbox.NetNSPath); err != nil {
return nil, fmt.Errorf("failed to disable DAD for sandbox %q: %v", id, err)
}
}
// Setup network for sandbox. // Setup network for sandbox.
// Certain VM based solutions like clear containers (Issue containerd/cri-containerd#524) // Certain VM based solutions like clear containers (Issue containerd/cri-containerd#524)
// rely on the assumption that CRI shim will not be querying the network namespace to check the // rely on the assumption that CRI shim will not be querying the network namespace to check the
// network states such as IP. // network states such as IP.
// In furture runtime implementation should avoid relying on CRI shim implementation details. // In future runtime implementation should avoid relying on CRI shim implementation details.
// In this case however caching the IP will add a subtle performance enhancement by avoiding // In this case however caching the IP will add a subtle performance enhancement by avoiding
// calls to network namespace of the pod to query the IP of the veth interface on every // calls to network namespace of the pod to query the IP of the veth interface on every
// SandboxStatus request. // SandboxStatus request.

View File

@ -11,7 +11,7 @@ github.com/containerd/go-runc bcb223a061a3dd7de1a89c0b402a60f4dd9bd307
github.com/containerd/go-cni f2d7272f12d045b16ed924f50e91f9f9cecc55a7 github.com/containerd/go-cni f2d7272f12d045b16ed924f50e91f9f9cecc55a7
github.com/containerd/typeurl f6943554a7e7e88b3c14aad190bf05932da84788 github.com/containerd/typeurl f6943554a7e7e88b3c14aad190bf05932da84788
github.com/containernetworking/cni v0.6.0 github.com/containernetworking/cni v0.6.0
github.com/containernetworking/plugins v0.6.0 github.com/containernetworking/plugins v0.7.0
github.com/coreos/go-systemd 48702e0da86bd25e76cfef347e2adeb434a0d0a6 github.com/coreos/go-systemd 48702e0da86bd25e76cfef347e2adeb434a0d0a6
github.com/davecgh/go-spew v1.1.0 github.com/davecgh/go-spew v1.1.0
github.com/docker/distribution b38e5838b7b2f2ad48e06ec4b500011976080621 github.com/docker/distribution b38e5838b7b2f2ad48e06ec4b500011976080621

View File

@ -1,4 +1,5 @@
[![Build Status](https://travis-ci.org/containernetworking/plugins.svg?branch=master)](https://travis-ci.org/containernetworking/plugins) [![Linux Build Status](https://travis-ci.org/containernetworking/plugins.svg?branch=master)](https://travis-ci.org/containernetworking/plugins)
[![Windows Build Status](https://ci.appveyor.com/api/projects/status/kcuubx0chr76ev86/branch/master?svg=true)](https://ci.appveyor.com/project/cni-bot/plugins/branch/master)
# plugins # plugins
Some CNI network plugins, maintained by the containernetworking team. For more information, see the individual READMEs. Some CNI network plugins, maintained by the containernetworking team. For more information, see the individual READMEs.

View File

@ -1,178 +0,0 @@
// Copyright 2015 CNI authors
//
// 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 ns
import (
"fmt"
"os"
"runtime"
"sync"
"syscall"
)
type NetNS interface {
// Executes the passed closure in this object's network namespace,
// attempting to restore the original namespace before returning.
// However, since each OS thread can have a different network namespace,
// and Go's thread scheduling is highly variable, callers cannot
// guarantee any specific namespace is set unless operations that
// require that namespace are wrapped with Do(). Also, no code called
// from Do() should call runtime.UnlockOSThread(), or the risk
// of executing code in an incorrect namespace will be greater. See
// https://github.com/golang/go/wiki/LockOSThread for further details.
Do(toRun func(NetNS) error) error
// Sets the current network namespace to this object's network namespace.
// Note that since Go's thread scheduling is highly variable, callers
// cannot guarantee the requested namespace will be the current namespace
// after this function is called; to ensure this wrap operations that
// require the namespace with Do() instead.
Set() error
// Returns the filesystem path representing this object's network namespace
Path() string
// Returns a file descriptor representing this object's network namespace
Fd() uintptr
// Cleans up this instance of the network namespace; if this instance
// is the last user the namespace will be destroyed
Close() error
}
type netNS struct {
file *os.File
mounted bool
closed bool
}
// netNS implements the NetNS interface
var _ NetNS = &netNS{}
const (
// https://github.com/torvalds/linux/blob/master/include/uapi/linux/magic.h
NSFS_MAGIC = 0x6e736673
PROCFS_MAGIC = 0x9fa0
)
type NSPathNotExistErr struct{ msg string }
func (e NSPathNotExistErr) Error() string { return e.msg }
type NSPathNotNSErr struct{ msg string }
func (e NSPathNotNSErr) Error() string { return e.msg }
func IsNSorErr(nspath string) error {
stat := syscall.Statfs_t{}
if err := syscall.Statfs(nspath, &stat); err != nil {
if os.IsNotExist(err) {
err = NSPathNotExistErr{msg: fmt.Sprintf("failed to Statfs %q: %v", nspath, err)}
} else {
err = fmt.Errorf("failed to Statfs %q: %v", nspath, err)
}
return err
}
switch stat.Type {
case PROCFS_MAGIC, NSFS_MAGIC:
return nil
default:
return NSPathNotNSErr{msg: fmt.Sprintf("unknown FS magic on %q: %x", nspath, stat.Type)}
}
}
// Returns an object representing the namespace referred to by @path
func GetNS(nspath string) (NetNS, error) {
err := IsNSorErr(nspath)
if err != nil {
return nil, err
}
fd, err := os.Open(nspath)
if err != nil {
return nil, err
}
return &netNS{file: fd}, nil
}
func (ns *netNS) Path() string {
return ns.file.Name()
}
func (ns *netNS) Fd() uintptr {
return ns.file.Fd()
}
func (ns *netNS) errorIfClosed() error {
if ns.closed {
return fmt.Errorf("%q has already been closed", ns.file.Name())
}
return nil
}
func (ns *netNS) Do(toRun func(NetNS) error) error {
if err := ns.errorIfClosed(); err != nil {
return err
}
containedCall := func(hostNS NetNS) error {
threadNS, err := GetCurrentNS()
if err != nil {
return fmt.Errorf("failed to open current netns: %v", err)
}
defer threadNS.Close()
// switch to target namespace
if err = ns.Set(); err != nil {
return fmt.Errorf("error switching to ns %v: %v", ns.file.Name(), err)
}
defer threadNS.Set() // switch back
return toRun(hostNS)
}
// save a handle to current network namespace
hostNS, err := GetCurrentNS()
if err != nil {
return fmt.Errorf("Failed to open current namespace: %v", err)
}
defer hostNS.Close()
var wg sync.WaitGroup
wg.Add(1)
var innerError error
go func() {
defer wg.Done()
runtime.LockOSThread()
innerError = containedCall(hostNS)
}()
wg.Wait()
return innerError
}
// WithNetNSPath executes the passed closure under the given network
// namespace, restoring the original namespace afterwards.
func WithNetNSPath(nspath string, toRun func(NetNS) error) error {
ns, err := GetNS(nspath)
if err != nil {
return err
}
defer ns.Close()
return ns.Do(toRun)
}

View File

@ -21,6 +21,7 @@ import (
"path" "path"
"runtime" "runtime"
"sync" "sync"
"syscall"
"golang.org/x/sys/unix" "golang.org/x/sys/unix"
) )
@ -147,3 +148,158 @@ func (ns *netNS) Set() error {
return nil return nil
} }
type NetNS interface {
// Executes the passed closure in this object's network namespace,
// attempting to restore the original namespace before returning.
// However, since each OS thread can have a different network namespace,
// and Go's thread scheduling is highly variable, callers cannot
// guarantee any specific namespace is set unless operations that
// require that namespace are wrapped with Do(). Also, no code called
// from Do() should call runtime.UnlockOSThread(), or the risk
// of executing code in an incorrect namespace will be greater. See
// https://github.com/golang/go/wiki/LockOSThread for further details.
Do(toRun func(NetNS) error) error
// Sets the current network namespace to this object's network namespace.
// Note that since Go's thread scheduling is highly variable, callers
// cannot guarantee the requested namespace will be the current namespace
// after this function is called; to ensure this wrap operations that
// require the namespace with Do() instead.
Set() error
// Returns the filesystem path representing this object's network namespace
Path() string
// Returns a file descriptor representing this object's network namespace
Fd() uintptr
// Cleans up this instance of the network namespace; if this instance
// is the last user the namespace will be destroyed
Close() error
}
type netNS struct {
file *os.File
mounted bool
closed bool
}
// netNS implements the NetNS interface
var _ NetNS = &netNS{}
const (
// https://github.com/torvalds/linux/blob/master/include/uapi/linux/magic.h
NSFS_MAGIC = 0x6e736673
PROCFS_MAGIC = 0x9fa0
)
type NSPathNotExistErr struct{ msg string }
func (e NSPathNotExistErr) Error() string { return e.msg }
type NSPathNotNSErr struct{ msg string }
func (e NSPathNotNSErr) Error() string { return e.msg }
func IsNSorErr(nspath string) error {
stat := syscall.Statfs_t{}
if err := syscall.Statfs(nspath, &stat); err != nil {
if os.IsNotExist(err) {
err = NSPathNotExistErr{msg: fmt.Sprintf("failed to Statfs %q: %v", nspath, err)}
} else {
err = fmt.Errorf("failed to Statfs %q: %v", nspath, err)
}
return err
}
switch stat.Type {
case PROCFS_MAGIC, NSFS_MAGIC:
return nil
default:
return NSPathNotNSErr{msg: fmt.Sprintf("unknown FS magic on %q: %x", nspath, stat.Type)}
}
}
// Returns an object representing the namespace referred to by @path
func GetNS(nspath string) (NetNS, error) {
err := IsNSorErr(nspath)
if err != nil {
return nil, err
}
fd, err := os.Open(nspath)
if err != nil {
return nil, err
}
return &netNS{file: fd}, nil
}
func (ns *netNS) Path() string {
return ns.file.Name()
}
func (ns *netNS) Fd() uintptr {
return ns.file.Fd()
}
func (ns *netNS) errorIfClosed() error {
if ns.closed {
return fmt.Errorf("%q has already been closed", ns.file.Name())
}
return nil
}
func (ns *netNS) Do(toRun func(NetNS) error) error {
if err := ns.errorIfClosed(); err != nil {
return err
}
containedCall := func(hostNS NetNS) error {
threadNS, err := GetCurrentNS()
if err != nil {
return fmt.Errorf("failed to open current netns: %v", err)
}
defer threadNS.Close()
// switch to target namespace
if err = ns.Set(); err != nil {
return fmt.Errorf("error switching to ns %v: %v", ns.file.Name(), err)
}
defer threadNS.Set() // switch back
return toRun(hostNS)
}
// save a handle to current network namespace
hostNS, err := GetCurrentNS()
if err != nil {
return fmt.Errorf("Failed to open current namespace: %v", err)
}
defer hostNS.Close()
var wg sync.WaitGroup
wg.Add(1)
var innerError error
go func() {
defer wg.Done()
runtime.LockOSThread()
innerError = containedCall(hostNS)
}()
wg.Wait()
return innerError
}
// WithNetNSPath executes the passed closure under the given network
// namespace, restoring the original namespace afterwards.
func WithNetNSPath(nspath string, toRun func(NetNS) error) error {
ns, err := GetNS(nspath)
if err != nil {
return err
}
defer ns.Close()
return ns.Do(toRun)
}

View File

@ -1,36 +0,0 @@
// Copyright 2015-2017 CNI authors
//
// 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.
// +build !linux
package ns
import "github.com/containernetworking/cni/pkg/types"
// Returns an object representing the current OS thread's network namespace
func GetCurrentNS() (NetNS, error) {
return nil, types.NotImplementedError
}
func NewNS() (NetNS, error) {
return nil, types.NotImplementedError
}
func (ns *netNS) Close() error {
return types.NotImplementedError
}
func (ns *netNS) Set() error {
return types.NotImplementedError
}

View File

@ -1,78 +0,0 @@
/*
Copyright 2015 The Kubernetes Authors.
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 sysctl
import (
"io/ioutil"
"path"
"strconv"
"strings"
)
const (
sysctlBase = "/proc/sys"
VmOvercommitMemory = "vm/overcommit_memory"
VmPanicOnOOM = "vm/panic_on_oom"
KernelPanic = "kernel/panic"
KernelPanicOnOops = "kernel/panic_on_oops"
RootMaxKeys = "kernel/keys/root_maxkeys"
RootMaxBytes = "kernel/keys/root_maxbytes"
VmOvercommitMemoryAlways = 1 // kernel performs no memory over-commit handling
VmPanicOnOOMInvokeOOMKiller = 0 // kernel calls the oom_killer function when OOM occurs
KernelPanicOnOopsAlways = 1 // kernel panics on kernel oops
KernelPanicRebootTimeout = 10 // seconds after a panic for the kernel to reboot
RootMaxKeysSetting = 1000000 // Needed since docker creates a new key per container
RootMaxBytesSetting = RootMaxKeysSetting * 25 // allocate 25 bytes per key * number of MaxKeys
)
// An injectable interface for running sysctl commands.
type Interface interface {
// GetSysctl returns the value for the specified sysctl setting
GetSysctl(sysctl string) (int, error)
// SetSysctl modifies the specified sysctl flag to the new value
SetSysctl(sysctl string, newVal int) error
}
// New returns a new Interface for accessing sysctl
func New() Interface {
return &procSysctl{}
}
// procSysctl implements Interface by reading and writing files under /proc/sys
type procSysctl struct {
}
// GetSysctl returns the value for the specified sysctl setting
func (_ *procSysctl) GetSysctl(sysctl string) (int, error) {
data, err := ioutil.ReadFile(path.Join(sysctlBase, sysctl))
if err != nil {
return -1, err
}
val, err := strconv.Atoi(strings.Trim(string(data), " \n"))
if err != nil {
return -1, err
}
return val, nil
}
// SetSysctl modifies the specified sysctl flag to the new value
func (_ *procSysctl) SetSysctl(sysctl string, newVal int) error {
return ioutil.WriteFile(path.Join(sysctlBase, sysctl), []byte(strconv.Itoa(newVal)), 0640)
}