Docker的使用示例(二)

本文最后更新于:4 个月前

Docker 官方文档

现在我们重新回到需求,我们需要在docker中导入一些文件,制作镜像并且希望其顺利运行。在Docker的使用示例(一)中,我们可以Build简单的镜像,然后使用docker run从这个镜像运行容器,并且为其做一系列的配置。理论上,在镜像已经完成的时候,我们可以直接通过一条docker run命令来实现应用的运行。

但是我们也可以只运行简单的容器,用docker contianer来管理和监视容器,docker cp为容器导入文件,docker exec运行指定的命令,docker commit等做版本管理,来构建想要的镜像应用。另外还涉及到一些容器或者镜像的管理或者使用上的细节,在本文中我们暂时不会涉及Docker CLI的volume或者dockerfile。

由于文档阅读和实践和认知的不统一,内容编排上有些可能不太符合认识的过程,敬请谅解。

容器的运行

假定我们已经有了一个容器,这个容器至少是linux runtime,那么我们可以把这个容器当成虚拟机进行操作。

docker container

docker container是一个命令集,帮助我们管理容器。实际上整个容器的运行部分全都是docker container命令,只不过因为有些比较常用会把中间的container关键字省去,比如docker run其实等价于docker container run。这里我们介绍一些常用的命令,如果存在省略关键字而功能同样的命令如docker rundocker container run,则在一条介绍了用法,另外一条给出超链接,从而方便日后的归档查询和使用。

docker container run

等同于docker run命令,参见docker run

docker container ls

1
docker container ls [OPTIONS]

选项:

Name, shorthand Default Description
–all , -a Show all containers (default shows just running)
–filter , -f Filter output based on conditions provided
–format Pretty-print containers using a Go template
–last , -n -1 Show n last created containers (includes all states)
–latest , -l Show the latest created container (includes all states)
–no-trunc Don’t truncate output
–quiet , -q Only display container IDs
–size , -s Display total file sizes

docker container start|restart|pause|stop|kill

docker容器的启停关闭和杀掉容器进程,这里省略部分新特性,如果遇到了可以查一下官方文档。

  1. docker container start

    1
    docker container start [OPTIONS] CONTAINER [CONTAINER...]

    选项:

    Name, shorthand Default Description
    –attach , -a Attach STDOUT/STDERR and forward signals
    –detach-keys Override the key sequence for detaching a container
    –interactive , -i Attach container’s STDIN

    关于标准输入输出流,也就是docker attach/detach这些操作,由于我对于这个概念还有一些模糊的地方,所以只了解基本用法,但是应该不影响我们操作。

  2. docker container restart

    1
    docker container restart [OPTIONS] CONTAINER [CONTAINER...]

    选项:

    Name, shorthand Default Description
    –time , -t 10 Seconds to wait for stop before killing the container
  3. docker container pause

    1
    docker pause CONTAINER [CONTAINER...]

    docker container pause命令会停止容器内执行的所有进程。

  4. docker container stop

    1
    docker container stop [OPTIONS] CONTAINER [CONTAINER...]

    选项:

    Name, shorthand Default Description
    –time , -t 10 Seconds to wait for stop before killing it
  5. docker container kill

    1
    docker container kill [OPTIONS] CONTAINER [CONTAINER...]

    选项:

    Name, shorthand Default Description
    –signal , -s KILL Signal to send to the container

docker container cp

等同于docker cp,参见docker cp

docker container exec

等同于docker exec,参见docker exec

docker container port

等同于docker port,参见docker port

docker container commit

docker container commit等于docker commit。参见docker commit

docker cp

1
docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-

docker cpSRC_PATH的内容复制到DEST_PATH。可以从本机将文件复制到容器,反之亦然。加上在SRC_PATH或者DEST_PATH上加上-,就可以从STDIN中读取tar archive或者将其输入到STDOUT。容器既可以是正在运行的或者是已经终止的,PATH既可以是文件夹也可以是文件。

docker cp命令假设容器的路径都是相对于容器的根目录。所以加上/是可选的项,不加一样从根目录开始解析路径。

docker cp命令和Unixcp -a命令类似,文件夹的内容如果权限允许的话都可以递归复制。复制后文件夹的权限被设置为user和primary group。例如,如果是容器内根用户创建的属于UID:GID的文件,复制到本机就是属于使用docker cp的用户。

加入-a命令,文件的所属被设为source的所属。命令默认不去复制link的target,-L选项可以解析link。在DEST_PATH不存在的时候,文件夹会被创建,SRC_PATH的内容而非父文件夹被复制进DEST_PATH。当DEST_PATH存在的时候,末尾不加/.则复制父文件夹,加./则复制文件夹内容。

:是CONTAINER与PATH之间的定界符,也可以用于描述本机文件。

示例:

  • 复制本地文件到容器

    1
    docker cp ./some_file CONTAINER:/work
  • 复制容器文件夹到本地

    1
    docker cp CONTAINER:/var/logs/ /tmp/app_logs
  • 复制容器文件到标准输出流

    1
    docker cp CONTAINER:/var/logs/app.log - | tar x -O | grep "ERROR"

    传输的是一个tar stream所以需要解码。

