https://www.jianshu.com/p/9737cbe33304

chroot

chroot就是可以改变某进程的根目录,使这个程序不能访问目录之外的其他目录。
Docker是利用Linux的Namespace、Cgroups和联合文件系统三大机制来保证实现的,它的原理是使用Namespace做主机名、网络、pid等资源的隔离,
使用Cgroups对进程或者进程组做资源的限制,联合文件系统用于镜像构建和容器运行环境。

Docker的命名空间

Docker主要用到一下五种命名空间:

  • pid namespace:用于隔离进程id。
  • net namespace:隔离网络接口。
  • mnt namespace:文件系统挂在点隔离。
  • ipc namespace:信号量,消息队列和共享内存的隔离。
  • ust namespace:主机名和域名的隔离。

Cgroups是一种unix内核功能,可以限制和隔离进程的资源使用情况。在容器的实现中,Cgroups通常用来限制容器的CPU和内存等资源的使用。

Docker有两个至关重要的组件:runC和containerd。

  • runC是Docker官方按照OCI容器运行时标准得到的一个实现。runC是一个用来运行容器的轻量级工具,是真正用来运行容器的。
  • containerd是从Docker中剥离出来的,containerd通过containerd-shim启动并管理runC,可以说containerd真正管理了容器的生命周期。

可以通过sudo ps aux|grep dockerd,查找到dockerd的pid,然后使用sudo pstree -l -a -A pid查看 docker组件之间的调用关系。

docker启动时,containerd就随之启动,dockerd与containerd一直存在。containerd会创建container-shim充当垫片进程,然后启动容器的真正进程。

镜像相关操作

镜像操作:

  • 拉取镜像,docker pull从本地拉取镜像获取从远程拉取镜像到本地;
  • 重命名镜像,docker tag重命名镜像
  • 查看镜像,docker images /docker image ls 查看现有镜像。
  • 删除镜像,docker rmi 镜像编号;
  • 构建镜像,docker build基于Dockerfile构建镜像,docker commit基于运行的容器提交为镜像。

Dockerfile操作

Dockerfile常用指令:

Dockerfile指令 指令介绍
FROM Dockerfile除了注释行,第一行必须是FROM,FROM后面跟镜像名称,作为基础镜像
RUN 跟具体命令,类似于Linux命令行的执行命令
ADD 拷贝本地文件或者远程文件到镜像内
COPY 拷贝本地文件到镜像内
USER 指定容器启动的用户
ENDPOINT 容器的启动命令
CMD CMD为ENDPOINT提供默认参数,也可以单独使用CMD指定容器启动参数
ENV 指定容器运行时的环境变量,格式为key=value
ARG 定义外部变量,构建镜像时可以使用build-arg=的格式传递参数用于构建
EXPOSE 指定容器监听的端口,格式为[port]/tcp或者[port]/udp
WORKDIR 为Dockerfile中跟在其后的所有RUN、CMD、ENDPOINT、COPY和ADD命令设置工作目录,只在当前有效

Docker清除数据的命令:

  • docker image prune -af 仅仅清除没有被容器使用的镜像文件
  • docker system prune -f 清除多余的数据,包括包含的容器、多余的镜像、未使用的volume等等。

Dockerfile书写原则:

  • 单一指责:一个Dockerfile只完成一个功能
  • 提供备注信息:提供注释信息
  • 保持容器最小化:只保留必要的内容
  • 合理选择基础镜像
  • 使用.dockerignore文件
  • 尽量使用构建缓存
  • 正确设置时区
    • Ubuntu和Debian系统: RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
      && RUN echo "Asia/Shanghai" >> /etc/timezone
    • Centos系统:RUN ln -sd /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
  • 使用国内软件源增加构建镜像构建速度
  • 最小化镜像层数。

