Skip to content

No output and hangs up without TTY mode #12198

@dex4er

Description

@dex4er

Description

gvisor (runsc) does not produce any output and hangs up if TTY mode (ie. --tty or oci.WithTTY) is not used.

I use containerd directly (either with ctr command or with github.com/containerd/containerd Go package).

Steps to reproduce

ctr run --runtime io.containerd.runsc.v1 docker.io/library/alpine:latest shell-$RANDOM ls -l

or

package main

import (
	"context"
	"fmt"
	"os"

	"github.com/containerd/containerd"
	"github.com/containerd/containerd/cio"
	"github.com/containerd/containerd/namespaces"
	"github.com/containerd/containerd/oci"
	specs "github.com/opencontainers/runtime-spec/specs-go"
)

func main() {
	if len(os.Args) < 2 {
		fmt.Println("Usage: go-ctr-run <image-name> <container-name> <command> <args>")
		os.Exit(1)
	}

	imageName := os.Args[1]
	containerName := os.Args[2]
	snapshotName := containerName + "-snapshot"
	command := os.Args[3:]

	ctx := namespaces.WithNamespace(context.Background(), "default") // ---namespace=default

	// connect to containerd
	client, err := containerd.New("/run/containerd/containerd.sock")
	if err != nil {
		panic(err)
	}
	defer client.Close()

	// pull image
	image, err := client.Pull(ctx, imageName, containerd.WithPullUnpack)
	if err != nil {
		panic(err)
	}

	// create a new container
	container, err := client.NewContainer(
		ctx,
		containerName,
		containerd.WithImage(image),
		containerd.WithNewSnapshot(snapshotName, image),
		containerd.WithRuntime("io.containerd.runsc.v1", nil), // --runtime=io.containerd.runsc.v1
		containerd.WithNewSpec(
			oci.WithProcessArgs(command...),
			oci.WithHostNamespace(specs.NetworkNamespace), // --net-host
			oci.WithEnv([]string{"TERM=dump", "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}),
			// oci.WithTTY, // --tty
		),
	)
	if err != nil {
		panic(err)
	}
	defer container.Delete(ctx, containerd.WithSnapshotCleanup) // --rm

	// create a task
	task, err := container.NewTask(ctx, cio.NewCreator(
		cio.WithStdio,
		// cio.WithTerminal,
	))
	if err != nil {
		panic(err)
	}
	defer task.Delete(ctx)

	// start task
	if err := task.Start(ctx); err != nil {
		panic(err)
	}

	// wait for exit
	statusC, err := task.Wait(ctx)
	if err != nil {
		panic(err)
	}

	// get exit code
	status := <-statusC
	code, _, err := status.Result()
	if err != nil {
		panic(err)
	}
	fmt.Printf("Container exited with code %d\n", code)
}

then

./go-ctr-run docker.io/library/alpine:latest shell-$RANDOM ls -l

runsc version

runsc version release-20250820.0
spec: 1.2.0

docker version (if using docker)

containerd github.com/containerd/containerd/v2 2.0.6 991cc3363c290ffd074e069f2b3034c7286ecbe0


or


containerd github.com/containerd/containerd 1.7.27

uname

6.12.40-64.114.amzn2023.x86_64 or 6.8.0-83-generic

kubectl (if using Kubernetes)

repo state (if built from source)

No response

runsc debug logs (if available)

I'm not sure how to enable debug for shim (I'm not using CRI!)

containerd with debug mode:

time="2025-10-06T11:21:16.742479944Z" level=debug msg="Ignoring events in namespace - \"default\""
time="2025-10-06T11:21:16.749041208Z" level=debug msg="prepare snapshot" key=bash-26343-snapshot parent="sha256:418dccb7d85a63a6aa574439840f7a6fa6fd2321b3e2394568a317735e867d35" snapshotter=overlayfs
time="2025-10-06T11:21:16.756494829Z" level=debug msg="get snapshot mounts" key=bash-26343-snapshot snapshotter=overlayfs
time="2025-10-06T11:21:16.850869950Z" level=info msg="connecting to shim bash-26343" address="unix:///run/containerd/s/894e1ca2baeed4e5ba38bea27f2860a20948a993d49db52c4d7662973e98e99c" namespace=default protocol=ttrpc version=2
time="2025-10-06T11:21:16.936539136Z" level=info msg="loading plugin \"io.containerd.event.v1.publisher\"..." runtime=io.containerd.runsc.v1 type=io.containerd.event.v1
time="2025-10-06T11:21:16.936588143Z" level=info msg="loading plugin \"io.containerd.ttrpc.v1.task\"..." runtime=io.containerd.runsc.v1 type=io.containerd.ttrpc.v1
time="2025-10-06T11:21:16.936603028Z" level=debug msg="registering ttrpc service" id=io.containerd.ttrpc.v1.task
time="2025-10-06T11:21:16.936611912Z" level=info msg="loading plugin \"io.containerd.internal.v1.shutdown\"..." runtime=io.containerd.runsc.v1 type=io.containerd.internal.v1
time="2025-10-06T11:21:16.936765347Z" level=debug msg="serving api on socket" socket="[inherited from parent]"
time="2025-10-06T11:21:16.936806074Z" level=info msg="starting signal loop" namespace=default path=/run/containerd/io.containerd.runtime.v2.task/default/bash-26343 pid=1190 runtime=io.containerd.runsc.v1
time="2025-10-06T11:21:16.937075849Z" level=debug msg="Create, id: bash-26343, bundle: \"/run/containerd/io.containerd.runtime.v2.task/default/bash-26343\""
time="2025-10-06T11:21:16.938498574Z" level=debug msg="Executing: [runsc --root=/run/containerd/runsc/default --log=/run/containerd/io.containerd.runtime.v2.task/default/bash-26343/log.json --log-format=json create --bundle /run/containerd/io.containerd.runtime.v2.task/default/bash-26343 --pid-file /run/containerd/io.containerd.runtime.v2.task/default/bash-26343/init.pid bash-26343]"

Metadata

Metadata

Assignees

No one assigned

    Labels

    type: bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions