INTRODUCTION TO
Chris Chen
OUTLINE
 About Docker
 Docker command
 Customized Docker Image
VIRTUALIZATION : HYPERVISORVS. CONTAINER
ABOUT DOCKER
 2013 年初,最初是 dotCloud 公司內部的一個業餘專案,是一個集打包、運送和使用
容器技術來執行應用程式。它基於 Google 公司推出的 Go 語言實作。 專案後來加入了
Linux 基金會,遵從了 Apache 2.0 協議,
 Docker 專案的目標是實作輕量級的作業系統虛擬化解決方案。 Docker 的基礎是 Linux
容器(LXC)等技術。使用者不需要去關心容器的管理,使得操作更為簡便。使用者操
作 Docker 的容器就像操作一個快速輕量級的虛擬機一樣簡單
 簡化移交作業流程、免除重建基礎建設工程、讓開發、測試和正式環境可以無縫接軌
IMAGE (映像檔/鏡像)
 將應用程式&執行環境進行包裝產生可佈署的
『Image』
 Docker Image就是一個唯讀的模板,每個模版都
是一個完整執行環境
 Docker 提供了一個很簡單的機制來建立Image或
者更新現有的Image ,使用者甚至可以直接從其
他人那裡下載一個已經做好的Image來直接使用。
CONTAINER(容器)
 Container是從Image建立的執行實例。它可以被啟動、開始、停止、刪除。每個容器
都是相互隔離的、保證安全的平台。
 Container可視為一個簡易版的 Linux 環境(包括root使用者權限、程式空間、使用者
空間和網路空間等)和在其中執行的應用程式。
 Image是唯讀的, 但啟動Container的時候會建立一層可寫層作為最上層
 每一個 Container都有一個唯一的 CONTAINER ID,不指定就會亂數產生
 當容器被刪除後,再次啟動時又是一個乾淨的環境
DOCKER REGISTRIES
• 用來存放images的倉庫,執行docker pull
時,Docker 會從指定的registry 將image
下載下來
• 預設的registries是Docker hub,也可建立
私有的Registry
Image Image
Container Container
Docker Registry
Pull
Run Commit
Push
DOCKER CLIENT/SERVER ARCHITECTURE
DOCKER優點
 不可變的(immutable)
 因為作業系統、函式庫(library)版本、設定、資料夾、應用程式都被包裝在 Container 裡頭,
所以能確保相同的 Image,在 QA 的測試下與正式環境中,都會擁有同樣的行為
 輕量的
 Container 只使用少量的記憶體。不再需要耗費成千上百 MB 的記憶體,Container 只會使用
主程序所需的用量,再多加上數十 MB 的記憶體而已
 快速的
 在幾秒內就啟動一個全新的 Container 。
DOCKER安全性問題
 Docker安全性疑慮?
 共用作業系統核心
 不明來源的容器安全性?
 Docker利用Linux Kernel機制,加強安全性
 namespace就可以保護各別Container的隱私,防止被人探查。
 cgroup則是控制系統所使用的資源分配,像是儲存、CPU、硬碟I/O,以及設備權限
 若Container使用root權限來執行時,將可能發生許多危險,可以利用Capabilities機制,將
root權限進行拆分。
 一旦Container可以任意呼叫Linux Kernel也會存在許多危險,可利用Linux Kernel內建的安全
運算模式(Secure Computing Mode),禁止不需要的系統呼叫權限。
DOCKER COMMAND
Command Line才能完整發揮Docker的操作
取得IMAGE(PULL)
列出本機所有(IMAGES)
新建並啟動容器(RUN)
Docker run 參數 說明
-d 背景執行Container
-i 以交互模式運行Container,通常與 -t 同時使用;
-t 為Container重新分配一个輸入端,通常與 -i 同时使用;
-name 為Container指定一个名稱,不指定名稱會自動亂數命名
-p Port Mapping,主機的目錄映射到容器裡
-v 掛載本地目錄至Container使用
VOLUME FOR STATE DATA
 多個容器可以共享單一volume。
 容器volume可以對應到實體機器FS路徑位置。
 若有持续更新的数据需要在容器之间共享 (--volumes-from)
 image產生時可以定義內部路徑位置的volume,並由另一個容器啟動時mount上去使用。
