一、docker 简介
docker官方介绍是这样的:“Docker is an open platform for developing, shipping, and running applications. Docker enables you to separate your applications from your infrastructure so you can deliver software quickly. With Docker, you can manage your infrastructure in the same ways you manage your applications. By taking advantage of Docker’s methodologies for shipping, testing, and deploying code quickly, you can significantly reduce the delay between writing code and running it in production.”
百度百科是这样说的:Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的linux或Windows操作系统的机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。
1. 什么是docker
1. Docker 是一个开放源代码软件,是一个开放平台,用于开发应用、交付(shipping)应用、运行应用。
2. Docker使用Google公司推出的Go语言进行开发实现,基于Linux内核的cgroup,namespace,以及AUFS类的UnionFS等技术,对进程进行封装隔离,属于操作系统层面的虚拟化技术。
3. 由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。
4. 容器镜像是轻量的、可执行的独立软件包 ,包含软件运行所需的所有内容:代码、运行时环境、系统工具、系统库和设置。
5. 容器化软件适用于基于Linux和Windows的应用,在任何环境中都能够始终如一地运行。
6. 容器赋予了软件独立性,使其免受外在环境差异(例如,开发和预演环境的差异)的影响,从而有助于减少团队间在相同基础设施上运行不同软件时的冲突。
7. Docker容器与虚拟机类似,但二者在原理上不同。容器是将操作系统层虚拟化,虚拟机则是虚拟化硬件,因此容器更具有便携性、高效地利用服务器。
8. Docker也为容器提供更强的业界的隔离兼容,Docker 利用Linux核心中的资源分离机制,这可以在单一Linux实体下运作,避免启动一个虚拟机造成的额外负担。Linux核心对名字空间的支持完全隔离了工作环境中应用程序的视野,包括行程树、网络、用户ID与挂载文件系统,而核心的cgroup提供资源隔离,包括CPU、存储器、block I/O与网络。
简单来说:docker是一个Go语言实现的基于LXC的用于开发应用、交付应用、运行应用的容器。
除了Docker以外,还有其它很多种容器,例如Linux上的LXC、OpenVZ,FreeBSD的Jail,Solaris的Zones等等。
2. 理解docker
docker是不太好理解的,这里通俗易懂的解释一下:
Docker的思想是来自于集装箱 :
在一艘大船上,可以把货物规整的摆放起来。
并且各种各样的货物被集装箱标准化了,集装箱和集装箱之间不会互相影响。
那么我就不需要专门运送水果的船和专门运送化学品的船了。
只要这些货物在集装箱里封装的好好的,那我就可以用一艘大船把他们都运走。
docker就是类似的理念。云计算可以理解为大货轮,docker可以理解为集装箱。
3. docker有什么特点
1. 交付标准化
专业点的说法就是持续集成和持续交付。
自从容器技术发展起来之后,Devops的发展也是如火如荼。究其原因,就是因为Docker提供了标准化交付的创新途径,使开发、测试、部署过程通过流水线工具可见可控可信。
所以总结起来就是:Docker解决了运行环境和配置问题,构建过程标准化,也就方便做持续集成和持续交付。
2. 资源轻量化
Docker 容器是在操作系统层面上实现虚化,直接复用本地主机的操作系统,因此更加轻量级。
3. 迁移成本降低
一次打包,到处运行的特点,使迁移成本直线下降。比如要将数据从公有云迁至私有云,只需要迁移数据,迁移容器就可以完成了。
4. 廉价
docker可以实现虚拟机隔离应用环境的功能,开销小,就意味着省钱了。
不同的应用程序可能会有不同的应用环境,如:.net开发的网站和php开发的网站依赖的软件就不一样,如果把他们依赖的软件都安装在一个服务器上可能会出现很多的问题,如:IIS和Apache访问端口冲突。
这个时候就需要隔离.net开发的网站和php开发的网站,常规来讲,我们可以在服务器上创建不同的虚拟机在不同的虚拟机上放置不同的应用,但是虚拟机开销比较高。而利用docker就很完美。
5. 速度快
你开发软件的时候用的是Ubuntu,但是运维管理的都是centos,运维在把你的软件从开发环境转移到生产环境的时候就会遇到一些Ubuntu转centos的问题
比如:有个特殊版本的数据库,只有Ubuntu支持,centos不支持,在转移的过程当中运维就得想办法解决这样的问题。
这时候要是有docker你就可以把开发环境直接封装转移给运维,运维直接部署你给他的docker就可以了。而且部署速度快。
6. 资源利用率高
在服务器负载方面,如果你单独开一个虚拟机,那么虚拟机会占用空闲内存的,docker部署的话,这些内存就会利用起来
二、docker优缺点介绍
1. docker与虚拟机有什么区别
Docker类似虚拟机的概念,但是与虚拟化技术的不同点在于下面几点:
1. 虚拟化技术依赖物理CPU和内存,是硬件级别的;而docker构建在操作系统上,利用操作系统的containerization技术,所以docker甚至可以在虚拟机上运行
2. 虚拟化系统一般都是指操作系统镜像,比较复杂,称为“系统”;而docker开源而且轻量,称为“容器”,单个容器适合部署少量应用,比如部署一个redis、一个memcached。
3. 虚拟化技术使用快照来保存状态;而docker在保存状态上不仅更为轻便和低成本,而且引入了类似源代码管理机制,将容器的快照历史版本一一记录,切换成本很低。
4. 虚拟化技术在构建系统的时候较为复杂,需要大量的人力;而docker可以通过Dockfile来构建整个容器,重启和构建速度很快。更重要的是Dockfile可以手动编写,这样应用程序开发人员可以通过发布Dockfile来指导系统环境和依赖,这样对于持续交付十分有利。
5. Dockerfile可以基于已经构建好的容器镜像,创建新容器。Dockerfile可以通过社区分享和下载,有利于该技术的推广。Docker会像一个可移植的容器引擎那样工作。它把应用程序及所有程序的依赖环境打包到一个虚拟容器中,这个虚拟容器可以运行在任何一种 Linux服务器上。这大大地提高了程序运行的灵活性和可移植性,无论需不需要许可、是在公共云还是私密云、是不是裸机环境等等。
简单来说: 容器和虚拟机具有相似的资源隔离和分配优势,但功能有所不同,因为容器虚拟化的是操作系统,而不是硬件,因此容器更容易移植,效率也更高。
传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程。
而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。
1. 两者对比图:
2. 容器与虚拟机(VM)总结
容器是一个应用层抽象,用于将代码和依赖资源打包在一起。 多个容器可以在同一台机器上运行,共享操作系统内核,但各自作为独立的进程在用户空间中运行 。与虚拟机相比, 容器占用的空间较少(容器镜像大小通常只有几十兆),瞬间就能完成启动 。
虚拟机(VM)是一个物理硬件层抽象,用于将一台服务器变成多台服务器。 管理程序允许多个VM在一台机器上运行。每个VM都包含一整套操作系统、一个或多个应用、必要的二进制文件和库资源,因此占用大量空间。而且VM启动也十分缓慢 。
通过Docker官网,我们知道了这么多Docker的优势,但是大家也没有必要完全否定虚拟机技术,因为两者有不同的使用场景。虚拟机更擅长于彻底隔离整个运行环境。例如,云服务提供商通常采用虚拟机技术隔离不同的用户。而Docker通常用于隔离不同的应用 ,例如前端,后端以及数据库。就我目前项目而言,对于两者无所谓谁会取代谁,而是两者可以和谐共存。
3. 容器与虚拟机(VM)两者共存:
2. docker优点
其实优点在上面已经基本上提到了,在这个位置做一个总结
轻量级:Docker 容器主要利用并共享主机内核,它并不是完整的操作系统,因此它更加轻量化。
灵活:它可以将复杂的应用程序容器化,因此它非常灵活和方便。
可移植:可以在本地构建 Docker容器,并把它部署到云服务器或任何地方进行使用。
相互隔离,方便升级:容器是高度自给自足并相互隔离的容器,这样就可以在不影响其他容器的情况下更换或升级你的 Docker 容器了。
可扩展:可以在数据中心内增加并自动分发容器副本。 安全:Docker 容器可以很好地约束和隔离应用程序,并且无须用户做任何配置。
更快速的交付和部署:Docker在整个开发周期都可以完美的辅助你实现快速交付。Docker允许开发者在装有应用和服务本地容器做开发。可以直接集成到可持续开发流程中。
高效的部署和扩容:Docker 容器几乎可以在任意的平台上运行,包括物理机、虚拟机、公有云、私有云、个人电脑、服务器等。
更高的资源利用率:Docker 对系统资源的利用率很高,一台主机上可以同时运行数千个 Docker 容器。
更简单的管理:使用 Docker,只需要小小的修改,就可以替代以往大量的更新工作。
3. docker局限和缺点
1. 局限
1. Docker并不是全能的,设计之初也不是KVM之类虚拟化手段的替代品,简单总结几点:
2. Docker是基于Linux 64bit的,无法在32bit的linux/Windows/unix环境下使用
3. LXC是基于cgroup等linux kernel功能的,因此container的guest系统只能是linux base的
4. 隔离性相比KVM之类的虚拟化方案还是有些欠缺,所有container公用一部分的运行库
5. 网络管理相对简单,主要是基于namespace隔离
6. cgroup的cpu和cpuset提供的cpu功能相比KVM的等虚拟化方案相比难以度量(所以dotcloud主要是按内存收费)
7. Docker对disk的管理比较有限
8. container随着用户进程的停止而销毁,container中的log等用户数据不便收集
2. 缺点
1.内核漏洞
Docker内核攻击对于容器化环境来说可能是致命性的,因为容器与主机共享相同的系统内核,因此单独信任容器内置保护机制是不够的。
容器的隔离性使得某个应用程序的漏洞不会直接影响到其他容器的应用程序,但是漏洞可能会破坏与其他容器所共享的单一的操作系统,进而影响机器上的其他容器。
如果漏洞允许代码执行,那么它将在主机操作系统上执行,而不是在容器内执行;如果此漏洞允许任意内存访问,则攻击者可以更改或读取任何其他容器的任何数据。
2.数据分离
在docker容器上,有一些非命名空间的资源:
1. SELinux 2. Cgroups 3. file systems under /sys, /proc/sys, 4. /proc/sysrq-trigger, /proc/irq, /proc/bus 5. /dev/mem, /dev/sd* file system 6. Kernel Modules
如果攻击者可以利用当中的任意一个元素,都将拥有主机系统的操作权限。
3.资源开销
Docker由于宿主机上的所有容器是共享相同的内核和相同的资源,如果对某些资源(CPU、内存、磁盘等)的访问不受限制,那么异常的容器将占用整个宿主机的资源,从而影响其他容器的运行,影响应用程序。
4.套接字问题
容器在默认情况下都安装了docker Unix套接字(/var/run/docker.sock),此套接字,可以关闭、启动或者创建新的镜像。
当你的容器启动并共享套接字的时候,你就给了容器操控宿主机的权限,它将可以启动或终止其它容器,在宿主机拖入或创建镜像,甚至写入到宿主机的文件系统。
正确配置和保护,可以使用docker容器实现高级别的安全性,但它的安全性还是低于正确配置的VM。
虽然,Docker容器还不算完美,但是瑕不掩瑜,它使得业务的上云部署更快,资源利用更高。并且云服务商也在不断完善Docker容器技术在云服务平台的应用。
三、Dorcker原理(传送门)
Docker核心解决的问题是利用LXC来实现类似VM的功能,从而利用更加节省的硬件资源提供给用户更多的计算资源。同VM的方式不同, LXC其并不是一套硬件虚拟化方法 - 无法归属到全虚拟化、部分虚拟化和半虚拟化中的任意一个,而是一个操作系统级虚拟化方法, 理解起来可能并不像VM那样直观。所以我们从虚拟化到docker要解决的问题出发,看看他是怎么满足用户虚拟化需求的。
用户需要考虑虚拟化方法,尤其是硬件虚拟化方法,需要借助其解决的主要是以下4个问题:
1. 隔离性 - 每个用户实例之间相互隔离, 互不影响。 硬件虚拟化方法给出的方法是VM, LXC给出的方法是container,更细一点是kernel namespace
2. 可配额/可度量 - 每个用户实例可以按需提供其计算资源,所使用的资源可以被计量。硬件虚拟化方法因为虚拟了CPU, memory可以方便实现, LXC则主要是利用cgroups来控制资源
3. 移动性 - 用户的实例可以很方便地复制、移动和重建。硬件虚拟化方法提供snapshot和image来实现,docker(主要)利用AUFS实现
4. 安全性 - 这个话题比较大,这里强调是host主机的角度尽量保护container。硬件虚拟化的方法因为虚拟化的水平比较高,用户进程都是在KVM等虚拟机容器中翻译运行的, 然而对于LXC, 用户的进程是lxc-start进程的子进程, 只是在Kernel的namespace中隔离的, 因此需要一些kernel的patch来保证用户的运行环境不会受到来自host主机的恶意入侵, dotcloud(主要是)利用kernel grsec patch解决的。
四、Dorcker核心概念
1. 镜像(image)
Docker 镜像(Image)就是一个只读的模板。镜像可以用来创建 Docker 容器,一个镜像可以创建很多容器。Docker 提供了一个很简单的机制来创建镜像或者更新现有的镜像,用户甚至可以直接从其他人那里下载一个已经做好的镜像来直接使用。
2. 容器(container)
Docker 利用容器(Container)独立运行的一个或一组应用。容器是从镜像创建的运行实例。它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台。可以把容器看做是一个简易版的 Linux 环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。容器的定义和镜像几乎一模一样,也是一堆层的统一视角,唯一区别在于容器的最上面那一层是可读可写的。
3. 仓库(repository)
仓库(Repository)是集中存放镜像文件的场所。有时候会把仓库和仓库注册服务器(Registry)混为一谈,并不严格区分。实际上,仓库注册服务器上往往存放着多个仓库,每个仓库中又包含了多个镜像,每个镜像有不同的标签(tag)。
仓库分为公开仓库(Public)和私有仓库(Private)两种形式。最大的公开仓库是 Docker Hub,存放了数量庞大的镜像供用户下载。国内的公开仓库包括 时速云 、网易云 等,可以提供大陆用户更稳定快速的访问。当然,用户也可以在本地网络内创建一个私有仓库。
当用户创建了自己的镜像之后就可以使用 push 命令将它上传到公有或者私有仓库,这样下次在另外一台机器上使用这个镜像时候,只需要从仓库上 pull 下来就可以了。
Docker 仓库的概念跟 Git 类似,注册服务器可以理解为 GitHub 这样的托管服务。
五、Dockerfile、Docker镜像和Docker容器的关系
Dockerfile 是软件的原材料,Docker 镜像是软件的交付品,而 Docker 容器则可以认为是软件的运行态。从应用软件的角度来看,Dockerfile、Docker 镜像与 Docker 容器分别代表软件的三个不同阶段,Dockerfile 面向开发,Docker 镜像成为交付标准,Docker 容器则涉及部署与运维,三者缺一不可,合力充当 Docker 体系的基石。
简单来讲,Dockerfile构建出Docker镜像,通过Docker镜像运行Docker容器。
六、Docker的四种网络模式
1. host模式
docker run -it --rm --net=host centos_with_net bash指定
如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。
但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。
2. container模式
docker run -it --rm --net=container :container_id/container_name,多个容器使用共同的网络看到的ip是一样。
Container模式指定新创建的容器和已经存在的一个容器共享一个Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过lo网卡设备通信。
3. none模式
docker run -it --rm --net=none ,这种模式下不会配置任何网络。
使用none模式,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息。需要我们自己为Docker容器添加网卡、配置IP等。
4. bridge模式
docker run -it --rm --net=bridge ,不用指定默认就是这种网络模式。这种模式会为每个容器分配一个独立的Network Namespace。类似于Vmware的nat网络模式。同一个宿主机上的所有容器会在同一个网段下,相互之间是可以通信的。
bridge模式是Docker默认的网络设置,此模式会为每一个容器分配Network Namespace、设置IP等,并将一个主机上的Docker容器连接到一个虚拟网桥上。
七、docker安装
1. docker安装
我用的是centos7环境
第一步:安装工具包
$ sudo yum install -y yum-utils #安装工具包,缺少这些依赖将无法完成
第二步:设置远程仓库
$sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
第三步:安装
$ sudo yum install docker-ce
第四步:启动
$ sudo systemctl start docker
第五步:查看版本
$ sudo docker version
第六步:校验
$ sudo docker run hello-world
3. 国内镜像配置
打开配置文件:
vi /etc/docker/daemon.json
添加以下内容:
{ "registry-mirrors": ["http://hub-mirror.c.163.com"] }
可以换的源:
当然可以从下面的替换 Docker中国官方镜像加速 --registry-mirror=https://registry.docker-cn.com 网易163镜像加速 --registry-mirror=http://hub-mirror.c.163.com 中科大镜像加速 --registry-mirror=https://docker.mirrors.ustc.edu.cn 阿里云镜像加速 --registry-mirror=https://{your_id}.mirror.aliyuncs.com daocloud镜像加速 --registry-mirror=http://{your_id}.m.daocloud.io
八、docker常用命令
1. 容器
docker run 创建并启动容器 docker start 启动容器 docker ps 查看容器 docker stop 终止容器 docker restart 重启容器 docker attach 进入容器 docker exec 进入容器 docker export 导出容器 docker import 导入容器快照 docker rm 删除容器 docker logs 查看日志
2. 服务
docker version 查看docker版本详细信息 docker -v 查看docker简要信息 systemctl start docker 启动docker systemctl stop docker 关闭docker systemctl enable docker 设置开机启动 service docker restart 重启docker服务 service docker stop 关闭docker服务
3. 镜像
docker search 检索镜像 docke pull 获取镜像 docker images 列出镜像 docker image Is 列出镜像 docker rmi 删除镜像 docker image rm 删除镜像 docker save 导出镜像 docker load 导入镜像 Dockerfile 定制镜像(三个) { docker build 构建镜像 docker run 运行镜像 Dockerfile 常用指令(四个) { COPY 复制文件 ADD 高级复制 CMD 容器启动命令 ENV 环境变量 EXPOSE 暴露端口 } }