标签 CD 下的文章

了解如何使用用于切换目录的一个基本但必不可少的 Linux 命令。

Linux 中的 cd 命令用于更改目录。cd 实际上是“ 更改目录 change directories ”的缩写。

这是你必须了解的 基本 Linux 命令之一。

使用 cd 命令非常简单:

cd path_to_directory

不可能比这更简单了,对吧。

然而,你应该理解它的路径部分,以便轻松地浏览 文件系统 而不会感到困惑。

这是绝对路径和相对路径的快速回顾:

Absolute vs relative path in Linux

如果你需要更多细节,我建议你阅读这篇文章:

Linux 上的绝对路径和相对路径有什么不同

让我们看一些使用 cd 命令的示例。

使用绝对路径更改目录

从视觉上看会更容易理解。看下图。

Absolute path travel to the python directory

我当前的位置是我的主目录(/home/abhishek),我必须进入 scripts 目录中的 python 目录。

假设我想使用绝对路径。python 目录的绝对路径是 /home/abhishek/scripts/python

cd /home/abhishek/scripts/python

cd command with absolute path

使用相对路径更改目录

让我们举同样的例子,但这次我将采用相对路径。

Relative path example

我的主目录到 python 目录的相对路径是 scripts/python。让我们用这个:

cd scripts/python

cd command with relative path

进入上级目录

到目前为止,你一直在进入下级。如果你必须进入上级目录怎么办?

假设你位于 /home/abhishek/scripts/python 中,并且必须将目录添加到 scripts

使用绝对路径始终是一种选择,但它相当冗长。相反,你可以使用特殊的目录符号 ..。双点 (..)表示父目录或上一级目录。单点(.)表示当前目录。

cd ..

这是一个例子:

cd up a directory

你可以使用 .. 在 Linux 文件系统层次结构中向上移动路径。

假设我在上图中的 python 目录中,想要进入 code 目录。这是我能做的:

cd ../../code

Go up the directory using cd command

进入主目录

如果你在所有这些目录切换中感到迷失并想回到主目录,有很多简单的快捷方式。

事实上,最简单的就是使用不带任何选项的 cd 命令。

cd

这将使你从文件系统上的任何位置返回主目录。

或者,你可以使用 ~ 符号,表示主目录。

cd ~

Use cd to go back home

进入根目录

尽管你不会像前一个那样经常使用它,但了解一下仍然有好处。

如果你想返回文件系统开始的根目录,请使用以下命令:

cd /

这里不涉及“魔法”。当放在路径开头使用时,/ 表示根。不要将它与路径分隔符混淆。

Paths in Linux

切换回上一级目录

这是一个救命稻草,或者我应该说是“省时稻草”。当你深入目录结构,然后转到另一个目录,然后你觉得需要返回到以前的位置时,此快捷方式会有所帮助。

cd -

还不清楚吗? 让我举个例子。

我位于 /etc/apt/sources.list.d。从这里,进入 /home/abhishek/scripts/python 来处理我的代码。然后我意识到我必须再次检查 /etc/apt/sources.list.d 目录中的某些内容。

通常的方法是这样做,这让我再次输入所有路径:

Go back to previous directory

但聪明的方法是使用这个:

Use cd - to go back to previous directory

看吧,无需再次输入冗长的路径。如期工作!

?️ 练习时间

如果你想练习 cd 命令,这里有一些练习供你使用。

  • 打开终端并进入 /var/log 目录。检查目录内容。你看到了什么?
  • 现在,进入 /var 目录。这是一个上级目录。
  • 从这里返回你的主目录。

这些内容足以让你熟悉 cd 命令。以下是你应该了解的其他一些重要命令。

每个 Ubuntu 用户都应该知道的 31 条 Linux 命令

如果你有疑问或建议,请告诉我。

(题图:MJ/6fbaa345-651a-4cb9-a752-130eda922790)


via: https://itsfoss.com/cd-command/

作者:Abhishek Prakash 选题:lkxed 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

对齐部署镜像和描述符是很困难的,但是某些策略可以使整个过程更高效。

 title=

在软件架构中,当两个组件之间有某些概念性或技术上的差异时会出现 阻抗失配 impedance mismatch 。这个术语其实是从电子工程中借用的,表示电路中输入和输出的电子阻抗必须要匹配。

在软件开发中,存储在镜像仓库中的镜像与存储在源码控制管理系统(LCTT 译注:SCM,Source Code Management)中它的 部署描述符 deployment descriptor 之间存在阻抗失配。你如何确定存储在 SCM 中的部署描述符表示的是正确的镜像?两个仓库追踪数据的方式并不一致,因此将一个镜像(在镜像仓库中独立存储的不可修改的二进制)和它的部署描述符(Git 中以文本文件形式存储的一系列修改记录)相匹配并不那么直观。

