Doker 的简介

Doker 的简介
1. docker 是什么

​ 首先 Docker 是一个在 2013 年开源的应用程序并且是一个基于 go 语言编写是一个开源的 PAAS 服务(Platform as a Service,平台即服务的缩写),go 语言是由 google 开发,docker 公司最早叫 dotCloud 后由于 Docker 开源后大受欢迎就将公司改名为 Docker Inc,总部位于美国加州的旧金山,Docker 是基于 linux 内核实现,Docker 最早采用 LXC 技术(LinuX Container 的简写,LXC 是 Linux 原生支持的容器技术,可以提供轻量级的虚拟化,可以说 docker 就是基于 LXC 发展起来的,提供 LXC 的高级封装,发展标准的配置方法),而虚拟化技术 KVM(Kernelbased Virtual Machine) 基于模块实现,Docker 后改为自己研发并开源的 runc 技术运行容器。

​ Docker 相比虚拟机的交付速度更快,资源消耗更低,Docker 采用客户端/服务端架构,使用远程 API 来管理和创建 Docker 容器,其可以轻松的创建一个轻量级的、可移植的、自给自足的容器,docker 的三大理念是 build(构建)、ship(运输)、 run(运行),Docker 遵从 apache 2.0 协议,并通过(namespace 及 cgroup 等)来提供容器的资源隔离与安全保障等,所以 Docke 容器在运行时不需要类似虚拟机(空运行的虚拟机占用物理机 6-8%性能)的额外资源开销,因此可以大幅提高资源利用率,总而言之 Docker 是一种用了新颖方式实现的轻量级虚拟机.类似于 VM 但是在原理和应用上和 VM 的差别还是很大的,并且 docker的专业叫法是应用容器(Application Container)。

2. Docker 的组成

参考文档

Docker 主机(Host):一个物理机或虚拟机,用于运行 Docker 服务进程和容器。

Docker 服务端(Server):Docker 守护进程,运行 docker 容器。

Docker 客户端(Client):客户端使用 docker 命令或其他工具调用 docker API。

Docker 仓库(Registry): 保存镜像的仓库,类似于 git 或 svn 这样的版本控制系 Docker 镜像(Images):镜像可以理解为创建实例使用的模板。

Docker 容器(Container): 容器是从镜像生成对外提供服务的一个或一组服务。

统,官方仓库

mark

mark

3. Docker 对比虚拟机:
  • 资源利用率更高:一台物理机可以运行数百个容器,但是一般只能运行数十个虚拟机。
  • 开销更小:不需要启动单独的虚拟机占用硬件资源。
  • 启动速度更快:可以在数秒内完成启动。

mark

mark

​ 使用虚拟机是为了更好的实现服务运行环境隔离,每个虚拟机都有独立的内核,虚拟化可以实现不同操作系统的虚拟机,但是通常一个虚拟机只运行一个服务,很明显资源利用率比较低且造成不必要的性能损耗,我们创建虚拟机的目的是为了运行应用程序,比如 Nginx、PHP、Tomcat 等 web 程序,使用虚拟机无疑带来了一些不必要的资源开销,但是容器技术则基于减少中间运行环节带来较大的性能提升。

mark

但是,如上图一个宿主机运行了 N 个容器,多个容器带来的以下问题怎么解决:

  1. 怎么样保证每个容器都有不同的文件系统并且能互不影响?
  2. 一个 docker 主进程内的各个容器都是其子进程,那么实现同一个主进程下不同类型的子进程?各个进程间通信能相互访问(内存数据)吗?
  3. 每个容器怎么解决 IP 及端口分配的问题?
  4. 多个容器的主机名能一样吗?
  5. 每个容器都要不要有 root 用户?怎么解决账户重名问题?以上问题怎么解决?

实际上 docker 上采用namespace 技术进行隔离,依赖内核的cgroup 的技术对容器进行资源限制

容器通过docker-proxy 生成的 iptables 内的 规则,与外界通信

mark

4、docker 逻辑网络图

mark

验证:

