containerd/linux/shim.go
Michael Crosby 634f0c0c83 Set oom score for containerd and shims
This adds a config option to set the oom score for the containerd daemon
as well as automatically setting the oom score for the shim's lauched so
that they are not killed until the very end of an out of memory
condition.

Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
2017-04-12 11:34:32 -07:00

85 lines
2.4 KiB
Go

// +build linux
package linux
import (
"fmt"
"io/ioutil"
"log"
"net"
"os/exec"
"path/filepath"
"syscall"
"time"
"google.golang.org/grpc"
"google.golang.org/grpc/grpclog"
"github.com/containerd/containerd/api/services/shim"
localShim "github.com/containerd/containerd/linux/shim"
"github.com/containerd/containerd/reaper"
"github.com/containerd/containerd/sys"
"github.com/pkg/errors"
)
func newShim(path string, remote bool) (shim.ShimClient, error) {
if !remote {
return localShim.Client(path), nil
}
socket := filepath.Join(path, "shim.sock")
l, err := sys.CreateUnixSocket(socket)
if err != nil {
return nil, err
}
cmd := exec.Command("containerd-shim")
cmd.Dir = path
f, err := l.(*net.UnixListener).File()
if err != nil {
return nil, err
}
// close our side of the socket, do not close the listener as it will
// remove the socket from disk
defer f.Close()
cmd.ExtraFiles = append(cmd.ExtraFiles, f)
// make sure the shim can be re-parented to system init
// and is cloned in a new mount namespace because the overlay/filesystems
// will be mounted by the shim
cmd.SysProcAttr = &syscall.SysProcAttr{
Cloneflags: syscall.CLONE_NEWNS,
Setpgid: true,
}
if err := reaper.Default.Start(cmd); err != nil {
return nil, errors.Wrapf(err, "failed to start shim")
}
if err := sys.SetOOMScore(cmd.Process.Pid, sys.OOMScoreMaxKillable); err != nil {
return nil, err
}
return connectShim(socket)
}
func loadShim(path string, remote bool) (shim.ShimClient, error) {
if !remote {
return localShim.Client(path), nil
}
socket := filepath.Join(path, "shim.sock")
return connectShim(socket)
}
func connectShim(socket string) (shim.ShimClient, error) {
// reset the logger for grpc to log to dev/null so that it does not mess with our stdio
grpclog.SetLogger(log.New(ioutil.Discard, "", log.LstdFlags))
dialOpts := []grpc.DialOption{grpc.WithInsecure(), grpc.WithTimeout(100 * time.Second)}
dialOpts = append(dialOpts,
grpc.WithDialer(func(addr string, timeout time.Duration) (net.Conn, error) {
return net.DialTimeout("unix", socket, timeout)
}),
grpc.WithBlock(),
grpc.WithTimeout(2*time.Second),
)
conn, err := grpc.Dial(fmt.Sprintf("unix://%s", socket), dialOpts...)
if err != nil {
return nil, errors.Wrapf(err, "failed to connect to shim via \"%s\"", fmt.Sprintf("unix://%s", socket))
}
return shim.NewShimClient(conn), nil
}