Docker快速指南

Docker使用Go語言開發,基於Linux內核的cgroup、namespace以及AUFS等技術對進程進行封裝隔離,是一種操做系統層面的虛擬化技術。因爲隔離的進程獨立於宿主和其它的隔離的進程,所以也稱其爲容器。html

Docker則使用宿主機內核提供的隔離機制建立沙盒環境,容器內的應用進程直接運行於宿主的內核。 由於容器內沒有虛擬硬件和內核,容器在啓動時間、執行效率、內存佔用以及鏡像大小等方面相對於傳統虛擬機都擁有很大優點。linux

Docker容器將程序及其運行環境打包在一塊兒,鏡像建立後能夠在任何安裝了Docker的系統上運行,無需配置運行環境, 加之較小的鏡像體積極大方便了協做開發和部署。nginx

使用Dockerfile將鏡像構建過程透明化,也便於開發和運維人員理解程序的運行環境。git

Docker相對於虛擬機的優點來源於它運行與宿主內核而減小了開銷,這使得Docker不能虛擬不一樣的內核環境。也就是說咱們能夠很容易地在Windows操做系統上啓動一個Linux虛擬機,可是在Windows上啓動一個基於Linux的Docker容器則是很困難的事情。redis

docker官方已經發布了docker for macdocker for windows。目前docker for mac使用MAC OS內核提供的HyperKit虛擬化技術代替了docker-toolbox採用的使用Linux虛擬機提供支持的方式。docker

目錄:json

What's Docker

cgroup和namespace是Linux內核提供的兩種隔離機制,是Docker虛擬化的技術基礎:ubuntu

  • cgroup: 全名Control Groups, Linux內核提供的用於監控和管理進程組佔用資源的機制。 這裏的資源包括CPU,內存和IO等硬件資源。
  • namespace: 爲某個進程提供獨立的空間,包括獨立的:
    • 進程樹: 進程擁有獨立的init進程及其下進程樹
    • 文件系統: 進程擁有獨立的根目錄/及其下目錄樹
    • 用戶: 進程能夠定義本身的用戶,組和權限系統
    • 協議棧: 進程能夠擁有獨立的ip地址及tcp/udp端口空間
    • 其它

在瞭解隔離機制以後咱們能夠了解Docker中的兩個核心概念:windows

  • 容器:容器的本質是進程,它擁有獨立的命名空間。所以容器表現很像一個虛擬操做系統,擁有本身的進程樹,文件系統等。
  • 鏡像:鏡像是容器運行依賴的文件系統,就像每一個Linux操做系統時都須要掛載root文件系統/,鏡像就是容器的root文件系統。

Docker採用服務端/客戶端架構:centos

  • 守護進程(dockerd): Docker服務端每一個dockerd下能夠運行多個容器,此外還提供了鏡像和容器管理的功能。
  • 客戶端: 經過API與dockerd通訊進行操做,官方提供了命令行客戶端以及Go和Python語言的SDK
  • 宿主機:用於運行dockerd及其容器的操做系統環境
  • Registry:Docker鏡像存儲中心,用於管理和共享docker鏡像。官方存儲中心DockerHub中提供了大量官方和第三方鏡像。

Docker採用UnionFS技術將鏡像設計爲分層結構,即一個鏡像分爲多層,每一層在上一層的基礎上構建(即存儲增量)。在容器中只能看到全部層疊加後的結果,隱藏了分層的結構。由於鏡像層會被其它層依賴,爲了保證下層能正常工做, 鏡像層在建立後就沒法進行修改。

Get Started

Docker目前分爲免費的社區版(CE)和付費的商業版(EE)兩種, 這裏咱們選用社區版。 Docker官網上提供了各類經常使用操做系統的安裝說明:

下面看一個簡單的示例:

finley@mbp:$ uname
Darwin
finley@mbp:$ docker run -it ubuntu
root@528ab91753d6:/# uname
Linux

在執行docker run命令後發現咱們已經從宿主機Mac的終端進入到了Linux終端中。 這個運行中的"Linux"就是容器,啓動這個虛擬的Linux環境所需的文件便是鏡像。

