OpenShift 上的現代應用程序,第 2 部分:鍊式構建

大家好! 這是我們系列文章的第二篇文章,我們將展示如何在 Red Hat OpenShift 上部署現代 Web 應用程式。

OpenShift 上的現代應用程序,第 2 部分:鍊式構建

在上一篇文章中,我們稍微介紹了新的 S2I(來源到映像)建構器映像的功能,該映像專為在 OpenShift 平台上建置和部署現代 Web 應用程式而設計。 然後我們對快速部署應用程式的主題感興趣,今天我們將了解如何使用 S2I 映像作為「純」建構器映像並將其與相關 OpenShift 組件結合。

乾淨的建造者形象

正如我們在第 XNUMX 部分中提到的,大多數現代 Web 應用程式都有一個所謂的建置階段,該階段通常執行程式碼轉譯、多檔案串聯和縮小等操作。 這些操作的結果所獲得的檔案 - 這是靜態 HTML、JavaScript 和 CSS - 儲存在輸出資料夾中。 該資料夾的位置通常取決於所使用的建置工具,對於 React,這將是 ./build 資料夾(我們將在下面更詳細地討論這一點)。

來源到影像 (S2I)

在這篇文章中,我們不會涉及“什麼是 S2I 以及如何使用它”這個主題(您可以閱讀有關此的更多信息 這裡),但重要的是要清楚此過程中的兩個步驟,以了解 Web App Builder 映像的作用。

組裝階段

組裝階段本質上與運行 docker build 並最終獲得新的 Docker 映像時發生的情況非常相似。 因此,當在 OpenShift 平台上開始建置時,就會發生此階段。

對於 Web App Builder 映像,它負責安裝應用程式的依賴項並運行建置。 彙編腳本。 預設情況下,建構器映像使用 npm run build 構造,但這可以透過 NPM_BUILD 環境變數覆寫。

正如我們之前所說,已完成的、已建置的應用程式的位置取決於您使用的工具。 例如,對於 React,這將是 ./build 資料夾,對於 Angular 應用程序,這將是 project_name/dist 資料夾。 而且,如上一篇文章所示,預設設定為建置的輸出目錄的位置可以透過 OUTPUT_DIR 環境變數覆蓋。 好吧,由於輸出資料夾的位置因框架而異,您只需將生成的輸出複製到映像中的標準資料夾,即 /opt/apt-root/output。 這對於理解本文的其餘部分很重要,但現在讓我們快速看看下一個階段 - 運行階段。

運行階段

當對組裝階段建立的新映像呼叫 docker run 時,就會發生此階段。 在 OpenShift 平台上部署時也會發生相同的情況。 預設 運行腳本 用途 服務模組 提供位於上述標準輸出目錄中的靜態內容。

此方法適合快速部署應用程序,但通常不建議以這種方式提供靜態內容。 好吧,因為實際上我們只提供靜態內容,所以我們不需要在映像中安裝 Node.js - 一個 Web 伺服器就足夠了。

換句話說,組裝時我們需要一件事,執行時我們需要另一件事。 在這種情況下,鍊式建構就派上用場了。

鍊式建構

這就是他們寫的 鍊式建構 在 OpenShift 文件中:

“兩個程序集可以連結在一起,一個程序集生成已編譯的實體,另一個程序集將該實體託管在用於運行該實體的單獨映像中。”

換句話說,我們可以使用 Web App Builder 映像來運行我們的構建,然後使用 Web 伺服器映像(相同的 NGINX)來提供我們的內容。

因此,我們可以將 Web App Builder 映像用作「純」建構器,同時擁有一個小型執行時間鏡像。

現在讓我們透過一個具體的例子來看一下。

對於訓練,我們將使用 簡單的反應應用程式,使用 create-react-app 命令列工具建立。

它將幫助我們將一切整合在一起 OpenShift 範本文件.

讓我們更詳細地查看該文件,並從參數部分開始。

parameters:
  - name: SOURCE_REPOSITORY_URL
    description: The source URL for the application
    displayName: Source URL
    required: true
  - name: SOURCE_REPOSITORY_REF
    description: The branch name for the application
    displayName: Source Branch
    value: master
    required: true
  - name: SOURCE_REPOSITORY_DIR
    description: The location within the source repo of the application
    displayName: Source Directory
    value: .
    required: true
  - name: OUTPUT_DIR
    description: The location of the compiled static files from your web apps builder
    displayName: Output Directory
    value: build
    required: false

