目录
一,什么是docker?它和虚拟机有什么区别?
docker它是一种容器技术,它可以开辟一定的虚拟空间提供给程序运行,空间和空间之间彼此隔离互相独立,这个空间被称为容器,它可以公用宿主机的资源,最大限度的运用宿主机的软硬件设备。
docker和虚拟机之间的区别,第一点:虚拟机通常是由虚拟机内核和发行版本组成的,这两者是强绑定关系,而docker它是基于虚拟机内核运作的,对发行版本没有强依赖关系,在一个虚拟机内核上docker可以通过运行不同的发行版本,来提供不同的操作系统,让适配更加灵活,第二点:虚拟机要想运行往往需要宿主机分割设备资源,比如需要分割内存,硬盘等资源,一台宿主机只能运行少量的虚拟机,数量一多会造成宿主机的卡顿,而docker它不需要宿主机分割资源,它和宿主机公用设备的资源,同一台宿主机运行docker容器的数量要远大于运行虚拟机的数量。第三点:docker容器的启动速度要远快于虚拟机的启动。
二,为什么要有docker
最主要的原因是因为docker可以保证环境的一致性和迁移的稳定性,以往开发一个项目,交给测试,测试将项目部署到测试环境,没问题后交给运维部署到生产环境,在这个过程中配置的改动,环境的依赖发生变化都需要手动去修改和传递,要是中间因为疏忽漏改或者改错,环境就会发生不一致,会出现开发环境可以,怎么测试环境就不行,测试环境可以,生产怎么又不行了,那么这其中的沟通成本也就比较大。使用docker来部署的话,我们只需要将项目依赖的配置和组件都写在Dockerfile里面,那么不管是在开发,测试,生产环境,通过Dockerfile构建出来的镜像都是一样的,就可以很好的保证环境的一致性,减少了沟通成本。还有一个小原因就是docker它不会改变宿主机的环境参数,通常运行一个项目,需要在对应的宿主机安装各种软件工具,可以会修改宿主机的一些配置参数等,使用docker,就只需要在宿主机上安装docker,然后在docker里pull你需要的镜像,修改配置,启动容器,不需要了就卸载docker就行,因为容器都是跑在docker里,你的宿主机会很干净。
三,docker由哪些核心组成
1,镜像。是一个只读模板,用于创建容器,镜像的获取方式有两种,一种是从镜像仓库拉取别人写好的镜像,一种是自己编写dockerfile构建镜像。
2,容器。容器是镜像的实例,容器和容器之间彼此隔离,互相独立
3,数据卷。存储容器运行产生的数据
4,网桥。分配一个网络接口,让容器和宿主机通信
四,容器的生命周期
如图,通过dockerfile或者远程镜像库去(build)构建或(pull)下载镜像,镜像(run)运行产生容器,容器(commit)提交可以生成镜像,镜像(push)推送镜像到远程仓库,镜像(save)保存将镜像保存到本地仓库,本地仓库(load)加载生成镜像。
五,docker的工作流程
第一步,启动docker,使用docker pull 镜像名称|版本 从远程仓库拉取镜像,如果本地仓库有该镜像,将不会从远程仓库拉取,直接使用本地镜像。
第二步,运行镜像生成容器实例。使用命令docker run 参数,镜像名,可以启动一个镜像生成实例,docker底层镜像使用了UFS技术,该技术将多个文件联合起来形成一个文件进行输出,当执行RUN命令时候,docker 会从最底层的镜像开始加载,逐层向上,将所有文件信息加载到一个空白层也称作读写层,然后将这个读写层放到镜像的最上层,返回读写层的镜像id,后续对容器的操作都是基于这个读写层,不会影响下面的其他基础镜像。为什么使用UFS技术,主要是为了方便存储和复用,原理类似搭积木,在构建镜像时候,如果有多个镜像都依赖一个基础镜像,那么只需要在内存里存储一个就行了,不用每个都存一遍,那么既然大家都用一个基础镜像,如果我对这个基础镜像修改,会影响到其他镜像吗?针对这个问题,docker采用copyonwrite(写时复制)技术,当涉及到修改基础只读镜像的操作,docker会将修改的内容从底层目标镜像复制一份到最上层的读写层,然后修改读写层的该参数,docker加载是从下往上,但是读取顺序是从上往下的,这样容器启动 时候会读取你修改的参数,基础镜像对应的参数不会读取。
第三步,进行容器和宿主机的端口映射,在容器启动时 参数里 加上 -p 宿主机端口|容器端口 命令,然后访问宿主机端口即可访问到容器中。
六,docker常用命令
搜寻镜像
docker search 镜像名|版本号
拉取镜像
docker pull 镜像名|版本号
删除镜像
docker rmi 镜像id
运行镜像
docker pull 镜像名|版本号
查看本地镜像
docker images
指定端口映射启动容器
docker run -p 宿主机端口|容器端口 镜像名|版本号
启动一个交互式容器
docker run -it 镜像名|版本 bash
-it:交互式界面
bash:指令编译解释器,用于翻译指令
启动一个容器在后台运行
docker run -d 镜像名|版本
-d:程序在后台运行(容器需要启动必须有命令或操作要在前端跑着,否则会挂掉)
给启动容器起名,设置容器挂了自动重启
docker run --name 容器名称 -d --restart=always 镜像名|版本 bash
--name:给启动容器命名
-d:容器后台运行
--restart:重启策略
查看容器日志
docker logs -f
-f:实时刷新
查看运行的容器
docker ps
查看所有容器包括挂掉的
docker ps -a
启动容器
docker start
停止容器
docker stop
进入容器
docker exec -it 容器id bash
删除容器
docker rm 容器id
强制删除容器
docker rm -f 容器id
查看容器内的进程信息
docker top 容器id
查看容器内资源管理信息
docker stats 容器id
查看容器详细信息
docker inspect 容器id
不使用缓存构建
docker build -no-cache
七,Dockerfile
dockerfile用来构建镜像的一个脚本,通过dockerfile自己的命令,来构建软件依赖,文件依赖,存储等,其目的就是定义一个你想要的容器环境。镜像式分层的,所以dockerfile也是一层一层构建。
FROM:指定基础镜像(发行版)
MAINTAINER:指定维护者
RUN:你想让它干什么
ADD:给它提供什么东西,copy文件会自动解压
WORKDIR:切换目录,类似cd命令
VOLUME:设置存储卷,挂载主机目录,比如,volume ["/data1","/data2"]他会将这两个目录自动和宿主机的目录进行挂载,可以通过docker inspect 容器id来查看具体挂载信息。还可以直接通过docker run -v 参数来指定挂载目录。
EXPOSE:对外指定端口
CMD:指定容器启动后干的事情
USER:切换用户
COPY:复制文件。不会自动解压单纯复制
ENV:环境变量,ENV MySQL=5.8,后面使用${MySQL}就可以引用它的值,方便统一管理
ENTRYPOINT:容器启动后要执行的命令
注意;CMD和ENTRYPOINT都是指定容器启动后执行的命令,当指定ENTRYPOINT之后,CMD的语义发生了变化,CMD输入的内容会 当初参数传入ENTRYPOINT中,比如 CMD 后面跟的命令是docker ps 那么容器启动后会自行执行docker ps命令,当你在输入-a 想查看所有容器记录时,-a命令会完全覆盖掉docker ps 命令,也就是单独执行了一个-a命令,会报错,但是如果ENTRYPOINT后面跟一个docker ps 命令,容器启动后会去自动执行docker ps,这个时候你输入-a 它会将-a作为参数传入到原有命令后面即执行的是 docker ps -a命令,就可以正确执行不会报错。
ENV和ARG
相同点:他们都是用于设置环境变量
不同点:ENV无论在镜像构建时还是容器运行时,都可以使用,ARG只在镜像构建时可以使用,容器运行时不可使用