本文主要介紹一下如何在Docker中發佈.NET Core 3.x 並對整個過程所遇到的問題加以記錄和分析. 環境、工具、準備工作 伺服器: VM中安裝CentOS, 內核版本3.10.x; 客戶端: Windows 10; IDE: VS2019 SFTP客戶端: FileZilla; 用來進行文 ...
本文主要介紹一下如何在Docker中發佈.NET Core 3.x 並對整個過程所遇到的問題加以記錄和分析.
環境、工具、準備工作
- 伺服器: VM中安裝CentOS, 內核版本3.10.x;
- 客戶端: Windows 10;
- IDE: VS2019
- SFTP客戶端: FileZilla; 用來進行文件傳輸;
- SSH工具: Putty; 用來在Windows 上遠程訪問CentOS;
- 本文示例均為Root許可權;
- 因為是本地環境,所以防火牆是關閉狀態,如果沒有關閉防火牆,埠映射的時候記得處理.
Docker安裝 (如已安裝可忽略)
參考官方文檔
1. 卸載刪除舊Docker版本,使用如下命令;
yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine
2. 安裝 yum-config-manager ,DeviceMapper(瞭解D
eviceMapper
) 和 lvm2(瞭解lvm2); 使用如下命令:
yum install -y yum-utils \ device-mapper-persistent-data \ lvm2
3. 設置倉庫地址; 使用如下命令:
//官方地址: yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo //阿裡雲(建議): yum-config-manager \ --add-repo \ http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
4. 安裝社區版Docker, 使用如下命令: (如需安裝指定版本請參考官方文檔)
yum install docker-ce docker-ce-cli containerd.io
5. 啟動Docker, 使用如下命令:
//設置開機自動啟動docker systemctl enable docker //啟動docker systemctl start docker
6. 運行測試, 使用如下命令:
docker version
Docker發佈.NET Core MVC
1. 使用VS2019創建.NET Core MVC, 選不選擇Docker 支持都無所謂,重要的是Dockerfile. (Dockerfile學習)
2. 編寫Dockerfile, 並設置始終複製到目錄; Dockerfile內容如下:
FROM mcr.microsoft.com/dotnet/core/sdk:3.1 WORKDIR /app COPY . . EXPOSE 80 ENTRYPOINT ["dotnet", "TestMVC.dll"]
說明:
2.1 如果創建項目時選擇了Docker支持, 請將內容修改為上面內容(主要為方便理解);
2.2 Dockerfile 路徑預設先放置在Project 下,並設置始終複製到目錄; 文件路徑並非一定要在Project下,但是這樣對初學者好理解;
2.3 著重說明下EXPOSE選項:
可以不設置,該選項只是告訴鏡像使用者容器準備以什麼協議暴露哪個埠號,實際運行是不發佈埠的;相當於描述信息(Docker Run -p);
Docker Run -P 命令會使用到該選項,後面介紹;
2.4 官方基礎鏡像庫 https://hub.docker.com/_/microsoft-dotnet-core 根據自己需要選擇
3. 發佈項目並上傳到CentOS;
4. 使用命令構建鏡像: (Build命令學習)
進入項目發佈目錄:
cd /home/publish
構建鏡像:
docker build -t testmvc:v1 .
註意: . 號不能丟失, 表示當前目錄
查看鏡像信息:
docker images
5. 使用命令運行容器: (Run命令學習)
docker run -d -p 5000:5000 --name testmvc testmvc:v1
查看容器:
docker ps -a
容器啟動, 這個時候我們的.NET Core MVC就算發佈完了, 在瀏覽器輸入http://你的伺服器地址:5000 訪問程式, 你會驚喜的發現,無論怎麼訪問你都訪問不到, 是不是很意外?
為什麼會訪問不到呢? 這也是初學者踩的最多的坑, 目前網上大部分博文的部署都是上面的流程, 你部署下來會發現無論如何都訪問不到, 很少有講解為什麼, 其實原因很簡單,我們使用命令來看看為什麼:
docker logs testmvc
根據log我們發現我們的程式是正常運行了, 但是仔細看內容, .NET Core 程式預設監聽的是localhost:5000 和 localhost:5001 而localhost 是迴環網路地址, 而我們的容器和宿主機是隔離的, 所以即便我們將容器埠和宿主機埠進行了映射綁定, 宿主機依然無法訪問容器內的應用.
解決方案有以下四種(順序既是優先順序,任選一種即可)
(1) 在程式Program.cs修改程式埠監聽配置;
(2) 修改Dockerfile的ENTRYPOINT參數;
(3) 啟動容器設置應用監聽埠;
docker run -d -p 5000:5000 -e ASPNETCORE_URLS=http://+:5000 --name testmvc testmvc:v1
(4)設置Dockerfile的環境變數;
以上四種方式都可以重新設置應用程式埠監聽,四種情況共存的話1最優先,4最後;一般建議使用3, 方便各種容器編排工具進行動態管理;
停止之前運行的容器,並刪除;
//停止運行的鏡像 docker stop testmvc //刪除已經創建的容器 docker rm testmvc
使用第三者方案重新創建運行容器, 並測試, 你會發現我們的應用程式已經可以正常的訪問了.
最後我們再來解析下Dockerfile的EXPOSE的作用;
使用命令來查看我們的容器配置信息:
docker inspect testmvc
我們會看到以下配置信息:
使用查看容器命令來看容器啟動信息:
docker ps
從以上內容來看,EXPOSE定義的埠,並未暴露給宿主機, 這也是我們上面說的EXPOSE實際並不發佈埠,僅相當於描述信息;
我們在啟動容器時使用了-p 5000:5000 意義是將容器的5000埠和宿主機5000埠進行綁定;
但是 docker run還有一個參數 -P ,我們使用以下命令:
docker run -d -P --name testmvc1 testmvc:v1
你會發現有一個隨機的埠和EXPOSE暴露的80埠進行了綁定,如果這個時候你的應用程式預設監聽了80埠, 則就可以使用http://伺服器地址:32768進行程式訪問了
這就是EXPOSE的作用;