最佳實踐-使用Github Actions來構建跨平臺容器映象

2023-11-15 15:01:53

公眾號「架構成長指南」,專注於生產實踐、雲原生、分散式系統、巨量資料技術分享。

前言

最近在寫K8s的相關係列文章,因為有涉及到映象構建,發現在Mac m1的Arm架構下構建的部分映象,沒法在X86架構下使用,不相容。

嘗試網上介紹的各種方式,都已失敗告終,效果如下:

最終還是GithubActions拯救了我,下面介紹一下Actions用法,希望對你有幫助。

概述

GitHub Actions 是一種持續整合和持續交付 (CI/CD) 平臺,可用於自動執行生成、測試和部署管道。 您可以建立工作流程來構建和測試儲存庫的每個拉取請求,或將合併的拉取請求部署到生產環境。

GitHub Actions 不僅僅是 DevOps,還允許您在儲存庫中發生其他事件時執行工作流程。 例如,您可以執行工作流程,以便在有人在您的儲存庫中建立新問題時自動新增相應的標籤。

GitHub 提供 Linux、Windows 和 macOS 虛擬機器器來執行工作流程,或者您可以在自己的資料中心或雲基礎架構中託管自己的自託管執行器。

以上是GitHub的官方介紹,其實就是有一個類似於Jenkinspipeline,支援手動或者程式碼等方式觸發,支援pipeline執行在 Linux、Windows 和 macOS等虛擬機器器中,下面是一個示意圖

GitHub的pipeline使用yaml進行維護,同時內建了很多現成的元件,拿來即用,下面就以具體的一個範例進行介紹,如何使用

我們將做什麼?

我們會構建一個前端工程的docker映象,並推播此映象至DockerHub倉庫,同時在k8s中拉取並執行驗證

1. 建立一個前端專案

工程已經建立好,地址:https://github.com/dongweizhao/frontend

其中為了方便部署,前端資源都存放在工程的dist目錄

2. 編寫Dockerfile

參照nginx映象,同時拷貝dist目錄下資源值容器的/frontend,同時拷貝nginx.conf覆蓋nginx映象預設的組態檔,以下檔案工程中都已經涵蓋
nginx.conf

server{
    listen 80;
    server_name localhost;
     root  /frontend;
     index index.html index.htm;

     location /login {
             try_files $uri $uri/ /login.html;
     }
}

Dockerfile

from nginx
copy ./dist /frontend
run chown nginx.nginx /frontend -R
copy nginx.conf /etc/nginx/conf.d/default.conf

3. Actions設定

設定DockerHub賬號密碼


點選New repository secret按鈕,建立對應的變數。

例如,我要建立DOCKER_HUB_USERNAME變數,值為root,設定如下:


建立worfkflow檔案
點選Actions

Actions內建了很多模版,拿過來設定下即可,這裡我們用Publish Docker Container,選擇其他也行,最終改成以下下檔案

#workflow名稱
name: ci
# 觸發條件
on:
#github頁面手動觸發
  workflow_dispatch: 
#打tag觸發,必須是v開頭的
  push:
    tags:
      - "v*.*"
#變數設定      
env:
  #映象名稱
  IMAGE_NAME: frontend
  #dockerHub倉庫名稱
  DOCKER_REGISTRY: dweizhao
jobs:
  build-image:
    #執行的環境  
    runs-on: ubuntu-latest
    env:
      TZ: Asia/Shanghai
    outputs:
      tags: ${{ steps.output-id.outputs.v }}
    steps:
      # 拉取程式碼,同時獲取tag,如果獲取不到則預設值為edge,並賦值給v變數
      - uses: actions/checkout@v3
      - id: output-id
        run: |
          VERSION=edge
          if [[ $GITHUB_REF == refs/tags/* ]]; then
            VERSION=${GITHUB_REF#refs/tags/v}
          fi
          echo "v=${VERSION}" >> $GITHUB_OUTPUT
     # Docker設定多平臺環境
      - name: Set up Docker BuildX
        uses: docker/setup-buildx-action@v2          
      # 登入映象倉庫
      - name: Login Docker Hub
        uses: docker/login-action@v1
        with:
        #這裡參照的變數為上一步設定的變數
          username: ${{ secrets.DOCKER_HUB_USERNAME }}
          password: ${{ secrets.DOCKER_HUB_PWD }}     
      # 打包構建並推播
      - name: Build and push
        uses: docker/build-push-action@v4
        with:
          context: .
          file: ./Dockerfile
          platforms: |
            linux/amd64
            linux/arm64
          #推播到映象倉庫  
          push: true
          # 這裡會構建兩個版本映象,
          # 1.dweizhao/backend:latest
          # 2.  output-id步驟中獲取的v,構建dweizhao/backend:edge或者dweizhao/backend:對應tag值
          tags: |
            ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.output-id.outputs.v }}
            ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:latest

以上檔案建立完成,會在工程目錄下建立一個.github的目錄,儲存有我們設定的檔案

同時再次點選Actions按鈕會出現,以下介面

這裡的ci就是設定的workflow的name名稱

4. 映象構建並行布

我們測試兩種方式,分別如下:

手動觸發構建

根據箭頭表示,點選run wofkflow按鈕,執行任務

點選ci可以檢視任務執行詳情,可以看到任務執行步驟以及對應狀態以及相關紀錄檔

以上結果表明,執行成功,檢視dockerhub映象倉庫,可以看到推播已經成功,由於是手動觸發獲取不到tag,所以構建了edgetag的映象

建立tag觸發構建
建立了一個v1.0.0

自動觸發構建

可以映象倉庫在同一時間,構建了latest1.0.0tag映象

5. 容器部署驗證

下面我們在k8s環境中拉取frontent前端映象,驗證是否部署成功。

我們建立了frontenddeployment,同時指定了映象為dweizhao/frontend:latest

可以看到映象啟動成功

結論

如果你用的是mac的m系列晶片,可以嘗試使用Github Actions來構建你的映象,前提是你自己的個人專案,Github Actions功能很強大,如果感興趣可以繼續去研究。