简体   繁体   English

如何使用 Docker.DotNet (NET CORE) 连接到工作容器

[英]How to attach to working container with Docker.DotNet (NET CORE)

I try to use https://github.com/dotnet/Docker.DotNet for control docker container.我尝试使用https://github.com/dotnet/Docker.DotNet来控制 docker 容器。 One of important future to working with running container is attaching to running container with one command.使用正在运行的容器的重要未来之一是使用一个命令附加到正在运行的容器。 Or with /bin/bash if we can attach interactively.或者 /bin/bash 如果我们可以交互附加。 So, this is command:所以,这是命令:

# sudo docker exec -it 7dde487b4424 bash
# sudo docker exec -it 7dde487b4424 pwd

Unfortunately, I can not found this command Docker.DotNet, some functions has similar name, but has no parameters like "bash command"不幸的是,我找不到这个命令 Docker.DotNet,有些函数名称相似,但没有像“bash 命令”这样的参数

Public Interface IContainerOperations
    Function ListContainersAsync(parameters As ContainersListParameters, Optional cancellationToken As CancellationToken = Nothing) As Task(Of IList(Of ContainerListResponse))
    Function ExtractArchiveToContainerAsync(id As String, parameters As ContainerPathStatParameters, stream As Stream, Optional cancellationToken As CancellationToken = Nothing) As Task
    Function GetArchiveFromContainerAsync(id As String, parameters As GetArchiveFromContainerParameters, statOnly As Boolean, Optional cancellationToken As CancellationToken = Nothing) As Task(Of GetArchiveFromContainerResponse)
    Function RemoveContainerAsync(id As String, parameters As ContainerRemoveParameters, Optional cancellationToken As CancellationToken = Nothing) As Task
    Function WaitContainerAsync(id As String, Optional cancellationToken As CancellationToken = Nothing) As Task(Of ContainerWaitResponse)
    Function AttachContainerAsync(id As String, tty As Boolean, parameters As ContainerAttachParameters, Optional cancellationToken As CancellationToken = Nothing) As Task(Of MultiplexedStream)
    Function UnpauseContainerAsync(id As String, Optional cancellationToken As CancellationToken = Nothing) As Task
    Function PauseContainerAsync(id As String, Optional cancellationToken As CancellationToken = Nothing) As Task
    Function RenameContainerAsync(id As String, parameters As ContainerRenameParameters, cancellationToken As CancellationToken) As Task
    Function KillContainerAsync(id As String, parameters As ContainerKillParameters, Optional cancellationToken As CancellationToken = Nothing) As Task
    Function RestartContainerAsync(id As String, parameters As ContainerRestartParameters, Optional cancellationToken As CancellationToken = Nothing) As Task
    Function StopContainerAsync(id As String, parameters As ContainerStopParameters, Optional cancellationToken As CancellationToken = Nothing) As Task(Of Boolean)
    Function StartContainerAsync(id As String, parameters As ContainerStartParameters, Optional cancellationToken As CancellationToken = Nothing) As Task(Of Boolean)
    Function ResizeContainerTtyAsync(id As String, parameters As ContainerResizeParameters, Optional cancellationToken As CancellationToken = Nothing) As Task
    Function GetContainerStatsAsync(id As String, parameters As ContainerStatsParameters, progress As IProgress(Of ContainerStatsResponse), Optional cancellationToken As CancellationToken = Nothing) As Task
    <Obsolete("Use 'Task GetContainerStatsAsync(string id, ContainerStatsParameters parameters, CancellationToken cancellationToken, IProgress<JSONMessage> progress)'")>
    Function GetContainerStatsAsync(id As String, parameters As ContainerStatsParameters, cancellationToken As CancellationToken) As Task(Of Stream)
    Function ExportContainerAsync(id As String, Optional cancellationToken As CancellationToken = Nothing) As Task(Of Stream)
    Function InspectChangesAsync(id As String, Optional cancellationToken As CancellationToken = Nothing) As Task(Of IList(Of ContainerFileSystemChangeResponse))
    Function GetContainerLogsAsync(id As String, tty As Boolean, parameters As ContainerLogsParameters, Optional cancellationToken As CancellationToken = Nothing) As Task(Of MultiplexedStream)
    Function GetContainerLogsAsync(id As String, parameters As ContainerLogsParameters, cancellationToken As CancellationToken, progress As IProgress(Of String)) As Task
    <Obsolete("The stream returned by this method won't be demultiplexed properly if the container was created without a TTY. Use GetContainerLogsAsync(string, bool, ContainerLogsParameters, CancellationToken) instead")>
    Function GetContainerLogsAsync(id As String, parameters As ContainerLogsParameters, Optional cancellationToken As CancellationToken = Nothing) As Task(Of Stream)
    Function ListProcessesAsync(id As String, parameters As ContainerListProcessesParameters, Optional cancellationToken As CancellationToken = Nothing) As Task(Of ContainerProcessesResponse)
    Function InspectContainerAsync(id As String, Optional cancellationToken As CancellationToken = Nothing) As Task(Of ContainerInspectResponse)
    Function CreateContainerAsync(parameters As CreateContainerParameters, Optional cancellationToken As CancellationToken = Nothing) As Task(Of CreateContainerResponse)
    Function PruneContainersAsync(Optional parameters As ContainersPruneParameters = Nothing, Optional cancellationToken As CancellationToken = Nothing) As Task(Of ContainersPruneResponse)
    Function UpdateContainerAsync(id As String, parameters As ContainerUpdateParameters, Optional cancellationToken As CancellationToken = Nothing) As Task(Of ContainerUpdateResponse)
