Docker helps developers build and ship higher-quality applications, faster." -- What is Dockerhtml
深刻 Docker:容器和鏡像node
docker-curriculumlinux
docker-cheat-sheetnginx
Docker 實戰github
經過系統自帶包安裝web
Ubuntu 14.04 版本系統中已經自帶了 Docker 包,能夠直接安裝。mongodb
$ sudo apt-get update $ sudo apt-get install -y docker.io $ sudo ln -sf /usr/bin/docker.io /usr/local/bin/docker $ sudo sed -i '$acomplete -F _docker docker' /etc/bash_completion.d/docker.io
若是使用操做系統自帶包安裝 Docker,目前安裝的版本是比較舊的 0.9.1。 要安裝更新的版本,能夠經過使用 Docker 源的方式。
經過Docker源安裝最新版本
要安裝最新的 Docker 版本,首先須要安裝 apt-transport-https 支持,以後經過添加源來安裝。
$ sudo apt-get install apt-transport-https $ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9 $ sudo bash -c "echo deb https://get.docker.io/ubuntu docker main > /etc/apt/sources.list.d/docker.list" $ sudo apt-get update $ sudo apt-get install lxc-docker
14.04 以前版本
若是是較低版本的 Ubuntu 系統,須要先更新內核。
$ sudo apt-get update $ sudo apt-get install linux-image-generic-lts-raring linux-headers-generic-lts-raring $ sudo reboot
而後重複上面的步驟便可。
安裝以後啓動 Docker 服務。
$ sudo service docker start
Docker 支持 CentOS6 及之後的版本。
CentOS6
對於 CentOS6,可使用 EPEL 庫安裝 Docker,命令以下
$ sudo yum install http://mirrors.yun-idc.com/epel/6/i386/epel-release-6-8.noarch.rpm $ sudo yum install docker-io
CentOS7
CentOS7 系統 CentOS-Extras
庫中已帶 Docker,能夠直接安裝:
$ sudo yum install docker
安裝以後啓動 Docker 服務,並讓它隨系統啓動自動加載。
$ sudo service docker start $ sudo chkconfig docker on
早期在Windows或者MAC環境下使用Docker主要利用的是Boot2Docker這個命令行工具,而Toolbox能夠安裝你在開發中運行Docker時所須要的一切:Docker客戶端、Compose(僅Mac須要)、Kitematic、Machine以及VirtualBox。Toolbox使用Machine和VirtualBox在虛擬機中建立了一個引擎來運行容器。在該虛擬機上,你可使用Docker客戶端、Compose以及Kitematic來運行容器。而Toolbox自己已經能夠取代了Boot2Docker的做用。
Docker的Toolbox主要集成了以下幾個不一樣的工具的集合:
Docker Client docker
binary
Docker Machine docker-machine
binary
Docker Compose docker-compose
binary
Kitematic – Desktop GUI for Docker
Docker Quickstart Terminal app
以Mac系統爲例,使用Docker Toolbox安裝Docker環境與Linux系統的區別在於,在標準的Linux系統上的安裝中,Docker客戶端、Docker守護進程以及全部的容器都是直接運行在本地的:
而在OS X或者Windows系統的安裝中,Docker的相關的程序是運行在一個內置的小型的Linux虛擬機中的。
在這裏能夠下載Toolbox的安裝程序,雙擊打開按照步驟提示安裝好以後,便可以進行下一步,首先在Applications文件夾或者Launchpad中打開Docker QuickStart Terminal,該程序會直接打開一個終端控制檯,而且建立或者鏈接到一個叫default
的虛擬機而且將控制檯登陸到該虛擬機中。固然,用戶也能夠用docker-machine
命令來手動建立或者登陸到虛擬機中:
建立一個新的Docker虛擬機
$ docker-machine create --driver virtualbox default Creating VirtualBox VM... Creating SSH key... Starting VirtualBox VM... Starting VM... To see how to connect Docker to this machine, run: docker-machine env default
注意,該虛擬機相關的配置文件存放在~/.docker/machine/machines/default
目錄下。
列舉全部可用的機器
$ docker-machine ls NAME ACTIVE DRIVER STATE URL SWARM default * virtualbox Running tcp://192.168.99.101:2376
獲取環境配置
$ docker-machine env default export DOCKER_TLS_VERIFY="1" export DOCKER_HOST="tcp://192.168.99.101:2376" export DOCKER_CERT_PATH="/Users/mary/.docker/machine/machines/default" export DOCKER_MACHINE_NAME="default" # Run this command to configure your shell: # eval "$(docker-machine env default)"
鏈接到該虛擬機
$ eval "$(docker-machine env default)"
若是是使用boot2docker配置的Docker的運行環境,那麼配置文件並無放置在Windows或者MAC系統種,而是附着在了小的Linux虛擬機的內核中。首先咱們須要在boot2docker的命令行中進入到VM的設置:
Creating Machine default... Creating VirtualBox VM... Creating SSH key... Starting VirtualBox VM... Starting VM... To see how to connect Docker to this machine, run: docker-machine env default Starting machine default... Started machines may have new IP addresses. You may need to re-run the `docker-machine env` command. Setting environment variables for machine default... . . . ## . ## ## ## == ## ## ## ## ## === /"""""""""""""""""\___/ === ~~~ {~~ ~~~~ ~~~ ~~~~ ~~~ ~ / ===- ~~~ \______ o __/ \ \ __/ \____\_______/ docker is configured to use the default machine with IP 192.168.99.100 For help getting started, check out the docs at https://docs.docker.com
如今能夠修改 /var/lib/boot2docker/profile 這個文件來設置代理:
docker@boot2docker:~$ sudo vi /var/lib/boot2docker/profile
Tinycore 須要按照以下格式進行配置: protocol://ip:port
安全起見我同時設置了 HTTP 與 HTTPS.
export HTTP_PROXY=http://your.proxy.name:8080 export HTTPS_PROXY=http://your.proxy.name:8080
如今你能夠重啓整個服務以及Docker容器:
docker@boot2docker:~$ sudo /etc/init.d/docker restart docker@boot2docker:~$ exit Connection to localhost closed.
接下來就能夠順利的運行鏡像了:
bash-3.2$ docker search ubuntu NAME DESCRIPTION STARS OFFICIAL AUTOMATED ubuntu Official Ubuntu base image 356 stackbrew/ubuntu Official Ubuntu base image 39 crashsystems/gitlab-docker A trusted, regularly updated build of GitL...
這個改變即便之後的虛擬機重啓重置也都一直會被保留,所以只須要被設置一次。
DaoCloud提供Docker Hub Mirror服務。用戶能夠進入Docker Hub Mirror註冊入口註冊。在進入控制檯頁面後直接點擊 啓動你的加速器後,您便可獲得一個Mirror的地址,將該地址配置在Docker Daemon的啓動腳本中,重啓Docker Daemon便可使得Docker Hub Mirror配置生效。
Ubuntu:
安裝或升級Docker
Docker 1.3.2版本以上才支持Docker Hub Mirror機制,若是您尚未安裝Docker或者版本太低,請安裝或升級版本。
配置Docker Hub Mirror
sudo echo "DOCKER_OPTS=\"$DOCKER_OPTS --registry-mirror=http://xxx.m.daocloud.io\"" >> /etc/default/docker service docker restart
請將xxx替換爲您在 DaoCloud 上註冊後,爲您專屬生成的Mirror地址連接名。 該腳本能夠將 --registry-mirror 加入到您的Docker配置文件 /etc/defaults/docker中。
盡情享受Docker Hub Mirror
Docker Hub Mirror使用不須要任何附件操做,就像這樣下載官方Ubuntu鏡像
docker pull ubuntu
CentOS:
安裝或升級Docker
Docker 1.3.2版本以上才支持Docker Hub Mirror機制,若是您尚未安裝Docker或者版本太低,請安裝或升級版本。
配置Docker Hub Mirror
sudo sed -i 's|OPTIONS=|OPTIONS=--registry-mirror=http://xxx.m.daocloud.io |g' /etc/sysconfig/docker service docker restart
請將xxx替換爲您在 DaoCloud 上註冊後,爲您專屬生成的Mirror地址連接名。
該腳本能夠將 --registry-mirror 加入到您的Docker配置文件/etc/defaults/docker中。
盡情享受Docker Hub Mirror
Docker Hub Mirror使用不須要任何附件操做,就像這樣下載官方Ubuntu鏡像
docker pull ubuntu
MAC:
安裝或升級MAC版本下的Boot2Docker
Docker 1.3.2版本以上才支持Docker Hub Mirror機制,若是您尚未安裝Docker或者版本太低,請安裝或升級版本。
配置Docker Hub Mirror
請確認你的Boot2Docker已經啓動,並執行
boot2docker ssh sudo su echo "EXTRA_ARGS=\"--registry-mirror=http://xxx.m.daocloud.io\"" >> /var/lib/boot2docker/profile && exit exit boot2docker restart
請將xxx替換爲您在 DaoCloud 上註冊後,爲您專屬生成的Mirror地址連接名。
盡情享受Docker Hub Mirror
Docker Hub Mirror使用不須要任何附件操做,就像這樣下載官方Ubuntu鏡像
docker pull ubuntu
Windows:
安裝或升級MAC版本下的Boot2Docker
Docker 1.3.2版本以上才支持Docker Hub Mirror機制,若是您尚未安裝Docker或者版本太低,請安裝或升級版本。
配置Docker Hub Mirror
進入Boot2Docker Start Shell,並執行
sudo su echo "EXTRA_ARGS=\"--registry-mirror=http://xxx.m.daocloud.io\"" >> /var/lib/boot2docker/profile exit # 從新啓動Boot2Docker
請將xxx替換爲您在 DaoCloud 上註冊後,爲您專屬生成的Mirror地址連接名
盡情享受Docker Hub Mirror
Docker Hub Mirror使用不須要任何附件操做,就像這樣下載官方Ubuntu鏡像
docker pull ubuntu
在Docker的學習中咱們依舊能夠借鑑經典的HelloWorld,直接運行docker run hello-world
便可,不過須要注意的是,因爲總所周知的緣由,國內每每沒法順利的下載鏡像,若是遇到相似的網絡的錯誤能夠參考上文中的代理或者鏡像的設置。
$ docker run hello-world Unable to find image 'hello-world:latest' locally 511136ea3c5a: Pull complete 31cbccb51277: Pull complete e45a5af57b00: Pull complete hello-world:latest: The image you are pulling has been verified. Important: image verification is a tech preview feature and should not be relied on to provide security. Status: Downloaded newer image for hello-world:latest Hello from Docker. This message shows that your installation appears to be working correctly. To generate this message, Docker took the following steps: 1. The Docker client contacted the Docker daemon. 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. (Assuming it was not already locally available.) 3. The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading. 4. The Docker daemon streamed that output to the Docker client, which sent it to your terminal. To try something more ambitious, you can run an Ubuntu container with: $ docker run -it ubuntu bash For more examples and ideas, visit: http://docs.docker.com/userguide/
你的Container會在你結束命令以後自動退出,使用如下的命令選項能夠將容器保持在激活狀態:
-i
即便在沒有附着的狀況下依然保持STDIN處於開啓。單純使用-i命令是不會出現root@689d580b6416:/
這種前綴。
-t
分配一個僞TTY控制檯
因此run
命令就變成了:
docker run -it -d shykes/pybuilder bin/bash
若是但願可以附着到一個已經存在的容器中,則利用exec
命令:
docker exec -it CONTAINER_ID /bin/bash
本章主要對於常見的Docker命令行命令進行詳細介紹。
docker create
會建立一個容器可是不會馬上啓動
docker run
會建立而且啓動某個容器
若是隻是但願有一個暫時性的容器,可使用 docker run --rm
將會在容器運行完畢以後刪除該容器。
若是但願在打開某個容器以後可以與其進行交互, docker run -t -i
會建立一個TTY控制檯。
docker stop
會關閉某個容器
docker start
會啓動某個容器
docker restart
會從新啓動某個容器
docker rm
會刪除某個容器
若是但願可以移除全部與該容器相關的Volume,可使用-v參數: docker rm -v
.
docker kill
會發送SIGKILL信號量到某個容器
docker attach
會附着到某個正在運行的容器
docker wait
會阻塞直到某個容器關閉
docker images
會展現全部的鏡像
docker import
會從原始碼中建立鏡像
docker build
會從某個Dockfile中建立鏡像
docker commit
會從某個Container中建立鏡像
docker rmi
會移除某個鏡像
docker load
以STDIN的方式從某個tar包中加載鏡像
docker save
以STDOUT的方式將鏡像存入到某個tar包中
docker ps
會列舉出全部正在運行的容器
docker ps -a
會展現出全部正在運行的和已經中止的容器
docker logs
從某個容器中獲取log日誌
docker inspect
檢測關於某個容器的詳細信息
docker events
從某個容器中獲取全部的事件
docker port
獲取某個容器的所有的開放端口
docker top
展現某個容器中運行的所有的進程
docker stats
展現某個容器中的資源的使用狀況的統計信息
docker diff
展現容器中文件的變化狀況
docker history
展現鏡像的所有歷史信息
docker tag
爲某個容器設置標籤
docker cp
在容器與本地文件系統之間進行文件複製
docker export
將某個容器中的文件系統的內容輸出到某個tar文件中
docker exec
在容器中運行某個命令
若是須要在某個名字爲foo的容器中運行交互命令,可使用:
docker exec -it foo /bin/bash
.
An instance of an image is called container
容器是Docker的核心概念,其相較於咱們認爲的虛擬機就比如進程中的線程同樣。
A docker container exits when its main process finishes.
Docker 背後的驅動力之一就是經過全部的 Docker 使服務器 能建立一個一致的環境,而且能建立一個能運行在任何 Docker 服務器上的合適的模板或是鏡像。所以,Docker 能很是完美的支持,能很是容易的導出一個正在運行的容器,而且從新導入另一臺 Docker 服務器。讓咱們假設一下,例如這個示例,你有一個你將移動到另一臺服務器去的正在運行的容器。這個進程的功能就是把這個容器保存爲一個鏡像,保存成 一個 tar 文件,把它移動到新的服務器,而且把這個鏡像加載進新的 docker 服務器。
將Container提交爲鏡像
$ docker commit 3a09b2588478 mynewimage 4d2eab1c0b9a13c83abd72b38e5d4b4315de3c9967165f78a7b817ca99bf191e
將鏡像打包
$ docker save mynewimage > /tmp/mynewimage.tar
在新的機器上載入鏡像
$ docker load < /tmp/mynewimage.tar
查看鏡像狀態
最後,運行 docker images
命令檢查鏡像如今是否可用。
$ docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE mynewimage latest 4d2eab1c0b9a 5 minutes ago 278.1 MB ubuntu 14.04 ad892dd21d60 11 days ago 275.5 MB <none> <none> 6b0a59aa7c48 11 days ago 169.4 MB <none> <none> 6cfa4d1f33fb 7 weeks ago 0 B
Dockerfile 由一行行命令語句組成,而且支持以 #
開頭的註釋行。通常的,Dockerfile 分爲四部分:基礎鏡像信息、維護者信息、鏡像操做指令和容器啓動時執行指令。例如:
# This dockerfile uses the ubuntu image # VERSION 2 - EDITION 1 # Author: docker_user # Command format: Instruction [arguments / command] .. # Base image to use, this must be set as the first line FROM ubuntu # Maintainer: docker_user <docker_user at email.com> (@docker_user) MAINTAINER docker_user docker_user@email.com # Commands to update the image RUN echo "deb http://archive.ubuntu.com/ubuntu/ raring main universe" >> /etc/apt/sources.list RUN apt-get update && apt-get install -y nginx RUN echo "\ndaemon off;" >> /etc/nginx/nginx.conf # Commands when creating a new container CMD /usr/sbin/nginx
其中,一開始必須指明所基於的鏡像名稱,接下來推薦說明維護者信息。後面則是鏡像操做指令,例如 RUN
指令,RUN
指令將對鏡像執行跟隨的命令。每運行一條 RUN
指令,鏡像添加新的一層,並提交。最後是 CMD
指令,來指定運行容器時的操做命令。
最後,這邊有一個Docker官方MongoDB的例子:
# # MongoDB Dockerfile # # https://github.com/dockerfile/mongodb # # Pull base image. FROM dockerfile/ubuntu # Install MongoDB. RUN \ apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10 && \ echo 'deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen' > /etc/apt/sources.list.d/mongodb.list && \ apt-get update && \ apt-get install -y mongodb-org && \ rm -rf /var/lib/apt/lists/* # Define mountable directories. VOLUME ["/data/db"] # Define working directory. WORKDIR /data # Define default command. CMD ["mongod"] # Expose ports. # - 27017: process # - 28017: http EXPOSE 27017 EXPOSE 28017
指令的通常格式爲 INSTRUCTION arguments
,指令包括 FROM
、MAINTAINER
、RUN
等。
FROM
格式爲 FROM <image>
或FROM <image>:<tag>
。
第一條指令必須爲 FROM
指令。而且,若是在同一個Dockerfile中建立多個鏡像時,可使用多個 FROM
指令(每一個鏡像一次)。
MAINTAINER
格式爲 MAINTAINER <name>
,指定維護者信息。
RUN
格式爲 RUN <command>
或 RUN ["executable", "param1", "param2"]
。
前者將在 shell 終端中運行命令,即 /bin/sh -c
;後者則使用 exec
執行。指定使用其它終端能夠經過第二種方式實現,例如 RUN ["/bin/bash", "-c", "echo hello"]
。
每條 RUN
指令將在當前鏡像基礎上執行指定命令,並提交爲新的鏡像。當命令較長時可使用 \
來換行。
CMD
支持三種格式
CMD ["executable","param1","param2"]
使用 exec
執行,推薦方式;
CMD command param1 param2
在 /bin/sh
中執行,提供給須要交互的應用;
CMD ["param1","param2"]
提供給 ENTRYPOINT
的默認參數;
指定啓動容器時執行的命令,每一個 Dockerfile 只能有一條 CMD
命令。若是指定了多條命令,只有最後一條會被執行。
若是用戶啓動容器時候指定了運行的命令,則會覆蓋掉 CMD
指定的命令。
EXPOSE
格式爲 EXPOSE <port> [<port>...]
。
告訴 Docker 服務端容器暴露的端口號,供互聯繫統使用。在啓動容器時須要經過 -P,Docker 主機會自動分配一個端口轉發到指定的端口。
ENV
格式爲 ENV<key><value>
。指定一個環境變量,會被後續 RUN
指令使用,並在容器運行時保持。
例如
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
格式爲 ADD<src><dest>
。
該命令將複製指定的 <src>
到容器中的 <dest>
。其中 <src>
能夠是Dockerfile所在目錄的一個相對路徑;也能夠是一個 URL;還能夠是一個 tar 文件(自動解壓爲目錄)。
COPY
格式爲 COPY <src><dest>
。
複製本地主機的 <src>
(爲 Dockerfile 所在目錄的相對路徑)到容器中的 dest
。
當使用本地目錄爲源目錄時,推薦使用 COPY
。
ENTRYPOINT
兩種格式:
ENTRYPOINT ["executable", "param1", "param2"]
ENTRYPOINT command param1 param2
(shell中執行)。
配置容器啓動後執行的命令,而且不可被 docker run
提供的參數覆蓋。
每一個 Dockerfile 中只能有一個 ENTRYPOINT
,當指定多個時,只有最後一個起效。
VOLUME
格式爲 VOLUME ["/data"]
。
建立一個能夠從本地主機或其餘容器掛載的掛載點,通常用來存放數據庫和須要保持的數據等。
USER
格式爲 USER daemon
。
指定運行容器時的用戶名或 UID,後續的 RUN
也會使用指定用戶。
當服務不須要管理員權限時,能夠經過該命令指定運行用戶。而且能夠在以前建立所須要的用戶,例如:RUN groupadd -r postgres && useradd -r -g postgres postgres
。要臨時獲取管理員權限可使用 gosu
,而不推薦 sudo
。
WORKDIR
格式爲 WORKDIR /path/to/workdir
。
爲後續的 RUN
、CMD
、ENTRYPOINT
指令配置工做目錄。
可使用多個 WORKDIR
指令,後續命令若是參數是相對路徑,則會基於以前命令指定的路徑。例如
WORKDIR /a WORKDIR b WORKDIR c RUN pwd
則最終路徑爲 /a/b/c
。
ONBUILD
格式爲 ONBUILD [INSTRUCTION]
。
配置當所建立的鏡像做爲其它新建立鏡像的基礎鏡像時,所執行的操做指令。
例如,Dockerfile 使用以下的內容建立了鏡像 image-A
。
[...] ONBUILD ADD . /app/src ONBUILD RUN /usr/local/bin/python-build --dir /app/src [...]
若是基於 image-A 建立新的鏡像時,新的Dockerfile中使用 FROM image-A
指定基礎鏡像時,會自動執行 ONBUILD
指令內容,等價於在後面添加了兩條指令。
FROM image-A #Automatically run the following ADD . /app/src RUN /usr/local/bin/python-build --dir /app/src
使用 ONBUILD
指令的鏡像,推薦在標籤中註明,例如 ruby:1.9-onbuild
。
編寫完成 Dockerfile 以後,能夠經過 docker build
命令來建立鏡像。
基本的格式爲 docker build [選項] 路徑
,該命令將讀取指定路徑下(包括子目錄)的 Dockerfile,並將該路徑下全部內容發送給 Docker 服務端,由服務端來建立鏡像。所以通常建議放置 Dockerfile 的目錄爲空目錄。也能夠經過 .dockerignore
文件(每一行添加一條匹配模式)來讓 Docker 忽略路徑下的目錄和文件。
要指定鏡像的標籤信息,能夠經過 -t
選項,例如
$ sudo docker build -t myrepo/myapp /tmp/test1/
數據卷是一個可供一個或多個容器使用的特殊目錄,它繞過 UFS,能夠提供不少有用的特性:
數據卷能夠在容器之間共享和重用
對數據卷的修改會立馬生效
對數據卷的更新,不會影響鏡像
卷會一直存在,直到沒有容器使用
*數據卷的使用,相似於 Linux 下對目錄或文件進行 mount。
在用 docker run
命令的時候,使用 -v
標記來建立一個數據卷並掛載到容器裏。在一次 run 中屢次使用能夠掛載多個數據卷。
下面建立一個 web 容器,並加載一個數據捲到容器的 /data
目錄。
$ sudo docker run -d -P --name web -v /data training/webapp python app.py
*注意:也能夠在 Dockerfile 中使用 VOLUME
來添加一個或者多個新的捲到由該鏡像建立的任意容器。這將在容器內建立路徑/data,它存在於聯合文件系統外部並能夠在主機上直接訪問。任何在該鏡像/data路徑的文件將被複制到volume。咱們可使用docker inspect命令找出Volume在主機存儲的地方:
$ docker inspect -f {{.Volumes}} web
你會看到如下相似內容:
map[/data:/var/lib/docker/vfs/dir/cde167197ccc3e138a14f1a4f...b32cec92e79059437a9]
這說明Docker把在/var/lib/docker下的某個目錄掛載到了容器內的/data目錄下。讓咱們從主機上添加文件到此文件夾下:
$ sudo touch /var/lib/docker/vfs/dir/cde167197ccc3e13814f...b32ce9059437a9/test-file
進入咱們的容器內能夠看到:
$ root@CONTAINER:/# ls /data test-file
改變會當即生效只要將主機的目錄掛載到容器的目錄上。咱們能夠在Dockerfile中經過使用VOLUME指令來達到相同的效果:
FROM debian:wheezy VOLUME /data
使用 -v
標記也能夠指定掛載一個本地主機的目錄到容器中去。
$ sudo docker run -d -P --name web -v /src/webapp:/opt/webapp training/webapp python app.py
上面的命令加載主機的 /src/webapp
目錄到容器的 /opt/webapp
目錄。這個功能在進行測試的時候十分方便,好比用戶能夠放置一些程序到本地目錄中,來查看容器是否正常工做。本地目錄的路徑必須是絕對路徑,若是目錄不存在 Docker 會自動爲你建立它。
*注意:Dockerfile 中不支持這種用法,這是由於 Dockerfile 是爲了移植和分享用的。然而,不一樣操做系統的路徑格式不同,因此目前還不能支持。
Docker 掛載數據卷的默認權限是讀寫,用戶也能夠經過 :ro
指定爲只讀。
$ sudo docker run -d -P --name web -v /src/webapp:/opt/webapp:ro training/webapp python app.py
加了 :ro
以後,就掛載爲只讀了。
-v
標記也能夠從主機掛載單個文件到容器中
$ sudo docker run --rm -it -v ~/.bash_history:/.bash_history ubuntu /bin/bash
這樣就能夠記錄在容器輸入過的命令了。
*注意:若是直接掛載一個文件,不少文件編輯工具,包括 vi
或者 sed --in-place
,可能會形成文件 inode 的改變,從 Docker 1.1.0起,這會致使報錯誤信息。因此最簡單的辦法就直接掛載文件的父目錄。
自從Docker 1.9版本以後,volume再也不僅僅做爲docker run的一個flag,也做爲一個單獨的子命令出如今Docker中。底層也爲volume添加了諸如ls、create、inspect和rm等volume子命令的api。新的volume子命令能夠容許用戶先建立volume,而後在啓動的container的時候進行掛載,此舉也更加方便了volume的管理。
$ docker volume create --name hello hello $ docker run -d -v hello:/world busybox ls /world
而在一個獨立的Volume被建立以後,就能夠經過inspect
命令來進行信息查看:
Usage: docker volume inspect [OPTIONS] VOLUME [VOLUME...] Inspect one or more volumes -f, --format= Format the output using the given go template. --help=false Print usage
該命令會返回某個數據卷的基本信息,大概樣式以下圖所示:
$ docker volume create 85bffb0677236974f93955d8ecc4df55ef5070117b0e53333cc1b443777be24d $ docker volume inspect 85bffb0677236974f93955d8ecc4df55ef5070117b0e53333cc1b443777be24d [ { "Name": "85bffb0677236974f93955d8ecc4df55ef5070117b0e53333cc1b443777be24d", "Driver": "local", "Mountpoint": "/var/lib/docker/volumes/85bffb0677236974f93955d8ecc4df55ef5070117b0e53333cc1b443777be24d/_data" } ] $ docker volume inspect --format '{{ .Mountpoint }}' 85bffb0677236974f93955d8ecc4df55ef5070117b0e53333cc1b443777be24d /var/lib/docker/volumes/85bffb0677236974f93955d8ecc4df55ef5070117b0e53333cc1b443777be24d/_data
Docker 1.9中正式引入了所謂的"Container Network Model",也就適合所謂的 CNM的概念。CNM即用於建立小型微分割的網絡來使得不一樣組的容器之間進行相互鏈接。
容器中能夠運行一些網絡應用,要讓外部也能夠訪問這些應用,能夠經過 -P
或 -p
參數來指定端口映射。
當使用 -P 標記時,Docker 會隨機映射一個 49000~49900
的端口到內部容器開放的網絡端口。
使用 docker ps
能夠看到,本地主機的 49155 被映射到了容器的 5000 端口。此時訪問本機的 49155 端口便可訪問容器內 web 應用提供的界面。
$ sudo docker run -d -P training/webapp python app.py $ sudo docker ps -l CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES bc533791f3f5 training/webapp:latest python app.py 5 seconds ago Up 2 seconds 0.0.0.0:49155->5000/tcp nostalgic_morse
一樣的,能夠經過 docker logs
命令來查看應用的信息。
$ sudo docker logs -f nostalgic_morse * Running on http://0.0.0.0:5000/ 10.0.2.2 - - [23/May/2014 20:16:31] "GET / HTTP/1.1" 200 - 10.0.2.2 - - [23/May/2014 20:16:31] "GET /favicon.ico HTTP/1.1" 404 -
-p(小寫的)則能夠指定要映射的端口,而且,在一個指定端口上只能夠綁定一個容器。支持的格式有 ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort
。
映射全部接口地址
使用 hostPort:containerPort
格式本地的 5000 端口映射到容器的 5000 端口,能夠執行
$ sudo docker run -d -p 5000:5000 training/webapp python app.py
此時默認會綁定本地全部接口上的全部地址。
映射到指定地址的指定端口
可使用 ip:hostPort:containerPort
格式指定映射使用一個特定地址,好比 localhost 地址 127.0.0.1
$ sudo docker run -d -p 127.0.0.1:5000:5000 training/webapp python app.py
映射到指定地址的任意端口
使用 ip::containerPort
綁定 localhost 的任意端口到容器的 5000 端口,本地主機會自動分配一個端口。
$ sudo docker run -d -p 127.0.0.1::5000 training/webapp python app.py
還可使用 udp 標記來指定 udp 端口
$ sudo docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py
查看映射端口配置
使用 docker port
來查看當前映射的端口配置,也能夠查看到綁定的地址
$ docker port nostalgic_morse 5000 127.0.0.1:49155.
注意:
容器有本身的內部網絡和 ip 地址(使用 docker inspect
能夠獲取全部的變量,Docker 還能夠有一個可變的網絡配置。)
-p 標記能夠屢次使用來綁定多個端口
例如
$ sudo docker run -d -p 5000:5000 -p 3000:80 training/webapp python app.py
注意,網絡映射的操做只會在run命令中起做用,若是已經運行了一個容器,須要從新設置其網絡映射狀況,請使用commit將容器轉化爲鏡像以後再建立新的容器。
容器的鏈接(linking)系統是除了端口映射外,另外一種跟容器中應用交互的方式。
該系統會在源和接收容器之間建立一個隧道,接收容器能夠看到源容器指定的信息。
鏈接系統依據容器的名稱來執行。所以,首先須要自定義一個好記的容器命名。
雖然當建立容器的時候,系統默認會分配一個名字。自定義命名容器有2個好處:
自定義的命名,比較好記,好比一個web應用容器咱們能夠給它起名叫web
當要鏈接其餘容器時候,能夠做爲一個有用的參考點,好比鏈接web容器到db容器
使用 --name
標記能夠爲容器自定義命名。
$ sudo docker run -d -P --name web training/webapp python app.py
使用 docker ps
來驗證設定的命名。
$ sudo docker ps -l CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES aed84ee21bde training/webapp:latest python app.py 12 hours ago Up 2 seconds 0.0.0.0:49154->5000/tcp web
也可使用 docker inspect
來查看容器的名字
$ sudo docker inspect -f "{{ .Name }}" aed84ee21bde /web
注意:容器的名稱是惟一的。若是已經命名了一個叫 web 的容器,當你要再次使用 web 這個名稱的時候,須要先用docker rm
來刪除以前建立的同名容器。
在執行 docker run
的時候若是添加 --rm
標記,則容器在終止後會馬上刪除。注意,--rm
和 -d
參數不能同時使用。
使用 --link
參數可讓容器之間安全的進行交互。
下面先建立一個新的數據庫容器。
$ sudo docker run -d --name db training/postgres
刪除以前建立的 web 容器
$ docker rm -f web
而後建立一個新的 web 容器,並將它鏈接到 db 容器
$ sudo docker run -d -P --name web --link db:db training/webapp python app.py
此時,db 容器和 web 容器創建互聯關係。
--link
參數的格式爲 --link name:alias
,其中 name
是要連接的容器的名稱,alias
是這個鏈接的別名。
使用 docker ps
來查看容器的鏈接
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 349169744e49 training/postgres:latest su postgres -c '/usr About a minute ago Up About a minute 5432/tcp db, web/db aed84ee21bde training/webapp:latest python app.py 16 hours ago Up 2 minutes 0.0.0.0:49154->5000/tcp web
能夠看到自定義命名的容器,db 和 web,db 容器的 names 列有 db 也有 web/db。這表示 web 容器連接到 db 容器,web 容器將被容許訪問 db 容器的信息。
Docker 在兩個互聯的容器之間建立了一個安全隧道,並且不用映射它們的端口到宿主主機上。在啓動 db 容器的時候並無使用 -p
和 -P
標記,從而避免了暴露數據庫端口到外部網絡上。
Docker 經過 2 種方式爲容器公開鏈接信息:
環境變量
更新 /etc/hosts
文件
使用 env
命令來查看 web 容器的環境變量
$ sudo docker run --rm --name web2 --link db:db training/webapp env . . . DB_NAME=/web2/db DB_PORT=tcp://172.17.0.5:5432 DB_PORT_5000_TCP=tcp://172.17.0.5:5432 DB_PORT_5000_TCP_PROTO=tcp DB_PORT_5000_TCP_PORT=5432 DB_PORT_5000_TCP_ADDR=172.17.0.5 . . .
其中 DB_ 開頭的環境變量是供 web 容器鏈接 db 容器使用,前綴採用大寫的鏈接別名。
除了環境變量,Docker 還添加 host 信息到父容器的 /etc/hosts
的文件。下面是父容器 web 的 hosts 文件
$ sudo docker run -t -i --rm --link db:db training/webapp /bin/bash root@aed84ee21bde:/opt/webapp# cat /etc/hosts 172.17.0.7 aed84ee21bde . . . 172.17.0.5 db
這裏有 2 個 hosts,第一個是 web 容器,web 容器用 id 做爲他的主機名,第二個是 db 容器的 ip 和主機名。能夠在 web 容器中安裝 ping 命令來測試跟db容器的連通。
root@aed84ee21bde:/opt/webapp# apt-get install -yqq inetutils-ping root@aed84ee21bde:/opt/webapp# ping db PING db (172.17.0.5): 48 data bytes 56 bytes from 172.17.0.5: icmp_seq=0 ttl=64 time=0.267 ms 56 bytes from 172.17.0.5: icmp_seq=1 ttl=64 time=0.250 ms 56 bytes from 172.17.0.5: icmp_seq=2 ttl=64 time=0.256 ms
用 ping 來測試db容器,它會解析成 172.17.0.5
。*注意:官方的 ubuntu 鏡像默認沒有安裝 ping,須要自行安裝。
用戶能夠連接多個父容器到子容器,好比能夠連接多個 web 到 db 容器上。
在Docker 1.9以後,Docker正式宣佈能夠將Networking應用於生產環境中,而且能夠與Swarm以及Compose進行較好的結合。與傳統的Links相比,Networking具備如下優點:
容許不一樣物理主機或者虛擬主機上的容器進行通訊
使用了Networking的容器能夠很方便地進行中止、啓動或者重啓等操做而不用擔憂會影響到與其餘容器之間的鏈接
並不須要在鏈接到某個容器以前就直接建立它,換言之,Networking再也不像本來的Links同樣會依賴某個容器而存在
能夠直接使用docker network
命令來使用Networking,其中可使用docker network create
來建立一個新的網絡,在這個示例中,咱們會建立一個叫作frontend
的網絡而且在其中運行一個nginx容器:
$ docker network create frontend $ docker run -itd --net=frontend --name web nginx
咱們使用網絡來分割應用,乃至於分割應用中的不一樣模塊。在本例子中,咱們能夠建立另外一個包含了應用程序的網絡app
,而後將這個網絡與frontend
網絡相連,命令以下所示:
$ docker network create app $ docker run -itd --name myapp --net=app <my application container> $ docker network connect app web
這樣咱們的Nginx服務器就可使用myapp.app
這個主機名來鏈接到應用程序中。咱們建立兩個基於busybox的容器來進行嘗試:
$ docker run -d --name rose --net=frontend busybox top c1fa2dc7fa3a412b52b53f5facd25ba11e99c362d77be8cea4ff49f3d5e2cafc $ docker run --rm --net=frontend busybox ping -c 4 rose PING rose (172.19.0.2): 56 data bytes 64 bytes from 172.19.0.2: seq=0 ttl=64 time=0.122 ms 64 bytes from 172.19.0.2: seq=1 ttl=64 time=0.078 ms 64 bytes from 172.19.0.2: seq=2 ttl=64 time=0.098 ms 64 bytes from 172.19.0.2: seq=3 ttl=64 time=0.241 ms
咱們已將第二個容器附着到frontend
網路中,而且用ping
命令來進行內建的容器發現,咱們能夠用inspect
命令來查看網絡的詳情:
$ docker network inspect frontend [ { "Name": "frontend", "Id": "a639a457122020faa69a4ab906bc33217c9c6d73048f3dbbb69e53dbe5e0952c", "Scope": "local", "Driver": "bridge", "IPAM": { "Driver": "default", "Config": [ {} ] }, "Containers": { "c1fa2dc7fa3a412b52b53f5facd25ba11e99c362d77be8cea4ff49f3d5e2cafc": { "EndpointID": "976bab21d4a11cd21d5d1c1560f67f39ef15245662aeacf097eb1d5c148ed748", "MacAddress": "02:42:ac:13:00:02", "IPv4Address": "172.19.0.2/16", "IPv6Address": "" } }, "Options": {} } ]
在前端網絡以外,咱們也能夠建立一個自定義的後端網絡,用於鏈接其餘容器:
$ docker network create backend 09733cac7890edca439cdc3d476b4cd1959e44065217aa581d359575b8d2288f $ docker network connect backend rose $ docker network inspect backend { "name": "backend", "id": "09733cac7890edca439cdc3d476b4cd1959e44065217aa581d359575b8d2288f", "scope": "local", "driver": "bridge", "ipam": { "driver": "default", "config": [ {} ] }, "containers": { "c1fa2dc7fa3a412b52b53f5facd25ba11e99c362d77be8cea4ff49f3d5e2cafc": { "endpoint": "438730c588915dd54dc694efdb3a15c77bc5e86c744f5f87a65f6ac46b43e5ad", "mac_address": "02:42:ac:14:00:02", "ipv4_address": "172.20.0.2/16", "ipv6_address": "" } }, "options": {} } ]
再看一下容器中具體的網絡的設置:
$ docker inspect -f '{{ json .NetworkSettings }}' rose { "Bridge": "", "SandboxID": "b600bebe1e2bb6dee92335e6acfe49215c30c4964d7a982711ec12c6acca3309", "HairpinMode": false, "LinkLocalIPv6Address": "", "LinkLocalIPv6PrefixLen": 0, "Ports": {}, "SandboxKey": "/var/run/docker/netns/b600bebe1e2b", "SecondaryIPAddresses": null, "SecondaryIPv6Addresses": null, "EndpointID": "", "Gateway": "", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "IPAddress": "", "IPPrefixLen": 0, "IPv6Gateway": "", "MacAddress": "", "Networks": { "backend": { "EndpointID": "438730c588915dd54dc694efdb3a15c77bc5e86c744f5f87a65f6ac46b43e5ad", "Gateway": "172.20.0.1", "IPAddress": "172.20.0.2", "IPPrefixLen": 16, "IPv6Gateway": "", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "MacAddress": "02:42:ac:14:00:02" }, "frontend": { "EndpointID": "976bab21d4a11cd21d5d1c1560f67f39ef15245662aeacf097eb1d5c148ed748", "Gateway": "172.19.0.1", "IPAddress": "172.19.0.2", "IPPrefixLen": 16, "IPv6Gateway": "", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "MacAddress": "02:42:ac:13:00:02" } } }
而在容器中使用ifconfig
命令查看時:
$ docker exec rose ifconifg eth0 Link encap:Ethernet HWaddr 02:42:AC:13:00:02 inet addr:172.19.0.2 Bcast:0.0.0.0 Mask:255.255.0.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:27 errors:0 dropped:0 overruns:0 frame:0 TX packets:16 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:2238 (2.1 KiB) TX bytes:1208 (1.1 KiB) eth1 Link encap:Ethernet HWaddr 02:42:AC:14:00:02 inet addr:172.20.0.2 Bcast:0.0.0.0 Mask:255.255.0.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:16 errors:0 dropped:0 overruns:0 frame:0 TX packets:8 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:1296 (1.2 KiB) TX bytes:648 (648.0 B) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
而若是要將某個容器從網絡中斷開時,可使用以下命令:
$ docker network disconnect backend rose
這種網絡配置方式的初衷即將服務獨立出來成爲一個網絡中不一樣的容器之間相互交流的惟一信息。換言之,在實踐中,須要構建出大量的小型網絡,每一個網絡中只負責某個服務的通訊,而且不一樣的網絡之間應該是相互隔離的。一個典型的例子就是負載均衡器、前端、後端以及一個數據庫。
在建立網絡的時候咱們也能夠設置不少的自定義的配置:
--aux-address=map[] auxiliary ipv4 or ipv6 addresses used by Network driver -d, --driver="bridge" Driver to manage the Network --gateway=[] ipv4 or ipv6 Gateway for the master subnet --help=false Print usage --ip-range=[] allocate container ip from a sub-range --ipam-driver=default IP Address Management Driver -o, --opt=map[] set driver specific options --subnet=[] subnet in CIDR format that represents a network segment
咱們首先來看下--driver
選項,該選項能夠來選定具體的網絡驅動方式來管理網絡,目前Docker提供了以下兩種驅動器:
bridge -- This driver provides the same sort of networking via veth bridge devices that prior versions of docker use, it is the default.
overlay -- Not to be confused with the "overlay" storage driver (thanks overlayfs), this driver provides native multi-host networking for docker clusters. When using swarm, this is the default driver.
另外一個經常使用的選項是--ipam-driver
,用來肯定IP地址是如何分配的。目前Docker僅內置了一種IP地址分配方案,將來會添加上DHCP IAMP方式。