查看容器行程(PS)
容器啟動(START)與終止(STOP)
 終止容器(Stop)
 docker stop [OPTIONS] CONTAINER [CONTAINER...]
 支持「優雅退出」。先發送SIGTERM信號,在一段時間之後(10s)再發送SIGKILL信號。
Docker內部的應用程式可以接收SIGTERM信號,然後做一些退出前工作,比如保存狀態、處
理當前請求等。
 啟用容器(Start)
 docker start [OPTIONS] CONTAINER [CONTAINER...]
 docker run就是docker create和docker start两个命令的组合
進入容器(EXEC)
提交IMAGE (COMMIT)
移除IMAGE和TAG (RMI)
移除容器(RM)
建立DOCKER IMAGE的方法
 在現有的Docker Image Commit 現有的變更,成為一個新的image
 使用 Dockerfile 讓使用者可以建立自定義的映像檔。
COMMIT CHANGE FORM DOCKER IMAGE
指令:docker commit {container ID} {repository_name:tag}
docker commit {docker id} chris/debian:1.0
docker run -it chris/debain:1.0
docker run -it debain:jessie
apt-get update && apt-get install -y git
Terminal A Terminal B
說明:下載debian的image,並安裝git 說明:將TerminalA目前執行的container
commit 成新的image chris/debian:1.0
BUILD A DOCKERFILE
 Dockerfile是一個純文字檔,且預設的檔案名稱就是Dockerfile (無副檔名)
 由許多的指令(Instructions)組成,每一個指令都在描述在Image中該做什麼
 每執行一個指令就會在Image中建立一個新的Layer,如果下一次,指令沒有改變,
Docker就會從再次使用現有的Layer
 Dockerfile 分為四部分:基底映像檔資訊、維護者資訊、映像檔操作指令和容器啟動時
執行指令
INSTRUCTIONS (1/3)
 FROM
 格式為 FROM <image>或FROM <image>:<tag>。
 第一條指令必須為 FROM 指令
 MAINTAINER
 格式為 MAINTAINER <name>,指定維護者訊息
 RUN
 格式為 RUN <command> 或 RUN ["executable", "param1", "param2"]。
 每條 RUN 指令將在當前映像檔基底上執行指定命令,並產生新的映像檔。當命令較長時可以
使用  來換行。
INSTRUCTIONS (2/3)
 CMD
 指定啟動容器時執行的命令,每個 Dockerfile 只能有一條 CMD 命令。如果指定了多條命令,
只有最後一條會被執行。
 如果使用者啟動容器時候指定了運行的命令,則會覆蓋掉 CMD 指定的命令。
 ADD
 格式為 ADD <src> <dest>。
 該命令將複製指定的 <src> 到容器中的 <dest>。 其中 <src> 可以是 Dockerfile 所在目錄的
相對路徑;也可以是一個 URL;還可以是一個 tar 檔案,複製後會自動解壓縮。
 COPY
 格式為 COPY <src> <dest>。
 複製本地端的 <src>(為 Dockerfile 所在目錄的相對路徑)到容器中的 <dest>。
 當使用本地目錄為根目錄時,推薦使用 COPY。
INSTRUCTIONS (3/3)
 VOLUME
 格式為 VOLUME ["/data"]。
 建立一個可以從本地端或其他容器掛載的掛載點,一般用來存放資料庫和需要保存的資料等
 WORKDIR
 格式為 WORKDIR /path/to/workdir。
 為後續的 RUN、CMD、ENTRYPOINT 指令指定工作目錄。
 USER
 執行RUN命令執行時的用戶
 ENV
 設置環境變數
BUILD A DOCKERFILE
 編輯完成 Dockerfile 之後,可以透過 docker build 命令建立映像檔。
 基本的格式為 docekr build [選項] 路徑,該命令將讀取指定路徑下(包括子目錄)的
Dockerfile,要指定映像檔的標籤資訊,可以透過 -t 選項
 Ex. docker build -t bq/XXX:0.2 .
 從映像檔產生 Dockerfile
 dockerfile-from-image 工具,以逆向工程建立出 Dockerfile 。
 類似 docker history 指令,透過映像檔每一層的 metadata 來重建出那 Dockerfile
