This commit is contained in:
Olli Janatuinen 2024-04-19 16:18:37 +03:00 committed by GitHub
commit ba6b2cd9df
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 120 additions and 22 deletions

View file

@ -337,7 +337,7 @@ jobs:
}
-
name: Starting containerd
if: matrix.runtime == 'containerd'
if: matrix.runtime == 'containerd' && matrix.os == 'windows-2019'
run: |
Write-Host "Generating config"
& "${{ env.BIN_OUT }}\containerd.exe" config default | Out-File "$env:TEMP\ctn.toml" -Encoding ascii
@ -360,10 +360,14 @@ jobs:
name: Starting test daemon
run: |
Write-Host "Creating service"
If ("${{ matrix.runtime }}" -eq "containerd") {
If ("${{ matrix.runtime }}" -eq "containerd" -and "${{ matrix.os }}" -eq "windows-2019") {
$runtimeArg="--containerd=\\.\pipe\containerd-containerd"
echo "DOCKER_WINDOWS_CONTAINERD_RUNTIME=1" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf-8 -Append
}
If ("${{ matrix.runtime }}" -eq "containerd" -and "${{ matrix.os }}" -eq "windows-2022") {
$runtimeArg="--default-runtime=io.containerd.runhcs.v1"
echo "DOCKER_WINDOWS_CONTAINERD_RUNTIME=1" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf-8 -Append
}
New-Item -ItemType Directory "$env:TEMP\moby-root" -ErrorAction SilentlyContinue | Out-Null
New-Item -ItemType Directory "$env:TEMP\moby-exec" -ErrorAction SilentlyContinue | Out-Null
Start-Process -Wait -NoNewWindow "${{ env.BIN_OUT }}\dockerd" `
@ -401,6 +405,11 @@ jobs:
Start-Sleep -Seconds 1
}
Write-Host "Test daemon started and replied!"
If ("${{ matrix.runtime }}" -eq "containerd") {
If (-not (Get-Process -Name containerd -ErrorAction:SilentlyContinue)) {
Throw "containerd process is not running"
}
}
env:
DOCKER_HOST: npipe:////./pipe/docker_engine
-
@ -466,14 +475,14 @@ jobs:
DOCKER_HOST: npipe:////./pipe/docker_engine
-
name: Stop containerd
if: always() && matrix.runtime == 'containerd'
if: always() && matrix.runtime == 'containerd' && matrix.os == 'windows-2019'
run: |
$ErrorActionPreference = "SilentlyContinue"
Stop-Service -Force -Name containerd
$ErrorActionPreference = "Stop"
-
name: Containerd logs
if: always() && matrix.runtime == 'containerd'
if: always() && matrix.runtime == 'containerd' && matrix.os == 'windows-2019'
run: |
Copy-Item "$env:TEMP\ctn.log" -Destination ".\bundles\containerd.log"
Get-Content "$env:TEMP\ctn.log" | Out-Host

View file

@ -4,11 +4,15 @@ import (
"context"
"fmt"
"os"
"path/filepath"
"time"
"github.com/containerd/log"
"github.com/docker/docker/daemon/config"
"github.com/docker/docker/libcontainerd/supervisor"
"github.com/docker/docker/pkg/system"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/sys/windows"
)
@ -57,6 +61,17 @@ func notifyShutdown(err error) {
}
}
func (cli *DaemonCli) getPlatformContainerdDaemonOpts() ([]supervisor.DaemonOpt, error) {
opts := []supervisor.DaemonOpt{
// On Windows, it first checks if a containerd binary is found in the same
// directory as the dockerd binary. If found, this binary takes precedence
// over containerd binaries installed in $PATH.
supervisor.WithDetectLocalBinary(),
}
return opts, nil
}
// setupConfigReloadTrap configures a Win32 event to reload the configuration.
func (cli *DaemonCli) setupConfigReloadTrap() {
go func() {
@ -89,9 +104,32 @@ func newCgroupParent(config *config.Config) string {
return ""
}
func (cli *DaemonCli) initContainerd(_ context.Context) (func(time.Duration) error, error) {
system.InitContainerdRuntime(cli.ContainerdAddr)
return nil, nil
func (cli *DaemonCli) initContainerd(ctx context.Context) (func(time.Duration) error, error) {
if cli.ContainerdAddr != "" {
// use system containerd at the given address.
system.InitContainerdRuntime(cli.ContainerdAddr)
return nil, nil
}
if cli.DefaultRuntime != config.WindowsV2RuntimeName {
return nil, nil
}
logrus.Info("containerd not running, starting managed containerd")
opts, err := cli.getContainerdDaemonOpts()
if err != nil {
return nil, errors.Wrap(err, "failed to generate containerd options")
}
r, err := supervisor.Start(ctx, filepath.Join(cli.Root, "containerd"), filepath.Join(cli.ExecRoot, "containerd"), opts...)
if err != nil {
return nil, errors.Wrap(err, "failed to start containerd")
}
cli.ContainerdAddr = r.Address()
system.InitContainerdRuntime(r.Address())
// Try to wait for containerd to shutdown
return r.WaitTimeout, nil
}
func validateCPURealtimeOptions(_ *config.Config) error {

View file

@ -38,6 +38,11 @@ const (
userlandProxyBinary = "docker-proxy"
)
var builtinRuntimes = map[string]bool{
StockRuntimeName: true,
LinuxV2RuntimeName: true,
}
// BridgeConfig stores all the parameters for both the bridge driver and the default bridge network.
type BridgeConfig struct {
DefaultBridgeConfig

View file

@ -13,8 +13,16 @@ const (
// default value. On Windows keep this empty so the value is auto-detected
// based on other options.
StockRuntimeName = ""
WindowsV1RuntimeName = "com.docker.hcsshim.v1"
WindowsV2RuntimeName = "io.containerd.runhcs.v1"
)
var builtinRuntimes = map[string]bool{
WindowsV1RuntimeName: true,
WindowsV2RuntimeName: true,
}
// BridgeConfig is meant to store all the parameters for both the bridge driver and the default bridge network. On
// Windows: 1. "bridge" in this context reference the nat driver and the default nat network; 2. the nat driver has no
// specific parameters, so this struct effectively just stores parameters for the default nat network.

View file

@ -40,9 +40,6 @@ const (
windowsMaxCPUShares = 10000
windowsMinCPUPercent = 1
windowsMaxCPUPercent = 100
windowsV1RuntimeName = "com.docker.hcsshim.v1"
windowsV2RuntimeName = "io.containerd.runhcs.v1"
)
// Windows containers are much larger than Linux containers and each of them
@ -567,14 +564,14 @@ func (daemon *Daemon) initLibcontainerd(ctx context.Context, cfg *config.Config)
rt := cfg.DefaultRuntime
if rt == "" {
if cfg.ContainerdAddr == "" {
rt = windowsV1RuntimeName
rt = config.WindowsV1RuntimeName
} else {
rt = windowsV2RuntimeName
rt = config.WindowsV2RuntimeName
}
}
switch rt {
case windowsV1RuntimeName:
case config.WindowsV1RuntimeName:
daemon.containerd, err = local.NewClient(
ctx,
daemon.containerdClient,
@ -582,7 +579,7 @@ func (daemon *Daemon) initLibcontainerd(ctx context.Context, cfg *config.Config)
cfg.ContainerdNamespace,
daemon,
)
case windowsV2RuntimeName:
case config.WindowsV2RuntimeName:
if cfg.ContainerdAddr == "" {
return fmt.Errorf("cannot use the specified runtime %q without containerd", rt)
}

View file

@ -3,13 +3,14 @@ package daemon // import "github.com/docker/docker/daemon"
import (
"github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/options"
"github.com/docker/docker/container"
"github.com/docker/docker/daemon/config"
"github.com/docker/docker/pkg/system"
)
func (daemon *Daemon) getLibcontainerdCreateOptions(*configStore, *container.Container) (string, interface{}, error) {
if system.ContainerdRuntimeSupported() {
opts := &options.Options{}
return "io.containerd.runhcs.v1", opts, nil
return config.WindowsV2RuntimeName, opts, nil
}
return "", nil, nil
}

View file

@ -30,7 +30,6 @@ const (
shutdownTimeout = 15 * time.Second
startupTimeout = 15 * time.Second
configFile = "containerd.toml"
binaryName = "containerd"
pidFile = "containerd.pid"
)
@ -41,9 +40,13 @@ type remote struct {
// file is saved.
configFile string
daemonPid int
pidFile string
logger *log.Entry
// daemonPath is the binary to execute, and can be either a basename (to use
// a binary installed in the system's $PATH), or the full path to the binary
// to use.
daemonPath string
daemonPid int
pidFile string
logger *log.Entry
daemonWaitCh chan struct{}
daemonStartCh chan error
@ -78,6 +81,7 @@ func Start(ctx context.Context, rootDir, stateDir string, opts ...DaemonOpt) (Da
State: filepath.Join(stateDir, "daemon"),
},
configFile: filepath.Join(stateDir, configFile),
daemonPath: binaryName,
daemonPid: -1,
pidFile: filepath.Join(stateDir, pidFile),
logger: log.G(ctx).WithField("module", "libcontainerd"),
@ -165,7 +169,8 @@ func (r *remote) startContainerd() error {
args = append(args, "--log-level", r.logLevel)
}
cmd := exec.Command(binaryName, args...)
r.logger.WithField("binary", r.daemonPath).Debug("starting containerd binary")
cmd := exec.Command(r.daemonPath, args...)
// redirect containerd logs to docker logs
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr

View file

@ -11,6 +11,7 @@ import (
)
const (
binaryName = "containerd"
sockFile = "containerd.sock"
debugSockFile = "containerd-debug.sock"
)

View file

@ -1,4 +1,10 @@
package supervisor // import "github.com/docker/docker/libcontainerd/supervisor"
import (
"os"
"path/filepath"
"github.com/pkg/errors"
)
import (
"github.com/containerd/log"
@ -33,3 +39,30 @@ func WithCRIDisabled() DaemonOpt {
return nil
}
}
// WithDetectLocalBinary checks if a containerd binary is present in the same
// directory as the dockerd binary, and overrides the path of the containerd
// binary to start if found. If no binary is found, no changes are made.
func WithDetectLocalBinary() DaemonOpt {
return func(r *remote) error {
dockerdPath, err := os.Executable()
if err != nil {
return errors.Wrap(err, "looking up binary path")
}
localBinary := filepath.Join(filepath.Dir(dockerdPath), binaryName)
fi, err := os.Stat(localBinary)
if err != nil {
if !errors.Is(err, os.ErrNotExist) {
return err
}
return nil
}
if fi.IsDir() {
return errors.Errorf("local containerd path found (%s), but is a directory", localBinary)
}
r.daemonPath = localBinary
r.logger.WithError(err).WithField("binary", localBinary).Debug("failed to look up local containerd binary; using default binary")
return nil
}
}

View file

@ -7,8 +7,9 @@ import (
)
const (
grpcPipeName = `\\.\pipe\containerd-containerd`
debugPipeName = `\\.\pipe\containerd-debug`
binaryName = "containerd.exe"
grpcPipeName = `\\.\pipe\docker-containerd`
debugPipeName = `\\.\pipe\docker-containerd-debug`
)
func (r *remote) setDefaults() {