在没有创建容器之前,宿主机只有一个docker0桥接设备

创建启动3个容器 ,会发现在宿主机上生成了3个虚拟网卡vethxxx

 docker  run  -d --name nginx_1  -p 80:80   nginx
 docker  run  -d --name nginx_2  -p 81:80   nginx
 docker  run  -d --name nginx_3  -p 82:80   nginx
 apt install bridge-utilsshell

并且容器会把自己的IP地址和自己的容器ID解析在一起

root@2648a1353cf3:/# cat /etc/hosts
127.0.0.1	localhost
::1	localhost ip6-localhost ip6-loopback
fe00::0	ip6-localnet
ff00::0	ip6-mcastprefix
ff02::1	ip6-allnodes
ff02::2	ip6-allrouters
172.17.0.3	2648a1353cf3
5. docker 进程间的关系

和docker 相关的主要进程为containerd 和 dockerd.

contained 和容器的运行管理有关

dockerd 和容器的网络访问有关

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6866cVxt-1590163567871)(A:%5Cimage_typoral_used%5Cimage-20200511104011292.png)]

如上图所示:

其中

​ 1、 2944 是 容器nginx 的工作进程

root@z1:~# ps -ef |grep nginx
root       2906   2877  0 09:45 ?        00:00:00 nginx: master process nginx -g daemon off;
systemd+   2944   2906  0 09:45 ?        00:00:00 nginx: worker process
root       3004   2980  0 09:45 ?        00:00:00 nginx: master process nginx -g daemon off;
systemd+   3048   3004  0 09:45 ?        00:00:00 nginx: worker process
root       3130   3102  0 09:46 ?        00:00:00 nginx: master process nginx -g daemon off;
systemd+   3170   3130  0 09:46 ?        00:00:00 nginx: worker process
root       3217   1889  0 10:32 pts/1    00:00:00 grep --color=auto nginx

​ 2、 2906是容器nginx的 的 master 进程

而在容器内就是 PID 为1 的守护进程

top - 01:44:37 up 51 min,  0 users,  load average: 0.01, 0.01, 0.00
Tasks:   4 total,   1 running,   3 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :   3921.7 total,   2931.4 free,    289.3 used,    701.0 buff/cache
MiB Swap:      0.0 total,      0.0 free,      0.0 used.   3393.3 avail Mem 

   PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND                                                              
     1 root      20   0   10632   5160   4452 S   0.0   0.1   0:00.33 nginx                                                                
     6 nginx     20   0   11120   2544   1416 S   0.0   0.1   0:00.00 nginx                                                                
     7 root      20   0    3868   3288   2812 S   0.0   0.1   0:00.28 bash                                                                 
   408 root      20   0    7964   3104   2684 R   0.0   0.1   0:00.69 top  

3、2877 containerd-shim 是真正运行容器的的进程 ,真正运行容器的载体,其父进程为 containerd。

root@z1:~# ps -ef |grep   2877
root       2877    716  0 09:45 ?        00:00:00 containerd-shim -namespace moby -workdir /var/lib/containerd/io.containerd.runtime.v1.linux/moby/35f2ded3d611903ad7405e908671a1a8fd786994d7a0e3bc7784415b75f5229a -address /run/containerd/containerd.sock -containerd-binary /usr/bin/containerd -runtime-root /var/run/docker/runtime-runc
root       2906   2877  0 09:45 ?        00:00:00 nginx: master process nginx -g daemon off;
root       3231   1889  0 10:35 pts/1    00:00:00 grep --color=auto 2877
root@z1:~# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
db520da956d2        nginx               "nginx -g 'daemon of…"   About an hour ago   Up About an hour    0.0.0.0:82->80/tcp   nginx_3
e7091f4d98f1        nginx               "nginx -g 'daemon of…"   About an hour ago   Up About an hour    0.0.0.0:81->80/tcp   nginx_2
35f2ded3d611        nginx               "nginx -g 'daemon of…"   About an hour ago   Up About an hour    0.0.0.0:80->80/tcp   nginx_1