注意:本文假定读者已经熟悉以下概念:

  • 源码控制管理 Source Control Management (SCM)系统和分支
  • Docker 或符合 OCI 标准的镜像和容器
  • 容器编排系统 Container Orchestration Platforms (COP),如 Kubernetes
  • 持续集成/持续交付 Continuous Integration/Continuous Delivery (CI/CD)
  • 软件开发生命周期 Software development lifecycle (SDLC)环境

阻抗失配:SCM 与镜像仓库

为了更好地理解阻抗失配在什么场景下会成为问题,请考虑任意项目中的软件开发生命周期环境(SDLC),如开发、测试或发布环境。

测试环境不会有阻抗失配。现在使用 CI/CD 的最佳实践中开发分支的最新提交都会对应开发环境中的最新部署。因此,一个典型的、成功的 CI/CD 开发流程如下:

  1. 向 SCM 的开发分支提交新的修改
  2. 新提交触发一次镜像构建
  3. 新生成的镜像被推送到镜像仓库,标记为开发中
  4. 镜像被部署到容器编排系统(COP)中的开发环境,该镜像的部署描述符也更新为从 SCM 拉取的最新描述符。

换句话说,开发环境中最新的镜像永远与最新的部署描述符匹配。回滚到前一个构建的版本也不是问题,因为 SCM 也会跟着回滚。

最终,随着开发流程继续推进,需要进行更多正式的测试,因此某个镜像 —— 镜像对应着 SCM 中的某次提交 —— 被推到测试环境。如果是一次成功的构建,那么不会有大问题,因为从开发环境推过来的镜像应该会与开发分支的最新提交相对应。

  1. 开发环境的最新部署被允许入库,触发入库过程
  2. 最新部署的镜像被标记为测试中
  3. 镜像在测试环境中被拉取和部署,(该镜像)对应从 SCM 拉取的最新部署描述符

到目前为止,一切都没有问题,对吗?如果出现下面的场景,会有什么问题?

场景 A:镜像被推到下游环境,如 用户验收测试 user acceptance testing (UAT),或者是生产环境。

场景 B:测试环境中发现了一个破坏性的 bug,镜像需要回滚到某个确定正常的版本。

在任一场景中,开发过程并没有停止,即开发分支上游有了一次或多次新的提交,而这意味着最新的部署描述符已经发生了变化,最新的镜像与之前部署在测试环境中的镜像不一致。对部署描述符的修改可能会也可能不会对之前版本的镜像起作用,但是它们一定是不可信任的。如果它们有了变化,那么它们就一定与目前为止你测试过的想要部署的镜像的部署描述符不一致。

问题的关键是:如果部署的镜像不是镜像库中的最新版本,你怎么确定与部署的镜像相对应的是 SCM 中的哪个部署描述符? 一言以蔽之,无法确定。两个库直接有阻抗失配。如果要详细阐述下,那么是有方法可以解决的,但是你需要做很多工作,这部分内容就是文章接下来的主题了。请注意,下面的方案并不是解决问题的唯一办法,但是已经投入到生产环境并已经对很多项目起了作用,而且已经被构建并部署到生产环境中运行了超过一年。

二进制与部署描述符

源码通常被构建成一个 Docker 镜像或符合 OCI 标准的镜像,该镜像通常被部署到一个容器编排平台(COP)上,如 Kubernetes。部署到 COP 需要部署描述符来定义镜像被如何部署以及作为容器运行,如 Kubernetes 部署CronJobs。这是因为在镜像和它的部署描述符之间有本质差异,在这里可以看到阻抗失配。在这次讨论中,我们认为镜像是存储在镜像仓库中不可修改的二进制。对源码的任何修改都不会修改镜像,而是用另一个新的镜像去替换它。

相比之下,部署描述符是文本文件,因而可以被认为是源码且可修改。如果遵循最佳实践,那么部署描述符是被存储在 SCM,所有修改都会提交,而这很容易回溯。

解决阻抗失配

建议的解决方案的第一部分,就是提供一个能匹配镜像仓库中的镜像与对保存部署描述符的 SCM 做的代码提交的方法。最直接的解决方案是用源提交的哈希值标记镜像。这个方法可以区分不同版本的镜像、容易分辨,并且提供足够的信息来查找正确的部署描述符,以便镜像更好地部署到 COP。

再回顾下上面的场景:

场景 A 镜像被推到下游环境: 当镜像被从测试环境推到 UAT 环境时,我们可以从镜像的标签中知道应该从 SCM 的哪一次源码提交拉取部署描述符。

场景 B 当一个镜像需要在某一环节中回滚:无论我们选择回滚到那个镜像版本,我们都可以知道从 SCM 的哪一次源码提交拉取正确的部署描述符。

在每一种情景中,无论在某个镜像被部署到测试环境后开发分支有多少次提交和构建,对于每一次升级的镜像,我们都可以找到它当初部署时对应的部署描述符。

然而,这并不是阻抗失配的完整解决方案。再考虑两个场景:

场景 C 在负载测试环境中,会尝试对不同的部署描述符进行多次部署,以此来验证某一次构建的表现。

