Docker 核心技术与实现原理
Docker
- Docker 核心技术与实现原理
- 一、为什么要学Docker?
- 二、Docker技术原理介绍
- 三、Docker 的基本概念
- 四、Docker 安装
一、为什么要学Docker?
首先我们要说一下云平台
云计算包括三个层次的服务:基础架构即服务IaaS
,平台即服务PaaS
和软件即服务SaaS
- IaaS
通过互联网提供数据中心、基础架构硬件和软件资源,还可以提供服务器、操作系统、磁盘存储、数据库和/或信息资源。
- Paas
提供了基础架构,软件开发者可以在这个基础架构之上建设新的应用,或者扩展已有的应用,同时却不必购买开发、质量控制或生产服务器。
- SaaS
最为成熟、最出名,也是得到最广泛应用的一种云计算。它是一种软件分布模式,在这种模式下,应用软件安装在厂商或者服务供应商那里,用户可以通过某个网络来使用这些软件,通常使用的网络是互联网。
- 总结:
IaaS、PaaS和SaaS之间的关系可从两个角度来看:从用户体验角度而言,它们之间的关系是独立的,因为它们面对不同类型的用户;而从技术角度而言,它们并不是简单的继承关系(SaaS基于PaaS,而PaaS基于IaaS),因为首先SaaS可以是基于PaaS或者直接部署于IaaS之上,其次PaaS可以构建于IaaS之上,也可以直接构建在物理资源之上。
IaaS、PaaS和SaaS这三种模式都采用了外包的方式,以减轻企业负担,降低管理、维护服务器硬件、网络硬件、基础架构软件和应用软件的人力成本。从更高的层次上看,它们都试图去解决同一个商业问题——用尽可能少甚至是为零的资本支出,获得功能、扩展能力、服务和商业价值。
老一代的PAAS平台的局限性和困境
- 主要提供应用的部署和托管
- 针对应用开发者
- 仅支持特定的laaS基础技术
- 支持单种开发语言和框架
- 支持特定的服务,比如自定义的数据存储APIs
- 没有很好的解决常用中间件的部署问题
- 难以解决应用和资源的隔离问题
二、Docker技术原理介绍
- Docker核心技术之cgroups
Linux中经常有个需求就是希望能限制某个或者某些进程的分配资源。于是就出现了cgroups的概念,cgroup就是controller[kənˈtrəʊlə(r)控制器] group,在这个group中,有分配好的特定比例的CPU时间,IO时间,可用内存大小等。cgroups是将任意进程进行分组化管理的Linux内核功能。最初由Google的工程师提出,后来被整合进Linux内核中。
cgroups中的重要概念是 "子系统",也就是资源控制器,每个子系统就是一个资源的分配器,比如cpu子系统是控制cpu时间分配的。首先挂载子系统,然后才有control group的。比如先挂载memory子系统,然后在memory子系统中创建一个cgroup节点,在这个节点中,将需要控制的进程id写入,并且将控制的属性写入,这就完成了内存的资源限制。
cgroups被Linux内核支持,有得天独厚的性能优势,发展势头迅猛。在很多领域可以取代虚拟化技术分割资源。cgroup默认有诸多资源组,可以限制几乎所有服务器上的资源:cpu mem iops,iobandwide,net,device acess等
- Docker核心技术之LXC
LXC是Linux containers的简称,是一种基于容器的操作系统层级的虚拟化技术。借助于namespace的隔离机制和cgroup限额功能,LXC提供了一套统一的API和工具来建立和管理container。LXC跟其他操作系统层次的虚拟化技术相比,最大的优势在于LXC被整合进内核,不用单独为内核打补丁
LXC提供一个kernel的OS级虚拟化方法,在执行时不用重复加载Kernel,且container的kernel与host共享,因此可以大大加快container的启动过程,并显著减少内存消耗,容器在提供隔离的同时,还通过共享这些资源节省开销,这意味着容器比真正的虚拟化的开销要小得多。在实际测试中,基于LXC的虚拟化方法的IO和CPU性能几乎接近baremetal的性能
虽然容器所使用的这种类型的隔离总的来说非常强大,然后是不是像运维在hypervisor上的虚拟机那么强壮仍具有争议性,如果内核停止,那么所有的容器就会停止运行。
性能方面:LXC > KVM > XEN
内存利用率:LXC > KVM > XEN
隔离程度:XEN > KVM > LXC
如果有应用需要对kernel操作,是无法单独修改和单独部署的,因为是使用的共享kernel,容器不支持修改。
- Docker核心技术之AUFS
什么是AUFS? AuFs是一个能透明覆盖一或多个现有文件系统的层状文件系统。支持将不同目录挂载到同一个虚拟文件系统下,可以把不同的目录联合在一起,组成一个单一的目录。这种是一种虚拟的文件系统,文件系统不用格式化,直接挂载即可。
Docker一直在用AuFS作为容器的文件系统。当一个进程需要修改一个文件时,AuFS创建该文件的一个副本。AuFS可以把多层合并文件系统的单层表示。这个过程称为写入复制(copy on write)
AuFS允许Docker把某种镜像作为容器的基础。例如,你可能有一个作为很多不同容器的Centos系统镜像。多亏AuFS,只要一个CentOS镜像的副本就够了,这样既节省了存储和内存,也保证更快速的容器部署。
使用AuFS的另一个好处是Docker的版本容器镜像能力,每个新版本都是一个与之前版本的简单差异改动,有效地保持镜像文件最小化。dan但,这也意味着你总是要有一个记录该容器从一个版本到另一个版本的改动的审计跟踪。
最早支持这项技术的是ubantu,后来RedHat看到这个技术比较好,跟docker配合把这项技术移植到RedHat上。AuFS相当于我们使用的ps,会在底层创建一个图像,每次修改只修改添加一个副本,并不影响底层。
LXC的基础上,Docker额外提供的Feature包括:标准统一的打包部署运行方案
为了最大化重要Image,加快运行速度,减少内存和磁盘footprint,Docker container运行时所构造的运行环境,实际上是具有依赖关系的多个Layer组成的。例如一个apache的运行环境可能是在基础的rootfs image的基础上,叠加了包含例如Emacs等各种工具的image,再叠加包含apache及其相关以来library的image,这些image由AUFS文件系统加载合并到统一路径中,以只读的方式存在,最后再叠加加载一层可写的空白的Layer用作记录对当前运行环境所做的修改。
有了层级化的Image做基础,理想中,不同的APP就可以既可能的共用底层文件系统,相关依赖工具等,同一个APP的不同实现也可以实现共用绝大多数数据,进而以copy on write的形式维护自己的那一份修改过的数据等。
- Docker全生命周期开发模式
Docker正在迅速改变云计算领域的运作规则,并彻底覆盖云技术的发展前景。从持续集成/持续交付到微服务、开源协作乃至DevOps已经给应用程序开发周期以及云工程技术实践带来了巨大变革。
Docker Hub相当于SVN服务器(用于存储打包好的image),如果我们启动一个image,本地没有会前往Docker Hub上拉取。
镜像变成全球性的,不需要我们自己安装MySQL,配置参数
当我们使用docker,docker Hub上镜像是全球性的,安装服务不需要我们手动编辑,配置参数等。有一个专门用于Docker的标准化的镜像
只要我们在Docker Hub上有镜像,我们可以在任意的Docker环境运行。 [笔记本、公有云、服务器、IBM、HP、亚马逊等]
三、Docker 的基本概念
1. Docker Image
Docker image 是一个极度精简版的Linux程序运行环境,比如vi这种基本的工具都没有,官网的JAVA镜像包括的东西更少,除非镜像叠加方式的,如Centos+JAVA7
Docker Image内不建议有运行期需要修改的配置文件
DockerFile用来创建一个自定义的Image,包含了用户指定的软件依赖等。当前木偶下包含Dockerfile,使用命令build来创建新的image
Docker image的最佳实践之一是尽量重用和使用网上公开的基础镜像
Docker image不建议存放配置文件,因为build一次需要十几分钟,建议配置文件通过参数传进去
Docker image 尽量不要打一个非标准的镜像
2. Docker Container
Docker Container是image的实例,共享内核
Docker Container里可以运行不同Os的Image,比如Ubuntu的或者Centos
Docker Container不建议内部开启一个SSHD服务,1.3版本后新增了docker exec命令进入容器排查
Docker Container没有IP地址,通常不会有服务端口暴露
Container 是共享内核,里面可以运行多个image[Centos,RedHat等]
不建议使用SSH服务登陆到Container [1]
3.Docker Container生命周期
Container不仅仅是后台程序,也可以是临时程序。比如我们就做个计算,计算完输出结束
4.Docker Daemin
Docker Daemon是创建和运行Container的Linux守护进程,也是Docker最主要的核心组件
Docker Daemon可以理解为Docker Container的Container
Docker Daemon可以绑定本地端口并提供Rest API服务,用来远程访问和控制
我们可以将Docker Daemon理解为tomcat 将Container理解为web[2]
5.Docker Registry/Hub
Docker之所以这么吸引人,除了它的新颖的技术外,围绕官网的Registry(Docker Hub)的生态圈也相当吸引人眼球的地方。在Docker Hub上你可以轻松下载到大量已经容器化好的应用镜像,即拉即用。这些镜像中,有些是Docker官网维护的,更多的是众多开发者自发上传分享的。而且你可以在Docker Hub中绑定你的代码托管系统(目前支持Github和Bitbucker)配置自动生成镜像功能,这样Docker Hub会在你代码更新时自动生成对应的Docker镜像[3]
在企业环境中,我们需要搭建一个私有的Registry(相当于私有的yum源)来方便我们下载部署,公有的会因为网络访问不到
Docker Client通过Docker api来和Docker Daemon沟通,来创建Container(创建/停止) 默认下载镜像是Docker Hub,需要我们手动指定。我们需要在image里面指定Docker Registry
四、Docker 安装
Docker官网:www.docker.com
注:
Docker 需要在内核3.8版以上,所以我们需要在Centos7上进行操作
Dcoker Engine改为Docker CE(社区版)
Docker Data Center改为Docker EE(企业版)
##### Docker 环境准备 #####
Docker官网yum源:http://yum.dockerproject.org/repo/main/
支持不同版本
1.关闭防火墙
$ systemctl stop firewalld
$ systemctl disable firewalld
2.修改主机名
$ hostnamectl set-hostname abc
$ vim /etc/hostname
abc
$ bash #默认重启生效,我们可以使用bash刷新
3.关闭SElinux
$ sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
4.设置Yum源
$ curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
$ wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
$ yum clean all && yum makecache
1.安装docker
####下载yum源及依赖包
$ yum install -y yum-utils \
device-mapper-persistent-data \
lvm2
$ yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
$ yum install docker-ce ##yum安装docker
2.启动Docker并设置开机启动
[root@docker ~]# systemctl start docker ##启动docker
[root@docker ~]# systemctl enable docker
我们可以检查进程是否正常
[root@abc ~]# ps -ef|grep docker
root 23450 1 2 05:29 ? 00:00:00 /usr/bin/dockerd
root 23454 23450 0 05:29 ? 00:00:00 docker-containerd --config /var/run/docker/containerd/containerd.toml
root 23609 23416 0 05:29 pts/1 00:00:00 grep --color=auto docker
########################
关闭开机启动
[root@abc ~]# systemctl disable docker
3.安装Iptables
首先Centos7将direwalld代替了iptables,但是docker里面有端口映射的地方需要使用iptables,所以我们需要关闭direwalld
,安装iptables
[root@abc ~]# systemctl disable firewalld #关闭开机启动
[root@abc ~]# yum install iptables-services -y #yum安装iptables
[root@abc ~]# systemctl start iptables #启动iptables
[root@abc ~]# systemctl enable iptables #设置开机启动
Created symlink from /etc/systemd/system/basic.target.wants/iptables.service to /usr/lib/systemd/system/iptables.service.
[root@abc ~]# iptables -L -n #查看Iptbles规则
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22
REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
Chain FORWARD (policy ACCEPT)
target prot opt source destination
REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
4.查看docker版本
我们可以使用docker info 命令查看docker的信息
[root@abc ~]# docker info
Containers: 1
Running: 0
Paused: 0
Stopped: 1
Images: 1
Server Version: 18.03.1-ce
Storage Driver: devicemapper
Pool Name: docker-253:0-374488-pool
Pool Blocksize: 65.54kB
Base Device Size: 10.74GB
Backing Filesystem: xfs
Udev Sync Supported: true
Data file: /dev/loop0
Metadata file: /dev/loop1
Data loop file: /var/lib/docker/devicemapper/devicemapper/data
Metadata loop file: /var/lib/docker/devicemapper/devicemapper/metadata
Data Space Used: 244.5MB
Data Space Total: 107.4GB
Data Space Available: 38.78GB
Metadata Space Used: 745.5kB
Metadata Space Total: 2.147GB
Metadata Space Available: 2.147GB
Thin Pool Minimum Free Space: 10.74GB
Deferred Removal Enabled: true
Deferred Deletion Enabled: true
Deferred Deleted Device Count: 0
Library Version: 1.02.146-RHEL7 (2018-01-22)
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
Volume: local
Network: bridge host macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file logentries splunk syslog
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 773c489c9c1b21a6d78b5c538cd395416ec50f88
runc version: 4fc53a81fb7c994640722ac585fa9ca548971871
init version: 949e6fa
Security Options:
seccomp
Profile: default
Kernel Version: 3.10.0-327.el7.x86_64
Operating System: CentOS Linux 7 (Core)
OSType: linux
Architecture: x86_64
CPUs: 1
Total Memory: 1.782GiB
Name: abc
ID: 4H7V:3PAO:3VWL:IBOV:IWIR:DJ4G:LXND:AFQV:6F3A:B5T5:LDEQ:5JXW
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
Labels:
Experimental: false
Insecure Registries:
127.0.0.0/8
Live Restore Enabled: false
WARNING: devicemapper: usage of loopback devices is strongly discouraged for production use.
Use `--storage-opt dm.thinpooldev` to specify a custom block storage device.
WARNING: bridge-nf-call-iptables is disabled
WARNING: bridge-nf-call-ip6tables is disabled
#注Docker 1.8对centos6是彻底不支持的
查看Docker版本号
[root@abc ~]# docker version
Client: #Docker 客户端版本
Version: 18.03.1-ce
API version: 1.37
Go version: go1.9.5
Git commit: 9ee9f40
Built: Thu Apr 26 07:20:16 2018
OS/Arch: linux/amd64
Experimental: false
Orchestrator: swarm
Server: #Docker 服务端版本
Engine:
Version: 18.03.1-ce
API version: 1.37 (minimum version 1.12)
Go version: go1.9.5
Git commit: 9ee9f40
Built: Thu Apr 26 07:23:58 2018
OS/Arch: linux/amd64
Experimental: false
Docker客户端和服务端通过API(发送app请求)来进行交互
5. Docker 配置文件与日志
Centos配置文件路径/usr/lib/systemd/system/docker.service
默认配置文件如下:
重要参数介绍
-H 表示Docker Daemon绑定的地址, -H=unix:///var/run/docker.sock -H=tcp://0.0.0.0:2222
--registry-mirror 表示Docker Registry的镜像地址 --registry-mirror=http://镜像地址
--insecure-registry 表示本地私有Docker Registry的地址, --insecure-registry $(pivateRegistryHost):5000
--selinux-enabled是否开启SElinux,默认开启 --selinux-enabled=true
--bip表示网桥docker0使用指定CIDR网络地址, --bip=10.0.0.1
-b 表示采用已经创建好的网桥, -b=xxx
OPTIONS:
OPTIONS=-H=unix:///var/run/docker.sock -H=tcp://0.0.0.0:222 --registry-mirror=http://4bc5abed.m.daocloud.io --selinux-enabled=true
下面是代理的配置
http_proxy=XXXXX:8080
https_proxy=XXXXX:8080
代理需要配置在Server标签上,填写完成之后需要重启服务
6.拉取镜像启动
[root@docker ~]# docker pull centos ##拉取centos镜像
Using default tag: latest
latest: Pulling from library/centos
85432449fd0f: Pull complete
Digest: sha256:3b1a65e9a05f0a77b5e8a698d3359459904c2a354dc3b25ae2e2f5c95f0b3667
Status: Downloaded newer image for centos:latest
[root@docker ~]# docker images ##插件镜像
REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest 3fa822599e10 5 weeks ago 204MB
[root@docker ~]# docker run -i -t centos /bin/bash ##进入容器
[root@f3894984f6c6 /]#
[root@f3894984f6c6 /]# cat /etc/redhat-release ##查看容器系统版本
CentOS Linux release 7.4.1708 (Core