一. 相关URL
https://hub.docker.com
http://www.docker.org.cn/
http://www.dockerinfo.net/document
二. 安装 - centos 7.x 安装docker
yum -y install docker-io
三. 相关命令
1. 容器
创建容器
创建一个随机名称的容器, 并且启动它
# -i 设置stdin开启
# -t 设置伪tty终端
# centos 表示基于centos镜像启动
docker run -it centos /bin/bash
docker run -it --name test centos /bin/bash
# -d 设置守护模式
docker run --name -d centos /bin/bash "while true; do echo hello world; sleep 1; done"
容器命名
在启动的时候添加 –name 参数
docker run --name xx -it centos /bin/bash
查看容器
# 查看已经开启的容器
docker ps
# 查看所有(包括关闭)的容器
docker ps -a
# 查看所有容器id
docker ps -qa
启动已经关闭的容器
docker start xx
docker start [ID]
附着容器(操作容器)
docker attach xx
docker start [ID]
查看容器内日志
docker logs xx
docker logs [ID]
# 可以使用tail
# 最后10条
docker logs --tail 10 xx
# 动态最终最后一条
docker logs --tail 0 -f xx
停止一个容器
docker stop xx
docker stop [ID]
删除容器
# 删除一个容器
docker rm xx
docker rm [ID]
# 删除所有容器
docker rm `docker ps -qa`
查看容器具体信息
docker inspect xx
docker inspect [ID]
# format参数
# 支持多个key, 多个容器查询, 会依次将每个容器的所有返回结果输出
docker inspect --format '{{.Name}} {{.State.Running}}' aa bb
/aa true
/bb true
2. 镜像
1) 镜像的组成
docker 的镜像是由文件系统叠加而成
最底层是引导文件系统 bootfs, 容器启动后, bootfs会被卸载, 留出更多的内存供initrd磁盘镜像使用
第二层是root文件系统 rootfs, rootfs可以是一个或多个文件系统(如centos, ubuntu), rootfs永远为只读再利用联合加载(union mount)在rootfs上加载更多的只读文件系统, 最终的文件系统会包含所有底层的文件和目录
联合加载: 一次同时加载多个文件系统, 但在外部只能看到一个文件系统
docker中将这样的文件系统称为镜像, 一个镜像可以放到另一个镜像的顶部, 位于下方的镜像称为父镜像, 最低端的镜像称为基础镜像, 当启动容器时, docker会在顶层加载一个读写文件系统, 我们的读写操作是在这个层执行的
2) 什么是读写复制
docker启动容器时, 初始的读写层是空的, 当文件系统发生变化时, 变化都会应用到这一层,
如果修改一个文件, 会先从下边的只读层复制到上边的读写层, 该文件的只读版本依然存在, 但是已经被读写层中的副本隐藏
3) 命令
列出镜像
docker images
拉取镜像
docker pull centos
docker pull ansible/centos7-ansible
查找镜像
docker search centos
构建镜像
1. 使用commit命令
docker commit [ID] [Image_name]
2. 使用docker build命令和Dockerfile文件
1) Dockerfile文件内容
# Version: 0.0.1
FROM centos # 基础镜像名称
MAINTAINER [author_name] [author_Email] # 作者名字和联系方式
RUN yum -y update # 操作1
RUN yum -y install epel-release; yum clean all # 操作2
RUN yum -y install nginx; yum clean all # 操作3
EXPOSE 80 # 打开80端口
2) 使用docker build构建
每条RUN指令执行时, 都会创建一个新的镜像层, 如果指令执行成功, 就会将镜像层提交, 继续执行下一条
# -t 指定[仓库名]/[镜像名]:[标签]
# 结尾的.表示在当前目录中寻找Dockerfile文件, 也可以指定git仓库的Dockerfile地址
docker build -t="centos/nginx:0.0.1" .
docker build -t="centos/nginx:0.0.2" git@github.com/xxx/xx
3) 忽略构建缓存
由于每次构建都会讲结果提交为镜像, 所以docker会将之前的镜像层看做缓存, 如果构建发生改变, 需要从新开始构建, 则需要使用docker build的–no-cache参数
docker build --no-cache -t="centos/nginx:0.0.3" .
查看新镜像
[root@ByPic-TEST test]# docker history centos/nginx:0.0.1
IMAGE CREATED CREATED BY SIZE COMMENT
f5955de41fc5 5 minutes ago /bin/sh -c #(nop) CMD ["nginx"] 0 B
980a194fa558 9 minutes ago /bin/sh -c #(nop) EXPOSE 80/tcp 0 B
c12c6555dfb6 9 minutes ago /bin/sh -c yum -y install nginx 136 MB
949c9b181249 9 minutes ago /bin/sh -c yum -y install epel-release 21.7 MB
c16622c54d4d 9 minutes ago /bin/sh -c yum -y update 51.6 MB
f4abc4a26790 9 minutes ago /bin/sh -c #(nop) MAINTAINER yangkaiyue "... 0 B
49f7960eb7e4 2 days ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0 B
<missing> 2 days ago /bin/sh -c #(nop) LABEL org.label-schema.... 0 B
<missing> 2 days ago /bin/sh -c #(nop) ADD file:8f4b3be0c1427b1... 200 MB
从新镜像启动容器
docker run -itd -p 80 --name mynginx centos/nginx:0.0.1 /usr/sbin/init
查看端口映射
查看 mynginx 镜像80端口映射到哪个ip的哪个端口
[root@ByPic-TEST test]# docker port mynginx 80
0.0.0.0:32781
手动绑定端口映射
# 宿主机8080 --> docker容器80
docker run -itd -p 8080:80 --name mynginx centos/nginx:0.0.1 /usr/sbin/init
# 127.0.0.1:8080 --> docker容器80
docker run -itd -p 127.0.0.0:8080:80 --name mynginx centos/nginx:0.0.1 /usr/sbin/init
# 127.0.0.1随机端口 --> docker容器80
docker run -itd -p 127.0.0.0::80 --name mynginx centos/nginx:0.0.1 /usr/sbin/init
4) Dockerfile指令
CMD
容器启动时要运行的命令, 类似docker run命令启动容器是指定的命令
推荐使用数组语法执行, 数组语法: [“pwd”]
Dockerfile中只能指定一条CMD, 即使有多条, 也只会执行最后一条, 所以如果有多个进程, 可以考虑使用supervisord
# Dockerfile CMD设置
CMD = ['ls','-l']
docker run命令**覆盖**Dockerfile中CMD指令
[root@ByPic-TEST test]# docker run -it test
total 44
lrwxrwxrwx 1 root root 7 May 31 18:02 bin -> usr/bin
drwxr-xr-x 5 root root 360 Jun 7 15:05 dev
drwxr-xr-x 1 root root 4096 Jun 7 15:05 etc
drwxr-xr-x 2 root root 4096 Apr 11 04:59 home
lrwxrwxrwx 1 root root 7 May 31 18:02 lib -> usr/lib
lrwxrwxrwx 1 root root 9 May 31 18:02 lib64 -> usr/lib64
drwxr-xr-x 2 root root 4096 Apr 11 04:59 media
drwxr-xr-x 2 root root 4096 Apr 11 04:59 mnt
drwxr-xr-x 2 root root 4096 Apr 11 04:59 opt
dr-xr-xr-x 99 root root 0 Jun 7 15:05 proc
dr-xr-x--- 2 root root 4096 May 31 18:03 root
drwxr-xr-x 1 root root 4096 Jun 7 15:05 run
lrwxrwxrwx 1 root root 8 May 31 18:02 sbin -> usr/sbin
drwxr-xr-x 2 root root 4096 Apr 11 04:59 srv
dr-xr-xr-x 13 root root 0 Apr 11 04:59 sys
drwxrwxrwt 7 root root 4096 May 31 18:03 tmp
drwxr-xr-x 1 root root 4096 May 31 18:02 usr
drwxr-xr-x 1 root root 4096 May 31 18:02 var
---
[root@ByPic-TEST test]# docker run -it test ps
PID TTY TIME CMD
1 ? 00:00:00 ps
ENTRYPOINT
与CMD类似, 但是ENTRYPOINT设置的命令不容易在启动容器时被覆盖
# Dockerfile CMD设置
ENTRYPOINT ["/usr/sbin/nginx"]
CMD ["-h"]
通常ENTRYPOINT和CMD同时使用可以使镜像既支持默认命令, 又支持docker run输入的命令
[root@ByPic-TEST test]# docker run -itd test -g 'daemon off;'
[root@ByPic-TEST test]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1d74144004da test "/usr/sbin/nginx -..." About a minute ago Up About a minute 80/tcp fervent_austin
---
[root@ByPic-TEST test]# docker run -it test
nginx version: nginx/1.12.2
Usage: nginx [-?hvVtTq] [-s signal] [-c filename] [-p prefix] [-g directives]
Options:
-?,-h : this help
-v : show version and exit
-V : show version and configure options then exit
-t : test configuration and exit
-T : test configuration, dump it and exit
-q : suppress non-error messages during configuration testing
-s signal : send signal to a master process: stop, quit, reopen, reload
-p prefix : set prefix path (default: /usr/share/nginx/)
-c filename : set configuration file (default: /etc/nginx/nginx.conf)
-g directives : set global directives out of configuration file
WORKDIR
设置工作目录
ENTRYPOINT 或 / 或 CMD 指定的程序会在这个目录下执行
# Dockerfile WORKDIR设置
WORKDIR /home/xx
可以通过-w标志在docker run时覆盖工作目录
[root@ByPic-TEST test]# docker run -it test
/tmp
---
[root@ByPic-TEST test]# docker run -it -w /home test pwd
/home
ENV
构建过程中设置变量
# Dockerfile ENV设置
# RVM_PATH 这个环境变量可以在后续的任何RUN指令中使用
ENV RVM_PATH /home/rvm
RUN gem install unicorn
# 等同于
RVM_PATH=/home/rvm gem install unicorn
# 可以设置变量
ENV HOME_PATH /home/xx
WORKDIR $HOME_PATH
可以通过-e标志在docker run时传递环境变量, 只在运行时生效
USER
指定镜像以什么用户或组运行
USER nginx
# 有如下模式
USER user
USER user:group
USER uid
USER uid:gid
USER user:gid
USER uid:group
可以通过-u标志在docker run时覆盖工作目录
如果不指定用户, 默认用户为root
VOLUME
设置卷, 一个卷是可以存在于一个或者多个容器内的特定的目录
卷可以在容器间共享
对卷的修改是立时生效的
卷的修改不会对镜像的更新有影响
卷会一直存在, 直到没有容器使用它
ADD
用来将构建环境下的文件或目录, 复制到镜像中
需要源文件的位置 和 目的文件位置两个参数
ADD根据目的位置的结尾判断源位置是目录还是文件, 如果结尾是/, 源为目录, 如果结尾不是/, 则源为文件
源文件位置可以是URL格式
且如果源文件格式为压缩包, ADD会自动解压到目的文件目录下
暂时不支持URL直接解压
如果目录位置不存在, Docker会创建全路径, 新创建的目录模式为0755, uid和gid为0
# Dockerfile ADD设置
ADD nginx.conf /home/xx/nginx/conf/nginx.conf
ADD latest.zip /home/
ADD http://wordpress.org/latest.zip /home/latest.zip
COPY
如果源路径是个目录, 则目录整个会被复制到容器中, 包括文件系统的元数据
如果源文件类型为文件, 则随同元数据一起被复制
元数据是实际数据的数据, 包括文件权限, 所有者, inode信息等
如果目的位置不存在, 则自动递归创建目录
# Dockerfile COPY设置
COPY nginx/cond.d/ /home/xx/nginx/conf/conf.d/
ONBUILD
能为镜像添加触发器, 当一个镜像被用作其他镜像的基础镜像时, 该镜像的触发器会被执行
只在作为父镜像时候执行, 且From / Maintainer / Onbuild 不能使用