<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          .Net微服務(wù)實(shí)戰(zhàn)之CI/CD

          共 8671字,需瀏覽 18分鐘

           ·

          2020-08-04 12:03

          地基

            在軟件工程不少的思想、概念來源于建筑工程,大家也喜歡把開發(fā)軟件比喻成建房子。那么如果說運(yùn)維是軟件的地基,那么框架就是承重墻。起房子就是先打地基,再建承重墻。地基打得越穩(wěn),房子才能起得更高。也等同于運(yùn)維技術(shù)越扎實(shí),系統(tǒng)才能更加健壯。

            特別在微服務(wù)興起得時(shí)代,運(yùn)維越發(fā)的現(xiàn)得尤為得重要,DevOps也風(fēng)靡全球。只要聊起DevOps與微服務(wù),CI/CD總是不能避免的。CI/CD不一定限制于微服務(wù),我認(rèn)為無論在什么樣風(fēng)格的架構(gòu)和怎么樣組織架構(gòu)的團(tuán)隊(duì),自動化技術(shù)越早使用收效越高。

            我認(rèn)為IT人員更多是腦力大于體力的勞動者,一些重復(fù)的、錯誤率高的、無法對自己有增長的工作應(yīng)該盡早交給自動化技術(shù)處理,節(jié)省了不需要浪費(fèi)的時(shí)間與精力,這樣才能更好的去完成有價(jià)值、有意義的工作。

          部署圖

            以上是我在虛擬機(jī)環(huán)境的部署圖:

            一共三臺服務(wù)器,每臺服務(wù)器都裝了Docker,Server B是docker swarm的Manger角色,A和C是worker。

            在Server B裝了Jenkins、Docker Registry、dotnet sdk,Server A裝了Gitlab,Server C裝了私有Nuget。

            那么工作流程是:

          1. 遷入代碼push到Gitlab

          2. Gitlab觸發(fā)webhook的push觸發(fā)事件并主動通知Jenkins構(gòu)建

          3. Jenkins在Gitlab獲取源碼并通過配置好的規(guī)則與shell腳本進(jìn)行構(gòu)建

            • 如果是工具庫則dotnet push到192.168.88.139:8081的私有Nuget

            • 如果是Web應(yīng)用則通過dockerfile構(gòu)建docker鏡像并push到192.168.88.141:6000的Docker Registry,然后由docker swarm create多節(jié)點(diǎn)

          安裝Docker

          安裝最新版本Docker,并在所有需要使用docker的服務(wù)器節(jié)點(diǎn)根據(jù)以下步驟安裝

          升級yum并安裝基礎(chǔ)組件

          yum upgrade -y

          sudo yum install -y yum-utils device-mapper-persistent-data lvm2

          添加安裝源信息

          yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

          安裝docker-ce

          yum makecache fast
          yum install docker-ce -y

          ?

          修改鏡像源

          vim /etc/docker/daemon.json

          {
          "registry-mirrors" : [
          "http://ovfftd6p.mirror.aliyuncs.com",
          "http://registry.docker-cn.com",
          "http://docker.mirrors.ustc.edu.cn",
          "http://hub-mirror.c.163.com"
          ],
          "insecure-registries" : [
          "registry.docker-cn.com",
          "docker.mirrors.ustc.edu.cn"
          ],
          "debug" : true,
          "experimental" : true
          }

          啟動docker

          systemctl daemon-reload
          systemctl enable docker
          systemctl start docker

          安裝 Docker Registry(私有倉儲)

          選取一個(gè)服務(wù)器-Server B使用docker安裝Registry

          docker run -d -p 6000:5000 -v /root/docker_registry:/var/lib/registry --name private_registry registry

          開放6000端口

          firewall-cmd --permanent --add-port=6000/tcp
          firewall
          -cmd --reload

          以上就Registry安裝完成了,但為了正常使用還需要做點(diǎn)配置修改

          編輯所有需要docker registry使用的節(jié)點(diǎn)的daemon.json文件,確保能正常訪問

          vim /etc/docker/daemon.json

          {
          "insecure-registries":["192.168.88.141:6000"]
          }

          重啟docker

          systemctl daemon-reload
          service docker restart

          如果需要推送鏡像到私庫確保標(biāo)簽(tag)前綴帶有私庫地址

          docker push?192.168.88.141:6000/testdockerswarm

          docker swarm的初始化

          把相關(guān)涉及到docker swarm的節(jié)點(diǎn)端口開啟

          firewall-cmd --permanent --zone=public --add-port=2377/tcp
          firewall
          -cmd --permanent --zone=public --add-port=4789/udp
          firewall
          -cmd --permanent --zone=public --add-port=7946/udp
          firewall
          -cmd --reload

          選取Server B作為Manager節(jié)點(diǎn),執(zhí)行下面的指令后會出現(xiàn)docker swarm join的指令文本,復(fù)制保存下來

          docker swarm init --advertise-addr 192.168.88.141

          Server A和Server C為Worker節(jié)點(diǎn),執(zhí)行剛剛保存下來指令

          docker swarm join --token SWMTKN-1-0odogegq3bwui4o76aq5v05doqqvuycb5jmuckjmvzy4bfmm59-ewht2cz6fo0r39ky44uv00aq5 192.168.88.141:2377

          查看節(jié)點(diǎn)信息

          docker node ls

          私有Nuget的安裝

          選擇Server C基于docker的Nuget安裝

          docker run -d \
          -p 8081:80 \
          --env NUGET_API_KEY=chengong \
          -v /root/nuget/database:/var/www/db \
          -v /root/nuget/packages:/var/www/packagefiles \
          --name nuget-server \
          sunside
          /simple-nuget-server

          開放相關(guān)8081端口

          firewall-cmd --permanent --add-port=8081/tcp
          firewall
          -cmd --reload

          上傳包指令,注意包名有中文會導(dǎo)致上傳出現(xiàn)bad request

          dotnet nuget push --source http://192.168.88.139:8081/ -k chengong TestPackage.1.0.0.nupkg

          刪除包指令

          dotnet nuget delete --source http://192.168.88.139:8081/ -k chengong  TestPackage 1.0.0

          如果在Windowsx系統(tǒng)可以通過工具上傳

          https://github.com/NuGetPackageExplorer/NuGetPackageExplorer

          Gitlab的安裝

          在Server A服務(wù)器上基于docker安裝

          sudo docker run -d \
          --hostname 192.168.88.138 \
          -p 443:443 -p 8080:80 -p 2222:22 \
          --name gitlab \
          --restart always \
          -v /root/gitlab/config:/etc/gitlab:Z \
          -v /root/gitlab/logs:/var/log/gitlab:Z \
          -v /root/gitlab/data:/var/opt/gitlab:Z \
          gitlab
          /gitlab-ce

          開放端口

          firewall-cmd --permanent --add-port=8080/tcp
          firewall
          -cmd --reload

          第一次啟動會有點(diǎn)慢,需要耐心的等待一下(幾分鐘),初始化完了后進(jìn)入系統(tǒng)設(shè)置root的密碼,登錄進(jìn)去我們創(chuàng)建兩個(gè)項(xiàng)目,一個(gè)Web應(yīng)用,一個(gè)工具庫,等會需要用到

          Jenkins的安裝

          在Server B服務(wù)器基于docker安裝Jenkins

          mkdir -p /root/jenkins
          setenforce
          0
          docker run --name jenkins -u 0 -d  --restart always -v /root/jenkins/jenkins_home:/var/jenkins_home -p 8080:8080 -p 50000:50000 jenkins/jenkins:lts

          開放端口

          firewall-cmd --permanent --add-port=8080/tcp
          firewall
          -cmd --reload

          啟動完了后需要等待一會,我們先去查看Jenkins的docker log,我們找到下面那段密碼,在Jenkins歡迎頁輸入,設(shè)置好管理員后,選擇Custom Select,如果您對網(wǎng)絡(luò)有自信就直接點(diǎn)繼續(xù),如果您對網(wǎng)絡(luò)沒自信,避免花了很長的時(shí)間還沒安裝好插件就直接啥都不選繼續(xù)。(如果出現(xiàn)一個(gè)XXX失敗代理的頁面直接跳過)

          docer logs xxx
          Please use the following password to proceed to installation:
          53d4a2880bf8460c8ff61936278855ca

          插件自動下載完后了,終于進(jìn)去了,如果有沒有安裝成功的都得保證以下三個(gè)插件安裝好,Gitlab Hook 、Gitlab、Push Over SSH.

          登錄后,在左側(cè)點(diǎn)擊【系統(tǒng)管理】,拖下去點(diǎn)擊 【插件管理】,確保Gitlab Hook 、Gitlab、Push Over SSH成功安裝,如果無法順利安裝則到https://plugins.jenkins.io/下載插件手動上傳。

          ?

          修改時(shí)區(qū),進(jìn)入Jenkins容器

          docker exec -it 81 /bin/bash

          執(zhí)行下面命令

          tzselect

          4
          9
          1
          1

          cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

          ##查看時(shí)間
          date -R

          在Server B安裝.Net SDK,因?yàn)樵赟erver B安裝了Jenkins,因此會基于Server B的環(huán)境進(jìn)行.Net的應(yīng)用進(jìn)行打包、發(fā)布

          添加下載源:

          rpm -Uvh https://packages.microsoft.com/config/centos/7/packages-microsoft-prod.rpm

          下載安裝:

          sudo yum install dotnet-sdk-3.1

          ?在Server B添加私有Nuget包源,因?yàn)樵?Net Core應(yīng)用 Build和Publish的時(shí)候會觸發(fā)Restore指令(還原包),默認(rèn)只有微軟的nuget源,如果缺少了私有Nuget源會還原包失敗

          dotnet nuget add source http://192.168.88.139:8081 -n LocalNugetServer

          列出已有包源

          dotnet nuget list source

          當(dāng)然可以通過 dotnet restore -s http://192.168.88.139:8081 指令指定還原包源,但是為了避免如果服務(wù)地址變動后shell腳本會大面積的修改,還是建議通過dotnet nuget add soure指令。

          ?

          那么到這里所有的關(guān)于Linux的工具安裝、初始化的準(zhǔn)備工作都完成了,那么接下來就是講解Jenkins結(jié)合Gitlab,把應(yīng)用與工具包發(fā)布到Nuget與Docker。

          Jenkins的使用

          在一切開始之前得把SSH配置好,因?yàn)楹罄m(xù)會使用到,在【SSH Servers】模塊把服務(wù)器地址、賬號密碼填進(jìn)去保存。

          返回到首頁面板點(diǎn)擊【新建任務(wù)】-選擇【構(gòu)建一個(gè)自由風(fēng)格的軟件項(xiàng)目】(FreeStyle Project)。

          自由風(fēng)格的項(xiàng)目更多是使用shell腳本結(jié)合相應(yīng)平臺的指令實(shí)現(xiàn)自動化,因此建議大家對shell腳本有個(gè)初步的認(rèn)識與學(xué)習(xí),雖然Jenkins也提供了對應(yīng)平臺語言的一些插件,但是只要您熟悉了shell就會發(fā)現(xiàn)它的靈活性與便捷性。

          接下來我們只要關(guān)注3個(gè)模塊,源碼管理、構(gòu)建觸發(fā)器、構(gòu)建

          源碼構(gòu)建,填寫您要自動發(fā)布的項(xiàng)目的源碼地址,并輸入賬號密碼。

          構(gòu)建觸發(fā)器,這里勾選Build when a chenge ……,把URL 復(fù)制記錄下來,等下在Gitlab需要使用到。這里就是與Gitlab webhook做了聯(lián)動,可以理解成Jenkins開放了一個(gè)接口,讓Gitlab被push代碼后會主動告訴Jenkins做一次自動化構(gòu)建。

          構(gòu)建,這里其實(shí)就是執(zhí)行shell腳本完成發(fā)布。這里得注意下我是用ssh,因?yàn)槲业腏enkins是使用了docker安裝的,如果我使用了【構(gòu)建】模塊里的【執(zhí)行shell】就會在Jenkins環(huán)境里進(jìn)行編譯、打包,同時(shí)也需要安裝相應(yīng)的環(huán)境 例如dotnet sdk等。值得注意的是,我的環(huán)境與Jenkins掛載的都是在了Server B這個(gè)宿主環(huán)境,因此通過Jenkins的SSH Publishers連到Jenkins的宿主服務(wù)器(Server B),執(zhí)行相應(yīng)的shell腳本從Jenkins掛載的目錄進(jìn)行構(gòu)建鏡像。

          當(dāng)然有同學(xué)想在Jenkins環(huán)境先打包然后通過SSH的Transfers模塊進(jìn)行文件傳也是可以的。?

          構(gòu)建腳本

          這個(gè)是工具庫發(fā)布到私有Nuget的腳本

          #腳本開始執(zhí)行
          echo '腳本開始執(zhí)行'

          base_path
          =/root/jenkins/jenkins_home/workspace/TestNuget
          nuget_url
          =http://192.168.88.139:8081/
          nuget_api_key=chengong

          project_path
          =$base_path/TestNuget
          package_path
          =$project_path/bin/Debug
          cd $project_path

          rm -rf $package_path/*.nupkg

          dotnet pack $project_path &&
          dotnet nuget push --source $nuget_url -k $nuget_api_key $package_path/*.nupkg >/dev/null

          if [ $? -eq 0 ]; then
          echo '發(fā)布成功:'$project_path''
          else
          echo '發(fā)布失敗:'$project_path''
          fi

          echo '腳本執(zhí)行結(jié)束'

          下面這個(gè)是Web應(yīng)用發(fā)布到單臺服務(wù)器的腳本

          #!/bin/bash
          echo '腳本開始執(zhí)行'

          base_path
          =/root/jenkins/jenkins_home/workspace/TestDockerSwarm

          project_name
          =testdockerswarm
          project_path
          =$base_path/TestDockerSwarm
          publish_path
          =$project_path/bin/Release/netcoreapp2.2/publish

          cd $project_path
          rm -rf $project_path/bin

          dotnet publish
          -c Release && (
          cd $publish_path
          &&
          docker stop $project_name
          docker
          rm $project_name
          docker image
          rm $project_name
          docker build
          -t $project_name . &&
          docker run
          -d -p 5000:80 -e ASPNETCORE_ENVIRONMENT="Development" --name $project_name $project_name &&
          echo '發(fā)布成功:'$project_path'' ||
          echo '發(fā)布失敗:'$project_path''
          )
          || echo '發(fā)布失敗:'$project_path''

          echo '腳本執(zhí)行結(jié)束'

          下面這個(gè)是通過Docker Swarm把Web應(yīng)用發(fā)布到多臺服務(wù)器

          #!/bin/bash
          echo '腳本開始執(zhí)行'

          base_path
          =/root/jenkins/jenkins_home/workspace/TestDockerSwarm

          project_name
          =testdockerswarm
          project_path
          =$base_path/TestDockerSwarm
          publish_path
          =$project_path/bin/Release/netcoreapp2.2/publish
          private_registry_url
          =192.168.88.141:6000
          version
          =`date "+%Y%m%d%H%M%S"`

          cd $project_path
          rm -rf $project_path/bin

          dotnet publish
          -c Release && (
          (
          cd $publish_path
          docker service
          rm testdockerswarm
          docker images
          | grep $private_registry_url/$project_name | awk '{print $3}' | xargs docker rmi
          docker build
          -t $private_registry_url/$project_name:$version ./
          docker push $private_registry_url
          /$project_name:$version
          )
          &&
          docker service create
          -d -p 5000:80 --replicas 2 -e ASPNETCORE_ENVIRONMENT="Development" --constraint=" node.role==worker" --name $project_name $private_registry_url/$project_name:$version &&
          echo '發(fā)布成功:'$project_path'' ||
          echo '發(fā)布失敗:'$project_path''
          )
          || echo '發(fā)布失敗:'$project_path''

          echo '腳本執(zhí)行結(jié)束'

          上面腳本有一處地址得注意下我指定了--constraint=" node.role==worker"?也就是woker節(jié)點(diǎn)才會部署應(yīng)用,因?yàn)槲叶x了ServerA和C是Web服務(wù)器。當(dāng)然各位可以按照自己的需要處理。

          Dockerfile

          FROM microsoft/dotnet:2.2-aspnetcore-runtime AS base
          WORKDIR
          /app
          EXPOSE
          80

          FROM base AS final
          WORKDIR
          /app
          COPY .
          / /app
          ENTRYPOINT [
          "dotnet", "TestDockerSwarm.dll"]

          Gitlab的使用

          進(jìn)入Gitlab,點(diǎn)擊【Admin Area】-【Network】,勾選選項(xiàng)后保存

          進(jìn)入一個(gè)Project,點(diǎn)擊【Setting】-【W(wǎng)ebhooks】,把剛剛在Jenkins的復(fù)制下來的Url填寫進(jìn)去,勾選相應(yīng)的觸發(fā)事件后保存。

          結(jié)束

          ?  以上就是本篇的內(nèi)容了,完成了部署后,可以在Jenkins點(diǎn)擊【立刻構(gòu)建】和在Gitlab遷入一次代碼查看運(yùn)行效果。Shell腳本作為一個(gè)demo,如果對腳本有更好的建議和優(yōu)化的寫法可以在評論區(qū)反饋給我。

          瀏覽 51
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  久久黄色樱桃视频 | 快C我啊用力嗯91影视 | 熟女人妻人妻の视频 | 无码一区二区激情 | 超碰天堂 |