End Interface

UPD: According to notes @kthompso UPD:根据注释@kthompso

If we can see to exec interface如果我们可以看到执行界面

Public Interface IExecOperations
    Function ExecCreateContainerAsync(id As String, parameters As ContainerExecCreateParameters, Optional cancellationToken As CancellationToken = Nothing) As Task(Of ContainerExecCreateResponse)
    Function StartContainerExecAsync(id As String, Optional cancellationToken As CancellationToken = Nothing) As Task
    Function StartAndAttachContainerExecAsync(id As String, tty As Boolean, Optional cancellationToken As CancellationToken = Nothing) As Task(Of MultiplexedStream)
    Function StartWithConfigContainerExecAsync(id As String, eConfig As ContainerExecStartParameters, Optional cancellationToken As CancellationToken = Nothing) As Task(Of MultiplexedStream)
    Function ResizeContainerExecTtyAsync(id As String, parameters As ContainerResizeParameters, Optional cancellationToken As CancellationToken = Nothing) As Task
    Function InspectContainerExecAsync(id As String, Optional cancellationToken As CancellationToken = Nothing) As Task(Of ContainerExecInspectResponse)
End Interface

We can see only two methods with CMD parameters - ExecCreateContainerAsync and StartWithConfigContainerExecAsync.我们只能看到两个带有 CMD 参数的方法——ExecCreateContainerAsync 和 StartWithConfigContainerExecAsync。

I try to use it我尝试使用它

            AttachToContainer(DockerHub, ContainerId, CMD, LogCtsSrc.Token)
            ReadContainerLog(DockerHub, ContainerId, Sub(X) Console.WriteLine(X), LogCtsSrc.Token)

            Function AttachToContainer(DockerHub As DockerClient, ContainerID As String, Cmd As IList(Of String), ExecCts As CancellationToken) As Task(Of ContainerExecCreateResponse)
                Dim ExecTask As Task(Of ContainerExecCreateResponse) = DockerHub.Exec.ExecCreateContainerAsync(ContainerID, New ContainerExecCreateParameters With {
                                 .AttachStdin = False,
                                 .AttachStderr = True,
                                 .AttachStdout = True,
                                 .Tty = False,
                                 .Cmd = Cmd
                                },
                                ExecCts)
                 Return ExecTask
             End Function

And receive nothing, only old part of container log instead response of my commands in CMD.并且什么也没收到,只有容器日志的旧部分,而不是我在 CMD 中的命令的响应。

在此处输入图像描述

It's not looks as result of standard docker operation as它看起来不是标准 docker 操作的结果

 # sudo docker exec -it 7dde487b4424 pwd

You are only creating the exec instance but you are not starting it.您只是在创建exec 实例,但没有启动它。 From the documentation :文档中:

Exec执行

Run new commands inside running containers.在正在运行的容器中运行新命令。 Refer to the command-line reference for more information.有关详细信息,请参阅命令行参考

To exec a command in a container, you first need to create an exec instance, then start it .要在容器中执行命令,首先需要创建一个 exec 实例,然后启动它 These two API endpoints are wrapped up in a single command-line command, docker exec .这两个 API 端点包含在一个命令行命令docker exec中。

Example Program示例程序

using Docker.DotNet;
using Docker.DotNet.Models;

namespace App
{
    public class Program
    {
        private static void Usage()
        {
            Console.WriteLine("Usage: dotnet run <container-id-or-name> <commands...>");
        }

        public async static Task Main(string[] args)
        {
            if (args.Length < 2)
            {
                Usage();
                return;
            }

            await ExecAsync(args[0], args[1..^0]);
        }

        private static async Task ExecAsync(string imageIdOrName, string[] command)
        {
            DockerClient client = new DockerClientConfiguration(
                new Uri("unix:///var/run/docker.sock"))
                    .CreateClient();

            var execParams = new ContainerExecCreateParameters()
            {
                AttachStderr = true,
                AttachStdout = true,
                Cmd = command,
            };

            # Create the exec instance, it is not started yet.
            var exec = await client.Exec.ExecCreateContainerAsync(imageIdOrName, execParams);
            # Start the exec instance and capture the output stream.
            var stream = await client.Exec.StartAndAttachContainerExecAsync(exec.ID, false);
            await stream.CopyOutputToAsync(
                null,
                Console.OpenStandardOutput(),
                Console.OpenStandardError(),
                CancellationToken.None);
        }
    }
}

Example Program Output示例程序 Output

# Create a running container
$ docker run --name docker-dotnet-test -d alpine tail -f
38a4dac4c5a2d42d57defbaa17778bb071a94e5a69c6427078ad278334fe5598
# Call our program with the container name and a command
$ dotnet run docker-dotnet-test echo hello world
hello world

Notes笔记

  • I'm using the StartAndAttachContainerExecAsync method to capture stdout/stderr.我正在使用StartAndAttachContainerExecAsync方法来捕获 stdout/stderr。 You can use StartContainerExecAsync if you don't care about the streams.如果您不关心流,则可以使用StartContainerExecAsync

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM