构建应用程序容器 - AWS RoboMaker

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

构建应用程序容器

在 AWS RoboMaker 中提交模拟作业有三个步骤:构建应用程序容器、将容器链接到 AWS RoboMaker 应用程序,以及使用容器提交模拟作业。本节介绍如何使用 Docker 为 AWS RoboMaker 构建应用程序容器。我们使用 hello-world 示例应用程序来演示为基于 ROS 的示例构建示例机器人和模拟应用程序容器所需的步骤。本页还演示了如何在本地测试您的容器。

如果您不使用 ROS,请参阅博客文章,其中介绍了如何在 AWS RoboMaker 中在 GPU 和容器支持下运行任何高保真模拟

先决条件

在开始之前,请确保您的开发环境具有必要的依赖关系。您的计算机上必须安装 Docker、AWS CLI、和 VCS 导入工具。

sudo pip3 install vcstool

您还必须拥有一个包含以下权限的 IAM 角色的 AWS 账户:

  • 创建 IAM 角色

  • 创建 AWS RoboMaker 资源(模拟作业、机器人和模拟应用程序)

  • 创建和上传 Amazon ECR 存储库

最后,您必须知道自己的账号,并且必须选择要在其中运行模拟的区域。AWS RoboMaker 在列出的以下区域中受支持AWS RoboMaker 终端节点和配额

从 ROS 工作区构建应用程序容器

AWS RoboMaker 模拟由一个模拟应用程序和一个可选机器人应用程序组成。这些应用程序中的每一个都由名称和容器映像定义。本节演示如何为模拟应用程序和机器人应用程序构建容器映像。在以下示例中,两个应用程序均在单个工作区内构建。接下来的方法可以很容易地推广到任何 ROS 项目。

首先,克隆 hello world 存储库并导入源代码。

git clone https://github.com/aws-robotics/aws-robomaker-sample-application-helloworld.git helloworld cd helloworld vcs import robot_ws < robot_ws/.rosinstall vcs import simulation_ws < simulation_ws/.rosinstall

然后在 helloworld 目录中创建一个新文件并将其命名为 Dockerfile。复制并粘贴以下内容:

# ======== ROS/Colcon Dockerfile ======== # This sample Dockerfile will build a Docker image for AWS RoboMaker # in any ROS workspace where all of the dependencies are managed by rosdep. # # Adapt the file below to include your additional dependencies/configuration # outside of rosdep. # ======================================= # ==== Arguments ==== # Override the below arguments to match your application configuration. # =================== # ROS Distribution (ex: melodic, foxy, etc.) ARG ROS_DISTRO=melodic # Application Name (ex: helloworld) ARG APP_NAME=robomaker_app # Path to workspace directory on the host (ex: ./robot_ws) ARG LOCAL_WS_DIR=workspace # User to create and use (default: robomaker) ARG USERNAME=robomaker # The gazebo version to use if applicable (ex: gazebo-9, gazebo-11) ARG GAZEBO_VERSION=gazebo-9 # Where to store the built application in the runtime image. ARG IMAGE_WS_DIR=/home/$USERNAME/workspace # ======== ROS Build Stages ======== # ${ROS_DISTRO}-ros-base # -> ros-robomaker-base # -> ros-robomaker-application-base # -> ros-robomaker-build-stage # -> ros-robomaker-app-runtime-image # ================================== # ==== ROS Base Image ============ # If running in production, you may choose to build the ROS base image # from the source instruction-set to prevent impact from upstream changes. # ARG UBUNTU_DISTRO=focal # FROM public.ecr.aws/lts/ubuntu:${UBUNTU_DISTRO} as ros-base # Instruction for each ROS release maintained by OSRF can be found here: # https://github.com/osrf/docker_images # ================================== # ==== Build Stage with AWS RoboMaker Dependencies ==== # This stage creates the robomaker user and installs dependencies required # to run applications in RoboMaker. # ================================== FROM public.ecr.aws/docker/library/ros:${ROS_DISTRO}-ros-base AS ros-robomaker-base ARG USERNAME ARG IMAGE_WS_DIR RUN apt-get clean RUN apt-get update && apt-get install -y \ lsb \ unzip \ wget \ curl \ xterm \ python3-colcon-common-extensions \ devilspie \ xfce4-terminal RUN groupadd $USERNAME && \ useradd -ms /bin/bash -g $USERNAME $USERNAME && \ sh -c 'echo "$USERNAME ALL=(root) NOPASSWD:ALL" >> /etc/sudoers' USER $USERNAME WORKDIR /home/$USERNAME RUN mkdir -p $IMAGE_WS_DIR # ==== ROS Application Base ==== # This section installs exec dependencies for your ROS application. # Note: Make sure you have defined 'exec' and 'build' dependencies correctly # in your package.xml files. # ======================================== FROM ros-robomaker-base as ros-robomaker-application-base ARG LOCAL_WS_DIR ARG IMAGE_WS_DIR ARG ROS_DISTRO ARG USERNAME WORKDIR $IMAGE_WS_DIR COPY --chown=$USERNAME:$USERNAME $LOCAL_WS_DIR/src $IMAGE_WS_DIR/src RUN sudo apt update && \ rosdep update && \ rosdep fix-permissions # Note: This will install all dependencies. # You could further optimize this by only defining the exec dependencies. # Then, install the build dependencies in the build image. RUN rosdep install --from-paths src --ignore-src -r -y # ==== ROS Workspace Build Stage ==== # In this stage, we will install copy source files, install build dependencies # and run a build. # =================================== FROM ros-robomaker-application-base AS ros-robomaker-build-stage LABEL build_step="${APP_NAME}Workspace_Build" ARG APP_NAME ARG LOCAL_WS_DIR ARG IMAGE_WS_DIR RUN . /opt/ros/$ROS_DISTRO/setup.sh && \ colcon build \ --install-base $IMAGE_WS_DIR/$APP_NAME # ==== ROS Robot Runtime Image ==== # In the final stage, we will copy the staged install directory to the runtime # image. # ================================= FROM ros-robomaker-application-base AS ros-robomaker-app-runtime-image ARG APP_NAME ARG USERNAME ARG GAZEBO_VERSION ENV USERNAME=$USERNAME ENV APP_NAME=$APP_NAME ENV GAZEBO_VERSION=$GAZEBO_VERSION RUN rm -rf $IMAGE_WS_DIR/src COPY --from=ros-robomaker-build-stage $IMAGE_WS_DIR/$APP_NAME $IMAGE_WS_DIR/$APP_NAME # Add the application source file to the entrypoint. WORKDIR / COPY entrypoint.sh /entrypoint.sh RUN sudo chmod +x /entrypoint.sh && \ sudo chown -R $USERNAME /entrypoint.sh && \ sudo chown -R $USERNAME $IMAGE_WS_DIR/$APP_NAME ENTRYPOINT ["/entrypoint.sh"]

