本文你能學到什麼
Docker 是什麼
Docker 概念
關於 Docker 的概念是確實不太好總結,下面我通過四點向你說明 Docker 到底是個什麼東西。
- Docker 是世界領先的軟件容器平臺。
- Docker 使用 Google 公司推出的 Go 語言 進行開發實現,基於 Linux 內核 的cgroup,namespace,以及 AUFS 類的 UnionFS 等技術,對進程進行封裝隔離,屬於操作系統層面的虛擬化技術。由於隔離的進程獨立於宿主和其它的隔離的進 程,因此也稱其為容器。Docker 最初實現是基於 LXC.
- Docker 能夠自動執行重複性任務,例如搭建和配置開發環境,從而解放了開發人員以便他們專注在真正重要的事情上,構建傑出的軟件。
- 用戶可以方便地創建和使用容器,把自己的應用放入容器。容器還可以進行版本管理、複製、分享、修改,就像管理普通的代碼一樣。
Docker 的基本組成架構
看一張 Docker 架構圖
- 左邊大框框是我們進行 Docker 操作的宿主機,其運行了一個 Docker daemon 的核心守護程序,負責構建、運行和分發 Docker 容器。
- 在宿主機中安裝了 Docker 客戶端,其與 Docker daemon 守護進程進行通信,客戶端會將 build、pull、run 等命令發送到 Docker daemon 守護進程進行執行。
- 右框框為 Docker 註冊表存儲 Docker 鏡像,是一個所有 Docker 用戶共享 Docker 鏡像的服務,Docker daemon 守護進程與之進行交互。
下面是對架構中基本組成說明,比較詳細,大家看的時候可以對著架構圖看。概念這個東西,你看下就好,怎麼記都記不住的,只有你常用的東西才會記住和想著去記住它,看完本文,可以把下面的應用實踐一遍。
Registry
鏡像倉庫,存儲大量鏡像,可以從鏡像倉庫拉取和推送鏡像。
Docker 鏡像
類似虛擬機快照,從倉庫拉取,或者在現有工具鏡像上創建新鏡像。通過鏡像可以啟動容器。
Docker 容器
從鏡像中創建應用環境,以單進程的方式運行。對外公開服務。是一種短暫的和一次性的環境。
Docker 數據卷
數據卷可以完成數據持久化,數據卷是一個可供一個或多個容器使用的特殊目錄,它繞過 UFS,可以提供很多有用的特性:
- 數據卷可以在容器之間共享和重用
- 對數據卷的修改會立馬生效
- 對數據卷的更新,不會影響鏡像
- 卷會一直存在,直到沒有容器使用
Docker 網絡
Docker 容器之間的網絡交互,可以使用端口映射的方式,其他容器可以直接通過端口實現。除該方式外還有一個容器連接(linking)系統也可以達到容器交互。(本文中 node 連接 mongodb 使用的是端口映射的方式)
關於Docker 網絡模塊,容器連接詳情推薦這篇文章:Docker的網絡模式詳解
Docker 應用場景
Docker 部署 Node 項目完整流程(DockerFile實踐)
- 使用 Koa2 初始化一個 Node 項目,通過 Mongose 中間件 連接 Mogodb 數據庫,實現一個基礎接口 Mogodb 插入數據。項目地址:https://github.com/koala-coding/dockerstudy
- 首先在項目根目錄下創建 .dockerignore 文件,把不需要打包進 Docker Image 裡的文件進行過濾# /usr/src/nodejs/dockerstudy/.dockerignore
.git
node_modules - 在項目的根目錄中創建 Dockerfile 文件(Dockerfile 這裡重點講一下)部署 Node項目 的時候,會有一個 Dockerfile 文件配置# /usr/src/nodejs/hello-docker/Dockerfile
FROM node:10.0
# 在容器中創建一個目錄
RUN mkdir -p /usr/src/nodejs/
# 定位到容器的工作目錄
WORKDIR /usr/src/nodejs/
# RUN/COPY 是分層的,package.json 提前,只要沒修改,就不會重新安裝包
COPY package.json /usr/src/app/package.json
RUN cd /usr/src/app/
RUN npm i
# 把當前目錄下的所有文件拷貝到 Image 的 /usr/src/nodejs/ 目錄下
COPY . /usr/src/nodejs/
EXPOSE 3000
CMD npm start配置參數說明( DockerFile 學習): - FROM:FROM 是構建鏡像的基礎源鏡像,該 Image 文件繼承官方的 node image。詳細說明:Dockerfile 中 FROM 是必備的指令,並且必須是第一條指令!它引入一個鏡像作為我們要構建鏡像的基礎層,就好像我們首先要安裝好操作系統,才可以在操作系統上面安裝軟件一樣。
- RUN:後面跟的是在容器中要執行的命令。詳細說明:每一個 RUN 指令都會新建立一層,在其上執行這些命令,我們頻繁使用 RUN 指令會創建大量鏡像層,然而 Union FS 是有最大層數限制的,不能超過 127 層,而且我們應該把每一層中我用文件清除,比如一些沒用的依賴,來防止鏡像臃腫。
- WORKDIR:容器的工作目錄
- COPY:拷貝文件至容器的工作目錄下,.dockerignore 指定的文件不會拷貝
- EXPOSE:將容器內的某個端口導出供外部訪問
- CMD:Dockerfile 執行寫一個 CMD 否則後面的會被覆蓋,CMD 後面的命令是容器每次啟動執行的命令,多個命令之間可以使用 && 鏈接,例如 CMD git pull && npm start詳細說明:CMD 指令用來在啟動容器的時候,指定默認的容器主進程的啟動命令和參數。它有兩種形式CMD echo 1
CMD ["npm", "run", "test"] 必須是雙引號第一種執行的命令會被包裝程,CMD [ "sh", "-c", "echo 1" ] JSON 數組形式,一般推薦 JSON 數組形式。容器中的應用都應該以前臺執行,而不是啟動後臺服務,容器內沒有後臺服務的概念。對於容器而言,其啟動程序就是容器應用進程,容器就是為了主進程而存在的,主進程退出,容器就失去了存在的意義。比如 CMD service nginx start 它等同於 CMD [ "sh", "-c", "service nginx start"] 主進程實際上是 sh,sh 也就結束了,sh 作為主進程退出了。 - ENV(補充)ENV 指令用來設置環境變量,它有兩種形式:ENV
<value>
ENV <key1>=<value1> <key2>=<value2>...定義了環境變量,那麼在後續的指令中,就可以使用這個環境變量。/<value2>/<key2>/<value1>/<key1>/<value> - 代碼環節暫且告一段落,將帶有 Dockerfile 提交到 github 或 gitlab等。以我的服務器 centos7 為例,已安裝好 Docker。
- 首先檢出代碼,把項目克隆到指定目錄git clone https://github.com/koala-coding/dockerstudy
- 進入目錄構建cd dockerstudy
docker build -t dockerstudy .★build 命令用來製作鏡像,-t 是給鏡像打標籤,-f 參數是指定 Dockerfile 路徑,由於我們使用的是默認 Dockerfile 名稱,所以可以不同填寫該參數。最後一個.也不要省略,表示 Dockerfile 文件的所在目錄, 代表是當前路徑,它指定鏡像構建的上下文。我們剛才說過,真正製作鏡像的是 docker server,當我們執行 build命令時,docker client 會將上下文路徑下的所有內容打包,然後上傳給 docker server。這樣當我們要在 Dockerfile 文件中執行 如 COPY 指令,就可以將上下文中的文件複製到鏡像中去了。”構建目標名稱 dockerstudy,是一個鏡像,可以通過 docker images 來列出所有的鏡像。一般應該會將 Dockerfile 置於一個空目錄下,或者項目根目錄下。如果該目錄下沒有所需文件,那麼應該把所需文件複製一份過來。如果目錄下有些東西確實不希望構建時傳給 Docker引擎,那麼可以用.gitignore 一樣的語法寫一個 .dockerignore。 - 通過鏡像 dockerstudy 創建一個容器並運行。docker run --name dockerstudycontainer -d -p 3000:3000 dockerstudy說明:創建的容器名稱是 dockerstudycontainer,你可以理解為 pid,這個名稱唯一,創建之後如果不刪除會一直存在。-p 用來指定端口映射,將容器的端口3000映射到主機3000`端口上,這樣就可外部訪問了。此時在宿主機中可以使用curl測試服務器提供的服務是否正常curl localhost:3000或者可以直接在瀏覽器中請求接口看一下輸出創建容器後,有時候需要看一下容器資源佔用,使用docker statsdocker stats dockerstudycontainer★如果是購買的阿里雲或者騰訊雲服務器,注意這裡將自己購買的 centos 服務器3000端口開放,在安全組”
- 進入容器docker ls -a 查看所有容器,包括當前容器的id
docker exec -itbash - 日誌檢查 查看運行日誌,“50425b8f2ef3” 為容器 ID$ docker logs -f 50425b8f2ef3但是到了這裡我還有個問題,那我真想看日誌文件的時候,也不能每個容器進去看日誌,好浪費時間啊!有沒有什麼更高的方式?我會在下一篇文章《線上環境如何優雅的打印,保存,分析日誌》中寫到。
Docker 部署 Mongodb 環境
- 遠程獲取 Mongodb 鏡像
<code>docker pull mongo/<code>
- 創建一個docker容器docker run -p 27017:27017 -v /data/db --name docker_mongodb -d mongo在上面的命令中,幾個命令參數的詳細解釋如下:
- -p 指定容器的端口映射(特殊說明:前面的是本機端口 ,後面的是容器的端口,添加-p參數主動將容器內部端口給暴漏出來,將服務器的 27017 端口映射到容器的 27017 端口,這樣在外網就可通過 服務器的 27017 端口訪問到我們的服務,Mongodb 默認端口為 27017。最終訪問的還是本機的端口)
- -v 為設置容器的掛載目錄,這裡是將即本機中的目錄掛載到容器中的/data/db中,作為 Mongodb 的存儲目錄
- --name 為設置該容器的名稱
- -d 設置容器以守護進程方式運行
- 測試連接容器中的 Mongodb
可視化工具連接
以上是 MongoDB 容器創建後的信息。接下來,我們使用 Robo 3T 圖形界面軟件嘗試打開數據庫。打開 RoBo 3T,選擇新建連接,按照下圖填入相關數據庫信息,保存。
★
注意其中的權限認證。連接數據庫時候可能失敗,會出現問題,這時候注意一個問題,安全組問題,需要把安全組中的27017的 Mongodb 數據庫端口打開
”
優雅部署方式 DockerCompose
Compose 是 Docker 官方開源的一個項目,可以管理多個 Docker 容器組成一個應用,例如 Web 服務,除了服務本身還有數據庫、Redis、Nginx 等一系列相關聯服務需要安裝。
有個 Compose 的支持,我們只需要定義一個 YAML 格式的配置文件(docker-compose.yml),來編寫一個項目所需要的多個容器配置及調用關係,通過簡單的命令即可同時開始或者關閉這些容器。Compose 定位是定義和運行多個 Docker 容器的應用。在這篇文章中不具體講 DockerCompose 使用,主要講清楚 Docker 基本架構各部分的應用,多實踐下哦!
Docker 帶來了什麼(優點)
- 環境隔離('隔離,安全')Docker 實現了資源隔離,一臺機器運行多個容器互無影響。
- 更高效的資源利用(節約成本)Docker 容器的運行不需要額外的虛擬化管理程序的支持,它是內核級的虛擬化,可以實現更高的性能,同時對資源的額外需求很低。
- 更快速的交付部署(敏捷)使用 Docker,開發人員可以利用鏡像快速構建一套標準的研發環境,開發完成後,測試和運維人員可以直接通過使用相同的環境來部署代碼。
- 更易遷移擴展( 可移植性)Docker 容器幾乎可以在任意的平臺上運行,包括虛擬機、公有云、私有云、個人電腦、服務器等,這種兼容性讓用戶可以在不同平臺之間輕鬆的遷移應用。
- 更簡單的更新管理(高效)使用 Dockerfile,只需要很少的配置修改,就可以替代以往大量的更新工作。並且所有修改都是以增量的方式進行分發和更新,從而實現自動化和高效的容器管理。
Docker的常用命令
鏡像常用命令
<code>docker pull [鏡像名稱:版本] 拉取鏡像
docker images 鏡像列表
docker rmi [鏡像名稱:版本] 刪除鏡像
docker history [鏡像名稱] 鏡像操作記錄
docker tag [鏡像名稱:版本][新鏡像名稱:新版本]
docker inspect [鏡像名稱:版本] 查看鏡像詳細
docker search [關鍵字] 搜索鏡像
docker login 鏡像登陸/<code>
容器常用命令
<code>docker ps -a 容器列表(所有容器)
docker ps 查看所有(運行的)容器
docker exec -tibash 以 bash 命令進入容器內 /<code>
docker run -ti --name [容器名稱][鏡像名稱:版本] bash 啟動容器並進入
docker logs 查看容器日誌
docker top <container> 查看容器最近的一個進程
docker run -ti --name [容器名稱] -p 8080:80 [鏡像名稱:版本] bash 端口映射
docker rm <container> 刪除容器
docker stop <container> 停止容器
docker start <container> 開啟容器
docker restart <container> 重啟容器
docker inspect <container> 查看容器詳情
docker commit [容器名稱] my_image:v1.0 容器提交為新的鏡像\t/<container>/<container>/<container>/<container>/<container>/<container>
DockerFile常用命令
在上面實戰中已經詳細講解,可以返回看,這裡就不再重複寫。
總結
讀完本文後,你應該掌握了 Docker 的基本使用,對 Docker 這個概念不那麼陌生了,並且知道了它的應用場景,可以自己實踐下,這個過程也會出現很多問題的,實踐才能更好的記住那些知識以及常用命令。
作者kaola
閱讀更多 開發者 的文章