OpenShift 上的现代应用程序,第 3 部分:OpenShift 作为开发环境和 OpenShift Pipelines

这个博客的大家好! 这是系列文章的第三篇,我们将在其中展示如何在 Red Hat OpenShift 上部署现代 Web 应用程序。

OpenShift 上的现代应用程序,第 3 部分:OpenShift 作为开发环境和 OpenShift Pipelines

在前两篇文章中,我们展示了如何通过几个步骤部署现代 Web 应用程序,以及如何使用新的 S2I 映像以及现成的 HTTP 服务器映像(例如 NGINX),使用链式构建来编排生产部署。

今天,我们将展示如何在 OpenShift 平台上为您的应用程序运行开发服务器并将其与本地文件系统同步,还将讨论什么是 OpenShift Pipelines 以及如何将它们用作链接程序集的替代方案。

OpenShift 作为开发环境

开发流程

如前所述 第一篇文章现代 Web 应用程序的典型开发过程只是某种跟踪本地文件更改的“开发服务器”。 当它们发生时,应用程序构建被触发,然后更新到浏览器。

在大多数现代框架中,这样的“开发服务器”被内置到相应的命令行工具中。

本地示例

首先,让我们看看在本地运行应用程序时它是如何工作的。 我们以应用程序为例 应对 尽管几乎相同的工作流概念适用于所有其他现代框架,但从之前的文章中可以看出。
因此,要在 React 示例中启动“开发服务器”,我们将输入以下命令:

$ npm run start

然后在终端窗口中我们会看到这样的内容:

OpenShift 上的现代应用程序,第 3 部分:OpenShift 作为开发环境和 OpenShift Pipelines

我们的应用程序将在默认浏览器中打开:

OpenShift 上的现代应用程序,第 3 部分:OpenShift 作为开发环境和 OpenShift Pipelines

现在,如果我们对文件进行更改,应用程序应该在浏览器中更新。

好的,本地模式下的开发一切都清楚了,但是如何在 OpenShift 上实现同样的目标呢?

OpenShift 上的开发服务器

如果你还记得的话,在 上一篇中,我们查看了 S2I 映像的所谓运行阶段,发现默认情况下,serve 模块负责为我们的 Web 应用程序提供服务。

然而,如果你仔细观察 运行脚本 在该示例中,它包含 $NPM_RUN 环境变量,它允许您执行命令。

例如,我们可以使用nodeshift模块来部署我们的应用程序:

$ npx nodeshift --deploy.env NPM_RUN="yarn start" --dockerImage=nodeshift/ubi8-s2i-web-app

注意:上面的例子是为了说明总体思路而进行了缩写。

在这里,我们将 NPM_RUN 环境变量添加到我们的部署中,它告诉运行时运行yarn start 命令,该命令启动 OpenShift pod 内的 React 开发服务器。

如果您查看正在运行的 pod 的日志,它将如下所示:

OpenShift 上的现代应用程序,第 3 部分:OpenShift 作为开发环境和 OpenShift Pipelines

当然,除非我们能够将本地代码与代码同步,所有这一切都将毫无意义,该代码也受到更改但位于远程服务器上。

同步远程和本地代码

幸运的是,nodeshift 可以轻松帮助同步,并且您可以使用 watch 命令来跟踪更改。

因此,在运行命令为应用程序部署开发服务器后,我们可以安全地使用以下命令:

$ npx nodeshift watch

结果,将与我们之前创建的正在运行的 pod 建立连接,将激活本地文件与远程集群的同步,并且将开始监视本地系统上的文件是否发生更改。

因此,如果我们现在更新 src/App.js 文件,系统将对这些更改做出反应,将它们复制到远程集群并启动开发服务器,然后开发服务器将在浏览器中更新我们的应用程序。

为了使图片更加完整,让我们展示一下整个命令的样子:

$ npx nodeshift --strictSSL=false --dockerImage=nodeshift/ubi8-s2i-web-app --build.env YARN_ENABLED=true --expose --deploy.env NPM_RUN="yarn start" --deploy.port 3000

$ npx nodeshift watch --strictSSL=false

watch 命令是 oc rsync 命令之上的抽象,您可以了解有关其工作原理的更多信息 这里.

这是 React 的示例,但完全相同的方法可以用于其他框架,只需根据需要设置 NPM_RUN 环境变量即可。

开放式管道