场景 D 一个镜像被推送到下游环境,在该环境中部署描述符有一个错误。

在上面的所有场景中,我们都需要修改部署描述符,但是目前为止我们只有一个源码提交哈希。请记住,最佳实践要求我们所有对源码的修改都要先提交到 SCM。某次提交的哈希本身是无法修改的,因此我们需要一个比仅仅追踪原来的源码提交哈希更好地解决方案。

解决方案是基于原来的源码提交哈希新建一个分支。我们把这个分支称为部署分支。每当一个镜像被推到下游测试或发布环境时,你应该基于前一个 SDLC 环境的部署分支的最新提交创建一个新的部署分支。

这样同一个镜像可以重复多次部署到不同的 SDLC 环境,并在后面每个环境中可以感知前面发现的改动或对镜像做的修改。

注意: 在某个环境中做的修改是如何影响下一个环境的,是用可以共享数据的工具(如 Helm Charts)还是手动剪切、粘贴到其他目录,都不在本文讨论的范围内。

因此,当一个镜像被从一个 SDLC 环境中推到下一环境时:

  1. 创建一个部署分支

    1. 如果镜像是从开发环境中推过来的,那么部署分支就基于构建这个镜像的源码提交哈希创建
    2. 否则,部署分支基于当前部署分支的最新提交创建
  2. 镜像被部署到下一个 SDLC 环境,使用的部署描述符是该环境中新创建的部署分支的部署描述符

deployment branching tree

图 1:部署分支树

  1. 部署分支
  2. 下游环境的第一个部署分支,只有一次提交
  3. 下游环境的第二个部署分支,只有一次提交

有了部署分支这个解决方案,再回顾下上面的场景 C 和场景 D:

场景 C 修改已经部署到下游 SDLC 环境中的镜像的部署描述符

场景 D 修复某个 SDLC 环境中部署描述符的错误

两个场景中,工作流如下:

  1. 把对部署描述符做的修改提交到 SLDC 环境和镜像对应的部署分支
  2. 通过部署分支最新提交对应的部署描述符把镜像重新部署到 SLDC 环境

这样,部署分支彻底解决了(存储着代表一次独一无二的构建的单一的、不可修改的镜像的)镜像仓库与(存储着对应一个或多个 SDLC 环境的可修改的部署描述符的)SCM 仓库之间的阻抗失配。

实践中的思考

这看起来像是行得通的解决方案,但同时它也为开发者和运维人员带来了新的实践中的问题,比如:

A. 为了更好地管理部署分支,部署描述符作为资源应该保存在哪里,是否要与构建镜像的源码保存在同一个 SCM 仓库?

到目前为止,我们都在避免谈论应该把部署描述符放在哪个仓库里。在还没有太多细节需要处理时,我们推荐把所有 SDLC 环境的部署描述符与镜像源码放在同一个 SCM 仓库。当部署分支创建后,镜像的源码可以作为方便找到部署的容器中运行的镜像的引用来使用。

上面提到过,可以通过镜像的标签来关联镜像与原始的源码提交。在一个单独的仓库中查找某次提交的源码的引用,会给开发者带来更大的困难(即便借助工具),这就是没有必要把所有资源都分开存储的原因。

B. 应该在部署分支上修改构建镜像的源码吗?

简答:不应该

详细阐述:不应该,因为永远不要在部署分支上构建镜像,它们是在开发分支上构建的。修改部署分支上定义一个镜像的源码会破坏被部署的镜像的构建记录,而且这些修改并不会对镜像的功能生效。在对比两个部署分支的版本时这也会成为问题。这可能会导致两个版本的功能差异有错误的测试结果(这是使用部署分支的一个很小的额外好处)。

C. 为什么使用镜像 标签 tag 标记 label 不可以吗?

通过 标签 tag 可以在仓库中很容易地查找镜像,可读性也很好。在一组镜像中读取和查找 标记 label 的值需要拉取所有镜像的 清单文件 manifest ,而这会增加复杂度、降低性能。而且,考虑到历史记录的追踪和不同版本的查找,对不同版本的镜像添加 标签 tag 也很有必要,因此使用源码提交哈希是保证唯一性,以及保存能即时生效的有用信息的最简单的解决方案。

D. 创建部署分支的最佳实践是怎样的?

DevOps 最重要的三个原则:自动化、自动化、自动化。

依赖资源来持续地强迫遵循最佳实践,充其量只是碰运气,因此在实现镜像的升级、回滚等 CI/CD 流水线时,把自动化部署分支写到脚本里。

E. 对部署分支的命名规范有建议吗?

<部署分支标识>-<环境>-<源码提交哈希>

  • 部署分支标识: 所有部署分支范围内唯一的字符串;如 “deployment” 或 “deploy”
  • 环境: 部署分支适用的 SDLC 环境;如 “qa”(测试环境)、 “stg”(预生产环境)、 或 “prod”(生产环境)
  • 源码提交哈希: 源码提交哈希中包含原来构建被部署的镜像的源码,开发者可以通过它很容易地查找到创建镜像的原始提交,同时也能保证分支名唯一。

