.Net微服務實戰之技術選型篇html
.Net微服務實戰之DevOps篇linux
相關源碼:https://github.com/SkyChenSky/Sikirogithub
在軟件工程很多的思想、概念來源於建築工程,你們也喜歡把開發軟件比喻成建房子。那麼若是說運維是軟件的地基,那麼框架就是承重牆。起房子就是先打地基,再建承重牆。地基打得越穩,房子才能起得更高。也等同於運維技術越紮實,系統才能更加健壯。web
特別在微服務興起得時代,運維愈加的現得尤其得重要,DevOps也風靡全球。只要聊起DevOps與微服務,CI/CD老是不能避免的。CI/CD不必定限制於微服務,我認爲不管在什麼樣風格的架構和怎麼樣組織架構的團隊,自動化技術越早使用收效越高。docker
我認爲IT人員更可能是腦力大於體力的勞動者,一些重複的、錯誤率高的、沒法對本身有增加的工做應該儘早交給自動化技術處理,節省了不須要浪費的時間與精力,這樣才能更好的去完成有價值、有意義的工做。shell
以上是我在虛擬機環境的部署圖:json
一共三臺服務器,每臺服務器都裝了Docker,Server B是docker swarm的Manger角色,A和C是worker。vim
在Server B裝了Jenkins、Docker Registry、dotnet sdk,Server A裝了Gitlab,Server C裝了私有Nuget。
那麼工做流程是:
安裝最新版本Docker,並在全部須要使用docker的服務器節點根據如下步驟安裝
升級yum並安裝基礎組件
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
選取一個服務器-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安裝完成了,但爲了正常使用還須要作點配置修改
編輯全部須要docker registry使用的節點的daemon.json文件,確保能正常訪問
vim /etc/docker/daemon.json { "insecure-registries":["192.168.88.141:6000"] }
重啓docker
systemctl daemon-reload
service docker restart
若是須要推送鏡像到私庫確保標籤(tag)前綴帶有私庫地址
docker push 192.168.88.141:6000/testdockerswarm
把相關涉及到docker swarm的節點端口開啓
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節點,執行下面的指令後會出現docker swarm join的指令文本,複製保存下來
docker swarm init --advertise-addr 192.168.88.141
Server A和Server C爲Worker節點,執行剛剛保存下來指令
docker swarm join --token SWMTKN-1-0odogegq3bwui4o76aq5v05doqqvuycb5jmuckjmvzy4bfmm59-ewht2cz6fo0r39ky44uv00aq5 192.168.88.141:2377
docker node ls
選擇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
開放相關8081端口
firewall-cmd --permanent --add-port=8081/tcp firewall-cmd --reload
上傳包指令,注意包名有中文會致使上傳出現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系統能夠經過工具上傳
https://github.com/NuGetPackageExplorer/NuGetPackageExplorer
在Server A服務器上基於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
第一次啓動會有點慢,須要耐心的等待一下(幾分鐘),初始化完了後進入系統設置root的密碼,登陸進去咱們建立兩個項目,一個Web應用,一個工具庫,等會須要用到
在Server B服務器基於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歡迎頁輸入,設置好管理員後,選擇Custom Select,若是您對網絡有自信就直接點繼續,若是您對網絡沒自信,避免花了很長的時間還沒安裝好插件就直接啥都不選繼續。(若是出現一個XXX失敗代理的頁面直接跳過)
docer logs xxx
Please use the following password to proceed to installation:
53d4a2880bf8460c8ff61936278855ca
插件自動下載完後了,終於進去了,若是有沒有安裝成功的都得保證如下三個插件安裝好,Gitlab Hook 、Gitlab、Push Over SSH.
登陸後,在左側點擊【系統管理】,拖下去點擊 【插件管理】,確保Gitlab Hook 、Gitlab、Push Over SSH成功安裝,若是沒法順利安裝則到https://plugins.jenkins.io/下載插件手動上傳。
docker exec -it 81 /bin/bash
tzselect 4 9 1 1 cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime ##查看時間 date -R
在Server B安裝.Net SDK,由於在Server B安裝了Jenkins,所以會基於Server B的環境進行.Net的應用進行打包、發佈
添加下載源:
rpm -Uvh https://packages.microsoft.com/config/centos/7/packages-microsoft-prod.rpm
下載安裝:
sudo yum install dotnet-sdk-3.1
dotnet nuget add source http://192.168.88.139:8081 -n LocalNugetServer
列出已有包源
dotnet nuget list source
固然能夠經過 dotnet restore -s http://192.168.88.139:8081 指令指定還原包源,可是爲了不若是服務地址變更後shell腳本會大面積的修改,仍是建議經過dotnet nuget add soure指令。
那麼到這裏全部的關於Linux的工具安裝、初始化的準備工做都完成了,那麼接下來就是講解Jenkins結合Gitlab,把應用與工具包發佈到Nuget與Docker。
在一切開始以前得把SSH配置好,由於後續會使用到,在【SSH Servers】模塊把服務器地址、帳號密碼填進去保存。
返回到首頁面板點擊【新建任務】-選擇【構建一個自由風格的軟件項目】(FreeStyle Project)。
自由風格的項目更可能是使用shell腳本結合相應平臺的指令實現自動化,所以建議你們對shell腳本有個初步的認識與學習,雖然Jenkins也提供了對應平臺語言的一些插件,可是隻要您熟悉了shell就會發現它的靈活性與便捷性。
接下來咱們只要關注3個模塊,源碼管理、構建觸發器、構建
源碼構建,填寫您要自動發佈的項目的源碼地址,並輸入帳號密碼。
構建觸發器,這裏勾選Build when a chenge ……,把URL 複製記錄下來,等下在Gitlab須要使用到。這裏就是與Gitlab webhook作了聯動,能夠理解成Jenkins開放了一個接口,讓Gitlab被push代碼後會主動告訴Jenkins作一次自動化構建。
構建,這裏其實就是執行shell腳本完成發佈。這裏得注意下我是用ssh,由於個人Jenkins是使用了docker安裝的,若是我使用了【構建】模塊裏的【執行shell】就會在Jenkins環境裏進行編譯、打包,同時也須要安裝相應的環境 例如dotnet sdk等。值得注意的是,個人環境與Jenkins掛載的都是在了Server B這個宿主環境,所以經過Jenkins的SSH Publishers連到Jenkins的宿主服務器(Server B),執行相應的shell腳本從Jenkins掛載的目錄進行構建鏡像。
固然有同窗想在Jenkins環境先打包而後經過SSH的Transfers模塊進行文件傳也是能夠的。
這個是工具庫發佈到私有Nuget的腳本
#腳本開始執行 echo '腳本開始執行' 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 '發佈成功:'$project_path'' else echo '發佈失敗:'$project_path'' fi echo '腳本執行結束'
下面這個是Web應用發佈到單臺服務器的腳本
#!/bin/bash echo '腳本開始執行' 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 '發佈成功:'$project_path'' || echo '發佈失敗:'$project_path'' ) || echo '發佈失敗:'$project_path'' echo '腳本執行結束'
下面這個是經過Docker Swarm把Web應用發佈到多臺服務器
#!/bin/bash echo '腳本開始執行' 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 '發佈成功:'$project_path'' || echo '發佈失敗:'$project_path'' ) || echo '發佈失敗:'$project_path'' echo '腳本執行結束'
上面腳本有一處地址得注意下我指定了--constraint=" node.role==worker" 也就是woker節點纔會部署應用,由於我定義了ServerA和C是Web服務器。固然各位能夠按照本身的須要處理。
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,點擊【Admin Area】-【Network】,勾選選項後保存
進入一個Project,點擊【Setting】-【Webhooks】,把剛剛在Jenkins的複製下來的Url填寫進去,勾選相應的觸發事件後保存。
以上就是本篇的內容了,完成了部署後,能夠在Jenkins點擊【馬上構建】和在Gitlab遷入一次代碼查看運行效果。Shell腳本做爲一個demo,若是對腳本有更好的建議和優化的寫法能夠在評論區反饋給我。