由 容器ID 35f2ded3d611 因此可以看见2877 为 刚才创建的 name 为 nginx_1 的容器进程ID,containerd-shim主要是来负责容器的运行,并且用来向docker-containerd来汇报容器的状态,从而容器的状态数据不用存放在内存中,而每个容器都会使用一个docker-containerd-shim的进程来进行管理。

4、 716 contianerd: 被 dockerd 进程调用以实现与 runc 交互。

用于 管理所有容器的父进程

6. 容器管理工具

目前主要是使用 docker,早期有使用 lxc。

6.1:lxc:

LXC:LXC 为 Linux Container 的简写。可以提供轻量级的虚拟化,以便隔离进程

和资源,官方网站:https://linuxcontainers.org/ Ubuntu 。 现在已经用的比较少了

6.2:docker:

​ Docker 启动一个容器也需要一个外部模板但是较多镜像,docke 的镜像可以保存在一个公共的地方共享使用,只要把镜像下载下来就可以使用,最主要的是可以在镜像基础之上做自定义配置并且可以再把其提交为一个镜像,一个镜像可以被启动为多个容器。

​ Docker 的镜像是分层的,镜像底层为库文件且只读层即不能写入也不能删除数据,从镜像加载启动为一个容器后会生成一个可写层,其写入的数据会复制到容器目录,但是容器内的数据在删除容器后也会被随之删除。

7.容器的创建与管理过程

通信流程:

  1. dockerd 通过 grpc 和 containerd 模块通信,dockerd 由 libcontainerd 负责和 containerd 进行交换,dockerd 和 containerd 通信 socket 文件:/run/containerd/containerd.sock。

  2. containerd 在 dockerd 启动时被启动,然后 containerd 启动 grpc 请求监听,containerd 处理 grpc 请求,根据请求做相应动作。

  3. 若是 start 或是 exec 容器,containerd 拉起一个 container-shim , 并进行相应的操作。

  4. container-shim 别拉起后,start/exec/create 拉起 runC 进程,通过 exit、control 文件和 containerd 通信,通过父子进程关系和 SIGCHLD 监控容器中进程状态。

在整个容器生命周期中,containerd 通过 epoll 监控容器文件,监控容器事件。

mark

8. docker 优点
  • 快速部署:短时间内可以部署成百上千个应用,更快速交付到线上。

  • 高效虚拟化:不需要额外的 hypervisor 支持,直接基于 linux 实现应用虚拟化,相比虚拟机大幅提高性能和效率。

  • 节省开支:提高服务器利用率,降低 IT 支出。

  • 简化配置:将运行环境打包保存至容器,使用时直接启动即可。

快速迁移和扩展:可夸平台运行在物理机、虚拟机、公有云等环境,良好的兼容性可以方便将应用从 A 宿主机迁移到 B 宿主机,甚至是 A 平台迁移到 B

9. Docker 的缺点:

隔离性:各应用之间的隔离不如虚拟机彻底。