例如, deployment-qa-asdf78s 表示推到 QA 环境的部署分支, deployment-stg-asdf78s 表示推到 STG 环境的部署分支。

F. 你怎么识别环境中运行的哪个镜像版本?

我们的建议是把最新的部署分支提交哈希和源码提交哈希添加到 标记 中。开发者和运维人员可以通过这两个独一无二的标识符查找到部署的所有东西及其来源。在诸如执行回滚或前滚操作时,使用那些不同版本的部署的选择器也能清理资源碎片。

G. 什么时候应该把部署分支的修改合并回开发分支?

这完全取决于开发团队。

如果你修改的目的是为了做负载测试,只是想验证什么情况会让程序崩溃,那么这些修改不应该被合并回开发分支。另一方面,如果你发现和修复了一个错误,或者对下游环境的部署做了调整,那么就应该把部署分支的修改合并回开发分支。

H. 有现成的部署分支示例让我们试水吗?

el-CICD 已经在生产上使用这个策略持续一年半应用到超过一百个项目了,覆盖所有的 SDLC 环境,包括管理生产环境的部署。如果你可以访问 OKD、Red Hat OpenShift lab cluster 或 Red Hat CodeReady Containers,你可以下载el-CICD 的最新版本,参照 教程 来学习部署分支是何时以怎样的方式创建和使用的。

结语

通过实践上面的例子可以帮助你更好的理解开发过程中阻抗失配相关的问题。对齐镜像和部署描述符是成功管理部署的关键部分。


via: https://opensource.com/article/21/8/impedance-mismatch-cicd

作者:Evan "Hippy" Slatis 选题:lujun9972 译者:lxbwolf 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

GitHub Actions 是一项为快速建立持续集成和交付(CI/CD)工作流程而提供的服务。这些工作流程在被称为“ 运行器 runner ”的主机上运行。GitHub 提供的 托管运行器 的操作系统的选择是有限的(Windows Server、Ubuntu、MacOS)。

另一个选择是使用 自托管 的运行器,这让仓库管理员对运行器有更多控制。自托管的运行程序是专门为某个存储库或组织服务的。下面的文章介绍了使用 Fedora CoreOS 配置自托管运行程序的步骤。

入门

Fedora CoreOS 是一个精简的操作系统,旨在便于大规模的部署和维护。该操作系统会自动更新,并默认提供运行容器所需的工具。由于这些原因,Fedora CoreOS 是运行 CI/CD 工作流程的一个极佳选择。

配置和配备 Fedora CoreOS 机器的第一步是生成一个 Ignition 文件。Butane 允许你使用更友好的格式(YAML)生成 Ignition 文件。

配置一个 Fedora CoreOS 运行器

要在 Fedora CoreOS 上执行 GitHub Actions,托管主机需要用于注册和运行该运行器的二进制文件和脚本。从 Actions 运行器项目 下载二进制文件和脚本,并部署在 /usr/local/sbin/actions-runner 下。

version: "1.3.0"
variant: fcos
storage:
  directories:
    - path: /usr/local/sbin/actions-runner
      mode: 0755
      user:
        name: core
      group:
        name: core
  files:
    - path: /usr/local/sbin/actions-runner/actions-runner-linux.tar.gz
      overwrite: true
      contents:
        source: https://github.com/actions/runner/releases/download/v2.278.0/actions-runner-linux-x64-2.278.0.tar.gz
      mode: 0755
      user:
        name: core
      group:
        name: core

注册和删除令牌

为一个项目配置运行器需要一个“ 令牌 token ”。这可以防止在没有正确权限的情况下从项目中注册或删除自托管的运行器。GitHub 提供的令牌有一个小时的过期时间。如果运行器在这个时间之后重新启动,它将需要一个新的注册令牌。

该令牌可能出问题,特别是在 Fedora CoreOS 自动更新时。更新过程希望托管主机在收到新数据后至少每隔几周重启一次。

幸运的是,可以使用 GitHub REST API 来获取这些令牌,并在托管主机每次重启时自动配置运行器。下面的 manage-runner.sh 脚本使用 API 来获取令牌,删除任何已经配置好的运行器,并用新的令牌注册运行器。

#!/bin/bash
# Handles the Github Action runner configuration.
# Remove and Registration token expires after 1 hour, if we want our runner
# to work after a reboot (auto update) we need to refresh the tokens.

# First remove the runner with a fresh remove token
REMOVE_TOKEN=$(curl -u ${GITHUB_USER}:${GITHUB_TOKEN} -X POST -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/${GITHUB_USER}/${GITHUB_REPO}/actions/runners/remove-token | jq -r '.token')
/usr/local/sbin/actions-runner/config.sh remove --token ${REMOVE_TOKEN}


