docker

https://img-blog.csdnimg.cn/15d4e5e743134ac9bd9e6e0e90259e73.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBARmlrTC0wOS0xOQ==,size_19,color_FFFFFF,t_70,g_se,x_16#pic_center

docker理论基础

基于 Linux 内核的 Cgroup,Namespace,以及 Union FS 等技术,对进程进行封装隔离,属于操作系统 层面的虚拟化技术,由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。 • 最初实现是基于 LXC,从 0.7 以后开始去除 LXC,转而使用自行开发的 Libcontainer,从 1.11 开始,则 进一步演进为使用 runC 和 Containerd。 • Docker 在容器的基础上,进行了进一步的封装,从文件系统、网络互联到进程隔离等等,极大的简化了容 器的创建和维护,使得 Docker 技术比虚拟机技术更为轻便、快捷。

容器操作

启动: • docker run

  • -it 交互
  • -d 后台运行
  • -p 端口映射
  • -v 磁盘挂载

• 启动已终止容器 docker start • 停止容器 docker stop • 查看容器进程 docker ps

Namespace

• Linux Namespace 是一种 Linux Kernel 提供的资源隔离方案: • 系统可以为进程分配不同的 Namespace; • 并保证不同的 Namespace 资源独立分配、进程彼此隔离,即不同的 Namespace 下的进程互不干扰

  • Namespace 可以隔离进程Id、主机名、用户ID、文件名、网络访问和进程间通信等相关资源
  • 参考油管教程

[[post/14.新语言学习记录/语言技术/Golang/容器技术/cgroup原理 | cgroup原理]] [[post/14.新语言学习记录/云原生原理/Docker学习/linux control groups(cgroups) | group应用]]

Cgroup

Cgroups (Control Groups)是 Linux 下用于对一个或一组进程进行资源控制和监控的机制; • 可以对诸如 CPU 使用时间、内存、磁盘 I/O 等进程所需的资源进行限制; • 不同资源的具体管理工作由相应的 Cgroup 子系统(Subsystem)来实现 ; • 针对不同类型的资源限制,只要将限制策略在不同的的子系统上进行关联即可 ; • Cgroups 在不同的系统资源管理子系统中以层级树(Hierarchy)的方式来组织管理:每个 Cgroup 都可以 包含其他的子 Cgroup,因此子 Cgroup 能使用的资源除了受本 Cgroup 配置的资源参数限制,还受到父 Cgroup 设置的资源限制 。

隔离原理 -Linux namespace

不同的进程 会有一个 PID ,不同的进程 pid 可以相同,也可以不同, 我们可以把 一组需要 手动管理的进程 放在 一个 PID namespace 里面, 也就是说 每个 namespace 的 pid 是不一样的,就能做到互相隔离

这是 linux 内核支持的

image-20211203235450417

隔离原理2. - net namespace

  • 网络隔离是通过 net namespace 实现的, 每个 net namespace 有独立的 network devices, IP addresses, IP routing tables, /proc/net 目录。
  • Docker 默认采用 veth 的方式将 container 中的虚拟网卡同 host 上的一个docker bridge: docker0连接 在一起

隔离原理3. -ipc namespace

  • Container 中进程交互还是采用 linux 常见的进程间交互方法 (interprocess communication – IPC), 包 括常见的信号量、消息队列和共享内存。
  • container 的进程间交互实际上还是 host上 具有相同 Pid namespace 中的进程间交互,因此需要在 IPC 资源申请时加入 namespace 信息 - 每个 IPC 资源有一个唯一的 32 位 ID。

bash 操作 namespace

1
2
3
4
lsns -t <type>
ls -la /proc/<pid>/ns/
# 进入某个 namespace 运行命令
nsenter -t <pid> -n ip addr

cgroups 资源管控

参考教程

  • cgroups (control groups) 是 linux 下用于对一个或者一组进程进行资源控制和监控的机制
  • 可以对诸如 CPU 使用时间、内存、磁盘I/O等进程所需的资源进行限制
  • 不同资源对具体隔离工作由相应的 Cgroup 子系统 (subsystem) 来实现
  • 针对不同类型的资源限制,只要将限制策略在不同的子系统上进行关联即可
  • Cgroups 在不同的系统资源管理子系统中以层级树的方式来组织和管理: 每个 cgroup 都可以包含其他的子Cgroup,因此 Cgroup 能使用的资源除了受本Cgroup 配置的资源参数限制,还受到父Cgroup 设置的资源限制

CPU 子系统

cpu.shares: 可出让的能获得 CPU 使用时间的相对值。 cpu.cfs_period_us:cfs_period_us 用来配置时间周期长度,单位为 us(微秒)。 cpu.cfs_quota_us:cfs_quota_us 用来配置当前 Cgroup 在 cfs_period_us 时间内最多能使用的 CPU 时间数,单 位为 us(微秒)。 cpu.stat : Cgroup 内的进程使用的 CPU 时间统计。 nr_periods : 经过 cpu.cfs_period_us 的时间周期数量。 nr_throttled : 在经过的周期内,有多少次因为进程在指定的时间周期内用光了配额时间而受到限制。 throttled_time : Cgroup 中的进程被限制使用 CPU 的总用时,单位是 ns(纳秒)。

https://images0.cnblogs.com/i/319578/201405/252326220902394.jpg

1
2
3
service cgconfig start   #开启cgroups服务
chkconfig cgconfig on   #开启启动
ls /cgroup/

