基於Github Actions + Docker + Git 的DevOps方案實踐教程

bleso發表於2021-12-13

為什麼需要DevOps

dveops的概念提出已經近十年,各種devops的實踐方案已經陸續在各個開發團隊應用,通過版本控制工具(Git、SVN) + 原始碼倉庫(Gitee、Github) +CI/CD平臺(Jenkins、Github actions、Travis CI...)的DevOps方案使得開發人員的開發體驗得到極大的提升,即減少了開發和運營的成本又提高了產品質量...

由於個人閱歷不足無法繼續詳細闡述DevOps的優勢和作用,所以我推薦了一篇blog

devops基礎理念梳理

如何實踐DevOps

廢話說那麼多,不如實踐一下見好壞,以Jenkins、Github actions、Travis CI等等CI/CD平臺為中心都可以很好的做到持續整合持續部署,在碼雲原始碼倉庫中我們可以看到如下流行的devops方案

image-20211213123551508

以及在Github中整合的Actions

image-20211213123709387

所以我們真正搭建這樣一個流水線平臺到底需要使用什麼技術,掌握什麼工具?

我總結如下:

  1. 掌握流行的版本控制工具(Git,SVN)基本使用方法
  2. 依託一個原始碼倉庫(Github、Gitee)
  3. 基本的linux運維技術(SSH遠端、Docker)
  4. 一個CI/CD平臺(Jenkins、Github Actions、Travis CI...)

就這麼多,不需要掌握任何程式設計技巧!

以上每一個技術精通都是不容易的,但是我們只需要任選其一掌握基本方法,能串起來就行。

我根據自己的技術棧設計了這樣一個DevOps的方案

Untitled (1)

為此我們需要按部就班做一些準備工作

版本控制工具(Git)

學習使用

學習使用方法,這裡我推薦廖雪峰的Git學習網站阮一峰-Git命令清單阮一峰-Git原理

配置環境

  1. 安裝軟體git官網

  2. 檢驗安裝

    git --version
    

    image-20211213131225874

  3. 配置本地使用者資訊

    git config --global user.name "Name"
    git config --global user.email "**.com"
    git config --list
    

    image-20211213131544008

    image-20211213131726959

原始碼倉庫

這裡我就不贅述了,太簡單了,搜尋引擎找一找,如圖所示,我在github上建了一個這樣的倉庫(空倉庫就行,程式碼可以後加)image-20211213132238551

注意,本教程依託了Github Actions這樣一個平臺,必需使用Github,所以網路問題需要自己解決

我們準備瞭如下圖所示目錄結構的一個基於Asp .NET Core 6 的一個圖書管理系統的專案。然後將原始碼推送到遠端程式碼倉庫如上圖所示。(推送指令就不在詳細描述,掌握了git的基本使用就會明白)

image-20211213161812137

一臺配置好環境的雲伺服器

為此我準備了一臺4g執行記憶體,8M頻寬的騰訊雲伺服器。作業系統為ubuntu

image-20211213162915469

SSH遠端登入

你可以使用雲伺服器控制檯提供的遠端工具,也可以使用xshell之類的遠端控制工具。為了之後的操作能夠儘可能順利進行,你需要會使用一些基本的linux指令,可以看看這個linux快速上手視訊

xshell有免費版,下載安裝後如下新建一個會話

image-20211213164150612

之後按照提示輸入賬戶名和密碼就好

image-20211213163900427

在伺服器上安裝docker

docker技術準備工作

這裡我隨便找了個視訊狂勝-docker詳細教程,大致看一下就能對docker有一個瞭解

一篇部落格為什麼要使用docker

我們知道一個專案要想執行起來是需要執行環境的,為了執行一個java專案我們為伺服器安裝對應版本的Jdk或Jre, 一個.Net應用想要執行起來需要對應版本的.Net FrameWork 或者.Net Core 的SDK,比如我們日常使用的可執行程式qq,weixin等等都是需要執行環境的,只不過windows提前安裝好了各種版本的.Net Framework,使得我們安裝好應用後就能直接使用。又比如在伺服器上安裝相應的資料庫(mysql,sqlserver),管理這些開發環境是相當煩人的,但是當我們使用了docker這樣一個容器化技術後庫,程式碼即環境,可以在任何一臺裝有docker的伺服器上執行,不需要配置任何環境。

安裝docker

菜鳥教程-ubuntu安裝docker

使用docker安裝mysql

有了docker我們安裝mysql將變得easy

docker pull mysql

image-20211213170543918

檢查一下我們拉去下來的docker映象

docker images

image-20211213170707008

執行

docker run -d --name mysql3306 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=******* mysql

檢視一下正在執行的的服務

image-20211213171048914

這樣我們就建立按好了一個伺服器上的資料庫,這樣的資料庫不僅能用於生產環境,用來學習也是不錯的,畢竟在筆記本上裝資料庫會比較佔記憶體。

於是我就能在我的專案中配置資料庫連線字串使用這個資料庫了image-20211213171540367

不管這個專案在哪臺主機上啟動,都是可以成功執行的,畢竟資料庫的Ip, 密碼都是固定的。

選擇合適的CI/CD平臺

如前文所說,我所用的是Github actions,最初我是在Asp .NET Core的官網文件上了解到的這個技術,自從github被微軟收購後,Github actions就一直是微軟推薦CI/CD技術。

Github Actions官網文件