# Then register the runner with a fresh registration token
REGISTRATION_TOKEN=$(curl -u ${GITHUB_USER}:${GITHUB_TOKEN} -X POST -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/${GITHUB_USER}/${GITHUB_REPO}/actions/runners/registration-token | jq -r '.token')
/usr/local/sbin/actions-runner/config.sh --url https://github.com/cverna/fcos-actions-runner --token ${REGISTRATION_TOKEN} --labels fcos --unattended

上面的脚本使用了一些环境变量,包含 GitHub 用户名和用于验证 REST API 请求的 个人访问令牌 Personal Access Token 。个人访问令牌需要存储库权限,以便成功检索运行器的注册和移除令牌。该令牌是安全敏感信息,所以最好将其存储在一个具有更严格权限的不同文件中。在这个例子中,这个文件是 actions-runner

GITHUB_USER=<user>
GITHUB_REPO=<repo>
GITHUB_TOKEN=<personal_access_token>

以下是创建这两个文件 manage-runner.shactions-runner 的 Butane 片段。

- path: /usr/local/sbin/actions-runner/manage-runner.sh
      contents:
        local: manage-runner.sh
      mode: 0755
      user:
        name: core
      group:
        name: core
    - path: /etc/actions-runner
      contents:
        local: actions-runner
      mode: 0700
      user:
        name: core
      group:
        name: core

在 Fedora CoreOS 上运行 Actions

最后,创建用于配置和启动运行器的 systemd 服务。在 Butane 配置文件中定义这些服务。

systemd:
  units:
    - name: github-runner-configure.service
      enabled: true
      contents: |
        [Unit]
        Description=Configure the github action runner for a repository
        After=network-online.target boot-complete.target
        Requires=boot-complete.target
        [Service]
        EnvironmentFile=/etc/actions-runner
        Type=oneshot
        RemainAfterExit=yes
        User=core
        WorkingDirectory=/usr/local/sbin/actions-runner
        ExecStartPre=tar xvf actions-runner-linux.tar.gz --no-same-owner
        ExecStart=/usr/local/sbin/actions-runner/manage-runner.sh
        [Install]
        WantedBy=multi-user.target
    - name: github-runner.service
      enabled: true
      contents: |
        [Unit]
        Description=Run the github action runner
        After=github-runner-configure.service
        [Service]
        WorkingDirectory=/usr/local/sbin/actions-runner
        User=core
        ExecStart=/usr/local/sbin/actions-runner/run.sh
        [Install]
        WantedBy=multi-user.target

这将创建两个服务:github-runner-configure.service(在主机启动完成后运行一次)和 github-runner.service(运行 Actions 运行器二进制文件并等待新的 CI/CD 作业)。

现在 Butane 配置已经完成,从中生成一个 Ignition 文件并配备一个 Fedora CoreOS Actions 运行器。

$ podman run -i --rm -v $PWD:/code:z --workdir /code quay.io/coreos/butane:release --pretty --strict --files-dir /code config.yaml -o config.ignition

一旦 Ignition 文件生成,它就可以用来在 支持 Fedora CoreOS 的平台上配备一个运行器。

配置一个 Action 来使用一个自托管的运行器

下面的测试 Action 工作流程将测试 FCOS 的自托管的运行器。在你的 git 存储库中创建以下文件 .github/workflows/main.yml

# This is a basic workflow to help you get started with Actions

name: CI

# Controls when the action will run.
on:
  # Triggers the workflow on push or pull request events but only for the main branch
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a single job called "build"
  build:
    # The type of runner that the job will run on
    runs-on: fcos

    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:
      # Runs a single command using the runners shell
      - name: Run a one-line script
        run: podman run --rm fedora-minimal:34 echo Hello World !

请注意,runs-on 的配置被设置为使用标签为 fcos 的运行器。

本文介绍的代码可以在 这里 中找到。


via: https://fedoramagazine.org/run-github-actions-on-fedora-coreos/

作者:Clément Verna 选题:lujun9972 译者:wxy 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

你如何定义持续集成/持续部署管道取决于你组织的要求。

 title=

持续集成 continuous integration / 持续部署 continuous deployment (CI/CD)管道是每个 DevOps 计划的基础。 CI/CD 管道打破了传统的开发孤岛,使开发和运营团队能够在整个软件开发生命周期中进行协作。

更好的是,转向 DevOps 和 CI/CD 管道可以帮助你的组织以更高的速度更安全地 交付软件

拆解 CI/CD 管道

CI/CD 管道有很多定义,所以我总是建议组织定义自己的 CI/CD 管道版本和其他 DevOps 概念,而不是使用其他人的。开源 CI/CD 工具为你提供构建满足组织要求的 CI/CD 管道的自由和选择。