DOCKER CONTAINER應避免的10件事
 不要在 Container 裡儲存資料(data)
 Container 是可以被停止、摧毀、或是取代的,真的需要儲存資料,請存在 volume
 不要將應用程式分兩部份搬移
 不要建立大型的 Image
 一個大型的 Image 只會讓它難以被散佈。確認只放置必須的應用所需的檔案和函式庫
 不要使用單層式的 Image
 應用程式應各獨立建置一層。在 Image 的重建和管理更加簡易,並易於散佈。
 不要用執行中的 Container 建立 Image
 用docker commit建立 的Image是難以重現異動
DOCKER CONTAINER 應避免的10件事
 不要只使用latest標籤
 譬如base image被一個無法向下相容的新版本給取代
 避免使用在正式環境下部署 Container,因為不能追蹤 Container 是跑哪一個 Image 版本
 不要在一個 Container 跑超過一個程序
 執行超過一個程序,可能會在管理、讀取紀錄或獨立更新上都感到棘手
 不要在 Image 儲存憑証,請使用環境變數
 不要將使用者名稱或是密碼hard-code在 Image 中。請使用環境變數從 Container 外面取得這些資
訊
 使用非 root 的使用者去執行程序
 Image 應該使用 USER 指令去指定非 root 的使用者讓 container 執行
 不要相依 IP 位址
 每個 Container 都擁有他們自己內部的 IP 位址,可能會在啟動或停止 Container 時被改變
Q&A