想要真正理解這門技術,最好閱讀一下英文版的文件,在看完“Understanding Github Actions"和”Finding and Customizing actions"這兩欄的介紹後,基本上就可以上手Github Acitions了

image-20211213172251298

推薦一篇blog,看完後你可以對其有個簡單瞭解 阮一峰-github actions入門

在原生程式碼倉庫中配置好dockerfile

在我的專案中實現如下

image-20211213173005228

FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["BMS.csproj", "./"]
RUN dotnet restore "BMS.csproj"
COPY . .
WORKDIR "/src/."
RUN dotnet build "BMS.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "BMS.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "BMS.dll"]

嘗試使用docker在本地打包構建部署

我們使用docker就可以根據這個檔案將專案原始碼按照我們想要的方式打包構建好

這裡我們簡單演示一下,進行該測試需要在本地電腦安裝docker,

切換到有dockerfile的專案目錄下使用

docker build .

image-20211213173429247

image-20211213174130158

image-20211213174331904

這個沒有tag的映象就是我們剛剛構建的

docker run -d --name bmstest -p 8080:80 7ab686d20640

image-20211213174929024

image-20211213175003600

開啟遊覽器檢查一下是否成功執行

image-20211213175139597

成功了!

但是,還不夠方便,雖然我們每次修改完程式碼執行幾個命令就執行好了,別人也可以拿著我們的映象去執行程式,但是執行的命令是固定的,我們能不能在修改完程式碼後就自動讓其打包構建部署,事實證明是可以的,人類也是可以在偷懶中進步的。

使用Github Actions自動化打包構建

image-20211213182007308

我們們在專案目錄workflows下建立自己的workfile

image-20211213182422517

name: .NET

env: 
  IMAGE_NAME:  test

on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2
    - name: Setup .NET
      uses: actions/setup-dotnet@v1
      with:
        dotnet-version: 6.0.x
    - name: Restore dependencies
      run: dotnet restore
    - name: Test
      run: dotnet test --no-build --verbosity normal
    - name: Docker Login
      uses: docker/login-action@v1.10.0
      with:
        username: ${{ secrets.DOCKER_USERNAME }}
        password: ${{ secrets.DOCKERHUB_TOKEN }}
    - name: Build and Push
      uses: docker/build-push-action@v2
      with: 
        tags: horaoen/app:latest 
        push: true
        context: ./BMS
    - name: deploy
      uses: appleboy/ssh-action@master
      with: 
        host: ${{ secrets.HOST }}
        username: ${{ secrets.HOST_USERNAME }}
        key: ${{ secrets.HOST_SSHKEY }}
        script: |
          docker stop bms-container
          docker rm bms-container
          docker rmi horaoen/app:latest
          docker pull horaoen/app:latest
          docker run -d --name bms-container -p 8080:80 horaoen/app

可以看到這裡的yml檔案引用了幾個變數,這些是有關使用者安全的東西不能直接寫在配置檔案中,需要在github 的倉庫中設定

image-20211213182841482

新增自己需要的金鑰

image-20211213182952946

image-20211213182911695

workfile詳解

關於上面這個dotnet.yml的Github Actions的配置檔案怎麼寫的需要先了解Github Actions的基本原理

然後掌握一下幾個Actions的使用

其實這些actions使用者下專案,基本格式是users/repository,是一些別人寫好的指令碼,通過重複利用別人寫好的指令碼,我們可以很方便的做許多事

actions/checkout@v2

這個是用於將遠端倉庫中的原始碼拉取到workfile自動化構建指令碼執行的伺服器,在我們這裡是github提供的ubutu latest(這在配置檔案中寫的有)

actions/setup-dotnet@v1

這個是用於搭建專案的基本環境

docker/login-action@v1.10.0

docke官方給的antion,用於登入docker以便我們後續上傳docker映象到自己的映象倉庫

docker/build-push-action@v2

構建docker映象,推送到自己的docker映象倉庫,這個context引數是比較難理解的,實際上是相對以遠端程式碼倉庫的根路徑的Dockerfile的路徑image-20211213184619882

在這個aciton的官網文件中介紹到,Dockerfile的檔案路徑預設在context/Dockerfile 下,所以這個配置很重要不能配錯。

appleboy/ssh-action@master

在我們成功將docker映象推送到映象倉庫後,需要ssh連線我們自己要部署專案的伺服器,然後在其上執行一系列docker commond去部署專案。

其它引數一目瞭然,唯獨這個稍微麻煩,它是我們將要連線到的伺服器的ssh私鑰,在這個action的官網中給出了教程image-20211213185043823

官網文件

image-20211213185346575

可以照著教程,其實你已經看到這裡就說明具備解決這個問題的能力,詳細步驟可以查一下部落格怎麼配置ssh金鑰。需要注意的是複製儘量用指令去複製,錯一個字元都不行

私鑰一定要把上下分割線也複製上,巨坑!!!

image-20211213185848449

image-20211213185905667

演示效果

image-20211213190350169

image-20211213190411877

image-20211213190549952

檢視專案

image-20211213190823418

我們發現有亂碼,這裡正好模擬實際專案中的bug,現在我們修改程式碼修復bug

實際上改一下encoding就好了,然後重新提交程式碼

image-20211213191453683

image-20211213192103688

成功了!!

心得

顯然從結果來看,這很方便,但是學習技術的過程是很痛苦的,如果把學習過程放到比較條件中去是不公平的,學習一次收益很久,但是不做改變就會一直麻煩。

評論區可以留言,我會盡力解答。

相關文章