OpenShift 上的现代应用程序,第 3 部分:OpenShift 作为开发环境和 OpenShift Pipelines

接下来我们将讨论 OpenShift Pipelines 等工具以及如何使用它来替代链式构建。

什么是 OpenShift 管道

OpenShift Pipelines 是一种云原生 CI/CD 持续集成和交付系统,专为使用 Tekton 组织管道而设计。 Tekton 是一个灵活的开源 Kubernetes 原生 CI/CD 框架,允许您通过从底层抽象来自动化在各种平台(Kubernetes、无服务器、虚拟机等)上的部署。

理解本文需要一些 Pipelines 知识,因此我们强烈建议您首先阅读 官方教科书.

设置您的工作环境

要使用本文中的示例,您首先需要准备工作环境:

  1. 安装并配置 OpenShift 4 集群。我们的示例使用 CodeReady Containers (CRD) 来实现此目的,可以找到其安装说明 这里.
  2. 集群准备就绪后,您需要在其上安装Pipeline Operator。 别害怕,很简单,安装说明 这里.
  3. 下载 Tekton CLI (tkn) 这里.
  4. 运行 create-react-app 命令行工具来创建一个应用程序,然后部署该应用程序(这是一个简单的应用程序 应对).
  5. (可选)克隆存储库以使用 npm install 和 npm start 在本地运行示例应用程序。

应用程序存储库还将有一个 k8s 文件夹,其中包含用于部署应用程序的 Kubernetes/OpenShift YAML。 我们将在此创建任务、集群任务、资源和管道 储存库.

让我们开始吧

我们示例的第一步是在 OpenShift 集群中创建一个新项目。 我们将此项目命名为 webapp-pipeline 并使用以下命令创建它:

$ oc new-project webapp-pipeline

该项目名称稍后将出现在代码中,因此,如果您决定将其命名为其他名称,请不要忘记相应地编辑示例代码。 从这一点开始,我们不会自上而下,而是自下而上:也就是说,我们将首先创建传送带的所有组件,然后才创建传送带本身。

所以,首先...

任务

让我们创建几个任务,这将有助于在我们的管道中部署应用程序。 第一个任务 - apply_manifests_task - 负责应用位于我们应用程序的 k8s 文件夹中的 Kubernetes 资源(服务、部署和路由)的 YAML。 第二个任务 – update_deployment_task – 负责将已部署的映像更新为我们的管道创建的映像。

如果还不是很清楚,请不要担心。 事实上,这些任务类似于实用程序,稍后我们将更详细地讨论它们。 现在,让我们创建它们:

$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/tasks/update_deployment_task.yaml
$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/tasks/apply_manifests_task.yaml

然后,使用 tkn CLI 命令,我们将检查任务是否已创建:

$ tkn task ls

NAME                AGE
apply-manifests     1 minute ago
update-deployment   1 minute ago

注意:这些是您当前项目的本地任务。

集群任务

集群任务与简单任务基本相同。 也就是说,它是运行特定任务时以某种方式组合的可重用步骤集合。 不同之处在于,集群任务在集群内的任何地方都可用。 要查看添加 Pipeline Operator 时自动创建的集群任务列表,我们将再次使用 tkn CLI 命令:

$ tkn clustertask ls

NAME                       AGE
buildah                    1 day ago
buildah-v0-10-0            1 day ago
jib-maven                  1 day ago
kn                         1 day ago
maven                      1 day ago
openshift-client           1 day ago
openshift-client-v0-10-0   1 day ago
s2i                        1 day ago
s2i-go                     1 day ago
s2i-go-v0-10-0             1 day ago
s2i-java-11                1 day ago
s2i-java-11-v0-10-0        1 day ago
s2i-java-8                 1 day ago
s2i-java-8-v0-10-0         1 day ago
s2i-nodejs                 1 day ago
s2i-nodejs-v0-10-0         1 day ago
s2i-perl                   1 day ago
s2i-perl-v0-10-0           1 day ago
s2i-php                    1 day ago
s2i-php-v0-10-0            1 day ago
s2i-python-3               1 day ago
s2i-python-3-v0-10-0       1 day ago
s2i-ruby                   1 day ago
s2i-ruby-v0-10-0           1 day ago
s2i-v0-10-0                1 day ago