Introduction to Docker

  • 1.
  • 2.
    OUTLINE  About Docker Docker command  Customized Docker Image
  • 3.
  • 5.
    ABOUT DOCKER  2013年初,最初是 dotCloud 公司內部的一個業餘專案,是一個集打包、運送和使用 容器技術來執行應用程式。它基於 Google 公司推出的 Go 語言實作。 專案後來加入了 Linux 基金會,遵從了 Apache 2.0 協議,  Docker 專案的目標是實作輕量級的作業系統虛擬化解決方案。 Docker 的基礎是 Linux 容器(LXC)等技術。使用者不需要去關心容器的管理,使得操作更為簡便。使用者操 作 Docker 的容器就像操作一個快速輕量級的虛擬機一樣簡單  簡化移交作業流程、免除重建基礎建設工程、讓開發、測試和正式環境可以無縫接軌
  • 6.
    IMAGE (映像檔/鏡像)  將應用程式&執行環境進行包裝產生可佈署的 『Image』 Docker Image就是一個唯讀的模板,每個模版都 是一個完整執行環境  Docker 提供了一個很簡單的機制來建立Image或 者更新現有的Image ,使用者甚至可以直接從其 他人那裡下載一個已經做好的Image來直接使用。
  • 7.
    CONTAINER(容器)  Container是從Image建立的執行實例。它可以被啟動、開始、停止、刪除。每個容器 都是相互隔離的、保證安全的平台。  Container可視為一個簡易版的Linux 環境(包括root使用者權限、程式空間、使用者 空間和網路空間等)和在其中執行的應用程式。  Image是唯讀的, 但啟動Container的時候會建立一層可寫層作為最上層  每一個 Container都有一個唯一的 CONTAINER ID,不指定就會亂數產生  當容器被刪除後,再次啟動時又是一個乾淨的環境
  • 8.
    DOCKER REGISTRIES • 用來存放images的倉庫,執行dockerpull 時,Docker 會從指定的registry 將image 下載下來 • 預設的registries是Docker hub,也可建立 私有的Registry Image Image Container Container Docker Registry Pull Run Commit Push
  • 9.
  • 11.
    DOCKER優點  不可變的(immutable)  因為作業系統、函式庫(library)版本、設定、資料夾、應用程式都被包裝在Container 裡頭, 所以能確保相同的 Image,在 QA 的測試下與正式環境中,都會擁有同樣的行為  輕量的  Container 只使用少量的記憶體。不再需要耗費成千上百 MB 的記憶體,Container 只會使用 主程序所需的用量,再多加上數十 MB 的記憶體而已  快速的  在幾秒內就啟動一個全新的 Container 。
  • 12.
    DOCKER安全性問題  Docker安全性疑慮?  共用作業系統核心 不明來源的容器安全性?  Docker利用Linux Kernel機制,加強安全性  namespace就可以保護各別Container的隱私,防止被人探查。  cgroup則是控制系統所使用的資源分配,像是儲存、CPU、硬碟I/O,以及設備權限  若Container使用root權限來執行時,將可能發生許多危險,可以利用Capabilities機制,將 root權限進行拆分。  一旦Container可以任意呼叫Linux Kernel也會存在許多危險,可利用Linux Kernel內建的安全 運算模式(Secure Computing Mode),禁止不需要的系統呼叫權限。
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
    Docker run 參數說明 -d 背景執行Container -i 以交互模式運行Container,通常與 -t 同時使用; -t 為Container重新分配一个輸入端,通常與 -i 同时使用; -name 為Container指定一个名稱,不指定名稱會自動亂數命名 -p Port Mapping,主機的目錄映射到容器裡 -v 掛載本地目錄至Container使用
  • 18.
    VOLUME FOR STATEDATA  多個容器可以共享單一volume。  容器volume可以對應到實體機器FS路徑位置。  若有持续更新的数据需要在容器之间共享 (--volumes-from)  image產生時可以定義內部路徑位置的volume,並由另一個容器啟動時mount上去使用。
  • 19.
  • 20.
    容器啟動(START)與終止(STOP)  終止容器(Stop)  dockerstop [OPTIONS] CONTAINER [CONTAINER...]  支持「優雅退出」。先發送SIGTERM信號,在一段時間之後(10s)再發送SIGKILL信號。 Docker內部的應用程式可以接收SIGTERM信號,然後做一些退出前工作,比如保存狀態、處 理當前請求等。  啟用容器(Start)  docker start [OPTIONS] CONTAINER [CONTAINER...]  docker run就是docker create和docker start两个命令的组合
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
    建立DOCKER IMAGE的方法  在現有的DockerImage Commit 現有的變更,成為一個新的image  使用 Dockerfile 讓使用者可以建立自定義的映像檔。
  • 26.
    COMMIT CHANGE FORMDOCKER IMAGE 指令:docker commit {container ID} {repository_name:tag} docker commit {docker id} chris/debian:1.0 docker run -it chris/debain:1.0 docker run -it debain:jessie apt-get update && apt-get install -y git Terminal A Terminal B 說明:下載debian的image,並安裝git 說明:將TerminalA目前執行的container commit 成新的image chris/debian:1.0
  • 27.
    BUILD A DOCKERFILE Dockerfile是一個純文字檔,且預設的檔案名稱就是Dockerfile (無副檔名)  由許多的指令(Instructions)組成,每一個指令都在描述在Image中該做什麼  每執行一個指令就會在Image中建立一個新的Layer,如果下一次,指令沒有改變, Docker就會從再次使用現有的Layer  Dockerfile 分為四部分:基底映像檔資訊、維護者資訊、映像檔操作指令和容器啟動時 執行指令
  • 29.
    INSTRUCTIONS (1/3)  FROM 格式為 FROM <image>或FROM <image>:<tag>。  第一條指令必須為 FROM 指令  MAINTAINER  格式為 MAINTAINER <name>,指定維護者訊息  RUN  格式為 RUN <command> 或 RUN ["executable", "param1", "param2"]。  每條 RUN 指令將在當前映像檔基底上執行指定命令,並產生新的映像檔。當命令較長時可以 使用 來換行。
  • 30.
    INSTRUCTIONS (2/3)  CMD 指定啟動容器時執行的命令,每個 Dockerfile 只能有一條 CMD 命令。如果指定了多條命令, 只有最後一條會被執行。  如果使用者啟動容器時候指定了運行的命令,則會覆蓋掉 CMD 指定的命令。  ADD  格式為 ADD <src> <dest>。  該命令將複製指定的 <src> 到容器中的 <dest>。 其中 <src> 可以是 Dockerfile 所在目錄的 相對路徑;也可以是一個 URL;還可以是一個 tar 檔案,複製後會自動解壓縮。  COPY  格式為 COPY <src> <dest>。  複製本地端的 <src>(為 Dockerfile 所在目錄的相對路徑)到容器中的 <dest>。  當使用本地目錄為根目錄時,推薦使用 COPY。
  • 31.
    INSTRUCTIONS (3/3)  VOLUME 格式為 VOLUME ["/data"]。  建立一個可以從本地端或其他容器掛載的掛載點,一般用來存放資料庫和需要保存的資料等  WORKDIR  格式為 WORKDIR /path/to/workdir。  為後續的 RUN、CMD、ENTRYPOINT 指令指定工作目錄。  USER  執行RUN命令執行時的用戶  ENV  設置環境變數
  • 32.
    BUILD A DOCKERFILE 編輯完成 Dockerfile 之後,可以透過 docker build 命令建立映像檔。  基本的格式為 docekr build [選項] 路徑,該命令將讀取指定路徑下(包括子目錄)的 Dockerfile,要指定映像檔的標籤資訊,可以透過 -t 選項  Ex. docker build -t bq/XXX:0.2 .  從映像檔產生 Dockerfile  dockerfile-from-image 工具,以逆向工程建立出 Dockerfile 。  類似 docker history 指令,透過映像檔每一層的 metadata 來重建出那 Dockerfile
  • 33.
    DOCKER CONTAINER應避免的10件事  不要在Container 裡儲存資料(data)  Container 是可以被停止、摧毀、或是取代的,真的需要儲存資料,請存在 volume  不要將應用程式分兩部份搬移  不要建立大型的 Image  一個大型的 Image 只會讓它難以被散佈。確認只放置必須的應用所需的檔案和函式庫  不要使用單層式的 Image  應用程式應各獨立建置一層。在 Image 的重建和管理更加簡易,並易於散佈。  不要用執行中的 Container 建立 Image  用docker commit建立 的Image是難以重現異動
  • 34.
    DOCKER CONTAINER 應避免的10件事 不要只使用latest標籤  譬如base image被一個無法向下相容的新版本給取代  避免使用在正式環境下部署 Container,因為不能追蹤 Container 是跑哪一個 Image 版本  不要在一個 Container 跑超過一個程序  執行超過一個程序,可能會在管理、讀取紀錄或獨立更新上都感到棘手  不要在 Image 儲存憑証,請使用環境變數  不要將使用者名稱或是密碼hard-code在 Image 中。請使用環境變數從 Container 外面取得這些資 訊  使用非 root 的使用者去執行程序  Image 應該使用 USER 指令去指定非 root 的使用者讓 container 執行  不要相依 IP 位址  每個 Container 都擁有他們自己內部的 IP 位址,可能會在啟動或停止 Container 時被改變
  • 35.