形成 CI/CD 管道的阶段是将不同的任务子集分组为 管道阶段。典型的管道阶段包括:

  • 构建:开发人员编译应用程序代码。
  • 测试:质量保证(QA)团队使用自动化测试工具和策略测试应用程序代码。
  • 发布:开发团队将应用程序代码交付到代码库。
  • 部署:DevOps 团队将应用程序代码分阶段投入生产。
  • 安全性和合规性:QA 团队根据项目要求验证构建。这是组织部署容器扫描工具的阶段,这些工具根据 常见漏洞和暴露 Common Vulnerabilities and Exposures (CVE)检查容器镜像的质量。

这些是 CI/CD 管道的标准阶段,但一些组织调整 CI/CD 管道模型以满足他们的要求。例如,为医疗保健市场构建应用程序的组织,具有严格的合规性标准,可以在整个工具链中分发测试、验证和合规性门槛。

其他示例可能是依赖于具有开源软件(OSS)的复杂软件供应链的组织。商业组件可能会设立一个门槛,开发团队成员可以在其中为 OSS 包生成 软件物料清单 software bill of materials (SBOM),或者外部商业软件供应商必须将 SBOM 作为其合同可交付成果的一部分进行交付。

CI/CD 管道的障碍

实施 CI/CD 管道会改变团队的流程和文化。尽管许多开发人员愿意接受某些任务和测试的自动化,但人员可能成为采用 CI/CD 的障碍。

从瀑布式流程转向 CI/CD 可能会动摇某些组织中基本的和隐含的权力结构。由于 CI/CD 管道提高了软件交付速度,旧手动流程的“守门人”可能会受到这种变化的威胁。

整合机会

随着你在文化、流程和工具中达到更高的 DevOps 成熟度水平,包含 CI/CD 工具链的工具的开源根源为一些激动人心的集成创造了机会。

分析公司 Forrester 在 2020 年预测, 即时学习 just-in-time learning 将加入 CI/CD 管道。如果你考虑一下,会发现这是有道理的。在当前远程工作的时代,甚至对于新员工的远程入职,这更有意义。例如,组织可以将文档 wiki 与内部流程文档集成到其管道中。

更雄心勃勃的组织可以将学习管理系统(LMS)(例如 Moodle)集成到其 CI/CD 管道中。它可以使用 LMS 发布有关新 DevOps 工具链功能的简短视频,开发人员在加入时或在整个管道中更新工具时需要学习这些功能。

一些组织正在将群聊和其他协作工具直接集成到他们的 CI/CD 管道中。聊天平台提供警报并支持团队之间的协作和沟通。将 Mattermost、Rocket.Chat 或其他 企业聊天 平台集成到你的 CI/CD 管道中需要预先规划和分析,以确保管道用户不会被警报淹没。

另一个需要探索的集成机会是将分析和高级报告构建到你的 CI/CD 管道中。这有助于你利用通过管道传输的数据。

总结

CI/CD 管道是 DevOps 的基础。开源使其能够适应并灵活地满足你在 DevOps 之旅中实施的运营变更所产生的新需求。

我希望看到对统一 DevOps 平台趋势的开源响应,在这种趋势中,组织寻求端到端的 CI/CD 解决方案。这种解决方案的要素就在那里。毕竟,GitLab 和 GitHub 将他们的平台追溯到开源根源。

最后,不要忘记每一个成功的 CI/CD 工具链背后的教育和外展。记录你的工具链和相关流程将改善开发人员入职和持续的 DevOps 团队培训。

你和你的组织如何定义你的 CI/CD 工具链?请在评论中分享你的反馈。


via: https://opensource.com/article/21/6/what-cicd-pipeline

作者:Will Kelly 选题:lujun9972 译者:baddate 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

统一的持续集成与持续交付的流水线的构想是一种梦想吗?

当我加入 WorkSafeBC 负责云端运维和工程流程优化的云端运维团队时,我和大家分享了我的梦想,那就是一个工具化的流水线,每一个产品都可以持续集成和持续交付。

根据 Lukas Klose 的说法, 流程 flow (在软件工程的语境内)是“软件系统以稳定和可预测的速度创造价值的状态”。我认为这是最大的挑战和机遇之一,特别是在复杂的新兴解决方案领域。我力求通过一种持续、高效和优质的解决方案,提供一种持续交付模式,并且能够构建正确的事物让我们的用户感到满意。想办法把我们的系统分解成更小的碎片,这些碎片本身是有价值的,使团队能够渐进式地交付价值。这需要业务和工程部门改变思维方式。

持续集成和持续交付的(CI/CD)流水线

CI/CD 流水线是一种 DevOps 实践,用于更频繁、一致、可靠的地交付代码变更。它可以帮助敏捷开发团队提高部署频率,减少变更准备时间变更失败率和关键绩效指标(KPI)的平均恢复时间,从而提高质量并且实现更快的交付。唯一的先决条件就是坚实的开发流程、对质量的心态和对需求从构想到废弃的责任心,以及一个全面的流水线(如下图所示)。

 title=

