映象
獲取映象
docker pull
檢視映象資訊
docker images
docker inspect <images id> # 獲取映象的詳細資訊
搜尋映象
docker search
刪除映象
docker rmi
當一個映象擁有多個標籤,
docker rmi
只是刪除該映象指定的標籤,並不影響映象檔案
當映象只剩下一個標籤時,再使用會徹底刪除該映象
先刪除該映象的所有容器,再刪除映象
建立映象
2 種方法:
- 基於已有映象的容器建立
- 基於 Dockerfile 建立(推薦)
基於已有映象的容器建立
docker commit
-a: 作者資訊
-m: 提交資訊
-p 提交時暫停容器執行
-c changelist
存出和載入映象
存出:sudo docker save -o ubuntu_16.04.tar ubuntu:16.04
載入:sudo docker load --input ubuntu_16.04.tar
或者 sudo docker load < ubuntu_16.04.tar
匯入映象,以及其相關的後設資料資訊(包括標籤等)
容器
建立容器
使用互動式來執行容器:sudo docker run -it ubuntu:latest /bin/bash
docker run
在後臺執行的標準操作:
- 檢查本地是否存在指定的映象, 不存在就從公有倉庫下載
- 利用映象建立並啟動一個容器
- 分配一個檔案系統,並在只讀的映象層外面掛載一層可讀寫層
- 從宿主主機配置的網橋介面中橋接一個虛擬介面到容器中去。
- 從地址池配置一個 IP 地址給容器
- 執行使用者指定的應用程式
- 執行完畢後容器被終止
守護態執行
sudo docker run -d ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done"
透過docker logs
命令獲取容器的輸出資訊:sudo docker -tf logs 2855b4d76ccb
-t: 列印時間戳
-f: 重新整理日誌到最後
2855b4d76ccb: 容器id
終止容器
sudo docker stop 2855b4d76ccb
檢視所有容器的資訊:sudo docker ps -a
處於終止狀態的容器,可以透過 docker start
命令來重新啟動:sudo docker start 2855b4d76ccb
重啟容器:sudo docker restart 2855b4d76ccb
進入容器
attach指令
sudo docker attach 2855b4d76ccb
當多個視窗同時 attach 到同一個容器時, 所有視窗會同步顯示。當某個視窗因命令阻塞時,其他視窗也無法執行操作。
exec 命令
sudo docker exec -ti 2855b4d76ccb /bin/bash
刪除容器
sudo docker rm 2855b4d76ccb
-f
強制刪除執行中的容器
-l
刪除容器連結,但保留容器
-v
刪除容器掛載的資料卷
匯入/匯出容器
匯出
sudo docker export 2855b4d76ccb > test.tar
可以將這些檔案傳輸到其他機器上, 在其他機器上透過匯入命令實現容器遷移
匯入
cat test.tar | sudo docker import - test/ubuntu:v1.0
docker load
匯入映象儲存檔案到本地的映象庫
docker import
匯入一個容器快照到本地映象庫
區別:
容器快照檔案將丟棄所有的歷史記錄和後設資料資訊(僅儲存容器當時的快照狀態),匯入時可以重新指定標籤等後設資料資訊。
映象儲存檔案將儲存完整記錄, 體積也大。
倉庫
Docker Hub
登入
docker login
搜尋
docker search
docker tag
sudo docker tag ubuntu:14.04 10.0.2.2:5000/test
自動建立
步驟:
- 登入 Docker Hub, 連線 GitHub 到 Docker
- 在Docker Hub 中配置自動建立:https://hub.docker.com/add/automated-build/caseycui/
- 選取一個目標網站專案(需要含 Dockerfile)和分支
- 指定 Dockerfile 的位置,並提交建立
- 之後,可以在 Docker Hub 的“自動建立”頁面中跟蹤每次建立的狀態。
建立和使用私有倉庫
使用 registry 映象建立私有倉庫
sudo docker -d -p 5000:5000 -v /opt/docker/registry/:/tmp/registry registry
監聽埠對映到 5000,docker 容器中的 /tmp/registry
被對映到本地的 /opt/docker/registry/
上。
管理私有倉庫映象
- 修改 tag 的 REGISTRYHOST
sudo docker tag ubuntu:latest 172.17.0.1:5000/test
- 使用 docker push 上傳
sudo docker push 172.17.0.1:5000/test
- 使用docker pull 下載
sudo docker pull 172.17.0.1:5000/test
資料管理
兩種方式:
- 資料卷(Data Volumes)
- 資料卷容器(Data Volume Containers)
資料卷
特性:
- 可以在容器間共享和重用
- 對資料卷的修改會立馬生效
- 對資料卷的更新, 不會影響容器
- 卷會一直存在, 直到沒有容器使用
類似 Linux 的 mount 操作
掛載一個主機目錄作為資料卷
sudo docker run -v /src/webapp:/opt/webapp training/webapp python app.py
載入主機的/src/webapp 目錄到容器的 /opt/webapp 目錄.
主機目錄必須是絕對路徑
預設許可權是讀寫(rw), 可以設定為只讀(ro)
/src/webapp:/opt/webapp:ro
資料卷容器
資料卷容器其實就是普通的容器, 專門用它提供資料卷供其他容器掛載使用.
-
建立一個資料卷容器:
sudo docker run -it -v /dbdata --name dbdata ubuntu
-
在其他容器中使用
volumes-from
來掛載 dbdata 容器中的資料卷.sudo docker run -it --volumes-from dbdata --name db1 ubuntu sudo docker run -it --volumes-from dbdata --name db2 ubuntu
3個容器任何一方在該目錄寫入, 其他容器都可以看到。
如果刪除了容器, 資料卷並不會自動刪除. 如果要刪除資料卷, 必須在刪除最後一個掛載著它的容器時顯式使用docker rm -v
命令來指定同時刪除關聯的容器
利用資料卷容器遷移資料
備份
sudo docker run --volumes-from dbdata -v $(pwd):/backup --name worker ubuntu tar cvf /backup/backup.tar /dbdata
恢復
sudo docker run -v /dbdata --name dbdata2 ubuntu /bin/bash
sudo docker run --volumes-from dbdata2 -v $(pwd):/backup busybox tar xvf /backup/backup.tar
網路基礎配置
埠對映實現訪問容器
sudo docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py
-P: 對映到隨機埠
檢視埠對映配置
sudo docker port loving_montalcini
容器互聯實現容器間通訊
容器的連線(linking)系統, 它會在源和接收容器之間建立一個隧道, 接收容器可以看到源容器指定的資訊.
連線系統依據容器的名稱來執行.
在執行
docker run
的時候如果新增--rm
標記, 則容器在終止後會立即刪除.--rm
和-d
無法同時使用.
容器互聯
sudo docker run -d --name db training/postgres # 建立一個新的資料庫容器
sudo docker run -d -P --name web --link db:db training/webapp python app.py # --link name:alias alias是連線的別名
Docker透過2種方式為容器公開連線資訊:
- 環境變數
- 更新
/etc/hosts
檔案
使用 env
命令檢視web容器的環境變數:
$ docker exec web env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=62b19d3b5add
DB_PORT=tcp://172.17.0.2:5432
DB_PORT_5432_TCP=tcp://172.17.0.2:5432
DB_PORT_5432_TCP_ADDR=172.17.0.2
DB_PORT_5432_TCP_PORT=5432
DB_PORT_5432_TCP_PROTO=tcp
DB_NAME=/web/db
DB_ENV_PG_VERSION=9.3
HOME=/root
/etc/hosts
檔案:
$ docker exec web cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2 db 4288c4f9ad47
172.17.0.3 62b19d3b5add # 本容器
也可以透過 ping 來測試:
$ docker exec web ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.083 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.054 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.054 ms
64 bytes from 172.17.0.2: icmp_seq=4 ttl=64 time=0.053 ms
64 bytes from 172.17.0.2: icmp_seq=5 ttl=64 time=0.055 ms
64 bytes from 172.17.0.2: icmp_seq=6 ttl=64 time=0.057 ms
使用 Dockerfile 建立映象
基本結構
- 基礎映象資訊
- 維護者資訊
- 映象操作指令
- 容器啟動時執行指令
指令
FROM
第一條指令必須為 FROM 指令
MAINTAINER(已棄用)
制定維護者資訊. 以後可以用 LABEL maintainer="CaseyCui cuikaidong@foxmail.com"
RUN
兩種格式:
RUN <command>
bash格式, 命令在bash中執行, 預設在Linux是/bin/sh -c
在windows上是cmd /S /C
RUN ["executable", "param1", "param2"]
(用docker exec
執行)
每條RUN指令將在當前映象基礎上執行指定命令, 並提交為新的映象.
最佳實踐:
apt-get安裝:
RUN apt-get update && apt-get install -y --no-install-recommends \
aufs-tools \
automake \
build-essential \
curl \
dpkg-sig \
libcap-dev \
libsqlite3-dev \
mercurial \
reprepro \
ruby1.9.1 \
ruby1.9.1-dev \
s3cmd=1.1.* \
&& rm -rf /var/lib/apt/lists/*
apt-get update && apt-get install
合用
apt-get install -y --no-install-recommends
不安裝其他推薦的包,-no-install-suggests
也可以加上
ruby1.9.1 s3cmd=1.1.*
安裝指定版本的包
rm -rf /var/lib/apt/lists/*
刪除軟體包殘留
## a few minor docker-specific tweaks
## see https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrap
RUN set -xe \
\
## https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrap#L40-L48
&& echo '#!/bin/sh' > /usr/sbin/policy-rc.d \
&& echo 'exit 101' >> /usr/sbin/policy-rc.d \
&& chmod +x /usr/sbin/policy-rc.d \
\
## https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrap#L54-L56
&& dpkg-divert --local --rename --add /sbin/initctl \
&& cp -a /usr/sbin/policy-rc.d /sbin/initctl \
&& sed -i 's/^exit.*/exit 0/' /sbin/initctl \
\
## https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrap#L71-L78
&& echo 'force-unsafe-io' > /etc/dpkg/dpkg.cfg.d/docker-apt-speedup \
\
## https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrap#L85-L105
&& echo 'DPkg::Post-Invoke { "rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true"; };' > /etc/apt/apt.conf.d/docker-clean \
&& echo 'APT::Update::Post-Invoke { "rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true"; };' >> /etc/apt/apt.conf.d/docker-clean \
&& echo 'Dir::Cache::pkgcache ""; Dir::Cache::srcpkgcache "";' >> /etc/apt/apt.conf.d/docker-clean \
\
## https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrap#L109-L115
&& echo 'Acquire::Languages "none";' > /etc/apt/apt.conf.d/docker-no-languages \
\
## https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrap#L118-L130
&& echo 'Acquire::GzipIndexes "true"; Acquire::CompressionTypes::Order:: "gz";' > /etc/apt/apt.conf.d/docker-gzip-indexes \
\
## https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrap#L134-L151
&& echo 'Apt::AutoRemove::SuggestsImportant "false";' > /etc/apt/apt.conf.d/docker-autoremove-suggests
set -xe
除錯模式, 返回非 0 (即不成功) 就退出
CMD
支援三種格式:
CMD ["executable","param1","param2"]
使用docker exec
執行, 推薦方式CMD ["param1","param2"]
作為 ENTRYPOINT 的預設引數CMD command param1 param2
bash
指定啟動容器時執行的命令, 每個 Dockerfile 只能有一條 CMD 命令.
EXPOSE
EXPOSE 80 8443
暴露的埠號, 供互聯絡統使用. 在啟動時可以透過 -P
或 -p
來指定對映
ENV
ENV PG_MAJOR 9.3
ENV PG_VERSION 9.3.4
RUN curl -SL http://example.com/postgres-$PG_VERSION.tar.xz | tar -xJC /usr/src/postgress && …
ENV PATH /usr/local/postgres-$PG_MAJOR/bin:$PATH
ADD
推薦只在 src
為 tar 檔案時(會自動解壓)使用. 其他時候使用 COPY. 不推薦使用 URL 的方式.
COPY
COPY <src> <dest>
當使用本例目錄為 src 時, 推薦使用 COPY
ENTRYPOINT
兩種格式:
ENTRYPOINT ["executable", "param1", "param2"]
exec 格式ENTRYPOINT command param1 param2
bash 格式
VOLUME
建立一個可以從本地主機或其他容器掛載的掛載點, 一般用來存放資料庫和需要保持的資料等.
USER
指定執行容器時的使用者名稱或 UID, 後續的 RUN
也會使用指定使用者.
當服務不需要管理員許可權時, 可以透過該命令指定執行使用者.
要臨時獲取管理員許可權推薦使用 gosu
, 不推薦sudo
WORKDIR
為後續的 RUN CMD ENTRYPOINT
指令配置工作目錄.
ONBUILD
ONBUILD [Dockerilfe的指令]
配置當所建立的映象作為其他新建立映象的基礎映象時, 所執行的操作指令.
使用 ONBUILD
指令的映象, 推薦在 tag 中註明, 如 ruby:1.9-onbuild
建立映象
docker build [選項] 路徑
實現:
- 讀取指定路徑下(包括子目錄)的 Dockerfile
- 將該路徑下所有內容傳送給 Docker 服務端
- 由服務端來建立映象
一般建議放置 Dockerfile 的目錄為空目錄
可以透過 .dockerignore 檔案來讓 Docker 忽略路徑下的目錄和檔案.
## comment
*/temp*
*/*/temp*
temp?
指令示例: sudo docker build -t build_repo/first_image /tmp/docker_builder/
三人行, 必有我師; 知識共享, 天下為公. 本文由東風微鳴技術部落格 EWhisper.cn 編寫.