10.docker(容器)的核心技术
  • 容器规范:

    ​ 容器技术除了的 docker 之外,还有 coreOS 的 rkt,还有阿里的 Pouch,为了保证容器生态的标准性和健康可持续发展,包括 Linux 基金会、Docker、微软、红帽谷歌和、IBM、等公司在 2015 年 6 月共同成立了一个叫 open container(OCI)的组织,其目的就是制定开放的标准的容器规范,目前 OCI 一共发布了两个规范,分别是 runtime specimage format spec,有了这两个规范,不同的容器公司开发的容器只要兼容这两个规范,就可以保证容器的可移植性和相互可操作性。

  • 容器 runtime:

    ​ runtime 是真正运行容器的地方,因此为了运行不同的容器 runtime 需要和操作系统内核紧密合作相互在支持,以便为容器提供相应的运行环境。 目前主流的三种 runtime:

    Lxc:linux 上早期的 runtime,Docker 早期就是采用 lxc 作为 runtime。

    runc:目前 Docker 默认的 runtime,runc 遵守 OCI 规范,因此可以兼容 lxc。

    rkt:是 CoreOS 开发的容器 runtime,也符合 OCI 规范,所以使用 rktruntime 也可以运行 Docker 容器。

  • 容器管理工具:

    管理工具连接 runtime 与用户,对用户提供图形或命令方式操作,然后管理工具将用户操作传递给 runtime 执行。

    • lxc 是 lxd 的管理工具。

    • Runc 的管理工具是 docker engine,docker engine 包含后台 deamon 和 cli 两部分,大家经常提到的 Docker 就是指的 docker engine。

    • Rkt 的管理工具是 rkt cli。

  • 容器定义工具:容器定义工具允许用户定义容器的属性和内容,以方便容器能够被保存、共享和重建。

    • Docker image:是 docker 容器的模板,runtime 依据 docker image 创建容器。

    • Dockerfile:包含 N 个命令的文本文件,通过 dockerfile 创建出 docker image。 ACI(App container image):与 docker image 类似,是 CoreOS 开发的 rkt 容器的镜像格式。

  • Registry:

    ​ 统一保存镜像而且是多个不同镜像版本的地方,叫做镜像仓库。

    ​ Image registry:docker 官方提供的私有仓库部署工具。

    ​ Docker hub:docker 官方的公共仓库,已经保存了大量的常用镜像,可以方便大家直接使用。

    ​ Harbor:vmware 提供的自带 web 界面自带认证功能的镜像仓库,目前有很多公司使用。

  • 编排工具:

    ​ 当多个容器在多个主机运行的时候,单独管理容器是相当复杂而且很容易出错,而且也无法实现某一台主机宕机后容器自动迁移到其他主机从而实现高可用的目的,也无法实现动态伸缩的功能,因此需要有一种工具可以实现统一管理、动态伸缩、故障自愈、批量执行等功能,这就是容器编排引擎。容器编排通常包括容器管理、调度、集群定义和服务发现等功能。

    ​ Docker swarm:docker 开发的容器编排引擎。

    ​ Kubernetes:google 领导开发的容器编排引擎,内部项目为 Borg,且其同时支持docker 和 CoreOS。

    ​ Mesos+Marathon:通用的集群组员调度平台,mesos(资源分配)与 marathon(容器编排平台)一起提供容器编排引擎功能。

11. docker(容器)的依赖技术:
  • 容器网络:

    docker 自带的网络 docker network 仅支持管理单机上的容器网络,当多主机运行的时候需要使用第三方开源网络,例如 calico、flannel 等。

  • 服务发现:

    ​ 容器的动态扩容特性决定了容器 IP 也会随之变化,因此需要有一种机制开源自动识别并将用户请求动态转发到新创建的容器上,kubernetes 自带服务发现功能,需要结合 kube-dns 服务解析内部域名。

  • 容器监控:

​ 可以通过原生命令 docker ps/top/stats 查看容器运行状态,另外也可以使heapster/ Prometheus 等第三方监控工具监控容器的运行状态。

  • 数据管理:

    ​ 容器的动态迁移会导致其在不同的 Host 之间迁移,因此如何保证与容器相关的数据也能随之迁移或随时访问,可以使用逻辑卷/存储挂载等方式解决。

  • 日志收集:

    docker 原生的日志查看工具 docker logs,但是容器内部的日志需要通过 ELK 等专门的日志收集分析和展示工具进行处理。

es 自带服务发现功能,需要结合 kube-dns 服务解析内部域名。

  • 容器监控:

​ 可以通过原生命令 docker ps/top/stats 查看容器运行状态,另外也可以使heapster/ Prometheus 等第三方监控工具监控容器的运行状态。

  • 数据管理:

    ​ 容器的动态迁移会导致其在不同的 Host 之间迁移,因此如何保证与容器相关的数据也能随之迁移或随时访问,可以使用逻辑卷/存储挂载等方式解决。

  • 日志收集:

    docker 原生的日志查看工具 docker logs,但是容器内部的日志需要通过 ELK 等专门的日志收集分析和展示工具进行处理。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值