沒有 docker 部署的程式是不完整的,在寫了 IIS/Centos/Supervisor 3篇托管介紹文章後,終於來到了容器化部署 ...
前言
沒有 docker 部署的程式是不完整的,在寫了 IIS/Centos/Supervisor 3篇托管介紹文章後,終於來到了容器化部署,博客園裡面有關於 docker 部署的文章比比皆是,作為硬核實戰派,這裡做的一定是一套打完帶走的功法。本文使用的學習機器是由 Azure 傾情提供的 30 天試用版本,大家都可以申請的哈。
1. 為什麼要使用 docker
1.1 docker 介紹
docker 帶來的好處是顯而易見的,使用 docker 可以在同一臺伺服器上部署多個版本的應用,彼此間不會引起衝突,更快的遷移過程,當需要增加服務實例的時候,只需要下載 docker 鏡像即可部署運行,無需擔心環境初始化等一系列前置工作,目前使用 docker 基於阿裡雲彈性計算的應用已經非常廣泛,docker 容器內部就是一個獨立的虛擬機,在容器中,你可以做一切你想做的工作,比如測試、代碼編譯,基於容器的版本回滾也非常的方便;有人說,使用了 docker 而沒有使用容器編排的話是沒有意義的;朋友們,不要聽人云亦云, docker 的存在,本意並非面向大型應用,現在大量的微服務化就已經證明瞭 docker 是一個小巧、靈活的載體,所以,在單體應用中使用 docker 也是非常有必要的。
1.2 應用舉例
舉個例子,某外包公司為某企業開發了一款基於圖像識別的程式套件,最初部署上線是使用 .NET Core 1.0 ,而由於技術迭代和業務的發展,甲方要求該套件必須升級到 .NET Core 2.0+,而該套件程式目前運行於正式環境中,且不能停機,這就是傳說中的給飛行中的飛機換引擎;首先,在當前正式環境安裝 .NET Core 2.0 風險較大,誰也不能保證沒有相容性問題;其次,使用另外一臺服務做 .NET Core 2.0 的升級方案,但是該方案的缺點是需要增加伺服器、且需要調整反向代理配置;開發方結合現實,給出 docker 部署升級的方案,通過容器化部署,對現有生產環境幾乎就是零影響,且無需增加伺服器和修改反向代理配置。
2 Centos 伺服器安裝前置條件
2.1 安裝 docker-ce
$ sudo yum install -y yum-utils \
device-mapper-persistent-data \
lvm2
添加包源
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
安裝完成,輸入
docker --version
- 表示安裝成功,但是僅僅是安裝成功,截至目前, docker 還沒有啟動,我們還需要手動啟動 docker 服務,輸入下麵的命令
sudo systemctl start docker
*測試運行
sudo docker run hello-world
看上圖紅框處的兩個消息,當輸入命令 sudo docker run hello-world,docker 檢查到本地倉庫沒有名稱為:hello-world 的鏡像,馬上從官方倉庫中拉取了該鏡像,然後執行,hellow-world 執行後輸出信息在紅框 2 處,表示您安裝的 docker 程式已經安裝成功併成功使用容器運行。
2.2 使用安裝腳本安裝 docker
好消息是,當你對上面的一堆命令非常茫然的時候,docker 官方提供了一份安裝腳本,可以一鍵安裝 docker ,地址在:https://github.com/docker/docker-install,註意使用該腳本的許可權,並且始終驗證腳本的合法性
3. 開始使用 Dockerfile
3.1 為 .NET Core 應用程式編寫 Dockerfile 文件
為了將 .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"] #運行鏡像入口命令和可執行文件名稱
3.2 構建鏡像
創建完 Dockerfile 文件後,將項目文件 copy 到伺服器上,定位到目錄 Deploye.Linux ,執行以下命令
sudo docker build -t demo .
- 註意:上面這條命令後面的小數點不是筆誤,是必須的!
看到輸出結果提示:Successfully tagged demo:latest 表示鏡像構建成功
輸入命令查看倉庫中的鏡像,可以看到 demo 鏡像已經安靜的躺在那裡等待我們去開發了
sudo docker images
3.3 運行鏡像
現在,可以輸入命令運行我們剛剛創建的 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 進行容器化部署成功!!!
4. 擴展的 docker 學習
當我們成功部署第一個 docker 應用後,後續的問題也隨之而來了,比如更新,這個是無法迴避的問題,從部署完成的那一刻開始就如影隨形,所以,學習其它的 docker 命令是非常有必要的
4.1 更新程式
容器化部署的每一次更新都伴隨著下麵的步驟,長此以往,生生不息
*步驟說明
1、編譯
2、打包
3、發佈
4、運行
我們可以把這些步驟都整合成一份腳本文件,每次都去執行該腳本即可,方便又安全,當後續引入 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
4.2 進入鏡像
進入運行中的容器的方法有多種,掌握一種足夠,在控制台輸入命令
sudo docker exec -it demo /bin/bash
在容器內部使用命令和在 Centos 系統中一樣,可以看到我們 demo 程式的執行目錄 /app
結束語
通過本文,我們學習了以下內容
1、在 Centos 中安裝 docker
2、編寫 Dockerfile 文件
3、在容器中構建 .NET Core 程式
4、編寫自動化構建腳本,為遷移到 Jenkins 做準備
5、學習了一些基本的 docker 擴展命令