kubernetes+Azure DevOps實現.Net Core項目的自動化部署&均衡負載


1. 前言

前前后后學習kubernetes也有一個來月了,關於kubernetes的博客也寫了有十多篇。但是技術如果無法落地到實際的應用場景終歸是紙上談兵,所以就有了這一出:通過結合kubernetesazure devops實現項目的CI/CD以及均衡負載

寫完這篇后kubernetes的相關學習也暫時告一段落了,有種終於闖關成功了啊的感覺,當然這是題外話了。

注1以下只是以Net Core項目為例,實際運用場景中,除了dockfile的編寫有差別,剩下整個自動化部署鏈條中的技術也好,工具也好,都可以復用,與語言和語言框架本身無關。
注2本文演示的也只是其中一種簡便的方式,具體的自動化流程中,由於自由度非常高,所以實際的流程可能會更加復雜,這里就不做贅述了

以下場景需要用到的工具或者技術:

  • .Net Core

部署的應用本身

作為代碼倉庫

  • kubernetes
    • docker
    • helm【kubernetes的包管理工具】
    • ingress【使用ingress綁定域名和https證書,實現域名訪問】
  • Azure DevOps

作為CI/CD的工具

:以下所有的相關部署代碼,都在下面這個倉庫

  • 倉庫內容只是我自己用的一個小工具,當然具體是什么內容不重要,這篇只是演示部署相關的
  • 整個演示的demo已經遷移至csharp-archived分支

https://github.com/lzw5399/toc-generator/tree/csharp-archived


2. Net Core項目本身的准備

2.1 dockerfile

你需要一個dockerfile來構建一個docker image, 如果是.Net Core項目,vs提供了傻瓜式生成dockerfile的功能,可以免去初學時編寫dockerfile的煩惱

  • 本示例dockerfile路徑和內容

2.2 創建kubernetes用於helm的chart包

2.2.1 說明

這一部分需要有helm相關的知識,說白了就是將你的如果熟悉k8s但不熟悉helm,可以參照:

kubernetes系列(十六) - Helm安裝和入門

2.2.2 chart文件目錄和文件組成

自定義的chart包,位於以下路徑

https://github.com/lzw5399/TocGenerator/tree/master/kubernetes

如上圖可以看出是一個很經典的自定義chart包的文件目錄,即:

.
├── Chart.yaml           【chart的name和version等信息】
├── templates            【k8s的資源清單模板,可以引用values.yaml的變量】
|   ├── deployment.yaml
|   └── service.yaml
├── values.yaml          【定義變量,供template/下的yaml使用,實現動態替換yaml內容】

3. Azure Devops創建倉庫的pipeline

3.1 前言

Azure DevOps是微軟出品的DevOps平台,里面包含了Pipelines工具鏈,對個人免費,可以用於項目的CI/CD

https://dev.azure.com

3.2 使用azure devops准備操作

  • 如果之前使用過azure devops,這幾步可以視情況跳過。
  1. 進入azure devops注冊賬號
  2. 之后按照引導新建一個organization
  3. 再新建一個project
  4. 進入project

3.3 創建service connections

這里要創建一個service connections,用於之后pipeline訪問k8s的master服務器

  1. 點擊peject setting
  2. 這里點擊service connections來創建一個連接,用於訪問k8s的master服務器
  3. 然后填寫具體的憑證,之后的pipeline上需要

3.4 新建pipeline流水線

新建pipeline流水線用於自定義部署流程

  1. 點擊pipelines,然后點擊create pipelines,新建一條流水線來部署我們的應用
  2. 選擇代碼倉庫位置,選github
  3. 然后會跳到github進行授權,授權完成后會顯示github的repo列表,選擇具體的倉庫
  4. 選擇完倉庫后,會自動按照你當前項目的語言,在github倉庫的根目錄生成一個默認的azure-pipelines.yml文件,
  5. 替換文件的內容,我們最終使用的yaml文件步驟大概如下
    • 第一步:構建docker鏡像
    • 第二步:將自定義的chart包拷貝到master服務器上
    • 第三步:執行deploy.sh腳本,完成部署
# 哪條分支會觸發構建
trigger:
- master