它简化了工程流程和产品,以稳定基础架构环境;优化工作流程;并创建一致的、可重复的、自动化的任务。正如 Dave Snowden 的 Cynefin Sensemaking 模型所说的那样,这样就允许我们将复杂不可解决的任务变成了复杂可解决的任务,降低了维护成本,提高了质量和可靠性。

精简流程的一部分是将 浪费实践类型 wasteful practice types Muri(过载)、Mura(变异)和 Muda(浪费)的浪费降低最低。

  • Muri(过载):避免过度工程化,避免与商业价值不相关的功能以及过多的文档。
  • Mura(变异):改善审批和验证流程(比如,安全签批);推动 左移提前 shift-left 策略以推行单元测试、安全漏洞扫描与代码质量检查;并改进风险评定。
  • Muda(浪费):避免技术债、错误或前期的详细文档等浪费。

看起来 80% 的重点都集中在提供一种可以集成和协作的工程产品上,这些系统可以采用一个创意和计划、开发、测试和监控你的解决方案。然而,一个成功的转型和工程系统是由 5% 的产品、15% 的过程和 80% 的开发人员组成的。

我们可以使用的产品有很多。比如,Azure DevOps 为持续集成(CI)、持续交付(CD)和可扩展性提供了丰富支持,并与 Stryker、SonarQube、WhiteSource、Jenkins 和 Octopus 等开源集成和商用成品(COTS)软件即服务(SaaS)进行集成。对于工程师来说,关注产品总是一种诱惑,但请记住,它们只是我们旅程的 5%。

 title=

最大的挑战是打破数十年的规则、规定和已经步入舒适区的流程:“我们一直都是这样做的;为什么需要改变呢?

开发和运维人员之间的摩擦导致了各种支离破碎的、重复的、不间断的集成和交付流水线。开发人员希望能访问所有东西,以便持续迭代,让用户使用起来和持续地快速发布。运维人员希望将所有东西锁起来,保护业务、用户和品质。这些矛盾在不经意间导致了很难做到一种自动化的流程,进而导致发布周期晚于预期。

让我们使用最近的一次白板讨论中的片段来探索流水线。

想要支持流水线的变化是一项困难并且花费巨大的工作;版本和可追溯性的不一致使得这个问题变得更加复杂,因此不断精简开发流程和流水线是一项挑战。

 title=

我主张一些原则使得每个产品都能使用通用流水线:

  • 使一切可自动化的东西都自动化
  • 一次构建
  • 保持持续集成和持续交付
  • 保持持续精简和改进
  • 保持一个构建的定义
  • 保持一个发布流水线的定义
  • 尽早、频繁地扫描漏洞,并且尽快失败
  • 尽早、频繁地进行测试,并且尽快失败
  • 保持已发布版本的可追踪和监控

但是,如果我要打破这些,最重要的原则就是保持简单。如果你不能说明流水线化的原因(是什么、为什么)和过程(如何),你或许是不了解自己的软件过程的。我们大多数人想要的不是最好的、超现代的和具有革命意义的流水线 —— 我们仅仅是需要一个功能强大的、有价值的和能促进工程的流水线。首先需要解决的是那 80% —— 文化、人员和他们的心态。请你的 CI/CD 骑士们穿上闪亮的盔甲,在他们的盾牌上贴上 TLA( 两个/三个字母的缩写 two/three-lettered acronym )符号,加入到实践和经验工程的力量中来。

统一流水线

让我们逐步完成我们的白板会议实践。

 title=

每个应用使用一套构建定义来定义一个 CI/CD 流水线,用来触发拉取请求的预合并验证持续集成的构建。生成一个带有调试信息的发布的构建,并且将其上传到 符号服务器。这使开发人员可以在本地和远程生产环境进行调试,而在不用考虑需要加载哪个构建和符号,符号服务器为我们施展了这样的魔法。

 title=

在构建过程中进行尽可能多的验证(左移提前),这允许开发新特性的团队可以尽快失败,不断的提高整体的产品质量,并在拉取请求中为代码审核人员提供宝贵证据。你喜欢有大量提交的拉取请求吗?还是一个带有少数提交和提供了漏洞检查、测试覆盖率、代码质量检查和 Stryker 突变残余等支持的拉取请求?就我个人而言,我投后者的票。

 title=

不要使用构建转换来生成多个特定环境的构建。通过一个构建实现发布时转换标记化和 XML/JSON 的值替换。换句话说,右移滞后具体环境的配置。

 title=

安全存储发布配置数据,并且根据数据的信任度敏感度,让开发和运维都能使用。使用开源的密钥管理工具、Azure 密钥保险库、AWS 密钥管理服务或者其他产品,记住你的工具箱中有很多方便的工具。

 title=

使用用户组而不是用户,将审批人管理从跨多个流水线的多个阶段移动到简单的组成员。

 title=

创建一条流水线并且对赋予特定的交付阶段的权限,而不是重复流水线让团队进入他们感兴趣的地方。

 title=

最后,但并非最不重要的是,拥抱拉取请求,以帮助提高对代码仓库的洞察力和透明度,增进整体质量、协作,并将预验证构建发布到选定的环境,比如,开发环境。

