Docker - 基础

虚拟化/容器化

概念

虚拟化:通过虚拟化技术将一台物理机虚拟为多台逻辑计算机。

虚拟化常见类别:

虚拟机:硬件层面的虚拟化,实现和真实物理机几乎一样的功能

容器:操作系统层的虚拟化

JVM 之类的虚拟机:存在于函数库层和应用程序之间的虚拟化技术,为程序员提供一个提供统一的运行环境

容器化:一种虚拟化技术,又称操作系统层虚拟化,将操作系统内核虚拟化,容器之间共享操作系统内核,每个容器可以配置自己的运行时环境,有独立的文件系统。相当于在一个房子里面开辟出一个个胶囊公寓,每个胶囊共享房子的洗手间,WiFi。胶囊内部又是一个独立的空间

原因

  1. 资源利用率高,用较少成本管理多台服务器
  2. 环境标准化,镜像提供除内核外完整的运行时环境
  3. 沙箱安全,容器内部的操作不会影响到容器外部
  4. 容器比虚拟机更加轻量,前者直接运行与宿主内核,无需启动完整的操作系统。

容器虚拟化实现

通过namespace进行各程序的隔离,加上cgroups进行资源控制以进行虚拟化,以下操作使用cgroup v1 实现

namespace

namespace是Linux内核用来隔离内核资源的一种方式。通过namespace可以让一些进程只能看到与自己相关的一些资源,不同namespace进程拥有独立的全集资源,相互之间无法感应,改变一个namespace的系统资源只会影响当前namespace的进程

Namespace 类型 隔离内容 Docker 对应能力
PID 进程号空间,容器内 PID 从 1 开始 容器进程隔离,看不到宿主机进程
Mount 文件系统挂载点视图 容器独立根目录、数据卷挂载隔离
Network 网卡、端口 容器独立 IP、端口、网络栈
UTS 主机名与域名 容器可设置独立 hostname
IPC 进程间通信(信号量、共享内存等) 容器间 IPC 隔离
User 用户 / 用户组 ID 映射 容器内 root 映射为宿主机普通用户,降权

实现PID隔离

unshare --fork --pid --mount-proc /bin/bash

--fork:创建一个子进程

--pid:隔离进程命名空间,/bin/bash为一号进程

--mount-proc:在新的PID空间里重新生成一份只包含当前环境进程的/proc文件,防止ps命令读取宿主机的/proc文件

实现mount隔离

文件系统隔离,在隔离空间内挂载目录,宿主机不可见

复制代码
shell窗口1
unshare --mount --fork /bin/bash 
mkdir -p /data/tmpmount
dd if=/dev/zero of=fdimage.img bs=8k count=10240
在目录下生成一个全0空白文件fdimage.img,大小为80mb
mkfs -t ext4 ./fdimage.img
将fdimage.img格式化为ext4文件系统
mount ./fdimage.img /data/tmpmount
将fdimage.img挂载到/data/tmpmount目录下,成功后进入/data/tmpmount写入的任何数据,都会添加到fdimage.img
shell窗口2

在窗口2无法感知/data/tmpmount有镜像挂载,窗口1对镜像进行操作,窗口2也无法感知

cgroups

cgroups是Linux内核提供的一种机制,这种机制可以根据需求把一系列进程及其子进程按照所需资源不同划分到不同的组内,每组有单独的资源划分方案,以实现对容器的cpu,内存等实现精细化控制

实现对CPU进行控制

  1. 进入cgroup的cpu控制目录,创建一个CPU控制组

  2. 启动stress进程,将CPU打满,stress -c 1

  3. 设置控制组CPU占用上限,cfs_quota_us存储Cgroup可以使用的cpu带宽,单位是微秒

    复制代码
    echo 20000 > cpu.cfs_quota_us 
  4. 将stress进程PID放入控制组

    复制代码
    echo 38578 > tasks
  5. CPU占用率降低

UnionFS

联合文件系统,docker镜像由一层层只读层堆叠而成,不同镜像之间可以共享底层基础镜像。当容器启动时,docker只会在只读的镜像层之上增加一个容器层(可读写层)。容器内的所有修改都在这一层执行,一旦容器被删除,这一层的数据也会丢失

LXC

Linux Containers Linus容器,容器化技术的具体实现,上层将应用软件打包成一个软件容器。内部存放了软件本身的代码以及所需要的操作系统核心和动态链接库,下层通过namespace技术实现文件系统的隔离,通过cgroup技术实现对系统资源的精细化控制

Docker

概念

早期Docker是LXC的增强版,它本身不是容器,并没有单独实现一个容器,而是一个容器的易用工具。底层是对LXC的二次封装,但是创建容器时不再使用模板进行生成,而是通过镜像技术(将一个操作系统的用户空间所使用的组件,编排好并打包成一个镜像文件),镜像文件集中放在镜像仓库。当需要创建容器时,docker连接到镜像服务器上下载匹配的文件。

docker的主要目标就是通过对组建的封装,分发,部署,运行等声明周期的管理,实现"一次构建,到处运行"

Docker 的引擎迭代

Docker早期是基于LXC容器管理引擎实现,当后来成熟之后,Docker自建了一个叫做libcontainer的引擎。之后Docker又研发了一个工业化标准的容器引擎 runC

Docker和虚拟机的区别

  1. 共享操作系统内核,磁盘占用低
  2. 安装管理比虚拟机方便,能够实现自动化部署
  3. 虚拟机通过虚拟层实现与硬件的交互,容器则直接与硬件交互,资源利用率高
  4. 虚拟机隔离性是系统级别,Docker是进程级别
  5. docker启动更快,不需要像虚拟机一样加载整个操作系统内核

架构

docker采用客户端-服务器架构,现代调用链:Docker Client -> daemon -> containerd -> containerd-shim -> runC

Docker Registry:docker仓库,用来保存镜像

Docker daemon;服务器组件,docker最核心的后台进程,称为守护进程

Docker Client:使用命令行或其他工具通过docker api与守护进程进行通信

Docker Host:用于执行docker守护进程

Docke Images;docker容器的模板

Docker Container:模板启动后,就成为docker容器,独立运行一个或一组应用

相关推荐
swipe1 小时前
06|(前端转后全栈)登录后端到底在做什么?JWT、Spring Security 和权限链路
前端·后端·全栈
Promise微笑1 小时前
智能激光清障仪选型指南:高效运维与安全保障的关键考量
运维·安全
Code_Ignis1 小时前
docker国内可用源(持续维护)
运维·docker·容器
一叶龙洲1 小时前
向日葵远程Ubuntu,支持隐私屏
linux·运维·ubuntu
阳光是sunny2 小时前
LangGraph实战教程:预定义状态MessagesState与AgentState
前端·人工智能·后端
我叫黑大帅2 小时前
add()和 __add__() 写法哪个更好呢?
后端·python·面试
Gopher_HBo3 小时前
moby-daemon-config配置
后端
拉斯特当思3 小时前
设备总掉线却复现不了?把弱网“造“出来:tcconfig 五种网络故障模拟实战
后端