
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>
85 lines
2.4 KiB
Go
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
|
|
}
|