.NET Core容器化開發系列(一)——Docker裡面跑個.NET Core
前言
部落格園中已經有很多如何在Docker裡面執行ASP.NET Core的介紹了。本篇主要介紹一些細節,幫助初學的朋友更加深入地理解如何在Docker中執行ASP.NET Core。
安裝Docker
Docker現支援在主流Linux、Windows和macOS上安裝,官方的安裝文件請參考docker docs。鑑於國內的網路環境,建議通過國內大廠/高校提供的映象站快速安裝,比如 阿里巴巴開源映象站,Ubuntu和Centos7上的安裝方式如下:
Ubuntu 14.04 16.04 (使用apt-get進行安裝)
# step 1: 安裝必要的一些系統工具 sudo apt-get update sudo apt-get -y install apt-transport-https ca-certificates curl software-properties-common # step 2: 安裝GPG證書 curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add - # Step 3: 寫入軟體源資訊 sudo add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable" # Step 4: 更新並安裝 Docker-CE sudo apt-get -y update sudo apt-get -y install docker-ce # 安裝指定版本的Docker-CE: # Step 1: 查詢Docker-CE的版本: # apt-cache madison docker-ce # docker-ce | 17.03.1~ce-0~ubuntu-xenial | http://mirrors.aliyun.com/docker-ce/linux/ubuntu xenial/stable amd64 Packages # docker-ce | 17.03.0~ce-0~ubuntu-xenial | http://mirrors.aliyun.com/docker-ce/linux/ubuntu xenial/stable amd64 Packages # Step 2: 安裝指定版本的Docker-CE: (VERSION 例如上面的 17.03.1~ce-0~ubuntu-xenial) # sudo apt-get -y install docker-ce=[VERSION]
CentOS 7 (使用yum進行安裝)
# step 1: 安裝必要的一些系統工具 sudo yum install -y yum-utils device-mapper-persistent-data lvm2 # Step 2: 新增軟體源資訊 sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo # Step 3: 更新並安裝 Docker-CE sudo yum makecache fast sudo yum -y install docker-ce # Step 4: 開啟Docker服務 sudo systemctl enable docker && systemctl start docker # 注意: # 官方軟體源預設啟用了最新的軟體,您可以通過編輯軟體源的方式獲取各個版本的軟體包。例如官方並沒有將測試版本的軟體源置為可用,你可以通過以下方式開啟。同理可以開啟各種測試版本等。 # vim /etc/yum.repos.d/docker-ce.repo # 將 [docker-ce-test] 下方的 enabled=0 修改為 enabled=1 # # 安裝指定版本的Docker-CE: # Step 1: 查詢Docker-CE的版本: # yum list docker-ce.x86_64 --showduplicates | sort -r # Loading mirror speeds from cached hostfile # Loaded plugins: branch, fastestmirror, langpacks # docker-ce.x86_64 17.03.1.ce-1.el7.centos docker-ce-stable # docker-ce.x86_64 17.03.1.ce-1.el7.centos @docker-ce-stable # docker-ce.x86_64 17.03.0.ce-1.el7.centos docker-ce-stable # Available Packages # Step2 : 安裝指定版本的Docker-CE: (VERSION 例如上面的 17.03.0.ce.1-1.el7.centos) # sudo yum -y install docker-ce-[VERSION]
以下我的實驗在Centos7中進行,其他系統基本類似。
安裝完成後,可以看到最新Docker版本為18.09(2018年12月27日)
效果0X01
既然Docker安裝好了,也正常執行起來了,我們第一件事兒做的就是執行一下Demo,看看是個什麼效果,微軟將dotnet的Docker映象都託管在Docker Hub上,我們可以開啟Docker Hub的官方網站:https://hub.docker.com 並直接搜尋dotnet,找到microsoft/dotnet即可。
根據Wiki提示,我們使用如下命令執行第一個ASP.NET Core的Demo:
docker run -it --rm -p 8000:80 --name aspnetcore_sample microsoft/dotnet-samples:aspnetapp
執行後輸出:
[[email protected] ~]# docker run -it --rm -p 8000:80 --name aspnetcore_sample microsoft/dotnet-samples:aspnetapp Unable to find image 'microsoft/dotnet-samples:aspnetapp' locally aspnetapp: Pulling from microsoft/dotnet-samples a5a6f2f73cd8: Pull complete 1e6f560accc2: Pull complete 8176b77dc10d: Pull complete e21dd5015bb0: Pull complete 10a7ec297783: Pull complete 52c4b3af04fb: Pull complete Digest: sha256:de388b1ced92eadb906f806d0253d93c76cb92b0814798e7441c014b9645a32c Status: Downloaded newer image for microsoft/dotnet-samples:aspnetapp warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35] No XML encryptor configured. Key {024f9978-2fea-4d8e-818a-b9a378553244} may be persisted to storage in unencrypted form. Hosting environment: Production Content root path: /app Now listening on: http://[::]:80 Application started. Press Ctrl+C to shut down.
簡單解釋一下命令中幾個常見的引數:
-it 開啟一個互動視窗,也急執行docker後,處於docker的互動式輸入輸出頁面
--rm 當從執行的容器中退出(ctrl+c)時,刪除映象殘留資訊及資料
-p 埠對映,將宿主機埠對映到容器內埠
--name 給容器起個名字,如不設定該項,容器名稱將有docker服務隨機設定
最後是映象的地址以及tag
執行該段命令後:
首先查詢宿主機本地是否存在microsoft/dotnet-samples:aspnetapp映象
如不存在,則從遠端拉取映象
拉取成功後,執行指定命令,將Demo服務執行起來
此時我們在區域網的任意一臺電腦瀏覽器中輸入http://[宿主機IP]:8000 即可開啟容器執行的demo
效果0X02
看完官方的Demo,接下來我們自制一個DemoV2 。該思路採用將Docker容器轉製為映象的辦法,因該方法擴充套件性不強,不適合重複使用,因此不被推薦,但其中的部分思路非常適合借鑑學習:
docker run -it --rm --name dotnet_sdk microsoft/dotnet:sdk
接下來我們在tmp目錄下新建一個ASP.NET Core MVC專案,併發布該專案都/app目錄下
此時我們進入/app目錄後,執行命令,即可看到demo1已經能在容器中正常執行:
cd /app && dotnet demo1.dll
接下來我們使用docker commit命令將當期容器轉製為映象,以便於我們重複使用。
首先,新開一個宿主機終端,並在終端中檢視當期執行的容器:
docker ps
可以發現名稱為dotnet_sdk的容器,其容器Id為9bc83a01a0d1,此時執行如下命令:
docker commit 9bc83a01a0d1 mydemo:v1
即可將指定容器儲存為名稱為mydemo的映象,執行docker images檢視:
包含我們demo程式的映象就已經儲存下來了,接下來我們可以直接執行該映象檢視效果:
docker run -it --rm -p 8001:80 --name ggg mydemo:v1 sh -c "cd /app && dotnet demo1.dll"
開啟瀏覽器訪問效果:
效果0x03
接下來我們用最常見也是最合適的方式製作我們的.NET Core MVC映象---Dockerfile
如果我們希望在Linux下直接開始.NET Core的程式碼編寫,首先就必須要安裝平臺相關的.Net Core SDK,安裝完成後,才可以使用dotnet 的相關指令建立、編譯、釋出專案。此時我們可以在Docker下采取更“雞賊”一些的辦法:
首先,我們執行一個.Net Sdk的容器,並進入互動式介面:
docker run -it --rm --name dotnet_sdk -v /tmp/src:/tmp/src microsoft/dotnet:sdk
執行.Net Core最新的SDK,並將宿主機/tmp/src 資料夾掛在到容器/tmp/src下面,而後我們在這個資料夾的檔案都不會因容器銷燬二丟失。
檢視容器中dotnet版本資訊,並在容器的/tmp/src資料夾下建立新的ASP.NET Core MVC專案:
cd /tmp/src dotnet new mvc -n mydemo
此時可以退出當前容器了,接下來進入的是Docker的打包步驟。
雖然這種做法有點“畫蛇添足”,但在某些時刻還是挺有用的,比如系統中存在老版本的.NET Core SDK,安裝新版本的SDK可能會產生未知的問題,此時在Docker裡面瞎玩,隨便搞都沒問題,棒呆!
同時有必要再強調一下,Docker從17.05版本開始支援“多階段構建(multi-stages builds)”,而大多數乾淨的Linux作業系統在直接使用系統包管理器安裝docker時安裝的是13.1的版本Docker,是不支援該特性的。
下面介紹的模式是分層結構的構建方式。
在宿主機/tmp/src/mydemo下新建Dockerfile檔案,輸入以下內容:
FROM microsoft/dotnet:2.2-runtime AS base WORKDIR /app EXPOSE 80 FROM microsoft/dotnet:2.2-sdk AS publish WORKDIR /src COPY . . RUN dotnet publish -c Release -o /app FROM base AS final WORKDIR /app COPY --from=publish /app . ENTRYPOINT ["dotnet", "mydemo.dll"]
該指令碼一共分3次,第一次定義了基礎映象,並設定/app為基礎工作目錄,告知外部80為開放埠
第二次,將當期目錄下的所有檔案傳送給Docker服務,執行釋出過程,將釋出輸出到/app資料夾下
第三次,採用第一次的映象基礎作為當期映象,並將第二次釋出輸出拷貝到當前基礎工作目錄/app
最後設定工作入口,當映象執行時,執行dotnet mydemo.dll
通過docker images命令可以看到剛剛打包出的映象
接下來我們嘗試將映象執行起來:
docker run -it --name mydemo -p 8002:80 mydemo:v1
成功!
這次隨筆主要介紹了在Docker裡面如何執行一個.NET Core專案的Demo,建議大家在學習Docker時,對如何書寫Dockerfile多下點功夫,理解裡面的基礎命令關鍵詞。