09_apollo_docker_build子模块软件架构分析文档

14 阅读7分钟

09_apollo_docker_build子模块软件架构分析文档

1. 概述

  Apollo Docker构建子模块是Apollo自动驾驶平台的核心基础设施,提供完整的Docker镜像构建与环境部署解决方案。该模块采用模块化架构,支持多架构(x86_64/aarch64)、多CUDA版本和多Ubuntu发行版配置,为开发者提供统一、可靠的开发与运行环境,确保平台在不同硬件软件环境下的一致性与可移植性。

2. 软件架构图

graph TB
    subgraph "用户交互层"
        U1[build_docker.sh] --> C1
        U2[命令行参数解析] --> C1
        U3[环境变量配置] --> C1
        U4[构建日志输出] --> C1
    end

    subgraph "核心构建逻辑层"
        C1[构建流程控制器] --> C2
        C1 --> C3
        C1 --> C4
        C1 --> C5
        C2[镜像依赖管理器] --> C6
        C3[架构检测与适配] --> C7
        C4[CUDA/TensorRT版本选择器] --> C8
        C5[构建命令生成器] --> C9
        C6[Docker镜像构建器] --> C10
    end

    subgraph "镜像层次结构层"
        M1[基础镜像层] --> M2
        M2[CyberRT中间件层] --> M3
        M3[开发环境层] --> M4
        M4[运行时环境层] --> M5
        M5[独立部署层] --> M6
    end

    subgraph "安装器工具集层"
        I1[基础环境安装器] --> M1
        I2[CyberRT依赖安装器] --> M2
        I3[核心模块依赖安装器] --> M3
        I4[传感器驱动依赖安装器] --> M3
        I5[DreamView依赖安装器] --> M3
        I6[GPU加速支持安装器] --> M3
        I7[可视化工具依赖安装器] --> M3
        I8[QA工具依赖安装器] --> M3
        I9[发布版本依赖安装器] --> M4
    end

    subgraph "配置管理系统层"
        CF1[RC配置文件模板] --> CF2
        CF2[环境变量设置器] --> CF3
        CF3[地理区域适配器] --> CF4
        CF4[软件源配置管理器] --> CF5
        CF5[构建参数配置器] --> CF6
    end

    subgraph "基础设施支持层"
        INF1[Docker引擎] --> C6
        INF2[NVIDIA Docker运行时] --> C6
        INF3[镜像仓库] --> C6
        INF4[网络连接管理器] --> C6
        INF5[存储管理器] --> C6
    end

    C2 --> M1
    C7 --> M1
    C8 --> M1
    C9 --> C6
    C6 --> M1
    C6 --> M2
    C6 --> M3
    C6 --> M4
    C6 --> M5
    C6 --> M6
    CF5 --> I1
    CF5 --> I2
    CF5 --> I3
    CF5 --> I4
    CF5 --> I5
    CF5 --> I6
    CF5 --> I7
    CF5 --> I8
    CF5 --> I9
    INF1 --> C6
    INF2 --> C6
    INF3 --> C6
    INF4 --> C6
    INF5 --> C6

    style C1 fill:#e1f5fe,stroke:#0097a7
    style M1 fill:#f3e5f5,stroke:#7b1fa2
    style I1 fill:#fff3e0,stroke:#f57c00
    style CF1 fill:#e8f5e8,stroke:#388e3c
    style INF1 fill:#ffebee,stroke:#d32f2f

3. 调用流程图