這裡的一切都非常清楚,但值得注意的是 OUTPUT_DIR 參數。 對於我們範例中的 React 應用程序,無需擔心,因為 React 使用預設值作為輸出資料夾,但對於 Angular 或其他應用程序,需要根據需要更改此參數。

現在讓我們來看看 ImageStreams 部分。

- apiVersion: v1
  kind: ImageStream
  metadata:
    name: react-web-app-builder  // 1 
  spec: {}
- apiVersion: v1
  kind: ImageStream
  metadata:
    name: react-web-app-runtime  // 2 
  spec: {}
- apiVersion: v1
  kind: ImageStream
  metadata:
    name: web-app-builder-runtime // 3
  spec:
    tags:
    - name: latest
      from:
        kind: DockerImage
        name: nodeshift/ubi8-s2i-web-app:10.x
- apiVersion: v1
  kind: ImageStream
  metadata:
    name: nginx-image-runtime // 4
  spec:
    tags:
    - name: latest
      from:
        kind: DockerImage
        name: 'centos/nginx-112-centos7:latest'

看一下第三張和第四張圖片。 它們都被定義為 Docker 映像,你可以清楚地看到它們來自哪裡。

第三張圖片是 web-app-builder,它來自 nodeshift/ubi8-s2i-web-app,標記為 10.x 泊塢樞紐.

第四個是帶有最新標籤的 NGINX 映像(版本 1.12) 泊塢樞紐.

現在讓我們來看看前兩張圖片。 它們在開始時都是空的,並且僅在建置階段建立。 第一個圖像,react-web-app-builder,將是一個組裝步驟的結果,該組裝步驟將結合 web-app-builder-runtime 圖像和我們的原始程式碼。 這就是為什麼我們在該鏡像的名稱中添加了“-builder”。

第二個鏡像——react-web-app-runtime——將是結合 nginx-image-runtime 和 React-web-app-builder 映像中的一些檔案的結果。 該映像也將在部署期間使用,並且僅包含我們應用程式的 Web 伺服器和靜態 HTML、JavaScript、CSS。

使困惑? 現在讓我們來看看建置配置,它會變得更清晰一些。

我們的模板有兩種建置配置。 這是第一個,它非常標準:

  apiVersion: v1
  kind: BuildConfig
  metadata:
    name: react-web-app-builder
  spec:
    output:
      to:
        kind: ImageStreamTag
        name: react-web-app-builder:latest // 1
    source:   // 2 
      git:
        uri: ${SOURCE_REPOSITORY_URL}
        ref: ${SOURCE_REPOSITORY_REF}
      contextDir: ${SOURCE_REPOSITORY_DIR}
      type: Git
    strategy:
      sourceStrategy:
        env:
          - name: OUTPUT_DIR // 3 
            value: ${OUTPUT_DIR}
        from:
          kind: ImageStreamTag
          name: web-app-builder-runtime:latest // 4
        incremental: true // 5
      type: Source
    triggers: // 6
    - github:
        secret: ${GITHUB_WEBHOOK_SECRET}
      type: GitHub
    - type: ConfigChange
    - imageChange: {}
      type: ImageChange

如您所看到的,帶有標籤 1 的行表示此建置的結果將放置在我們之前在 ImageStreams 部分中看到的同一個react-web-app-builder 映像中。

標記為 2 的行告訴您從哪裡取得程式碼。 在我們的例子中,這是一個 git 儲存庫,位置、ref 和上下文資料夾由我們上面看到的參數決定。

標記為 3 的行是我們在參數部分中看到的。 它添加了 OUTPUT_DIR 環境變量,在我們的範例中是 build。
標記為 4 的行表示使用 web-app-builder-runtime 映像,我們已經在 ImageStream 部分中看到了該圖像。

標記為 5 的行表示,如果 S2I 映像支援增量構建,並且 Web App Builder 映像也支援增量構建,則我們希望使用增量構建。 首次啟動時,完成組裝階段後,映像會將 node_modules 資料夾儲存到存檔檔案中。 然後,在後續運行中,映像將簡單地解壓縮此資料夾以減少建置時間。

最後,標記為 6 的行只是一些觸發器,使建置在發生變化時自動運行,無需手動幹預。

總的來說,這是一個非常標準的建造配置。

現在讓我們來看看第二個建置配置。 它與第一個非常相似,但有一個重要的區別。