Editor's Notes

  • #4 傳統虛擬化技術從作業系統層下手,目標是建立一個可以用來執行整套作業系統的沙箱獨立執行環境,習慣以虛擬機器(Virtual Machine)來稱呼。而Container技術則是直接將一個應用程式所需的相關程式碼、函式庫、環境配置檔都打包起來建立沙箱執行環境,為了和傳統虛擬化技術產生的虛擬機器區分,Container技術產生的環境就稱為Container。 最明顯的差別是,虛擬機器需要安裝作業系統(安裝Guest OS)才能執行應用程式,而Container內不需要安裝作業系統就能執行應用程式。Container技術不是在OS外來建立虛擬環境,而是在OS內的核心系統層來打造虛擬執行環境,透過共用Host OS的作法,取代一個一個Guest OS的功用。Container也因此被稱為是OS層的虛擬化技術。 因為Container技術採取共用Host OS的作法,而不需在每一個Container內執行Guest OS,因此建立Container不需要等待作業系統開機時間,不用1分鐘或幾秒鐘就可以啟用,遠比需要數分鐘甚至數十分鐘才能開啟的傳統虛擬機器來的快。 早在1982年,Unix系統內建的chroot機制也是一種Container技術。其他如1998年的FreeBSD jails、2005年出現的Solaris Zones和OpenVZ,或像是Windows系統2004年就有的Sandboxie機制都屬於在作業系統內建立孤立虛擬執行環境的作法,都可稱為是Container的技術。 直到2013年,dotCloud這家PaaS服務公司開源釋出了一套將Container標準化的平臺Docker,大受歡迎,所以,dotCloud決定以Docker為名成立新公司力推。
  • #5 Docker 提供應用程式在獨立的 container 中執行,這些 container 並不需要像虛擬化一樣額外依附在 hypervisor 或 guest OS 上,是透過 Docker Engine 來進行管理。 Docker是一个开发的平台,用来为开发者和系统管理员构建、发布和运行分布式应用。”也就是说,如果把你的应用比喻为货物,那么码头工人(Docker)就会迅速的用集装箱将它们装上船。快速、简单而有效率
  • #7 映像檔(Image):定義貨櫃內的存放的物品,會有不同名稱作為識別。 Docker映象檔是一種分層堆疊的運作方式,要建立一個可提供應用程式完整執行環境的Container映象檔,要先從一個基礎映象檔(Base Image)開始疊起,一層層將不同Stack的Docker映象檔疊加上去,最後組合成一個應用程式所需Container執行環境的映象檔,而每一個Stack也都是可以會匯出成(Docker commit指令)一個映象檔
  • #8 Docker Containers Docker Containers 提供獨立、安全的環境給應用程式執行,container 是從 Docker image 建立,運行在主機上。 容器(Container):是指從映像檔拿來執行後就會變成放在容器內執行的實體,每個容器都會有一個獨一無二的Name(可指定不然就亂數隨機產生),方便對他做操作。
  • #9 Docker Registries 將 Docker images 上傳、下載到公開或私有的 Docker Registries 上,與其他人分享,公開的像 Docker Hub 提供了許多不同的 images ,如:Ubuntu 或 Ubuntu 環境下安裝 Ruby on Rails 的 images ,只要下載來,就能直接開啟成 container。
  • #10 Docker是一個Client-Server架構的應用程式,在一個Docker執行環境中,包括了Docker用戶端程式、和在背景執行(Daemon)的Docker伺服器(也稱為Docker Engine),另外還有將Container封裝後的Docker映象檔,用來儲存映象檔的Registry服務。官方提供的映象檔Registry服務就稱為Docker Hub,這是類似Github程式碼Repository儲存服務的映象檔Repository儲存服務。 安裝Docker之後,會提供了一個命令列的用戶端程式來和在背景執行的Docker伺服器溝通。開發者可以直接從Docker Hub下載Docker映象檔(Docker pull指令),再執行(Docker run指令)就可以用這個映象檔來建立一個Container。
  • #13 http://www.ithome.com.tw/news/109876 Docker安全發展總共可歸納為四大面向,第一是資料通訊安全,包含客戶端至Docker引擎,以及Docker引擎至儲存庫間傳輸映像檔的安全考量。第二則是映像檔本身的安全性,透過縮小尺寸提升其安全性。 再者是Docker Container的安全,孫宏亮企業業務系統都掛載於映像檔,但是仍然是透過Container交付服務,「如果容器出現問題,整個企業就無法正常運作。」 最後則是網路安全,他解釋,許多企業在使用Docker前,就已經對於內部資料中心網路架構有所規畫,如果選擇導入Docker,其架構勢必得要進行調整,「這時網路安全就變成重要議題。」
  • #20 若這個Container已經執行完畢,因此用docker ps是無法看到。此時要加-a參數,列出所有的Container,包括已經執行結束的(即死掉的Container)。 docker ps -a
  • #30 RUN在Dockerfile构建镜像的过程(Build)中运行,最终被commit的到镜像。 ENTRYPOINT和CMD在容器运行(run、start)时运行。
  • #31 ADD:URL下载和解压特性不能一起使用。任何压缩文件通过URL拷贝,都不会自动解压 COPY是ADD的一种简化版本,目的在于满足大多数人“复制文件到容器”的需求。 假如目前还不明显的话,那Docker 团队的建议是在大多数情况下使用COPY。真的,使用ADD的唯一原因就是你有一个压缩文件,你想自动解压到镜像中
  • #34 https://blog.fntsr.tw/articles/2016/03/06/10-things-to-avoid-in-docker-containers/