上面的示例中咱們使用docker代替了ubuntu虛擬機,對比之下docker在鏡像大小,啓動時間和運行內存佔用方面都具備巨大的優點。 

由於啓動docker容器的開銷和啓動相應進程的開銷基本相同, 所以徹底可使用docker代替原生進程, 避免複雜的編譯安裝配置過程。

$ docker run -p 6379:6379 -d redis
3a5748eef653
$ redis-cli
127.0.0.1:6379> keys *
(empty list or set)

這個示例中咱們一鍵安裝並啓動了redis-server。

在終端中輸入docker命令則會顯示全部命令和使用幫助, 在docker命令後添加--help選項能夠查看該命令的幫助信息, 如docker run --help能夠查看run命令的幫助。

鏡像

本節將簡單介紹如何搜索和管理鏡像, 爲介紹容器作準備。更多關於鏡像的構建和共享的內容將在下文中介紹。

docker images

docker images命令用於顯示本地全部鏡像:

REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest 00fd29ccc6f1 3 weeks ago 111MB
redis latest 1e70071f4af4 4 weeks ago 107MB

和其它軟件同樣docker鏡像也能夠演進出不一樣版本,tag用於標識鏡像的版本。

repository表明同一鏡像多個版本的集合, 它的值是一個URI用於全局惟一標識一組鏡像,如"registry.cn-hangzhou.aliyuncs.com/acs/agent"。

對於DockerHub中的鏡像則會省略倉庫的地址,諸如dorowu/ubuntu-desktop-lxde-vncubuntu就是DockerHub中的鏡像。

因而可知,repositorytag能夠惟一標識docker鏡像。

除此以外每一個鏡像還擁有一個摘要(DIGEST),docker images --digest能夠顯示鏡像的摘要。

DockerHub是docker官方提供的公有倉庫,docker search命令用於根據關鍵字搜索DockerHub中的鏡像:

format: docker search TERM
demo: docker search ubuntu
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
ubuntu Ubuntu is a ... 7076 [OK]
dorowu/ubuntu-desktop-lxde-vnc Ubuntu with openssh-server and NoVNC 156 [OK]

docker pull

docker pull命令用於從遠程下載鏡像,能夠經過NAME:TAGNAME@DIGEST的格式來指明目標鏡像。

當只提供了鏡像NAME時,默認下載tag爲latest的鏡像。

$docker pull ubuntu
$docker pull ubuntu:16.04
$docker pull ubuntu@sha256:fbaf303d18563e57a3c1a0005356ad102509b60884f3aa89ef9a90c0ea5d1212

NAME也能夠是私有倉庫中一個REPOSITORY的URI。

docker rmi

docker rmi用於刪除鏡像,可使用IMAGE IDREPOSITORY:TAG來標記一個容器。

容器

docker run

docker run命令用於新建一個容器並啓動, 是最重要的和最經常使用的docker命令之一。

format: docker run IMAGE CMD ARGS

docker run命令的標準執行流程包括:

  • 檢查本地是否包含指定的鏡像,若不存在就從公有倉庫下載
  • 在只讀的基礎鏡像層上掛載一個可讀寫層,建立容器的文件系統
  • 根據文件系統啓動容器
  • 將容器與宿主機橋接
  • 用指定的身份登陸容器,並在指定目錄下執行CMD ARGS參數指定的命令
  • 在命令執行完成後關閉容器

docker容器在命令執行完畢後會自動退出, 容器的生存週期僅決定於執行命令所需的時間。 若是在容器中執行bash等長期運行的命令, 就能夠保證容器長期運行。

docker run命令默認會把標準輸出流(stdout)重定向到終端,並與容器保持鏈接狀態(attach)。

在attach狀態下, 容器退出以前doceker run命令不會返回,而是在終端回顯容器的輸出。 若發出kill信號(如ctrl + c快捷鍵)殺死docekr run, 那麼容器也會提早退出。

容器對文件系統的修改在可讀寫層,不會對鏡像產生影響, 除非使用docker commit建立新的鏡像層。 容器退出後其文件系統仍將保存在磁盤中,下次啓動後會保留全部修改。

打開終端

