Docker的理论介绍

一、Docker简介

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

1、docker的组成

docker组成

Docker 主机(Host):一个物理机或虚拟机,用于运行 Docker 服务进程和容器。
Docker 服务端(Server): Docker 守护进程, 运行 docker 容器。
Docker 客户端(Client): 客户端使用 docker 命令或其他工具调用 docker API 。
Docker 仓库(Registry) :保存镜像的仓库,类似于 git 或 svn 这样的版本控制系统。
Docker 镜像(Images):镜像可以理解为创建实例 使用 的模板。
Docker 容器(Container):容器是从镜像生成对外提供服务的一个或一组服务 。

2、namespace

》1 MNT namespace

MNT namespace 技术可使每个docker容器都有独立的文件系统以及root用户目录,使用chroot技术将容器的root根目录指定到宿主机的指定目录。
例如:/var/lib/containerd/io.containerd.runtime.v1.linux/ 容器 ID

》2 IPC namespace

IPC namespace技术可使同一容器内,不同进程数据、内存相通,但不能跨容器。

》3 UTS namespace

UTS namespace技术可使容器有不同的主机名,相同的也可以,都使用宿主机的内核。

》4 PID namespace

PID namespace技术要求启动容器时要保证有一个服务一直运行,并作为容器的守护进程存在。容器内查看服务的进程pid为守护进程的pid。


PID namespace

》5 NET namespace

每个容器都有自己的网卡、端口、协议。Docker使用 network namespace 启动一个 vethX 接口,这样你的容器将拥有它自己的桥接 ip 地址,通常是 docker0 ,而 docker0 实质 就是 Linux 的虚拟网桥,网桥是在 OSI 七层模型的数据链路层的网络设备,通过 mac 地址对网络进行划分,并且在不同网络直接传递数据 。


宿主机的网卡信息

宿主机桥接设备

网络图

宿主机iptables地址转换规则

宿主机iptables转发规则

》6 USER namespace

User Namespace允许在各个宿主机的各个容器空间内创建相同的用户名以及相同的用户 UID 和 GID 只是会把用户的作用范围限制在每个容器内,即 A 容器和 B 容器可以有相同的用户名称和 ID 的账户,但是此 用户的有效范围仅是当前容器内不能访问另外一个容器内的文件系统,即相互隔离、互不影响、永不相见 。

3、Linux Control Groups

Linux Cgroups 的全称是 Linux Control Groups 它最主要的作用,就是限制一个进程组能够使用的资源上限,包括 CPU 、内存、磁盘、网络带宽等等。此外,还能够对进程进行优先级设置,以及将进程挂起和恢复等操作。
Cgroups 在内核层默认已经开启从 centos 和 ubuntu 对比结果来看显然内核较新的 ubuntu 支持的功能更多。


Centos7.6 cgroups

ubuntu cgroups

》1 cgroups的实现

blkio :块设备 IO 限制。
cpu :使用调度程序为 cgroup 任务提供 cpu 的访问。
cpuacct :产生 cgroup 任务的 cpu 资源报告。
cpuset :如果是多核心的 cpu ,这个子系统会为 cgroup 任务分配单独的 cpu 和内存。
devices :允许或拒绝 cgroup 任务对设备的访问。
freezer :暂停和恢复 cgroup 任务。
memory :设置每个 cgroup 的内存限制以及产生内存资源报告。
net_cls :标记每个网络包以供 cgroup 方便使用。
ns :命名空间子系统。
perf_event :增加了对每 group 的监测跟踪的能力,可以监测属于某个特定的 group 的所有线程以及运行在特定 CPU 上的线程。

4、容器的核心技术

》1 容器runtime

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


runtime

》2 容器管理工具

管理工具连接runtime与用户,对用户提供图形或命令方式操作,然后管理工具将用户操作传递给runtime执行 。Runc的管理工具是docker engine 。docker engine包含后台deamon和cli两部分 ,大家经常提到的Docker就是指的docker engine 。


容器引擎

》3 容器定义工具

容器定义工具允许用户定义容器的属性和内容,以方便容器能够被保存、共享和重建 。
Docker image:是 docker 容器的模板, runtime依据docker image创建 容器。
Docker file :包含 N个命令的文本文件,通过dockerfile创建出 docker image 。
ACI(App container image)与docker image 类似是CoreOS开发的rkt容器的镜像格式。

》4 Registry

统一保存镜像 而且是多个不同镜像版本的地方, 叫做镜像仓库 。
Image registry是docker官方提供的私有仓库部署工具。
Docker hub是docker官方的公共仓库已经保存了大量的常用镜像,可以方便大家直接使用。

5、docker的安装

docker的安装可参考阿里镜像网站
安装后配置镜像加速器,默认docker会从docker的官网去拉取镜像,国内访问会比较慢,连接容易超时,可以选择使用国内的镜像,我这边使用的是阿里云的镜像库

阿里云镜像仓库

》1 docker网卡