参考博客

linux进程调度器

内核默认提供了5个调度器,Linux 内核使用 struct sched_class 来对调度器进行抽象: • Stop 调度器,stop_sched_class:优先级最高的调度类,可以抢占其他所有进程,不能被其他进程抢占; • Deadline 调度器,dl_sched_class:使用红黑树,把进程按照绝对截止期限进行排序,选择最小进程进 行调度运行; • RT 调度器, rt_sched_class:实时调度器,为每个优先级维护一个队列; • CFS 调度器, cfs_sched_class:完全公平调度器,采用完全公平调度算法,引入虚拟运行时间概念; • IDLE-Task 调度器, idle_sched_class:空闲调度器,每个 CPU 都会有一个 idle 线程,当没有其他进程 可以调度时,调度运行 idle 线程。

CFS 调度器 • CFS 是 Completely Fair Scheduler 简称,即完全公平调度器。 • CFS 实现的主要思想是维护为任务提供处理器时间方面的平衡,这意味着应给进程分配相当数量的处理器。 • 分给某个任务的时间失去平衡时,应给失去平衡的任务分配时间,让其执行。 • CFS 通过虚拟运行时间(vruntime)来实现平衡,维护提供给某个任务的时间量。 • vruntime = 实际运行时间*1024 / 进程权重 • 进程按照各自不同的速率在物理时钟节拍内前进,优先级高则权重大,其虚拟时钟比真实时钟跑得慢,但 获得比较多的运行时间。

ve runtime 红黑树 CFS 调度器没有将进程维护在运行队列中,而是维护了一个以虚拟运行时间为顺序的红黑树。 红黑树的主要 特点有:

  1. 自平衡,树上没有一条路径会比其他路径长出俩倍。
  2. O(log n) 时间复杂度,能够在树上进行快速高效地插入或删除进程。

podman

podman 和 docker的区别是什么?

docker 后台有一个 dockerd的 进程, docker的各种命令 就是 和 dockerd 进程交互使用的。

docker 概念梳理

参考油管的视频

image-20220311173920397

docker 是基于 linux 来实现的,如果要在windows下使用,就要通过 hyperv 上面装一个 linux虚拟机来实现,mac下 就要 装linux 虚拟机实现。

油管-docker源码学习

  1. 打开docker调试模式,查看详细日志,根据调试日志去查找对应的Docker代码,发现 dockerd请求 containerd无响应。
  2. 发送linux siguser1信号量,打印 Golang堆栈信息
  3. 结合 内核 Cgroups相关日志,定位和解决问题

docker实现的三大机制

  • namespace 【隔离 进程,内核隔离】

    1. pid namespace 隔离进程 id
    2. net namespace 隔离网络接口
    3. mnt namespace 文件系统挂载点隔离
    4. ipc namespace 信号量,消息队列和共享内存的隔离
    5. uts namespace 主机名和域名隔离
  • cgroup 【限制资源调用】,限制和隔离进程的资源使用情况【CPU、内存、磁盘、网络等】

  • 联合文件系统 【镜像构建】【实现容器的写时复制,定向分层构建和存储】

    • 又叫 UnionFs,是一种通过创建文件层进程操作的文件系统,常用联合文件系统有 AUFS、 Overlay 和 Devicemapper 等

安装Docker ,需要centos7及以上版本,建议使用overlay2存储驱动程序

chroot实现简单的 docker进程

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# 需要你安装最新版本的docker
sudo docker run hello-world
mkdir rootfs
# 创建一个 rootfs目录
cd rootfs
docker export $(docker create busybox) -o busybox.tar
tar -xf busybox.tar

chroot /home/centos/rootfs /bin/sh

# 这时候其实并没有隔离,ip等信息,需要用namespace,cgroup ,联合文件系统来搞
ip route
# ip和原来的一样
image-20220311195455443

在经过 chroot 之后,系统读取到的目录和文件将不在是旧系统根下的而是新根下(即被指定的新的位置)的目录结构和文件,因此它带来的好处大致有以下3个:

  1. 增加了系统的安全性,限制了用户的权力;

    在经过 chroot 之后,在新根下将访问不到旧系统的根目录结构和文件,这样就增强了系统的安全性。这个一般是在登录 (login) 前使用 chroot,以此达到用户不能访问一些特定的文件。

  2. 建立一个与原系统隔离的系统目录结构,方便用户的开发;

    使用 chroot 后,系统读取的是新根下的目录和文件,这是一个与原系统根下文件不相关的目录结构。在这个新的环境中,可以用来测试软件的静态编译以及一些与系统不相关的独立开发。

  3. 切换系统的根目录位置,引导 Linux 系统启动以及急救系统等。

    chroot 的作用就是切换系统的根位置,而这个作用最为明显的是在系统初始引导磁盘的处理过程中使用,从初始 RAM 磁盘 (initrd) 切换系统的根位置并执行真正的 init。另外,当系统出现一些问题时,我们也可以使用 chroot 来切换到一个临时的系统。

容器的概念

容器是镜像的运行实体

容器运行这真正的应用进程

容器有初建、运行、停止、暂停和删除五种状态

在容器内部,无法看到主机上的进程、环境变量、网络等信息

Docker Hub

Docker Hub是官方公开镜像仓库,有引用或者操作系统的官方镜像,还有很多组织和个人开发的镜像供我们免费存放、下载、研究和使用