小结
本文:
- 展示使用 GitLab Runner、Docker 容器和 CI/CD Automation for Simulink Check 为 Simulink 模型建立实用的 CI/CD 管道,以在建模环境之外简化验证过程。
- 介绍配置 GitLab CI/CD、构建 Docker 镜像、启动容器以及通过模板 .yml 文件将过程顾问检查嵌入作业的过程。
- 强调安全关键型工作流和自动化检查带来的合规性优势,以及更快的缺陷检测/解决方法。
技术文章
本页面使用了机器翻译。
请花 1 分钟时间完成一个翻译质量的调查。
MathWorks 见解
作者:
阅读时间:9 分钟
本文:
随着系统变得日益复杂和互联,软件可靠性和完整性的重要性持续升级。尽管遵循了既定的工程最佳实践,高完整性系统的开发仍然是一项对技术要求极高且资金投入巨大的工作。鉴于审查、分析、测试和回归工作涉及的大量精力,工程师们一直在寻找减少浪费并提高整体软件质量的方法。最新的趋势之一是推动持续集成和持续部署 (CI/CD) 解决方案。
CI/CD 实践改变了软件开发,实现了高质量软件的快速和一致交付。但是,该技术的快速发展以及可用工具的数量,可能会使创建稳健的 CI/CD 解决方案变得极具挑战性。本文介绍了一种使用 GitLab® Runner、Docker® 和 CI/CD Automation for Simulink Check™ 实现 CI/CD 管道的综合方法。
CI/CD 是现代软件开发中的重要实践,对于医疗、汽车和航空航天工业等领域的安全关键型系统尤为如此。部署高效的 CI/CD 解决方案有助于提高质量和可靠性,更快速地检测和解决问题,并确保持续符合监管标准。由于需求的单一变更可能会引发一连串的回归工作,因此建立强大的 CI/CD 流程对于以经济高效的方式管理任何安全关键型软件开发项目至关重要。
本文将介绍以下步骤,以配置本机建模环境之外的工具,以便与 MATLAB® 和 Simulink® 工具套件集成:
作为 CI/CD Automation for Simulink Check 的一部分,过程顾问是一个强大的工具,用于在 MATLAB 环境中开发基于模型的设计管道,然后可以通过提供的模板 .yml 文件在外部环境中使用该管道。对于旨在在 MATLAB 环境中配置流程管道的模型开发人员,请参阅以下文档:
此时,您已准备好将过程模型引入 GitLab 中的 CI/CD 管道。为了确保 Simulink 过程模型的更新自动反映在 GitLab 管道中,我们使用了一种独特的方法:我们不将过程模型重新创建为静态 .yml 文件,而是使用一个 .yml 文件来生成另一个包含过程模型中当前任务的 .yml 文件。请参阅附录 A 中的示例管道配置文件 (gitlab-ci.yml)。请注意,这里有两个阶段:
stages: - SimulinkPipelineGeneration - SimulinkPipelineExecution
第一个阶段为第二个阶段生成管道。
此时,考虑如何许可管道中使用的建模和验证工具非常重要。一种方法是使用批处理令牌。要使用批处理令牌,您必须从 Batch Licensing Pilot 申请一个,并将其包含在您的 .yml 文件的 variables 部分中。
variables: MLM_LICENSE_TOKEN: "<MATLAB_BATCH_TOKEN>"
并非所有产品都支持批处理令牌。在这种情况下,您可能需要使用传统的许可证文件 (.lic)。您可以在此处找到有关批处理令牌的更多信息:MATLAB 批量许可令牌。请注意,最佳实践是避免将令牌(和其他凭据类型信息)硬编码到您的 .yml 或 Dockerfile 中。更安全的方法是考虑使用环境变量构建您的 Docker 镜像。
配置您的 GitLab 项目以管理作业非常简单。您首先需要确保 GitLab 知道在哪里可以找到您的 .yml 文件。在 Settings > CI/CD > General pipelines > CI/CD configuration file 下,提供项目 .yml 文件的路径,最好命名为 “.gitlab-ic.yml”(图 1)。
接下来,您需要在 GitLab 中创建一个新的 runner。这样做将提供一个 gitlab-runner-token,您稍后将使用它来将 Docker 容器注册到您的 GitLab runner 实例(图 2)。
在 Settings > CI/CD > Runners > New project runner 下,提供一个标签并点击 Create Runner(图 3)。
创建 runner 后,复制并保存 runner 身份验证令牌(图 4)。
这可能是该过程中最困难的部分,因为您需要确保 Docker 镜像不仅安装了所有工具依赖项,而且还获得了使用这些工具的许可。同样重要的是要注意,您的 Docker 镜像可以是众多操作系统发行版中的一种。本示例将使用 Ubuntu 22.04。
首先安装运行 Simulink 过程模型和 GitLab runners 所需的所有工具。在您的 Dockerfile 中,拉取基础 MATLAB 镜像:
FROM mathworks/matlab-deps:${MATLAB_DOCKER_RELEASE}
随后,您将直接开始安装所需的一些基本依赖项。请注意,构建变量将在后面讨论。有关完整的安装细目,请参阅附录 B 中的示例 Dockerfile。Dockerfile 首先安装 MPM 的依赖项,然后将使用 MPM 安装所需的 MATLAB 和 Simulink 产品(Simulink Code Inspector™ 除外)。接下来,安装 matlab-proxy 的依赖项。安装完成后,使用 MPM 安装所需的工具并配置您的许可方法。请注意,您还需要在 Docker 镜像上安装 gitlab-runner 并使用您之前保存的 gitlab-runner-token 对其进行注册。下面的代码片段显示了如何使用理想的配置选项进行安装和注册:
RUN curl -L
"https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh" | sudo bash && \
sudo apt-get install --no-install-recommends --yes \
gitlab-runner && \
sudo apt-get clean && sudo apt-get autoremove && \
gitlab-runner start && \
sudo gitlab-runner register --non-interactive \
--url "<gitlab-url>" \
--token "${GITLAB_TOKEN}" \
--docker-image ${IMAGE_NAME} \
--executor "shell"
如 Dockerfile 所示,MPM 可以安装除 Simulink Code Inspector 之外的所有必需 MATLAB 和 Simulink 工具。对于 Simulink Code Inspector,您需要从 MathWorks 网站下载 .iso 文件并从中安装。有关更多信息,请参阅 mpm install 文档。
现在产品已安装,您需要配置许可方法。目前有三种可用的许可方法:
matlab-batch 以启用 MATLAB 批处理许可令牌的使用。请注意,Polyspace Code Prover Server™ 和 Polyspace Bug Finder Server™ 不支持批处理令牌许可,并且在 CI/CD 环境中使用用于桌面的 Polyspace Code Prover™ 和 Polyspace Bug Finder™ 违反软件许可协议。要安装 matlab-batch,请将以下内容添加到您的 Dockerfile:
RUN wget -q https://ssd.mathworks.com/supportfiles/ci/matlab-batch/v1/glnxa64/matlab-batch \ && sudo mv matlab-batch /usr/local/bin \ && sudo chmod +x /usr/local/bin/matlab-batch
--build-arg LICENSE_SERVER=27000@MyServerName
ENV MLM_LICENSE_FILE=27000@flexlm-server-name
COPY ${PATH_TO_LICENSE} /opt/matlab/licenses/
ADD ${PATH_TO_LICENSE} /opt/matlab/licenses/
关于已安装依赖项的最后一点:某些报告需要显示设备来捕获模型的屏幕截图。Xvfb 为诸如 padv.builtin.task.GenerateSDDReport、padv.builtin.task.GenerateSimulinkWebView 和 padv.builtin.task.GenerateModelComparison 之类的任务提供虚拟显示。这应该作为 MPM 依赖项的一部分进行安装。请确保 MPM 由将运行该管道的用户安装。
在这个例子中,Dockerfile 配置为接受多个构建参量。构建参量对于维护一个可用于构建多个镜像的 Dockerfile 非常有价值,或者允许用户传入可能会随时间变化或不希望硬编码到 Dockerfile 本身中的构建信息。
此 Dockerfile 包含以下构建参量 (--build-arg):
# docker build --build-arg MATLAB_DOCKER_RELEASE=<matlab-docker-release> # --build-arg MATLAB_VERSION=<matlab-release> # --build-arg GITLAB_TOKEN=<gitlab-token> # --build-arg MATLAB_BATCH_TOKEN=<matlab-token> # --build-arg IMAGE_NAME=<image-image> # --build-arg PATH_TO_LICENSE=<path-to-license>
在 Dockerfile 的开头,您可以为每个参量指定默认值,以防构建命令未提供值:
ARG MATLAB_DOCKER_RELEASE=r2023b-ubuntu22.04 ARG MATLAB_VERSION=r2023b ARG MATLAB_BATCH_TOKEN="<USER>|TOKEN_ML|<TOKEN>" ARG GITLAB_TOKEN=<TOKEN> ARG IMAGE_NAME=matlab_image ARG PATH_TO_LICENSE=<PATH_TO_LICENSE>
在 Dockerfile 中的 FROM 语句之后,您必须声明将使用的变量:
FROM mathworks/matlab-deps:${MATLAB_DOCKER_RELEASE}
ARG MATLAB_VERSION
ARG MATLAB_BATCH_TOKEN
ARG GITLAB_TOKEN
ARG IMAGE_NAME
ARG PATH_TO_LICENSE
请注意上面的代码片段中,MATLAB_DOCKER_RELEASE 的值是通过 ${<var>} 语法访问的。
现在您的 Dockerfile 已准备就绪,您可以从 Docker 终端构建您的第一个容器:
> cd <path-to-dockerfile> > ls
> docker build -t <image-name> -f <dockerfile-name>
如果您的 Docker 文件使用构建参量,那么您的构建命令可能看起来更像这样:
> docker build --build-arg PATH_TO_LICENSE=<path-to-license> --build-arg GITLAB_TOKEN=<gitlab-runner-token> --build-arg MATLAB_BATCH_TOKEN="<USER>|TOKEN_ML|<TOKEN>" -t <image-name> -f <dockerfile-name>
容器构建完成后,您可以使用 UI 或终端从 Docker 运行它:
> docker run --name <container_name> -v <optional_volume> <image_name>:latest
您的 Dockerfile 已经将您的镜像注册为 gitlab-runner。要确认这一点,请查看 Docker 中的文件 /etc/gitlab-runner/config.toml 并验证是否注册了正确的 runner(图 5)。
如果 runner 注册不正确或需要更改或重新启动,请在 Docker 镜像的终端中使用以下命令取消注册 runner,然后恢复正确的 runner:
> sudo gitlab-runner unregister --token "<gitlab_token>" > sudo gitlab-runner register --non-interactive --url "<gitlab-url>" --token "<gitlab-runner-token>" --executor "shell"
现在容器正在运行并已注册为 GitLab runner,您可以运行 gitlab-runner 并开始监听作业(图 6)。从容器的终端,使用以下命令启动 runner:
> sudo gitlab-runner run
有许多方法可以启动您的管道,包括计划构建、手动或按需构建,以及基于对 GitLab 仓库的新提交的构建(图 7)。
curl 从终端触发构建的信息。一旦管道执行完毕,结果可以从管道中的最后一个作业 —— Collect_Artifacts 中查看和下载(图 8)。
在设置和配置 Docker 镜像时,能够沿途测试非常重要。以下是您可以在 Docker 容器的终端中执行的一些有用步骤,以确保一切按预期工作:
$ matlab-batch "disp('Hello, World.')"
$ sudo xvfb-run -e /dev/stdout -a matlab-batch "disp('Hello, World.')"
$ sudo git clone <gitlab-repo-url> <local-repo> $ sudo git clone https://<user>:<access_token>@<gitlab-repo-url> <local-repo>
$ cd <local-repo>/<project-path>
$ sudo -E matlab-batch -logfile "MATLAB_LOG_FILE" -nodesktop "cp = openProject(pwd); padv.pipeline.generatePipeline( padv.pipeline.GitLabOptions(PipelineArchitecture = padv.pipeline.Architecture.SerialStagesGroupPerTask, Tags = 'docker-matlab', GeneratedYMLFileName = 'simulink_pipeline.yml', GeneratedPipelineDirectory = fullfile('derived','pipeline'), MatlabLaunchCmd = 'xvfb -a matlab-batch', AddBatchStartupOption = false, EnableArtifactCollection = 'always'));"
simulink_pipeline.yml 文件的生成:$ cd derived $ ls
CI/CD 的集成对于维持高质量、可靠性和合规性标准至关重要。CI/CD 实践简化了开发过程,实现了更新的快速和一致交付,同时确保所有更改符合严格的认证要求。这种方法不仅提高了生产力,还显著降低了错误和违规的风险,这在认证环境中至关重要。
通过应用本文讨论的工具和实践,组织应该能够使用 Docker 和 GitLab Runner 建立一个稳健的环境,以创建一个高效且节省成本的 CI/CD 管道。该管道应促进简化、可靠且合规的开发生命周期,并最终有助于以更大的信心和效率交付高质量的可认证系统。
# 版权所有 2023 - 2025 The MathWorks, Inc.
variables:
MATLAB_LOG_FILE:"MATLAB_Log_Output.txt"
GIT_SUBMODULE_STRATEGY: recursive
MLM_LICENSE_TOKEN: "<USER>|TOKEN_ML|<BATCHTOKEN>"
stages:
- SimulinkPipelineGeneration
- SimulinkPipelineExecution
# 请勿更改此管道中的作业名称
SimulinkPipelineGeneration:
stage:SimulinkPipelineGeneration
tags:
- docker-matlab
script:
# 打开项目并使用适当的选项生成管道
sudo -E matlab-batch
-logfile "MATLAB_LOG_FILE"
-nodesktop
"cp = openProject(pwd);
padv.pipeline.generatePipeline(
padv.pipeline.GitLabOptions(
PipelineArchitecture = padv.pipeline.Architecture.SerialStagesGroupPerTask,
Tags = 'docker-matlab',
GeneratedYMLFileName = 'simulink_pipeline.yml',
GeneratedPipelineDirectory = fullfile('derived','pipeline'),
MatlabLaunchCmd = 'xvfb-run -a matlab-batch',
AddBatchStartupOption = false,
EnableArtifactCollection = 'always'));"
artifacts:
paths:
# 此文件由 padv.pipeline.generatePipeline 自动生成。
# 如果生成的管道文件的名称或位置发生更改,
# 请更新此字段
- derived/pipeline
SimulinkPipelineExecution:
stage:SimulinkPipelineExecution
trigger:
include:
- artifact: derived/pipeline/simulink_pipeline.yml
job:SimulinkPipelineGeneration
strategy: depend
# 请勿更改此变量的名称
variables:
PADV_ROOT_PIPELINE_ID: $CI_PIPELINE_ID
# 版权所有 2023 - 2025 The MathWorks, Inc.
# docker build --build-arg MATLAB_DOCKER_RELEASE=<matlab-docker-release>
# --build-arg MATLAB_VERSION=<matlab-release>
# --build-arg GITLAB_TOKEN=<gitlab-token>
# --build-arg MATLAB_BATCH_TOKEN=<matlab-token>
# --build-arg IMAGE_NAME=<image-image>
# -t <image-image>
# -f <dockerfile-name> .
# 示例:$ docker build --build-arg PATH_TO_LICENSE=<path-to-license> --build-arg GITLAB_TOKEN=<gitlab-token> --build-arg MATLAB_BATCH_TOKEN="<USER>|TOKEN_ML|<TOKEN>" -t matlab_image -f matlab.Dockerfile .
# 注意:最佳实践是在执行时传递 MATLAB Batch Token,
# 而不是像此处所示在构建时传递。为了简单起见,
# 此处在构建时传递了令牌。
# 若要指定在容器中安装哪个 MATLAB 版本,请编辑 MATLAB_RELEASE 参量的值。
# 使用小写字母指定版本,例如:ARG MATLAB_RELEASE=r2023b
ARG MATLAB_DOCKER_RELEASE=r2023b-ubuntu22.04
ARG MATLAB_VERSION=r2023b
ARG MATLAB_BATCH_TOKEN="<USER>|TOKEN_ML|<TOKEN>"
ARG GITLAB_TOKEN=<TOKEN>
ARG IMAGE_NAME=matlab_image
ARG PATH_TO_LICENSE=<PATH_TO_LICENSE>
# 当您开始构建阶段时,此 Dockerfile 默认使用基于 Ubuntu 的 matlab-deps 镜像。
# 若要查看可用的 matlab-deps 镜像,请参阅:https://hub.docker.com/r/mathworks/matlab-deps
FROM mathworks/matlab-deps:${MATLAB_DOCKER_RELEASE}
# 声明要在当前构建阶段使用的全局参量
ARG MATLAB_VERSION
ARG MATLAB_BATCH_TOKEN
ARG GITLAB_TOKEN
ARG IMAGE_NAME
ARG PATH_TO_LICENSE
RUN sudo apt-get update && \
sudo apt-get install --no-install-recommends --yes \
curl && \
sudo apt-get clean && sudo apt-get autoremove
RUN curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh" | sudo bash && \
sudo apt-get install --no-install-recommends --yes \
gitlab-runner && \
sudo apt-get clean && sudo apt-get autoremove && \
gitlab-runner start && \
sudo gitlab-runner register --non-interactive \
--url "https://external-git.mathworks.com/" \
--token "${GITLAB_TOKEN}" \
--docker-image ${IMAGE_NAME} \
--executor "shell"
# 安装 mpm 依赖项
RUN export DEBIAN_FRONTEND=noninteractive && \
sudo apt-get update && \
sudo apt-get install --no-install-recommends --yes \
wget \
ca-certificates \
xvfb \
build-essential \
clang \
libopenblas-dev \
liblapacke-dev \
liblapack-dev \
libomp-dev \
unzip \
iproute2 \
git \
libeigen3-dev \
cmake \
psmisc && \
sudo apt-get clean && sudo apt-get autoremove
RUN sudo apt-get update && sudo apt-get install libunwind-dev -y && \
sudo apt-get clean && sudo apt-get autoremove
# 安装 matlab-proxy 的依赖项
RUN DEBIAN_FRONTEND=noninteractive && \
sudo apt-get update && sudo apt-get install --no-install-recommends -y \
python3 \
python3-pip \
&& sudo apt-get clean \
&& sudo rm -rf /var/lib/apt/lists/*
RUN python3 -m pip install matlab-proxy
# 添加 "matlab_user" 用户并授予 sudo 权限
RUN adduser --shell /bin/bash --disabled-password --gecos "" matlab_user && \
echo "matlab_user ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/matlab_user && \
chmod 0440 /etc/sudoers.d/matlab_user
# 设置用户和工作目录
USER matlab_user
WORKDIR /home/matlab_user
# 运行 mpm 以在目标位置安装 MATLAB,并在之后删除 mpm 安装
# 在 --products 行添加工具箱,将空格替换为 _,例如 Simulink_Test
# 注意:仅当从 iso 文件安装时,mpm 才支持 Simulink_Code_Inspector:
RUN wget -q https://www.mathworks.com/mpm/glnxa64/mpm && \
chmod +x mpm && \
sudo ./mpm install \
--release=${MATLAB_VERSION} \
--destination=/opt/matlab \
--products MATLAB Simulink Stateflow \
Requirements_Toolbox \
Simulink_Check CI/CD_Automation_for_Simulink_Check Simulink_Design_Verifier \
Simulink_Test Simulink_Coverage \
MATLAB_Coder MATLAB_Compiler Simulink_Coder Simulink_Compiler Embedded_Coder \
Polyspace_Bug_Finder_Server Polyspace_Code_Prover_Server \
MATLAB_Report_Generator Simulink_Report_Generator \
DSP_System_Toolbox Simulink_3D_Animation Phased_Array_System_Toolbox \
Computer_Vision_Toolbox Image_Processing_Toolbox \
System_Identification_Toolbox Instrument_Control_Toolbox Aerospace_Toolbox \
Aerospace_Blockset Signal_Processing_Toolbox Symbolic_Math_Toolbox \
Automated_Driving_Toolbox DDS_Blockset Geoid_Data_for_Aerospace_Toolbox \
|| (echo "MPM 安装失败。请参阅下文以获取更多信息:" && cat /tmp/mathworks_root.log && false) && \
sudo rm -rf mpm /tmp/mathworks_root.log && \
sudo ln -s /opt/matlab/bin/matlab /usr/local/bin/matlab
# 必须取消注释以下 3 种配置许可证服务器方法中的
# 一种。
# 1) 批处理令牌
# 安装 matlab-batch 以启用 MATLAB 批处理许可令牌的使用。
RUN wget -q https://ssd.mathworks.com/supportfiles/ci/matlab-batch/v1/glnxa64/matlab-batch \
&& sudo mv matlab-batch /usr/local/bin \
&& sudo chmod +x /usr/local/bin/matlab-batch
# 2) 许可证服务器
#ARG LICENSE_SERVER
# 如果您希望将许可证信息作为环境变量绑定,请指定
# 提供网络许可证的机器的主机和端口。这是
# 许可的首选选项。可以使用类似
# --build-arg LICENSE_SERVER=27000@MyServerName 进行构建,或者
# 您可以直接使用以下方式指定许可证服务器
# ENV MLM_LICENSE_FILE=27000@flexlm-server-name
#ENV MLM_LICENSE_FILE=$LICENSE_SERVER
# 3) 许可证文件
# 或者,您可以将许可证文件放入容器中。
# 您应该填写此文件,其中包含您要使用的
# 许可证服务器的详细信息,并取消注释以下行。
#COPY ${PATH_TO_LICENSE} /opt/matlab/licenses/
ADD ${PATH_TO_LICENSE} /opt/matlab/licenses/
ENV ENV="/home/matlab_user/.profile"
ENV BASH_ENV="/home/matlab_user/.profile"
ENV MLM_LICENSE_TOKEN=${MATLAB_BATCH_TOKEN}
ENTRYPOINT ["xvfb-run"]
CMD ["/bin/bash"]
2025 年发布
选择网站
选择网站以获取翻译的可用内容,以及查看当地活动和优惠。根据您的位置,我们建议您选择:。
您也可以从以下列表中选择网站:
如何获得最佳网站性能
选择中国网站(中文或英文)以获得最佳网站性能。其他 MathWorks 国家/地区网站并未针对您所在位置的访问进行优化。
美洲
欧洲