Dockerfile书写建议:

  • Run指令在构建时会生成一个新的镜像层并且执行RUN指令后面的内容。

    • RUN指令后面跟内容复杂时,建议使用反斜杠结尾且换行;
    • RUN后面的内容尽量按照字母顺序排列,提高可读性。
  • CMD和ENDPOINT
    • CMD/ENDPOINT指令方式:CMD/ENDPOINT ["command","param"](exec模式,Docker 官方推荐的方式);
      CMD/ENDPOINT command param ,称为shell模式。
    • exec模式,容器的1号进程就是CMD/ENDPOINT指定的命令,shell模式启动的进程在容器中实际上并不是1号进程。
    • ENDPOINT可以和CMD指令结合使用,也可以单独使用,CMD只能单独使用。
    • Dockerfile中如果使用了ENDPOINT指令,启动Docker容器时需要使用--entrypoint参数才能覆盖Dockerfile中的ENDPOINT指令,
      使用CMD设置的命令,可以被docker run后面的参数直接覆盖。
  • ADD和COPY
    • COPY指令只支持基本的文件和文件拷贝功能,ADD则支持更多文件来源类型,比如自动提取tar包,并且可以支持源文件为URL格式。

基于内核的弱隔离系统如何保证安全

Docker与虚拟机的区别:

  • 虚拟机是通过管理系统(hypervisor)模拟出CPU、内存、网络等硬件,这样做的好处是虚拟机有自己的内核和操作系统,
    并且硬件是通过虚拟机管理系统模拟出来的,用户程序无法直接使用到主机的操作系统和硬件资源,虚拟机也对隔离性和安全性有着更好的保证。
  • Docker容器则是通过Linux内核的Namespace技术实现了文件系统、进程、设备以及网络的隔离,然后通过cgroups对CPU、内存等资源进行限制,
    最终实现容器之间互相不受影响,由于容器的隔离性仅仅依靠内核来提供,因此容器的隔离型也远弱于虚拟机。
Docker容器的安全问题 解决方法
Docker作为一款容器引擎,
本身也会存在一些安全漏洞
使用最新的版本,有相应的命名空间
镜像安全 私有镜像仓库自己进行扫描
Namespace隔离不够,然后部分关键
内容没有被安全隔离
宿主机内核应该尽量安装最新补丁;
使用capabilities划分权限;使用SELinux、
AppArmor、GRSecurity等安全组件加强安全;
每个容器都要限制资源使用
所有容器共享主机内核 使用安全容器来代替runC

cadvisor相关

cadvisor可以监控物理机和容器的状态;可以展示监控历史数据。
cadvisor的监控是基于cgroupsde。cgroups的工作目录是/sys/fs/cgroup,/sys/fs/cgroup目录,容器启动之后,可以在
/sys/fs/cgroup/memory/docker目录下查看内存相关的数据。memory.limit_in_bytes(限制总量)、memory.usage_in_bytes(使用量)。
如果监控网络信息,在/proc/{pid}/net/dev下面读取。

为什么容器需要Namespace

Namespace产生时间

命名空间与版本的关系:

Namespace名称 作用 内核版本
Mount(mnt) 隔离挂载点 2.4.19
Process(pid) 隔离进程id 2.6.24
Network(net) 隔离网络设备,端口号 2.6.29
Interprocess Communication(ipc) 隔离System IPC和POSIX Message Queue 2.6.19
UTS Namespace(uts) 隔离主机名和域名 2.6.19
User Namespace(user) 隔离用户和用户组 3.8
Control group Namespace 隔离cgroups根目录 4.6
Time Namespace 隔离系统时间 5.6

各个Namespace的作用

Mount Namespace

Mount Namespace用来隔离不同的进程或进程组看到的挂载点。
使用unshare命令可以新建Mount Namespace,并且在新建的Mount Namespace内Mount是和外部完全隔离的。

[root@centos7 centos]# sudo unshare --mount --fork /bin/bash
[root@centos7 centos]# mkdir /tmp/tmpfs
[root@centos7 centos]# mount -t tmpfs -o size=20m tmpfs /tmp/tmpfs
[root@centos7 centos]# ls -l /proc/self/ns

PID Namespace

PID Namespace的作用是用来隔离进程。

[root@centos7 centos]# sudo unshare --pid --fork --mount-proc /bin/bash
[root@centos7 centos]# ps aux # 查看进程

UTS Namespace

UTS Namespace主要是用来隔离主机名的,允许每个UTS Namespace拥有一个独立的主机名。