现在让我们创建两个集群任务。 第一个将生成 S2I 映像并将其发送到内部 OpenShift 注册表; 第二个是基于 NGINX 构建我们的镜像,使用我们已经构建的应用程序作为内容。

创建并发送图像

创建第一个任务时,我们将重复我们在上一篇文章中有关链接程序集所做的操作。 回想一下,我们使用 S2I 映像 (ubi8-s2i-web-app) 来“构建”我们的应用程序,并最终将映像存储在 OpenShift 内部注册表中。 现在,我们将使用此 S2I Web 应用程序映像为我们的应用程序创建 DockerFile,然后使用 Buildah 进行实际构建并将生成的映像推送到 OpenShift 内部注册表,因为这正是使用 NodeShift 部署应用程序时 OpenShift 所做的事情。

你问我们怎么知道这一切? 从 官方 Node.js 官方版本,我们只是复制并自己修改一下。

那么,现在让我们创建 s2i-web-app 集群任务:

$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/clustertasks/s2i-web-app-task.yaml

我们不会对此进行详细分析,而仅关注 OUTPUT_DIR 参数:

params:
      - name: OUTPUT_DIR
        description: The location of the build output directory
        default: build

默认情况下,这个参数等于build,这是React放置组装内容的地方。 其他框架使用不同的路径,例如,在 Ember 中是 dist。 我们的第一个集群任务的输出将是一个包含我们收集的 HTML、JavaScript 和 CSS 的图像。

基于NGINX构建镜像

至于我们的第二个集群任务,它应该使用我们已经构建的应用程序的内容为我们构建一个基于 NGINX 的映像。 本质上,这是上一节中我们研究链式构建的部分。

为此,我们(与上面完全相同)将创建一个集群任务 webapp-build-runtime:

$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/clustertasks/webapp-build-runtime-task.yaml

如果您查看这些集群任务的代码,您会发现它没有指定我们正在使用的 Git 存储库或我们正在创建的映像的名称。 我们只指定要传输到 Git 的具体内容,或者最终图像应输出的某个图像。 这就是为什么这些集群任务在与其他应用程序一起工作时可以重用。

在这里,我们优雅地进入下一点......

资源

因此,正如我们刚才所说,集群任务应该尽可能通用,因此我们需要创建用作输入(Git 存储库)和输出(最终图像)的资源。 我们需要的第一个资源是 Git,我们的应用程序驻留在其中,如下所示:

# This resource is the location of the git repo with the web application source
apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
  name: web-application-repo
spec:
  type: git
  params:
    - name: url
      value: https://github.com/nodeshift-starters/react-pipeline-example
    - name: revision
      value: master

这里 PipelineResource 的类型是 git。 params 部分中的 url 键指向特定存储库并指定 master 分支(这是可选的,但我们为了完整性而编写它)。

现在我们需要为图像创建一个资源,用于保存 s2i-web-app 任务的结果,具体操作如下:

# This resource is the result of running "npm run build",  the resulting built files will be located in /opt/app-root/output
apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
  name: built-web-application-image
spec:
  type: image
  params:
    - name: url
      value: image-registry.openshift-image-registry.svc:5000/webapp-pipeline/built-web-application:latest

这里 PipelineResource 是 image 类型,url 参数的值指向内部 OpenShift Image Registry,特别是位于 webapp-pipeline 命名空间中的那个。 如果您使用不同的命名空间,请不要忘记更改此设置。

最后,我们需要的最后一个资源也将是 image 类型,这将是部署期间使用的最终 NGINX 映像:

# This resource is the image that will be just the static html, css, js files being run with nginx
apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
  name: runtime-web-application-image
spec:
  type: image
  params:
    - name: url
      value: image-registry.openshift-image-registry.svc:5000/webapp-pipeline/runtime-web-application:latest

再次请注意,此资源将图像存储在 webapp-pipeline 命名空间的内部 OpenShift 注册表中。

要一次创建所有这些资源,我们使用 create 命令:

$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/resources/resource.yaml

您可以确保资源已按如下方式创建:

$ tkn resource ls

输送管道

现在我们已经拥有了所有必要的组件,让我们通过使用以下命令创建管道来组装管道:

$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/pipelines/build-and-deploy-react.yaml

但在运行此命令之前,让我们先看一下这些组件。 首先是名字:

apiVersion: tekton.dev/v1alpha1
kind: Pipeline
metadata:
  name: build-and-deploy-react

