Docker基础
Docker安装
Docker安装(CentOS 7)
Docker在CentOS 7上的安装,直接参考官网安装手册即可: Install Docker Engine on CentOS
安装Dockerd主版本的步骤如下,要按照特定版本的,参考Docker官网。
1 | sudo yum -y install epel-release |
执行docker version来验证docker是否正常安装。
Tips:
也可以换用阿里云的docker镜像源yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
设置镜像加速
设置网易云镜像加速
1 | sudo mkdir -p /etc/docker |
检查镜像加速是否设置成功, 查看Registry Mirrors中是否有163的镜像。
1 | $ docker info |
执行hello-world镜像
1 | docker run hello-world |
Docker命令
Docker帮助命令
1 | docker version |
镜像命令
列出本机镜像
列出本地的镜像docker images, 使用REPOSITORY:TAG来定义不同的镜像
1 | [root@localhost ~]# docker images |
参数
-a: 列出所有的镜像-q: 列出镜像的ID--digests: 显示镜像的digest摘要信息--no-trunc: 显示ID的完整信息
搜索镜像
docker search从Docker Hub上搜索镜像
1 | [root@localhost ~]# docker search tomcat |
其中OFFICIAL表示是否是官方镜像,STARS表示星星数。
常用参数
--filter: 加上过滤条件,比如--filter=stars=10就是索索star数大于等于10的镜像--no-trunc: 输出完整的信息,比如Description中不要省略
拉取镜像
docker pull拉取镜像,docker pull IMAGE_NAME:TAG,如果省略TAG,那么默认拉取latest
1 | [root@localhost ~]# docker pull alpine |
删除镜像
docker rmi用来删除镜像
如果镜像被某个container在使用时,删除会提示类似Error response from daemon: conflict: unable to remove repository reference "hello-world" (must force) - container a8a7d78cf5b4 is using its referenced image bf756fb1ae65的错误信息。
此时加上-f参数进行强制删除即可,docker rmi hello-world -f
1 | # 删除单个 |
容器命令
新建并启动容器
docker run: 按照某个镜像新建容器示例。
1 | docker run -it 7e6257c9f8d8 |
常用参数:
--name: 执行容器名字-d: 后台运行容器-i: 以命令交互模式运行容器,常和-t同时使用-t: 为容器重新分配一个伪输入终端,通常和-i一起使用-P: 随机端口映射-p: 指定端口映射- ip:hostPort:containerPort
- ip::containerPort
- hostPort:containerPort
- containerPort
显示docker内容
docker ps查看docker里面的container
1 | [root@localhost ~]# docker ps -a |
常用参数
-a: 列出当前所有正在运行和历史上运行过的容器-l: 列出最新创建的容器-n: 显示最近n个创建的容器-q: 静默模式,只显示容器编号--no-trunc: 不截断输出
查看镜像layer
命令docker history image_id来查看镜像的layer数据
例子:
1 | [root@localhost ~]# docker history 7e6257c9f8d8 |
启动容器
命令docker start [OPTIONS] CONTAINER [CONTAINER...]来启动已经停止的容器。docker ps -a找出container id,然后再docker start container_id启动容器
重启容器
命令docker restart [OPTIONS] CONTAINER [CONTAINER...]来重启容器
停止容器
命令docker stop [OPTIONS] CONTAINER [CONTAINER...]来停止容器
强制关闭容器
命令docker kill [OPTIONS] CONTAINER [CONTAINER...]来强制停止容器
删除已停止的容器
命令docker rm [OPTIONS] CONTAINER [CONTAINER...]来删除容器
参数:
-f, --force: 强制删除容器,即使在运行中也会被删除。
用法:
- 一次性删除所有容器
docker rm -f $(docker ps -a -q)docker ps -q -q | xargs docker rm
容器退出
-it模式下
exit, 退出容器并关闭容器ctrl + P + Q, 退出容器但不关闭容器
启动守护进程
命令docker run -d 以守护进程来启动容器
注意:
- Docker容器后台运行,就必须有一个前台进程,容器运行的命令如果不是那些一直挂起的命令(比如top,tail)等,容器会自动退出。
- 所以使用docker来启动服务时,需要以前台方式进行。nginx为例,正常机器下,启动nginx的service即可,systemctl start nginx。但是在容器中,因为没有前台进程在运行,这种方式下docker会退出。
保存镜像到文件
命令docker save用于保存镜像到文件中。完整形式docker save [OPTIONS] IMAGE [IMAGE...]
用法:
1 | docker save carl/mycentos7:latest > carl_mycentos7_latest.tar |
从镜像文件导入镜像
命令docker load用于从镜像文件中导入镜像
用法:
1 | docker load < carl_mycentos7_latest.tar |
将容器导出为镜像文件
命令docker export用于将容器内容导出为镜像文件,docker export [OPTIONS] CONTAINER
和docker save的区别是save是将image保存为文件,export是将容器保存为文件。
用法:
1 | docker export 3a809727879b > carl_mycentos7_export.tar |
将export导出的文件导入为文件
命令docker import将导出的tar文件导入为镜像。docker import [OPTIONS] file|URL|- [REPOSITORY[:TAG]]
用法:
1 | docker import carl_mycentos7_export.tar carl/mycentos7:from_export |
查看容器日志
docker logs -f -t --tail 容器ID
参数:
-t: 加入时间戳-f: 跟随最新的日志打印--tail: 数字,显示最后多少条
查看容器内进程
docker top CONTAINER查看某个container中的进程
查看容器内部细节
docker inspect NAME|ID, 查看容器的配置参数
1 | [root@localhost ~]# docker inspect 859a0d5a0491 |
重新进入容器
docker attach CONTAINER 重新进入运行的容器docker exec -t CONTAINER COMMAND,不进入容器运行命令。例如docker exec -t 8599f87085d7 ls -l /tmp/
从容器中拷贝文件到宿主机
命令docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH
例子: docker cp 8599f87085d7:/tmp/yum.log ./
Docker镜像原理
UnionFS
UnionFS(联合文件系统):Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。Union 文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。 特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录
镜像commit
docker commit -a "author name" -m "commit message" CONTAINER REPOSITORY[:TAG]将修改后的容器副本,使之成为一个新的镜像
例子docker commit -a "carl" -m "repackage tomcat" 1238e0d02ff5 carl/tomcat:v1
容器数据卷
使用命令挂载数据卷
命令docker run -it -v /宿主机绝对路径目录:/容器内目录 镜像名
例子:docker run -it -v /myDataVolumn:/container_data_info centos:centos7 /bin/bash
挂载带读写权限,在容器内目录后面加上:ro, docker run -it -v /宿主机绝对路径目录:/容器内目录:ro 镜像名
使用Dockerfile来挂载容器卷
可在Dockerfile中使用VOLUME指令来给镜像添加一个或多个数据卷VOLUME["/dataVolumeContainer","/dataVolumeContainer2","/dataVolumeContainer3"]
说明:
出于可移植和分享的考虑,用-v 主机目录:容器目录这种方法不能够直接在Dockerfile中实现。由于宿主机目录是依赖于特定宿主机的,并不能够保证在所有的宿主机上都存在这样的特定目录。
编写Dockerfile
1
2
3
4
5# volume test
FROM centos:centos7
VOLUME ["/dataVolumeContainer1", "/dataVolumeContainer2"]
CMD echo "finished,==== success1"
CMD /bin/bashdocker build
docker build -f /mydocker/Dockerfile -t carl/centos7 .
1 | [root@localhost mydocker]# docker build -f /mydocker/Dockerfile -t carl/centos7 . |
- 查看构建的新images
1
2
3
4
5
6
7
8[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
carl/centos7 latest 54e2ebd7b090 10 minutes ago 203MB
carl/tomcat v1 45cab61abaa6 19 hours ago 652MB
tomcat latest 891fcd9c5b3a 47 hours ago 647MB
centos centos7 7e6257c9f8d8 2 months ago 203MB
hello-world latest bf756fb1ae65 9 months ago 13.3kB
[root@localhost ~]#
容器数据卷volumes-from
命名的容器挂载数据卷,其他容器通过挂载这个(父容器)实现数据共享,挂载数据卷的容器,称之为数据卷容器。
docker run时使用--volumes-from container_name_xx来挂载container_name_xx中的volume。
例子:docker run -it --name dc02 --volumes-from dc01 carl/centos7, 即运行一个名为dc02的容器,并挂载来自dc01的卷。
结论: 容器之间配置信息的传递,数据卷的生命周期一直持续到没有容器使用它为止。
Dockfile解析
Dockerfile是什么
Dockerfile是用来构建Docker镜像的构建文件,是由一系列命令和参数构成的脚本。
docker构三步骤:
- 手动编写一个dockerfile文件,要符合file的规范
- 有这个文件后,直接docker build命令执行,获得一个自定义的镜像
- run
Dockerfile构建过程解析
Dockerfile 内容基础知识
- 每条保留字指令都必须为大写字母且后面要跟随至少一个参数
- 指令按照从上到下,顺序执行
- # 表示注释
- 每条指令都会创建一个新的镜像层,并对镜像进行提交
docker执行Dockerfile的大致流程
- docker从基础镜像运行一个容器
- 执行一条指令并对容器作出修改
- 执行类似docker commit的操作提交一个新的镜像层
- docker再基于刚提交的镜像运行一个新容器
- 执行dockerfile中的下一条指令直到所有指令都执行完成
从应用软件的角度来看,Dockerfile、Docker镜像与Docker容器分别代表软件的三个不同阶段,
- Dockerfile是软件的原材料
- Docker镜像是软件的交付品
- Docker容器则可以认为是软件的运行态。
Dockerfile面向开发,Docker镜像成为交付标准,Docker容器则涉及部署与运维,三者缺一不可,合力充当Docker体系的基石
Dockerfile体系结构(保留字指令)
- FROM: 基础镜像,当前镜像是基于哪个镜像的
- MAINTAINER: 镜像维护者的姓名和邮箱地址
- RUN: 容器构建时需要运行的命令
- EXPOSE: 当前容器对外暴露出的端口
- WORKDIR: 指定在创建容器后,终端默认登录的进来的工作目录
- ENV: 用来在构建镜像过程中设置环境变量, 如
ENV MY_PATH /usr/mypath - ADD: 将宿主机目录下的文件拷贝进镜像,且ADD命令会自动处理URL和解压tar压缩包
- COPY:
- 类似ADD,拷贝文件和目录到镜像中。将从构建上下文目录中<源路径>的文件或目录复制到新一层的镜像内的<目录路径>的位置
- 写法:
- Shell写法: COPY src dst
- JSON数组写法: COPY [“src”, “dst”]
- VOLUME: 容器数据卷,用于数据保持和持久化工作
- CMD: 指定一个容器启动时要运行的命令。Dockerfile中可以有多个CMD命令,但只有最后一个生效,CMD会被docker run之后的参数替换
- ENTRYPOINT: 指定一个容器启动时要运行的命令,ENTRYPOINT的目的和CMD一样,都是在指定容器启动程序和参数,docker run的命令会添加到ENTRYPOINT的后面。
- ONBUILD: 当构建一个被继承的Dockerfile时运行命令,父镜像在被子继承后父镜像的onbuild被触发。
DockerFile案例,自定义镜像centos
Base镜像(scratch)
自定义镜像需求
- 设置登录后的默认路径
- 安装vim编辑器
- 查看网络配置ifconfig支持
创建DockerFile
1
2
3
4
5
6
7
8
9
10
11
12
13
14FROM centos:centos7
MAINTAINER xxxx<xxxx@yyy.com>
ENV MYPATH /use/local
WORKDIR $MYPATH
RUN yum -y install vim
RUN yum -y install net-tools
EXPOSE 80
CMD echo $MYPATH
CMD echo "success--------ok"
CMD /bin/bash根据Dockerfil构建镜像
docker build -t mycentos:1.3 .根据创建好的镜像,运行容器
1
docker run -it mycentos:1.3
查看镜像历史
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15[root@localhost ~]# docker history mycentos:1.3
IMAGE CREATED CREATED BY SIZE COMMENT
6099241fa296 4 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "/bin… 0B
dcfbaf894d59 4 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "echo… 0B
6fd7a4095306 4 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "echo… 0B
707263299b11 4 minutes ago /bin/sh -c #(nop) EXPOSE 80 0B
48d44a7faba4 4 minutes ago /bin/sh -c yum -y install net-tools 92.3MB
ce4deda18898 4 minutes ago /bin/sh -c yum -y install vim 147MB
db4e75c1541a 5 minutes ago /bin/sh -c #(nop) WORKDIR /use/local 0B
5ec65a85b950 5 minutes ago /bin/sh -c #(nop) ENV MYPATH=/use/local 0B
108c8029c6a5 5 minutes ago /bin/sh -c #(nop) MAINTAINER xxxx<xxxx@yyy.… 0B
7e6257c9f8d8 2 months ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B
<missing> 2 months ago /bin/sh -c #(nop) LABEL org.label-schema.sc… 0B
<missing> 2 months ago /bin/sh -c #(nop) ADD file:61908381d3142ffba… 203MB
[root@localhost ~]#
CMD/ENTRYPOINT镜像案例
CMD
- CMD的命令会被docker run后添加的命令参数所覆盖。
ENTRYPOINT
- docker run之后的参数会被当做参数传递给ENTRYPOINT, 之后形成新的命令组合
Dockerfile案例 – 自定义的tomcat9
Docker常用安装
安装mysql
1 | # 虚拟机中启动mysql |
安装中遇到的问题
第一次docker run时,把密码写错写成了-e MYSQL_ROOT_PASSWORD=123455,然后进入到mysql的容器中mysql -uroot -p时输密码123456死活报ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)。把容器删了重新跑命令也不顶用。最后才反应过来,因为容器跑的时候添加了-v挂载配置文件的目录到宿主机上了。因此配置文件中设置的密码,一直都是第一次输错的密码123455, 把/zzyyuse/mysql目录下全部清掉,重新docker run后,就OK了。
一些要点
CMD 和 ENTRYPOINT的区别
Dockerfile中
- CMD,会被命令行参数覆盖
1
2
3
4
5
6
7# Dockerfile
FROM Ubuntu
CMD sleep 5
# 命令行要修改sleep时间时,需要连命令一起带入
docker run ubuntu-sleeper sleep 10 - ENTRYPOINT的命令,一定会被执行,不会被命令行参数覆盖。
1
2
3
4
5
6
7# Dockerfile
FROM Ubuntu
ENTRYPOINT ["sleep"]
# 命令行执行时,加秒数即可
docker run ubuntu-sleeper 10
Shell vs. Exec模式
推荐使用exec模式(JSON格式), Shell模式是先使用shell来调用命令,多一层调用,如果从外部发送任何POSIX信号到docker容器, 由于/bin/sh命令不会转发消息给实际运行的ping命令, 则不能安全得关闭docker容器(参考更详细的文档:Gracefully Stopping Docker Containers).
注意Exec模式,是不能获取$HOME等环境变量的,因为环境变量是shell相关的。
组合使用
组合使用ENTRYPOINT和CMD, ENTRYPOINT指定默认的运行命令, CMD指定默认的运行参数. 例子如下:
1 | FROM ubuntu:trusty |
则从外面可以修改CMD,但是/bin/ping -c 3被当做强行命令不能被命令行参数所修改。
强制修改Dockerfile中的entrypoint
使用--entrypoint参数来修改Dockerfile中的ENTRYPOINT命令
例子:
1 | docker run --entrypoint sleep2.0 ubuntu-sleeper 10 |
在docker起来后,会执行命令sleep2.0 10。
export 和save的区别
- 是否包含镜像历史
export导出(import导入)是根据容器拿到的镜像,再导入时会丢失镜像所有的历史记录和元数据信息(即仅保存容器当时的快照状态),所以无法进行回滚操作。- 而
save保存(load加载)的镜像,没有丢失镜像的历史,可以回滚到之前的层(layer)。
- 是否可以对镜像重命名
docker import可以为镜像指定新名称docker load不能对载入的镜像重命名
- 是否可以同时将多个镜像打包到一个文件中
docker export不支持docker save支持
- 是否包含容器修改
docker save是基于镜像的操作,因此容器中的修改内容不会体现到镜像文件中。docker export是基于容器的操作,因此容器中所做的修改会体现到镜像文件中。
Docker 基础命令
docker run
1 | # 以交互方式运行名为nginx的image |
获取某个container的环境变量
1 | # 获取全部信息,手动查找 |
docker build
1 | # 根据当前目录Dockerfile打包Image,命名为webapp-color |
docker network create
1 | # 查看docker network create的参数 |
获取container网络有关的信息
1 | docker inspect container_name -f "{{json .NetworkSettings.Networks }}" |