sequenceDiagram
    participant User as 用户
    participant BuildScript as 构建脚本(build_docker.sh)
    participant DockerEngine as Docker引擎
    participant Installer as 安装器工具集
    participant ConfigManager as 配置管理器
    participant Registry as 镜像仓库
    participant EnvManager as 环境管理器

    User->>BuildScript: 执行构建命令
    BuildScript->>BuildScript: 初始化构建环境
    BuildScript->>BuildScript: 解析命令行参数
    BuildScript->>ConfigManager: 获取构建配置
    ConfigManager->>ConfigManager: 读取配置文件
    ConfigManager->>ConfigManager: 解析环境变量
    ConfigManager->>BuildScript: 返回配置信息
    BuildScript->>BuildScript: 确定目标架构
    BuildScript->>BuildScript: 确定CUDA/TensorRT版本
    BuildScript->>BuildScript: 确定镜像依赖层次
    BuildScript->>Registry: 检查基础镜像是否存在
    Registry->>BuildScript: 返回镜像状态
    alt 基础镜像不存在
        BuildScript->>Registry: 拉取基础镜像
        Registry->>BuildScript: 返回基础镜像
    end
    BuildScript->>DockerEngine: 启动Docker构建过程
    DockerEngine->>DockerEngine: 创建构建上下文
    DockerEngine->>Installer: 执行系统依赖安装
    Installer->>Installer: 更新软件源
    Installer->>Installer: 安装基础系统包
    Installer->>DockerEngine: 基础系统安装完成
    DockerEngine->>Installer: 执行CyberRT依赖安装
    Installer->>Installer: 安装Protobuf
    Installer->>Installer: 安装Fast-RTPS
    Installer->>Installer: 安装gflags/glog
    Installer->>Installer: 安装Abseil
    Installer->>DockerEngine: CyberRT依赖安装完成
    DockerEngine->>Installer: 执行核心模块依赖安装
    Installer->>Installer: 安装OpenCV
    Installer->>Installer: 安装PCL
    Installer->>Installer: 安装Boost
    Installer->>Installer: 安装Eigen
    Installer->>DockerEngine: 核心模块依赖安装完成
    DockerEngine->>Installer: 执行GPU支持安装
    Installer->>Installer: 配置CUDA环境
    Installer->>Installer: 安装cuDNN
    Installer->>Installer: 安装TensorRT
    Installer->>DockerEngine: GPU支持安装完成
    DockerEngine->>EnvManager: 配置环境变量
    EnvManager->>EnvManager: 设置PATH变量
    EnvManager->>EnvManager: 设置LD_LIBRARY_PATH变量
    EnvManager->>EnvManager: 设置APOLLO相关变量
    EnvManager->>DockerEngine: 环境变量配置完成
    DockerEngine->>BuildScript: 构建完成
    BuildScript->>Registry: 推送镜像(可选)
    BuildScript->>User: 显示构建结果
    BuildScript->>User: 输出构建日志

4. UML类图

4.1 核心构建类图

classDiagram
    class BuildDockerScript {
        -dockerfile: string
        -installMode: string
        -geoLoc: string
        -dist: string
        -targetArch: string
        -targetStage: string
        +parseArguments(): void
        +determineTargetArchAndStage(): void
        +determineCudaVersions(): void
        +determineImagesInOut(): void
        +dockerBuildPreview(): void
        +dockerBuildRun(): void
        +main(): int
    }

    class ImageManager {
        -inputImage: string
        -outputImage: string
        -timestamp: string
        -prevImageTimestamp: string
        +getBaseImage(): string
        +getOutputImage(): string
        +setTimestamp(): void
        +getTimestamp(): string
    }

    class ConfigManager {
        -configFile: string
        -cudaVersion: string
        -cudnnVersion: string
        -tensorrtVersion: string
        -geoLoc: string
        -softwareSources: SoftwareSources
        +getCudaVersion(): string
        +getCudnnVersion(): string
        +getTensorrtVersion(): string
        +getSoftwareSources(): SoftwareSources
        +loadConfig(): void
    }

    class SoftwareSources {
        -sourcesList: string
        -geoLoc: string
        +getSourcesList(): string
        +setGeoLoc(geoLoc: string): void
        +loadSourcesList(): void
    }

    class Installer {
        <<interface>>
        +install(): bool
        +cleanup(): void
        +getDependencies(): string[]
    }

    class SystemInstaller implements Installer {
        -packages: string[]
        -geoLoc: string
        +install(): bool
        +cleanup(): void
        +getDependencies(): string[]
    }

    class CyberDepsInstaller implements Installer {
        -dependencies: string[]
        -installMode: string
        +install(): bool
        +cleanup(): void
        +getDependencies(): string[]
    }

    class ModuleDepsInstaller implements Installer {
        -modules: string[]
        -workhorse: string
        +install(): bool
        +cleanup(): void
        +getDependencies(): string[]
    }

    class DockerEngine {
        -dockerClient: DockerClient
        +buildImage(buildContext: string, dockerfile: string, buildArgs: map<string, string>): Image
        +pullImage(imageName: string): Image
        +pushImage(imageName: string): bool
        +runContainer(imageName: string, cmd: string): Container
    }

    class BuildLogger {
        -logLevel: string
        -logFile: string
        -terminalOutput: bool
        +info(message: string): void
        +warning(message: string): void
        +error(message: string): void
        +debug(message: string): void
        +setLogLevel(level: string): void
    }

    BuildDockerScript --> ImageManager
    BuildDockerScript --> ConfigManager
    BuildDockerScript --> Installer
    BuildDockerScript --> DockerEngine
    BuildDockerScript --> BuildLogger
    ConfigManager --> SoftwareSources
    DockerEngine --> Installer

