阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

Docker快速入门指南

498次阅读
没有评论

共计 14587 个字符,预计需要花费 37 分钟才能阅读完成。

Docker 使用 Go 语言开发,基于 Linux 内核的 cgroup、namespace 以及 AUFS 等技术对进程进行封装隔离,是一种操作系统层面的虚拟化技术。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。

Docker 则使用宿主机内核提供的隔离机制创建沙盒环境,容器内的应用进程直接运行于宿主的内核。因为容器内没有虚拟硬件和内核,容器在启动时间、执行效率、内存占用以及镜像大小等方面相对于传统虚拟机都拥有很大优势。

Docker 容器将程序及其运行环境打包在一起,镜像创建后可以在任何安装了 Docker 的系统上运行,无需配置运行环境,加之较小的镜像体积极大方便了协作开发和部署。

使用 Dockerfile 将镜像构建过程透明化,也便于开发和运维人员理解程序的运行环境。

Docker 相对于虚拟机的优势来源于它运行与宿主内核而减少了开销,这使得 Docker 不能虚拟不同的内核环境。也就是说我们可以很容易地在 Windows 操作系统上启动一个 Linux 虚拟机,但是在 Windows 上启动一个基于 Linux 的 Docker 容器则是很困难的事情。

docker 官方已经发布了 docker for macdocker for windows。目前 docker for mac 使用 MAC OS 内核提供的 HyperKit 虚拟化技术代替了 docker-toolbox 采用的使用 Linux 虚拟机提供支持的方式。

What’s Docker

cgroup 和 namespace 是 Linux 内核提供的两种隔离机制,是 Docker 虚拟化的技术基础:

  • cgroup: 全名 Control Groups, Linux 内核提供的用于监控和管理进程组占用资源的机制。这里的资源包括 CPU,内存和 IO 等硬件资源。
  • namespace: 为某个进程提供独立的空间,包括独立的:
    • 进程树:进程拥有独立的 init 进程及其下进程树
    • 文件系统:进程拥有独立的根目录 / 及其下目录树
    • 用户: 进程可以定义自己的用户,组和权限系统
    • 协议栈: 进程可以拥有独立的 ip 地址及 tcp/udp 端口空间
    • 其它

在了解隔离机制之后我们可以了解 Docker 中的两个核心概念:

  • 容器:容器的本质是进程,它拥有独立的命名空间。因此容器表现很像一个虚拟操作系统,拥有自己的进程树,文件系统等。
  • 镜像:镜像是容器运行依赖的文件系统,就像每个 Linux 操作系统时都需要挂载 root 文件系统/,镜像就是容器的 root 文件系统。

Docker 采用服务端 / 客户端架构:

  • 守护进程(dockerd): Docker 服务端每个 dockerd 下可以运行多个容器,此外还提供了镜像和容器管理的功能。
  • 客户端: 通过 API 与 dockerd 通信进行操作,官方提供了命令行客户端以及 Go 和 Python 语言的 SDK
  • 宿主机:用于运行 dockerd 及其容器的操作系统环境
  • Registry:Docker 镜像存储中心,用于管理和共享 docker 镜像。官方存储中心 DockerHub 中提供了大量官方和第三方镜像。

Docker 采用 UnionFS 技术将镜像设计为分层结构,即一个镜像分为多层,每一层在上一层的基础上构建(即存储增量)。在容器中只能看到所有层叠加后的结果,隐藏了分层的结构。因为镜像层会被其它层依赖,为了保证下层能正常工作,镜像层在创建后就无法进行修改。

Get Started

Docker 目前分为免费的社区版(CE)和付费的商业版(EE)两种, 这里我们选用社区版。Docker 官网上提供了各种常用操作系统的安装说明:

  • MAC
  • Ubuntu
  • Centos
  • Debian
  • Windows

下面看一个简单的示例:

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 来查看私有仓库中的镜像。

更多 Docker 相关教程见以下内容

Docker 安装应用(CentOS 6.5_x64) http://www.linuxidc.com/Linux/2014-07/104595.htm 

Ubuntu 16.04 服务器上配置使用 Docker  http://www.linuxidc.com/Linux/2017-06/145176.htm 

Ubuntu 15.04 下安装 Docker  http://www.linuxidc.com/Linux/2015-07/120444.htm 

Docker 安装实例 http://www.linuxidc.com/Linux/2017-04/142666.htm 

Docker 创建基础镜像  http://www.linuxidc.com/Linux/2017-05/144112.htm 

在 Ubuntu 15.04 上如何安装 Docker 及基本用法 http://www.linuxidc.com/Linux/2015-09/122885.htm 

Ubuntu 16.04 上 Docker 使用手记 http://www.linuxidc.com/Linux/2016-12/138490.htm 