docker run命令默認將容器的標準輸出流重定向到終端, 可是沒有將終端的標準輸入流(stdin)重定向到容器。 也就是說,容器沒法接收咱們在終端中輸入的命令。

使用-i--interactive選項會保持容器的輸入流(stdin)打開,即便docker run不與容器保持attach狀態。

docker run -i ubuntu bash命令能夠打開一個ubuntu終端, 該終端也能夠接受咱們輸入的指令。

和標準的Linux系統同樣,docker鏡像也爲用戶指定了默認終端。 使用-t--tty選項會打開一個虛擬終端(Pseudo-TTY)。

也就是說,docker run -it ubuntu命令能夠輕鬆地打開一個可交互ubuntu虛擬環境。

後臺運行

docker run命令默認與容器保持鏈接狀態(attach), -d--detach選項能夠與容器斷開鏈接。 docker run命令在顯示容器ID後當即返回,容器則會在後臺運行。

上文redis-server的示例即便用了-d選項, docker run當即返回, redis-server在後臺繼續運行。

$ docker run -p 6379:6379 -d redis
3a5748eef653
$ redis-cli
127.0.0.1:6379>

端口映射

如上文中redis-server示例, 咱們常用docker容器提供服務,所以須要docker容器監聽宿主機的某個端口。

docker run -p 6379:6379 -d redis將對宿主機TCP6379端口的訪問映射到容器的TCP6379端口。

-p 6379:6379/udp則能夠映射udp訪問(雖然對redis-server來講沒有意義)。 多個-p選項能夠映射多個端口docker run -p 80:8080 -p 8080:8081 -d my_server.

端口映射是將對宿主機某個端口的訪問映射到容器的某個端口上, 容器訪問宿主機端口不須要配置端口映射。


掛載數據卷

-v選項能夠將宿主機上某個目錄掛載到容器中的某個目錄

$ ls ~/myvol
history.txt
$ docker run -it -v ~/myvol:/app ubuntu
root@e690c508219e:/# ls /app
history.txt

上述指令將宿主機目錄~/myvol掛載到鏡像的/app目錄下,/app目錄下原來的內容會被隱藏而是顯示宿主機目錄~/myvol下的內容。

這種方式咱們稱爲在容器上掛載了數據卷,對數據卷的讀寫獨立於容器以外:

  • 容器對數據卷的修改將當即存儲到數據卷所在的(即宿主機的文件系統)上
  • 除非指明刪除數據卷,不然容器刪除不會對數據卷產生影響
  • 其它進程對數據卷的修改將當即生效

若數據卷~/myvol或掛載點/app不存在的時候, docker會自動建立空目錄。

docker提供了獨立於容器的數據卷管理功能,參考docker volume

爲容器命名

每一個容器都擁有一個惟一的CONTAINER ID來標識,但ID不便於記憶和使用。 所以在docker run建立容器時可使用--name選項來爲容器指定一個名稱。

在某個dockerd中容器名稱是惟一的, 咱們可使用容器名來惟一指定容器。

示例:docker run --name my_ubuntu -it ubuntu

退出時自動刪除

docker run --rm選項會在容器退出時自動刪除容器。 使用該命令時需謹慎, 容器一旦刪除便不可恢復。

自定義工做目錄

docker run -w PATH選項會在啓動容器時,使用PATH參數指定的路徑做爲工做目錄。

docker create

docker create命令與docker run指令極爲類似,區別在於docker run建立容器後自動啓動容器, 而docker create不自動啓動容器須要使用docker start命令來啓動。

docker ps

docker ps命令用於顯示容器的信息,默認狀況下顯示運行中的容器:

finley@mbp $ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3a5748eef653 redis "docker-entrypoint..." 3 hours ago Up 3 hours 0.0.0.0:6379->6379/tcp redis-server
c10921921bfb ubuntu "/bin/bash" 3 hours ago Up 52 seconds my_ubuntu

-a選項能夠顯示包括已中止容器在內的全部容器信息。

docker start

docker start命令用於啓動一個已中止的容器,默認狀況下不與容器鏈接(attach)也不將輸入重定向到容器。