[root@centos7 centos]# sudo unshare --uts --fork /bin/bash
[root@centos7 centos]# hostname -b docker
[root@centos7 centos]# hostname

IPC Namespace

IPC Namespace主要是用来隔离进程间通信。

[root@centos7 centos]# sudo unshare --ipc --fork /bin/bash
[centos@centos7 ~]$ ipcs -q
[root@centos7 centos]# ipcmk -Q

ipcs -q命令:用来查看系统间通信队列列表。
ipcmk -Q命令:用来创建系统间通信队列。

User Namespace

User Namespace 主要是用来隔离用户和用户组的。

[centos@centos7 ~]$ unshare --user -r /bin/bash # 如果没有权限,执行echo 65535 > /proc/sys/user/max_user_namespaces,然后再次尝试创建 User Namespace。

Net Namespace

Net Namespace用来隔离网络设备、IP地址和端口等信息。

[root@centos7 centos]#  sudo unshare --net --fork /bin/bash

如何通过Cgroups机制实现资源限制

cgroups主要功能:

  • 资源限制:限制资源的使用量,设置上限。
  • 优先级控制:不同的组可以有不同的资源使用优先级。
  • 审计:计算控制组的资源使用情况。
  • 控制:控制进程的挂起或恢复。

Cgroups功能的实现依赖与三个核心概念:子系统、控制组、层级树。

  • 子系统:是一个内核的组件,一个子系统代表一类资源调度控制器。
  • 控制组:一组进程和一组带有参数的子系统的关联关系。
  • 层级树:一系列的控制组按照树状结构排列组成的。
sudo mount -t cgroup # 查看当前系统已经挂载的cgroups信息

CPU子系统

在cpu子系统下创建cgroup

[root@centos7 centos]# mkdir /sys/fs/cgroup/cpu/mydocker

创建进程,加入cgroup

[root@centos7 centos]# cd /sys/fs/cgroup/cpu/mydocker
[root@centos7 centos]# echo $$ > tasks

执行CPU耗时任务,验证cgroup是否可以限制cpu使用时间

[root@centos7 centos]# cd /sys/fs/cgroup/cpu/mydocker
[root@centos7 centos]# echo 50000 > cpu.cfs_quota_us

memory 子系统

在memory子系统下创建cgroup

[root@centos7 centos]# mkdir /sys/fs/cgroup/memory/mydocker

创建进程,加入cgroup

[root@centos7 centos]# cd /sys/fs/cgroup/cpu/mydocker
[root@centos7 centos]# echo $$ > tasks

删除cgroups

[root@centos7 centos]# rmdir /sys/fs/cgroup/memory/mydocker

Docker组件机器原理

docker相关的组件:docker、dockerd、docker-init和docker-proxy。
containerd相关的组件:containerd、container-shim和ctr。
容器运行时相关的组件:runC。

dockerd

dockerd是Docker服务端的后台常驻进程,用来接收客户端发送的请求,执行具体的处理任务,处理完成后将结果返回给客户端。
Docker客户端与dockerd的交互方式:

  • unix套接字与服务端通信:配置格式为,unix://socket_path,默认为/var/run/docker.sock,该文件只有root或者docker用户可以访问。
  • TCP与服务端通信:可以配置为tcp://host:port
  • 文件描述符的方式与服务端通信:配置格式为: fd:// 这种格式一般用于systemd管理的系统中。

docker-init

init进程是1号进程,在docker run启动容器时可以添加--init参数,此时docker会使用docker-init作为1号进程。

docker-proxy

docker-proxy主要是用来做端口映射的。docker-proxy组件就会把容器内先赢的端口映射到主机上来,底层是依赖iptables实现的。

[root@centos7 centos]# sudo iptables -L -nv -t nat # iptables nat表的规则。

docker是官方实现的标准客户端,dockerd是Docker服务端的入口,负责接收客户端发送的指令并返回相应结果,docker-init在业务主进程没有进程回收功能,
docker-proxy组件是实现Docker网络访问的主要组件。

containerd

