Experimental Pre-fork Pool: Recycle net ns (#890)

* fn: experimental prefork recycle and other improvements

*) Recycle and do not use same pool container again option.
*) Two state processing: initializing versus ready (start-kill).
*) Ready state is exempt from rate limiter.

* fn: experimental prefork pool multiple network support

In order to exceed 1023 container (bridge port) limit, add
multiple networks:

    for i in fn-net1 fn-net2 fn-net3 fn-net4
    do
            docker network create $i
    done

to Docker startup, (eg. dind preentry.sh), then provide this
to prefork pool using:

    export FN_EXPERIMENTAL_PREFORK_NETWORKS="fn-net1 fn-net2 fn-net3 fn-net4"

which should be able to spawn 1023 * 4 containers.

* fn: fixup tests for cfg move

* fn: add ipc and pid namespaces into prefork pooling

* fn: revert ipc and pid namespaces for now

Pid/Ipc opens up the function container to pause container.
This commit is contained in:
Tolga Ceylan
2018-04-05 15:07:30 -07:00
committed by GitHub
parent 629559ecc8
commit 584e4e75eb
7 changed files with 229 additions and 106 deletions

View File

@@ -131,6 +131,29 @@ func (drv *DockerDriver) Close() error {
return err
}
func (drv *DockerDriver) tryUsePool(ctx context.Context, container *docker.CreateContainerOptions) string {
ctx, log := common.LoggerWithFields(ctx, logrus.Fields{"stack": "tryUsePool"})
if drv.pool != nil {
id, err := drv.pool.AllocPoolId()
if err == nil {
linker := fmt.Sprintf("container:%s", id)
// We are able to fetch a container from pool. Now, use its
// network, ipc and pid namespaces.
container.HostConfig.NetworkMode = linker
//container.HostConfig.IpcMode = linker
//container.HostConfig.PidMode = linker
return id
}
log.WithError(err).Error("Could not fetch pre fork pool container")
}
// hostname and container NetworkMode is not compatible.
container.Config.Hostname = drv.hostname
return ""
}
func (drv *DockerDriver) Prepare(ctx context.Context, task drivers.ContainerTask) (drivers.Cookie, error) {
ctx, log := common.LoggerWithFields(ctx, logrus.Fields{"stack": "Prepare"})
var cmd []string
@@ -171,19 +194,7 @@ func (drv *DockerDriver) Prepare(ctx context.Context, task drivers.ContainerTask
Context: ctx,
}
poolId := ""
if drv.pool != nil {
id, err := drv.pool.AllocPoolId()
if err != nil {
log.WithError(err).Error("Could not fetch pre fork pool container")
} else {
poolId = id
container.HostConfig.NetworkMode = fmt.Sprintf("container:%s", id)
}
} else {
// hostname and container NetworkMode is not compatible.
container.Config.Hostname = drv.hostname
}
poolId := drv.tryUsePool(ctx, &container)
// Translate milli cpus into CPUQuota & CPUPeriod (see Linux cGroups CFS cgroup v1 documentation)
// eg: task.CPUQuota() of 8000 means CPUQuota of 8 * 100000 usecs in 100000 usec period,