$ docker run --name redis-server -p 6379:6379 redis
$ docker stop redis-server # 此時已經存在一個名爲redis-server的已中止容器
$ docker start redis-server
redis-server
$ redis-cli
127.0.0.1:6379>

若使用-a--attach選項將docker start與容器鏈接(attach), 終端將回顯容器輸出。

-i--interactive選項則會將輸入重定向到容器。

$ docker run --name my_ubuntu -it ubuntu
root@c10921921bfb # exit
# 此時已經存在一個名爲my_ubuntu的已中止容器
$ docker start -ai my_ubuntu
root@c10921921bfb:/#

docker exec

docker exec用於讓一個正在運行的容器執行命令,命令執行完成後docker exec將返回容器繼續運行。

$ docker run --name my_ubuntu -d ubuntu
$ docker exec my_ubuntu ls
home bin ...

默認狀況下docker exec與容器鏈接,-d--detach選項能夠不與容器鏈接而在後臺執行命令。

docker run命令相似, -i選項用於將標準輸入重定向到容器以便接收用戶輸入, -t選項能夠打開終端。

$docker exec -it my_ubuntu bash
root@c10921921bfb:/#

docker attach

docker attach命令用於與容器鏈接, 即將容器輸出流重定向到終端,終端輸入流重定向到容器。

$ docker attach my_ubuntu
# 再按一次回車
root@c10921921bfb:/#

當容器沒有輸出時終端中沒有回顯,可能令用戶誤覺得卡死。 attach以後再次輸入回車, bash將回顯命令行提示符。

attach狀態下ctrl + c快捷鍵會發送SIGKILL信號停止容器, 而ctrl + p, ctrl + q快捷鍵會退出attach容器繼續運行。

docker stop

docker stop用於終止容器的運行

$docker stop redis-server

docker stop命令會先發送SIGTERM信號要求容器中的進程執行退出操做,若達到超時時間(默認10s)容器仍未退出則會發送SIGKILL信號強制退出。

-t-time選項能夠秒爲單位設置強制殺死以前的等待時間:

$docker stop -t 20 redis-server

docker kill

docker kill命令將直接向容器發送SIGKILL命令中止容器:

$docker kill redis-server

-s--signal選項能夠向容器發送指定的信號:

docker kill -s SIGINT my_ubuntu

docker cp

docker cp命令負責在運行的容器和宿主機之間複製文件:

# format: docker cp FROM TO 
$ docker cp test.txt my_ubuntu:/root/test.txt
$ docker cp my_ubuntu:/root/test.txt test.txt

docker rm

docker rm用於刪除一個鏡像,經過鏡像ID或鏡像名來指定要刪除的鏡像, 默認狀況下只能刪除已退出的鏡像:

$ docker stop my_ubuntu
$ docker rm my_ubuntu

-f--force選項能夠強制刪除運行中的鏡像。

-v--volumes選項將刪除全部掛載的數據卷。

docker volume

docker volume系列指令用於獨立的管理數據卷, 請先閱讀docker run:掛載數據卷

create

將宿主機上一個目錄建立爲數據卷:

# format: docker volume create PATH
$ docker volume create myvol

ls

查看全部數據卷:

docker volume ls
DRIVER  VOLUME NAME
local   0c28b79a9b3f
local   myvol

inspect

查看某個數據卷的詳細信息:

docker volume inspect myvol
[
    {
        "CreatedAt": "2018-01-16T09:04:16Z",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/myvol/_data",
        "Name": "myvol",
        "Options": {},
        "Scope": "local"
    }
]

rm

刪除某個數據卷:

docker volume remove myvol
myvol

prune

刪除全部未被使用的數據卷:

docker volume prune
WARNING! This will remove all volumes not used by at least one container.
Are you sure you want to continue? [y/N] y
Total reclaimed space: 0B

使用數據卷

docker rundocker create命令可使用-v--volume選項來使用數據卷:

docker run -d -it -v myvol:/app ubuntu

docker會優先尋找數據卷列表中的myvol而不是當前目錄下的myvol子目錄。

若找不到myvol數據卷且當前目錄下也不存在myvol子目錄,docker會自動建立myvol數據卷不會再當前目錄下建立子目錄。

