docker命令
1. 源设置
/etc/docker/daemon.json
1 |
|
2. 镜像仓库
docker login [OPTIONS] [SERVER]
登录镜像仓库
-u:用户名
-p:密码
example:
1 |
|
docker logout
登出镜像仓库
docker search [OPTIONS] images
–automated :只列出automated build类型的镜像
–no-trunc:显示完整的镜像描述
-s:列出收藏数不小于指定值的镜像
example:
1
docker search -s 20 unbuntu //列出收藏数不小于20的ubuntu镜像
docker pull [OPTIONS] name[:TAG@DIGEST]
-a:拉起所有tagged镜像
–disable-content-trust:忽略镜像校验,默认开启
example:
1
docker pull unbuntu //拉去ubuntu最新版镜像
docker push [OPTIONS] NAME[:TAG]
将本地镜像上传到镜像仓库,首先要登录到镜像仓库,还要登录到Docker Hub创建对应名称的仓库,然后用tag命令给镜像打标签,只有打完标签后才能上传。
docker tag [OPTIONS] IMAGE[:TAG] [REGISTRYHOST/] [USERNAME/] NAME[:TAG]
标记本地镜像,归入某一仓库。
完整版push:
1
2
3docker tag ubuntu:latest eara0/ubuntu:v1
docker Hub创建对应仓库
docker push area0/ubuntu:v1
3. 生命周期
docker run
创建一个新的容器并运行
常用指令
1
2
3
4
5
6
7
8-i选项表示使用交互模式,始终保持输入流开放
-t选项表示分配一个伪终端,一般两个参数结合时使用-it,即可在容器中利用打开的伪终端进行交互操作
-d选项: 后台运行容器,并返回容器ID--name选项可以指定docker run命令启动的容器名字,若无此选项,Docker 将为容器随机分配一个名字
-c选项:用于给运行在容器中的所有进程分配CPU的shares值,这是一个相对权重,实际的处理速度还与宿主机的CPU相 关
-m选项:用于限制为容器中所有进程分配的内存总量,以B、K、M、G为单位-v选项:用于挂载一个volume,可以用多个
-v参数同时挂载多个volume。volume的格式为[host-dir]:[container-dir]:[rw|ro]
-p选项:用于将容器内部端口映射给宿主机的端口,其常见格式为:主机(宿主)端口:容器内部端口
-P选项:随机端口映射,容器内部端口随机映射到宿主机的端口example:
1
2docker run -it ubuntu /bin/bash //启动并返回终端
docker run -itd --name ubuntu-test ubuntu /bin/bash //后台启动并返回终端
docker start
启动一个或多个已经停止的容器
1
docker start b750bbbcfd88
docker stop
停止一个运行的容器
1
docker stop b750bbbcfd88
docker restart
重启容器
1
docker restart b750bbbcfd88
docker rm
删除容器
1
2
3-f :通过SIGKILL信号强制删除一个运行中的容器
-l :移除容器间的网络连接,而非容器本身
-v :-v 删除与容器关联的卷1
docker rm -f b750bbbcfd88
docker kill
杀掉运行中的容器
1
docker kill -s kill b750bbbcfd88
PS.常见rm和kill组合命令
杀掉所有正在运行的容器
1
docker kill $(docker ps -a -q)
删除所有正在运行的容器
1
docker rm $(docker ps -a -q)
docker exec和docker attach
在运行中的容器执行命令
attach:
1
docker attach 1e560fca3906 // 如果从这个容器退出,会导致容器的停止。
exec:
1
2
3-d :分离模式: 在后台运行
-i :即使没有附加也保持STDIN 打开
-t :分配一个伪终端example:
1
docker exec -it 243c32535da7 /bin/bash //返回shell
4. 导出和导入
- export和import
docker export
导出镜像
1
docker export 1e560fca3906 > ubuntu.tar
docker import
导入镜像
1
2cat docker/ubuntu.tar | docker import - demo/ubuntu:v1
docker import http://demo.com //支持从url导入save和load
- docker save
将指定镜像保存为tar文件
1
docker save -o nginx.tar nginx:last
- docker load
导入使用docker save命令导出的镜像
1
docker load -i nginx.tar
docker save和docker export的区别
- docker save保存的是镜像(image),docker export保存的是容器(container);
- docker load用来载入镜像包,docker import用来载入容器包,但两者都会恢复为镜像;
- docker load不能对载入的镜像重命名,而docker import可以为镜像指定新名称。
5.端口
1 |
|
6. 镜像管理
docker images
通过docker images命令可以列出主机上的镜像,默认只列出最顶层的镜像,可以使用-a选项显示出所有镜像
1
docker images -a
docker rmi
docker rmi命令用于删除镜像,删除镜像时,如果已有基于该镜像启动的容器存在,则无法直接删除,需要先用rm命令删除容器。这两个子命令都提供 -f 选项,可强制删除存在容器的镜像或启动中的容器。
1
docker rmi kali:10.1
docker commit
docker commit命令可以将一个容器固化为一个新的镜像。当需要制定特定的镜像时,会进行修改容器的配置,比如在容器中安装一些特定的工具等,通过commit命令可以将这些修改保存起来,使其不会因为容器的停止而丢失。
- -a:提交的镜像作者
- -c :使用Dockerfile指令来创建镜像
- -m :提交时的说明文字
- -p :在commit时,将容器暂停
1
docker commit -a "demo" 66d682605023 kali:10.1
7. 运维相关
docker ps
常用的选项有-a和-l,-a选项可以查看所有的容器,包括停止的容器;-l选项只查看最新创建的容器,包括不在运行的容器
docker rename
重命名容器
1
docker rename 12312391 newname
docer stats
显示容器资源的使用情况统计信息
1
docker stats 12312391
docker top
查看运行的进程信息
docker cp
主机与容器之间数据拷贝
example:
将本目录下的test.php文件复制到容器的’/var/www/html/‘目录下
1
docker cp test.php 5198ec963e43:/var/www/html/
将容器内’/var/www/html/index.php’复制到本机/root目录下:
1
docker cp 5198ec963e43:/var/www/html/index.php /root/
docker diff
查看容器文件结构
1
docker diff 5198ec963e43
docker events
从服务器获取实时时间
1
2
3-f:根据条件过滤事件
--since:从指定的时间戳后显示所有事件
--until:流水时间显示到指定的时间为止1
docker events --since=""2020-01-21"
docker history
查看指定镜像的创建历史
1
docker history TAG
docker inspect
来查看 Docker 的底层信息
1
docker inspect 243c32535da7
docker logs
查看容器打印日志
1
docker logs -f bf08b7f2cd89 //查看日志
8. 文件映射
- 主机卷的映射
1 |
|
通过docker创建卷
此种方式不必考虑权限问题,docker会为我们处理好权限。
- 创建 docker volume create –name v1
- 查看 docker inspect v1
- 删除数据卷 docker volume rm v1
创建容器
1
docker run -d -v v1:/usr/local/nginx --name nginx //v1为创建的卷
使用共享存储的映射
将一台主机做为nfs主机, 创建相应的文件夹,并将其共享给docker的两台主机,两台docker主机将分享的文件夹映射到容器中,使得对应的容器可以共享到nfs主机的内容。可以将http等服务器的相应的页面文件夹使用这种形式,从而实现多个容器跑一个业务
nfs主机配置【192.168.6.77】
1 |
|
9. 网络设置
1 |
|
配置 DNS
可以在宿主机的 /etc/docker/daemon.json 文件中增加以下内容来设置全部容器的 DNS:
1 |
|
设置后,启动容器的 DNS 会自动配置为 114.114.114.114 和 8.8.8.8。
配置完,需要重启 docker 才能生效。
启动时设置DNS
1 |
|
10 .Dockerfile
什么是 Dockerfile?
Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。
- 案例:
创建Dockerfile文件
vi Dockerfile
1 |
|
创建镜像
1 |
|
FROM 和 RUN 指令的作用
FROM:定制的镜像都是基于 FROM 的镜像,这里的 nginx 就是定制需要的基础镜像。后续的操作都是基于 nginx。
RUN:用于执行后面跟着的命令行命令。有以下俩种格式:
shell 格式:
1 |
|
exec 格式:
1 |
|
注意:Dockerfile 的指令每执行一次都会在 docker 上新建一层。所以过多无意义的层,会造成镜像膨胀过大。例如:
1 |
|
上下文路径
上面中,有提到指令最后一个 . 是上下文路径,那么什么是上下文路径呢?
1 |
|
上下文路径,是指 docker 在构建镜像,有时候想要使用到本机的文件(比如复制),docker build 命令得知这个路径后,会将路径下的所有内容打包。
解析:由于 docker 的运行模式是 C/S。我们本机是 C,docker 引擎是 S。实际的构建过程是在 docker 引擎下完成的,所以这个时候无法用到我们本机的文件。这就需要把我们本机的指定目录下的文件一起打包提供给 docker 引擎使用。
如果未说明最后一个参数,那么默认上下文路径就是 Dockerfile 所在的位置。
注意:上下文路径下不要放无用的文件,因为会一起打包发送给 docker 引擎,如果文件过多会造成过程缓慢。
指令详解
COPY
复制指令,从上下文目录中复制文件或者目录到容器里指定路径。
格式:
1 |
|
**[–chown=:]**:可选参数,用户改变复制到容器内文件的拥有者和属组。
**<源路径>**:源文件或者源目录,这里可以是通配符表达式,其通配符规则要满足 Go 的 filepath.Match 规则。例如:
1 |
|
**<目标路径>**:容器内的指定路径,该路径不用事先建好,路径不存在的话,会自动创建。
ADD
ADD 指令和 COPY 的使用格式一致(同样需求下,官方推荐使用 COPY)。功能也类似,不同之处如下:
- ADD 的优点:在执行 <源文件> 为 tar 压缩文件的话,压缩格式为 gzip, bzip2 以及 xz 的情况下,会自动复制并解压到 <目标路径>。
- ADD 的缺点:在不解压的前提下,无法复制 tar 压缩文件。会令镜像构建缓存失效,从而可能会令镜像构建变得比较缓慢。具体是否使用,可以根据是否需要自动解压来决定。
因此在 COPY 和 ADD 指令中选择的时候,可以遵循这样的原则,**所有的文件复制均使用 COPY 指令,仅在需要自动解压缩的场合使用 ADD 。**
CMD
类似于 RUN 指令,用于运行程序,但二者运行的时间点不同:
- CMD 在docker run 时运行。
- RUN 是在 docker build。
作用:为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束。CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。
注意:如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效。
格式:
1 |
|
推荐使用第二种格式,执行过程比较明确。第一种格式实际上在运行的过程中也会自动转换成第二种格式运行,并且默认可执行文件是 sh。
ENTRYPOINT
类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。
但是, 如果运行 docker run 时使用了 –entrypoint 选项,此选项的参数可当作要运行的程序覆盖 ENTRYPOINT 指令指定的程序。
优点:在执行 docker run 的时候可以指定 ENTRYPOINT 运行所需的参数。
注意:如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。
格式:
1 |
|
当指定了 ENTRYPOINT 后, CMD 的含义就发生了改变,不再是直接的运行其命令,而是将CMD 的内容作为参数传给 ENTRYPOINT 指令,换句话说实际执行时,将变为:
1 |
|
可以搭配 CMD 命令使用:一般是变参才会使用 CMD ,这里的 CMD 等于是在给 ENTRYPOINT 传参,以下示例会提到。
示例:
假设已通过 Dockerfile 构建了 nginx:test 镜像:
1 |
|
1、不传参运行
1 |
|
容器内会默认运行以下命令,启动主进程。
1 |
|
2、传参运行
1 |
|
容器内会默认运行以下命令,启动主进程(/etc/nginx/new.conf:假设容器内已有此文件)
1 |
|
那么有了 CMD 后,为什么还要有 ENTRYPOINT 呢?这种 ""
有什么好处么?让我们来看几个场景。
场景一:让镜像变成像命令一样使用
假设我们需要一个得知自己当前公网 IP 的镜像,那么可以先用 CMD 来实现:
1 |
|
假如我们使用 docker build -t myip .
来构建镜像的话,如果我们需要查询当前公网 IP,只需要执行:
1 |
|
嗯,这么看起来好像可以直接把镜像当做命令使用了,不过命令总有参数,如果我们希望加参数呢?比如从上面的 CMD 中可以看到实质的命令是 curl ,那么如果我们希望显示 HTTP头信息,就需要加上 -i 参数。那么我们可以直接加 -i 参数
给 docker run myip
么?
1 |
|
我们可以看到可执行文件找不到的报错, executable file not found
。之前我们说过,跟在镜像名后面的是 command ,运行时会替换 CMD 的默认值。因此这里的 -i 替换了原来的 CMD ,而不是添加在原来的 curl -s http://ip.cn
后面。而 -i 根本不是命令,所以自然找不到。
那么如果我们希望加入 -i 这参数,我们就必须重新完整的输入这个命令:
1 |
|
这显然不是很好的解决方案,而使用 ENTRYPOINT 就可以解决这个问题。现在我们重新用 ENTRYPOINT 来实现这个镜像:
1 |
|
这次我们再来尝试直接使用 docker run myip -i :
1 |
|
可以看到,这次成功了。这是因为当存在 ENTRYPOINT 后, CMD 的内容将会作为参数传给 ENTRYPOINT ,而这里 -i 就是新的 CMD ,因此会作为参数传给 curl ,从而达到了我们预期的效果。
场景二:应用运行前的准备工作
启动容器就是启动主进程,但有些时候,启动主进程前,需要一些准备工作。比如 mysql 类的数据库,可能需要一些数据库配置、初始化的工作,这些工作要在最终的 mysql 服务器运行之前解决。
此外,可能希望避免使用 root 用户去启动服务,从而提高安全性,而在启动服务前还需要以 root 身份执行一些必要的准备工作,最后切换到服务用户身份启动服务。或者除了服务外,其它命令依旧可以使用 root 身份执行,方便调试等。
这些准备工作是和容器 CMD 无关的,无论 CMD 为什么,都需要事先进行一个预处理的工作。这种情况下,可以写一个脚本,然后放入 ENTRYPOINT 中去执行,而这个脚本会将接到的参数(也就是 )作为命令,在脚本最后执行。比如官方镜像 redis 中就是这么做的:
1 |
|
可以看到其中为了 redis 服务创建了 redis 用户,并在最后指定了 ENTRYPOINT 为 dockerentrypoint.sh 脚本。
1 |
|
该脚本的内容就是根据 CMD 的内容来判断,如果是 redis-server 的话,则切换到 redis 用户身份启动服务器,否则依旧使用 root 身份执行。比如:
1 |
|
而使用 service nginx start
命令,则是希望 systemd
来以后台守护进程形式启动 nginx 服务。而刚才说了 CMD service nginx start
会被理解为 CMD [ “sh”, “-c”, “service nginxstart”] ,因此主进程实际上是 sh 。那么当 service nginx start 命令结束后, sh 也就结束了, sh 作为主进程退出了,自然就会令容器退出。
正确的做法是直接执行 nginx 可执行文件,并且要求以前台形式运行。比如:
1 |
|
EXPOSE
仅仅只是声明端口。
EXPOSE 指令是声明运行时容器提供服务端口,这只是一个声明,在运行时并不会因为这个声明应用就会开启这个端口的服务。
作用:
- 帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射。
- 在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。
格式:
1 |
|
WORKDIR
指定工作目录。用 WORKDIR 指定的工作目录,会在构建镜像的每一层中都存在。(WORKDIR 指定的工作目录,必须是提前创建好的)。
docker build 构建镜像过程中的,每一个 RUN 命令都是新建的一层。只有通过 WORKDIR 创建的目录才会一直存在。
格式:
1 |
|
USER
用于指定执行后续命令的用户和用户组,这边只是切换后续命令执行的用户(用户和用户组必须提前已经存在)。
格式:
1 |
|
VOLUME 定义匿名卷
格式为:
1 |
|
容器运行时应该尽量保持容器存储层不发生写操作,对于数据库类需要保存动态数据的应用,其数据库文件应该保存于卷(volume)中。为了防止运行时用户忘记将动态文件所保存目录挂载为卷,在 Dockerfile 中,我们可以事先指定某些目录挂载为匿名卷,这样在运行时如果用户不指定挂载,其应用也可以正常运行,不会向容器存储层写入大量数据。
1 |
|
这里的 /data
目录就会在运行时自动挂载为匿名卷,任何向 /data 中写入的信息都不会记录进容器存储层,从而保证了容器存储层的无状态化。当然,运行时可以覆盖这个挂载设置。比如:
1 |
|
在这行命令中,就使用了 mydata 这个命名卷挂载到了 /data
这个位置,替代了 Dockerfile 中定义的匿名卷的挂载配置。
ENV
设置环境变量,定义了环境变量,那么在后续的指令中,就可以使用这个环境变量。
格式:
1 |
|
以下示例设置 NODE_VERSION = 7.2.0 , 在后续的指令中可以通过 $NODE_VERSION 引用:
1 |
|
ARG
构建参数,与 ENV 作用一至。不过作用域不一样。ARG 设置的环境变量仅对 Dockerfile 内有效,也就是说只有 docker build 的过程中有效,构建好的镜像内不存在此环境变量。
构建命令 docker build 中可以用 –build-arg <参数名>=<值> 来覆盖。
格式:
1 |
|
HEALTHCHECK
用于指定某个程序或者指令来监控 docker 容器服务的运行状态。
格式:
1 |
|
ONBUILD
用于延迟构建命令的执行。简单的说,就是 Dockerfile 里用 ONBUILD 指定的命令,在本次构建镜像的过程中不会执行(假设镜像为 test-build)。当有新的 Dockerfile 使用了之前构建的镜像 FROM test-build ,这是执行新镜像的 Dockerfile 构建时候,会执行 test-build 的 Dockerfile 里的 ONBUILD 指定的命令。
格式:
1 |
|