日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > linux >内容正文

linux

.NetCoreLinuxDockerPortainer踩坑历险记

發(fā)布時(shí)間:2023/12/4 linux 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 .NetCoreLinuxDockerPortainer踩坑历险记 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

最近有一個(gè)云服務(wù)器和數(shù)據(jù)庫的遷移任務(wù),踩坑爬坑無數(shù)次,覺得必須要記錄一下。大家瓜子花生準(zhǔn)備好,聽我慢慢講故事#手動(dòng)笑哭#。

故事背景

公司是做電商業(yè)務(wù)的,在天貓有幾家旗艦店數(shù)據(jù)量也很大。阿里有一個(gè)稱為聚石塔的平臺(tái),專門給這些ISV提供各種云資源,強(qiáng)制綁定了一些業(yè)務(wù),原本我們?cè)诰凼杏幸慌_(tái)ECS和一臺(tái)RDS部署在華東杭州節(jié)點(diǎn),本月初突然收到阿里的郵件說是要整體遷移到張北節(jié)點(diǎn),華東節(jié)點(diǎn)將會(huì)在9月底全部停止服務(wù),并附帶發(fā)了一份遷移文檔,要我們盡快遷移。好在我們用到的資源不多,最初覺得遷移過程并不會(huì)太復(fù)雜,實(shí)際還是太天真了。像我這樣只有一臺(tái)服務(wù)器和一臺(tái)數(shù)據(jù)庫的用戶遷移過程都謂之艱辛,對(duì)于那些有幾十甚至上百實(shí)例的ISV,那真是欲哭無淚了。每天看著遷移群里大家的各種吐槽、抱怨、焦急、無可奈何,還有那幾位一整天都在被艾特的阿里技術(shù)支持,說起來都是淚。

于是接下來制定好遷移計(jì)劃,發(fā)郵件購買要用到的資源,等過了兩天東西到位,就擼起袖子開干了。

忘了說了,這些東西原先是由另外一位同事負(fù)責(zé),然而年后他就開溜了,上級(jí)指示我扛過大旗(guo)。

開胃菜

我們的RDS是SQL Server 08 R2版本,阿里在遷移通知中專門提到了這個(gè)產(chǎn)品,而且用到了重要提示字樣,大意是說微軟已經(jīng)對(duì)這個(gè)版本的數(shù)據(jù)庫停止了安全更新,所以張北節(jié)點(diǎn)已經(jīng)不再售賣這個(gè)版本的實(shí)例,要先在當(dāng)前節(jié)點(diǎn)完成版本升級(jí)后再遷移??戳讼滤倪w移手冊(cè),覺得異常復(fù)雜和危險(xiǎn)重重,于是果斷放棄官方方案,決定在張北節(jié)點(diǎn)買好2016版本數(shù)據(jù)庫,直接切換數(shù)據(jù)推送,后來找阿里的技術(shù)支持咨詢了這個(gè)方案,也表示可以執(zhí)行。當(dāng)然了,我能這樣做是有一個(gè)前提的,我們的這個(gè)庫是只讀庫,用來接收阿里的數(shù)據(jù)推送然后給業(yè)務(wù)系統(tǒng)查詢,可以理解為只是一個(gè)過渡不存儲(chǔ)實(shí)際的業(yè)務(wù)數(shù)據(jù),對(duì)安全性要求不高,就算丟失也能通過淘寶開放平臺(tái)的API去查詢。如果是業(yè)務(wù)庫,那就只能老老實(shí)實(shí)的按官方文檔摸著石頭過河了,看群里的反饋,這道開胃菜不好吃,我也算是幸運(yùn)跳過了第一個(gè)坑。

初進(jìn)坑

RDS處理完畢,那就著手開始折騰服務(wù)器,這是一臺(tái)Linux的機(jī)器,系統(tǒng)是Centos7,主要跑了3個(gè)服務(wù):上文提到的RDS數(shù)據(jù)查詢API(一個(gè)dotnetcore2.1的程序)、Rabbitmq實(shí)例和它的管理工具、Portainer,由Docker統(tǒng)一管理,而Docker又由Portainer來管理。按照官方文檔,先在原服務(wù)器上創(chuàng)建鏡像,經(jīng)過漫長的等待(大概40分鐘吧,有的人反映等了大半天最后生成失敗的,心態(tài)崩…),然后把鏡像復(fù)制到張北節(jié)點(diǎn),然后通過鏡像生成實(shí)例,按理說新機(jī)器和原機(jī)器是完全一樣的,各項(xiàng)服務(wù)都應(yīng)該運(yùn)行正常,并且專門找技術(shù)支持確認(rèn)了,可實(shí)際真的不是這樣。

聚石塔的服務(wù)器只開放30001-30005這幾個(gè)端口,于是嘗試訪問一下Portainer所在的30003端口。瀏覽器輸入地址再回車,等了幾十秒后顯示超時(shí)無法訪問,一臉懵逼。Ping了一下服務(wù)器IP,沒毛病,又登錄服務(wù)器查看docker和container的運(yùn)行狀態(tài)以及端口映射,都沒問題,又查看端口監(jiān)聽和防火墻,還是正常,二臉懵逼。

查一下container的日志,提示運(yùn)行正常,三臉懵逼。

我的招已經(jīng)用完了,沒辦法轉(zhuǎn)向群里咨詢技術(shù)支持,回復(fù)說這幾個(gè)端口要走工單申請(qǐng)開通,WTF……老實(shí)寫工單提交再到群里艾特幫忙快點(diǎn)處理,又陷入漫長的等待中,當(dāng)時(shí)大概2點(diǎn)鐘的樣子。下午5點(diǎn)多工單狀態(tài)更新了說正在轉(zhuǎn)給技術(shù)處理請(qǐng)耐心等待,然后,就沒有然后了接著等,到7點(diǎn)還是沒消息決定先下班。

第二天上班發(fā)現(xiàn)還是沒有消息,又去群里艾特技術(shù)支持,幾分鐘后回復(fù)叫我去給ECS綁定一個(gè)安全組,照做后再次訪問30003端口依然不行,長嘆一口氣。又嘗試訪問了一下webapi所在的30001端口,神奇般的成功了#手動(dòng)黑人問號(hào)臉#。咨詢了公司運(yùn)維,教我?guī)讉€(gè)命令簡單排查了下,后來因?yàn)樘]回復(fù)我了,后來又一頓百度谷歌無果,陷入僵局。心理暗自把這個(gè)鍋丟給了阿里,覺得是他們哪里配置有問題。

事情不能就這樣僵著啊,Portainer起不來程序不能更新,于是打算直接在宿主機(jī)上跑一下修改后的dotnetcore程序看數(shù)據(jù)庫訪問是否正常。按照微軟文檔安裝對(duì)應(yīng)版本的SDK:

安裝好后把發(fā)布文件上傳到服務(wù)器,然后用dotnet命令啟動(dòng)了程序,一切正常。訪問我的測(cè)試入口:

Curl http://locahost:5000/api/values/testdb/123

看到返回了數(shù)據(jù)庫的測(cè)試數(shù)據(jù),信心重拾。回過頭重新折騰docker,發(fā)現(xiàn)docker死活起不來了,囧:

  

拿著錯(cuò)誤信息又是一頓百度谷歌,不斷的照網(wǎng)上改配置重啟系統(tǒng),幾個(gè)小時(shí)過去依然不行,決定卸載docker重裝。于是依次執(zhí)行:

yum remove docker*
reboot
yum install docker
docker version
systemctl start docker

然而啟動(dòng)的時(shí)候問題依舊,又是長嘆一口氣。仔細(xì)回想了一下,只有yum update對(duì)系統(tǒng)做了大的改動(dòng),難道是這個(gè)問題么?不知不覺又到了晚上7點(diǎn)多,腦子懵的很決定先下班第二天接著搞。

真所謂一波未平一波又起。

再進(jìn)坑

早上到公司和微信群的小伙伴吐糟著遭遇,大家勸我重裝系統(tǒng),我一邊發(fā)著捂臉笑哭的表情,一邊默默地上聚石塔后臺(tái)點(diǎn)了磁盤初始化,docker啟動(dòng)不了的問題就算翻篇了,一切從頭再來。

依然還是端口的問題,實(shí)在沒轍了只有給阿里提工單問為什么端口不通,阿里工程師先后叫我排查了iptables、端口監(jiān)聽情況、清除iptables等等還是不行,最后要了我的服務(wù)器賬號(hào)上去排查,在工單中看到阿里的工程師晚上11點(diǎn)多還在幫我排查問題,也真不容易。

終于,在阿里后面的回復(fù)中事情迎來了轉(zhuǎn)機(jī),給了我非常大的提示:

從中我捕捉到了2個(gè)重要信息,一個(gè)是容器的IP,一個(gè)是路由解析問題。我馬上百度如何查容器的IP地址,然后試著去ping容器的IP,發(fā)現(xiàn)30001端口綁定的容器(172.22.0網(wǎng)段)正常,30003端口綁定的容器(192.168.0網(wǎng)段)無法訪問,那么這就說明是宿主機(jī)和容器網(wǎng)絡(luò)不通導(dǎo)致的問題。又查看了系統(tǒng)的路由表:

