Docker
Docker
概述
安装时把原始环境一模一样的复制过来,只需要一次配置好环境,换到别的机子上就可以一键部署好
三要素
- 仓库:集中存放镜像文件的场所
- 镜像:只读的模板
- 容器:镜像的实例
虚拟机与容器虚拟化
- 虚拟机:带环境安装的一种解决方案
- 在一种操作系统里运行另一种操作系统
- 资源占用多,冗余步骤多,启动慢
- Linux容器:对进程进行隔离
- 没有硬件虚拟,较为轻便
- 容器间互相隔离
安装
镜像加速配置
- 阿里云镜像
- https://dev.aliyun.com/search.html
- 获得加速器地址连接:https://j019hj13.mirror.aliyuncs.com
- 配置本机Docker运行镜像加速器
- 重新启动Docker后台服务:
service docker restart
- Linux系统下配置完加速器需要检查是否生效
- 网易云加速
- 同阿里
启动Docker后台容器(测试运行hello-world)
docker run hello-world
底层原理
- Docker是CS结构,守护进程运行在主机上,通过Socket连接从客户端访问,守护进程接收客户端命令并管理运行在主机上的容器
Docker和VM
- Docker
- 与宿主共享OS
- 镜像小
- 几乎无额外性能损失
- 轻便灵活
- 面向软件开发者
- 快速部署
- VM
- 宿主机OS上运行虚拟机OS
- 镜像大
- 需要额外的CPU,内存消耗
- 与虚拟化技术耦合度高
- 面向硬件运维者
- 部署较慢
命令
帮助
docker version
docker info
docker --help
镜像
- 列出本地主机上的镜像:
docker images
-a
:列出本地所有的镜像(含中间映像层)-q
:只显示镜像ID--digests
:显示镜像的摘要信息--no-trunc
:显示完整的镜像信息
- 查找镜像:
docker search [OPTIONS] 镜像名字
--no-trunc
:显示完整的镜像描述-s
:列出收藏数不小于指定值的镜像--automated
:只列出automated build类型的镜像
- 下载镜像:
docker pull 镜像名字[:TAG]
docker pull tomcat
等价于docker pull tomcat:latest
- 删除镜像:
docker rmi 镜像名字ID
docker rmi -f 镜像ID
:删除单个docker rmi -f 镜像名1:TAG 镜像名2:TAG
:删除多个docker rmi -f $(docker images -qa)
:删除全部
容器
新建并启动容器:
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
--name="容器新名字"
:为容器指定一个名称-d
:后台运行,返回容器ID(守护式容器)-i
:以交互模式运行容器,通常与-t
同时使用-t
:为容器重新分配一个伪输入终端,通常与-i
同时使用-P
:随机端口映射-p
:端口映射,有一下四种格式ip:hostPort:containerPort
ip::containerPort
hostPort:containerPort
containerPort
1
2docker run -it -p 8888:8080 tomcat
# Docker对外暴露的端口号8888与Tomcat服务的端口8080映射列出当前所有正在运行的容器:
docker ps [OPTIONS]
-a
:列出当前所有正在运行+历史上运行过的容器-l
:显示最近创建的容器-n
:显示最近n个创建的容器-q
:静默模式,只显示容器编号--no-trunc
:不截断输出
退出容器
- 方式1,容器停止退出:
exit
- 方式2,容器不停止退出:
ctrl+P+Q
- 方式1,容器停止退出:
启动容器:
docker start 容器ID或者容器名
重启容器:
docker restart 容器ID或者容器名
停止容器:
docker stop 容器ID或者容器名
强制停止容器:
docker kill 容器ID或者容器名
删除已停止的容器:
docker rm 容器ID
- 一次性删除多个容器
docker rm -f $(docker ps -a -q)
docker ps -a -q | xargs docker rm
- 一次性删除多个容器
重要
- run的时候一定要加
--privileged=true
,否则服务容易出错 - 启动守护式容器:
docker run -d 容器名
- 后台运行的容器必须有一个前台进程,若不是一直挂起的命令就会自动退出
- 查看容器日志:
docker logs -f -t --tail 容器ID
-t
:加入时间戳-f
:跟随最新的日志打印--tail 数字
:显示最后多少条
- 查看容器内运行的进程:
docker top 容器ID
- 查看容器内部细节:
docker inspect 容器ID
- 进入正在运行的容器并以命令行交互
docker exec -it 容器ID bashShell命令
docker exec -t 容器ID bashShell命令
:容器中运行命令并直接返回
- 重新进入:
docker attach 容器ID
- 上述两个区别
- attach直接进入容器启动命令的终端,不会启动新的进程
- exec是在容器中打开新的终端,并且可以启动新的进程
- 从容器内拷贝文件到主机上:
docker cp 容器ID:容器内路径 目的主机路径
- run的时候一定要加
镜像
概述
- 用来打包软件运行环境和基于运行环境开发的软件,它支持对文件系统的修改作为一次提交来层层叠加,联合文件系统是Docker镜像的基础
原理
最底层是bootfs,bootfs上一层是rootfs
1
2
3
4Tomcat
JDK
CentOS
Kernel
commit
docker commit
:提交容器副本使之成为一个新的镜像docker commit -m=“提交的描述信息” -a=“作者” 容器ID 要创建的目标镜像名:[标签名]
1
docker commit -m "With vim, dataVolumeContainer1 and dataVolumeContainer2" -a "PhineasZ" 3051806a3837 pz/debian-vim:1
容器数据卷
概述
- 容器的持久化,类似于Redis里的rdb和aof文件。可以使容器之间继承+共享数据
- 数据卷可在容器之间共享或重用数据
- 卷中的更改可以直接生效
- 数据卷中的更改不会包含在镜像的更新中
- 数据卷的生命周期一致持续到没有容器使用它为止
容器内添加数据卷方法
直接命令添加
命令:
docker run -it -v /宿主机绝对路径目录:/容器内目录 镜像名
1
docker run -it -v /myDataVolume:/dataVolumeContainer debain
查看数据卷是否挂载成功:
docker inspect 容器名
1
2
3
4
5
6
7
8
9
10
11
12
13"Volumes": {
"/dataVolumeContainer": "myDataVolume"
}
"VolumesRW": {
"/dataVolumeContainer": true
}
……
"HostConfig": {
"Binfs": [
"/myDataVolume:/dataVolumeContainer"
],
……
}容器和宿主机之间数据共享。容器停止退出后,主机修改后数据也同步
命令(对容器只读):
docker run -it -v /宿主机绝对路径目录:/容器内目录:ro 镜像名
1
docker run -it -v /myDataVolume:/dataVolumeContainer:ro debain
- 只允许主机单向传给容器
1
2
3
4
5
6
7
8
9
10
11
12
13"Volumes": {
"/dataVolumeContainer": "myDataVolume"
}
"VolumesRW": {
"/dataVolumeContainer": false
}
……
"HostConfig": {
"Binfs": [
"/myDataVolume:/dataVolumeContainer:ro"
],
……
}
DockerFile添加
根目录下新建mydocker文件夹并进入
File构建
1
2
3
4
5FROM debian
# 可在Dockerfile中使用VOLUME指令来给镜像添加一个或多个数据卷
VOLUME ["/dataVolumeContainer1","/dataVolumeContainer2"]
CMD echo "finished,--------success1"
CMD /bin/bashbuild后生成镜像
1
docker build -f /Users/mousse/Docker/Dockerfile -t pz/debian .
run容器
宿主机上的文件夹自动生成默认地址
Docker挂载主机目录Docker访问出现connot open directory .: Permission denied的解决办法:在挂在目录后多加一个
--privileged=true
1
docker run -it -v /myDataVolume:/dataVolumeContainer --privileged=true debain
数据卷容器
命名的容器挂载数据卷,其它容器通过挂载这个父容器实现数据共享,挂载数据卷的容器称之为数据卷容器
容器间传递共享
容器之间配置信息的传递,数据卷的生命周期一直持续到没有容器使用它为止
先启动一个父容器dc01,在dataVolumeContainer2新增内容
1
docker run -it --name dc01 pz/debian-vim:1
dc02/dc03继承自dc01:
--volumes-from
1
2docker run -it --name dc02 --volumes-from dc01 pz/debian-vim:1
docker run -it --name dc03 --volumes-from dc01 pz/debian-vim:1dc01/dc02/dc03互相之间都能共享,dc01后也无妨
DockerFile
概述
- 用来构建Docker镜像的构建文件,是由一系列命令和参数构成的脚本
- 构建三步骤
- 编写Dockerfile文件
- docker build
- docker run
构建过程
- 基础知识
- 每条保留字指令都必须为大写字母且后面要跟随至少一个参数
- 指令按照从上到下,顺序执行
#
表示注释- 每条指令都会创建一个新的镜像层,并对镜像进行提交
- 大致流程
- docker从基础镜像运行一个容器
- 执行一条指令并对容器作出修改
- 执行类似docker commit的操作提交一个新的镜像层
- docker再基于刚提交的镜像运行一个新容器
- 执行dockerfile中的下一条指令直到所有指令都执行完成
- 总结
- DockerFile:软件原材料,面向开发
- DockerImage:软件交付品,交付标准
- DockerContainer:软件运行态,部署运维
体系结构(保留字指令)
- FROM:基础镜像,当前新镜像是基于哪个镜像的
- MAINTAINER:镜像维护者的姓名和邮箱地址
- RUN:容器构建时需要运行的命令
- EXPOSE:当前容器对外暴露出的端口
- WORKDIR:指定在创建容器后,终端默认登陆的进来工作目录,一个落脚点
- ENV:用来在构建镜像过程中设置环境变量
- ADD:将宿主机目录下的文件拷贝进镜像且ADD命令会自动处理URL和解压tar压缩包
- COPY:类似ADD,拷贝文件和目录到镜像中
- 将从构建上下文目录中<源路径>的文件/目录复制到新的一层的镜像内的<目标路径>位置
COPY src dest
COPY ["src", "dest"]
- VOLUME:容器数据卷,用于数据保存和持久化工作
- CMD:指定一个容器启动时要运行的命令
- Dockerfile 中可以有多个CMD指令,但只有最后一个生效,CMD会被docker run之后的参数替换
- ENTRYPOINT:指定一个容器启动时要运行的命令
- ENTRYPOINT的目的和CMD一样,都是在指定容器启动程序及参数
- ONBUILD:当构建一个被继承的Dockerfile时运行命令,父镜像在被子继承后父镜像的onbuild被触发
- 子镜像通过FROM继承
案例
Base镜像(scratch):Docker Hub中99%的镜像都是通过在base镜像中安装和配置需要的软件构建出来的
自定义镜像debian
1
2
3
4
5
6
7
8
9FROM debian
# VOLUME ["/dataVolumeContainer1","/dataVolumeContainer2"]
# ENV mypath /home
# WORKDIR $mypath
RUN apt update
RUN apt install vim -y
RUN apt install net-tools -y
# EXPOSE 80
CMD /bin/bashCMD/ENTRYPOINT镜像案例
都是指定一个容器启动时要运行的命令
CMD
- Dockerfile中可以有多个CMD指令,但只有最后一个生效,CMD会被 docker run之后的参数替换
ENTRYPOINT
- docker run之后的参数会被当做参数传递给ENTRYPOINT,之后形成新的命令组合
1
2
3
4
5
6
7
8
9
10
11# 制作CMD版可以查询IP信息的容器
FROM debian
RUN apt update
RUN apt install curl -y
CMD ["curl", "-s", "http://ip.cn"]
# 如果我们希望显示 HTTP 头信息,就需要加上 -i 参数
FROM debian
RUN apt update
RUN apt install curl -y
ENTRYPOINT ["curl", "-s", "http://ip.cn"]
ADD/COPY镜像案例:自定义镜像Tomcat9
将jdk和tomcat安装的压缩包拷贝进目录
- apache-tomcat-9.0.8.tar.gz
- jdk-8u171-linux-x64.tar.gz
- copyFile.tar.gz
目录下新建Dockerfile文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18FROM debian
MAINTAINER pz<pz@mousse.cc>
COPY copyFile.tar.gz /usr/local/copyFile.tar.gz
ADD jdk-8u171-linux-x64.tar.gz /usr/loacl
ADD apache-tomcat-9.0.8.tar.gz /usr/loacl
RUN apt update
RUN apt install vim -y
ENV /usr/local
WORKDIR $MYPATH
# 配置Java与Tomcat环境变量
ENV JAVA_HOME /usr/local/jdk1.8.0_171
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /ust/local/apache=tomcat-9.0.8
ENV CATALINA_BASE /ust/local/apache=tomcat-9.0.8
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
# 运行容器时监听的端口
EXPOSE 8080
CMD /usr/local/apache-tomcat-9.0.8/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.8/bin/logs/catalina.out1
docker run -d -p 8081:8080 --name mytomcat9 -v /host/mydockerfile/tomcat9/test:/usr/local/apache-tomcat-9.0.8/webapps/test -v /host/mydockerfile/tomcat9/logs:/usr/local/apache-tomcat-9.0.8/apache-tomcat-9.0.8/logs --privileged=true pz/tomcat9
发布到云
- 将本地镜像推送到阿里云
- 阿里云开发者平台:https://dev.aliyun.com/search.html
- 创建仓库镜像
- 将镜像推送到registry