4.2 安装器类图

classDiagram
    class InstallerBase {
        -pkgName: string
        -checksum: string
        -downloadLink: string
        -installPath: string
        +downloadIfNotCached(): bool
        +aptGetUpdateAndInstall(): bool
        +aptGetRemove(): bool
        +cleanup(): void
        +verifyChecksum(): bool
    }

    class MinimalEnvironmentInstaller {
        +install(): bool
        +cleanup(): void
        -installSystemPackages(): bool
        -configureSoftwareSources(): bool
    }

    class CyberDepsInstaller {
        +install(): bool
        +cleanup(): void
        -installProtobuf(): bool
        -installFastRTPS(): bool
        -installGflagsGlog(): bool
        -installAbseil(): bool
    }

    class ModulesBaseInstaller {
        +install(): bool
        +cleanup(): void
        -installCMake(): bool
        -installBazel(): bool
        -installLLVMClang(): bool
    }

    class OrdinaryModulesInstaller {
        +install(): bool
        +cleanup(): void
        -installCommonDeps(): bool
        -installPerceptionDeps(): bool
        -installPlanningDeps(): bool
        -installMapDeps(): bool
        -installTeleopDeps(): bool
    }

    class DriversDepsInstaller {
        +install(): bool
        +cleanup(): void
        -installCameraDeps(): bool
        -installLidarDeps(): bool
        -installRadarDeps(): bool
    }

    class DreamviewDepsInstaller {
        +install(): bool
        +cleanup(): void
        -installNodeJS(): bool
        -installYarn(): bool
        -installWebDeps(): bool
    }

    class GPUSupportInstaller {
        +install(): bool
        +cleanup(): void
        -installCUDA(): bool
        -installCuDNN(): bool
        -installTensorRT(): bool
        -configureGPUEnvironment(): bool
    }

    class VisualizerDepsInstaller {
        +install(): bool
        +cleanup(): void
        -installQt(): bool
        -installOpenGL(): bool
        -installOtherVisualDeps(): bool
    }

    InstallerBase <|-- MinimalEnvironmentInstaller
    InstallerBase <|-- CyberDepsInstaller
    InstallerBase <|-- ModulesBaseInstaller
    InstallerBase <|-- OrdinaryModulesInstaller
    InstallerBase <|-- DriversDepsInstaller
    InstallerBase <|-- DreamviewDepsInstaller
    InstallerBase <|-- GPUSupportInstaller
    InstallerBase <|-- VisualizerDepsInstaller

5. 状态机

stateDiagram-v2
    [*] --> 初始状态
    初始状态 --> 参数解析
    参数解析 --> 配置加载
    配置加载 --> 架构检测
    架构检测 --> CUDA版本选择
    CUDA版本选择 --> 镜像依赖确定
    镜像依赖确定 --> 基础镜像检查
    基础镜像检查 --> 构建准备就绪
    构建准备就绪 --> Docker构建开始
    Docker构建开始 --> 系统依赖安装
    系统依赖安装 --> CyberRT依赖安装
    CyberRT依赖安装 --> 模块依赖安装
    模块依赖安装 --> GPU支持安装
    GPU支持安装 --> 环境变量配置
    环境变量配置 --> Docker构建完成
    Docker构建完成 --> 镜像推送
    镜像推送 --> 构建完成
    构建完成 --> [*]

    参数解析 --> 参数错误: 参数无效
    配置加载 --> 配置错误: 配置文件不存在
    架构检测 --> 架构不支持: 未知架构
    CUDA版本选择 --> CUDA版本错误: 版本不兼容
    基础镜像检查 --> 镜像拉取失败: 网络错误
    Docker构建开始 --> 构建失败: Docker错误
    系统依赖安装 --> 依赖安装失败: 系统包错误
    CyberRT依赖安装 --> 依赖安装失败: CyberRT包错误
    模块依赖安装 --> 依赖安装失败: 模块包错误
    GPU支持安装 --> 依赖安装失败: GPU包错误
    镜像推送 --> 推送失败: 镜像仓库错误

    参数错误 --> [*]
    配置错误 --> [*]
    架构不支持 --> [*]
    CUDA版本错误 --> [*]
    镜像拉取失败 --> [*]
    构建失败 --> [*]
    依赖安装失败 --> [*]
    推送失败 --> [*]