docker安装成功后,默认会生成一个名称为docker0的网卡并且默认IP地址为172.17 .0.1的网卡。

》2 docker存储引擎

目前docker的默认存储引擎为overlay2,需要磁盘分区支持 dtype文件分层功能 ,因此需要系统磁盘的额外支持。


如果docker数据目录是一块单独的磁盘分区而且是xfs格式的,那么需要在格式化的时候加上参数-n ftype=1 否则后期在启动容器的时候会报错不支持 dtype 。

报错界面:

:禁止在生产环境修改docker引擎,修改完存储引擎,重启docker后,保存的数据就会丢失。

》3 docker进程

查看docker进程,运行一个容器会比较直观,从镜像仓库拉取镜像,运行即可


拉取镜像
#拉取镜像
docker pull anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6
#生成容器
docker run --name some-nginx -d -p 8080:80 registry.openanolis.cn/openanolis/nginx:1.14.1-8.6
docker进程

有四个进程:
dockerd:被client直接访问,其父进程为宿主机的systemd守护进程 。
docker-proxy:实现容器通信,其父进程为dockerd。docker-proxy是帮忙生成网络的,创建iptables规则。
containerd:被dockerd进程调用以实现与runc交互 。
containerd-shim:真正运行容器的载体其父进程为containerd 。

3.1 容器的创建与管理过程

通信流程:

  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监控容器中进程状态。
  5. 在整个容器生命周期中,containerd通过epoll监控容器文件,监控容器事件。

》4 docker镜像管理

Docker镜像里面是一层层文件系统,叫做Union FS(联合文件系统),可以将几层目录挂载到一起,形成一个虚拟文件系统。虚拟文件系统的目录结构就像普通 linux 的目录结构一样, docker通过这些文件再加上宿主机的内核提供了一个linux的虚拟环境,每一层文件系统我们叫做一层layer,联合文件系统可以对每一层文件系统设置三种权限,只读(readonly)、读写(readwrite )和写出 (whiteout-able ),但是docker镜像中每一层文件系统都是只读的,构建镜像的时候,从一个最基本的操作系统开始,每个构建的操作都相当于做一层的修改,增加了一层文件系统,一层层往上叠加,上层的修改会覆盖底层该位置的可见性,这也很容易理解,就像上层把底层遮住了一样。当使用镜像的时候,我们只会看到一个完全的整体,不知道里面有几层也不需要知道里面有几层。

》5 docker常用命令

#搜索镜像
docker search centos:7.2.1511 #带指定版本号
docker search centos #不带版本号默认latest
#下载镜像
docker pull 仓库服务器:端口/项目名称/镜像名称:tag号
#镜像导出
docker save centos -o /opt/centos.tar.gz
docker save 镜像名 > /opt/centos.tar.gz 
#镜像导入
docker load < /opt/centos.tar.gz
#删除镜像
docker rmi centos
#登入容器
docker attach 容器id #不同的窗口都进入容器后,使用命令,别的窗口也会显示,退出后,容器也会退出
#启动容器
docker run centos /bin/echo 'hello wold' #启动的容器在执行完shell命令就退出了
docker run -it docker.io/centos bash #直接进入容器,并随机生成容器ID和名称,退出容器不注销。
#随机映射端口
docker run -P docker.io/nginx #前台启动并随机映射本地端口到容器的 80,随机端口映射,默认是从32768开始的。
#查看容器访问日志
docker logs -f nginx-test-port3
#查看容器已经映射的端口
docker port nginx-test-port5
#单次运行
docker run   -it --rm docker.io/ nginx  #容器退出后自动删除
#传递运行命令
docker run -d centos /usr/bin/tail -f '/etc/hosts' #容器需要有一个前台运行的进程才能保持容器的运行, 通过传递运行参数是一种方式,另外也可以在构建镜像的时候指定容器启动时运行的前台命令。
#批量操作容器
docker stop $(docker ps -a -q)  #正常关闭所有运行中的容器
docker rm -f `docker ps -aq -f status=exited`  #批量删除已退出的容器
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 虽然Kubernetes 在 v1.20 版本之后将不支持 Docker作为容器运行时Container Runt...
    向前进一点阅读 633评论 0 1
  • 本章内容 ◆ Docker简介◆ Docker 镜像与制作◆ Docker 数据管理◆ Docker 网络◆ Do...
    Liang_JC阅读 937评论 0 0
  • Docker 一、Namespace:名称空间,主要用于容器间的资源隔离,每个容器都运行在各自的不同的名称空间,各...
    花花遴20102967阅读 1,033评论 1 0
  • chroot chroot就是可以改变某进程的根目录,使这个程序不能访问目录之外的其他目录。Docker是利用Li...
    一生逍遥一生阅读 897评论 0 1
  • docker.io(官网) 轻量、高效的虚拟化 Docker 公司位于旧金山,原名dotCloud,底层利用了Li...
    以九为书阅读 435评论 0 1

友情链接更多精彩内容