您刚创建的 Dockerfile 是用于构建 Docker 映像的指令集。通读 Dockerfile 中的评论,了解正在构建的内容,并根据需要进行调整。为便于开发,Dockerfile 基于开源机器人基金会 (OSRF)维护的官方 ROS Docker 映像。但是,在生产环境中运行时,您可以选择使用 GitHub 中设置的 OSRF 源指令来构建 ROS 基础映像,以防止上游更改的影响。

接着创建名为 entrypoint.sh 的新文件。

#!/bin/bash set -e source "/home/$USERNAME/workspace/$APP_NAME/setup.bash" if [[ -f "/usr/share/$GAZEBO_VERSION/setup.sh" ]] then source /usr/share/$GAZEBO_VERSION/setup.sh fi printenv exec "${@:1}"

ENTRYPOINT 文件是生成 Docker 容器时运行的可执行文件。我们正在使用入口点来获取 ROS 工作空间,因此我们可以轻松地在 AWS RoboMaker 中运行 roslaunch 命令。您可能需要将自己的环境配置步骤添加到此 ENTRYPOINT 文件中。

我们 Dockerfile 通过 Docker BuildKit 使用多阶段构建和集成缓存。多阶段构建允许工作流程具有单独的构建步骤,因此构建依赖项和源代码不会复制到运行时系统映像中。这样可以减小 Docker 映像的大小并提高性能。缓存操作通过存储先前构建的文件来加快未来的构建速度。

使用以下命令构建机器人应用程序:

DOCKER_BUILDKIT=1 docker build . \ --build-arg ROS_DISTRO=melodic \ --build-arg LOCAL_WS_DIR=./robot_ws \ --build-arg APP_NAME=helloworld-robot-app \ -t robomaker-helloworld-robot-app

构建机器人应用程序后,您可以按如下方式构建模拟应用程序:

DOCKER_BUILDKIT=1 docker build . \ --build-arg GAZEBO_VERSION=gazebo-9 \ --build-arg ROS_DISTRO=melodic \ --build-arg LOCAL_WS_DIR=./simulation_ws \ --build-arg APP_NAME=helloworld-sim-app \ -t robomaker-helloworld-sim-app

运行命令 docker images 以确认 Docker 映像已成功构建。输出应与以下内容类似:

Administrator:~/environment/helloworld (ros1) $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE robomaker-helloworld-sim-app latest 5cb08816b6b3 6 minutes ago 2.8GB robomaker-helloworld-robot-app latest b5f6f755feec 10 minutes ago 2.79GB

此时,您已成功构建 Docker 映像。在上传它们以供使用之前,最好先在本地对其进行测试AWS RoboMaker。下一节将介绍如何执行此操作。

测试容器

以下命令使您能够在本地开发环境中运行该应用程序。

启动机器人应用程序:

docker run -it -v /tmp/.X11-unix/:/tmp/.X11-unix/ \ -u robomaker -e ROBOMAKER_GAZEBO_MASTER_URI=http://localhost:5555 \ -e ROBOMAKER_ROS_MASTER_URI=http://localhost:11311 \ robomaker-helloworld-robot-app:latest roslaunch hello_world_robot rotate.launch

启动模拟应用程序:

docker run -it -v /tmp/.X11-unix/:/tmp/.X11-unix/ \ -u robomaker -e ROBOMAKER_GAZEBO_MASTER_URI=http://localhost:5555 \ -e ROBOMAKER_ROS_MASTER_URI=http://localhost:11311 \ robomaker-helloworld-sim-app:latest roslaunch hello_world_simulation empty_world.launch

确认容器运行正常后,您可以将应用程序容器发布到 Amazon ECR,然后提交模拟作业