【Docker】基本介紹
Docker - 基礎
Docker簡介
什麼是Docker
Docker 使用 Google 公司推出的 Go 語言 進行開發實現,基於 Linux 核心的 cgroup,namespace,以及 OverlayFS 類的 Union FS 等技術,對程序進行封裝隔離,屬於 作業系統層面的虛擬化技術。
Docker 在容器的基礎上,進行了進一步的封裝,從檔案系統、網路互聯到程序隔離等等,極大的簡化了容器的建立和維護。使得 Docker 技術比虛擬機器技術更為輕便、快捷。
為什麼使用Docker
作為一種新興的虛擬化方式,Docker 跟傳統的虛擬化方式相比具有眾多的優勢。
更高效的利用系統資源
由於容器不需要進行硬體虛擬以及執行完整作業系統等額外開銷,Docker 對系統資源的利用率更高。無論是應用執行速度、記憶體損耗或者檔案儲存速度,都要比傳統虛擬機器技術更高效。因此,相比虛擬機器技術,一個相同配置的主機,往往可以執行更多數量的應用。
更快速的啟動時間
傳統的虛擬機器技術啟動應用服務往往需要數分鐘,而 Docker 容器應用,由於直接運行於宿主核心,無需啟動完整的作業系統,因此可以做到秒級、甚至毫秒級的啟動時間。大大的節約了開發、測試、部署的時間。
一致的執行環境
開發過程中一個常見的問題是環境一致性問題。由於開發環境、測試環境、生產環境不一致,導致有些 bug 並未在開發過程中被發現。而 Docker 的映象提供了除核心外完整的執行時環境,確保了應用執行環境一致性,從而不會再出現 「這段程式碼在我機器上沒問題啊」 這類問題。
持續交付和部署
開發和運維(DevOps)人員來說,最希望的就是一次建立或配置,可以在任意地方正常執行。
使用 Docker 可以通過定製應用映象來實現持續整合、持續交付、部署。開發人員可以通過 Dockerfile 來進行映象構建,並結合 持續整合(Continuous Integration) 系統進行整合測試,而運維人員則可以直接在生產環境中快速部署該映象,甚至結合 持續部署(Continuous Delivery/Deployment) 系統進行自動部署。
而且使用 Dockerfile 使映象構建透明化,不僅僅開發團隊可以理解應用執行環境,也方便運維團隊理解應用執行所需條件,幫助更好的生產環境中部署該映象。
更輕鬆的遷移
由於 Docker 確保了執行環境的一致性,使得應用的遷移更加容易。Docker 可以在很多平臺上執行,無論是物理機、虛擬機器、公有云、私有云,甚至是筆記本,其執行結果是一致的。因此使用者可以很輕易的將在一個平臺上執行的應用,遷移到另一個平臺上,而不用擔心執行環境的變化導致應用無法正常執行的情況。
更輕鬆的維護和擴充套件
Docker 使用的分層儲存以及映象的技術,使得應用重複部分的複用更為容易,也使得應用的維護更新更加簡單,基於基礎映象進一步擴充套件映象也變得非常簡單。此外,Docker 團隊同各個開源專案團隊一起維護了一大批高質量的 官方映象,既可以直接在生產環境使用,又可以作為基礎進一步定製,大大的降低了應用服務的映象製作成本。
對比傳統虛擬機器總結
虛擬機器 VS 容器
特性 | 容器 | 虛擬機器 |
---|---|---|
啟動 | 秒級 | 分鐘級 |
硬碟使用 | 一般為 MB | 一般為 GB |
效能 | 接近原生 | 弱於 |
系統支援量 | 單機支援上千個容器 | 一般幾十個 |
Docker基本概念
映象
作業系統分為 核心 和 使用者空間 對於 Linux 而言,核心啟動後,會掛載 root 檔案系統為其提供使用者空間支援。而 Docker 映象(Image),就相當於是一個 root 檔案系統。比如官方映象 ubuntu:18.04 就包含了完整的一套 Ubuntu 18.04 最小系統的 root 檔案系統
Docker 映象 是一個特殊的檔案系統,除了提供容器執行時所需的程式、庫、資源、配置等檔案外,還包含了一些為執行時準備的一些配置引數(如匿名卷、環境變數、使用者等)
相關命令
docker image ls # 列出映象
docker image build # 根據Dockerfile檔案建立映象
docker image history <image> # 列出映象歷史
docker image import # 從檔案/目錄匯入生成映象
docker image inspect <image> # 顯示映象詳情
docker image pull <image> # 從遠端倉庫拉取映象
docker image push <image> # 推送映象到遠端倉庫
docker image rm <image> # 刪除映象
docker image save <image> -o <path> # 儲存映象到檔案
docker image tag <image> <image>:<tag> # 映象打標籤
Dockerfile 指令詳解
Dockerfile 是一個文字檔案,其內包含了一條條的 指令(Instruction),每一條指令構建一層,因此每一條指令的內容,就是描述該層應當如何構建
指令 | 作用 | 說明 |
---|---|---|
FROM | 指定基礎映象 | FROM 是必備的指令,並且必須是第一條指令 |
COPY | 複製檔案 | 兩種格式,一種類似於命令列,一種類似於函式呼叫 |
ADD | 更高階的複製檔案 | 在COPY基礎上增加自動解壓縮的場合 |
RUN | 執行命令 | 映象構建步驟 |
CMD | 容器啟動命令 | 容器預設執行的命令 |
ENTRYPOINT | 入口點 | 容器啟動程式及引數 |
ENV | 設定環境變數 | 定義了環境變數,那麼在後續的指令中,就可以使用這個環境變數 |
ARG | 構建引數 | ARG 所設定的構建環境的環境變數,在將來容器執行時是不會存在這些環境變數的 |
VOLUME | 定義匿名卷 | 對於資料庫類需要儲存動態資料的應用,其資料庫檔案應該保存於卷(volume) |
EXPOSE | 暴露埠 | 宣告容器執行時提供服務的埠 |
WORKDIR | 指定工作目錄 | 指定當前目錄,如該目錄不存在,WORKDIR 會幫你建立目錄 |
USER | 指定當前使用者 | 這個使用者必須是事先建立好的,否則無法切換 |
HEALTHCHECK | 健康檢查 | 告訴 Docker 應該如何進行判斷容器的狀態是否正常 |
ONBUILD | 為構建下一層映象準備 | 構建下一級映象的時候才會被執行 |
LABEL | 映象新增元資料 | 指令用來給映象以鍵值對的形式新增一些元資料(metadata) |
SHELL | 指令 | SHELL 指令可以指定 RUN ENTRYPOINT CMD 指令的 shell,Linux 中預設為 |
映象構建上下文
當構建的時候,使用者會指定構建映象上下文的路徑,docker build 命令得知這個路徑後,會將路徑下的所有內容打包,然後上傳給 Docker 引擎。這樣 Docker 引擎收到這個上下文包後,展開就會獲得構建映象所需的一切檔案
容器
映象(Image)和容器(Container)的關係,就像是面向物件程式設計中的 類 和 例項 一樣,映象是靜態的定義,容器是映象執行時的實體。容器可以被建立、啟動、停止、刪除、暫停等。
容器的實質是程序,但與直接在宿主執行的程序不同,容器程序運行於屬於自己的獨立的 名稱空間
容器儲存層的生存週期和容器一樣,容器消亡時,容器儲存層也隨之消亡。因此,任何保存於容器儲存層的資訊都會隨容器刪除而丟失。
按照 Docker 最佳實踐的要求,容器不應該向其儲存層內寫入任何資料,容器儲存層要保持無狀態化。所有的檔案寫入操作,都應該使用 資料卷(Volume)、或者 繫結宿主目錄,在這些位置的讀寫會跳過容器儲存層,直接對宿主(或網路儲存)發生讀寫,其效能和穩定性更高。
相關命令
docker run # 構建並啟動映象
docker run -t -i ubuntu:18.04 /bin/bash # 啟動一個 bash 終端,允許互動
docker run -d ubuntu:18.04 # 後臺執行容器
docker container start <container> # 重啟已經停止容器
docker container stop <container> # 終止容器
docker attach <container> # 附加到容器中,執行exit導致容器推出
docker exec -it <container> bash # 進入容器, 執行exit不會容器推出(推薦)
docker export <container> > ubuntu.tar # 匯出映象
cat ubuntu.tar | docker import - ubuntu:v1.0 # 匯入容器快照
docker container rm <container> # 刪除一個處於終止狀態的容器
docker container prune # 清理所有處於終止狀態的容器
倉庫
映象構建完成後,可以很容易的在當前宿主機上執行,但是,如果需要在其它伺服器上使用這個映象,我們就需要一個集中的儲存、分發映象的服務,Docker Registry 就是這樣的服務。
一個 Docker Registry 中可以包含多個 倉庫(Repository);每個倉庫可以包含多個 標籤(Tag);每個標籤對應一個映象。
相關命令
docker search centos # 搜尋倉庫
docker pull centos # 拉取映象
docker push username/ubuntu:18.04 # 推送映象