Merge pull request #1767 from stevvooe/ttrpc-shim

linux/shim: reduce memory overhead by using ttrpc
This commit is contained in:
Phil Estes
2017-11-28 12:43:41 -05:00
committed by GitHub
20 changed files with 1375 additions and 726 deletions

View File

@@ -25,8 +25,8 @@ import (
"github.com/containerd/typeurl"
ptypes "github.com/gogo/protobuf/types"
"github.com/sirupsen/logrus"
"github.com/stevvooe/ttrpc"
"golang.org/x/sys/unix"
"google.golang.org/grpc"
)
var (
@@ -100,7 +100,8 @@ func executeShim() error {
return err
}
logrus.Debug("registering grpc server")
shimapi.RegisterShimServer(server, sv)
shimapi.RegisterShimService(server, sv)
socket := socketFlag
if err := serve(server, socket); err != nil {
return err
@@ -115,7 +116,7 @@ func executeShim() error {
// serve serves the grpc API over a unix socket at the provided path
// this function does not block
func serve(server *grpc.Server, path string) error {
func serve(server *ttrpc.Server, path string) error {
var (
l net.Listener
err error
@@ -140,7 +141,7 @@ func serve(server *grpc.Server, path string) error {
return nil
}
func handleSignals(logger *logrus.Entry, signals chan os.Signal, server *grpc.Server, sv *shim.Service) error {
func handleSignals(logger *logrus.Entry, signals chan os.Signal, server *ttrpc.Server, sv *shim.Service) error {
var (
termOnce sync.Once
done = make(chan struct{})
@@ -158,9 +159,12 @@ func handleSignals(logger *logrus.Entry, signals chan os.Signal, server *grpc.Se
}
case unix.SIGTERM, unix.SIGINT:
go termOnce.Do(func() {
server.Stop()
ctx := context.TODO()
if err := server.Shutdown(ctx); err != nil {
logger.WithError(err).Error("failed to shutdown server")
}
// Ensure our child is dead if any
sv.Kill(context.Background(), &shimapi.KillRequest{
sv.Kill(ctx, &shimapi.KillRequest{
Signal: uint32(syscall.SIGKILL),
All: true,
})

View File

@@ -1,20 +1,13 @@
package main
import (
"net"
"os"
"os/signal"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"golang.org/x/net/context"
"golang.org/x/sys/unix"
"github.com/containerd/containerd/reaper"
"github.com/containerd/containerd/sys"
runc "github.com/containerd/go-runc"
"github.com/pkg/errors"
"github.com/stevvooe/ttrpc"
)
// setupSignals creates a new signal handler for all signals and sets the shim as a
@@ -32,64 +25,6 @@ func setupSignals() (chan os.Signal, error) {
return signals, nil
}
func newServer() *grpc.Server {
return grpc.NewServer(grpc.Creds(NewUnixSocketCredentials(0, 0)))
}
type unixSocketCredentials struct {
uid int
gid int
serverName string
}
// NewUnixSocketCredentials returns TransportCredentials for a local unix socket
func NewUnixSocketCredentials(uid, gid int) credentials.TransportCredentials {
return &unixSocketCredentials{uid, gid, "locahost"}
}
func (u *unixSocketCredentials) ClientHandshake(ctx context.Context, addr string, rawConn net.Conn) (net.Conn, credentials.AuthInfo, error) {
return nil, nil, errors.New("ClientHandshake is not supported by unixSocketCredentials")
}
func (u *unixSocketCredentials) ServerHandshake(c net.Conn) (net.Conn, credentials.AuthInfo, error) {
uc, ok := c.(*net.UnixConn)
if !ok {
return nil, nil, errors.New("unixSocketCredentials only supports unix socket")
}
f, err := uc.File()
if err != nil {
return nil, nil, errors.Wrap(err, "unixSocketCredentials: failed to retrieve connection underlying fd")
}
pcred, err := unix.GetsockoptUcred(int(f.Fd()), unix.SOL_SOCKET, unix.SO_PEERCRED)
if err != nil {
return nil, nil, errors.Wrap(err, "unixSocketCredentials: failed to retrieve socket peer credentials")
}
if (u.uid != -1 && uint32(u.uid) != pcred.Uid) || (u.gid != -1 && uint32(u.gid) != pcred.Gid) {
return nil, nil, errors.New("unixSocketCredentials: invalid credentials")
}
return c, u, nil
}
func (u *unixSocketCredentials) Info() credentials.ProtocolInfo {
return credentials.ProtocolInfo{
SecurityProtocol: "unix-socket-peer-creds",
SecurityVersion: "1.0",
ServerName: u.serverName,
}
}
func (u *unixSocketCredentials) Clone() credentials.TransportCredentials {
return &unixSocketCredentials{u.uid, u.gid, u.serverName}
}
func (u *unixSocketCredentials) OverrideServerName(serverName string) error {
u.serverName = serverName
return nil
}
func (u *unixSocketCredentials) AuthType() string {
return "unix-socket-peer-creds"
func newServer() *ttrpc.Server {
return ttrpc.NewServer()
}

View File

@@ -6,10 +6,9 @@ import (
"os"
"os/signal"
"google.golang.org/grpc"
"github.com/containerd/containerd/reaper"
runc "github.com/containerd/go-runc"
"github.com/stevvooe/ttrpc"
)
// setupSignals creates a new signal handler for all signals and sets the shim as a
@@ -23,6 +22,6 @@ func setupSignals() (chan os.Signal, error) {
return signals, nil
}
func newServer() *grpc.Server {
return grpc.NewServer()
func newServer() *ttrpc.Server {
return ttrpc.NewServer()
}

View File

@@ -6,12 +6,9 @@ import (
"fmt"
"io/ioutil"
"net"
"time"
gocontext "context"
"google.golang.org/grpc"
"github.com/containerd/console"
"github.com/containerd/containerd/cmd/ctr/commands"
shim "github.com/containerd/containerd/linux/shim/v1"
@@ -20,6 +17,7 @@ import (
"github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/stevvooe/ttrpc"
"github.com/urfave/cli"
)
@@ -212,21 +210,21 @@ var execCommand = cli.Command{
},
}
func getShimService(context *cli.Context) (shim.ShimClient, error) {
func getShimService(context *cli.Context) (shim.ShimService, error) {
bindSocket := context.GlobalString("socket")
if bindSocket == "" {
return nil, errors.New("socket path must be specified")
}
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", "\x00"+bindSocket, timeout)
},
))
conn, err := grpc.Dial(fmt.Sprintf("unix://%s", bindSocket), dialOpts...)
conn, err := net.Dial("unix", "\x00"+bindSocket)
if err != nil {
return nil, err
}
return shim.NewShimClient(conn), nil
client := ttrpc.NewClient(conn)
// TODO(stevvooe): This actually leaks the connection. We were leaking it
// before, so may not be a huge deal.
return shim.NewShimClient(client), nil
}

View File

@@ -5,6 +5,7 @@ import (
"github.com/gogo/protobuf/protoc-gen-gogo/descriptor"
"github.com/gogo/protobuf/vanity"
"github.com/gogo/protobuf/vanity/command"
_ "github.com/stevvooe/ttrpc/plugin"
)
func main() {