docker 为什么比虚拟机更快
- docker有着比虚拟机更少的抽象层
- docker不需要虚拟机实现硬件资源的虚拟化,运行在docker容器上的程序直接使用的都是实际物理机的硬件资源,因此在CPU、内存利用率上docekr将会在效率上有明显的优势。
- docker利用的是宿主机的内核,而不需要加载操作系统OS内核
- 当新建一个容器时,docker不需要和虚拟机一样重新加载一个操作系统内核。进而避免引寻、加载操作系统内核返回等比较费时费资源的过程,当新建一个虚拟机时,虚拟软甲需要加载OS,返回新建过程是分钟级别的。而docker由于直接利用宿主机的操作系统,则省略了返回过程,因此新建一个docker容器只需要几秒钟。、
Docker容器 | 虚拟机(VM) | |
---|---|---|
操作系统 | 与宿主机共享OS | 宿主机OS上运行虚拟机OS |
存储大小 | 镜像小,便于存储与传输 | 镜像庞大(vmdb,vdi)等 |
运行性能 | 几乎无额外性能损失 | 操作系统额外的CPU、内存消耗 |
移植性 | 轻便、灵活、适用于Linux | 笨重,与虚拟化技术耦合度高 |
硬件亲和性 | 面向软件开发者 | 面向硬件运维者 |
部署速度 | 快速,秒级 | 较慢,10s以上 |
docker 常用命令
- docker 三要素 镜像、容器、仓库
功能 | 命令 |
---|---|
启动docker | systemctl start docker |
停止docker | systemctl stop docker |
重启docker | systemctl restart docker |
查看docker状态 | systemctl status docker |
开机启动 | systemctl enable docker |
查看docker总体帮助文档 | docker --help |
查看docker命令帮助文档 | docker 具体命令 --help |
查看docker镜像 | docker images [-q][-a] |
搜索镜像 | docker search 某个镜像名字 |
拉取镜像 | docker pull 某个镜像名字 |
查看镜像/容器/数据卷所占空间 | docker system df |
删除某个镜像 | docker rmi [-f] [镜像ID1] [镜像ID2] |
删除全部镜像 | docker rmi -f $(docker images -qa) |
- 面试题:docker虚悬镜像是什么
- 仓库名、标签都是的镜像,速成虚悬镜像dangling image
容器命令
- docker run [options] image [command] [arg...]
- option 说明
- --name="容器新名字" 为容器指定一个名字
- -d: 后台运行并返回容器ID,也即启动守护式容器(后台运行)
- -i: 以交互模式运行容器,通常与-t同时使用
- -t: 为容器重新分配一个伪输入终端,通常与-i同时使用(也即启动交互式容器,前台有伪终端,等待交互)
- -P:随机端口映射(大写P)
- -p: 指定端口映射(小写p)
- docker run -it centos /bin/bash
- -i:交互式操作
- -t: 终端
- centos:centos镜像
- /bin/bash: 放在镜像后面的命令,这里我们希望有个交互式Shell,因此使用的是/bin/bash
- exit 退出终端
- 前台交互式启动:docker run -it redis:6.0.8
- 后台守护式启动:docker run -d redis:6.0.8
- option 说明
- 退出容器
- exit run进去容器,exit退出,容器停止
- ctrl + p + q run 进去容器,ctrl + p + q退出,容器不停止
- 启动已停止的容器
- docker start 容器ID或者容器名
- 重启容器
- docker restart 容器ID或容器名
- 停止容器
- docker stop 容器ID或容器名
- 强制停止容器
- docker kill 容器ID或容器名
- 删除已停止容器
- docker rm [-f] 容器ID (-f)为强制删除
- 一次性删除多个容器实例:
- docker rm - f $(docker ps -a)
- docker ps -a -q | xargs docker rm
- 查看运行日志
- docker logs 容器ID
- 查看容器内运行的进程
- docekr top 容器ID
- 查看容器内部细节(每一个docker容器都是一个简易版的Linux环境)
- docker inspect 容器ID
- 进入正在运行的容器并以命令行交互
- docker exec -it 容器ID bashShell
- 重新进入docker attach 容器ID
- exit 停止容器
- ctrl + p + q:退出容器,容器继续运行
- 区别:
- attach 直接进入容器启动命令的终端,不会启动新的进程,用exit退出,会导致容器停止
- exec是在容器中打开新的终端,并且可以启动新的进程,用exit退出,不会导致容器的停止。
- 推荐使用docker exec命令,因为退出容器终端,不会导致容器的停止
- 一般用-d后台启动程序,再用exec进入对应的容器实例
- 从容器拷贝文件到主机
- docker cp 容器ID:容器内路径 目的主机路径
- 导入和导出容器
- export导出容器的内容作为一个tar归档文件[对应import命令] : docker export 容器ID > 文件名.tar
- import从tar包中创建一个新的文件系统再导入为镜像[对应export] : cat 文件名.tar | docker import - 镜像用户/镜像名:镜像版本号
docker镜像
镜像:镜像是一种轻量级、可独立执行的软件包,它包含运行某个软件所需的所有内容,我们把应用程序和配置依赖打包好形成一个可交付的运行环境(包括代码、运行时所需要的库,环境变量和配置文件等),这个打包好的运行环境就是image镜像文件。只有通过该镜像文件才能生成docker容器实例(类似java中new一个对象)(镜像是分层的)
UnionFS(联合文件系统):Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改操作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite serval directories into a single virtual filesystem)。Union文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作具体的应用镜像。
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来这样最终的文件系统会包含所有底层的文件和目录。
Docker镜像加载原理: docker的镜像实际上由一层一层文件系统组成,这种层级的文件系统UnionFS。
bootfs(boot file system)主要包含bootloader和kernel,bootloader主要是引导加载kernel,Linux刚启动时会加载bootfs文件系统,**在Docker镜像的最底层是引导文件系统bootfs。**这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会写在bootfs。
rootfs(root file system),在bootfs之上,包含的就是典型的Linux系统的/dev, /proc, /bin, /etc等标准目录和文件,rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等。
为什么虚拟机的CentOS都是好几个G,为什么docker才200M?
回答:基于容器的虚拟化技术,仅包含业务运行所需的runtime环境,CentOS/Ubuntn基础镜像仅170M,宿主机可部署100~1000个容器。
- docker commit 提交容器副本使其成为一个新的镜像
- docker commit -m="提交的描述信息" -a="作者" 容器ID 要创建的目标镜像名:[标签名]
- DockerFile 生成镜像
- 本地镜像推送到阿里云
- 阿里云主页有相关描述
- 本地镜像推送到私服库
- 下载镜像docker registry:
docker pull registry
- 运行私有库:
docker run -d -p 5000:5000 -v /zzyyuse/myregistry/:tmp/registry --privileged=true registry
curl -XGET http://公网IP:Port/v2/_catalog
查询主机端口都有哪些服务(需开放端口) -docker tag 镜像名:Tag Host:Port/Repository:Tag
将镜像修改为符合私服规范的Tag- 修改配置文件使其支持http:
vim /etc/docker/daemon.json //在Json文件中添加以下内容 "insecure-registries":["公网ip:私服库端口"] //重启docker服务,并启动私服库 systemctl restart docker docker run -d -p 5000:5000 -v /zzyyuse/myregistry/:tmp/registry --privileged=true registry
- 推送到私服库
docker push ip:port/镜像名:tag
- pull到本地运行
- 下载镜像docker registry:
Docker容器数据卷
Docker挂载主机目录访问如果出现cannot open directory:Permission denied
解决办法: 在挂载目录后多加一个--privileged=true参数即可
如果是CentOS7安全模块会比之前系统版本加强,目录挂载的情况被默认为不安全的行为。在SELinux里面挂载目录被禁止掉了。若要开启,一般使用--privileged=true命令,扩大容器的权限解决挂载目录没有权限的问题,也即使用该参数,container内的root拥有真正的root权限,否则,container内的root只是外部的一个普通用户权限。
docker -d -p 5000:5000 -v /zzyyuse/myregistry/:/tmp/registry --privileged=true registry
// -v 代表容器卷挂载地址
// /zzyyuse/myregistry/ 表示宿主机绝对路径地址
// /tmp/registry 表示docker中的地址,可与宿主机地址进行信息共享与互通互联
卷就是目录或文件,存在于一个或多个容器中,由docker挂载到容器,但不属于联合文件系统,因此能够绕过Union File System提供一些用于持续存储或共享数据的特性。
卷的设计目的是数据的可持久化,完全独立于容器的生存周期,因此Docker不会在容器删除时删除其挂载的数据卷。
- 特点
- 数据卷可在容器之间共享或重用数据
- 卷中的更改可以直接实时生效
- 数据卷中的更改不会包含在镜像的更新中
- 数据卷的生命周期一直持续到没有容器使用它为止
- 命令
docker run -it --privileged=true -v /宿主机中的绝对路径目录:/容器内目录 镜像名
docker inspect 容器Id
将容器内部重要信息以Json串形式展示,Mounts中展示容器挂载信息
容器卷的读写权限
- 只读权限(容器实例只能读取容器卷中的文件,不能写)
- ro = read only
- 命令: `docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录:ro 镜像名`
容器卷的读写与共享
- 容器2继承容器1的卷规则
- 参数: --volumes-from 父类
- docker run -it --privileged=true --volumes-from 父类(容器名) --name u2 ubuntu
软件安装简介
- 总体步骤
- 搜索镜像
- docker hub 上搜索镜像
- 命令搜索: docker search tomcat
- 拉取镜像
- docker pull tomcat
- docker run -d -p 8080:8080 --name mytomcat8 billygoo/tomcat8-jdk8
- 执行run命令时,若本地不存在镜像,则会自动拉取
- 查看镜像
- docker images tomcat
- 启动镜像
- 服务端口映射
- docker run -it -p 8080:8080 tomcat
- 停止容器
- docker stop tomcat
- 移除容器
- docker rm -f tomcat
- 搜索镜像
- 安装mysql(简单版,存在中文乱码问题)
- docker run -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7(需确保3306无占用)
- 运行成功后可在本地连接宿主机的3306端口来远程连接mysql
- 查看字符集编码
- show variables like 'character%'
- docker run -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7(需确保3306无占用)
- 安装mysql(开发版,解决中文乱码,挂载容器数据卷)
docker run -d -p 3306:3306 --privileged=true -v /zzyyuse/mysql/log:/var/log/mysql -v /zzyyuse/mysql/data:/var/lib/mysql -v /zzyyuse/mysql/conf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=123456 --name mysql mysql:5.7
- 解决中文乱码问题
- cd /zzyyuse/mysql/conf/
- vim my.cnf
[client] default_character_set=utf8 [mysqld] collation_server = utf8_general_ci character_set_server = utf8
- 解决中文乱码问题
- 安装redis
- 在宿主机/app/redis/文件夹下配置redis.conf文件
- 安装并运行redis命令
docker run -p 6379:6379 --name myr3 --privileged=true -v /app/redis/redis.conf:/etc/redis/redis.conf //配置文件映射 -v /app/redis/data:/data -d redis:6.0.8 redis-server /etc/redis/redis.cong