边界情况:docker cp命令无法复制/proc/sys/dev,tmpfs和mounts等用户在容器中创建的资源,但是可以通过在docker exec运行tar命令来进行。下面命令展示如何将SRC_PATH的内容绑定到标准输入流再从DEST_PATH中解析:

1
docker exec CONTAINER tar Ccf $(dirname SRC_PATH) - $(basename SRC_PATH) | tar Cxf DEST_PATH -
1
tar Ccf $(dirname SRC_PATH) - $(basename SRC_PATH) | docker exec -i CONTAINER tar Cxf DEST_PATH -

这里DEST_PATH必须是文件夹。

docker exec

参见docker exec

通常情况下我们运行:

1
docker exec -it CONTAINER /bin/bash

然后进入容器进行操作就完全够了。

docker port

1
docker port CONTAINER [PRIVATE_PORT[/PROTO]]

显示某个容器的端口映射。

docker port

Docker管理

对于镜像和容器的版本管理和维护,加载或者导出。

docker commit

1
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]

通常更建议使用dockerfile来对镜像进行维护,但是也可以通过这种方式在容器中开启一个交互命令进行debug,也可以讲一个正在工作的数据集上传到另外一个服务器上。docker commit命令不涉及volume的操作。

OPTIONS:

Name, shorthand Default Description
–author , -a Author (e.g., “John Hannibal Smith hannibal@a-team.com“)
–change , -c Apply Dockerfile instruction to the created image
–message , -m Commit message
–pause , -p true Pause container during commit

默认情况下,当commiting镜像时,正在commited的容器和进程会被暂停,以减小数据崩溃的可能性。如果希望取消,可以置--pauseflag为False

--change可以将任意的dockerfile命令应用到images当中。

commit容器和新的configurations:
commit a container with configurations

commit容器和新的命令:
commit a container with new CMD and EXPOSE instructions

docker save

commit是将容器的改变传给镜像,而save是将一个或者多个镜像打包成tar包,默认绑定在STDOUT上。这个包可以包含一个镜像的所有父层,以及其所有带标签的版本,也可以限定其标签。

1
docker save [OPTIONS] IMAGE [IMAGE...]

选项:

Name, shorthand Default Description
–output , -o Write to a file, instead of STDOUT
1
2
3
4
docker save busybox > busybox.tar
docker save --output busybox.tar busybox
docker save -o fedora-all.tar fedora
docker save -o fedora-latest.tar fedora:latest

上述命令都是写入tar包,但是第一条是将标准输出流写入文件。

也可以同时打包成gz:

1
docker save myimage:latest | gzip > myimage_latest.tar.gz

或者选择标签:

1
docker save -o ubuntu.tar ubuntu:lucid ubuntu:saucy

docker load

从一个tar(可以是被压缩的gzip,bzip2,或者xz)或者标准输入流中载入一个镜像。会复原原本的镜像和其标签。

1
docker load [OPTIONS]
Name, shorthand Default Description
–input , -i Read from tar archive file, instead of STDIN
–quiet , -q Suppress the load output

例子:

1
2
docker load < busybox.tar.gz
docker load --input fedora.tar

docker image save&load

docker savedocker image save基本一致;docker loaddocker image load基本一致。

docker export

docker save命令保存的是镜像,而docker export命令是将容器的文件系统打包成tar。但是docker export并不会将容器数据卷的内容输出,如果数据卷被mount在容器的一个文件夹中,也只会将本身就在文件夹中从内容输出。

1
docker export [OPTIONS] CONTAINER

选项:

Name, shorthand Default Description
–output , -o Write to a file, instead of STDOUT

docker save类似:

1
2
docker export red_panda > latest.tar
docker export --output="latest.tar" red_panda

docker import

引入tar或者其他来源的内容创建一个文件系统镜像。

1
docker import [OPTIONS] file|URL|- [REPOSITORY[:TAG]]

URL指向dockerhost上的任一带有文件系统或者单纯文件的archive(.tar, .tar.gz, .tgz, .bzip, .tar.xz, or .txz)。docker在import的时候会自动解包,如果是单个文件,一定要写其相对于host的绝对路径,如果是远端,则URI一定要以http://或者https://开头。

Name, shorthand Default Description
–change , -c Apply Dockerfile instruction to the created image
–message , -m Set commit message for imported image
–platform Set platform if server is multi-platform capable

基本和docker commit的命令类似。

从远端import

1
docker import https://example.com/exampleimage.tgz

import本地文件

1
cat exampleimage.tgz | docker import - exampleimagelocal:new
1
cat exampleimage.tgz | docker import --message "New image imported from tarball" - exampleimagelocal:new
1
docker import /path/to/exampleimage.tgz
1
docker import /path/to/exampleimage.tgz

import本地文件夹

1
sudo tar -c . | docker import - exampleimagedir
1
sudo tar -c . | docker import --change "ENV DEBUG=true" - exampleimagedir

docker image import

docker image importdocker import相同。

总结

了解了上述这些,我们应该很容易从image构建container,也很容易将container的改变传到image,在没有涉及到dockerfile的情况下,我们已经完全可以构建并且运行docker应用了。


Docker的使用示例(二)
https://coldison.github.io/2023/02/14/Docker的使用示例(二)/
作者
Coldison
发布于
2023年2月14日
更新于
2022年10月11日
许可协议