docker介绍与体系结构
docker是什么
docker是一个开源的应用容器引擎,使用go语言开发,基于Linux内核的cgroup、namespace、Union FS等技术,对应用进程进行封装隔离,并且独立与宿主机与其他进程,这种运行时封装的状态称为容器。
docker早期版本实现是基于LXC,并进一步对其封装,包括文件系统、网络互连、镜像管理等方面,极大简化了容器管理。从0.7版本以后开始去除LXC,转为自行研发的libcontainer,从1.11版本开始,进一步演进为使用runC和containerd。
docker理念是将应用及依赖包打包到一个可移植的容器中,可发布到任意linux发行版docker引擎上。使用沙箱机制运行程序,程序之间互相隔离。
docker体系结构
containerd:一个简单的守护进程,使用runC管理容器,向docker engine提供接口。
shim:只负责管理一个容器。
runC:一个轻量级的工具,只用来运行容器。
查看进程树:pstree -p或ps axjf
[root@docker ~]# ps axjf
985 1182 1182 1182 ? -1 Ss 0 0:01 _ sshd: root@pts/0
1182 1366 1366 1366 pts/0 2029 Ss 0 0:00 _ -bash
1366 1830 1830 1366 pts/0 2029 T 0 0:00 _ ping www.baidu.com
1366 2029 2029 1366 pts/0 2029 R+ 0 0:00 _ ps axjf
内部组件
namespace
命名空间,linux内核提供的一种对进程资源隔离的机制,例如进程、网络、挂载点等资源。
cgroup
控制组,linux内核提供的一种限制进程资源的机制,例如cpu、内存等资源。
[root@docker ~]# ll /sys/fs/cgroup/
total 0
drwxr-xr-x. 2 root root 0 Jun 7 01:04 blkio
lrwxrwxrwx. 1 root root 11 Jun 7 01:04 cpu -> cpu,cpuacct
lrwxrwxrwx. 1 root root 11 Jun 7 01:04 cpuacct -> cpu,cpuacct
drwxr-xr-x. 2 root root 0 Jun 7 01:04 cpu,cpuacct
drwxr-xr-x. 2 root root 0 Jun 7 01:04 cpuset
drwxr-xr-x. 4 root root 0 Jun 7 01:04 devices
drwxr-xr-x. 2 root root 0 Jun 7 01:04 freezer
drwxr-xr-x. 2 root root 0 Jun 7 01:04 hugetlb
drwxr-xr-x. 2 root root 0 Jun 7 01:04 memory
lrwxrwxrwx. 1 root root 16 Jun 7 01:04 net_cls -> net_cls,net_prio
drwxr-xr-x. 2 root root 0 Jun 7 01:04 net_cls,net_prio
lrwxrwxrwx. 1 root root 16 Jun 7 01:04 net_prio -> net_cls,net_prio
drwxr-xr-x. 2 root root 0 Jun 7 01:04 perf_event
drwxr-xr-x. 2 root root 0 Jun 7 01:04 pids
drwxr-xr-x. 4 root root 0 Jun 7 01:04 systemd
unionFS
联合文件系统,支持将不同位置的目录挂载到同一虚拟文件系统,形成一种分层的模型。
虚拟机与容器区别
以KVM与docker对比为例:
启动时间
docker秒级启动,kvm分钟级启动。
轻量级
容器镜像大小通常以M为单位,虚拟机以G为单位。
容器资源占用小,比虚拟机 部署更快速。
性能
容器共享宿主机内核,系统级虚拟化,占用资源少,没有Hypervisor层开销,容器性能基本接近物理机。
虚拟机需要Hypervisor层支持,虚拟化一些设备,具有完整的GuestOS,虚拟化开销大,因而降低性能,没有容器性能好。
安全性
由于共享宿主机内核,只是进程级隔离,因此隔离性和稳定性不如虚拟机,容器具有一定权限访问宿主机内核,存在一定安全隐患。
使用要求
KVM基于硬件的完全虚拟化,需要硬件cpu虚拟化技术支持。
容器共享宿主机内核,可运行在主流的linux发行版,不用考虑cpu是否支持虚拟化技术。
docker应用场景
场景一:节省项目环境部署时间
1、单项目打包
每次部署项目到测试、生产等环境,都要部署一大堆依赖的软件、工具,而且部署期间出现问题几率很大,不经意间就花费很长时间。
docker主要理念就是环境打包部署,可在任意docker engine运行。期间我们只需要将每个项目环境打包到镜像,push到镜像仓库,当需要部署这个项目时,直接pull镜像启动容器,这个项目就可以访问了。一次构建多次部署,一劳永逸。
2、整套项目打包
公司有一个产品可以整套部署到客户环境,以往都是派一名实施工程师到客户现场部署。如果使用docker我们可以前期整套项目封装打包,实现一键部署,分分钟完成,就不需要再到客户现场。例如官方的docker compose编排工具。
3、新开源技术试用
当我们想调研一些开源项目,我们可以直接从公共镜像仓库pull项目官方做好的镜像,启动容器即可。
场景二:环境一致性
开发工程师在windows系统开发项目,测试、生产环境操作系统都是linux系统,这就产生了环境不一致的情况,项目在开发本地运行没有问题,到了测试或生产环境无法运行,解决这个问题最好方式就是三处环境保持一致。软件版本、操作系统、物理机、云主机等不可能完全保持一致。
docker将项目环境打包成镜像,可以在任何docker engine上运行,此时docker就是我们项目的基石。
docker可移植性,保持运行状态一致性。
场景三:持续集成
一个项目版本快速迭代的测试场景,需要一个合理的CI(持续集成)/CD(持续部署)环境支撑。CI/CD是一个周期性自动化项目测试环境,包括构建、部署、测试、发布等工作,很少需要人工干预。项目测试流程如下:
docker结合Jenkins构建持续集成环境如下:
docker在上面这个图中的作用是促使项目镜像构建和快速部署,打通测试环境与生产环境,高度保持多个环境之间一致性。
场景四:微服务
微服务是近几年比较火的架构,简单的来说就是尽可能细粒度拆分业务程序架构,由多个独立服务组成业务系统。
docker的容器设计原则,一个容器一个服务,容器之间互相隔离,一个服务独立部署在一个容器中,恰到好处的实现了微服务。
场景五:弹性伸缩
弹性伸缩通常是集群模式下存在。例如AWS AutoScaling,可以自定义资源阈值,SLB自动添加EC2云主机,应对业务访问量突发情况。
当采用docker技术以后,这种弹性伸缩的单元就是云主机之上的容器。
容器集群化管理已经有成熟的解决方案,例如官方的swarm,google的kubernetes(k8s)。
由于docker容器快速启动特性,可以快速的启动几十个,甚至上百个容器来提供更多并发和资源利用(如果宿主机资源不够,还需要加主机到集群中)。
Linux安装docker
docker官方文档:https://docs.docker.com/
docker-ce centos版:https://docs.docker.com/install/linux/docker-ce/centos/
安装依赖包
[root@docker ~]# yum install -y yum-utils device-mapper-persistent-data lvm2
添加docker软件包源
[root@docker ~]# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
更新yum包索引
[root@docker ~]# yum makecache fast
安装docker ce
[root@docker ~]# yum install -y docker-ce
启动
[root@docker ~]# systemctl start docker
查看docker信息
[root@docker ~]# docker info
Containers: 0
Running: 0
Paused: 0
Stopped: 0
Images: 0
Server Version: 18.09.6
Storage Driver: overlay2
Backing Filesystem: xfs
Supports d_type: true
Native Overlay Diff: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
Volume: local
Network: bridge host macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: bb71b10fd8f58240ca47fbb579b9d1028eea7c84
runc version: 2b18fe1d885ee5083ef9f0838fee39b62d653e30
init version: fec3683
Security Options:
seccomp
Profile: default
Kernel Version: 3.10.0-862.el7.x86_64
Operating System: CentOS Linux 7 (Core)
OSType: linux
Architecture: x86_64
CPUs: 2
Total Memory: 3.697GiB
Name: docker
ID: 3EAH:DXYW:7DXA:76IW:AKHC:TKG5:FC5N:QPRB:SFAY:T6HB:LSCS:CUPK
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
Product License: Community Engine
下载nginx image
[root@docker ~]# docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
743f2d6c1f65: Pulling fs layer
d6c2f01b1dae: Pulling fs layer
d4da6ff1b555: Pulling fs layer
error pulling image configuration: Get https://production.cloudflare.docker.com/registry-v2/docker/registry/v2/blobs/sha256/62/62c261073ecffe22a28f2ba67760a9320bc4bfe8136a83ba9b579983346564be/data?verify=1559898802-6kJ3EPQFnUNrY1vlJ7ApCoUBZ%2Bg%3D: EOF
以上下载错误原因是时区设置错误导致。
[root@docker ~]# date
Fri Jun 7 04:24:41 EDT 2019
修改linux时区
[root@docker ~]# cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
[root@docker ~]# date
Fri Jun 7 16:27:52 CST 2019
再次下载成功
[root@docker ~]# docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
743f2d6c1f65: Pull complete
d6c2f01b1dae: Pull complete
d4da6ff1b555: Pull complete
Digest: sha256:12db363acf5b2d2f9f5fed240e228a04692bdac68402430fbd2f720c3a967d01
Status: Downloaded newer image for nginx:latest
卸载
[root@docker ~]# yum remove docker-ce
[root@docker ~]# rm -fr /var/lib/docker