一、基本原理
- 什么是Docker?
- Docker是基于Go语言实现的云开源项目。
- Docker的主要目标是“Build,Ship and Run Any App,Anywhere”,也就是通过对应用组件的封装、分发、部署、运行等生命周期的管理,使用户的APP(可以是一个WEB应用或者数据库应用等等)及其运行环境能够做到“一次封装,到处运行”。
- Docker引擎的基础是Linux自带的容器(Linux Containers,LXC)技术。
- Docker给DevOps带来的好处
- 更快速的交付和部署:开发人员可以使用镜像快速的构建标准开发环境;开发完成后,测试和运维人员可以使用开发人员提供的docker镜像快速部署应用,可以避免开发和测试运维人员之间的环境差异导致的部署问题。
- 更高校的资源利用:Docker容器的运行不需要额外的虚拟化管理程序支持,它是内核级的虚拟化,在占用更少资源的情况实现更高的性能。
- 更方便的迁移和扩展:Docker容器几乎可以在任意的平台上运行,包括物理机、虚拟机、公有云、私有云、服务器等。这种兼容使得用户可以在不同的平台之间很方便的完成应用迁移。
- 更简单的更新管理:使用Dockerfile,只需要小小的配置修改,就可以替代以往大量的更新工作,并且所有修改都以增量方式进行分发和更新。
- 虚拟化与Docker
- 虚拟化的核心是对资源进行抽象,目标往往是为了在同一个机器上运行多个系统或应用,从而提高系统资源的利用率。虚拟化分为很多类型,比如常见的硬件辅助虚拟化(VMware workstation、 KVM等)。Docker所代表的容器虚拟化技术属于操作系统级虚拟化:内核通过创建多个虚拟的操作系统实例(内核和库)来隔离不同的进程。
- 传统虚拟化和容器技术结构比较:传统虚拟化技术是在硬件层面实现虚拟化,增加了系统调用链路的环节,有性能损耗;容器虚拟化技术以共享Kernel的方式实现,几乎没有性能损耗。
- Docker怎么实现的?
- Docker是Client/Server的架构,Docker客户端与Docker daemon进行交互,daemon负责构建、运行和发布Docker容器。客户端可以和服务端运行在同一个系统中,也可以连接远程的daemon。Docker的客户端的daemon通过RESTful API进行socket通信。
![](https://i-blog.csdnimg.cn/blog_migrate/d2f100e37a22d0f12f57175a4c281f35.png)
如上图,Docker守护进程(daemon)在主机上运行,用户不能直接和守护进程打交道,但是可以通过Docker客户端与其进行交互;Client是Docker的初始用户界面,它接收用户的命令并反馈,并且与Docker的守护进行交互。
- Docker基于Linux容器技术(LXC),Namespace,Cgroup,UnionFS(联合文件系统)等技术实现:
- namespace(命名空间):命名空间是 Linux 内核一个强大的特性。每个容器都有自己单独的命名空间,运行在其中的应用都像是在独立的操作系统中运行一样。命名空间保证了容器之间彼此互不影响。docker实际上一个进程容器,它通过namespace实现了进程和进程所使用的资源的隔离。使不同的进程之间彼此不可见。
Docker用到的一些命名空间有:
pid命名空间:用于隔离进程,容器都有自己独立的进程表和1号进程;
net命名空间:用于管理网络,容器有自己独立的networkinfo;
ipc命名空间:用于访问IPC资源(IPC:InterProcess Communication);
mnt命名空间:用于管理挂载点,每个容器都有自己唯一的目录挂载;
uts命名空间:用于隔离内核和版本标识(UTS:UnixTimeProcess System),每个容器都有独立的hostname和domain。 - cgroup(控制组):是 Linux 内核的一个特性,主要用来对共享资源进行隔离、限制、审计等。只有能控制分配到容器的资源,才能避免当多个容器同时运行时的对系统资源的竞争。控制组技术最早是由 Google 的程序员 2006 年起提出,Linux 内核自 2.6.24 开始支持。控制组可以提供对容器的内存、CPU、磁盘 IO 等资源的限制和审计管理。
- UnionFS(联合文件系统):Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对 文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。Union 文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。另外,不同 Docker 容器就可以共享一些基础的文件系统层,同时再加上自己独有的改动层,大大提高了存储的效率。Docker 中使用的 AUFS(AnotherUnionFS)就是一种 Union FS。 AUFS 支持为每一个成员目录(类似 Git 的分支)设定只读(readonly)、读写(readwrite)和写出(whiteout-able)权限, 同时 AUFS 里有一个类似分层的概念, 对只读权限的分支可以逻辑上进行增量地修改(不影响只读部分的)。Docker 目前支持的 Union 文件系统种类包括 AUFS, btrfs, vfs 和 DeviceMapper。
二、为什么使用
-
Docker 容器的启动可以在秒级实现,这相比传统的虚拟机方式要快得多。
-
Docker 对系统资源的利用率很高,一台主机上可以同时运行数千个 Docker 容器,容器除了运行其中应用外,基本不消耗额外的系统资源,使得应用的性能很高,同时系统的开销尽量小。
-
传统虚拟机方式运行 10 个不同的应用就要起 10 个虚拟机,而Docker 只需要启动 10 个隔离的应用即可。
-
与传统虚拟机相比
特性 | 容器 | 虚拟机 |
---|---|---|
启动 | 秒级 | 分钟级 |
硬盘使用 | 一般为MB | 一般为GB |
性能 | 接近原生 | 弱于 |
系统支持量 | 单机支持上千个容器 | 一般几十个 |
三、如何使用
- 镜像Image
- 引用其它任何基础镜像,再结合自身需求,对其二次加工成新的镜像
- 直接pull第三方或官方(类似npm,下载速度堪忧,可以配置阿里加速)的镜像,比如:nginx,MySQL,tomcat等等
- 公司内部私服(和nexus一样)
- 本地导入
- 国内第三方,如:阿里、网易…
- 启动容器Container
- 直接启动docker run
- 导入本地容器快照或者从某个URL导入
- docker-compose
四、进阶使用
-
默认docker启动会创建一个虚拟网桥叫docker0 (172.17.0.0网段),启动的容器都会动态从这个网段分配未使用的ip,容器可以与容器以及宿主机通信(未映射其它容器),默认docker会将用户的端口映射加入iptables(防火墙重启失效需重启docker)
-
如果不喜欢默认桥,我们也可以重新定义网桥或者基于默认桥修改
-
自定义网桥,由于默认的网桥有个缺点,就是每次容器启动顺序不一样分配的ip也不一样,自定义网桥的话,我们可以指定各容器ip,这样就不用每次更换ip了
五、通信机制
-
host模式,docker使用linux中的namespace隔离资源,一个docker容器会分配一个独立的network namespace。但是如果容器采用host时,那么这个容器会和宿主机公用一个network namespqce,容器将不会虚拟出自己的网卡,配置自己的ip,而是使用宿主机的ip和端口
-
contianer模式是指和已经存在的一个容器共享一个network namespaces,那两个容器除了网络方面,其它的资源还是隔离的,两个容器的进程可以通过lo网卡设备通信
-
none模式时docker拥有自己的network namespaces,但是docker进行任何网络配置,需要我们自己为docker容器添加网络、配置ip
-
bridge模式是docker默认的网络设置,此模式会为每个容器分配network namespace、设置ip等,并将一个主机的docker容器连接到一个虚拟网络上
六、资源分配
- 一般使用默认的配置,如果需要自定义资源分配,可以在启动容器时通过一些命令指定,如:-m:内存限制,–memory-swap等等,详细可以使用dcoker run –help查看
七、实战
- plantdata_console前台部署到生产环境中。
- 一台物理机(模拟测试机,部署docker)、一台虚拟机(模拟生产环境)
- 在测试机使用Dockerfile 构建生产的镜像
- 提交到私服或者本地导出
- 导入部署环境,私服docker pull 192.168.1.138:5000/nginx,本地docker load -i nginx.tar
- docker run --name plantdata_nginx -p 80:80 -d nginx
八、安装注意
-
从1.8.2开始,Docker requires a 64-bit installation regardless of your CentOS version. Also, your kernel must be 3.10 at minimum, which CentOS 7 runs.
-
Docker之前的版本是可以运行在较低内核版本之上的,比如1.7.1。但是docker引擎也会给出警告“level=warning msg="You are running linux kernel version 2.6.32-504.el6.x86_64, which might be unstable running docker. Please upgrade your kernel to 3.10.0.”
-
在1.12之前的版本有很多集成特性没有,比如docker swarm和network(引擎没这个,还怎么玩)以及其它之前需要第三方工具实现的,现在内部都直接集成,比之前要方便很多很多
-
docker-compose现在最新版是1.16.1,而每个版本都有最低docker 引擎的要求以及docker-compose.yml格式版本的要求(目前最新3.3,且之前的每个大版本直接完全不兼容),很早之前的根本无法用,具体请参考
-
特别说明:
- 以redhat(centos是redhat再编译产物)举例,下表是各发行版与对应的内核
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-H0YDG0Np-1684392814947)(null)] - 如果自行升级内核至3.10.0+,要么升级失败,要么在安装docker失败(因为依旧缺少许许多多模块)
- 强烈建议用原生发行版自带内核,一方面可以在用自带yum源安装,另一方用最新源安装也是非常方便