原文地址:LoveDev
Docker相對于傳統(tǒng)意義上的虛擬機最大的區(qū)別就在于傳統(tǒng)虛擬機是虛擬出一套硬件后,再在上面運行一個完整的操作系統(tǒng),再把需要運行的應(yīng)用裝在操作系統(tǒng)中運行。Docker在宿主的內(nèi)核中運行應(yīng)用進(jìn)程,沒有自己的內(nèi)核,沒有虛擬硬件,比起傳統(tǒng)虛擬機更加輕快。
Docker基本概念
- 鏡像:操作系統(tǒng)
- 容器:容器是獨立運行的一個或一組應(yīng)用,以及它們的運行態(tài)環(huán)境,鏡像和容器的關(guān)系就像是面向?qū)ο?/strong>中的類和實例
- 倉庫:鏡像需要存儲和分發(fā),倉庫用來存儲鏡像
Docker Registry
一個Docker Registry中可以包含多個倉庫
Docker Hub
最常使用的 Registry 公開服務(wù)是官方的 Docker Hub,這也是默認(rèn)的 Registry。
Docker Registry 公開服務(wù)
國內(nèi)訪問Registry 公開服務(wù)會有些慢(原因你懂得),國內(nèi)云服務(wù)商提供了針對 Docker Hub 的鏡像服務(wù)(Registry Mirror),這些鏡像服務(wù)被稱為加速器,常見的有 阿里云加速器、DaoCloud 加速器、靈雀云加速器等。
配置如下:
國內(nèi)也有一些云服務(wù)商提供類似于 Docker Hub 的公開服務(wù)。比如 時速云鏡像倉庫、網(wǎng)易云鏡像服務(wù)、DaoCloud 鏡像市場、阿里云鏡像庫等。
鏡像
獲取鏡像
$ docker pull [選項][Docker Registry地址]<倉庫名>:<標(biāo)簽>
例如:$ docker pull ubuntu
- Docker Registry地址:地址的格式一般是 <域名/IP>[:端口號]
,默認(rèn)地址是 Docker Hub。 - 倉庫名:如之前所說,這里的倉庫名是兩段式名稱,既 <用戶名>/<軟件名>
。對于 Docker Hub,如果不給出用戶名,則默認(rèn)為 library
,也就是官方鏡像。
運行鏡像
有個鏡像就可以以這個鏡像運行一個容器,以上面ubuntu為例運行一個容器。
$ docker run -it --rm ubuntu bash
-
docker run:就是運行容器的命令 -
-it:其實是兩個參數(shù),-i:交互式操作,-t:終端 -
--rm:容器退出后隨之將其刪除 -
ubuntu:用 ubuntu 鏡像為基礎(chǔ)來啟動容器 -
bash:放在鏡像名后的是命令,這里我們希望有個交互式 Shell,因此用的是 bash
$ docker run -d -p 22 -p 80:8080 ubuntu/kevin /usr/sbin/sshd -D
-
-d:容器后臺運行 -
-p:指定端口設(shè)置 -
-p 80:8080:端口映射,省略80表示把容器端口8080映射到一個動態(tài)端口 -
/usr/sbin/sshd:啟動 ssh 服務(wù) -
-D:容器長時間運行
注:exit:退出容器
列出鏡像
列出下載的鏡像用docker images命令。
列表中的鏡像體積綜合并非實際硬盤消耗,由于 Docker 鏡像是多層存儲結(jié)構(gòu),并且可以繼承、復(fù)用,因此不同鏡像可能會因為使用相同的基礎(chǔ)鏡像,從而擁有共同的層。
虛懸鏡像
鏡像既沒有倉庫名,也沒有標(biāo)簽,均為 <none>。此類鏡像為虛懸鏡像(dangling image) ,下面命令專門顯示此類鏡像
$ docker images -f dangling=true
這類鏡像已經(jīng)失去了存在的價值,可以隨意刪除,刪除命令如下
$ docker rmi $(docker images -q -f dangling=true)
中間層鏡像
為了加速鏡像構(gòu)建、重復(fù)利用資源,Docker 會利用 中間層鏡像。所以在使用一段時間后,可能會看到一些依賴的中間層鏡像。默認(rèn)的 docker images 列表中只會顯示頂層鏡像,如果希望顯示包括中間層鏡像在內(nèi)的所有鏡像的話,需要加 -a 參數(shù)。
$ docker images -a
列出部分鏡像
根據(jù)倉庫名列出鏡像
$ docker image ubuntu
根據(jù)倉庫名和標(biāo)簽
$ docker images ubunut:16.04
除此以外,docker images 還支持強大的過濾器參數(shù) --filter,或者簡寫 -f。希望看到在nginx之后建立的鏡像,可以用下面的命令
$ docker images -f since=nginx
希望看到nginx之前建立的鏡像,since換成before
保存鏡像
可用下面命令保存鏡像
$ docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
例如:docker commit -m "commit message" CONTAINER kevinlovedev/tomcat
-
-m:保存commit信息
刪除鏡像
可用下面命令刪除鏡像
$ docker rmi [OPTIONS] IMAGE [IMAGE...]
容器
啟動
所需主要命令為docker run
$ sudo docker run --name kevin -i -t ubuntu /bin/bash
-
--name:為容器指定名稱 -
-i:保證容器中STDIN是開啟的 -
-t:為創(chuàng)建的容器分配一個偽tty終端,這樣容器才能提供一個交互式shell
docker start命令直接將一個已經(jīng)終止的容器啟動運行
后臺運行
更多的時候,需要讓 Docker在后臺運行而不是直接把執(zhí)行命令的結(jié)果輸出在當(dāng)前宿主機下。此時,可以通過添加 -d 參數(shù)來實現(xiàn)。
獲取容器的輸出信息,可以通過 docker logs 命令。
啟動并進(jìn)入
大多數(shù)情況,我們需要啟動并且直接進(jìn)入到容器里面。
$ docker run -it 容器名 bash
終止
可用 docker stop [OPTIONS] CONTAINER [CONTAINER...] 來終止一個運行中的容器。
注:此命令后面是CONTAINER ID或者NAME參數(shù),可用docker ps查看
此外,當(dāng)Docker容器中指定的應(yīng)用終結(jié)時,容器也自動終止。 例如對于上一章節(jié)中只啟動了一個終端的容器,用戶通過 exit 命令或 Ctrl+d 來退出終端時,所創(chuàng)建的容器立刻終止。
終止?fàn)顟B(tài)的容器可以用 docker ps -a 命令看到。
$ docker rm $(docker ps -qa --no-trunc --filter "status=exited") # 刪除所有已退出容器
進(jìn)入容器
在使用 -d 參數(shù)時,容器啟動后會進(jìn)入后臺。 某些時候需要進(jìn)入容器進(jìn)行操作
可用docker attach [OPTIONS] CONTAINER命令進(jìn)入
導(dǎo)出容器
可用 docker export 命令。
$ docker export ubuntu:kevin > latest.tar
導(dǎo)入容器
可用 docker improt 命令。
注:用戶既可以使用 docker load 來導(dǎo)入鏡像存儲文件到本地鏡像庫,也可以使用 docker import 來導(dǎo)入一個容器快照到本地鏡像庫。這兩者的區(qū)別在于容器快照文件將丟棄所有的歷史記錄和元數(shù)據(jù)信息(即僅保存容器當(dāng)時的快照狀態(tài)),而鏡像存儲文件將保存完整記錄,體積也要大。此外,從容器快照文件導(dǎo)入時可以重新指定標(biāo)簽等元數(shù)據(jù)信息。
刪除容器
可用 docker rm 來刪除一個處于終止?fàn)顟B(tài)的容器
用 docker ps -a 命令可以查看所有已經(jīng)創(chuàng)建的包括終止?fàn)顟B(tài)的容器,如果數(shù)量太多要一個個刪除可能會很麻煩,用 docker rm $(docker ps -a -q) 可以全部清理掉。
倉庫
倉庫(Repository)是集中存放鏡像的地方。
搜索
用戶無需登錄即可通過 docker search 命令來查找官方倉庫中的鏡像,并利用 docker pull 命令來將它下載到本地。
另外,查找的時候通過 -s N 參數(shù)可以指定僅顯示評價為 N 星以上的鏡像(已經(jīng)過時,不推薦使用),最新版本使用
--filter過濾查找。
利用下面命令下載到本地
$ sudo docker pull centos
數(shù)據(jù)管理
容器中管理數(shù)據(jù)主要有兩種方式:
- 數(shù)據(jù)卷(Data volumes)
- 數(shù)據(jù)卷容器(Data volume containers)
數(shù)據(jù)卷
數(shù)據(jù)卷是一個可供一個或多個容器使用的特殊目錄,它繞過 UFS,可以提供很多有用的特性:
- 數(shù)據(jù)卷可以在容器之間共享和重用
- 對數(shù)據(jù)卷的修改會立馬生效
- 對數(shù)據(jù)卷的更新,不會影響鏡像
- 數(shù)據(jù)卷默認(rèn)會一直存在,即使容器被刪除
注意:數(shù)據(jù)卷的使用,類似于 Linux 下對目錄或文件進(jìn)行 mount,鏡像中的被指定為掛載點的目錄中的文件會隱藏掉,能顯示看的是掛載的數(shù)據(jù)卷。
容器和主機之間拷貝數(shù)據(jù)
拷貝容器文件到主機
$ docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH
例如:docker cp CONTAINER:/usr/local/tomcat/webapps/ROOT/index.html index.html
拷貝主機文件到容器
$ docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH
例如:docker cp index.html CONTAINER:/usr/local/tomcat/webapps/ROOT/index.html
Docker Machine
Docker Machine 是一個 docker 管理工具,主要解決兩個問題:
- docker 只能運行在 Linux 上
- docker 只能管理運行本機的 docker 鏡像
由于之前配置了 使用Docker Machine管理阿里云ECS ,Docker Machine使用一直不成功,報錯信息如下:
Error setting machine configuration from flags provided: --engine-install-url cannot be used with the virtualbox driver, use --virtualbox-boot2docker-url instead
原因在于配置了阿里的一些參數(shù),其中包括了MACHINE_DOCKER_INSTALL_URL,這個是報錯的主要原因,查了半天的資料終于爬出坑了
Push本地鏡像到DockerHub
首先鏡像名稱格式需要是DockerHubName/RepositoryName,例如kevinlovedev/tomcat,可用docker commit命令保存鏡像,/前面是DockerHub昵稱,/后面是DockerHub倉庫名。
保存鏡像成功之后,需要用docker login命令登陸到DockerHub。
最后用docker push命令提交本地鏡像到DockerHub倉庫。
Dockerfile
MAINTAINER:設(shè)置該鏡像的作者。語法如下:
MAINTAINER kevin "kevinlovemail@gmail.com"
build
使用了 docker build 命令進(jìn)行鏡像構(gòu)建。其格式為:
$ docker build -t ubuntu:kevin .
-t 指定了最終鏡像的名稱 ubuntu:kevin

常見問題
無法刪除一
Error response from daemon: conflict: unable to delete e4b9e4f71238 (must be forced) - image is being used by stopped container 1e359ad4363d
該容器是終止?fàn)顟B(tài),需要將此容器從終止?fàn)顟B(tài)刪除,然后再刪除鏡像
$ docker rm 1e359ad4363d # 刪除終止容器
$ docker rmi e4b9e4f71238 # 刪除鏡像
無法刪除二
Error response from daemon: conflict: unable to delete 1dc4f730b414 (cannot be forced) - image has dependent child images
先刪除依賴,如果 IMAGE ID 相同的話,根據(jù) TAG 刪除
$ docker rm REPOSITORY:TAG # 根據(jù)TAG刪除容器
語法錯誤
Error response from daemon: Unknown instruction: RUNCMD
can't initialize iptables
can't initialize iptables table `filter': Permission denied (you must be root)
啟動容器時加入?yún)?shù) --privileged=true