--mount選項雖然語法複雜,可是能夠配置更多選項:

docker run -it --mount source=my_volume,target=/app ubuntu

構建鏡像

上文中已經介紹瞭如何獲取和使用已有鏡像,接下來介紹如何構建本身的鏡像。

咱們能夠將本身的程序及其運行環境打包成Docker容器,部署到服務器或者共享給其它開發者免去配置環境的煩惱。

docker diff

前文已經提到過Docker鏡像採用分層結構,容器運行時沒法修改鏡像的內容,而是在鏡像層上掛載了一個可讀寫層。

docker diff命令能夠查看容器對鏡像的修改:

$ docker run --name my_ubuntu -it ubuntu 
# if exists: docker start -ai my_ubuntu
root@c10921921bfb:~# echo "Hello, from finley" > hello.txt
root@c10921921bfb:~# exit
➜  ~ docker diff my_ubuntu
C /root
A /root/.bash_history
A /root/hello.txt

咱們打開一個ubuntu容器在/root目錄中建立了hello.txt文件, 並在其中寫入"Hello, from finley"。

經過docker diff能夠看出這個操做產生了三個影響:

  • 工做目錄修改成/root, C表明變動工做目錄
  • 命令歷史.bash_history文件改變, A表明文件或目錄內容發生改變
  • 修改了文件hello.txt

docker commit

docker commit命令根據容器對鏡像的修改建立新的鏡像層

# format: docker commit CONTAINER REPOSITORY[:TAG]
$docker commit my_ubuntu my_ubuntu:2018_01_14
sha256:8096f47d8d6b80e52e617030938c7a83a9d50bafd73915d6952675e7126bb38a
$docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
my_ubuntu 2018_01_14 8096f47d8d6b Less than a second ago 111MB

-a--author選項能夠指定容器的做者, -m--message能夠添加備註信息:

$docker commit \
    -a "finley<finley@finley.pw>"  \
    -m "say hello" \
    my_ubuntu my_ubuntu:2018_01_14

-c--change選項能夠添加一系列Dockerfile指令,關於Dockerfile的內容咱們將在下文介紹。

docker tag

docker tag命令用於爲鏡像建立一個別名。

# format: docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
$ docker tag ubuntu my_ubuntu

TARGET_IMAGE能夠是私有倉庫REPOSITORY的URI,tag命令常常被用來協助將鏡像推送到私有倉庫。

docker history

docker history命令用於顯示鏡像各層的信息,即查看commit歷史:

$ docker history ubuntu

Dockerfile

docker commit命令雖然能夠很方便的建立新的鏡像,可是咱們在容器內操做(特別是嘗試性的操做)可能會在新鏡像內產生無關的內容,如命令歷史和日誌等。

Dockerfile是控制鏡像構建過程的腳本,使用Dockerfile能夠有效避免鏡像中包含無關內容。

Dockerfile中包含多行指令,每一個指令會在鏡像中建立一層。

FROM nginx
RUN echo '<h1>Hello from finley!</h1>' > /usr/share/nginx/html/index.html
$ docker build -t nginx_hello .
Step 1/2 : FROM nginx
  ---> 3f8a4339aadd
Step 2/2 : RUN echo '<h1>Hello from finley!</h1>' > /usr/share/nginx/html/index.html
  ---> Running in 2b3c5df09f9c
  ---> a918263d0f2f
Removing intermediate container 2b3c5df09f9c
Successfully built a918263d0f2f
Successfully tagged nginx_hello:latest
$ docker run --name nginx_hello -p 80:80 -d --rm nginx_hello
$ curl localhost
<h1>Hello from finley!</h1>

上面示例中咱們以nginx爲基礎構建了一個新鏡像,並啓動它提供服務。

在具體介紹Dockerfile的指令以前,咱們先介紹一下docker build命令。

docker build指令用於根據Dockerfile構建鏡像,一般該指令須要一個PATH參數來指定某個目錄作爲構建上下文(context)。

-f--file選項用於在構建上下文指定Dockerfile文件的路徑, 默認爲PATH/Dockerfile

