

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# Docker 队列环境概述
<a name="containers-queue-environment"></a>

默认Docker队列环境声明了`EXPR`和 `WRAP_ACTIONS` OpenJD 扩展。它自己的进入和退出操作管理工作Docker程序上的无根守护程序和会话容器。队列环境处于活动状态时，三个封装操作取代了内部环境和任务的操作。

以下流程显示了队列环境如何封装任务操作：

1. 便携式作业模板提供了`onRun`命令及其参数。

1. 会话运行时将原始`onRun`操作封装在里面，`onWrapTaskRun`而不是直接运行命令。

1. 钩子将`WrappedAction.Command``WrappedAction.Args`、和作为单独的参数传递`WrappedAction.Environment`给静态包装脚本。

1. 包装脚本`docker container exec`用于在无根会话容器中运行原始命令和参数。

包装环境的`onEnter`操作启动会话容器，其`onExit`操作停止容器。容器绑定将会话目录挂载到同一路径。它还可以为可重复使用的缓存绑定挂载永久存储。

![便携式作业模板将其原始的 onRun 操作传递到开启边WrapTaskRun界。该操作作为 WrappedAction 值传递给静态包装脚本，并在无根会话容器中运行。队列环境启动和停止容器，容器装载会话目录和可选的永久存储。](https://docs.aws.amazon.com/zh_cn/deadline-cloud/latest/developerguide/images/wrap-actions-flow.png)



| 队列环境操作 | 跑进来 | 用途 | 
| --- | --- | --- | 
| onEnter | 工作线程 | 启动无根守护程序，向 Amazon ECR 进行身份验证，提取映像，然后启动会话容器。 | 
| onWrapEnvEnter | Container | 运行内部环境的回车操作。 | 
| onWrapTaskRun | Container | 运行每个任务的应用程序命令和参数。 | 
| onWrapEnvExit | Container | 运行内部环境的退出操作。 | 
| onExit | 工作线程 | 停止会话容器、无根守护程序和用户管理器。 | 

包装环境必须定义所有三个包装操作。每个挂钩都通过`WrappedAction.Command``WrappedAction.Args`、和接收原始动作`WrappedAction.Environment`。以下部分模板显示了默认环境如何转发这些值：

```
specificationVersion: "environment-2023-09"
extensions:
  - WRAP_ACTIONS
  - EXPR
environment:
  name: DockerContainer
  script:
    actions:
      onWrapEnvEnter:
        command: bash
        args:
          - "{{Env.File.Wrap}}"
          - "{{ flatten([['-e', e] for e in WrappedAction.Environment]) }}"
          - "--"
          - "{{WrappedAction.Command}}"
          - "{{WrappedAction.Args}}"
      onWrapTaskRun:
        command: bash
        args:
          - "{{Env.File.Wrap}}"
          - "{{ flatten([['-e', e] for e in WrappedAction.Environment]) }}"
          - "--"
          - "{{WrappedAction.Command}}"
          - "{{WrappedAction.Args}}"
      onWrapEnvExit:
        command: bash
        args:
          - "{{Env.File.Wrap}}"
          - "{{ flatten([['-e', e] for e in WrappedAction.Environment]) }}"
          - "--"
          - "{{WrappedAction.Command}}"
          - "{{WrappedAction.Args}}"
```

wrap 脚本将命令作为参数向量接收，并在 rootless 中以非`job-user`特权Docker身份运行原始操作。该脚本仅从主机转发已知的基于使用量的许可证变量。它不会将 AWS 证书转发到容器中。

默认环境将会话工作目录安装在同一路径上。当容器设备接口 (CDI) 可用时，它会通过容器设备接口 (CDI) 选择 GPU，并传播封装操作的退出状态。有关数据共享的详细信息，请参阅[共享会话工作目录](containers-share-session-directory.md)。

## 自定义 Docker 队列环境
<a name="containers-queue-customize"></a>

控制台创建默认Docker队列环境。您可以使用该模板作为应用程序特定的挂载、环境变量、网络、图像选择和运行时选项的起点。自定义模板时，保留无根守护程序生命周期、会话目录挂载以及所有三个包装挂钩。

该`EXPR`扩展支持条件表达式。以下部分输入脚本示例在两个图像之间进行选择，并仅在参数为真时添加 GPU `UseGpu` 参数：

```
IMAGE={{ repr_sh(Param.GpuImage if Param.UseGpu else Param.CpuImage) }}
GPU_ARGS=({{ repr_sh(['--gpus', 'all'] if Param.UseGpu else []) }})

docker container run \
    --rm \
    --detach \
    "${GPU_ARGS[@]}" \
    --mount {{ repr_sh("type=bind,src=" + Session.WorkingDirectory + ",dst=" + Session.WorkingDirectory) }} \
    --workdir {{ repr_sh(Session.WorkingDirectory) }} \
    "$IMAGE"
```

您也可以在每个挂接中有条件地选择包装脚本。以下部分操作从一个队列环境参数中选择容器包装器或主机封装器：

```
onWrapTaskRun:
  command: bash
  args:
    - "{{ Env.File.WrapContainer if Param.RunInContainer else Env.File.WrapHost }}"
    - "{{ flatten([['-e', e] for e in WrappedAction.Environment]) }}"
    - "--"
    - "{{WrappedAction.Command}}"
    - "{{WrappedAction.Args}}"
```

对`onWrapEnvEnter`、`onWrapTaskRun`和使用相同的运行时条件`onWrapEnvExit`。将所有生命周期阶段保持在同一个运行时可以防止内部环境进入一个上下文而在另一个上下文中退出。即使条件选择了主机封装器，该`WRAP_ACTIONS`扩展也需要全部三个挂钩。

主机包装器必须应用`WrappedAction.Environment`，保留原始参数边界，并返回封装操作的退出状态。将命令和参数值作为参数向量传递。不要将原始值组合成字符串`bash -c`。有关报价规则，请参阅[指挥构造和逃跑](containers-security.md#containers-security-command-construction)。

## OpenJD 规格
<a name="containers-openjd-references"></a>

 GitHub 网站上的 [OpenJD 表达式语言提案](https://github.com/OpenJobDescription/openjd-specifications/blob/mainline/rfcs/0005-expression-language.md)定义了表达式评估、键入路径和会话符号。

 GitHub 网站上的 [OpenJD 表达式函数库提案](https://github.com/OpenJobDescription/openjd-specifications/blob/mainline/rfcs/0006-expression-function-library.md)定义了函数`flatten`和`repr_*`函数。

 GitHub 网站上的 [OpenJD 扩展参数类型提案](https://github.com/OpenJobDescription/openjd-specifications/blob/mainline/rfcs/0007-extend-parameter-types.md)定义了便携式模板可以使用的列表值参数。

 GitHub 网站上的 [OpenJD 环境包装操作提案](https://github.com/OpenJobDescription/openjd-specifications/blob/mainline/rfcs/0008-environment-wrap-actions.md)定义了三个包装钩子和`WrappedAction.*`值。