本文你能學到什麼
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 部署 Node 項目完整流程(DockerFile實踐)
- 使用 Koa2 初始化一個 Node 項目,通過 Mongose 中間件 連接 Mogodb 數據庫,實現一個基礎接口 Mogodb 插入數據。 項目地址:github.com/koala-codin…
- 首先在項目根目錄下創建 .dockerignore 文件,把不需要打包進 Docker Image 裡的文件進行過濾
<code># /usr/src/nodejs/dockerstudy/.dockerignore.gitnode_modules/<code>
3.在項目的根目錄中創建 Dockerfile 文件(Dockerfile 這裡重點講一下)
部署 Node項目 的時候,會有一個 Dockerfile 文件配置
<code># /usr/src/nodejs/hello-docker/DockerfileFROM node:10.0# 在容器中創建一個目錄RUN mkdir -p /usr/src/nodejs/# 定位到容器的工作目錄WORKDIR /usr/src/nodejs/# RUN/COPY 是分層的,package.json 提前,只要沒修改,就不會重新安裝包COPY package.json /usr/src/app/package.jsonRUN cd /usr/src/app/RUN npm i# 把當前目錄下的所有文件拷貝到 Image 的 /usr/src/nodejs/ 目錄下COPY . /usr/src/nodejs/EXPOSE 3000CMD npm start/<code>
配置參數說明( 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 指令用來在啟動容器的時候,指定默認的容器主進程的啟動命令和參數。 它有兩種形式
<code>CMD echo 1CMD ["npm", "run", "test"] 必須是雙引號/<code>
<code>ENV<value>ENV <key1>=<value1> <key2>=<value2>.../<value2>/<key2>/<value1>/<key1>/<value> /<code>
4.代碼環節暫且告一段落,將帶有 Dockerfile 提交到 github 或 gitlab等。 以我的服務器 centos7 為例,已安裝好 Docker。
5.首先檢出代碼,把項目克隆到指定目錄
<code>git clone https://github.com/koala-coding/dockerstudy/<code>
6.進入目錄構建
<code>cd dockerstudy docker build -t dockerstudy . /<code>
build 命令用來製作鏡像,-t 是給鏡像打標籤,-f 參數是指定 Dockerfile 路徑,由於我們使用的是默認 Dockerfile 名稱,所以可以不同填寫該參數。最後一個.也不要省略,表示 Dockerfile 文件的所在目錄, 代表是當前路徑,它指定鏡像構建的上下文。我們剛才說過,真正製作鏡像的是 docker server,當我們執行 build 命令時,docker client 會將上下文路徑下的所有內容打包,然後上傳給 docker server。這樣當我們要在 Dockerfile 文件中執行 如 COPY 指令,就可以將上下文中的文件複製到鏡像中去了。
構建目標名稱 dockerstudy,是一個鏡像,可以通過 docker images 來列出所有的鏡像。
7.通過鏡像 dockerstudy 創建一個容器並運行。
<code>docker run --name dockerstudycontainer -d -p 3000:3000 dockerstudy /<code>
說明:創建的容器名稱是 dockerstudycontainer,你可以理解為 pid,這個名稱唯一,創建之後如果不刪除會一直存在。-p 用來指定端口映射,將容器的端口3000映射到主機3000`端口上,這樣就可外部訪問了。
此時在宿主機中可以使用curl測試服務器提供的服務是否正常
<code>curl localhost:3000/<code>
或者可以直接在瀏覽器中請求接口看一下輸出
創建容器後,有時候需要看一下容器資源佔用,使用docker stats
<code>docker stats dockerstudycontainer/<code>
如果是購買的阿里雲或者騰訊雲服務器,注意這裡將自己購買的 centos 服務器3000端口開放,在安全組
8.進入容器
<code>docker ls -a 查看所有容器,包括當前容器的iddocker exec -itbash /<code>
9.日誌檢查 查看運行日誌,“50425b8f2ef3” 為容器 ID
<code>$ docker logs -f 50425b8f2ef3/<code>
但是到了這裡我還有個問題,那我真想看日誌文件的時候,也不能每個容器進去看日誌,好浪費時間啊!有沒有什麼更高的方式?我會在下一篇文章《線上環境如何優雅的打印,保存,分析日誌》中寫到。
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 命令進入容器內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 容器提交為新的鏡像/<container>/<container>/<container>/<container>/<container>/<container> /<code>
DockerFile常用命令
在上面實戰中已經詳細講解,可以返回看,這裡就不再重複寫。
總結
讀完本文後,你應該掌握了 Docker 的基本使用,對 Docker 這個概念不那麼陌生了,並且知道了它的應用場景,可以自己實踐下,這個過程也會出現很多問題的,實踐才能更好的記住那些知識以及常用命令。
閱讀更多 Java領域佼佼者 的文章