docker和传统虚拟化方式不同:
- 传统虚拟化技术是虚拟出一套硬件后,在其上运行一个完整的操作系统,在该系统上运行所需应用进程;
- 容器内的应用进程直接运行于宿主的内核,容器没有自己的内核,也没有硬件虚拟。因此更为轻便
- 每个容器之间相互隔离,每个容器都有自己的文件系统,容器直接的进程不会相互影响,能区分计算资源
docker三要素:
镜像(Image):一个只读的模板。镜像可以用来创建docker容器,一个镜像可以创建很多容器
容器(Container):docker利用容器独立运行的一个或一组应用。容器是镜像创建的运行实例。
可以被启动,开始,停止,删除。每个容器都是相互隔离的、保证安全的平台。
可以把容器看成简易版的Linux环境(root权限,进程空间,用户空间和网络空间)和运行在其中的应用程序。
容器的定义和镜像几乎相同,也是一堆层的统一视角,唯一区别是容器最上面一层是可读可写的。
仓库(Repository):存放镜像文件的场所。
仓库(Repository)和仓库注册服务器(Registry)是有区别的。仓库注册服务器上往往存放多个仓库,每个仓库又包含多个镜像,每个镜像都有自己的唯一标签(tag).
仓库分为公开仓库(public)和私有的仓库(private)。最大的公开仓库是Docker Hub(https://hub.docker.com/
docker使用EPEL发布,RHEL系的OS首先确保已经持有EPEL仓库,否则先检查os的版本,然后安装相应的EPEL包
docker常用帮助命令 docker version,docker info,docker --help
docker 镜像命令:
- docker images
REPOSITORY:镜像仓库源
TAG:镜像的标签
IMAGE ID:镜像ID
CREATED:创建时间
SIZE:镜像大小
同一个仓库源可以有多个TAG,代表这个仓库源的不同版本,使用REPOSITORY:TAG 来定义不同的镜像。
如果不指定一个镜像的版本标签,例如只使用ubuntu,docker会默认使用ubuntu:lastest镜像
OPTIONS说明:-a:列出本地所有镜像(含中间映像层)
-q:只显示镜像ID
--digests:显示镜像的摘要信息
--no-trunc:显示完整的镜像信息
- docker search
docker search [OPTIONS] 镜像名字
OPTIONS说明:--no-trunc:显示完整的镜像描述
-s:列出收藏数不小于指定值的镜像(Flag --stars has been deprecated, use --filter=stars=3 instead)
--automated:只列出automated build类型的镜像
- docker pull
docker pull tomcat 等价于docker pull tomcat:latest
- docker rmi
删除单个:docker rmi 镜像ID或镜像名 #docker rmi hello-world等价于docker rmi hello-world:latest
-f:强制删除
删除多个:docker rmi 镜像名1:TAG 镜像名2:TAG
删除全部:docker rmi -f $(docker images -qa)
Docker 容器命令:
docker create [OPTIONS] IMAGE [COMMAND] [ARG…]
创建一个容器但不启动它。
- docker run [OPTIONS] IMAGE [COMMAND] [ARG…]
OPTIONS: --name=“容器新名字”:为容器指定一个名称
-d:后台运行容器,并返回容器ID,即启动守护式容器
-i:以交互模式运行容器,通常与-t同时使用
-t:为容器重新分配一个伪输入终端,通常与-i同时使用
-P:随机端口映射
-p:指定端口映射,有以下四种格式:
ip:hostPort:containerPort
ip::containerPort
hostPort:containerPort
containerPort
OPTIONS说明:
-a stdin: 指定标准输入输出内容类型,可选 STDIN/STDOUT/STDERR 三项;
-d: 后台运行容器,并返回容器ID;
-i: 以交互模式运行容器,通常与 -t 同时使用;
-P: 随机端口映射,容器内部端口随机映射到主机的高端口
-p: 指定端口映射,格式为:主机(宿主)端口:容器端口
-t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用;
--name="nginx-lb": 为容器指定一个名称;
--dns 8.8.8.8: 指定容器使用的DNS服务器,默认和宿主一致;
--dns-search example.com: 指定容器DNS搜索域名,默认和宿主一致;
-h "mars": 指定容器的hostname;
-e username="ritchie": 设置环境变量;
--env-file=[]: 从指定文件读入环境变量;
--cpuset="0-2" or --cpuset="0,1,2": 绑定容器到指定CPU运行;
-m :设置容器使用内存最大值;
--net="bridge": 指定容器的网络连接类型,支持 bridge/host/none/container: 四种类型;
--link=[]: 添加链接到另一个容器;
--expose=[]: 开放一个端口或一组端口;
--volume , -v: 绑定一个卷
- docker ps
docker ps [OPTIONS]:查看docker有哪些容器在运行
OPTIONS:-a:列出当前所有正在运行的容器+历史上运行过的容器
-l:显示最近创建的容器
-n 3:显示最近3个创建的容器
-q:静默模式,只显示容器编号
--no-trunc:不截断输出
- 退出容器
exit:容器停止退出
ctrl+P+Q:容器不停止退出
- 启动容器
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
重要:
docker run -d centos /bin/sh -c "while true; do echo hello world; sleep 2; done"
docker run -d 镜像:后台运行镜像。
docker容器后台运行,就必须有一个前台进程。容器运行的命令如果不是那些一直挂起的命令(比如top,tail),就是会自动退出的。
=====================
-
镜像原理:
镜像是一个轻量级、可执行的独立软件包,用来打包运行环境和基于运行环境开发的软件。它包含应用软件所需的所有内容,包括代码,运行时,库,环境变量以及配置文件。
联合文件系统(UnionFS):
是一种分层,轻量级,高性能的文件系统,它支持文件系统的修改作为一次提交来层层叠加。Union文件系统是docker镜像的基础。镜像通过分层来继承,基于基础镜像,可以制作各种各样的应用镜像。特性:一次加载多个文件系统,但是在外面看来,只有一个文件系统。联合加载会把各个文件叠加起来,这样的文件系统会包含所有的底层和目录。
docker镜像加载原理:
bootfs(boot file system)主要包含bootloader 和kernel,bootloader主要是引导加载kernel。linux刚启动时会加载bootfs系统。docker的底层就是bootfs,Linux系统启动时,通过bootloader加载内核,加载完成后内核就在内存中了,此时系统将会卸载bootloader。
rootfs(root file system),在bootfs之上,典型的是Linux系统的标准文件和目录(/dev,/etc。。。)。rootfs是不同操作系统的发行版(Ubuntu,centos etc)。
特点:镜像都是只读的,当容器启动时,一个可写层被加载到镜像的顶部,这一层叫容器层,容器层下的都叫做镜像层。
镜像提交:
docker commit 提交容器副本使之成为一个新的镜像
docker commit -m "描述信息" -a "作者" 容器ID 要创建的镜像名:标签
容器是一个简易的Linux系统包括root用户权限,进程空间,用户空间和网络空间等
启动守护式进程:docker run -d 容器名
查看容器日志:docker logs -f -t --tail 容器id
-t:加入时间戳(time)
-f:持续输出
--tail 数字:显示后多少行
查看容器内进程:docker top 容器ID
查看容器内部细节:docker inspect 容器ID
操作容器并以命令行交互:1. docker exec -it 容器ID /bin/bash
2. docker attach 容器ID:重新进入docker
区别:attach 进入容器启动的终端 exec:在容器中启动新的终端,并可以启动新的进程,exit不会终结容器
docker exec -t centos容器id ls -l /tmp:查看centos容器内/tmp路径下的文件并返回给宿主机
-t:tty命令行 -i:interactive交互式
从容器内拷贝文件到宿主机:docker cp 容器ID:docker内路径 宿主机路径
容器数据卷
概念:容器和宿主机之间共享数据的文件夹
特点:1.数据卷可在容器间共享或重用数据
2.卷中的更改可以直接生效
3.数据卷中的更改不会包含在镜像中
4. 数据卷的生命周期一直持续到没有容器使用它为止
容器内添加:
1.直接命令添加
命令:docker run -it -v /宿主机绝对路径:/容器内路径 镜像名(--mount source=myvol2,target=/app 也可)
查看数据卷是否挂载成功:docker inspect containerID (会在Mounts:"RW":true 显示 read write)
容器停止后再启动依然会同步
带权限的容器数据卷:docker run -it -v /宿主机绝对路径:/容器内路径:ro 镜像名(read only)
2.Dockerfile添加
VOLUME["/dataVolumeContainer", "/dataVolumeContainer2", "/dataVolumeContainer3"]
说明:出于可移植性和分享的考虑,用-v 主机目录:容器目录这种方法不能够直接在Dockerfile中实现。并不能保证所有的宿主机都存在这样的目录。
docker build -f /DockerfilePath -t 镜像名称 . #-f:file -t:命名空间 最后还有一个点
使用: docker inspect containerID 查看映射的宿主机路径
如果出现docker挂载主机目录docker访问出现cannot open directory.:Permission denied, 解决办法:在挂载目录后面多加一个--privieged=true 即可
数据卷容器:命名的容器挂载数据卷,其它容器通过挂载这个(父容器)实现数据共享,挂载数据卷的容器,称之为数据卷容器
容器间传递共享: --volumes-from
docker run -it --name c02 --volume-from c01 imageID
删除数据卷容器后子容器依然可以共享数据卷,因为都绑定的是同一个宿主机目录。容器之间配置信息的传递,数据卷的生命周期一直持续到没有容器使用它为止。
Dockerfile
概念:Dockerfile是用来构建docker镜像的构建文件,是由一系列命令和参数构建成的脚本。
构建三步曲:编写Dockerfile -> docker build -> docker run
scratch: 所有镜像的父镜像相当于java object类
Dockerfile基础:
1. 每条保留字指令都必须为大写且后面必须跟随至少一个参数
2. 指令按照从上到下,顺序执行。
3. #表示注释
4. 每条指令都会创建一个新的镜像层,并对镜像进行提交
Docker执行Dockerfile的大致流程:
1. docker从基础镜像运行一个容器
2. 执行一条指令并对容器作出修改
3. 执行类似docker commit 的操作提交一个新的镜像层
4. docker再基于刚提交的镜像运行一个新的容器
5. 执行Dockerfile中的下一条指令直至所有指令都执行完成
Dockerfile、Docker镜像、Docker容器关系:
1. Dockerfile定义了进程所需要的一切东西。Dockerfile涉及的内容包括执行代码或者是文件、环境变量、依赖包、运行时环境、动态链接库、操作系统发行版、服务进程和内核进程等。
2.Docker镜像:在用Dockerfile定义一个文件之后,docker build时会产生一个Docker镜像,当运行Docker镜像时,会真正开始提供服务;
3. Docker容器,容器是直接提供服务的。
Dockerfile保留字指令:
FROM:基础镜像,当前新镜像是基于哪个镜像的。
MAINTAINER: 镜像维护者的姓名 和邮箱地址
RUN:容器构建时需要的命令
EXPOSE:当前容器对外暴露的端口号
WORKDIR:指定在创建容器后,终端默认登陆的进来工作目录,一个落脚点
ENV:用来在构建镜像过程中设置环境变量 ENV KEY VALUE
ADD:在宿主机目录下的文件拷贝进镜像并且ADD命令会自动处理URL和解压tar压缩包
COPY:类似ADD,拷贝文件和目录到镜像中。将从构建上下文目录中<源路径>的文件/目录复制到新的一层的镜像内的<目标路径>位置
1)copy src dest
2)COPY ["src", "dest"]
VOLUME:容器数据卷,保存数据和数据持久化工作
CMD:指定一个容器启动时要运行的命令
CMD指令的格式和RUN相似,也是两种格式:
1)shell格式:CMD <命令>
2)exec格式:CMD ["可执行文件", "参数1", "参数2"]
参数格式:CMD ["参数1", "参数2"...], 在指定了ENTRYPOINT 指令后,用CMD指定具体的参数。
Dockerfile中可以有多个CMD命令,但只有最后一个生效,CMD会被docker run之后的参数替换。
ENTRYPOINT:指定一个容器启动时要运行的命令
ENTRYPOINT的目的和CMD一样,都是在指定容器启动程序及参数。(追加)
ONBUILD:当构建一个被继承的Dockerfile时运行命令,父镜像在被子继承后父镜像的onbuild被触发。
docker run -p 3306:3306 --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
Docker build 镜像
docker build -f /DockerfilePath -t 镜像名称 . #-f:file -t:命名空间 最后还有一个点
Docker commit 镜像
docker commit -a author -m "commit content" containerID imageName:version
Mac 查看docker volume路径