一、Docker简介
容器:运行在同一类用户空间上的程序打包在一起,相当于一个集装箱
Docker:码头装运工;把集装箱搬运到该有的位置。
Docker 项目的目标是实现轻量级的操作系统虚拟化解决方案。 Docker 的基础是 Linux 容器(LXC)等技术。
在 LXC 的基础上 Docker 进行了进一步的封装,让用户不需要去关心容器的管理,使得操作更为简便。用户操作 Docker 的容器就像操作一个快速轻量级的虚拟机一样简单。
下面的图片比较了 Docker 和传统虚拟化方式的不同之处,可见容器是在操作系统层面上实现虚拟化,直接复用本地主机的操作系统,而传统方式则是在硬件层面实现。
docker
极大减少了容器的使用难度
每一个进程运行在自己的空间
自带调试工具
二、Docker与KVM对比
作为一种新兴的虚拟化方式,Docker 跟传统的虚拟化方式相比具有众多的优势。
1. Docker 容器的启动可以在秒级实现,这相比传统的虚拟机方式要快得多。 其次,Docker 对系统资源的利用率很高,一台主机上可以同时运行数千个 Docker 容器。
2. 容器除了运行其中应用外,基本不消耗额外的系统资源,使得应用的性能很高,同时系统的开销尽量小。传统虚拟机方式运行 10 个不同的应用就要起 10 个虚拟机,而Docker 只需要启动 10 个隔离的应用即可。
3. 虚拟化技术依赖物理CPU和内存,是硬件级别的;而docker构建在操作系统上,利用操作系统的containerization技术,所以docker甚至可以在虚拟机上运行。
4. 虚拟化系统一般都是指操作系统镜像,比较复杂,称为“系统”;而docker开源而且轻量,称为“容器”,单个容器适合部署少量应用,比如部署一个redis、一个memcached。
5. 传统的虚拟化技术使用快照来保存状态;而docker在保存状态上不仅更为轻便和低成本,而且引入了类似源代码管理机制,将容器的快照历史版本一一记录,切换成本很低。
6. 传统的虚拟化技术在构建系统的时候较为复杂,需要大量的人力;而docker可以通过Dockfile来构建整个容器,重启和构建速度很快。更重要的是Dockfile可以手动编写,这样应用程序开发人员可以通过发布Dockfile来指导系统环境和依赖,这样对于持续交付十分有利。
7. 当然KVM对比于容器也有一个比较大的优势就是可以使用不同的操作系统或内核。所以,举例说,你可以使用微软Azure,同时运行Windows Server2012的实例和SUSE Linux企业级服务器的实例。至于Docker,所有容器都必须使用同样的操作系统和内核。
Docker 在如下几个方面具有较大的优势。
2.1 更快速的交付和部署
对开发和运维(devop)人员来说,最希望的就是一次创建或配置,可以在任意地方正常运行。
开发者可以使用一个标准的镜像来构建一套开发容器,开发完成之后,运维人员可以直接使用这个容器来部署代码。 Docker 可以快速创建容器,快速迭代应用程序,并让整个过程全程可见,使团队中的其他成员更容易理解应用程序是如何创建和工作的。 Docker 容器很轻很快!容器的启动时间是秒级的,大量地节约开发、测试、部署的时间。
2.2 更高效的虚拟化
Docker 容器的运行不需要额外的 hypervisor 支持,它是内核级的虚拟化,因此可以实现更高的性能和效率。
2.3 更轻松的迁移和扩展
Docker 容器几乎可以在任意的平台上运行,包括物理机、虚拟机、公有云、私有云、个人电脑、服务器等。这种兼容性可以让用户把一个应用程序从一个平台直接迁移到另外一个。
2.4 更简单的管理
使用 Docker,只需要小小的修改,就可以替代以往大量的更新工作。所有的修改都以增量的方式被分发和更新,从而实现自动化并且高效的管理。
2.5 对比传统虚拟机(KVM)总结
三、Docker在实际应用中的一些问题和局限性
LXC是基于cgroup等linux kernel功能的,因此container的guest系统只能是linux base的
隔离性相比KVM之类的虚拟化方案还是有些欠缺,所有container公用一部分的运行库
网络管理相对简单,主要是基于namespace隔离
cgroup的cpu和cpuset提供的cpu功能相比KVM的等虚拟化方案相比难以度量(所以dotcloud主要是安内存收费)
container随着用户进程的停止而销毁,container中的log等用户数据不便收集
另外,Docker是面向应用的,其终极目标是构建PAAS平台,而现有虚拟机主要目的是提供一个灵活的计算资源池,是面向架构的,其终极目标是构建一个IAAS平台,所以它不能替代传统虚拟化解决方案。目前在容器可管理性方面,对于方便运维,提供UI来管理监控各个containers的功能还不足,还都是第三方实现。因为容器技术本身更适于解决大规模应用场景,所以通常都是集群基础上的部署、运维,但是目前对这一系列任务的自动化处理尚无统一的或者标准的框架。如果要让Docker真正在实际环境中发挥最大的效能并且易于维护,就需要有成熟稳定的资源编排(orchestration)、资源调度(scheduling)和部署(deployment)的支持,但是这方面暂时还没有很明显的最佳解决方案,所以大多数人都在摸索和搭建自己的解决方案。
镜像
docker镜像:分层;联合挂载;只读. 在 Docker 的术语里,一个只读层被称为镜像,一个镜像是永久不会变的。
由于 Docker 使用一个统一文件系统,Docker 进程认为整个文件系统是以读写方式挂载的。 但是所有的变更都发生顶层的可写层,而下层的原始的只读镜像文件并未变化。由于镜像不 可写,所以镜像是无状态的。 每一个镜像都可能依赖于由一个或多个下层的组成的另一个镜像。我们有时说,下层那个 镜像是上层镜像的父镜像,一个没有任何父镜像的镜像,谓之基础镜像.
Registry
镜像放在Registry后面的存储空间,在这里可有多个仓库,每个仓库只放一个镜像,仓库名即是程序名;Registry中可单独创建名称空间。http magedu/http 顶级名称空间,名称空间,版本;有索引。
仓库名就是应用程序名,镜像与容器关系,程序和进程的关系,镜像是有生命周期的,容器是动态的。
每一个容器可以运行多个进程但是在docker中每个容器内部只能运行一个进程及其子程序,记录的日志会放送到控制台。
docker对象:
imsges,containers,network,volumes,plugins.对每一个对象都能进行增删改查操作
docker六大名称空间:
user;pid;mount;ipc;network;utc
安装使用docker两种方法
1 官方 RPM extras仓库 2 阿里镜像
1 需要安装epel源 才能yum安装container-selinux
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
yum install epel-release #阿里云上的epel源
2 yum install docker-ce
出现报错
Error: Package: docker-ce-18.06.1.ce-3.el7.x86_64 (docker-ce-stable)
Requires: container-selinux >= 2.9
You could try using --skip-broken to work around the problem
You could try running: rpm -Va --nofiles --nodigest
解决办法:
yum install container-selinux
3 安装镜像加速器
mkdir /etc/docker
vim /etc/docker/daemon.json
{ "registry-mirrors": ["https://registry.docker-cn.com"] }
4 systemctl start docker.service
docker架构
docker命令
新版进行了分组,对于容器管理用container,对于镜像用image
查找
使用 docker search 命令查找默认仓库中的镜像 docker search nginx 常用选项: --automated 只列出 automated build类型的镜像 --no-trunc 显示完整的镜像描述 -s 列出收藏数不小于指定值的镜像
docker info 显示版本信息
获取
使用 docker image pull 命令来从仓库获取所需要的镜像 docker images pull alpine:3.8 常用选项: -a 拉取所有 tagged 镜像 --disable-content-trust 忽略镜像的校验,默认开启
###### 查看
使用 docker image ls 命令来显示本地所有的镜像
别名:docker image <ls | list | images> docker image ls
删除
使用 docker image rmi 命令删除本地镜像 docker image rmi busybox:latest 常用选项: -f 强制删除,不保留已有容器 --no-prune 不移除该镜像的过程镜像,默认移除
docker images inspect alpin 详细查看镜像
容器
容器本质上是进程,我们原先是在一个操作系统上装很多个服务,比如nginx,mysql,或者其他的服务器,掺杂到系统里面,现在有个容器以后,我会在操作系统中运行mysql容器,nginx容器,或者tomcat容器,会把这个3个进程全部打包到容器里面,这样的话,如果这个进程想要的话,我们就把这个容器启动起来,我们这个进程想把这个容器删掉。所以很显而易见docker它不是虚拟化技术。 容器本质上是进程,我们原先是在一个操作系统上装很多个服务,比如nginx,mysql,或者其他的服务器,掺杂到系统里面,现在有个容器以后,我会在操作系统中运行mysql容器,nginx容器,或者tomcat容器,会把这个3个进程全部打包到容器里面,这样的话,如果这个进程想要的话,我们就把这个容器启动起来,我们这个进程想把这个容器删掉。所以很显而易见docker它不是虚拟化技术。
创建 使用 docker container create 命令新建容器 docker container run --name b1 -it alpine:3.8 创建并在后台alpine:3.8上运行 docker container ps -a 显示所有容器
启动容器有两种方式,一种是基于镜像新建一个容器并启动,另外一个是将在终止状态(stopped)的容器重新启动。
新键并启动 使用 docker container run 命令来新建容器并启动 docker run --name webserver -d nginx:1.14-alpine
常用选项:
-a stdin 指定标准输入输出内容类型,可选 STDIN/STDOUT/STDERR 三项 -d 后台运行容器,并返回容器ID -i 以交互模式运行容器,通常与 -t 同时使用 -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=[] 开放一个端口或一组端口 重新启动
使用 docker container start 命令重新启动停止状态的容器 docker start webserver
常用选项:
start 启动一个或多个处于停止状态的容器
stop 暂停一个处于UP状态的容器
restart 重启容器
查看
使用 docker container ps 查看容器当前的状态
别名:docker container <ls | list> docker ps
常用选项:
-a 显示所有的容器,包括未运行的 -f 根据条件过滤显示的内容 --format 指定返回值的模板文件 -l 显示最近创建的容器 -n 列出最近创建的n个容器 --no-trunc 不截断输出 -q 静默模式,只显示容器编号 -s 显示总的文件大小
暂停 使用 docker container pause/unpause 暂停或继续容器 docker container pause Bbox docker container unpause Bbox
中止 使用 docker container kill 中止一个或多个容器 docker container kill webserver 常用选项:
-s 向容器发送一个信号
删除
使用 docker container rm 删除一个或多个容器
docker container rm quirky_ramanujan 常用选项:
-f 通过SIGKILL信号强制删除一个运行中的容器
-l 移除容器间的网络连接,而非容器本身
-v -v 删除与容器关联的卷