6. 源码分析

6.1 构建脚本核心源码分析

6.1.1 build_docker.sh主函数分析
function main() {
  parse_arguments "$@"
  determine_target_arch_and_stage
  determine_cuda_versions
  determine_images_in_out
  docker_build_preview
  docker_build_run
}

# 调用主函数
main "$@"

  build_docker.sh是整个构建系统的入口点,采用模块化设计,将构建过程分解为多个独立的功能函数:

  • parse_arguments:解析命令行参数,支持多种构建选项
  • determine_target_arch_and_stage:检测目标架构和构建阶段
  • determine_cuda_versions:确定CUDA和TensorRT版本
  • determine_images_in_out:确定输入输出镜像名称
  • docker_build_preview:预览构建命令
  • docker_build_run:执行Docker构建
6.1.2 参数解析函数分析
function parse_arguments() {
  while [[ $# -gt 0 ]]; do
    case "$1" in
      -f|--dockerfile)
        dockerfile="$2"
        shift 2
        ;;
      -m|--mode)
        install_mode="$2"
        shift 2
        ;;
      -g|--geo)
        geoloc="$2"
        shift 2
        ;;
      -d|--dist)
        dist="$2"
        shift 2
        ;;
      -c|--clean)
        clean_build="true"
        shift
        ;;
      *)
        error "未知参数: $1"
        usage
        exit 1
        ;;
    esac
  done
  
  # 参数验证
  if [[ -z "${dockerfile}" ]]; then
    error "必须指定Dockerfile路径"
    usage
    exit 1
  fi
}

  参数解析函数支持多种构建选项,包括:

  • -f|--dockerfile:指定Dockerfile路径
  • -m|--mode:安装模式(build/download)
  • -g|--geo:地理区域(cn/us)
  • -d|--dist:发布版本(stable/testing)
  • -c|--clean:干净构建

  该函数还包含参数验证逻辑,确保必要参数存在。

6.1.3 Docker构建执行函数分析
function docker_build_run() {
  local extra_args=""
  local context="$(dirname "${dockerfile}")"
  local dockerfile_name="$(basename "${dockerfile}")"
  
  # 添加构建参数
  local build_args=""
  build_args+=" --build-arg BASE_IMAGE=${in_image}"
  build_args+=" --build-arg GEOLOC=${geoloc}"
  build_args+=" --build-arg CLEAN_DEPS=${clean_deps}"
  build_args+=" --build-arg INSTALL_MODE=${install_mode}"
  
  # 执行Docker构建
  docker build ${extra_args} \
    --file "${dockerfile_name}" \
    ${build_args} \
    -t "${out_image}" \
    "${context}"
  
  # 构建结果检查
  if [[ $? -ne 0 ]]; then
    error "Docker构建失败"
    exit 1
  fi
}

  Docker构建执行函数负责生成并执行Docker构建命令,包括:

  • 构建上下文设置
  • 构建参数添加
  • Docker命令执行
  • 构建结果检查

6.2 安装器源码分析

6.2.1 安装器基础类分析
function download_if_not_cached() {
  local filename="$1"
  local expected_cs="$2"
  local url="$3"
  local download_dir="/var/cache/apollo/distfiles"
  
  mkdir -p "${download_dir}"
  
  # 检查文件是否已缓存
  if [[ -f "${download_dir}/${filename}" ]]; then
    if verify_checksum "${download_dir}/${filename}" "${expected_cs}"; then
      info "使用缓存的文件: ${filename}"
      return 0
    fi
  fi
  
  # 下载文件
  info "下载文件: ${filename}"
  wget -q -O "${download_dir}/${filename}" "${url}"
  
  # 验证校验和
  if ! verify_checksum "${download_dir}/${filename}" "${expected_cs}"; then
    error "文件校验和验证失败: ${filename}"
    return 1
  fi
  
  return 0
}

  安装器基础类提供了通用的下载和安装功能:

  • download_if_not_cached:检查文件是否已缓存,若未缓存则下载
  • verify_checksum:验证文件校验和
  • aptGetUpdateAndInstall:更新软件源并安装包
  • cleanup:清理临时文件