-t--tag選項用於爲鏡像指定標籤,默認狀況下名稱仍然與基礎鏡像相同, 而-t NAME:TAG則會指定容器的名稱。

除了使用一個目錄做爲構建上下文以外,也可使用tar壓縮包、git倉庫做爲上下文, 甚至從標準輸入中讀取Dockerfile或tar進行構建。

接下來介紹經常使用的Dockerfile命令:

FROM

FROM指令用於指定構建容器的基礎鏡像,標記鏡像的語法與docker pull命令相同。

除了使用已存在的鏡像做爲基礎鏡像以外還有一個特殊的鏡像scratch, 它是一個空鏡像。

咱們能夠把靜態編譯的可執行文件放入空白鏡像中,由內核直接執行能夠極大的下降鏡像的體積。

RUN

RUN命令在鏡像中建立一個容器並執行指定指令,執行結束後commit修改做爲鏡像的一層。

上文示例中的Step2展現了RUN指令運行的過程:

  • 建立一箇中間容器(intermediate container): 2b3c5df09f9c
  • 運行命令echo '<h1>Hello from finley!</h1>' > /usr/share/nginx/html/index.html
  • 將修改提交,產生新的容器: a918263d0f2f
  • 刪除中間容器:2b3c5df09f9c

RUN命令有兩種參數格式:

  • 命令行式: RUN ls -al
  • 函數調用式: RUN ["ls", "-al"]

在實際執行過程當中命令行式指令會被映射爲RUN ["sh", "-c", "ls", "-al"]

由於每一個RUN指令都會生成一層鏡像, 所以最好用&&將多條指令鏈接而不是寫多條RUN指令。

COPY

COPY from to指令將文件或目錄從構建上下文(context)將文件複製到鏡像內部。

COPY ./config.json /root/config.json

WORKDIR

WORKDIR path命令用於指定容器的默認工做目錄。

WORKDIR命令對Dockerfile中的後續命令都有影響, 除非有另外一條WORKDIR命令修改了工做目錄

上文已經介紹過每條RUN指令都會建立一個臨時容器, 所以RUN cd PATH &&...只對同一條RUN中的後續指令有效。

USER

USER命令用於指定容器中的當前用戶:

RUN groupadd -r redis && useradd -r -g redis redis
USER redis
RUN redis-server

WORKDIR命令同樣,USER指令直到下一條USER指令以前始終有效。

CMD

CMD命令用於指定啓動容器的指令, 和RUN命令同樣有兩種格式。

EXPOSE

EXPOSE命令用於聲明須要暴露哪些接口,注意EXPOSE命令沒有創建端口映射, 須要在建立容器時啓動端口映射。

ENV

ENV命令用於爲容器設置環境變量:

ENV DEBUG=on VERSION='1.0'

ENTRYPOINT

ENTRYPOINT指令和CMD同樣,用於指定啓動容器的指令。 當指定了ENTRYPOINT以後,CMD命令的內容將被做爲參數傳遞給ENTRYPOINT指定的指令。

首先建立一個容器:

FROM ubuntu
CMD ls
$ docker build -t ls:v1 .
$ docker run --rm ls:v1
bin boot dev etc home lib ...

若是咱們試圖傳遞-al選項給ls以顯示更詳細的信息:

$ docker docker run --rm ls -al
container_linux.go:265: starting container process caused "exec: \"-al\": executable file not found in $PATH"

根據docker run的語法咱們試圖讓ls鏡像執行-al命令代替默認命令, 這固然行不通。

用ENTRYPOINT代替CMD:

FROM ubuntu
ENTRYPOINT ["ls"]

從新建立:

$ docker build -t ls:v2 .
$ docker run --rm ls:v2 -al
total 72
drwxr-xr-x   1 root root 4096 Jan 14 13:29 .
drwxr-xr-x   1 root root 4096 Jan 14 13:29 ..
-rwxr-xr-x   1 root root    0 Jan 14 13:29 .dockerenv
drwxr-xr-x   2 root root 4096 Dec  1 21:53 bin
drwxr-xr-x   2 root root 4096 Apr 12  2016 boot
drwxr-xr-x   5 root root  340 Jan 14 13:29 dev