然后在规范部分,我们看到我们之前创建的资源的指示:

spec:
  resources:
    - name: web-application-repo
      type: git
    - name: built-web-application-image
      type: image
    - name: runtime-web-application-image
      type: image

然后我们创建管道需要完成的任务。 首先,它必须执行我们已经创建的 s2i-web-app 任务:

tasks:
    - name: build-web-application
      taskRef:
        name: s2i-web-app
        kind: ClusterTask

此任务采用输入(gir 资源)和输出(内置 Web 应用程序图像资源)参数。 我们还向它传递了一个特殊参数,以便它不会验证 TLS,因为我们使用的是自签名证书:

resources:
        inputs:
          - name: source
            resource: web-application-repo
        outputs:
          - name: image
            resource: built-web-application-image
      params:
        - name: TLSVERIFY
          value: "false"

接下来的任务几乎是一样的,只是这里调用了我们已经创建的 webapp-build-runtime 集群任务:

name: build-runtime-image
    taskRef:
      name: webapp-build-runtime
      kind: ClusterTask

与上一个任务一样,我们传入一个资源,但现在它是built-web-application-image(上一个任务的输出)。 作为输出,我们再次设置图像。 由于此任务必须在前一个任务之后执行,因此我们添加 runAfter 字段:

resources:
        inputs:
          - name: image
            resource: built-web-application-image
        outputs:
          - name: image
            resource: runtime-web-application-image
        params:
        - name: TLSVERIFY
          value: "false"
      runAfter:
        - build-web-application

接下来的两个任务负责使用位于 Web 应用程序的 k8s 目录中的服务、路由和部署 YAML 文件,并在创建新映像时更新此部署。 我们在文章开头定义了这两个集群任务。

启动输送机

因此,管道的所有部分都已创建,我们将使用以下命令运行它:

$ tkn pipeline start build-and-deploy-react

在此阶段,命令行以交互方式使用,您需要选择适当的资源来响应其每个请求:对于 git 资源,选择 web-application-repo,然后对于第一个图像资源,选择built-web-application -image,最后是第二个图像资源 –runtime-web-application-image:

? Choose the git resource to use for web-application-repo: web-application-repo (https://github.com/nodeshift-starters/react-pipeline-example)
? Choose the image resource to use for built-web-application-image: built-web-application-image (image-registry.openshift-image-registry.svc:5000/webapp-pipeline/built-web-
application:latest)
? Choose the image resource to use for runtime-web-application-image: runtime-web-application-image (image-registry.openshift-image-registry.svc:5000/webapp-pipeline/runtim
e-web-application:latest)
Pipelinerun started: build-and-deploy-react-run-4xwsr

现在让我们使用以下命令检查管道的状态:

$ tkn pipeline logs -f

管道启动并部署应用程序后,我们可以使用以下命令请求已发布的路由:

$ oc get route react-pipeline-example --template='http://{{.spec.host}}'

为了获得更好的可视化效果,您可以在 Web 控制台的开发人员模式下查看我们的管道部分 管道,如图所示1.

OpenShift 上的现代应用程序,第 3 部分:OpenShift 作为开发环境和 OpenShift Pipelines

图。1。 审查正在运行的管道。

单击正在运行的管道会显示更多详细信息,如图 2 所示。

OpenShift 上的现代应用程序,第 3 部分:OpenShift 作为开发环境和 OpenShift Pipelines

米。 2. 有关管道的附加信息。

更多信息后,您可以在视图中看到正在运行的应用程序 拓扑,如图3所示。

OpenShift 上的现代应用程序,第 3 部分:OpenShift 作为开发环境和 OpenShift Pipelines

图 3. 启动的 Pod。

单击图标右上角的圆圈将打开我们的应用程序,如图 4 所示。

OpenShift 上的现代应用程序,第 3 部分:OpenShift 作为开发环境和 OpenShift Pipelines

米。 4. 运行 React 应用程序。

结论

因此,我们展示了如何在 OpenShift 上为您的应用程序运行开发服务器并将其与本地文件系统同步。 我们还研究了如何使用 OpenShift Pipelines 模拟链式构建模板。 本文中的所有示例代码都可以找到 这里.

其他资源(EN)

即将举行的网络研讨会的公告

我们将在周五举办一系列有关使用红帽 OpenShift 容器平台和 Kubernetes 的本机体验的网络研讨会:

来源: habr.com

添加评论