6.2.2 CyberRT依赖安装器分析
function install_cyber_deps() {
  apt-get -y update && \
    apt-get -y install \
    ncurses-dev \
    libuuid1 \
    uuid-dev
  
  info "安装Protobuf ..."
  bash ${CURR_DIR}/install_protobuf.sh
  
  info "安装Fast-RTPS ..."
  bash ${CURR_DIR}/install_fast-rtps.sh
  
  # absl
  bash ${CURR_DIR}/install_abseil.sh
  
  # gflags and glog
  bash ${CURR_DIR}/install_gflags_glog.sh
  
  # Clean up cache to reduce layer size.
  apt-get clean && \
    rm -rf /var/lib/apt/lists/*
}

  CyberRT依赖安装器负责安装CyberRT中间件所需的依赖:

  • Protobuf:序列化框架
  • Fast-RTPS:实时通信中间件
  • Abseil:C++标准库扩展
  • gflags/glog:命令行参数和日志库
6.2.3 OpenCV安装器分析
function install_opencv() {
  apt_get_update_and_install \
    libjpeg-dev \
    libpng-dev \
    libtiff-dev \
    libgtk2.0-dev \
    libv4l-dev \
    libeigen3-dev \
    libopenblas-dev \
    libatlas-base-dev \
    libxvidcore-dev \
    libx264-dev \
    libopenni-dev \
    libwebp-dev
  
  pip3_install numpy
  
  VERSION="4.4.0"
  PKG_OCV="opencv-${VERSION}.tar.gz"
  CHECKSUM="bb95acd849e458be7f7024d17968568d1ccd2f0681d47fd60d34ffb4b8c52563"
  DOWNLOAD_LINK="https://github.com/opencv/opencv/archive/${VERSION}.tar.gz"
  download_if_not_cached "${PKG_OCV}" "${CHECKSUM}" "${DOWNLOAD_LINK}"
  
  # 构建和安装OpenCV
  tar xzf ${PKG_OCV}
  pushd "opencv-${VERSION}"
    mkdir -p build
    cd build
    cmake .. \
        -DCMAKE_INSTALL_PREFIX="${SYSROOT_DIR}" \
        -DCMAKE_BUILD_TYPE=Release \
        -DBUILD_SHARED_LIBS=ON \
        -DENABLE_PRECOMPILED_HEADERS=OFF \
        -DOPENCV_GENERATE_PKGCONFIG=ON \
        -DBUILD_EXAMPLES=OFF \
        -DBUILD_DOCS=OFF \
        -DBUILD_TESTS=OFF \
        -DBUILD_PERF_TESTS=OFF \
        -DBUILD_JAVA=OFF \
        -DBUILD_PROTOBUF=OFF \
        -DPROTOBUF_UPDATE_FILES=ON \
        -DINSTALL_C_EXAMPLES=OFF \
        -DWITH_QT=OFF \
        -DWITH_GTK=ON \
        -DWITH_GTK_2_X=ON \
        -DWITH_IPP=OFF \
        -DWITH_ITT=OFF \
        -DWITH_TBB=OFF \
        -DWITH_EIGEN=ON \
        -DWITH_FFMPEG=ON \
        -DWITH_LIBV4L=ON \
        -DWITH_OPENMP=ON \
        -DWITH_OPENNI=ON \
        -DWITH_OPENCL=ON \
        -DWITH_WEBP=ON \
        -DOpenGL_GL_PREFERENCE=GLVND \
        -DBUILD_opencv_python2=OFF \
        -DBUILD_opencv_python3=ON \
        -DBUILD_NEW_PYTHON_SUPPORT=ON \
        -DPYTHON_DEFAULT_EXECUTABLE="$(which python3)" \
        -DOPENCV_PYTHON3_INSTALL_PATH="/usr/local/lib/python$(py3_version)/dist-packages" \
        -DOPENCV_ENABLE_NONFREE=ON \
        -DCV_TRACE=OFF \
        ${GPU_OPTIONS} \
        ${EXTRA_OPTIONS}
    make -j$(nproc)
    make install
  popd
  
  ldconfig
  ok "成功安装OpenCV ${VERSION}."
  
  # 清理
  rm -rf opencv*
}

  OpenCV安装器负责安装计算机视觉库,包括:

  • 系统依赖安装
  • Python依赖安装
  • OpenCV源码下载
  • 配置、编译和安装
  • 环境配置

6.3 配置管理源码分析

  配置管理是Apollo Docker构建系统的重要组成部分,负责管理构建过程中的各种配置信息,包括环境变量、软件源、构建参数等。配置管理模块确保构建过程中使用正确的配置,支持不同地理区域、不同架构和不同CUDA版本的灵活配置。

6.3.1 环境变量设置分析
function setup_environment() {
  if [ ! -f /apollo/LICENSE ]; then
    APOLLO_IN_DOCKER=false
    APOLLO_PATH="/opt/apollo/neo"
    APOLLO_ROOT_DIR=${APOLLO_PATH}/packages
    
    if [ -f /.dockerenv ]; then
      APOLLO_IN_DOCKER=true
    fi
  
    export APOLLO_PATH
    export APOLLO_ROOT_DIR=${APOLLO_PATH}/packages
    export CYBER_PATH=${APOLLO_ROOT_DIR}/cyber
    export APOLLO_IN_DOCKER
    export APOLLO_SYSROOT_DIR=/opt/apollo/sysroot
    export CYBER_DOMAIN_ID=80
    export CYBER_IP=127.0.0.1
    export GLOG_log_dir=${APOLLO_PATH}/data/log
    export GLOG_alsologtostderr=0
    export GLOG_colorlogtostderr=1
    export GLOG_minloglevel=0
    export sysmo_start=0
    export USE_ESD_CAN=false
  fi
}
6.3.2 软件源配置分析
function configure_software_sources() {
  local geoloc="$1"
  local arch="$(uname -m)"
  
  if [[ "${geoloc}" == "cn" ]]; then
    if [[ "${arch}" == "x86_64" ]]; then
      cp /opt/apollo/rcfiles/sources.list.cn.x86_64 /etc/apt/sources.list
    elif [[ "${arch}" == "aarch64" ]]; then
      cp /opt/apollo/rcfiles/sources.list.cn.aarch64 /etc/apt/sources.list
    fi
  else
    # 使用默认软件源
    return 0
  fi
  
  # 更新软件源
  apt-get update
}

6.4 Dockerfile源码分析

  Dockerfile是Apollo Docker构建系统的核心文件之一,定义了Docker镜像的构建过程和内容。不同类型的Dockerfile对应不同的Apollo环境,如开发环境、运行时环境、CyberRT中间件环境等。

6.4.1 dev.x86_64.nvidia.dockerfile分析
ARG BASE_IMAGE
FROM ${BASE_IMAGE}

ARG APOLLO_DIST
ARG GEOLOC
ARG CLEAN_DEPS
ARG INSTALL_MODE

LABEL version="1.2"

ENV DEBIAN_FRONTEND=noninteractive
ENV PATH /opt/apollo/sysroot/bin:$PATH
ENV APOLLO_DIST ${APOLLO_DIST}

COPY installers /opt/apollo/installers
COPY rcfiles /opt/apollo/rcfiles

RUN bash /opt/apollo/installers/install_minimal_environment.sh ${GEOLOC}
RUN bash /opt/apollo/installers/install_cmake.sh
RUN bash /opt/apollo/installers/install_cyber_deps.sh ${INSTALL_MODE}
RUN bash /opt/apollo/installers/install_llvm_clang.sh
RUN bash /opt/apollo/installers/install_qa_tools.sh
RUN bash /opt/apollo/installers/install_visualizer_deps.sh
RUN bash /opt/apollo/installers/install_bazel.sh
RUN bash /opt/apollo/installers/post_install.sh cyber

WORKDIR /apollo

  开发环境Dockerfile定义了Apollo平台完整的开发环境构建过程,包括以下关键部分:

6.4.2 cyber.x86_64.nvidia.dockerfile分析
ARG BASE_IMAGE
FROM ${BASE_IMAGE}

ARG APOLLO_DIST
ARG GEOLOC
ARG CLEAN_DEPS
ARG INSTALL_MODE

LABEL version="1.2"

ENV DEBIAN_FRONTEND=noninteractive
ENV PATH /opt/apollo/sysroot/bin:$PATH
ENV APOLLO_DIST ${APOLLO_DIST}

COPY installers /opt/apollo/installers
COPY rcfiles /opt/apollo/rcfiles

RUN bash /opt/apollo/installers/install_minimal_environment.sh ${GEOLOC}
RUN bash /opt/apollo/installers/install_cmake.sh
RUN bash /opt/apollo/installers/install_cyber_deps.sh ${INSTALL_MODE}
RUN bash /opt/apollo/installers/install_llvm_clang.sh
RUN bash /opt/apollo/installers/install_qa_tools.sh
RUN bash /opt/apollo/installers/install_visualizer_deps.sh
RUN bash /opt/apollo/installers/install_bazel.sh
RUN bash /opt/apollo/installers/post_install.sh cyber

WORKDIR /apollo

  CyberRT镜像Dockerfile定义了CyberRT中间件环境的构建过程,与开发环境镜像类似,但包含的组件较少,主要专注于CyberRT中间件的运行环境。

7. 设计模式

  Apollo Docker构建系统采用了多种设计模式,这些设计模式提高了系统的灵活性、可扩展性和可维护性。本节将详细分析系统中使用的主要设计模式。

7.1 工厂模式

  工厂模式是一种创建型设计模式,它提供了一种创建对象的最佳方式。在工厂模式中,创建对象时不会对客户端暴露创建逻辑,而是通过一个共同的接口来指向新创建的对象。

  Apollo Docker构建系统使用工厂模式创建不同类型的安装器:

function create_installer() {
  local installer_type="$1"
  
  case "${installer_type}" in
    "minimal")
      return "MinimalEnvironmentInstaller"
      ;;
    "cyber_deps")
      return "CyberDepsInstaller"
      ;;
    "modules_base")
      return "ModulesBaseInstaller"
      ;;
    "ordinary_modules")
      return "OrdinaryModulesInstaller"
      ;;
    "drivers_deps")
      return "DriversDepsInstaller"
      ;;
    "dreamview_deps")
      return "DreamviewDepsInstaller"
      ;;
    "gpu_support")
      return "GPUSupportInstaller"
      ;;
    "visualizer_deps")
      return "VisualizerDepsInstaller"
      ;;
    *)
      error "未知的安装器类型: ${installer_type}"
      return 1
      ;;
  esac
}

7.2 策略模式

  策略模式是一种行为型设计模式,它定义了一系列算法,并将每个算法封装起来,使它们可以相互替换。策略模式让算法独立于使用它的客户端而变化。

  构建系统使用策略模式处理不同架构和CUDA版本的构建策略:

function get_build_strategy() {
  local arch="$1"
  local cuda_version="$2"
  
  if [[ "${arch}" == "x86_64" && "${cuda_version}" == "11.1" ]]; then
    return "X86_64_CUDA_11_1_Strategy"
  elif [[ "${arch}" == "x86_64" && "${cuda_version}" == "11.2" ]]; then
    return "X86_64_CUDA_11_2_Strategy"
  elif [[ "${arch}" == "aarch64" && "${cuda_version}" == "11.1" ]]; then
    return "AARCH64_CUDA_11_1_Strategy"
  elif [[ "${arch}" == "aarch64" && "${cuda_version}" == "11.2" ]]; then
    return "AARCH64_CUDA_11_2_Strategy"
  else
    return "Default_Strategy"
  fi
}

7.3 模板方法模式

  模板方法模式是一种行为型设计模式,它定义了一个算法的骨架,并允许子类在不改变算法结构的情况下重定义算法的某些步骤。模板方法模式使得子类可以在不改变算法结构的情况下,重新定义算法的某些特定步骤。

  安装器系统使用模板方法模式定义安装流程的骨架:

function install_template() {
  local installer_type="$1"
  
  # 模板方法定义安装流程骨架
  pre_install
  install_dependencies
  configure_environment
  post_install
  cleanup
}

function pre_install() {
  # 钩子方法,可被子类重写
  info "开始安装 ${installer_type}"
}

function install_dependencies() {
  # 抽象方法,必须被子类实现
  error "install_dependencies 必须被子类实现"
  return 1
}

function configure_environment() {
  # 钩子方法,可被子类重写
  info "配置环境"
}

function post_install() {
  # 钩子方法,可被子类重写
  info "安装完成 ${installer_type}"
}

function cleanup() {
  # 钩子方法,可被子类重写
  info "清理安装文件"
}

7.4 单例模式

  单例模式是一种创建型设计模式,它确保一个类只有一个实例,并提供一个全局访问点来访问这个实例。单例模式在需要控制对象创建、限制实例数量、节省资源等场景中非常有用。

  构建系统使用单例模式管理配置信息:

function get_config_manager() {
  if [[ -z "${CONFIG_MANAGER_INSTANCE}" ]]; then
    CONFIG_MANAGER_INSTANCE="$(create_config_manager)"
  fi
  return "${CONFIG_MANAGER_INSTANCE}"
}

7.5 观察者模式

  观察者模式是一种行为型设计模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生变化时,所有依赖于它的对象都会自动收到通知并更新。

  构建系统使用观察者模式处理构建事件:

function register_observer() {
  local event="$1"
  local observer="$2"
  
  if [[ -z "${OBSERVERS[${event}]}" ]]; then
    OBSERVERS[${event}]=""
  fi
  
  OBSERVERS[${event}]+=" ${observer}"
}

function notify_observers() {
  local event="$1"
  local data="$2"
  
  if [[ -n "${OBSERVERS[${event}]}" ]]; then
    for observer in ${OBSERVERS[${event}]}; do
      ${observer} "${data}"
    done
  fi
}
7.5.1 观察者模式的应用场景

  在Apollo Docker构建系统中,观察者模式主要用于以下场景:

  1. 构建事件处理:当构建过程中的某个事件发生时,通知相关的观察者进行处理。
  2. 状态变化通知:当构建状态发生变化时,通知相关的组件进行更新。
  3. 日志记录:当发生重要事件时,通知日志记录器进行记录。
7.5.2 观察者模式的优势
  • 解耦对象:观察者和被观察者之间通过接口进行通信,实现了解耦。
  • 动态关系:可以动态地添加或移除观察者,实现了对象之间的动态关系。
  • 广播通信:当被观察者状态发生变化时,可以同时通知所有观察者,实现了广播通信。
function get_build_strategy() {
  local arch="$1"
  local cuda_version="$2"
  
  if [[ "${arch}" == "x86_64" && "${cuda_version}" == "11.1" ]]; then
    return "X86_64_CUDA_11_1_Strategy"
  elif [[ "${arch}" == "x86_64" && "${cuda_version}" == "11.2" ]]; then
    return "X86_64_CUDA_11_2_Strategy"
  elif [[ "${arch}" == "aarch64" && "${cuda_version}" == "11.1" ]]; then
    return "AARCH64_CUDA_11_1_Strategy"
  elif [[ "${arch}" == "aarch64" && "${cuda_version}" == "11.2" ]]; then
    return "AARCH64_CUDA_11_2_Strategy"
  else
    return "Default_Strategy"
  fi
}

  策略模式的应用使得不同的构建策略可以独立实现和切换,提高了系统的可维护性。

7.3 模板方法模式

  安装器系统使用模板方法模式定义安装流程的骨架:

function install_template() {
  local installer_type="$1"
  
  # 模板方法定义安装流程骨架
  pre_install
  install_dependencies
  configure_environment
  post_install
  cleanup
}

function pre_install() {
  # 钩子方法,可被子类重写
  info "开始安装 ${installer_type}"
}

function install_dependencies() {
  # 抽象方法,必须被子类实现
  error "install_dependencies 必须被子类实现"
  return 1
}

function configure_environment() {
  # 钩子方法,可被子类重写
  info "配置环境"
}

function post_install() {
  # 钩子方法,可被子类重写
  info "安装完成 ${installer_type}"
}

function cleanup() {
  # 钩子方法,可被子类重写
  info "清理安装文件"
}

  模板方法模式的应用使得安装流程标准化,同时允许子类定制特定步骤。

7.4 单例模式

  构建系统使用单例模式管理配置信息:

function get_config_manager() {
  if [[ -z "${CONFIG_MANAGER_INSTANCE}" ]]; then
    CONFIG_MANAGER_INSTANCE="$(create_config_manager)"
  fi
  return "${CONFIG_MANAGER_INSTANCE}"
}

  单例模式的应用确保配置信息在整个构建过程中保持一致,避免了配置不一致的问题。

7.5 观察者模式

  构建系统使用观察者模式处理构建事件:

function register_observer() {
  local event="$1"
  local observer="$2"
  
  if [[ -z "${OBSERVERS[${event}]}" ]]; then
    OBSERVERS[${event}]=""
  fi
  
  OBSERVERS[${event}]+=" ${observer}"
}

function notify_observers() {
  local event="$1"
  local data="$2"
  
  if [[ -n "${OBSERVERS[${event}]}" ]]; then
    for observer in ${OBSERVERS[${event}]}; do
      ${observer} "${data}"
    done
  fi
}

  观察者模式的应用使得构建事件可以被多个组件监听和处理,提高了系统的扩展性。

8. 总结

  Apollo Docker构建子模块是一个设计精良的容器化构建系统,采用模块化架构,支持多架构、多CUDA版本和多Ubuntu发行版的灵活配置。该系统通过分层设计、设计模式应用和完善的错误处理机制,为Apollo开发者提供了统一、可靠的开发和运行环境。随着Apollo平台的不断发展,Docker构建系统将继续演进,提供更高效、更灵活的构建解决方案,支持Apollo在不同硬件和软件环境下的广泛应用。