基本介绍
Docker是一个开源的容器引擎,可以将开的的应用以及依赖进行打包到一个可移植的镜像当中,可在Linux和Windows上运行,容器是完全使用沙箱机制,相互之间是隔离的。
版本
- CE (Community Edition: 社区版)
- EE (Enterprise Edition: 企业版)
特性
Docker容器化与常用虚拟化(Vmware、Hyper-V)区别:
- 虚拟机需要虚拟出硬件,以及一套完整的操作系统,然后在操作系统上运行软件,空间利用率很低,其基础的系统运行会消耗极大一部分的宿主机资源。
- Docker容器化是运行在宿主机上的一个服务,container没有独立的内核,也没有独立的虚拟硬件,环境相似的container之间共用同一个(linux)内核,以节省系统开销,并且Docker使用了Union File System(联合文件系统),这使得空间利用率和资源复用进一步提高。
- Container 之间都是互相隔离的,每个容器都有自己文件系统,互不影响。
Docker的优势:
- 使应用更快速的交付和部署
- 更便捷的升级和扩缩容
- 更简单的系统运维
- 更高效的计算机资源利用
组成
- 镜像(Image)
- 一个只读的数据包,当中包含了虚拟环境运行的最原始的文件系统。
- 容器(Container)
- 用来隔离虚拟环境的基础设施,它包含了程序的运行环境,和指令集。
- 网络(Network)
- 在容器间建立虚拟网络,将数个容器包裹其中,同时与其他网络环境隔离。
- 数据卷(Volume)
- 可以从宿主操作系统中挂载容器目录,还能够建立独立的目录存放数据,或者在容器之间共享。
镜像加速
阿里云
- 打开阿里云官网登录后找到 控制台 -> 容器镜像服务 -> 镜像加速器 -> (选择对应的系统)复制加速地址
在Docker宿主机中执行如下代码(centos)
sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["https://yourid.mirror.aliyuncs.com"] } EOF sudo systemctl daemon-reload sudo systemctl restart docker
常用命令
(在这之前先确保Docker已正确安装并启动)
基础命令
docker version #查看docker的版本信息
docker info #查看docker的系统信息,包括镜像和容器的数量
docker COMMAND --help #帮助命令(可查看可选的参数)
镜像命令
docker images #查看本地所有的镜像
# 字段解释:
1.REPOSITORY 仓库源
2.TAG 标签
3.IMAGE ID
4.CREATED 创建时间
5.SIZE
# option参数
-a/--all 列出所有镜像
-q/--quiet 只显示镜像的id
镜像搜索
docker search imgname
# 字段解释:
1.NAME
2.DESCRIPTION 镜像描述
3.STARS
4.OFFICIAL 官方镜像
5.AUTOMATED
# option说明
-f, --filter filter 过滤器
--format string
--limit int
--no-trunc
#eg(搜索nginx大于1000start的镜像):
docker search nginx --filter=STARS=1000
镜像下载
# 下载nginx镜像
docker pull nginx # 默认为latest
# 指定版本(1.20.2)下载
docker pull nginx:1.20.2
镜像删除
# 删除单个镜像
docker rmi -f imgId
# 删除多个镜像
docker rmi -f imgId1 imgId2 ...
# 删除所有镜像(表达式)
docker rmi -f $(docker images -aq)
容器命令
# 创建一个容器
docker run [option] image
# option说明
--name="name" 容器名
-d 后台运行
-it 使用交互方式运行
-p 端口
-p ip:宿主机端口:容器端口
-p 宿主机端口:容器端口
-p 容器端口
# 进入容器
docker run -it nginx /bin/bash
# 退出容器
exit #停止并退出容器
Ctrl+P+Q #不停止容器退出
# 列出运行的容器
docker ps
-a # 列出所有容器
-n=? # 最近创建的容器
-q # 容器Id
# 删除容器
docker rm containerId #不能删除正在运行的容器(强制删除 rm -f)
# 删除所有容器
docker rm -f $(docker images -aq)
# 结合linux命令删除所有容器
docker ps -a -q|xargs docker rm
# 启动或停止容器
docker start contaId #启动容器
docker restart contaId #重启容器
docker stop contaId #停止容器
docker kill contaId #强制停止容器
# 查看容器中的进程
docker top contaId
# 查看容器的配置
docker inspect contaId
# 进入容器命令
docker exec -it contaId /bin/bash #开启一个新的终端
docker attach contaId #进入正在执行的终端
# 数据拷贝操作
docker cp contaId:容器内部路径 宿主机路径 #将容器内的文件拷贝到宿主机
docker cp 宿主机路径 contaId:容器内路径 #宿主机文件拷贝到容器内部
日志命令
# 查看容器日志
docker logs
--details 显示详细的日志信息
-f, --follow 输出日志
--since string Show logs since timestamp
-n, --tail string 显示日志行数
-t, --timestamps 显示时间戳
--until string Show logs before a timestamp
# eg(输出该容器的日志信息):
docker logs -tf contaId
docker logs --tail num contaId #num为要显示的日志条数
Docker深入解析
Docker镜像原理
Docker的镜像是由一层一层的文件系统组成,这种分层的文件系统就是UFS
联合文件系统。UFS主要体现在镜像和容器上,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。UFS是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。不同容器之间可以共享一些基础的文件系统层,再加上自己独有的改动层,可以大大提高存储效率。
分层概念理解:
分层的概念主要围绕一个系统文件复用的过程,简单点说就是资源共享,假设有多个镜像是基于同一个基础镜像构建而来,那么宿主机只需要保留一份基础镜像即可,容器运行的时候在内存中加载一份镜像,就可以为所有容器提供服务,这好比你的多个应用程序基于同一个版本的SDK开发,那么在宿主机上只需要装一个该版本的Runtime就可以为这些应用提供服务。并且Docker的镜像每一层都可以被共享。
# 可通过inspect命令查看镜像的分层信息
docker image inspect imgName #在Rootfs中的部分
注意
在Docker中会将多个镜像的组合对外展示为统一的文件系统,每次往基础镜像中添加额外的镜像层时,镜像始终保持是当前所有镜像的组合。镜像始终呈现出一种堆叠的状态。
镜像提交(commit)
# 使用commit提交一个新的镜像版本
docker commit -m='描述信息' -a='作者' contaid imgName:[TAG]
Dockerfile
命令详解
指令 | 时效 | 说明 |
---|---|---|
FROM | xxx | 指定该镜像的基础镜像FROM centos:8 |
MAINTAINER | xxx | MAINTAINER "Geek created" |
RUN | 构建镜像时执行 | 镜像构建时需要运行的命令RUN ls -l |
CMD | 运行容器时执行 | 容器启动时要运行的命令(只有最后一个会生效)CMD ["ls", "-l"] |
ENTRYPOINT | 运行容器时执行 | 容器启动时要运行的命令,可追加命令ENTRYPOINT ["install.sh", "run"] |
EXPOSE | xxx | 暴露容器的端口号EXPOSE 80 |
WORKDIR | xxx | 工作目录WORKDIR /path/to/workdir |
ADD | xxx | 拷贝文件添加到容器中,tar文件会自动解压(网络压缩资源不会被解压),可以访问网络资源ADD txt.tff /web |
ENV | 运行容器时执行 | 环境变量ENV MYPATH /usr/local |
COPY | xxx | 复制文件到容器COPY mycss.css /source |
VOLUME | xxx | 挂载目录VOLUME ["/web/static", "/web/root"] |
EMTRYPOINT | 容器启动时执行 | 首次启动时需要执行的命令EMTRYPOINT ["/docker-entrypoint.sh"] |
ONBUILD | xxx | 当该镜像为基础镜像再次构建新的镜像时,会触发执行ONBUILD ADD . /app/src |
镜像构建
# 注意最后有个点(特指上下文路径,即Dockerfile所在路径)
docker build -t myapp:v1 .
注意
有些指令在功能上都差不多,但也是有区别的:
RUN
、CMD
、ENTRYPOINT
执行脚本的指令- 三个指令都是执行脚本
RUN
是在创建镜像时执行,使用docker build
命令时执行,在一个Dockerfile里面可以有多个RUN
CMD
和ENTRYPOINT
是在运行容器时执行,即使用docker run
命令时执行,这两个指令在Dockerfile中都只有最后一条被执行CMD
在使用docker run
时可以加参数将Dockerfile中的CMD
覆盖ENTRYPOINT
在Dockerfile中出现后就一定会在docker run
时被执行,不必担心会被其他参数所覆盖。
ADD
、COPY
拷贝文件到容器ADD
拷贝文件(夹)时可以指定本地文件、远程URL地址,如果拷贝的是tar
压缩文件时将会被自动解压成文件夹COPY
拷贝文件(夹)时不可以指定远程URL地址,不会自动解压成文件夹,在拷贝本地文件时建议使用COPY
优化
- 组合运行语句:合并相同类型构建语句,可以有效减少镜像分层;
- 利用镜像构建缓存:时间同步,基础软件安装等固定内容在镜像前部分处理,镜像重新构建时会使用缓存,节省时间;
- 清理中间产物:注意安装过程中使用的软件和压缩包在一定要同一层里清理,否则仍然会占用镜像空间;
- 构建语句优化:比如ADD在处理本地文件时可以直接解压缩,起到COPY + RUN tar的作用;
- 优化基础镜像源:国内高校和大型IT企业都有创建镜像站,选择一个稳定更新及时的镜像站可以有效缩短构建时间;
Docker Compose
简介
在实际的生产环境中一个项目大多是由多个容器运行起来,这样做还有个好处就是一个容器down掉,不会影响到其他服务。Compose 是用于运行多容器 Docker 应用程序的工具。通过使用 YML 文件来配置应用程序需要的所有服务。
docker-compose.yml文件
version: '2'
services:
web:
image: dockercloud/hello-world
ports:
- 8080
networks:
- front-tier
- back-tier
redis:
image: redis
links:
- web
networks:
- back-tier
lb:
image: dockercloud/haproxy
ports:
- 80:80
links:
- web
networks:
- front-tier
- back-tier
volumes:
- /var/run/docker.sock:/var/run/docker.sock
networks:
front-tier:
driver: bridge
back-tier:
driver: bridge
- version: 指定compose版本
service: 使用到的容器集合
- image: 容器使用的镜像
- links: 链接到另一个容器
- networks:加入的网络
- devices: 设备映射列表
- labels: 向容器添加元数据
- build: 指定镜像,可以基于一份 Dockerfile