这是整个白板更正式的视图。

 title=

所以,你对 CI/CD 流水线有什么想法和经验?我的通过一条流水线来管理它们的这个梦想是空想吗?


via: https://opensource.com/article/19/7/cicd-pipeline-rule-them-all

作者:Willy-Peter Schaub 选题:lujun9972 译者:chunibyo-wly 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

cd 命令可能是任何 Linux 用户学习的前 10 个命令之一,但这并不是在 Linux 文件系统中导航的唯一方法,这里还有其他一些方法。

无论你是在文件系统中四处查看、寻找文件还是尝试进入重要目录,Linux 都可以提供很多帮助。在本文中,我们将介绍一些技巧,使你可以在文件系统中移动,查找和使用所需的命令也更加轻松。

添加到 $PATH

确保你不必花费大量时间在 Linux 系统上查找命令的最简单、最有用的方法之一就是在 $PATH 变量中添加适当的目录。但是,添加到 $PATH 变量中的目录顺序非常重要。它们确定系统在目录中查找要运行命令的目录顺序–在找到第一个匹配项时停止。

例如,你可能希望将家目录放在第一个,这样,如果你创建的脚本与其他可执行文件有相同的名称,那么只要输入该脚本的名称,它便会运行。

要将家目录添加到 $PATH 变量中,可以执行以下操作:

$ export PATH=~:$PATH

~ 字符代表家目录。

如果将脚本保存在 bin 目录中,下面的会有效:

$ export PATH=~/bin:$PATH

然后,你可以运行位于家目录中的脚本,如下所示:

$ myscript
Good morning, you just ran /home/myacct/bin/myscript

重要提示:上面显示的命令会添加到你的搜索路径中,因为 $PATH(当前路径)被包含在内。它们不会覆盖它。你的搜索路径应该在你的 .bashrc 文件中配置,任何你打算永久化的更改也应该添加到那里。

使用符号链接

符号链接提供了一种简单而明显的方式来记录可能经常需要使用的目录的位置。例如,如果你管理网站的内容,那么可能需要通过创建如下链接来使你的帐户“记住”网页文件的位置:

ln -s /var/www/html www

参数的顺序很重要。第一个(/var/www/html)是目标,第二个是你创建的链接的名称。如果你当前不在家目录中,那么以下命令将执行相同的操作:

ln -s /var/www/html ~/www

设置好之后,你可以使用 cd www 进入 /var/www/html

使用 shopt

shopt 命令还提供了一种让移动到其他目录更加容易的方法。当你使用 shoptautocd 选项时,只需输入名称即可转到目录。例如:

$ shopt -s autocd
$ www
cd -- www
/home/myacct/www
$ pwd -P
/var/www/html

$ ~/bin
cd -- /home/myacct/bin
$ pwd
/home/myacct/bin

在上面的第一组命令中,启用了 shopt 命令的 autocd 选项。输入 www,就会调用 cd www 命令。由于此符号链接是在上面的 ln 命令示例之一中创建的,因此将我们移至 /var/www/htmlpwd -P 命令显示实际位置。

在第二组中,键入 ~/bin 会调用 cd 进入在用户家目录的 bin 目录。

请注意,当你输入的是命令时,autocd 行为将不会生效,即使它也是目录的名称。

shopt 是 bash 内置命令,它有很多选项。这只是意味着你不必在要进入每个目录的名称之前输入 cd

要查看 shopt 的其他选项,只需输入 shopt

使用 $CDPATH

可能进入特定目录的最有用技巧之一,就是将你希望能够轻松进入的路径添加到 $CDPATH 中。这将创建一个目录列表,只需输入完整路径名的一部分即可进入。

一方面,这可能有点棘手。你的 $CDPATH 需要包含要移动到的目录的父目录,而不是目录本身。

例如,假设你希望仅通过输入 cd html 就可以移至 /var/www/html 目录,并仅使用 cd 和简单目录名即可移至 /var/log 中的子目录。在这种情况下,此 $CDPATH 就可以起作用:

$ CDPATH=.:/var/log:/var/www

你将看到:

$ cd journal
/var/log/journal
$ cd html
/var/www/html

当你输入的不是完整路径时,$CDPATH 就会生效。它向下查看其目录列表,以查看指定的目录是否存在于其中一个目录中。找到匹配项后,它将带你到那里。

$CDPATH 开头保持 . 意味着你可以进入本地目录,而不必在 $CDPATH 中定义它们。

$ export CDPATH=".:$CDPATH"
$ Videos
cd -- Videos
/home/myacct/Videos

在 Linux 文件系统键切换并不难,但是如果你使用一些方便的技巧轻松地到达各个位置,那你可以节省一些大脑细胞。


via: https://www.networkworld.com/article/3533421/tricks-for-getting-around-your-linux-file-system.html

作者:Sandra Henry-Stocker 选题:lujun9972 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出