沒有 docker 部署的程序是不完整的,在寫了 IIS/Centos/Supervisor 3篇託管介紹文章後,終於來到了容器化部署,博客園裏面有關於 docker 部署的文章比比皆是,做爲硬核實戰派,這裏作的必定是一套打完帶走的功法。本文使用的學習機器是由 Azure 傾情提供的 30 天試用版本,你們均可以申請的哈。linux
docker 帶來的好處是顯而易見的,使用 docker 能夠在同一臺服務器上部署多個版本的應用,彼此間不會引發衝突,更快的遷移過程,當須要增長服務實例的時候,只須要下載 docker 鏡像便可部署運行,無需擔憂環境初始化等一系列前置工做,目前使用 docker 基於阿里雲彈性計算的應用已經很是普遍,docker 容器內部就是一個獨立的虛擬機,在容器中,你能夠作一切你想作的工做,好比測試、代碼編譯,基於容器的版本回滾也很是的方便;有人說,使用了 docker 而沒有使用容器編排的話是沒有意義的;朋友們,不要聽人云亦云, docker 的存在,本意並不是面向大型應用,如今大量的微服務化就已經證實了 docker 是一個小巧、靈活的載體,因此,在單體應用中使用 docker 也是很是有必要的。git
舉個例子,某外包公司爲某企業開發了一款基於圖像識別的程序套件,最初部署上線是使用 .NET Core 1.0 ,而因爲技術迭代和業務的發展,甲方要求該套件必須升級到 .NET Core 2.0+,而該套件程序目前運行於正式環境中,且不能停機,這就是傳說中的給飛行中的飛機換引擎;首先,在當前正式環境安裝 .NET Core 2.0 風險較大,誰也不能保證沒有兼容性問題;其次,使用另一臺服務作 .NET Core 2.0 的升級方案,可是該方案的缺點是須要增長服務器、且須要調整反向代理配置;開發方結合現實,給出 docker 部署升級的方案,經過容器化部署,對現有生產環境幾乎就是零影響,且無需增長服務器和修改反向代理配置。github
參考:https://docs.docker.com/install/linux/docker-ce/centos/docker
$ sudo yum install -y yum-utils \ device-mapper-persistent-data \ lvm2
添加包源centos
sudo yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo
開始安裝 docker-ce安全
sudo yum install docker-ce docker-ce-cli containerd.io
安裝完成,輸入bash
docker --version
sudo systemctl start docker
*測試運行服務器
sudo docker run hello-world
看上圖紅框處的兩個消息,當輸入命令 sudo docker run hello-world,docker 檢查到本地倉庫沒有名稱爲:hello-world 的鏡像,立刻從官方倉庫中拉取了該鏡像,而後執行,hellow-world 執行後輸出信息在紅框 2 處,表示您安裝的 docker 程序已經安裝成功併成功使用容器運行。app
好消息是,當你對上面的一堆命令很是茫然的時候,docker 官方提供了一份安裝腳本,能夠一鍵安裝 docker ,地址在:https://github.com/docker/docker-install,注意使用該腳本的權限,而且始終驗證腳本的合法性微服務
爲了將 .NET Core 應用程序進行容器化,咱們須要爲程序編寫一個 Dockerfile 文件,正如其名稱同樣,該文件的名字也須要命名爲 Dockerfile,,而後將其放入程序根目錄下,仍是以以前的 Deploy.Linux 程序爲例子,在 Deploy.Linux 根目錄下建立 Dockerfile
咱們有兩種建立 Dockerfile 文件的方式
經過開發工具 visual studio 右鍵點擊項目:添加-> Docker 支持
或者手動建立該文件,一個標準的 Dockerfile 以下
FROM microsoft/dotnet:2.2-sdk #這是第一個指令,必須是 FROM 這裏指定基礎構建鏡像 WORKDIR /app #工做目錄,即程序運行根目錄 COPY *.csproj ./ #複製文件到容器中 RUN dotnet restore #下載項目依賴項 COPY . ./ #將剩餘文件複製到容器中 RUN dotnet publish "Deploy.Linux.csproj" -c Release -o /app #發佈容器中的項目到 容器中 /app 目錄 ENTRYPOINT ["dotnet", "Deploy.Linux.dll"] #運行鏡像入口命令和可執行文件名稱
建立完 Dockerfile 文件後,將項目文件 copy 到服務器上,定位到目錄 Deploye.Linux ,執行如下命令
sudo docker build -t demo .
看到輸出結果提示:Successfully tagged demo:latest 表示鏡像構建成功
輸入命令查看倉庫中的鏡像,能夠看到 demo 鏡像已經安靜的躺在那裏等待咱們去開發了
sudo docker images
如今,能夠輸入命令運行咱們剛剛建立的 demo 鏡像了
sudo docker run -d -p 80:80 -e --name demo demo:latest . -v /data/logs/demo:/data/logs/demo
如今你們打開我 Azure 雲主機的地址訪問:http://139.219.9.102/(學習機器,可能會過時) ,目前運行的程序正是基於 dokcer 容器的實例
很是開心,使用 docker 進行容器化部署成功!!!
當咱們成功部署第一個 docker 應用後,後續的問題也隨之而來了,好比更新,這個是沒法迴避的問題,從部署完成的那一刻開始就如影隨形,因此,學習其它的 docker 命令是很是有必要的
容器化部署的每一次更新都伴隨着下面的步驟,久而久之,生生不息
*步驟說明
一、編譯
二、打包
三、發佈
四、運行
咱們能夠把這些步驟都整合成一份腳本文件,每次都去執行該腳本便可,方便又安全,當後續引入 Jenkins 進行自動化構建以後,咱們直接把該腳本遷移到 Jenkins 中便可,仍是以當前的實例 Deploy.Linux 爲例子,編寫 demo.sh 腳本文件以下:
sudo docker build -t demo . #開始執行Dockerfile進行構建 sudo docker images -a #列出現有倉庫的鏡像列表 sudo docker ps -a | grep "Exited" | awk '{print $1 }'|xargs docker stop #查找並中止鏡像 sudo docker ps -a | grep "Exited" | awk '{print $1 }'|xargs docker rm #移除已中止的鏡像 sudo docker images -q -a | xargs docker inspect --format='{{.Id}}{{range $rt := .RepoTags}} {{$rt}} {{end}}'|grep -v ':' #移除懸空鏡像,沒起做用,求指導 sudo docker ps -a #列出全部實例 sudo docker stop demo #中止demo實例 sudo docker rm demo #移除demo實例 sudo docker run -d -p 80:80 --name demo demo:latest . -v /data/logs/demo:/data/logs/demoo docker run -d -p 80:80 -e --names demo demo:latest . -v /data/logs/demo:/data/logs/demo #指定demo鏡像,運行demo實例
爲了使用腳本,咱們必須爲 docker 用戶賦予 root 用戶組權限,不然 docker 無權執行中止實例等操做,執行下面的命令
sudo groupadd docker sudo gpasswd -a ${USER} docker sudo service docker restart newgrp - docker
好了,如今能夠愉快的執行腳本了,使用下面的命令執行一鍵構建鏡像
sudo sh demo.sh
進入運行中的容器的方法有多種,掌握一種足夠,在控制檯輸入命令
sudo docker exec -it demo /bin/bash
在容器內部使用命令和在 Centos 系統中同樣,能夠看到咱們 demo 程序的執行目錄 /app
經過本文,咱們學習瞭如下內容
一、在 Centos 中安裝 docker 二、編寫 Dockerfile 文件 三、在容器中構建 .NET Core 程序 四、編寫自動化構建腳本,爲遷移到 Jenkins 作準備 五、學習了一些基本的 docker 擴展命令