接下來咱們就要慢慢步入在.NET Core中使用Docker的殿堂了,在開始以前如題,咱們須要搞清楚一些概念,要否則看到官方提供以下一系列鏡像,咱們會一臉懵逼,不知道到底要使用哪個。web
本節咱們所講解的官方所提供的一系列鏡像都是最新鏡像,並且閱讀本文的您還需明白一點,要是您看到其餘博文中提供的鏡像以microsoft開頭,那麼說明已過期再也不可取。這裏額外再多說一句,不少時候咱們看到一些資料,而後親自實踐卻沒達到文章中所描述的效果,大部分狀況下可能都是官方已更新致使,一切以官方文檔爲主纔是最佳。咱們將官方所提供的鏡像做以下說明:docker
鏡像地址json |
鏡像名稱 | 鏡像說明 |
mcr.microsoft.com/dotnet/core/runtimeubuntu |
.NET Core Runtime | 部署.NET Core控制檯程序 |
mcr.microsoft.com/dotnet/core/runtime-deps | .NET Core Runtime Dependenciesapi |
部署自包含的部署應用程序 |
mcr.microsoft.com/dotnet/core/sdk 緩存 |
.NET Core SDK | 構建.NET Core(或ASP.NET Core應用程序) |
mcr.microsoft.com/dotnet/core/aspnet 網絡 |
ASP.NET Core Runtime | 部署ASP.NET Core應用程序 |
上述對於.NET Core Runtime Dependencies鏡像包我沒作過多瞭解,在官方文檔上有對這個的詳細介紹名叫《SCD》,送上地址《https://docs.microsoft.com/en-gb/dotnet/core/deploying/index#self-contained-deployments-scd》,搞那麼多包,好像很複雜似的,其實咱們只需謹記以下兩點:架構
若需構建.NET Core應用程序,請使用.NET Core SDK併發
若需運行.NET Core應用程序,請使用.NET Core Runtimeapp
好比上一節咱們構建、發佈應用程序直接在本地進行,因此咱們只構建了.NET Core Runtime鏡像,若在鏡像中發佈則還需提早下載.NET Core SDK鏡像,接下來咱們運行webapi來講明經過SDK鏡像來構建程序,Runtime來運行程序。這裏須要注意下,若下載了3.0預覽版本直接運行以下命令所建立的程序版本爲3.0,此時可能會因缺乏對應包而還原失敗,因此這裏咱們將經過命令( dotnet new globaljson --sdk-version 2.2.203 --force )回退到2.2穩定版,繼續往下走。
到這裏爲止咱們並未如上一節那樣直接發佈,咱們將其直接拖到ubuntu中,以下:
這裏針對上一節內容補充說一句(我的有強迫症,上一節建立的鏡像名稱爲(hellowrold),這個鏡像所打的標籤單詞名稱打錯了,應該是helloworld,因此這裏咱們重命名下鏡像標籤名稱。又掌握了一個命令,哈哈。首先,咱們查看鏡像,以下
在Docker中重命名鏡像標籤名稱有兩種方式,一是直接經過標籤名稱來重命名,而是經過鏡像id來重命名,以下:
docker tag hellowrold:latest helloworld:latest
或
docker tag 75a287b4f21c helloworld:latest
咱們經過如上任何一種方式重命名後再查看鏡像,以下:
由於容器存在對舊鏡像的引用,因此舊的會仍然存在而不是以新的進行徹底覆蓋,因此咱們接下來執行以下命令將舊的鏡像給移除:
docker rmi hellowrold
經過執行如上命令會刪除別名/標籤,因爲75a287b4f21c具備其餘名稱,所以不會刪除實際圖像。
回到正題,接下來咱們開始經過Dockerfile來構建webapi鏡像,以下:
FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build WORKDIR /app COPY *.csproj ./ RUN dotnet restore COPY . ./ RUN dotnet publish -c Release -o out FROM mcr.microsoft.com/dotnet/core/aspnet:2.2 AS runtime WORKDIR /app COPY --from=build /app/out . ENTRYPOINT ["dotnet", "WebApi.dll"]
首先咱們構建基礎鏡像SDK來構建應用程序,咱們指定/app做爲咱們構建的工做目錄。而後將文件從本地文件系統複製到鏡像中,咱們將只複製csproj文件並運行restore,而後複製其餘剩餘文件並運行dotnet publish來構建咱們的應用程序併發布。該文件的運行時部分使用不一樣的docker基礎映像也就是使用aspnetcore-runtime映像,它複製構建中的全部文件,而後定義應用程序入口點。咱們發如今整個構建鏡像過程的不一樣階段都是可交互的,由於如上咱們第一階段獲取構建程序鏡像也就是別名爲build,在第二階段獲取運行程序鏡像也就是runtime,咱們引用了build。
從如上咱們構建鏡像命令和上一節對比知道,構建命令能夠經過 docker build . -t tagname 或 docker build -t tagname . 這兩種方式來進行皆可。構建鏡像就是基於上一鏡像層並建立一個新的鏡像層的過程,每一個新的鏡像層都對應一個惟一的標識id,咱們能夠經過以下命令來查看鏡像構建的歷史記錄:
docker image history webapi:latest
當咱們構建完鏡像後,咱們查看鏡像列表會看到此時會多出了鏡像標籤名稱爲none的,以下:
如上生成的鏡像none的做用是什麼呢?咱們是否是能夠將其刪除呢?
優勢:它用來維護中間鏡像層,由於對於每一個Dockerfile說明的每一步驟,都會爲中間層建立一個新的哈希值,經過容許緩存每一個步驟來提升可重用性,減小磁盤使用量並加速docker構建。
缺點:它做爲懸空鏡像,可能會致使磁盤空間問題,可是它被列爲docker鏡像的一部分。(Docker中空的文件系統層是未使用的,而且沒有被任何鏡像所引用,所以咱們須要一種機制讓Docker清除這些空的鏡像)
none的鏡像只是爲臨時容器保存而已,因爲Docker的架構,即便容器中止了,這些懸空的鏡像也依然會保留,因此咱們能夠對其進行清理,咱們可使用 docker rmi $(docker images -f "dangling=true" -q) 來清理它們,-f "dangling = true" -q顯示全部懸空鏡像,rmi將刪除全部這些圖像,若沒有任何懸空鏡像但執行了此命令,則會返回錯誤,可是咱們可使用 docker images prune -a (僅適用於1.25以上的docker版本)。
接下來則是建立並啓動容器運行程序,上一節咱們在代碼中配置了端口號爲5000,而且也經過 docker run -p 5050:5050 hellowrold 指定相同端口號運行程序,這裏咱們在代碼中並未配置端口,因此默認端口號爲80,以下:
docker run webapi:latest
接下來若是咱們訪問http:// localhost/api/values,咱們會看到沒法鏈接,也就是說沒有獲得咱們所指望的JSON響應。
這是爲什麼呢?咱們來看看docker給咱們生成容器的名稱,docker給容器隨機生成例如以下一個名稱:
接下來咱們經過終端運行容器管理命令來修復,咱們首先將容器中止,而後進行移除,命令以下:
docker container stop gracious_chaplygin
docker container rm gracious_chaplygin
咱們須要將gracious_chaplygi替換爲從docker container ls返回的容器名稱,咱們使用如下命令再次啓動容器:
docker run --name webapi --env ASPNETCORE_ENVIRONMENT=Production -p 80:80 webapi:latest
如上咱們配置了3個參數,--name是容器啓動和運行時的名稱,--env容許咱們將環境變量傳遞給正在運行的容器,-p容許咱們將容器上的端口映射到在咱們的機器上的端口。
如上容器已啓動,咱們再次使用ls命令查看咱們提供的名稱和端口映射:
上述我猜想多是由於容器名稱隨機生成的問題,而後指定了容器名稱,結果好使了,可是上述咱們再次獲取容器名稱時發現依然是隨機生成的容器名稱,因此我認爲不是這個問題致使,和上一節咱們運行容器作本節對比,只是指定了映射端口號,而本節未指定端口號,默認啓動端口號爲80,容器也運行起來了呀,最終發現仍是未指定端口號的緣故,由於當我啓動容器時,也以下明確指定端口號爲80就好使了,因此這裏須要注意下。
本節咱們講解了在Docker中安裝對應.NET Core鏡像包的問題,而且以一個例子來講明,同時呢,咱們在上一節使用指令的基礎上又額外添加了對WORKDIR和RUN指令的使用,以及對容器中止、移除、鏡像列表查看、鏡像重命名、鏡像刪除、鏡像構建歷史記錄查看指令的使用。接下來咱們會繼續經過例子來靈活使用各類指令,而後在這個過程當中還涉及到一些可優化、以及Docker中好比卷、網絡更深刻的講解。