Update cri to 4b4b2abb2e.
Signed-off-by: Lantao Liu <lantaol@google.com>
This commit is contained in:
6
vendor/github.com/containerd/cri/README.md
generated
vendored
6
vendor/github.com/containerd/cri/README.md
generated
vendored
@@ -1,7 +1,7 @@
|
||||
# cri
|
||||
<p align="center">
|
||||
<img src="https://kubernetes.io/images/favicon.png" width="50" height="50">
|
||||
<img src="https://containerd.io/img/containerd-dark.png" width="200" >
|
||||
<img src="https://containerd.io/img/logos/icon/black/containerd-icon-black.png" width="50" >
|
||||
</p>
|
||||
|
||||
*Note: The standalone `cri-containerd` binary is end-of-life. `cri-containerd` is
|
||||
@@ -36,6 +36,7 @@ See [test dashboard](https://k8s-testgrid.appspot.com/sig-node-containerd)
|
||||
| v1.0.0-alpha.x | | 1.7, 1.8 | v1alpha1 |
|
||||
| v1.0.0-beta.x | | 1.9 | v1alpha1 |
|
||||
| End-Of-Life | v1.1 | 1.10+ | v1alpha2 |
|
||||
| | v1.2 | 1.10+ | v1alpha2 |
|
||||
| | HEAD | 1.10+ | v1alpha2 |
|
||||
|
||||
## Production Quality Cluster on GCE
|
||||
@@ -149,7 +150,8 @@ implementation.
|
||||
For sync communication we have a community slack with a #containerd channel that
|
||||
everyone is welcome to join and chat about development.
|
||||
|
||||
**Slack:** https://dockr.ly/community
|
||||
**Slack:** Catch us in the #containerd and #containerd-dev channels on dockercommunity.slack.com.
|
||||
[Click here for an invite to docker community slack.](https://join.slack.com/t/dockercommunity/shared_invite/enQtNDY4MDc1Mzc0MzIwLTgxZDBlMmM4ZGEyNDc1N2FkMzlhODJkYmE1YTVkYjM1MDE3ZjAwZjBkOGFlOTJkZjRmZGYzNjYyY2M3ZTUxYzQ)
|
||||
|
||||
## Other Communications
|
||||
As this project is tightly coupled to CRI and CRI-Tools and they are Kubernetes
|
||||
|
||||
11
vendor/github.com/containerd/cri/cri.go
generated
vendored
11
vendor/github.com/containerd/cri/cri.go
generated
vendored
@@ -36,6 +36,7 @@ import (
|
||||
imagespec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"k8s.io/klog"
|
||||
|
||||
criconfig "github.com/containerd/cri/pkg/config"
|
||||
"github.com/containerd/cri/pkg/constants"
|
||||
@@ -175,16 +176,18 @@ func getServicesOpts(ic *plugin.InitContext) ([]containerd.ServicesOpt, error) {
|
||||
// Set glog level.
|
||||
func setGLogLevel() error {
|
||||
l := logrus.GetLevel()
|
||||
if err := flag.Set("logtostderr", "true"); err != nil {
|
||||
fs := flag.NewFlagSet("klog", flag.PanicOnError)
|
||||
klog.InitFlags(fs)
|
||||
if err := fs.Set("logtostderr", "true"); err != nil {
|
||||
return err
|
||||
}
|
||||
switch l {
|
||||
case log.TraceLevel:
|
||||
return flag.Set("v", "5")
|
||||
return fs.Set("v", "5")
|
||||
case logrus.DebugLevel:
|
||||
return flag.Set("v", "4")
|
||||
return fs.Set("v", "4")
|
||||
case logrus.InfoLevel:
|
||||
return flag.Set("v", "2")
|
||||
return fs.Set("v", "2")
|
||||
// glog doesn't support following filters. Defaults to v=0.
|
||||
case logrus.WarnLevel:
|
||||
case logrus.ErrorLevel:
|
||||
|
||||
220
vendor/github.com/containerd/cri/pkg/netns/netns.go
generated
vendored
Normal file
220
vendor/github.com/containerd/cri/pkg/netns/netns.go
generated
vendored
Normal file
@@ -0,0 +1,220 @@
|
||||
/*
|
||||
Copyright 2018 The Containerd 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.
|
||||
*/
|
||||
|
||||
// Copyright 2018 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 netns
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"runtime"
|
||||
"sync"
|
||||
|
||||
cnins "github.com/containernetworking/plugins/pkg/ns"
|
||||
"github.com/docker/docker/pkg/symlink"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/sys/unix"
|
||||
|
||||
osinterface "github.com/containerd/cri/pkg/os"
|
||||
)
|
||||
|
||||
const nsRunDir = "/var/run/netns"
|
||||
|
||||
// Some of the following functions are migrated from
|
||||
// https://github.com/containernetworking/plugins/blob/master/pkg/testutils/netns_linux.go
|
||||
|
||||
// newNS creates a new persistent (bind-mounted) network namespace and returns the
|
||||
// path to the network namespace.
|
||||
func newNS() (nsPath string, err error) {
|
||||
b := make([]byte, 16)
|
||||
if _, err := rand.Reader.Read(b); err != nil {
|
||||
return "", errors.Wrap(err, "failed to generate random netns name")
|
||||
}
|
||||
|
||||
// Create the directory for mounting network namespaces
|
||||
// This needs to be a shared mountpoint in case it is mounted in to
|
||||
// other namespaces (containers)
|
||||
if err := os.MkdirAll(nsRunDir, 0755); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// create an empty file at the mount point
|
||||
nsName := fmt.Sprintf("cni-%x-%x-%x-%x-%x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:])
|
||||
nsPath = path.Join(nsRunDir, nsName)
|
||||
mountPointFd, err := os.Create(nsPath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
mountPointFd.Close()
|
||||
|
||||
defer func() {
|
||||
// Ensure the mount point is cleaned up on errors
|
||||
if err != nil {
|
||||
os.RemoveAll(nsPath) // nolint: errcheck
|
||||
}
|
||||
}()
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
|
||||
// do namespace work in a dedicated goroutine, so that we can safely
|
||||
// Lock/Unlock OSThread without upsetting the lock/unlock state of
|
||||
// the caller of this function
|
||||
go (func() {
|
||||
defer wg.Done()
|
||||
runtime.LockOSThread()
|
||||
// Don't unlock. By not unlocking, golang will kill the OS thread when the
|
||||
// goroutine is done (for go1.10+)
|
||||
|
||||
var origNS cnins.NetNS
|
||||
origNS, err = cnins.GetNS(getCurrentThreadNetNSPath())
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer origNS.Close()
|
||||
|
||||
// create a new netns on the current thread
|
||||
err = unix.Unshare(unix.CLONE_NEWNET)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Put this thread back to the orig ns, since it might get reused (pre go1.10)
|
||||
defer origNS.Set() // nolint: errcheck
|
||||
|
||||
// bind mount the netns from the current thread (from /proc) onto the
|
||||
// mount point. This causes the namespace to persist, even when there
|
||||
// are no threads in the ns.
|
||||
err = unix.Mount(getCurrentThreadNetNSPath(), nsPath, "none", unix.MS_BIND, "")
|
||||
if err != nil {
|
||||
err = errors.Wrapf(err, "failed to bind mount ns at %s", nsPath)
|
||||
}
|
||||
})()
|
||||
wg.Wait()
|
||||
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "failed to create namespace")
|
||||
}
|
||||
|
||||
return nsPath, nil
|
||||
}
|
||||
|
||||
// unmountNS unmounts the NS held by the netns object. unmountNS is idempotent.
|
||||
func unmountNS(path string) error {
|
||||
if _, err := os.Stat(path); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil
|
||||
}
|
||||
return errors.Wrap(err, "failed to stat netns")
|
||||
}
|
||||
path, err := symlink.FollowSymlinkInScope(path, "/")
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to follow symlink")
|
||||
}
|
||||
if err := osinterface.Unmount(path); err != nil && !os.IsNotExist(err) {
|
||||
return errors.Wrap(err, "failed to umount netns")
|
||||
}
|
||||
if err := os.RemoveAll(path); err != nil {
|
||||
return errors.Wrap(err, "failed to remove netns")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// getCurrentThreadNetNSPath copied from pkg/ns
|
||||
func getCurrentThreadNetNSPath() string {
|
||||
// /proc/self/ns/net returns the namespace of the main thread, not
|
||||
// of whatever thread this goroutine is running on. Make sure we
|
||||
// use the thread's net namespace since the thread is switching around
|
||||
return fmt.Sprintf("/proc/%d/task/%d/ns/net", os.Getpid(), unix.Gettid())
|
||||
}
|
||||
|
||||
// NetNS holds network namespace.
|
||||
type NetNS struct {
|
||||
path string
|
||||
}
|
||||
|
||||
// NewNetNS creates a network namespace.
|
||||
func NewNetNS() (*NetNS, error) {
|
||||
path, err := newNS()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to setup netns")
|
||||
}
|
||||
return &NetNS{path: path}, nil
|
||||
}
|
||||
|
||||
// LoadNetNS loads existing network namespace.
|
||||
func LoadNetNS(path string) *NetNS {
|
||||
return &NetNS{path: path}
|
||||
}
|
||||
|
||||
// Remove removes network namepace. Remove is idempotent, meaning it might
|
||||
// be invoked multiple times and provides consistent result.
|
||||
func (n *NetNS) Remove() error {
|
||||
return unmountNS(n.path)
|
||||
}
|
||||
|
||||
// Closed checks whether the network namespace has been closed.
|
||||
func (n *NetNS) Closed() (bool, error) {
|
||||
ns, err := cnins.GetNS(n.path)
|
||||
if err != nil {
|
||||
if _, ok := err.(cnins.NSPathNotExistErr); ok {
|
||||
// The network namespace has already been removed.
|
||||
return true, nil
|
||||
}
|
||||
if _, ok := err.(cnins.NSPathNotNSErr); ok {
|
||||
// The network namespace is not mounted, remove it.
|
||||
if err := os.RemoveAll(n.path); err != nil {
|
||||
return false, errors.Wrap(err, "remove netns")
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
return false, errors.Wrap(err, "get netns fd")
|
||||
}
|
||||
if err := ns.Close(); err != nil {
|
||||
return false, errors.Wrap(err, "close netns fd")
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// GetPath returns network namespace path for sandbox container
|
||||
func (n *NetNS) GetPath() string {
|
||||
return n.path
|
||||
}
|
||||
|
||||
// Do runs a function in the network namespace.
|
||||
func (n *NetNS) Do(f func(cnins.NetNS) error) error {
|
||||
ns, err := cnins.GetNS(n.path)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "get netns fd")
|
||||
}
|
||||
defer ns.Close() // nolint: errcheck
|
||||
return ns.Do(f)
|
||||
}
|
||||
1
vendor/github.com/containerd/cri/pkg/server/container_create.go
generated
vendored
1
vendor/github.com/containerd/cri/pkg/server/container_create.go
generated
vendored
@@ -187,6 +187,7 @@ func (c *criService) CreateContainer(ctx context.Context, r *runtime.CreateConta
|
||||
opts = append(opts, customopts.WithVolumes(mountMap))
|
||||
}
|
||||
meta.ImageRef = image.ID
|
||||
meta.StopSignal = image.ImageSpec.Config.StopSignal
|
||||
|
||||
// Get container log path.
|
||||
if config.GetLogPath() != "" {
|
||||
|
||||
26
vendor/github.com/containerd/cri/pkg/server/container_status.go
generated
vendored
26
vendor/github.com/containerd/cri/pkg/server/container_status.go
generated
vendored
@@ -24,6 +24,7 @@ import (
|
||||
"golang.org/x/net/context"
|
||||
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
||||
|
||||
"github.com/containerd/cri/pkg/store"
|
||||
containerstore "github.com/containerd/cri/pkg/store/container"
|
||||
)
|
||||
|
||||
@@ -43,17 +44,20 @@ func (c *criService) ContainerStatus(ctx context.Context, r *runtime.ContainerSt
|
||||
imageRef := container.ImageRef
|
||||
image, err := c.imageStore.Get(imageRef)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to get image %q", imageRef)
|
||||
}
|
||||
repoTags, repoDigests := parseImageReferences(image.References)
|
||||
if len(repoTags) > 0 {
|
||||
// Based on current behavior of dockershim, this field should be
|
||||
// image tag.
|
||||
spec = &runtime.ImageSpec{Image: repoTags[0]}
|
||||
}
|
||||
if len(repoDigests) > 0 {
|
||||
// Based on the CRI definition, this field will be consumed by user.
|
||||
imageRef = repoDigests[0]
|
||||
if err != store.ErrNotExist {
|
||||
return nil, errors.Wrapf(err, "failed to get image %q", imageRef)
|
||||
}
|
||||
} else {
|
||||
repoTags, repoDigests := parseImageReferences(image.References)
|
||||
if len(repoTags) > 0 {
|
||||
// Based on current behavior of dockershim, this field should be
|
||||
// image tag.
|
||||
spec = &runtime.ImageSpec{Image: repoTags[0]}
|
||||
}
|
||||
if len(repoDigests) > 0 {
|
||||
// Based on the CRI definition, this field will be consumed by user.
|
||||
imageRef = repoDigests[0]
|
||||
}
|
||||
}
|
||||
status := toCRIContainerStatus(container, spec, imageRef)
|
||||
info, err := toCRIContainerInfo(ctx, container, r.GetVerbose())
|
||||
|
||||
69
vendor/github.com/containerd/cri/pkg/server/container_stop.go
generated
vendored
69
vendor/github.com/containerd/cri/pkg/server/container_stop.go
generated
vendored
@@ -19,7 +19,6 @@ package server
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/containerd/containerd"
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
"github.com/docker/docker/pkg/signal"
|
||||
"github.com/pkg/errors"
|
||||
@@ -28,6 +27,7 @@ import (
|
||||
"golang.org/x/sys/unix"
|
||||
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
||||
|
||||
"github.com/containerd/cri/pkg/store"
|
||||
containerstore "github.com/containerd/cri/pkg/store/container"
|
||||
)
|
||||
|
||||
@@ -77,24 +77,36 @@ func (c *criService) stopContainer(ctx context.Context, container containerstore
|
||||
// We only need to kill the task. The event handler will Delete the
|
||||
// task from containerd after it handles the Exited event.
|
||||
if timeout > 0 {
|
||||
stopSignal := unix.SIGTERM
|
||||
image, err := c.imageStore.Get(container.ImageRef)
|
||||
if err != nil {
|
||||
// NOTE(random-liu): It's possible that the container is stopped,
|
||||
// deleted and image is garbage collected before this point. However,
|
||||
// the chance is really slim, even it happens, it's still fine to return
|
||||
// an error here.
|
||||
return errors.Wrapf(err, "failed to get image metadata %q", container.ImageRef)
|
||||
}
|
||||
if image.ImageSpec.Config.StopSignal != "" {
|
||||
stopSignal, err = signal.ParseSignal(image.ImageSpec.Config.StopSignal)
|
||||
stopSignal := "SIGTERM"
|
||||
if container.StopSignal != "" {
|
||||
stopSignal = container.StopSignal
|
||||
} else {
|
||||
// The image may have been deleted, and the `StopSignal` field is
|
||||
// just introduced to handle that.
|
||||
// However, for containers created before the `StopSignal` field is
|
||||
// introduced, still try to get the stop signal from the image config.
|
||||
// If the image has been deleted, logging an error and using the
|
||||
// default SIGTERM is still better than returning error and leaving
|
||||
// the container unstoppable. (See issue #990)
|
||||
// TODO(random-liu): Remove this logic when containerd 1.2 is deprecated.
|
||||
image, err := c.imageStore.Get(container.ImageRef)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to parse stop signal %q",
|
||||
image.ImageSpec.Config.StopSignal)
|
||||
if err != store.ErrNotExist {
|
||||
return errors.Wrapf(err, "failed to get image %q", container.ImageRef)
|
||||
}
|
||||
logrus.Warningf("Image %q not found, stop container with signal %q", container.ImageRef, stopSignal)
|
||||
} else {
|
||||
if image.ImageSpec.Config.StopSignal != "" {
|
||||
stopSignal = image.ImageSpec.Config.StopSignal
|
||||
}
|
||||
}
|
||||
}
|
||||
logrus.Infof("Stop container %q with signal %v", id, stopSignal)
|
||||
if err = task.Kill(ctx, stopSignal); err != nil && !errdefs.IsNotFound(err) {
|
||||
sig, err := signal.ParseSignal(stopSignal)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to parse stop signal %q", stopSignal)
|
||||
}
|
||||
logrus.Infof("Stop container %q with signal %v", id, sig)
|
||||
if err = task.Kill(ctx, sig); err != nil && !errdefs.IsNotFound(err) {
|
||||
return errors.Wrapf(err, "failed to stop container %q", id)
|
||||
}
|
||||
|
||||
@@ -105,7 +117,7 @@ func (c *criService) stopContainer(ctx context.Context, container containerstore
|
||||
}
|
||||
|
||||
logrus.Infof("Kill container %q", id)
|
||||
if err = task.Kill(ctx, unix.SIGKILL, containerd.WithKillAll); err != nil && !errdefs.IsNotFound(err) {
|
||||
if err = task.Kill(ctx, unix.SIGKILL); err != nil && !errdefs.IsNotFound(err) {
|
||||
return errors.Wrapf(err, "failed to kill container %q", id)
|
||||
}
|
||||
|
||||
@@ -113,28 +125,7 @@ func (c *criService) stopContainer(ctx context.Context, container containerstore
|
||||
if err = c.waitContainerStop(ctx, container, killContainerTimeout); err == nil {
|
||||
return nil
|
||||
}
|
||||
logrus.WithError(err).Errorf("An error occurs during waiting for container %q to be killed", id)
|
||||
|
||||
// This is a fix for `runc`, and should not break other runtimes. With
|
||||
// containerd.WithKillAll, `runc` will get all processes from the container
|
||||
// cgroups, and kill them. However, sometimes the processes may be moved
|
||||
// out from the container cgroup, e.g. users manually move them by mistake,
|
||||
// or systemd.Delegate=true is not set.
|
||||
// In these cases, we should try our best to do cleanup, kill the container
|
||||
// without containerd.WithKillAll, so that runc can kill the container init
|
||||
// process directly.
|
||||
// NOTE(random-liu): If pid namespace is shared inside the pod, non-init processes
|
||||
// of this container will be left running until the pause container is stopped.
|
||||
logrus.Infof("Kill container %q init process", id)
|
||||
if err = task.Kill(ctx, unix.SIGKILL); err != nil && !errdefs.IsNotFound(err) {
|
||||
return errors.Wrapf(err, "failed to kill container %q init process", id)
|
||||
}
|
||||
|
||||
// Wait for a fixed timeout until container stop is observed by event monitor.
|
||||
if err = c.waitContainerStop(ctx, container, killContainerTimeout); err == nil {
|
||||
return nil
|
||||
}
|
||||
return errors.Wrapf(err, "an error occurs during waiting for container %q init process to be killed", id)
|
||||
return errors.Wrapf(err, "an error occurs during waiting for container %q to be killed", id)
|
||||
}
|
||||
|
||||
// waitContainerStop waits for container to be stopped until timeout exceeds or context is cancelled.
|
||||
|
||||
37
vendor/github.com/containerd/cri/pkg/server/events.go
generated
vendored
37
vendor/github.com/containerd/cri/pkg/server/events.go
generated
vendored
@@ -20,6 +20,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/containerd/containerd"
|
||||
eventtypes "github.com/containerd/containerd/api/events"
|
||||
containerdio "github.com/containerd/containerd/cio"
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
@@ -31,6 +32,7 @@ import (
|
||||
"golang.org/x/net/context"
|
||||
"k8s.io/apimachinery/pkg/util/clock"
|
||||
|
||||
"github.com/containerd/cri/pkg/constants"
|
||||
ctrdutil "github.com/containerd/cri/pkg/containerd/util"
|
||||
"github.com/containerd/cri/pkg/store"
|
||||
containerstore "github.com/containerd/cri/pkg/store/container"
|
||||
@@ -82,7 +84,6 @@ type backOffQueue struct {
|
||||
// Create new event monitor. New event monitor will start subscribing containerd event. All events
|
||||
// happen after it should be monitored.
|
||||
func newEventMonitor(c *criService) *eventMonitor {
|
||||
// event subscribe doesn't need namespace.
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
return &eventMonitor{
|
||||
c: c,
|
||||
@@ -94,6 +95,8 @@ func newEventMonitor(c *criService) *eventMonitor {
|
||||
|
||||
// subscribe starts to subscribe containerd events.
|
||||
func (em *eventMonitor) subscribe(subscriber events.Subscriber) {
|
||||
// note: filters are any match, if you want any match but not in namespace foo
|
||||
// then you have to manually filter namespace foo
|
||||
filters := []string{
|
||||
`topic=="/tasks/exit"`,
|
||||
`topic=="/tasks/oom"`,
|
||||
@@ -141,6 +144,10 @@ func (em *eventMonitor) start() <-chan error {
|
||||
select {
|
||||
case e := <-em.ch:
|
||||
logrus.Debugf("Received containerd event timestamp - %v, namespace - %q, topic - %q", e.Timestamp, e.Namespace, e.Topic)
|
||||
if e.Namespace != constants.K8sContainerdNamespace {
|
||||
logrus.Debugf("Ignoring events in namespace - %q", e.Namespace)
|
||||
break
|
||||
}
|
||||
id, evt, err := convertEvent(e.Event)
|
||||
if err != nil {
|
||||
logrus.WithError(err).Errorf("Failed to convert event %+v", e)
|
||||
@@ -194,14 +201,11 @@ func (em *eventMonitor) handleEvent(any interface{}) error {
|
||||
defer cancel()
|
||||
|
||||
switch any.(type) {
|
||||
// If containerd-shim exits unexpectedly, there will be no corresponding event.
|
||||
// However, containerd could not retrieve container state in that case, so it's
|
||||
// fine to leave out that case for now.
|
||||
// TODO(random-liu): [P2] Handle containerd-shim exit.
|
||||
case *eventtypes.TaskExit:
|
||||
e := any.(*eventtypes.TaskExit)
|
||||
logrus.Infof("TaskExit event %+v", e)
|
||||
cntr, err := em.c.containerStore.Get(e.ContainerID)
|
||||
// Use ID instead of ContainerID to rule out TaskExit event for exec.
|
||||
cntr, err := em.c.containerStore.Get(e.ID)
|
||||
if err == nil {
|
||||
if err := handleContainerExit(ctx, e, cntr); err != nil {
|
||||
return errors.Wrap(err, "failed to handle container TaskExit event")
|
||||
@@ -211,7 +215,7 @@ func (em *eventMonitor) handleEvent(any interface{}) error {
|
||||
return errors.Wrap(err, "can't find container for TaskExit event")
|
||||
}
|
||||
// Use GetAll to include sandbox in unknown state.
|
||||
sb, err := em.c.sandboxStore.GetAll(e.ContainerID)
|
||||
sb, err := em.c.sandboxStore.GetAll(e.ID)
|
||||
if err == nil {
|
||||
if err := handleSandboxExit(ctx, e, sb); err != nil {
|
||||
return errors.Wrap(err, "failed to handle sandbox TaskExit event")
|
||||
@@ -224,17 +228,12 @@ func (em *eventMonitor) handleEvent(any interface{}) error {
|
||||
case *eventtypes.TaskOOM:
|
||||
e := any.(*eventtypes.TaskOOM)
|
||||
logrus.Infof("TaskOOM event %+v", e)
|
||||
// For TaskOOM, we only care which container it belongs to.
|
||||
cntr, err := em.c.containerStore.Get(e.ContainerID)
|
||||
if err != nil {
|
||||
if err != store.ErrNotExist {
|
||||
return errors.Wrap(err, "can't find container for TaskOOM event")
|
||||
}
|
||||
if _, err = em.c.sandboxStore.Get(e.ContainerID); err != nil {
|
||||
if err != store.ErrNotExist {
|
||||
return errors.Wrap(err, "can't find sandbox for TaskOOM event")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
err = cntr.Status.UpdateSync(func(status containerstore.Status) (containerstore.Status, error) {
|
||||
@@ -263,10 +262,6 @@ func (em *eventMonitor) handleEvent(any interface{}) error {
|
||||
|
||||
// handleContainerExit handles TaskExit event for container.
|
||||
func handleContainerExit(ctx context.Context, e *eventtypes.TaskExit, cntr containerstore.Container) error {
|
||||
if e.Pid != cntr.Status.Get().Pid {
|
||||
// Non-init process died, ignore the event.
|
||||
return nil
|
||||
}
|
||||
// Attach container IO so that `Delete` could cleanup the stream properly.
|
||||
task, err := cntr.Container.Task(ctx,
|
||||
func(*containerdio.FIFOSet) (containerdio.IO, error) {
|
||||
@@ -279,7 +274,7 @@ func handleContainerExit(ctx context.Context, e *eventtypes.TaskExit, cntr conta
|
||||
}
|
||||
} else {
|
||||
// TODO(random-liu): [P1] This may block the loop, we may want to spawn a worker
|
||||
if _, err = task.Delete(ctx); err != nil {
|
||||
if _, err = task.Delete(ctx, containerd.WithProcessKill); err != nil {
|
||||
if !errdefs.IsNotFound(err) {
|
||||
return errors.Wrap(err, "failed to stop container")
|
||||
}
|
||||
@@ -307,10 +302,6 @@ func handleContainerExit(ctx context.Context, e *eventtypes.TaskExit, cntr conta
|
||||
|
||||
// handleSandboxExit handles TaskExit event for sandbox.
|
||||
func handleSandboxExit(ctx context.Context, e *eventtypes.TaskExit, sb sandboxstore.Sandbox) error {
|
||||
if e.Pid != sb.Status.Get().Pid {
|
||||
// Non-init process died, ignore the event.
|
||||
return nil
|
||||
}
|
||||
// No stream attached to sandbox container.
|
||||
task, err := sb.Container.Task(ctx, nil)
|
||||
if err != nil {
|
||||
@@ -319,7 +310,7 @@ func handleSandboxExit(ctx context.Context, e *eventtypes.TaskExit, sb sandboxst
|
||||
}
|
||||
} else {
|
||||
// TODO(random-liu): [P1] This may block the loop, we may want to spawn a worker
|
||||
if _, err = task.Delete(ctx); err != nil {
|
||||
if _, err = task.Delete(ctx, containerd.WithProcessKill); err != nil {
|
||||
if !errdefs.IsNotFound(err) {
|
||||
return errors.Wrap(err, "failed to stop sandbox")
|
||||
}
|
||||
|
||||
16
vendor/github.com/containerd/cri/pkg/server/helpers.go
generated
vendored
16
vendor/github.com/containerd/cri/pkg/server/helpers.go
generated
vendored
@@ -137,9 +137,9 @@ const (
|
||||
// generated is unique as long as sandbox metadata is unique.
|
||||
func makeSandboxName(s *runtime.PodSandboxMetadata) string {
|
||||
return strings.Join([]string{
|
||||
s.Name, // 0
|
||||
s.Namespace, // 1
|
||||
s.Uid, // 2
|
||||
s.Name, // 0
|
||||
s.Namespace, // 1
|
||||
s.Uid, // 2
|
||||
fmt.Sprintf("%d", s.Attempt), // 3
|
||||
}, nameDelimiter)
|
||||
}
|
||||
@@ -149,10 +149,10 @@ func makeSandboxName(s *runtime.PodSandboxMetadata) string {
|
||||
// unique.
|
||||
func makeContainerName(c *runtime.ContainerMetadata, s *runtime.PodSandboxMetadata) string {
|
||||
return strings.Join([]string{
|
||||
c.Name, // 0
|
||||
s.Name, // 1: pod name
|
||||
s.Namespace, // 2: pod namespace
|
||||
s.Uid, // 3: pod uid
|
||||
c.Name, // 0
|
||||
s.Name, // 1: pod name
|
||||
s.Namespace, // 2: pod namespace
|
||||
s.Uid, // 3: pod uid
|
||||
fmt.Sprintf("%d", c.Attempt), // 4
|
||||
}, nameDelimiter)
|
||||
}
|
||||
@@ -353,7 +353,7 @@ func checkSelinuxLevel(level string) (bool, error) {
|
||||
|
||||
matched, err := regexp.MatchString(`^s\d(-s\d)??(:c\d{1,4}((.c\d{1,4})?,c\d{1,4})*(.c\d{1,4})?(,c\d{1,4}(.c\d{1,4})?)*)?$`, level)
|
||||
if err != nil || !matched {
|
||||
return false, fmt.Errorf("the format of 'level' %q is not correct: %v", level, err)
|
||||
return false, errors.Wrapf(err, "the format of 'level' %q is not correct", level)
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
4
vendor/github.com/containerd/cri/pkg/server/image_pull.go
generated
vendored
4
vendor/github.com/containerd/cri/pkg/server/image_pull.go
generated
vendored
@@ -61,11 +61,11 @@ import (
|
||||
// if we saw an image without snapshots or with in-complete contents during startup,
|
||||
// should we re-pull the image? Or should we remove the entry?
|
||||
//
|
||||
// yanxuean: We cann't delete image directly, because we don't know if the image
|
||||
// yanxuean: We can't delete image directly, because we don't know if the image
|
||||
// is pulled by us. There are resource leakage.
|
||||
//
|
||||
// 2) Containerd suggests user to add entry before pulling the image. However if
|
||||
// an error occurrs during the pulling, should we remove the entry from metadata
|
||||
// an error occurs during the pulling, should we remove the entry from metadata
|
||||
// store? Or should we leave it there until next startup (resource leakage)?
|
||||
//
|
||||
// 3) The cri plugin only exposes "READY" (successfully pulled and unpacked) images
|
||||
|
||||
2
vendor/github.com/containerd/cri/pkg/server/instrumented_service.go
generated
vendored
2
vendor/github.com/containerd/cri/pkg/server/instrumented_service.go
generated
vendored
@@ -299,7 +299,7 @@ func (in *instrumentedService) PullImage(ctx context.Context, r *runtime.PullIma
|
||||
if err := in.checkInitialized(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
logrus.Infof("PullImage %q with auth config %+v", r.GetImage().GetImage(), r.GetAuth())
|
||||
logrus.Infof("PullImage %q", r.GetImage().GetImage())
|
||||
defer func() {
|
||||
if err != nil {
|
||||
logrus.WithError(err).Errorf("PullImage %q failed", r.GetImage().GetImage())
|
||||
|
||||
12
vendor/github.com/containerd/cri/pkg/server/restart.go
generated
vendored
12
vendor/github.com/containerd/cri/pkg/server/restart.go
generated
vendored
@@ -34,6 +34,7 @@ import (
|
||||
"golang.org/x/net/context"
|
||||
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
||||
|
||||
"github.com/containerd/cri/pkg/netns"
|
||||
cio "github.com/containerd/cri/pkg/server/io"
|
||||
containerstore "github.com/containerd/cri/pkg/store/container"
|
||||
sandboxstore "github.com/containerd/cri/pkg/store/sandbox"
|
||||
@@ -145,7 +146,7 @@ func (c *criService) recover(ctx context.Context) error {
|
||||
// * ListContainerStats: Not in critical code path, a default timeout will
|
||||
// be applied at CRI level.
|
||||
// * Recovery logic: We should set a time for each container/sandbox recovery.
|
||||
// * Event montior: We should set a timeout for each container/sandbox event handling.
|
||||
// * Event monitor: We should set a timeout for each container/sandbox event handling.
|
||||
const loadContainerTimeout = 10 * time.Second
|
||||
|
||||
// loadContainer loads container from containerd and status checkpoint.
|
||||
@@ -394,14 +395,7 @@ func loadSandbox(ctx context.Context, cntr containerd.Container) (sandboxstore.S
|
||||
// Don't need to load netns for host network sandbox.
|
||||
return sandbox, nil
|
||||
}
|
||||
netNS, err := sandboxstore.LoadNetNS(meta.NetNSPath)
|
||||
if err != nil {
|
||||
if err != sandboxstore.ErrClosedNetNS {
|
||||
return sandbox, errors.Wrapf(err, "failed to load netns %q", meta.NetNSPath)
|
||||
}
|
||||
netNS = nil
|
||||
}
|
||||
sandbox.NetNS = netNS
|
||||
sandbox.NetNS = netns.LoadNetNS(meta.NetNSPath)
|
||||
|
||||
// It doesn't matter whether task is running or not. If it is running, sandbox
|
||||
// status will be `READY`; if it is not running, sandbox status will be `NOT_READY`,
|
||||
|
||||
6
vendor/github.com/containerd/cri/pkg/server/sandbox_portforward.go
generated
vendored
6
vendor/github.com/containerd/cri/pkg/server/sandbox_portforward.go
generated
vendored
@@ -59,10 +59,12 @@ func (c *criService) portForward(id string, port int32, stream io.ReadWriteClose
|
||||
securityContext := s.Config.GetLinux().GetSecurityContext()
|
||||
hostNet := securityContext.GetNamespaceOptions().GetNetwork() == runtime.NamespaceMode_NODE
|
||||
if !hostNet {
|
||||
if s.NetNS == nil || s.NetNS.Closed() {
|
||||
if closed, err := s.NetNS.Closed(); err != nil {
|
||||
return errors.Wrapf(err, "failed to check netwok namespace closed for sandbox %q", id)
|
||||
} else if closed {
|
||||
return errors.Errorf("network namespace for sandbox %q is closed", id)
|
||||
}
|
||||
netNSDo = s.NetNS.GetNs().Do
|
||||
netNSDo = s.NetNS.Do
|
||||
netNSPath = s.NetNS.GetPath()
|
||||
} else {
|
||||
// Run the function directly for host network.
|
||||
|
||||
9
vendor/github.com/containerd/cri/pkg/server/sandbox_remove.go
generated
vendored
9
vendor/github.com/containerd/cri/pkg/server/sandbox_remove.go
generated
vendored
@@ -52,8 +52,13 @@ func (c *criService) RemovePodSandbox(ctx context.Context, r *runtime.RemovePodS
|
||||
}
|
||||
|
||||
// Return error if sandbox network namespace is not closed yet.
|
||||
if sandbox.NetNS != nil && !sandbox.NetNS.Closed() {
|
||||
return nil, errors.Errorf("sandbox network namespace %q is not fully closed", sandbox.NetNS.GetPath())
|
||||
if sandbox.NetNS != nil {
|
||||
nsPath := sandbox.NetNS.GetPath()
|
||||
if closed, err := sandbox.NetNS.Closed(); err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to check sandbox network namespace %q closed", nsPath)
|
||||
} else if !closed {
|
||||
return nil, errors.Errorf("sandbox network namespace %q is not fully closed", nsPath)
|
||||
}
|
||||
}
|
||||
|
||||
// Remove all containers inside the sandbox.
|
||||
|
||||
42
vendor/github.com/containerd/cri/pkg/server/sandbox_run.go
generated
vendored
42
vendor/github.com/containerd/cri/pkg/server/sandbox_run.go
generated
vendored
@@ -17,6 +17,7 @@ limitations under the License.
|
||||
package server
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
@@ -40,6 +41,7 @@ import (
|
||||
customopts "github.com/containerd/cri/pkg/containerd/opts"
|
||||
ctrdutil "github.com/containerd/cri/pkg/containerd/util"
|
||||
"github.com/containerd/cri/pkg/log"
|
||||
"github.com/containerd/cri/pkg/netns"
|
||||
sandboxstore "github.com/containerd/cri/pkg/store/sandbox"
|
||||
"github.com/containerd/cri/pkg/util"
|
||||
)
|
||||
@@ -88,6 +90,13 @@ func (c *criService) RunPodSandbox(ctx context.Context, r *runtime.RunPodSandbox
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to get sandbox image %q", c.config.SandboxImage)
|
||||
}
|
||||
|
||||
ociRuntime, err := c.getSandboxRuntime(config, r.GetRuntimeHandler())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get sandbox runtime")
|
||||
}
|
||||
logrus.Debugf("Use OCI %+v for sandbox %q", ociRuntime, id)
|
||||
|
||||
securityContext := config.GetLinux().GetSecurityContext()
|
||||
//Create Network Namespace if it is not in host network
|
||||
hostNet := securityContext.GetNamespaceOptions().GetNetwork() == runtime.NamespaceMode_NODE
|
||||
@@ -96,7 +105,7 @@ func (c *criService) RunPodSandbox(ctx context.Context, r *runtime.RunPodSandbox
|
||||
// handle. NetNSPath in sandbox metadata and NetNS is non empty only for non host network
|
||||
// namespaces. If the pod is in host network namespace then both are empty and should not
|
||||
// be used.
|
||||
sandbox.NetNS, err = sandboxstore.NewNetNS()
|
||||
sandbox.NetNS, err = netns.NewNetNS()
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to create network namespace for sandbox %q", id)
|
||||
}
|
||||
@@ -117,7 +126,7 @@ func (c *criService) RunPodSandbox(ctx context.Context, r *runtime.RunPodSandbox
|
||||
// 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
|
||||
// SandboxStatus request.
|
||||
sandbox.IP, err = c.setupPod(id, sandbox.NetNSPath, config)
|
||||
sandbox.IP, sandbox.CNIResult, err = c.setupPod(id, sandbox.NetNSPath, config)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to setup network for sandbox %q", id)
|
||||
}
|
||||
@@ -131,12 +140,6 @@ func (c *criService) RunPodSandbox(ctx context.Context, r *runtime.RunPodSandbox
|
||||
}()
|
||||
}
|
||||
|
||||
ociRuntime, err := c.getSandboxRuntime(config, r.GetRuntimeHandler())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get sandbox runtime")
|
||||
}
|
||||
logrus.Debugf("Use OCI %+v for sandbox %q", ociRuntime, id)
|
||||
|
||||
// Create sandbox container.
|
||||
spec, err := c.generateSandboxContainerSpec(id, config, &image.ImageSpec.Config, sandbox.NetNSPath)
|
||||
if err != nil {
|
||||
@@ -527,9 +530,9 @@ func (c *criService) unmountSandboxFiles(id string, config *runtime.PodSandboxCo
|
||||
}
|
||||
|
||||
// setupPod setups up the network for a pod
|
||||
func (c *criService) setupPod(id string, path string, config *runtime.PodSandboxConfig) (string, error) {
|
||||
func (c *criService) setupPod(id string, path string, config *runtime.PodSandboxConfig) (string, *cni.CNIResult, error) {
|
||||
if c.netPlugin == nil {
|
||||
return "", errors.New("cni config not intialized")
|
||||
return "", nil, errors.New("cni config not initialized")
|
||||
}
|
||||
|
||||
labels := getPodCNILabels(id, config)
|
||||
@@ -538,17 +541,18 @@ func (c *criService) setupPod(id string, path string, config *runtime.PodSandbox
|
||||
cni.WithLabels(labels),
|
||||
cni.WithCapabilityPortMap(toCNIPortMappings(config.GetPortMappings())))
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "", nil, err
|
||||
}
|
||||
logDebugCNIResult(id, result)
|
||||
// Check if the default interface has IP config
|
||||
if configs, ok := result.Interfaces[defaultIfName]; ok && len(configs.IPConfigs) > 0 {
|
||||
return selectPodIP(configs.IPConfigs), nil
|
||||
return selectPodIP(configs.IPConfigs), result, nil
|
||||
}
|
||||
// If it comes here then the result was invalid so destroy the pod network and return error
|
||||
if err := c.teardownPod(id, path, config); err != nil {
|
||||
logrus.WithError(err).Errorf("Failed to destroy network for sandbox %q", id)
|
||||
}
|
||||
return "", errors.Errorf("failed to find network info for sandbox %q", id)
|
||||
return "", result, errors.Errorf("failed to find network info for sandbox %q", id)
|
||||
}
|
||||
|
||||
// toCNIPortMappings converts CRI port mappings to CNI.
|
||||
@@ -638,3 +642,15 @@ func (c *criService) getSandboxRuntime(config *runtime.PodSandboxConfig, runtime
|
||||
}
|
||||
return handler, nil
|
||||
}
|
||||
|
||||
func logDebugCNIResult(sandboxID string, result *cni.CNIResult) {
|
||||
if logrus.GetLevel() < logrus.DebugLevel {
|
||||
return
|
||||
}
|
||||
cniResult, err := json.Marshal(result)
|
||||
if err != nil {
|
||||
logrus.WithError(err).Errorf("Failed to marshal CNI result for sandbox %q: %v", sandboxID, err)
|
||||
return
|
||||
}
|
||||
logrus.Debugf("cni result for sandbox %q: %s", sandboxID, string(cniResult))
|
||||
}
|
||||
|
||||
29
vendor/github.com/containerd/cri/pkg/server/sandbox_status.go
generated
vendored
29
vendor/github.com/containerd/cri/pkg/server/sandbox_status.go
generated
vendored
@@ -21,6 +21,7 @@ import (
|
||||
|
||||
"github.com/containerd/containerd"
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
cni "github.com/containerd/go-cni"
|
||||
runtimespec "github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/net/context"
|
||||
@@ -36,7 +37,10 @@ func (c *criService) PodSandboxStatus(ctx context.Context, r *runtime.PodSandbox
|
||||
return nil, errors.Wrap(err, "an error occurred when try to find sandbox")
|
||||
}
|
||||
|
||||
ip := c.getIP(sandbox)
|
||||
ip, err := c.getIP(sandbox)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get sandbox ip")
|
||||
}
|
||||
status := toCRISandboxStatus(sandbox.Metadata, sandbox.Status.Get(), ip)
|
||||
if !r.GetVerbose() {
|
||||
return &runtime.PodSandboxStatusResponse{Status: status}, nil
|
||||
@@ -54,21 +58,22 @@ func (c *criService) PodSandboxStatus(ctx context.Context, r *runtime.PodSandbox
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *criService) getIP(sandbox sandboxstore.Sandbox) string {
|
||||
func (c *criService) getIP(sandbox sandboxstore.Sandbox) (string, error) {
|
||||
config := sandbox.Config
|
||||
|
||||
if config.GetLinux().GetSecurityContext().GetNamespaceOptions().GetNetwork() == runtime.NamespaceMode_NODE {
|
||||
// For sandboxes using the node network we are not
|
||||
// responsible for reporting the IP.
|
||||
return ""
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// The network namespace has been closed.
|
||||
if sandbox.NetNS == nil || sandbox.NetNS.Closed() {
|
||||
return ""
|
||||
if closed, err := sandbox.NetNS.Closed(); err != nil {
|
||||
return "", errors.Wrap(err, "check network namespace closed")
|
||||
} else if closed {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
return sandbox.IP
|
||||
return sandbox.IP, nil
|
||||
}
|
||||
|
||||
// toCRISandboxStatus converts sandbox metadata into CRI pod sandbox status.
|
||||
@@ -113,6 +118,7 @@ type SandboxInfo struct {
|
||||
RuntimeOptions interface{} `json:"runtimeOptions"`
|
||||
Config *runtime.PodSandboxConfig `json:"config"`
|
||||
RuntimeSpec *runtimespec.Spec `json:"runtimeSpec"`
|
||||
CNIResult *cni.CNIResult `json:"cniResult"`
|
||||
}
|
||||
|
||||
// toCRISandboxInfo converts internal container object information to CRI sandbox status response info map.
|
||||
@@ -138,6 +144,7 @@ func toCRISandboxInfo(ctx context.Context, sandbox sandboxstore.Sandbox) (map[st
|
||||
RuntimeHandler: sandbox.RuntimeHandler,
|
||||
Status: string(processStatus),
|
||||
Config: sandbox.Config,
|
||||
CNIResult: sandbox.CNIResult,
|
||||
}
|
||||
|
||||
if si.Status == "" {
|
||||
@@ -146,9 +153,13 @@ func toCRISandboxInfo(ctx context.Context, sandbox sandboxstore.Sandbox) (map[st
|
||||
si.Status = "deleted"
|
||||
}
|
||||
|
||||
if sandbox.NetNSPath != "" {
|
||||
if sandbox.NetNS != nil {
|
||||
// Add network closed information if sandbox is not using host network.
|
||||
si.NetNSClosed = (sandbox.NetNS == nil || sandbox.NetNS.Closed())
|
||||
closed, err := sandbox.NetNS.Closed()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to check network namespace closed")
|
||||
}
|
||||
si.NetNSClosed = closed
|
||||
}
|
||||
|
||||
spec, err := container.Spec(ctx)
|
||||
|
||||
62
vendor/github.com/containerd/cri/pkg/server/sandbox_stop.go
generated
vendored
62
vendor/github.com/containerd/cri/pkg/server/sandbox_stop.go
generated
vendored
@@ -19,7 +19,6 @@ package server
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/containerd/containerd"
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
cni "github.com/containerd/go-cni"
|
||||
"github.com/pkg/errors"
|
||||
@@ -43,9 +42,8 @@ func (c *criService) StopPodSandbox(ctx context.Context, r *runtime.StopPodSandb
|
||||
id := sandbox.ID
|
||||
|
||||
// Stop all containers inside the sandbox. This terminates the container forcibly,
|
||||
// and container may still be so production should not rely on this behavior.
|
||||
// TODO(random-liu): Delete the sandbox container before this after permanent network namespace
|
||||
// is introduced, so that no container will be started after that.
|
||||
// and container may still be created, so production should not rely on this behavior.
|
||||
// TODO(random-liu): Introduce a state in sandbox to avoid future container creation.
|
||||
containers := c.containerStore.List()
|
||||
for _, container := range containers {
|
||||
if container.SandboxID != id {
|
||||
@@ -58,27 +56,6 @@ func (c *criService) StopPodSandbox(ctx context.Context, r *runtime.StopPodSandb
|
||||
}
|
||||
}
|
||||
|
||||
// Teardown network for sandbox.
|
||||
if sandbox.NetNSPath != "" {
|
||||
netNSPath := sandbox.NetNSPath
|
||||
if sandbox.NetNS == nil || sandbox.NetNS.Closed() {
|
||||
// Use empty netns path if netns is not available. This is defined in:
|
||||
// https://github.com/containernetworking/cni/blob/v0.7.0-alpha1/SPEC.md
|
||||
netNSPath = ""
|
||||
}
|
||||
if err := c.teardownPod(id, netNSPath, sandbox.Config); err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to destroy network for sandbox %q", id)
|
||||
}
|
||||
// Close the sandbox network namespace if it was created
|
||||
if sandbox.NetNS != nil {
|
||||
if err = sandbox.NetNS.Remove(); err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to remove network namespace for sandbox %q", id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
logrus.Infof("TearDown network for sandbox %q successfully", id)
|
||||
|
||||
if err := c.unmountSandboxFiles(id, sandbox.Config); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to unmount sandbox files")
|
||||
}
|
||||
@@ -89,6 +66,27 @@ func (c *criService) StopPodSandbox(ctx context.Context, r *runtime.StopPodSandb
|
||||
return nil, errors.Wrapf(err, "failed to stop sandbox container %q", id)
|
||||
}
|
||||
}
|
||||
|
||||
// Teardown network for sandbox.
|
||||
if sandbox.NetNS != nil {
|
||||
netNSPath := sandbox.NetNSPath
|
||||
// Use empty netns path if netns is not available. This is defined in:
|
||||
// https://github.com/containernetworking/cni/blob/v0.7.0-alpha1/SPEC.md
|
||||
if closed, err := sandbox.NetNS.Closed(); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to check network namespace closed")
|
||||
} else if closed {
|
||||
netNSPath = ""
|
||||
}
|
||||
if err := c.teardownPod(id, netNSPath, sandbox.Config); err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to destroy network for sandbox %q", id)
|
||||
}
|
||||
if err = sandbox.NetNS.Remove(); err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to remove network namespace for sandbox %q", id)
|
||||
}
|
||||
}
|
||||
|
||||
logrus.Infof("TearDown network for sandbox %q successfully", id)
|
||||
|
||||
return &runtime.StopPodSandboxResponse{}, nil
|
||||
}
|
||||
|
||||
@@ -106,18 +104,8 @@ func (c *criService) stopSandboxContainer(ctx context.Context, sandbox sandboxst
|
||||
}
|
||||
|
||||
// Kill the sandbox container.
|
||||
if err = task.Kill(ctx, unix.SIGKILL, containerd.WithKillAll); err != nil && !errdefs.IsNotFound(err) {
|
||||
return errors.Wrap(err, "failed to kill sandbox container")
|
||||
}
|
||||
|
||||
if err = c.waitSandboxStop(ctx, sandbox, killContainerTimeout); err == nil {
|
||||
return nil
|
||||
}
|
||||
logrus.WithError(err).Errorf("An error occurs during waiting for sandbox %q to be killed", sandbox.ID)
|
||||
|
||||
// Kill the sandbox container init process.
|
||||
if err = task.Kill(ctx, unix.SIGKILL); err != nil && !errdefs.IsNotFound(err) {
|
||||
return errors.Wrap(err, "failed to kill sandbox container init process")
|
||||
return errors.Wrap(err, "failed to kill sandbox container")
|
||||
}
|
||||
|
||||
return c.waitSandboxStop(ctx, sandbox, killContainerTimeout)
|
||||
@@ -140,7 +128,7 @@ func (c *criService) waitSandboxStop(ctx context.Context, sandbox sandboxstore.S
|
||||
// teardownPod removes the network from the pod
|
||||
func (c *criService) teardownPod(id string, path string, config *runtime.PodSandboxConfig) error {
|
||||
if c.netPlugin == nil {
|
||||
return errors.New("cni config not intialized")
|
||||
return errors.New("cni config not initialized")
|
||||
}
|
||||
|
||||
labels := getPodCNILabels(id, config)
|
||||
|
||||
5
vendor/github.com/containerd/cri/pkg/store/container/metadata.go
generated
vendored
5
vendor/github.com/containerd/cri/pkg/store/container/metadata.go
generated
vendored
@@ -27,7 +27,7 @@ import (
|
||||
// 1) Metadata is immutable after created.
|
||||
// 2) Metadata is checkpointed as containerd container label.
|
||||
|
||||
// metadataVersion is current version of container metadata.
|
||||
// metadataVersion is current version of container metadata.
|
||||
const metadataVersion = "v1" // nolint
|
||||
|
||||
// versionedMetadata is the internal versioned container metadata.
|
||||
@@ -58,6 +58,9 @@ type Metadata struct {
|
||||
ImageRef string
|
||||
// LogPath is the container log path.
|
||||
LogPath string
|
||||
// StopSignal is the system call signal that will be sent to the container to exit.
|
||||
// TODO(random-liu): Add integration test for stop signal.
|
||||
StopSignal string
|
||||
}
|
||||
|
||||
// MarshalJSON encodes Metadata into bytes in json format.
|
||||
|
||||
3
vendor/github.com/containerd/cri/pkg/store/sandbox/metadata.go
generated
vendored
3
vendor/github.com/containerd/cri/pkg/store/sandbox/metadata.go
generated
vendored
@@ -19,6 +19,7 @@ package sandbox
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
cni "github.com/containerd/go-cni"
|
||||
"github.com/pkg/errors"
|
||||
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
||||
)
|
||||
@@ -56,6 +57,8 @@ type Metadata struct {
|
||||
IP string
|
||||
// RuntimeHandler is the runtime handler name of the pod.
|
||||
RuntimeHandler string
|
||||
// CNI result
|
||||
CNIResult *cni.CNIResult
|
||||
}
|
||||
|
||||
// MarshalJSON encodes Metadata into bytes in json format.
|
||||
|
||||
132
vendor/github.com/containerd/cri/pkg/store/sandbox/netns.go
generated
vendored
132
vendor/github.com/containerd/cri/pkg/store/sandbox/netns.go
generated
vendored
@@ -1,132 +0,0 @@
|
||||
/*
|
||||
Copyright 2017 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 sandbox
|
||||
|
||||
import (
|
||||
"os"
|
||||
"sync"
|
||||
|
||||
cnins "github.com/containernetworking/plugins/pkg/ns"
|
||||
"github.com/docker/docker/pkg/symlink"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
osinterface "github.com/containerd/cri/pkg/os"
|
||||
)
|
||||
|
||||
// The NetNS library assumes only containerd manages the lifecycle of the
|
||||
// network namespace mount. The only case that netns will be unmounted by
|
||||
// someone else is node reboot.
|
||||
// If this assumption is broken, NetNS won't be aware of the external
|
||||
// unmount, and there will be a state mismatch.
|
||||
// TODO(random-liu): Don't cache state, always load from the system.
|
||||
|
||||
// ErrClosedNetNS is the error returned when network namespace is closed.
|
||||
var ErrClosedNetNS = errors.New("network namespace is closed")
|
||||
|
||||
// NetNS holds network namespace for sandbox
|
||||
type NetNS struct {
|
||||
sync.Mutex
|
||||
ns cnins.NetNS
|
||||
closed bool
|
||||
restored bool
|
||||
}
|
||||
|
||||
// NewNetNS creates a network namespace for the sandbox
|
||||
func NewNetNS() (*NetNS, error) {
|
||||
netns, err := cnins.NewNS()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to setup network namespace")
|
||||
}
|
||||
n := new(NetNS)
|
||||
n.ns = netns
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// LoadNetNS loads existing network namespace. It returns ErrClosedNetNS
|
||||
// if the network namespace has already been closed.
|
||||
func LoadNetNS(path string) (*NetNS, error) {
|
||||
ns, err := cnins.GetNS(path)
|
||||
if err != nil {
|
||||
if _, ok := err.(cnins.NSPathNotExistErr); ok {
|
||||
return nil, ErrClosedNetNS
|
||||
}
|
||||
if _, ok := err.(cnins.NSPathNotNSErr); ok {
|
||||
// Do best effort cleanup.
|
||||
os.RemoveAll(path) // nolint: errcheck
|
||||
return nil, ErrClosedNetNS
|
||||
}
|
||||
return nil, errors.Wrap(err, "failed to load network namespace")
|
||||
}
|
||||
return &NetNS{ns: ns, restored: true}, nil
|
||||
}
|
||||
|
||||
// Remove removes network namepace if it exists and not closed. Remove is idempotent,
|
||||
// meaning it might be invoked multiple times and provides consistent result.
|
||||
func (n *NetNS) Remove() error {
|
||||
n.Lock()
|
||||
defer n.Unlock()
|
||||
if !n.closed {
|
||||
err := n.ns.Close()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to close network namespace")
|
||||
}
|
||||
n.closed = true
|
||||
}
|
||||
if n.restored {
|
||||
path := n.ns.Path()
|
||||
// Check netns existence.
|
||||
if _, err := os.Stat(path); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil
|
||||
}
|
||||
return errors.Wrap(err, "failed to stat netns")
|
||||
}
|
||||
path, err := symlink.FollowSymlinkInScope(path, "/")
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to follow symlink")
|
||||
}
|
||||
if err := osinterface.Unmount(path); err != nil && !os.IsNotExist(err) {
|
||||
return errors.Wrap(err, "failed to umount netns")
|
||||
}
|
||||
if err := os.RemoveAll(path); err != nil {
|
||||
return errors.Wrap(err, "failed to remove netns")
|
||||
}
|
||||
n.restored = false
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Closed checks whether the network namespace has been closed.
|
||||
func (n *NetNS) Closed() bool {
|
||||
n.Lock()
|
||||
defer n.Unlock()
|
||||
return n.closed && !n.restored
|
||||
}
|
||||
|
||||
// GetPath returns network namespace path for sandbox container
|
||||
func (n *NetNS) GetPath() string {
|
||||
n.Lock()
|
||||
defer n.Unlock()
|
||||
return n.ns.Path()
|
||||
}
|
||||
|
||||
// GetNs returns the network namespace handle
|
||||
func (n *NetNS) GetNs() cnins.NetNS {
|
||||
n.Lock()
|
||||
defer n.Unlock()
|
||||
return n.ns
|
||||
}
|
||||
9
vendor/github.com/containerd/cri/pkg/store/sandbox/sandbox.go
generated
vendored
9
vendor/github.com/containerd/cri/pkg/store/sandbox/sandbox.go
generated
vendored
@@ -22,6 +22,7 @@ import (
|
||||
"github.com/containerd/containerd"
|
||||
"github.com/docker/docker/pkg/truncindex"
|
||||
|
||||
"github.com/containerd/cri/pkg/netns"
|
||||
"github.com/containerd/cri/pkg/store"
|
||||
)
|
||||
|
||||
@@ -32,10 +33,12 @@ type Sandbox struct {
|
||||
Metadata
|
||||
// Status stores the status of the sandbox.
|
||||
Status StatusStorage
|
||||
// Container is the containerd sandbox container client
|
||||
// Container is the containerd sandbox container client.
|
||||
Container containerd.Container
|
||||
// CNI network namespace client
|
||||
NetNS *NetNS
|
||||
// CNI network namespace client.
|
||||
// For hostnetwork pod, this is always nil;
|
||||
// For non hostnetwork pod, this should never be nil.
|
||||
NetNS *netns.NetNS
|
||||
// StopCh is used to propagate the stop information of the sandbox.
|
||||
*store.StopCh
|
||||
}
|
||||
|
||||
30
vendor/github.com/containerd/cri/vendor.conf
generated
vendored
30
vendor/github.com/containerd/cri/vendor.conf
generated
vendored
@@ -3,7 +3,7 @@ github.com/blang/semver v3.1.0
|
||||
github.com/BurntSushi/toml a368813c5e648fee92e5f6c30e3944ff9d5e8895
|
||||
github.com/containerd/cgroups 5e610833b72089b37d0e615de9a92dfc043757c2
|
||||
github.com/containerd/console c12b1e7919c14469339a5d38f2f8ed9b64a9de23
|
||||
github.com/containerd/containerd 15f19d7a67fa322e6de0ef4c6a1bf9da0f056554
|
||||
github.com/containerd/containerd 6937c5a3ba8280edff9e9030767e3b0cb742581c
|
||||
github.com/containerd/continuity bd77b46c8352f74eb12c85bdc01f4b90f69d66b4
|
||||
github.com/containerd/fifo 3d5202aec260678c48179c56f40e6f38a095738c
|
||||
github.com/containerd/go-cni 40bcf8ec8acd7372be1d77031d585d5d8e561c90
|
||||
@@ -21,11 +21,9 @@ github.com/docker/go-metrics 4ea375f7759c82740c893fc030bc37088d2ec098
|
||||
github.com/docker/go-units v0.3.1
|
||||
github.com/docker/spdystream 449fdfce4d962303d702fec724ef0ad181c92528
|
||||
github.com/emicklei/go-restful v2.2.1
|
||||
github.com/ghodss/yaml v1.0.0
|
||||
github.com/godbus/dbus v3
|
||||
github.com/gogo/googleapis 08a7655d27152912db7aaf4f983275eaf8d128ef
|
||||
github.com/gogo/protobuf v1.0.0
|
||||
github.com/golang/glog 44145f04b68cf362d9c4df2182967c2275eaefed
|
||||
github.com/golang/protobuf v1.1.0
|
||||
github.com/google/gofuzz 44d81051d367757e1c7c6a5a86423ece9afcf63c
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.1
|
||||
@@ -33,15 +31,15 @@ github.com/hashicorp/errwrap 7554cd9344cec97297fa6649b055a8c98c2a1e55
|
||||
github.com/hashicorp/go-multierror ed905158d87462226a13fe39ddf685ea65f1c11f
|
||||
github.com/json-iterator/go 1.1.5
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.0
|
||||
github.com/Microsoft/go-winio v0.4.10
|
||||
github.com/Microsoft/hcsshim v0.7.6
|
||||
github.com/Microsoft/go-winio v0.4.11
|
||||
github.com/Microsoft/hcsshim v0.8.2
|
||||
github.com/modern-go/concurrent 1.0.3
|
||||
github.com/modern-go/reflect2 1.0.1
|
||||
github.com/opencontainers/go-digest c9281466c8b2f606084ac71339773efd177436e7
|
||||
github.com/opencontainers/image-spec v1.0.1
|
||||
github.com/opencontainers/runc 00dc70017d222b178a002ed30e9321b12647af2d
|
||||
github.com/opencontainers/runc v1.0.0-rc6
|
||||
github.com/opencontainers/runtime-spec eba862dc2470385a233c7507392675cbeadf7353
|
||||
github.com/opencontainers/runtime-tools v0.6.0
|
||||
github.com/opencontainers/runtime-tools fb101d5d42ab9c040f7d0a004e78336e5d5cb197
|
||||
github.com/opencontainers/selinux b6fa367ed7f534f9ba25391cc2d467085dbb445a
|
||||
github.com/pkg/errors v0.8.0
|
||||
github.com/pmezard/go-difflib v1.0.0
|
||||
@@ -50,7 +48,7 @@ github.com/prometheus/client_model 99fa1f4be8e564e8a6b613da7fa6f46c9edafc6c
|
||||
github.com/prometheus/common 89604d197083d4781071d3c65855d24ecfb0a563
|
||||
github.com/prometheus/procfs cb4147076ac75738c9a7d279075a253c0cc5acbd
|
||||
github.com/seccomp/libseccomp-golang 32f571b70023028bd57d9288c20efbcb237f3ce0
|
||||
github.com/sirupsen/logrus v1.0.0
|
||||
github.com/sirupsen/logrus v1.0.3
|
||||
github.com/stretchr/testify v1.1.4
|
||||
github.com/syndtr/gocapability db04d3cc01c8b54962a58ec7e491717d06cfcc16
|
||||
github.com/tchap/go-patricia v2.2.6
|
||||
@@ -69,10 +67,12 @@ golang.org/x/time f51c12702a4d776e4c1fa9b0fabab841babae631
|
||||
google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944
|
||||
google.golang.org/grpc v1.12.0
|
||||
gopkg.in/inf.v0 3887ee99ecf07df5b447e9b00d9c0b2adaa9f3e4
|
||||
gopkg.in/yaml.v2 53feefa2559fb8dfa8d81baad31be332c97d6c77
|
||||
k8s.io/api kubernetes-1.12.0
|
||||
k8s.io/apimachinery kubernetes-1.12.0
|
||||
k8s.io/apiserver kubernetes-1.12.0
|
||||
k8s.io/client-go kubernetes-1.12.0
|
||||
k8s.io/kubernetes v1.12.0
|
||||
k8s.io/utils cd34563cd63c2bd7c6fe88a73c4dcf34ed8a67cb
|
||||
gopkg.in/yaml.v2 v2.2.1
|
||||
k8s.io/api kubernetes-1.13.0
|
||||
k8s.io/apimachinery kubernetes-1.13.0
|
||||
k8s.io/apiserver kubernetes-1.13.0
|
||||
k8s.io/client-go kubernetes-1.13.0
|
||||
k8s.io/klog 8139d8cb77af419532b33dfa7dd09fbc5f1d344f
|
||||
k8s.io/kubernetes v1.13.0
|
||||
k8s.io/utils 0d26856f57b32ec3398579285e5c8a2bfe8c5243
|
||||
sigs.k8s.io/yaml v1.1.0
|
||||
|
||||
Reference in New Issue
Block a user