這個(gè)路由表有個(gè)奇怪的現(xiàn)象,就是192.168.0這個(gè)網(wǎng)段指向了2個(gè)不同的網(wǎng)卡,分別是eth0和docker0。我知道,eth0是宿主機(jī)默認(rèn)的網(wǎng)關(guān),docker0是docker啟動(dòng)時(shí)自動(dòng)創(chuàng)建的虛擬網(wǎng)關(guān),但是還不清楚這樣的配置會(huì)有什么影響,于是百度了一下Linux路由的詳細(xì)介紹,得知相同的配置會(huì)有優(yōu)先級(jí)的問題,又嘗試著刪除eth0的配置:

1

route del -net 192.168.0.0 netmask 255.255.255.0

再次用公網(wǎng)訪問30003端口,成功了!!!終于看到了熟悉的頁面:

沒那么簡單

以為事情就此告一段落后面都是平坦大道,想不到問題又來了。通過docker run我新鏡像后發(fā)現(xiàn)容器總是自動(dòng)退出,于是尋找各種讓容器持續(xù)運(yùn)行的辦法,一陣折騰沒有效果,去微信群問小伙伴,問我是不是程序拋異常了,我頓時(shí)一種柳暗花明的感覺,立馬查看容器日志:

果然是報(bào)錯(cuò)了:

很顯然,是說我的framework版本不對(duì),但是我的dockerfile中確實(shí)引入的2.1版本運(yùn)行時(shí):

FROM microsoft/dotnet:2.1-runtime
COPY . /app
WORKDIR /app
EXPOSE 5000 80
ENTRYPOINT ["dotnet", "DRP.API.dll"]

退一萬步說,宿主機(jī)我也已經(jīng)安裝過SDK,而且直接在宿主機(jī)上運(yùn)行都是可以的,為什么通過docker來運(yùn)行就掛了,百思不得解。只能按照提示中的信息排查是不是少裝了什么組件,一陣yum install下來還是失敗:

去廣州微軟.net俱樂部的微信群請(qǐng)教別人,兩位大佬給我分析解答了一下,一位說是我的dockerfile在copy文件時(shí)漏了一些引用文件,要我重新修改dockerfile,不過經(jīng)過多次調(diào)整測(cè)試依然無效,不得不采用第二位的辦法,就是把運(yùn)行時(shí)改為2.2版本:

修改dockerfile為如下內(nèi)容:

# 添加基礎(chǔ)鏡像
FROM microsoft/dotnet:2.2-aspnetcore-runtime

#容器中系統(tǒng)的工作空間
WORKDIR /app

#拷貝當(dāng)前文件夾下的文件到容器中系統(tǒng)的工作空間
COPY . /app

#設(shè)置Docker容器對(duì)外暴露的端口
EXPOSE 5000 80

#運(yùn)行應(yīng)用程序
ENTRYPOINT ["dotnet", "DRP.API.dll"]

重新打包鏡像,然后run起來,這次一切都是那么的自然,docker ps查看容器已經(jīng)狀態(tài)是up了。欣喜若狂,以為即將看到勝利的曙光,接著用瀏覽器打開我的測(cè)試入口:

http://xxx.xxx.xxx.xxx:30001/api/values/testdb/123

尷尬的報(bào)了500,心中萬馬奔騰….

這次學(xué)機(jī)靈了,第一時(shí)間docker logs,發(fā)現(xiàn)是數(shù)據(jù)庫報(bào)錯(cuò)了:

fail: Microsoft.AspNetCore.Server.Kestrel[13]
=> ConnectionId:0HLM4DDINAGJC => RequestId:0HLM4DDINAGJC:00000001 RequestPath:/api/values/testdb/123
Connection id
"0HLM4DDINAGJC", Request id "0HLM4DDINAGJC:00000001": An unhandled exception was thrown by the application.
SqlSugar.UtilExceptions: English Message : Connection open error . A network
-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: TCP Provider, error: 40 - Could not open a connection to SQL Server)
Chinese Message : 連接數(shù)據(jù)庫過程中發(fā)生錯(cuò)誤,檢查服務(wù)器是否正常連接字符串是否正確,實(shí)在找不到原因請(qǐng)先Google錯(cuò)誤信息:A network
-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: TCP Provider, error: 40 - Could not open a connection to SQL Server).
at SqlSugar.AdoProvider.GetDataReader(String sql, SugarParameter[] parameters)
at SqlSugar.QueryableProvider`
1.GetData[TResult](KeyValuePair`2 sqlObj)
at SqlSugar.QueryableProvider`
1._ToList[TResult]()

很明顯是數(shù)據(jù)庫連接不上,檢查連接字符串,沒毛病,再次進(jìn)入僵局。

正在苦惱時(shí),突然想起前面刪掉的那條路由,嘗試重啟網(wǎng)絡(luò)恢復(fù)路由:

再次訪問測(cè)試地址,確實(shí)成功了。可問題又進(jìn)入了死循環(huán),容器內(nèi)的應(yīng)用無法訪問。

終見天日

經(jīng)過以上的種種分析后,最終把問題定在了路由這兒。既然是因?yàn)橥痪W(wǎng)段有2個(gè)網(wǎng)關(guān),那么我修改一下docker的默認(rèn)網(wǎng)段不就可以了嗎?再次面向百度編程,得到兩種方案:

第一種方案,創(chuàng)建新的的網(wǎng)關(guān)和路由,然后分配給docker:

service docker stop

ip addr add
192.168.1.1/24 dev bridge0
ip link set dev bridge0 up

vim
/etc/docker/daemon.json

加上"bridge": "bridge0"節(jié)點(diǎn)并保存退出,再重啟docker:

第二種方案,直接修改docker0的默認(rèn)網(wǎng)段:

service docker stop

vim
/etc/docker/daemon.json

加上"bip": "192.168.1.1/24"節(jié)點(diǎn)并保存退出,再重啟docker即可。

我這里采用第二種方式,修改后的路由表為:

重新訪問各種服務(wù),全部都正常運(yùn)行,到此總算是撥開云霧見青天。

有個(gè)小細(xì)節(jié)不知大家是否發(fā)現(xiàn),也是我當(dāng)時(shí)存在的一個(gè)疑惑,就是前面有提過兩個(gè)容器的網(wǎng)段不一樣,按理說通過docker run來的容器應(yīng)該都是相同的網(wǎng)段,為什么會(huì)這樣呢?后來在折騰Portainer的時(shí)候找到了這個(gè)問題。

Portainer是一款docker管理工具,簡而言之的說就是把用命令操作的東西可視化,當(dāng)然功能遠(yuǎn)不止這些。Portainer中有一個(gè)Stack功能,我并不清楚這是干什么用的,只是看到舊的Portainer中的容器綁定了一個(gè)stack所以想依葫蘆畫瓢也搞一個(gè):

于是拿stack的配置文件新創(chuàng)建一個(gè),沒想到居然報(bào)錯(cuò),提示已存在相同名稱的容器。我馬上意識(shí)到這個(gè)特殊的容器應(yīng)該是通過stack創(chuàng)建,我刪掉已存在的容器再次創(chuàng)建stack,這次成功了。出于好奇,仔細(xì)分析了stack的配置文件:

發(fā)現(xiàn)里面主要是定義了鏡像名、容器名、網(wǎng)絡(luò)模式、端口映射這些,而其中vhnet這個(gè)網(wǎng)絡(luò)配置讓我很感興趣,轉(zhuǎn)而查看docker已經(jīng)配置好的網(wǎng)關(guān):

看到這里,一種恍然大悟的感覺,你懂的。

除此之外,從前任留下的文檔里可以知道,stack有一種類似熱更新的功能,修改配置文件中的鏡像名后update stack就能實(shí)現(xiàn)對(duì)應(yīng)的容器更新,不用起新的容器,這點(diǎn)確實(shí)很不錯(cuò)。更多強(qiáng)大的功能日后也會(huì)慢慢學(xué)習(xí)。

我的收獲

經(jīng)過前面幾天的折騰,我更加熟悉了docker的各種基本操作和配置,也學(xué)會(huì)了使用新的命令,像docker inspect查看容器信息、docker attach進(jìn)入容器內(nèi)部,也加深了在Linux上排查問題的思路理解,學(xué)到了新的操作命令。也實(shí)際使用docker在Linux上部署了一次dotnetcore的生產(chǎn)環(huán)境,收獲頗豐。

遺留的問題

1、 ? ? yum update后到底經(jīng)歷了什么讓docker跪地不起,報(bào)錯(cuò)原因至今沒搞明白。

2、 ? ?為什么2.1的dotnetcore程序在2.1運(yùn)行時(shí)跑不起來,換成2.2版本就可以。

3、stack是怎么實(shí)現(xiàn)修改鏡像后容器就能生效的呢?

有知道的大佬還請(qǐng)多多指導(dǎo)。

總結(jié)

表面上全篇都在講才踩坑的事,但追根究底還是因?yàn)樽约涸贚inux方面的知識(shí)欠缺和經(jīng)驗(yàn)不足。還是那句話,多踩坑,會(huì)讓你記憶深刻,會(huì)讓你學(xué)到意想不到的東西,會(huì)讓你的身體變得足夠大,下次碰到坑能一腳踏過去。

原文地址:https://www.cnblogs.com/hohoa/p/10743552.html

.NET社區(qū)新聞,深度好文,歡迎訪問公眾號(hào)文章匯總?http://www.csharpkit.com?

總結(jié)

以上是生活随笔為你收集整理的.NetCoreLinuxDockerPortainer踩坑历险记的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。