resources:
- repo: self

# 定義變量
variables:
- name: appName
  value: tocgenerator

- name: tag
  value: $(Build.BuildNumber)

- name: imageNameWithoutTag
  value: $(dockerid)/$(appName)

- name: imageNameWithTag
  value: $(imageNameWithoutTag):$(tag)

- name: serverChartLocation
  value: /root/helm-chart-folder/toc

stages:
- stage: Build
  jobs:  
  - job: Build
    pool:
      vmImage: 'ubuntu-latest'
  
    # 這下面是每個我們要具體執行的任務
    steps:
    # build docker images並且push到倉庫
    - task: Docker@2
      displayName: docker build and push
      inputs:
        containerRegistry: 'my_docker_hub'
        repository: '$(imageNameWithoutTag)'
        command: 'buildAndPush'
        Dockerfile: '**/Dockerfile'
        buildContext: '.'
        tags: $(tag)
        addPipelineData: false

    # 將kubernetes文件夾,即chart包拷貝到k8s的master服務器
    - task: CopyFilesOverSSH@0
      displayName: copy helm chart to server
      inputs:
        # 這個endpoint就是我們剛剛創建的service connection的名字
        sshEndpoint: 'my_server'
        sourceFolder: 'kubernetes'
        contents: '**'
        targetFolder: $(serverChartLocation)
        readyTimeout: '20000'
  
    # 在k8s的master服務器上運行我們github倉庫的根目錄的deploy.sh,進行部署操作
    - task: SSH@0
      displayName: run deploy shell on server
      inputs:
        # 這個endpoint就是我們剛剛創建的service connection的名字
        sshEndpoint: 'my_server'
        runOptions: 'script'
        scriptPath: 'deploy.sh'
        args: '$(tag) $(serverChartLocation)'
        readyTimeout: '20000'

3.5 創建部署shell腳本

部署腳本的位置

https://github.com/lzw5399/TocGenerator/blob/master/deploy.sh

幾點說明

  1. echo純粹是為了記錄log使用的,下面的示例把echo部分刪除了
  2. $1 and $2 代表外部傳入的參數
  3. $1是image的tag,$2是k8s的master服務器上我們自定義的chart的目錄
  4. 移除沒有tag的懸掛docker image,純粹為了節省服務器空間,為可選項
#!/bin/bash

# 出現錯誤退出腳本執行
set -o errexit

# $1 and $2 代表外部傳入的參數
# $1是image的tag,$2是k8s的master服務器上我們自定義的chart的目錄
buildNumber=$1
serverChartLocation=$2
cd $serverChartLocation

# 安裝或者升級我們的helm release
# 即如果查詢到了有release存在就upgrade,沒有則install
if test -z "$(helm ls | grep toc-release)"; then
  helm install -f values.yaml --set env.buildnumber=$buildNumber --set image.tag=$buildNumber toc-release .
else
  helm upgrade -f values.yaml --set env.buildnumber=$buildNumber --set image.tag=$buildNumber toc-release .
fi

# 移除沒有tag的懸掛docker image(可選)
danglings=$(sudo docker images -f "dangling=true" -q)
if test -n "$danglings"; then
  sudo docker rmi $(sudo docker images -f "dangling=true" -q) >>/dev/null 2>&1
  if [[ $? != 0 ]]; then
    exit $?
  fi
fi

exit 0

4. 觸發pipeline部署流水線

這里有兩種辦法,

  1. 點擊我們剛剛創建的pipeline手動run一個
  2. 通過push代碼到倉庫的指定分支(我們設置的master)觸發構建

顯示構建成功之后就可以查看了!

5. 關於均衡負載

均衡負載是kubernetes自帶的基礎功能之一,這里只是做了一個試驗可以更加直觀地感受到而已

如下

  1. 定義一個靜態的guid
  2. 在/version 路由下輸出guid

則如果有2個實例,且均衡負載成功的話,每次刷新這個界面,會隨機顯示這兩個guid

  • deployment的replicas實例數需要設置2以上

最后均衡負載試驗的地址,也是本次實例項目的線上地址

https://toc.codepie.fun/version

  • 如下,會出現兩個不同的guid


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM