Ubantu docker学习笔记(五)容器底层技术


一、Docker基本架构

docker架构采用标准的c/s架构,服务端用于管理数据,客户端用于用户交互,服务端和客户端可以在同一台机器上面运行,也可以在不同的机器上运行。

1.1 服务端

一般运行于后台,接受客户端的请求,只允许本地的root和docker用户组成员访问,可以通过-H来修改参数监听方式。同时支持HTTPS的方式来验证。

1.2 客户端

用户不可以和服务器直连,需要通过Docker客户端执行命令,与Docker服务器进行交互。与docker服务端不同的是,等待服务器放回的消息,收到消息后会马上结束。再执行的时候,需要再次调用客户端程序。同时可以执行命令指定服务器地址。
可以通过

docker version

去查看链接情况
在这里插入图片描述
如果没有则需要指定其到正确通信位置,实例代码如下

docker -H tcp://127.0.0.1:1234 version

二、Namespace

Namespace其实就相当于修改了看待计算机的视图,对于用户看到的线程进行了限制,比如说,我在外面运行了一个进程号为100的centos,但是在centos的内部,其进程号是重新开始计算的
在这里插入图片描述
我们通过一个小例子来操作一下

docker run -it centos /bin/bash
ps

在这里插入图片描述
在镜像容器内部,我们的进程从1重新开始

ctrl+q+p(退出但不终止容器)
docker ps
ps aux | grep d7ebd94af48f

ps a 显示现行终端机下的所有程序,包括其他用户的程序​​
ps u 以用户为主的格式来显示程序状况
ps x 显示所有程序,不以终端机来区分

在这里插入图片描述
找到刚刚这个镜像的id后,再去去打印其所有进程,很清楚的可以看到,centos的进程号为2799,但是其内部的进程号为1

2.1 Namespace的类别

Linux使用了6种namespace,分别对应6种资源: Mount、 UTS、IPC、PID、Network和User。
1.Mount namespace
其可以将文件系统的目录和另外一个目录关联起来,让容器看上去拥有了一整个文件系统,我们操作只会在当前容器生效不会影响其他容器。

2.UTS namespace
简单的来说可以让容器拥有自己的名字

docker run -h xiaotang -it centos

在这里插入图片描述

3.IPC namespace
让容器有共享的内存和信号量,使其在同一Namespace下可以互相通信

4.PID namespace
主要用来隔离我们的进程ID,使其可以重复且相互之间不受影响,也就是我们之前上面的例子啦,如果比喻成父子关系的话也就是,所有的父亲可以看到自己的子进程,子看不到父,楚门的世界啊哈哈哈哈。

5.Network namespace
让我们的容器拥有独立的网卡、ip和路由

6.Usernamespace
主要用来隔离和User权限相关的Linux资源,包括User ID和Group ID,用来管理用户和划分权限。

2.2 Namespace的劣势

1.隔离不彻底
多个容器使用的依旧是宿主机的内核,在windows宿主机上用低版本的Linux运行较高版本的Linux,行不通

2.部分资源不可以被Namespace化
时间,宿主机和容器时间保持一致

3.安全问题
因为共享内核,容器中应用暴露,攻击面大。可以通过一些技术来调整,但通常情况下不知道应该禁用哪些系统调用。

三、Cgroups

虽然我们使用namespace所限制,但是在外部看来,容器里面的进程会是一个整体,和宿主机上其他的资源依旧是竞争关系,因此依据有可能会把所有资源耗尽。Cgroups的设置,可以限制单个进程或者多个进程使用资源分配管理的机制,如上一小节中,我们设置cpu时间以及I/O读取限制,都属于其中的一种。
举个例子吧

docker run -it --cpu-shares 521 progrium/stress -c 1

然后我们

ls  /sys/fs/cgroup/cpu/docker

可以看到会有一个容器进程ip的目录
在这里插入图片描述
进入,然后打开里面的

cat cpu.shares

然后就可以看到我们刚刚分配的内存资源
在这里插入图片描述

3.1 Cgroups的限制能力

子系统功能
blkio该子系统为块设备设定输入/输出限制,如物理设备(磁盘、固态硬盘、USB 等 )。
cpu该子系统使用调度程序提供对 CPU的 Cgroups 任务访问
cpuacct该子系统自动生成Cgroups 中任务所使用的 CPU 报告
cpuset该子系统为 Cgroups 中的任务分配独立CPU(在多核系统)和内存节点。
devuces该子系统可允许或者拒绝 Cgroups 中的任务访问设备
freezer该子系统挂起或者恢复 Cgroups 中的任务
memory该子系统设定 Cgroups 中任务的内存限制,并自动生成由那些任务使用的内存资源报告
net_cls该子系统使用等级识别符标记网络数据包,可允许 Linux 流量控制程序识别从具体 Cgroups中生成数据包
ns该子系统提供了一个将进程分组到不同命名空间的方法

Cgroups对用户暴露出来的操作接口是文件系统,会在/sys/fs/cgroups的路径下,可以进行查看

mount -t cgroupscd 
cd /sys/fs/cgroup/cpu
ls

在这里插入图片描述

3.2 实例验证

cd /sys/fs/cgroup/cpu
mkdir container
ls container/

在这里插入图片描述
然后去跑满cpu

while :; do :; done &
top

在这里插入图片描述

cat /sys/fs/cgroup/cpu/container/cpu.cfs_quota_us
cat /sys/fs/cgroup/cpu/container/cpu.cfs_period_us

现在我们打开限制,使其只能使用20%的cpu带宽,然后注意把我们刚刚top里面的进程号写入tasks

echo 20000 > /sys/fs/cgroup/cpu/container/cpu.cfs_quota_us
echo 21097 > /sys/fs/cgroup/cpu/container/tasks

在这里插入图片描述
即我们可以通过为每一个容器创建控制组,加入到task文件中,来进行限制

docker run -it -d --cpu-period=100000 --cpu-quota=20000 centos /bin/bash

启动后也可以在在我们的控制组里面看到对应文件啦

cd /sys/fs/cgroup/cpu/docker
ls
cd 你的进程号
cat cpu.cfs_quota_us
cat cpu.cfs_period_us

在这里插入图片描述

3.3 Cgroups的劣势

在proc文件中,用户可以直接访问这些文件,但是用户在容器中中,使用top查看的会是宿主机的数据

四、Docker文件系统

4.1可读可写层的工作原理

docker镜像采用的是层级结构,通过docker命令一层一层通过docker commit来形成只读层,我们容器所有的操作都是在可读可写层上进行操作,直接删除容器后,可读可写层也会随着删除,可以用docker commit,来形成只读层。
1.写时复制
cow技术相当于直接共用容器中的只读层来节约空间,我们要进行操作时只需要把要写的文件复制到自己的文件系统进行修改

2.分时复制
用时分配是先前没有分配空间,只有在写入一个新文件的时候才进行分配

4.2docker存储驱动

Docker 提供了多种存储驱动(Storage Driver)来存储镜像,常用的几种 Storage Driver 是 AUFS、OverlayFS、Device Mapper、Btrfs、ZFS。

Docker存储驱动宿主机文件系统
Overlay, Overlay2XFS(ftype=1), EXT4
AUFSXFS,EXT4
Device Mapperdirect-lvm
BtrfsBtrfs
ZFSZFS
docker info

在这里插入图片描述

存储驱动特点优点缺点适用场合
AUFS联合文件系统,未并入内核主线,文件级存储作为 Docker 的第一个存储系统,有较长历史,比较文档,且在大量的生产中实践过,有较强的社区支持有多层,在做写时复制操作时,如果文件比较大且存在于比较低的层,可能会慢一些大并发但少IO的场景
OverlayFS联合文件系统,并入内核主线,文件级存储只有两层不管修改的内容多少都会复制整个文件,对大文件进行修改显示要比小文件消耗更多的时间大并发但少 IO的场景
Device Mapper并入内核主线,块级存储无论是大文件还是小文件都只复制需要修改的块,并不复制整个文件不支持共享存储,当有多个容器读同一个文件时,需要生成多个复本,在很多容器启停的情况下可能会导致磁盘溢出IO 密集的场景
<think>嗯,用户问的是零基础如何从零开始学习计算机。首先,我需要考虑用户可能的背景。零基础可能意味着他们对计算机的了解非常有限,甚至可能没有接触过编程或者计算机科学的基本概念。因此,我应该从最基础的部分开始,逐步引导他们建立知识体系。 接下来,我需要确定学习路径的结构。通常,计算机科学的学习可以分为几个阶段:基础知识、编程入门、核心领域、工具和环境、项目实践、持续学习。这样的结构可以帮助用户分步骤学习,不会感到太吃力。 基础知识部分,应该包括计算机的组成、操作系统的基本使用,以及网络基础。比如,解释什么是CPU、内存、硬盘,以及如何安装软件和管理文件。这些内容对于完全零基础的人来说是必要的,因为他们可能对这些概念一无所知。 然后是编程入门。选择一门适合初学者的语言很重要,Python通常是一个不错的选择,因为它语法简洁,应用广泛。需要指导用户学习基本语法、数据类型、流程控制,然后逐步过渡到函数和模块。同时,强调练习的重要性,比如通过在线平台做题,或者自己尝试解决实际问题。 核心领域方面,可能需要介绍数据结构与算法、计算机组成原理、操作系统、计算机网络、数据库等。但这里要注意深度,零基础的人可能无法一下子掌握这么多内容,所以需要分阶段,可能先重点在数据结构和算法,因为这对编程能力提升最直接。 工具和环境部分,版本控制工具如Git是必须的,开发环境如VS Code或PyCharm也需要介绍。此外,命令行操作也是基础技能之一,应该让用户熟悉基本的命令。 项目实践是关键,因为只有通过实际项目,用户才能巩固所学知识。需要建议他们从小项目开始,逐步增加复杂度,并参与开源项目或团队协作,这有助于学习协作开发和代码管理。 持续学习方面,推荐优质资源如在线课程、书籍、技术社区等。同时,提醒用户保持好奇心和耐心,因为学习计算机可能会遇到很多困难,需要坚持不懈。 最后,需要注意用户的潜在需求。他们可能想转行进入IT行业,或者只是对计算机感兴趣。因此,在回答中应该鼓励他们设定目标,并持之以恒。同时,强调实践的重要性,避免只停留在理论层面。 可能还需要调整语言,避免使用过于专业的术语,用更通俗易懂的例子来解释概念。例如,用“计算机的大脑”来比喻CPU,帮助用户理解。此外,提醒用户不要急于求成,学习是一个渐进的过程,每一步都需要打好基础。 总结一下,回答的结构应该是分步骤、循序渐进,涵盖基础到进阶,强调实践和资源推荐,同时给予鼓励和支持,帮助用户建立信心。</think>零基础学习计算机可以遵循以下结构化路径,从底层逻辑到实践逐步深入: ### 一、认知基础阶段(1-2周) 1. **计算机组成原理** - 理解冯·诺依曼架构:CPU=大脑,内存=短期记忆,硬盘=长期记忆 - 二进制入门:用开关电路理解0/1的物理实现 - 存储单位换算:1MB=1024KB=1,048,576字节 2. **操作系统初探** - 文件系统树形结构:Windows的C盘/Linux的根目录 - 进程概念:程序运行时的"生命体" - 注册表/配置文件:系统设置的DNA ### 二、编程思维培养(3-8周) 1. **Python入门** ```python # 理解编程本质:数据转换器 def celsius_to_fahrenheit(c): return c * 9/5 + 32 print(f"37℃ = {celsius_to_fahrenheit(37)}℉") ``` - 掌握基础语法结构(顺序/分支/循环) - 理解数据类型的底层存储差异 - 文件操作:实现简单日记本程序 2. **算法思维训练** - 时间复杂度可视化:对比O(n)与O()的增长曲线 - 经典算法实践: - 冒泡排序(可视化演示) - 二分查找(电话簿查找模拟) ### 三、计算机系统认知(2-3个月) 1. **网络协议栈** - 模拟TCP三次握手:写信-回执-确认的通信过程 - 用Wireshark抓包分析HTTP请求 2. **数据库原理** ```sql -- 设计个人博客数据库 CREATE TABLE posts ( id INT PRIMARY KEY, title VARCHAR(255), content TEXT, created_at TIMESTAMP ); ``` 3. **Linux系统实践** - 虚拟机安装Ubuntu - Shell脚本自动化:批量重命名照片 - 权限管理:chmod 755的实际意义 ### 四、工程化能力建设(持续) 1. **开发工具链** - Git版本控制:创建个人代码仓库 - Docker容器化:打包开发环境 - CI/CD流水线:自动部署静态网站 2. **项目实战建议** - 初级:开发Markdown笔记转换器 - 中级:实现RSS阅读器带数据统计 - 高级:构建物联网温度监控系统 ### 学习资源导航 1. **理论奠基** - 《计算机科学导论》(Behrouz Forouzan) - CS50公开课(哈佛大学) 2. **实践平台** - LeetCode每日一题(从简单难度起步) - Kaggle机器学习入门竞赛 3. **社区互动** - Stack Overflow提问技巧 - GitHub开源项目协作规范 关键成长指标: - 第1个月:能独立编写100行左右的实用脚本 - 第3个月:完成首个全栈项目部署 - 第6个月:形成个人技术知识体系框架 注意避免的认知陷阱: 1. 不要陷入"最新技术"焦虑,先掌握通用原理 2. 警惕过度依赖可视化工具,理解底层实现 3. 编程语言只是工具,计算思维才是核心 学习曲线管理建议: - 每天保持1-2小时深度学习 - 每周完成1个mini-project - 每月进行知识体系复盘 通过这种结构化学习路径,配合刻意练习,零基础学习者可在6-12个月内建立完整的计算机知识框架,并具备基础开发能力。重要的是保持持续学习的节奏,在实践中不断深化理解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

叫我小唐就好了

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值