ENTRYPOINT一般用於在執行容器CMD作一些準備工做, 好比官方redis鏡像中:

FROM alpine:3.4
...
RUN addgroup -S redis && adduser -S -G redis redis
...
ENTRYPOINT ["docker-entrypoint.sh"]

docker run --entrypoint CMD能夠用來更改容器的ENTRYPOINT。

共享鏡像

如今咱們已經瞭解如何構造本身的鏡像,接下來的問題是如何將鏡像分享給其它開發者或者部署到服務器。

docker export

docker export命令用於導出容器的快照, 默認輸出到標準輸出流,須要將輸出重定向到文件進行保存。

# format: docker export CONTAINER > TAR
$ docker export my_ubuntu > my_ubuntu.tar

或者使用-o--output選項

$ docker export -o my_ubuntu.tar my_ubuntu

docker export命令導出時會新建一個空白鏡像而後將容器文件系統的內容寫入,不包含容器基礎鏡像各層和tag等信息。

docker save

docker save用於將鏡像存儲爲tar壓縮包,默認導出到標準輸出流須要重定向以寫入文件

# format: docker save IMAGE > TAR
$ docker save ubuntu > ubuntu.tar

或者使用-o--output選項

$ docker save -o ubuntu.tar ubuntu

docker save命令會將鏡像各層及其tag信息導出到文件。

docker import

docker import命令用於導入tar格式的快照,生成的鏡像只有一層不導入各層和tag信息。

$ docker import my_ubuntu.tar my_ubuntu:v2

該指令與docker export相對用於導入容器鏡像,但也能夠導入docker save生成的tar文件。

docker load

docker load用於導入tar格式的鏡像副本,導入時保留各層和tag等元數據, 所以不須要指定鏡像名和tag。

默認從標準輸入流導入:

$ cat ubuntu.tar | docker load

或者使用-i--input選項:

docker load -i ubuntu.tar

docker load命令與docker save命令相對,由於缺乏元數據不能導入docker export生成的tar文件。

Registry

雖然docker支持以文件的形式導入導出鏡像,但這種方式對於共享鏡像來講仍十分不便。

Docker官方提供了一個registry鏡像,咱們可使用它輕鬆搭建私有倉庫。

$ mkdir registry
$ docker run -d \
    -p 5000:5000 \
    -v registry:/var/lib/registry \
    registry

-v選項將./registry目錄掛載到了容器中,這個目錄將用來實際存儲鏡像。

docker默認採用HTTPS方式推送和拉取鏡像,本文再也不介紹如何爲私有倉庫配置HTTPS證書。

私有倉庫能夠配置權限認證,僅受權用戶才能推送或拉取鏡像,這裏也再也不詳細介紹權限認證相關功能。

docker push

docker push命令用於將鏡像推送到倉庫,推送到的倉庫由鏡像的REPOSITORY屬性決定。

$ docker tag ubuntu 127.0.0.1:5000/finley/my_ubuntu:v1
$ docker docker push 127.0.0.1:5000/finley/my_ubuntu:v1
The push refers to a repository [127.0.0.1:5000/finley/my_ubuntu]
f17fc24fb8d0: Mounted from registry/my_ubuntu
6458f770d435: Mounted from registry/my_ubuntu
5a876f8f1a3d: Mounted from registry/my_ubuntu
d2f8c05d353b: Mounted from registry/my_ubuntu
48e0baf45d4d: Mounted from registry/my_ubuntu
v1: digest: sha256:f871d0805ee3ce1c52b0608108dbdf1b447a34d22d5c7278a3a9dd78fc12c663 size: 1357
$ curl 127.0.0.1:5000/v2/_catalog
{"repositories":["registry/my_ubuntu"]}

首先,使用docker tag命令給想要推送的鏡像unbuntu:latest建立一個別名127.0.0.1:5000/registry/my_ubuntu:v1

在這個URI中, 127.0.0.1:5000是Registry的地址,finley是私有倉庫中的一個命名空間, my_ubuntu是私有倉庫中的一個REPOSITORY。

訪問127.0.0.1:5000/v2/_catalog來查看私有倉庫中的鏡像。

相關文章
相關標籤/搜索