containerd不仅负责容器生命周期的管理,同时负责一些其他的功能:

  • 镜像的管理
  • 接收dockerd的请求,通过适当的参数调用runC启动容器;
  • 管理存储相关资源;
  • 管理网络相关资源;

containerd包含一个后台常驻进程,默认的socket路径为/run/containerd/containerd.sock,dockerd通过unix套接字向containerd发送请求,
containerd接收到请求后负责执行相关的动作并把执行结果返回给dockerd。

container-shim

container-shim的主要作用是将containerd和真正的容器进程解耦,使用container-shim作为容器进程的父进程,
从而实现containerd不影响已经启动的容器进程。

ctr

ctr是containerd-ctr,它是containerd的客户端,主要用来开发和调试。

runC

[root@centos7 centos]# cd  /home/centos
[root@centos7 centos]# mkdir runc # 创建runc运行根目录
[root@centos7 centos]# mkdir rootfs &&& docker export $(docker create busybox) | tar -C rootfs -xvf - # 导入rootfs镜像文件
[root@centos7 centos]# runc spec
[root@centos7 centos]# cat config.json
[root@centos7 centos]# runc run busybox # 启动容器
[root@centos7 centos]# cd /home/centos/runc
[root@centos7 centos]# runc list
组件分类 组件名称 作用剖析
Docker相关组件 docker Docker客户端,负责发送Docker操作请求
Docker相关组件 dockerd Docker服务端入口,负责接收客户端请求并返回结果
Docker相关组件 docker-init 业务主进程没有回收能力时,docker-init可以作为容器的1号进程,负责管理容器的内子进程
Docker相关组件 docker-proxy 用于Docker的网络实现,通过设置iptables规则使得访问到主机的流量可以转发到容器中
containerd相关组件 containerd 负责管理容器的生命周期,接收dockerd的请求,执行启动或者销毁容器操作
containerd相关组件 containerd-shim 将containerd和真正的容器进行解解耦,使用containerd-shim作为容器进程的父进程,可以实现重启containerd不影响已经启动的容器进程
containerd相关组件 ctr containerd的客户端,可以直接向containerd发送容器操作请求,主要用来测试和开发
容器运行时组件 runc 通过Namespace、Cgroups等系统接口,实现容器的创建和销毁

Docker网络模型

libnetwork常见的网络模式 作用 业务场景
null空间模式 不提供任何容器网络 处理一些保密数据,需要一个隔离的网络环境执行一些纯计算任务
bridge桥接模式 使得容器与容器之间网络可以互通 容器需要实现网络通信或者提供网络服务
host主机模式 让容器内的程序可以使用到主机的网络 容器需要控制主机网络或者使用主机网络提供服务
container网络模式 将两个容器放到同一个网络空间中,可以直接通过localhost本地访问 两个容器之间需要通过localhost通信

