Docker 部署Python項目
導讀: 軟件開發最大的麻煩事之一就是環境配置,操作系統設置,各種庫和組件的安裝。只有它們都正確,軟件才能運行。如果從一種操作系統里面運行另一種操作系統,通常我們采取的策略就是引入虛擬機,比如在 Windows 系統里面運行 Linux 系統。這種方式有個很大的缺點就是資源占用多、冗余步驟多、啟動慢。目前最流行的 Linux 容器解決方案之一就是Docker,它最大優點就是輕量、資源占用少、啟動快。本文從什么是Docker?Docker解決什么問題?有哪些好處?如何去部署實現去全面介紹。
0 引言
設想這樣一個真實案例,假如我們要部署一個Python應用程序,要做哪些工作?
- 首先需要python運行環境,比如部署的是python3,而機器上是python2。先裝個python3,還要裝各種依賴包,機器一些可能的沖突。
- 裝完python之后,發現還要裝mysql或者redis。繼續下載安裝配置。
- 啥?服務器不用了,需要換一台服務器?那重新來一遍吧。
- 啥?基礎應用做的太好要進行推廣,需要指導其他廠商部署?這怎么辦?
可以看出,在 Docker 之前軟件行業的運維存在着以下這些痛點:
- 軟件的發布和部署低效又繁瑣,而且總是需要人工介入
- 環境的一致性難移保證
- 在不同環境之間遷移的成本較高
在完成Docker部署安裝之前,我們還是先認識下Docker的優點:
- 軟件構建容易,分發簡單
- 應用得到隔離,依賴被解除
- 可以完美地用於 CI/CD
- 快速部署,測試完以后銷毀也方便
1 什么是Docker
Docker 是一個開源項目,誕生於 2013 年初,最初是 dotCloud 公司內部的一個業余項目。它基於 Google 公司推出的 Go 語言實現。 項目后來加入了 Linux 基金會,遵從了 Apache 2.0 協議,項目代碼在 GitHub 上進行維護。2013年3月,dotCloud公司的創始人之一,Docker之父,28歲的Solomon Hykes正式決定,將Docker項目開源,Docker 自開源后受到廣泛的關注和討論。Redhat 已經在其 RHEL6.5 中集中支持 Docker;Google 也在其 PaaS 產品中廣泛應用。WIn10下Docker下載地址:鏈接: https://pan.baidu.com/s/1GlneodbQduUdX9yLRF2hcA 提取碼: mqf6
Docker 屬於 Linux 容器的一種封裝,提供簡單易用的容器使用接口。它是目前最流行的 Linux 容器解決方案。有了 Docker,就不用擔心環境問題。總體來說,Docker 的接口相當簡單,用戶可以方便地創建和使用容器,把自己的應用放入容器。容器還可以進行版本管理、復制、分享、修改,就像管理普通的代碼一樣。
通俗解釋Docker
Docker的思想來自於集裝箱,集裝箱解決了什么問題?在一艘大船上,把貨物規整的擺放起來。並且各種各樣的貨物被集裝箱標准化了,集裝箱和集裝箱之間不會互相影響。docker就是類似的理念。現在都流行雲計算了,雲計算就好比大貨輪。docker就是集裝箱。
- 不同的應用程序可能會有不同的應用環境,比如.net開發的網站和php開發的網站依賴的軟件就不一樣,如果把他們依賴的軟件都安裝在一個服務器上就要調試很久,而且很麻煩,還會造成一些沖突。這個時候你就要隔離.net開發的網站和php開發的網站。常規來講,我們可以在服務器上創建不同的虛擬機在不同的虛擬機上放置不同的應用,但是虛擬機開銷比較高。docker可以實現虛擬機隔離應用環境的功能,並且開銷比虛擬機小,小就意味着省錢了。
- 開發軟件的時候用的是Ubuntu,但是運維管理的都是centos,運維在把你的軟件從開發環境轉移到生產環境的時候就會遇到一些Ubuntu轉centos的問題,比如:有個特殊版本的數據庫,只有Ubuntu支持,centos不支持,在轉移的過程當中運維就得想辦法解決這樣的問題。這時候要是有docker你就可以把開發環境直接封裝轉移給運維,運維直接部署你給他的docker就可以了。而且部署速度快。
- 在服務器負載方面,如果你單獨開一個虛擬機,那么虛擬機會占用空閑內存的,docker部署的話,這些內存就會利用起來。總之docker就是集裝箱原理。
2 Docker用途
Docker 的主要用途,目前有三大類。
(1)提供一次性的環境。本地測試的軟件、持續集成的時候提供單元測試和構建的環境。
(2)提供彈性的雲服務。因為 Docker 容器可以隨開隨關,很適合動態擴容和縮容。
(3)組建微服務架構。一台機器可以跑多個服務,在本機可以模擬出微服務架構。
應用場景
- Web 應用的自動化打包和發布。
- 自動化測試和持續集成、發布。
- 在服務型環境中部署和調整數據庫或其他的后台應用。
- 從頭編譯或者擴展現有的OpenShift或Cloud Foundry平台來搭建自己的PaaS環境。
Docker 能干什么?
-
簡化配置:這是Docker公司宣傳的Docker的主要使用場景。虛擬機的最大好處是能在你的硬件設施上運行各種配置不一樣的平台(軟件、系統),Docker在降低額外開銷的情況下提供了同樣的功能。它能讓你將運行環境和配置放在代碼中然后部署,同一個Docker的配置可以在不同的環境中使用,這樣就降低了硬件要求和應用環境之間耦合度。
-
代碼流水線管理:前一個場景對於管理代碼的流水線起到了很大的幫助。代碼從開發者的機器到最終在生產環境上的部署,需要經過很多的中間環境。而每一個中間環境都有自己微小的差別,Docker給應用提供了一個從開發到上線均一致的環境,讓代碼的流水線變得簡單不少。
-
提高開發效率:這就帶來了一些額外的好處:Docker能提升開發者的開發效率。如果你想看一個詳細一點的例子,可以參考Aater在DevOpsDays Austin 2014 大會或者是DockerCon上的演講。 不同的開發環境中,我們都想把兩件事做好。一是我們想讓開發環境盡量貼近生產環境,二是我們想快速搭建開發環境。
理想狀態中,要達到第一個目標,我們需要將每一個服務都跑在獨立的虛擬機中以便監控生產環境中服務的運行狀態。然而,我們卻不想每次都需要網絡連接,每次重新編譯的時候遠程連接上去特別麻煩。這就是Docker做的特別好的地方,開發環境的機器通常內存比較小,之前使用虛擬的時候,我們經常需要為開發環境的機器加內存,而現在Docker可以輕易的讓幾十個服務在Docker中跑起來。
-
隔離應用: 有很多種原因會讓你選擇在一個機器上運行不同的應用,比如之前提到的提高開發效率的場景等。我們經常需要考慮兩點,一是因為要降低成本而進行服務器整合,二是將一個整體式的應用拆分成松耦合的單個服務(譯者注:微服務架構)。如果你想了解為什么松耦合的應用這么重要,請參考Steve Yege的這篇論文,文中將Google和亞馬遜做了比較。
-
整合服務器:正如通過虛擬機來整合多個應用,Docker隔離應用的能力使得Docker可以整合多個服務器以降低成本。由於沒有多個操作系統的內存占用,以及能在多個實例之間共享沒有使用的內存,Docker可以比虛擬機提供更好的服務器整合解決方案。
-
調試能力:Docker提供了很多的工具,這些工具不一定只是針對容器,但是卻適用於容器。它們提供了很多的功能,包括可以為容器設置檢查點、設置版本和查看兩個容器之間的差別,這些特性可以幫助調試Bug。你可以在《Docker拯救世界》的文章中找到這一點的例證。
-
多租戶: 另外一個Docker有意思的使用場景是在多租戶的應用中,它可以避免關鍵應用的重寫。我們一個特別的關於這個場景的例子是為IoT(譯者注:物聯網)的應用開發一個快速、易用的多租戶環境。這種多租戶的基本代碼非常復雜,很難處理,重新規划這樣一個應用不但消耗時間,也浪費金錢。使用Docker,可以為每一個租戶的應用層的多個實例創建隔離的環境,這不僅簡單而且成本低廉,當然這一切得益於Docker環境的啟動速度和其高效的
diff
命令。 -
快速部署: 在虛擬機之前,引入新的硬件資源需要消耗幾天的時間。虛擬化技術(Virtualization)將這個時間縮短到了分鍾級別。而Docker通過為進程僅僅創建一個容器而無需啟動一個操作系統,再次將這個過程縮短到了秒級。這正是Google和Facebook都看重的特性。你可以在數據中心創建銷毀資源而無需擔心重新啟動帶來的開銷。通常數據中心的資源利用率只有30%,通過使用Docker並進行有效的資源分配可以提高資源的利用率。
3 Docker優點
- 更快速的交付和部署
Docker在整個開發周期都可以完美的輔助你實現快速交付。Docker允許開發者在裝有應用和服務本地容器做開發。可以直接集成到可持續開發流程中。例如:開發者可以使用一個標准的鏡像來構建一套開發容器,開發完成之后,運維人員可以直接使用這個容器來部署代碼。 Docker 可以快速創建容器,快速迭代應用程序,並讓整個過程全程可見,使團隊中的其他成員更容易理解應用程序是如何創建和工作的。 Docker 容器很輕很快!容器的啟動時間是秒級的,大量地節約開發、測試、部署的時間。
- 高效的部署和擴容
Docker 容器幾乎可以在任意的平台上運行,包括物理機、虛擬機、公有雲、私有雲、個人電腦、服務器等。 這種兼容性可以讓用戶把一個應用程序從一個平台直接遷移到另外一個。
- 更高的資源利用率
Docker 對系統資源的利用率很高,一台主機上可以同時運行數千個 Docker 容器。容器除了運行其中應用外,基本不消耗額外的系統資源,使得應用的性能很高,同時系統的開銷盡量小。傳統虛擬機方式運行 10 個不同的應用就要起 10 個虛擬機,而Docker 只需要啟動 10 個隔離的應用即可。
- 更簡單的管理
使用 Docker,只需要小小的修改,就可以替代以往大量的更新工作。所有的修改都以增量的方式被分發和更新,從而實現自動化並且高效的管理。
4 Docker的三個概念
- 鏡像(Image):類似於虛擬機中的鏡像。任何應用程序運行都需要環境,而鏡像就是用來提供這種運行環境的。例如一個Ubuntu鏡像就是一個包含Ubuntu操作系統環境的模板,同理在該鏡像上裝上Apache軟件,就可以稱為Apache鏡像。
- 容器(Container):類似於一個輕量級的沙盒,可以將其看作一個極簡的Linux系統環境(包括root權限、進程空間、用戶空間和網絡空間等),以及運行在其中的應用程序。Docker引擎利用容器來運行、隔離各個應用。容器是鏡像創建的應用實例,可以創建、啟動、停止、刪除容器,各個容器之間是是相互隔離的,互不影響。注意:鏡像本身是只讀的,容器從鏡像啟動時,Docker在鏡像的上層創建一個可寫層,鏡像本身不變。
- 倉庫(Repository):類似於代碼倉庫,這里是鏡像倉庫,是Docker用來集中存放鏡像文件的地方。注意與注冊服務器(Registry)的區別:注冊服務器是存放倉庫的地方,一般會有多個倉庫;而倉庫是存放鏡像的地方,一般每個倉庫存放一類鏡像,每個鏡像利用tag進行區分,比如Ubuntu倉庫存放有多個版本(12.04、14.04等)的Ubuntu鏡像。
5 Docker的使用
5.1 Win10下安裝Docker
第一步:啟動虛擬環境
Win10 系統下安裝Docker,首先WIN+X,點擊應用和功能;之后點擊右側的“程序和功能”,接着點擊左側欄“啟用或關閉Windows功能”,並做以下Hyper-V(hyper-v可以理解為虛擬機平台)的配置:
第二步:安裝Toolbox
最新版 Toolbox下載地址 鏈接: https://pan.baidu.com/s/1Nx3gVdbRrO32elJcRBfiOA 提取碼: dsd4 。下載完成后,雙擊下載的 Docker for Windows Installer 安裝文件,一路 Next,點擊 Finish 完成安裝。docker toolbox是一個工具集,它主要包含以下一些內容:
- Docker CLI 客戶端,用來運行docker引擎創建鏡像和容器
- Docker Machine. 可以讓你在windows的命令行中運行docker引擎命令
- Docker Compose. 用來運行docker-compose命令
- Kitematic. 這是Docker的GUI版本
- Docker QuickStart shell. 這是一個已經配置好Docker的命令行環境
- Oracle VM Virtualbox. 虛擬機
安裝完成后,Docker 會自動啟動。通知欄上會出現個小鯨魚的圖標,這表示 Docker 正在運行。桌邊也會出現三個圖標,我們可以在命令行執行 docker version 來查看版本號,docker run hello-world 來載入測試鏡像測試。
點擊WIN+R,輸入CMD打開命令行窗口,輸入命令docker version結果如下:
運行docker run hello-world 來載入測試鏡像測試,效果如下:
第三步:鏡像加速
鑒於國內網絡問題,后續拉取 Docker 鏡像十分緩慢,我們可以需要配置加速器來解決,我使用的是網易的鏡像地址:http://hub-mirror.c.163.com。新版的 Docker 使用 /etc/docker/daemon.json(Linux) 或者 %programdata%\docker\config\daemon.json(Windows) 來配置 Daemon。請在該配置文件中加入(沒有該文件的話,請先建一個):
{
"registry-mirrors": ["http://hub-mirror.c.163.com"]
}
也可以通過點擊小鯨魚右鍵settings來設置:
5.2 Docker 常用命令
- 確認容器有在運行,可以通過 docker ps 來查看
- 使用 docker stop 容器Name 命令來停止容器
- 查看docker信息 docker info
- 刪除鏡像:docker rmi imageID
- 停用鏡像:docker stop ImageID
- 重啟鏡像: docker start imageID
- 刪除容器: docker rm ID
- docker inspect 來查看 Docker 的底層信息
- docker images 查看docker 鏡像
- 從 Docker Hub 網站來搜索鏡像,Docker Hub 網址為: https://hub.docker.com/
- 使用 docker search 命令來搜索鏡像。如搜索httpd的鏡像。
- 使用命令 docker pull 來下載鏡像。
- 命令 docker build , 從零開始來創建一個新的鏡像
- 容器連接:指定容器綁定的網絡地址,比如綁定 127.0.0.1。
6 Docker的實例
6.1 Docker 安裝 MySQL
第一步:創建MySQL鏡像:docker pull mysql
查找Docker Hub上的mysql鏡像: docker search mysql
第二步:下載鏡像: docker pull mysql:5.6
第三步:查看鏡像。列表里查到REPOSITORY為mysql,標簽為5.6的鏡像。docker images mysql
第四步:使用最新的MySQL鏡像。
# docker 中下載 mysql
docker pull mysql
#啟動,設置初始密碼
docker run --name bnc-mysql -p 3307:3306 -e MYSQL_ROOT_PASSWORD=root -d mysql
#進入容器
docker exec -it bnc-mysql bash
#登錄mysql
mysql -u root -p
ALTER user 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
FLUSH PRIVILEGES;
#添加遠程登錄用戶
CREATE USER 'liaozesong'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
GRANT ALL PRIVILEGES ON *.* TO 'liaozesong'@'%';
第五步:遠程連接MySQL數據庫。
第六步:新授權用戶連接測試。
6.2 Docker 安裝 Python項目
場景描述:我們使用一個簡單的python項目,本項目是中文分詞的算法。如何實現Docker安裝部署。
第一步: Win10下創建目錄文本
選擇在D盤下創建docker目錄,分別新建三個文件:Dockerfile,app.py,equirements.txt
-
Dockerfile(沒有后綴):一個文本文件,包含了一條條的指令(Instruction),每一條指令構建一層,因此每一條指令的內容,就是描述該層應當如何構建。創建鏡像必須文件。
# 基於鏡像基礎 FROM python:3.7 # 設置代碼文件夾工作目錄 /app WORKDIR /app # 復制當前代碼文件到容器中 /app ADD . /app # 安裝所需的包 RUN pip install -r requirements.txt # Run app.py when the container launches CMD ["python", "app.py"]
-
app.py:python項目的源代碼,這里測試的單個python文件,如果是一個完整項目,可以將整個文件夾拷貝到這里。
# coding:utf8
"""
DESC: Python數據預處理之第一個分詞程序范例
Author:伏草惟存
Prompt: code in Python3 env
"""
import jieba
str = "道路千萬條,安全第一條;行車不規范,親人兩行淚。"
print("原句: \n" + str)
seg_list = jieba.cut(str)
print("分詞: \n" + " / ".join(seg_list))
- equirements.txt :所需要的插件,以python為例,其獲取方法是cmd命令,進入到【D:\docker】目錄,執行命令:pip freeze > requirements.txt
第二步:生成鏡像。本文采用的windows環境。docker build -t friendlyhello .命令中最后的點不要忘記,這里表示當前目錄
第三步:查看鏡像是否生成
第四步:運行鏡像程序,這里可以看到分詞效果
6.3 Docker 安裝 Django項目
第一步:載入鏡像。一般采用自構建的方法,本文采用直接pull下載完成。docker pull training/webapp
第二步:運行鏡像。docker run -d -P training/webapp python app.py # 多個PORTS端口
第三步:瀏覽器輸入本地ip:端口號,訪問網頁信息
擴展:使用 Docker 和 Elasticsearch 構建一個全文搜索應用程序https://www.zcfy.cc/article/building-a-full-text-search-app-using-docker-and-elasticsearch
7 技術交流共享QQ群
【機器學習和自然語言QQ群:436303759】:
機器學習和自然語言(QQ群號:436303759)是一個研究深度學習、機器學習、自然語言處理、數據挖掘、圖像處理、目標檢測、數據科學等AI相關領域的技術群。其宗旨是純粹的AI技術圈子、綠色的交流環境。本群禁止有違背法律法規和道德的言談舉止。群成員備注格式:城市-自命名。微信訂閱號:datathinks