apiVersion: v1
  kind: BuildConfig
  metadata:
    name: react-web-app-runtime
  spec:
    output:
      to:
        kind: ImageStreamTag
        name: react-web-app-runtime:latest // 1
    source: // 2
      type: Image
      images:                              
        - from:
            kind: ImageStreamTag
            name: react-web-app-builder:latest // 3
          paths:
            - sourcePath: /opt/app-root/output/.  // 4
              destinationDir: .  // 5
             
    strategy: // 6
      sourceStrategy:
        from:
          kind: ImageStreamTag
          name: nginx-image-runtime:latest
        incremental: true
      type: Source
    triggers:
    - github:
        secret: ${GITHUB_WEBHOOK_SECRET}
      type: GitHub
    - type: ConfigChange
    - type: ImageChange
      imageChange: {}
    - type: ImageChange
      imageChange:
        from:
          kind: ImageStreamTag
          name: react-web-app-builder:latest // 7

所以第二個建置配置是react-web-app-runtime,它一開始非常標準。

標記為 1 的行並不是什麼新鮮事 - 它只是表示構建結果被放入react-web-app-runtime 圖像中。

與先前的配置一樣,標記為 2 的行指示從何處取得原始程式碼。 但請注意,這裡我們說的是從圖像中獲取的。 此外,從我們剛剛創建的圖像 - 來自react-web-app-builder(如標記為3的行所示)。 我們想要使用的檔案位於圖像內部,其位置在標記為 4 的行中設置,在我們的範例中為 /opt/app-root/output/。 如果您還記得,這是儲存根據建置應用程式結果產生的檔案的位置。

在帶有標籤 5 的術語中指定的目標資料夾只是當前目錄(記住,這就是全部,在名為 OpenShift 的神奇東西中運行,而不是在本機電腦上運行)。

策略部分(標記為 6 的行)也與第一個建置配置類似。 只是這次我們將使用 nginx-image-runtime,我們已經在 ImageStream 部分看到過它。

最後,標記為 7 的行是觸發器的一部分,每次react-web-app-builder 影像發生變化時都會啟動此建置。

否則,此範本包含非常標準的部署配置,以及與服務和路由相關的內容,但我們不會討論太多細節。 請注意,將部署的映像是react-web-app-runtime 映像。

應用程式部署

現在我們已經了解了模板,接下來讓我們看看如何使用它來部署應用程式。

我們可以使用名為 oc 的 OpenShift 用戶端工具來部署我們的模板:

$ find . | grep openshiftio | grep application | xargs -n 1 oc apply -f

$ oc new-app --template react-web-app -p SOURCE_REPOSITORY_URL=https://github.com/lholmquist/react-web-app

上面螢幕截圖中的第一個指令是一種有意的工程方式來尋找範本。/openshiftio/application.yaml。

第二個命令只是基於此模板創建一個新應用程式。

這些命令運行後,我們將看到有兩個組件:

OpenShift 上的現代應用程序,第 2 部分:鍊式構建

返回概覽畫面,我們將看到啟動的 Pod:

OpenShift 上的現代應用程序,第 2 部分:鍊式構建

點擊該鏈接,我們將進入我們的應用程序,這是預設的 React 應用程式頁面:

OpenShift 上的現代應用程序,第 2 部分:鍊式構建

加法1

對於 Angular 愛好者,我們還有 範例應用程式.

除了 OUTPUT_DIR 變數之外,這裡的模式是相同的。

加法2

在本文中,我們使用NGINX作為Web伺服器,但是將其替換為Apache非常容易,只需更改檔案中的範本即可 NGINX 鏡像阿帕契影像.

結論

在本系列的第一部分中,我們展示如何在 OpenShift 平台上快速部署現代 Web 應用程式。 今天,我們研究了 Web 應用程式映像的作用,以及如何使用鍊式建置將其與 NGINX 等純 Web 伺服器結合起來,以創建更適合生產的應用程式建置。 在本系列的下一篇也是最後一篇文章中,我們將展示如何在 OpenShift 上為您的應用程式運行開發伺服器並確保本機和遠端檔案的同步。

本系列文章內容

  • 部分1: 如何透過幾個步驟部署現代 Web 應用程式;
  • 第 2 部分:如何將新的 S2I 映像與現有 HTTP 伺服器映像(例如 NGINX)一起使用,並使用關聯的 OpenShift 組件進行生產部署;
  • 第 3 部分:如何在 OpenShift 平台上為您的應用程式運行開發伺服器並將其與本機檔案系統同步。

其他資源

來源: www.habr.com

添加評論