[转帖]Docker相关的概念和原理的更多相关文章

  1. [转帖]Docker五种存储驱动原理及应用场景和性能测试对比

    Docker五种存储驱动原理及应用场景和性能测试对比 来源:http://dockone.io/article/1513 作者: 陈爱珍 布道师@七牛云   Docker最开始采用AUFS作为文件系统 ...

  2. 【转帖】Hadoop — HDFS的概念、原理及基本操作

    Hadoop — HDFS的概念.原理及基本操作 https://www.cnblogs.com/swordfall/p/8709025.html 分类: Hadoop undefined 1. HD ...

  3. Docker相关文档

    网上找到的一个入门级Docker学习笔记,写的不错,值得一看. 转自:http://www.open-open.com/lib/view/open1423703640748.html#articleH ...

  4. Docker学习笔记,从原理到实践

    什么是docker Docker是使用go语言基于LINUX内核的cgroup,namespace以及AUFS 类的 Union FS 等技术,对进程进行封装隔离的一种操作系统层面的虚拟化技术,由于隔 ...

  5. Oracle 集群】ORACLE DATABASE 11G RAC 知识图文详细教程之ORACLE集群概念和原理(二)

    ORACLE集群概念和原理(二) 概述:写下本文档的初衷和动力,来源于上篇的<oracle基本操作手册>.oracle基本操作手册是作者研一假期对oracle基础知识学习的汇总.然后形成体 ...

  6. Java线程:概念与原理

    Java线程:概念与原理 一.操作系统中线程和进程的概念 现在的操作系统是多任务操作系统.多线程是实现多任务的一种方式. 进程是指一个内存中运行的应用程序,每个进程都有自己独立的一块内存空间,一个进程 ...

  7. RabbitMQ基本概念和原理

    RabbitMQ基本概念和原理 1.AMQP,即Advanced Message Queuing Protocol,高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计. 2.Rabb ...

  8. LDAP服务器的概念和原理简单介绍

    LDAP服务器的概念和原理简单介绍 1. 目录服务 目录是一个为查询.浏览和搜索而优化的专业分布式数据库,它呈树状结构组织数据,就好象Linux/Unix系统中的文件目录一样.目录数据库和关系数据库不 ...

  9. Java注解的基本概念和原理及其简单实用

      一.注解的基本概念和原理及其简单实用 注解(Annotation)提供了一种安全的类似注释的机制,为我们在代码中添加信息提供了一种形式化得方法,使我们可以在稍后某个时刻方便的使用这些数据(通过解析 ...

  10. Docker —几个概念的理解

    本文从一种使用场景来引出docker,并讨论了什么是镜像,容器,仓库,以及docker的相关概念. 试想一种使用场景: 我的wordpress 博客网站现在部署在阿里云服务器上,但是在后期的使用中我有 ...

随机推荐

  1. Llama2-Chinese项目:8-TRL资料整理

      TRL(Transformer Reinforcement Learning)是一个使用强化学习来训练Transformer语言模型和Stable Diffusion模型的Python类库工具集, ...

  2. Llama2-Chinese项目:6-模型评测

      测试问题筛选自AtomBulb[1],共95个测试问题,包含:通用知识.语言理解.创作能力.逻辑推理.代码编程.工作技能.使用工具.人格特征八个大的类别. 1.测试中的Prompt   例如对于问 ...

  3. 神经网络入门篇:激活函数的导数(Derivatives of activation functions)

    激活函数的导数 在神经网络中使用反向传播的时候,真的需要计算激活函数的斜率或者导数.针对以下四种激活,求其导数如下: 1)sigmoid activation function 图1.8.1 其具体的 ...

  4. 如何利用动态配置中心在JavaAgent中实现微服务的多样化治理

    本文分享自华为云社区<如何利用动态配置中心在JavaAgent中实现微服务的多样化治理>,作者:华为云开源 . 一.前言 随着JavaAgent在微服务治理方面的广泛应用和发展,我们可以在 ...

  5. 华为云黄瑾:做强坚实数据底座,GaussDB与产业携手共进

    近日,华为全球智慧金融峰会2023在上海顺利举行,华为云副总裁.战略与产业发展部总裁黄瑾发表了<做强坚实数据底座,GaussDB与产业携手共进>的主题演讲. 以下为演讲实录: 尊敬的各位来 ...

  6. 一文读懂配置管理(CM)

    配置管理(Configuration Management),是一个用于建立和维护产品性能.功能和物理属性,并与其需求.设计和操作信息在整个生命周期内保持一致的系统工程. 配置管理是 ITIL(Inf ...

  7. 大数据-业务数据采集-FlinkCDC The MySQL server is not configured to use a ROW binlog_format

    Caused by: org.apache.kafka.connect.errors.ConnectException: The MySQL server is not configured to u ...

  8. 微服务网关 —— SpringCloud Netflix Zuul

    概述 Spring Cloud Zuul 是 Spring Cloud Netflix 子项目的核心组件之一,可以作为微服务架构中的 API 网关使用,有以下用途: 鉴权:对于访问每个服务的请求进行鉴 ...

  9. Codeforce 318A - Even Odds(数学水题)

    Being a nonconformist, Volodya is displeased with the current state of things, particularly with the ...

  10. L1-046 整除光棍 (20分)

    问题描述 这里所谓的"光棍",并不是指单身汪啦~ 说的是全部由1组成的数字,比如1.11.111.1111等.传说任何一个光棍都能被一个不以5结尾的奇数整除.比如,111111就可 ...