Docker:使用教程
docker 即容器
一些概念
Docker Registry
Docker 遠端映象倉庫
-
DockerHub
-
DaoCloud / Aliyun
Docker Images
Docker Images
是用來建立 docker 容器的只讀模版,其中包含了容器啟動所需要的所有配置資訊和執行程式,一次構建之後可以多次複用。
從結構上來講, Docker Image
是分層次的,如圖所示:
這樣就自然出現了父映象和基礎映象的概念,在圖中,每一個上層映象都是依賴於下一層的映象,所以下層映象可稱為上層映象的父映象,而最底層的映象是沒有父映象的,可稱其為基礎映象(Base Image)。
實際場景下,一般我們自己建立的映象都會依賴於某個 Linux
作業系統的映象,例如 ubuntu
,大多數情況下,我們可稱其為基礎映象,但是我們也可以檢視 ubuntu
映象的 Dockerfile
會發現,它也是依賴於一個叫 scratch
的映象, scratch
是 docker
的一個空映象,裡面只有 docker
加入的一些元資料,如果我們想要追求自己的映象儘可能的輕量,也可以將 scratch
映象作為我們的基礎映象來構建。
Dockerfile
Dockerfile
是用來說明如何自動構建 docker image
的指令集檔案,在 Dockerfile
中編寫好指令集之後,我們就可以通過 docker build
命令構建映象, Dockerfile
檔案中命令的順序就是構建過程中執行的順序。
以下為幾個常用的指令:
1. FROM:依賴映象
所有 Dockerfile
都必須以 FROM
命令開始,表示其依賴的映象。
FROM image_name
2. MAINTAINER:映象作者資訊
MAINTAINER author <author_email>
3. RUN:在shell或者exec的環境下執行的命令
RUN <command>
4. ADD:將主機檔案複製到容器中
ADD /path/to/sourcefile/in/host /path/to/targetfile/in/container
5. CMD:指定容器啟動預設執行的命令
CMD ["executable","param1","param2"]
6. EXPOSE:指定容器在執行時監聽的埠
EXPOSE <port>
7. WORKDIR:指定 RUN
、 CMD
與 ENTRYPOINT
命令的工作目錄
WORKDIR /path/to/workdir/in/container
8. VOLUME:授權訪問從容器內到主機上的目錄
VOLUME ["/data"]
關於 Dockerfile
編寫有以下幾點需要注意:
-
儘量不要省略
MAINTAINER
資訊。 -
EXPOSE
的埠不使用公有埠。 -
CMD
與ENTRYPOINT
命令使用陣列語法。
另外,在國內使用 docker
(以 ubuntu 為例), Dockerfile
第一個執行的命令最好為(具體原因你猜):
RUN sed -i 's/archive.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list \ && apt-get update --fix-missing \ && apt-get -y upgrade
Docker Container
Docker Container
中包含了我們的應用程式碼和程式碼執行的環境,是用來打包分發程式碼的單元。
構建映象
首先要編寫 Dockerfile
,在檔案中寫入構建映象需要的指令集,然後執行下面命令:
docker build {image_name} {/path/to/Dockerfile}
例如,我們構建一個 mysql
的映象,先編寫 Dockerfile
FROM ubuntu:14.04 MAINTAINER Tairy <tairyguo@gmail.com> # Install Base. RUN \ sed -i 's/archive.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list && \ apt-get update && \ apt-get -y upgrade && \ apt-get install -y build-essential && \ apt-get install -y software-properties-common && \ apt-get install -y byobu curl git htop man unzip vim wget RUN apt-get -y install mysql-server EXPOSE 3306 CMD ["mysqld"]
執行
docker build -t mysql ./
構建工具將先在本地查詢 ubuntu:14.04
的映象,如果有,則直接依賴使用,如果沒有,將去遠端的倉庫中下載官方構建的 ubuntu:14.04
的映象,當然因為一些不可描述的原因,這個下載過程成功率不大,而且非常耗時,所以我們可以做如下優化:
docker pull daocloud.io/library/ubuntu:wily-20160706
然後將 Dockerfile
中 FROM
命令修改為:
# 我註冊了daocloud 賬號,就使用 daocloud 的映象,也可以選擇使用阿里雲的映象。 FROM daocloud.io/library/ubuntu:wily-20160706
這樣,就節省了很多的時間。
總之,在安裝環境的過程中,因為某個偉大的防火牆工程,我們需要的大部分資源都沒法順利的獲取到,解決辦法就是將下載的源換成國內某些廠商提供的映象源。(推薦阿里雲,畢竟有錢,穩定。)
經過一段時間的自動構建,便可生成一個可用的 mysql
映象,使用 docker images
命令檢視構建好的映象列表,輸出:
REPOSITORYTAGIMAGE IDCREATEDSIZE mysqllatestffe5a4341fee1 days ago1.009 GB
刪除一個映象,使用下面命令:
# -f 表示強制刪除,慎重使用 docker rmi -f image_name
建立容器
有了基礎的映象模板之後,就可以建立容器來執行應用程式碼,具體用到 run
命令:
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
例如我們要建立一個執行 mysql 的容器,可以執行
docker run -d --name db1 -v `pwd`:/data:rw -p 8001:3306 mysql
這條命令將建立後臺執行的 mysql 容器,裡面執行一個 mysql 伺服器,可以使用 docker ps
命令檢視啟動的容器。
-
-d 引數表示後臺守護程序執行容器。
-
--name 引數表示容器的名稱,可隨意取。
-
-v 表示主機和容器共享檔案的對映,容器的目錄就是 Dockerfile 中用 VOLUME 命令定義的目錄。
-
-p 表器主機和容器埠對映,容器的埠就是 Dockerfile 中用 EXPOSE 命令繫結的埠。
關於建立容器的時候的坑:
一般來說,我們會在 Dockerfile
中的最後用 CMD 命令定義容器啟動之後執行的命令,但是如果我們定義的命令執行報錯或者命令沒有建立一個守護程序的話, docker ps
之後是看不到容器在執行的,此時可以使用 docker l ogs
命令檢視容器啟動的日誌,進行排錯。
當然,我們也可以在 run 的時候定義容器啟動的命令,例如下面命令將啟動一個 ubuntu 的容器,並執行 /bin/bash
程式,進入 ubuntu 的 terminal:
docker run -it ubuntu:14.04 /bin/bash
此命令成功的標誌就是你會發現命令列變成了類似:
root@d71ff8587917:/#
說明現在已經進入了 ubuntu
的容器中,可以直接在此命令列中操作 ubuntu
,或者輸入 exit
回車之後即可退出,退出之後再 docker ps
會發現容器也不再運行了。
一些常用命令:
-
docker ps -a
命令可以列出所有的容器,包括已經終止執行的。 -
docker rm container_name/container_id
可以刪除某個容器。 -
docker start container_name/container_id
啟動某個容器。 -
docker stop container_name/container_id
終止某個容器。 -
docker exec -it contaner_name /bin/bash
在容器中執行/bin/bash
,執行該命令之後將可以以互動命令列的方式操作容器,另外/bin/bash
可以替換成任意可執行命令。
Docker compose
docker-compose
是用來建立和管理多容器應用的工具,使用 docker-compose
只需三步:
-
編寫應用執行環境的
Dockerfile
,即 image。 -
編寫
docker-compose.yml
,在services
塊下指定容器相關引數以及與其它容器的依賴關係。 -
執行
docker-compose up
,執行應用。
一個簡單的 docker-compose.yml
如下:
version: '2' # compose 版本,當前為 2 services: web: # web 容器 build: . # Dockerfile 所在路徑 ports: - "5000:5000" # 埠對映 volumes: - .:/code # 檔案路徑對映 - logvolume01:/var/log links: - redis # 連結容器 redis: image: redis # 定義連結容器 volumes: logvolume01: {}