使用 Docker 分分钟启动常用应用  http://www.linuxidc.com/Linux/2017-04/142649.htm 

Ubuntu 16.04 下 Docker 修改配置文件不生效解决办法  http://www.linuxidc.com/Linux/2017-05/143862.htm 

Docker 的详细介绍:请点这里
Docker 的下载地址:请点这里

本文永久更新链接地址:http://www.linuxidc.com/Linux/2018-01/150348.htm

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-21发表,共计14587字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中

星哥玩云

星哥玩云
星哥玩云
分享互联网知识
用户数
4
文章数
19351
评论数
4
阅读量
7993236
文章搜索
热门文章
星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛 NAS-6:抖音视频同步工具,视频下载自动下载保存 前言 各位玩 NAS 的朋友好,我是星哥!...
星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛 NAS-3:安装飞牛 NAS 后的很有必要的操作 前言 如果你已经有了飞牛 NAS 系统,之前...
我把用了20年的360安全卫士卸载了

我把用了20年的360安全卫士卸载了

我把用了 20 年的 360 安全卫士卸载了 是的,正如标题你看到的。 原因 偷摸安装自家的软件 莫名其妙安装...
再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

再见 zabbix!轻量级自建服务器监控神器在 Linux 的完整部署指南 在日常运维中,服务器监控是绕不开的...
飞牛NAS中安装Navidrome音乐文件中文标签乱码问题解决、安装FntermX终端

飞牛NAS中安装Navidrome音乐文件中文标签乱码问题解决、安装FntermX终端

飞牛 NAS 中安装 Navidrome 音乐文件中文标签乱码问题解决、安装 FntermX 终端 问题背景 ...
阿里云CDN
阿里云CDN-提高用户访问的响应速度和成功率
随机文章
星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛 NAS-3:安装飞牛 NAS 后的很有必要的操作 前言 如果你已经有了飞牛 NAS 系统,之前...
恶意团伙利用 PHP-FPM 未授权访问漏洞发起大规模攻击

恶意团伙利用 PHP-FPM 未授权访问漏洞发起大规模攻击

恶意团伙利用 PHP-FPM 未授权访问漏洞发起大规模攻击 PHP-FPM(FastCGl Process M...
星哥带你玩飞牛NAS-16:不再错过公众号更新,飞牛NAS搭建RSS

星哥带你玩飞牛NAS-16:不再错过公众号更新,飞牛NAS搭建RSS

  星哥带你玩飞牛 NAS-16:不再错过公众号更新,飞牛 NAS 搭建 RSS 对于经常关注多个微...
如何免费使用强大的Nano Banana Pro?附赠邪修的用法

如何免费使用强大的Nano Banana Pro?附赠邪修的用法

如何免费使用强大的 Nano Banana Pro?附赠邪修的用法 前言 大家好,我是星哥,今天来介绍谷歌的 ...
浏览器自动化工具!开源 AI 浏览器助手让你效率翻倍

浏览器自动化工具!开源 AI 浏览器助手让你效率翻倍

浏览器自动化工具!开源 AI 浏览器助手让你效率翻倍 前言 在 AI 自动化快速发展的当下,浏览器早已不再只是...

免费图片视频管理工具让灵感库告别混乱

一言一句话
-「
手气不错
如何安装2026年最强个人助理ClawdBot、完整安装教程

如何安装2026年最强个人助理ClawdBot、完整安装教程

如何安装 2026 年最强个人助理 ClawdBot、完整安装教程 一、前言 学不完,根本学不完!近期,一款名...
150元打造低成本NAS小钢炮,捡一块3865U工控板

150元打造低成本NAS小钢炮,捡一块3865U工控板

150 元打造低成本 NAS 小钢炮,捡一块 3865U 工控板 一块二手的熊猫 B3 工控板 3865U,搭...
开发者福利:免费 .frii.site 子域名,一分钟申请即用

开发者福利:免费 .frii.site 子域名,一分钟申请即用

  开发者福利:免费 .frii.site 子域名,一分钟申请即用 前言 在学习 Web 开发、部署...
240 元左右!五盘位 NAS主机,7 代U硬解4K稳如狗,拓展性碾压同价位

240 元左右!五盘位 NAS主机,7 代U硬解4K稳如狗,拓展性碾压同价位

  240 元左右!五盘位 NAS 主机,7 代 U 硬解 4K 稳如狗,拓展性碾压同价位 在 NA...
手把手教你,购买云服务器并且安装宝塔面板

手把手教你,购买云服务器并且安装宝塔面板

手把手教你,购买云服务器并且安装宝塔面板 前言 大家好,我是星哥。星哥发现很多新手刚接触服务器时,都会被“选购...